summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml121
-rw-r--r--.gitlab/ci/configure_common.cmake4
-rw-r--r--.gitlab/ci/configure_debian10_legacy.cmake6
-rw-r--r--.gitlab/ci/configure_debian12_aarch64_extdeps.cmake (renamed from .gitlab/ci/configure_debian10_extdeps.cmake)0
-rw-r--r--.gitlab/ci/configure_debian12_aarch64_ninja.cmake (renamed from .gitlab/ci/configure_debian10_aarch64_ninja.cmake)14
-rw-r--r--.gitlab/ci/configure_debian12_extdeps.cmake (renamed from .gitlab/ci/configure_debian10_aarch64_extdeps.cmake)0
-rw-r--r--.gitlab/ci/configure_debian12_hip_radeon.cmake3
-rw-r--r--.gitlab/ci/configure_debian12_iwyu.cmake (renamed from .gitlab/ci/configure_debian10_iwyu.cmake)3
-rw-r--r--.gitlab/ci/configure_debian12_makefiles_clang.cmake (renamed from .gitlab/ci/configure_debian10_ninja_clang.cmake)0
-rw-r--r--.gitlab/ci/configure_debian12_makefiles_inplace.cmake (renamed from .gitlab/ci/configure_debian10_makefiles_inplace.cmake)0
-rw-r--r--.gitlab/ci/configure_debian12_ninja.cmake (renamed from .gitlab/ci/configure_debian10_ninja.cmake)19
-rw-r--r--.gitlab/ci/configure_debian12_ninja_clang.cmake (renamed from .gitlab/ci/configure_debian10_makefiles_clang.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora38_hip_radeon.cmake3
-rw-r--r--.gitlab/ci/configure_fedora38_makefiles.cmake9
-rw-r--r--.gitlab/ci/configure_fedora38_makefiles_clang.cmake4
-rw-r--r--.gitlab/ci/configure_fedora38_ninja_clang.cmake2
-rw-r--r--.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake2
-rw-r--r--.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake2
-rw-r--r--.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake2
-rw-r--r--.gitlab/ci/configure_macos_arm64_ninja_multi.cmake5
-rw-r--r--.gitlab/ci/configure_macos_arm64_pch.cmake7
-rw-r--r--.gitlab/ci/configure_mingw_osdn_io_common.cmake3
-rw-r--r--.gitlab/ci/configure_windows_clang_ninja.cmake2
-rw-r--r--.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake2
-rw-r--r--.gitlab/ci/configure_windows_vs2019_x64.cmake4
-rw-r--r--.gitlab/ci/configure_windows_vs2022_x64_pch.cmake2
-rw-r--r--.gitlab/ci/cxx_modules_rules_gcc.cmake15
-rw-r--r--.gitlab/ci/docker/debian10-x86_64/Dockerfile (renamed from .gitlab/ci/docker/debian10-aarch64/Dockerfile)3
-rw-r--r--.gitlab/ci/docker/debian10-x86_64/deps_packages.lst16
-rw-r--r--.gitlab/ci/docker/debian10-x86_64/docker-clean (renamed from .gitlab/ci/docker/debian10/docker-clean)0
-rw-r--r--.gitlab/ci/docker/debian10-x86_64/dpkg-exclude (renamed from .gitlab/ci/docker/debian10/dpkg-exclude)0
-rwxr-xr-x.gitlab/ci/docker/debian10-x86_64/install_deps.sh11
-rwxr-xr-x.gitlab/ci/docker/debian10/install_deps.sh15
-rw-r--r--.gitlab/ci/docker/debian12-aarch64/Dockerfile26
-rw-r--r--.gitlab/ci/docker/debian12-aarch64/deps_packages.lst (renamed from .gitlab/ci/docker/debian10-aarch64/deps_packages.lst)13
-rw-r--r--.gitlab/ci/docker/debian12-aarch64/docker-clean (renamed from .gitlab/ci/docker/debian10-aarch64/docker-clean)0
-rw-r--r--.gitlab/ci/docker/debian12-aarch64/dpkg-exclude (renamed from .gitlab/ci/docker/debian10-aarch64/dpkg-exclude)0
-rwxr-xr-x.gitlab/ci/docker/debian12-aarch64/install_deps.sh (renamed from .gitlab/ci/docker/debian10-aarch64/install_deps.sh)0
-rw-r--r--.gitlab/ci/docker/debian12-x86_64/Dockerfile (renamed from .gitlab/ci/docker/debian10/Dockerfile)4
-rw-r--r--.gitlab/ci/docker/debian12-x86_64/deps_packages.lst (renamed from .gitlab/ci/docker/debian10/deps_packages.lst)18
-rw-r--r--.gitlab/ci/docker/debian12-x86_64/docker-clean (renamed from Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON.cmake)0
-rw-r--r--.gitlab/ci/docker/debian12-x86_64/dpkg-exclude21
-rwxr-xr-x.gitlab/ci/docker/debian12-x86_64/install_deps.sh15
-rwxr-xr-x.gitlab/ci/docker/debian12-x86_64/install_iwyu.sh (renamed from .gitlab/ci/docker/debian10/install_iwyu.sh)3
-rwxr-xr-x.gitlab/ci/docker/debian12-x86_64/install_rvm.sh (renamed from .gitlab/ci/docker/debian10/install_rvm.sh)2
-rw-r--r--.gitlab/ci/docker/debian12-x86_64/iwyu_packages.lst (renamed from .gitlab/ci/docker/debian10/iwyu_packages.lst)6
-rw-r--r--.gitlab/ci/docker/debian12-x86_64/rvm_packages.lst (renamed from .gitlab/ci/docker/debian10/rvm_packages.lst)0
-rw-r--r--.gitlab/ci/docker/fedora38/deps_packages.lst7
-rw-r--r--.gitlab/ci/docker/gcc_cxx_modules/Dockerfile2
-rwxr-xr-x.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh2
-rw-r--r--.gitlab/ci/download_qt.cmake8
-rw-r--r--.gitlab/ci/download_qt_hashes.cmake4
-rw-r--r--.gitlab/ci/env_debian10_makefiles_clang.sh2
-rw-r--r--.gitlab/ci/env_debian10_ninja_clang.sh2
-rw-r--r--.gitlab/ci/env_debian12_aarch64_extdeps.sh (renamed from .gitlab/ci/env_debian10_extdeps.sh)0
-rw-r--r--.gitlab/ci/env_debian12_extdeps.sh (renamed from .gitlab/ci/env_debian10_aarch64_extdeps.sh)0
-rw-r--r--.gitlab/ci/env_debian12_hip_radeon.sh9
-rw-r--r--.gitlab/ci/env_debian12_makefiles_clang.sh2
-rw-r--r--.gitlab/ci/env_debian12_ninja.sh (renamed from .gitlab/ci/env_debian10_ninja.sh)2
-rw-r--r--.gitlab/ci/env_debian12_ninja_clang.sh2
-rw-r--r--.gitlab/ci/env_fedora38_hip_radeon.sh1
-rwxr-xr-x.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps14
-rwxr-xr-x.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps16
-rwxr-xr-x.gitlab/ci/env_windows_vs2022_x64.ps14
-rwxr-xr-x.gitlab/ci/ispc.sh4
-rwxr-xr-x.gitlab/ci/mingw-env.ps15
-rwxr-xr-x.gitlab/ci/qt-env.ps15
-rw-r--r--.gitlab/os-linux.yml104
-rw-r--r--.gitlab/os-macos.yml6
-rw-r--r--.gitlab/os-windows.yml8
-rw-r--r--Auxiliary/vim/cmake.vim.in6
-rwxr-xr-xAuxiliary/vim/extract-upper-case.pl6
-rw-r--r--Auxiliary/vim/syntax/cmake.vim863
-rw-r--r--CMakeLists.txt8
-rw-r--r--Help/command/add_custom_command.rst16
-rw-r--r--Help/command/add_custom_target.rst14
-rw-r--r--Help/command/block.rst3
-rw-r--r--Help/command/cmake_host_system_information.rst7
-rw-r--r--Help/command/cmake_policy.rst36
-rw-r--r--Help/command/exec_program.rst4
-rw-r--r--Help/command/file.rst5
-rw-r--r--Help/command/find_library.rst4
-rw-r--r--Help/command/get_property.rst13
-rw-r--r--Help/command/get_test_property.rst13
-rw-r--r--Help/command/if.rst20
-rw-r--r--Help/command/install.rst1648
-rw-r--r--Help/command/set.rst11
-rw-r--r--Help/command/set_property.rst14
-rw-r--r--Help/command/set_tests_properties.rst12
-rw-r--r--Help/command/target_link_libraries.rst6
-rw-r--r--Help/command/target_precompile_headers.rst2
-rw-r--r--Help/command/try_compile.rst29
-rw-r--r--Help/command/try_run.rst6
-rw-r--r--Help/dev/documentation.rst1
-rw-r--r--Help/dev/experimental.rst8
-rw-r--r--Help/envvar/CMAKE_CROSSCOMPILING_EMULATOR.rst11
-rw-r--r--Help/generator/Visual Studio 10 2010.rst2
-rw-r--r--Help/generator/Visual Studio 11 2012.rst59
-rw-r--r--Help/generator/Visual Studio 12 2013.rst9
-rw-r--r--Help/generator/Visual Studio 9 2008.rst2
-rw-r--r--Help/guide/tutorial/A Basic Starting Point.rst14
-rw-r--r--Help/guide/tutorial/Adding Generator Expressions.rst4
-rw-r--r--Help/guide/tutorial/Adding Usage Requirements for a Library.rst31
-rw-r--r--Help/guide/tutorial/Adding a Library.rst4
-rw-r--r--Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Selecting Static or Shared Libraries.rst13
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt2
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt7
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt5
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt4
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt3
-rw-r--r--Help/manual/cmake-env-variables.7.rst1
-rw-r--r--Help/manual/cmake-policies.7.rst9
-rw-r--r--Help/manual/cmake-properties.7.rst6
-rw-r--r--Help/manual/cmake-qt.7.rst2
-rw-r--r--Help/manual/cmake-toolchains.7.rst25
-rw-r--r--Help/manual/ctest.1.rst19
-rw-r--r--Help/policy/CMP0152.rst20
-rw-r--r--Help/policy/CMP0153.rst12
-rw-r--r--Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst4
-rw-r--r--Help/prop_test/GENERATED_RESOURCE_SPEC_FILE.rst7
-rw-r--r--Help/prop_tgt/DLL_NAME_WITH_SOVERSION.rst4
-rw-r--r--Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst14
-rw-r--r--Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst13
-rw-r--r--Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst13
-rw-r--r--Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst14
-rw-r--r--Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst11
-rw-r--r--Help/prop_tgt/IMPORTED_IMPLIB.rst6
-rw-r--r--Help/prop_tgt/IMPORTED_LOCATION.rst11
-rw-r--r--Help/prop_tgt/IMPORTED_OBJECTS.rst2
-rw-r--r--Help/prop_tgt/IOS_INSTALL_COMBINED.rst17
-rw-r--r--Help/prop_tgt/Swift_LANGUAGE_VERSION.rst5
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_COMMAND.rst2
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst2
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst2
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst2
-rw-r--r--Help/prop_tgt/VS_DOTNET_STARTUP_OBJECT.rst2
-rw-r--r--Help/prop_tgt/VS_KEYWORD.rst2
-rw-r--r--Help/prop_tgt/XCODE_EMBED_type.rst6
-rw-r--r--Help/prop_tgt/XCODE_EMBED_type_PATH.rst3
-rw-r--r--Help/release/3.14.rst3
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/CMAKE_CROSSCOMPILING_EMULATOR-env-variable.rst6
-rw-r--r--Help/release/dev/ExternalProject-build-jobserver.rst10
-rw-r--r--Help/release/dev/FindCURL-static.rst5
-rw-r--r--Help/release/dev/FindEXPAT-static.rst5
-rw-r--r--Help/release/dev/apple-visionos.rst7
-rw-r--r--Help/release/dev/command-job-server-aware.rst5
-rw-r--r--Help/release/dev/deprecate-install-combined.rst6
-rw-r--r--Help/release/dev/dynamically-generated-resource-spec-file.rst6
-rw-r--r--Help/release/dev/exec_program-policy.rst6
-rw-r--r--Help/release/dev/host-msystem-prefix.rst6
-rw-r--r--Help/release/dev/imported-implib-only.rst7
-rw-r--r--Help/release/dev/imported-target-framework-path.rst5
-rw-r--r--Help/release/dev/rel-linux-x86_64.rst5
-rw-r--r--Help/release/dev/remove-vs11-generator.rst4
-rw-r--r--Help/release/dev/test-properties-directory.rst15
-rw-r--r--Help/release/dev/vs12-deprecate.rst5
-rw-r--r--Help/release/dev/xcframework-find-library.rst5
-rw-r--r--Help/release/dev/xcframework-target-link-libraries.rst7
-rw-r--r--Help/release/dev/xcode-embed-resources.rst6
-rw-r--r--Help/release/dev/xcode-no-legacy-buildsystem.rst8
-rw-r--r--Help/release/index.rst2
-rw-r--r--Help/variable/APPLE.rst2
-rw-r--r--Help/variable/CMAKE_CFG_INTDIR.rst2
-rw-r--r--Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst4
-rw-r--r--Help/variable/CMAKE_CUDA_HOST_COMPILER.rst7
-rw-r--r--Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst3
-rw-r--r--Help/variable/CMAKE_MACOSX_BUNDLE.rst2
-rw-r--r--Help/variable/CMAKE_OSX_VARIABLE.txt2
-rw-r--r--Help/variable/CMAKE_VS_DEVENV_COMMAND.rst2
-rw-r--r--Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_BUILD_SYSTEM.rst3
-rw-r--r--Help/variable/ENV.rst11
-rw-r--r--Modules/CMakeCompilerIdDetection.cmake4
-rw-r--r--Modules/CMakeDetermineCSharpCompiler.cmake2
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake1
-rw-r--r--Modules/CMakeDetermineSystem.cmake22
-rw-r--r--Modules/CMakeFindBinUtils.cmake2
-rw-r--r--Modules/CMakeSwiftInformation.cmake6
-rw-r--r--Modules/CMakeSystemSpecificInitialize.cmake2
-rw-r--r--Modules/CheckCXXSymbolExists.cmake2
-rw-r--r--Modules/CheckLanguage.cmake47
-rw-r--r--Modules/Compiler/Clang-CXX.cmake1
-rw-r--r--Modules/Compiler/IntelLLVM.cmake7
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake1
-rw-r--r--Modules/Compiler/NVIDIA-CUDA.cmake64
-rw-r--r--Modules/Compiler/NVIDIA.cmake69
-rw-r--r--Modules/ExternalProject.cmake1801
-rw-r--r--Modules/FindBoost.cmake20
-rw-r--r--Modules/FindCUDAToolkit.cmake40
-rw-r--r--Modules/FindCURL.cmake23
-rw-r--r--Modules/FindEXPAT.cmake23
-rw-r--r--Modules/FindFLTK.cmake8
-rw-r--r--Modules/FindFLTK2.cmake4
-rw-r--r--Modules/FindFreetype.cmake58
-rw-r--r--Modules/FindGLEW.cmake4
-rw-r--r--Modules/FindGLUT.cmake55
-rw-r--r--Modules/FindLua50.cmake15
-rw-r--r--Modules/FindLua51.cmake13
-rw-r--r--Modules/FindMatlab.cmake87
-rw-r--r--Modules/FindOpenAL.cmake12
-rw-r--r--Modules/FindOpenGL.cmake26
-rw-r--r--Modules/FindPkgConfig.cmake18
-rw-r--r--Modules/FindProtobuf.cmake123
-rw-r--r--Modules/FindPython/Support.cmake69
-rw-r--r--Modules/FindQt.cmake6
-rw-r--r--Modules/Findosg.cmake6
-rw-r--r--Modules/FindosgAnimation.cmake6
-rw-r--r--Modules/FindosgFX.cmake6
-rw-r--r--Modules/FindosgGA.cmake6
-rw-r--r--Modules/FindosgIntrospection.cmake6
-rw-r--r--Modules/FindosgManipulator.cmake6
-rw-r--r--Modules/FindosgParticle.cmake6
-rw-r--r--Modules/FindosgPresentation.cmake6
-rw-r--r--Modules/FindosgProducer.cmake6
-rw-r--r--Modules/FindosgQt.cmake6
-rw-r--r--Modules/FindosgShadow.cmake6
-rw-r--r--Modules/FindosgSim.cmake6
-rw-r--r--Modules/FindosgTerrain.cmake6
-rw-r--r--Modules/FindosgText.cmake6
-rw-r--r--Modules/FindosgUtil.cmake6
-rw-r--r--Modules/FindosgViewer.cmake6
-rw-r--r--Modules/FindosgVolume.cmake6
-rw-r--r--Modules/FindosgWidget.cmake6
-rw-r--r--Modules/FindwxWidgets.cmake3
-rw-r--r--Modules/FindwxWindows.cmake13
-rw-r--r--Modules/FortranCInterface.cmake1
-rw-r--r--Modules/Internal/CPack/NSIS.template.in2
-rw-r--r--Modules/Internal/FeatureTesting.cmake1
-rw-r--r--Modules/Platform/Apple-Clang.cmake4
-rw-r--r--Modules/Platform/Darwin-Initialize.cmake4
-rw-r--r--Modules/Platform/Darwin.cmake2
-rw-r--r--Modules/Platform/Windows-MSVC.cmake24
-rw-r--r--Modules/Platform/Windows.cmake6
-rw-r--r--Modules/Platform/WindowsKernelModeDriver-Initialize.cmake11
-rw-r--r--Modules/Platform/WindowsKernelModeDriver-MSVC-C.cmake1
-rw-r--r--Modules/Platform/WindowsKernelModeDriver-MSVC-CXX.cmake1
-rw-r--r--Modules/Platform/WindowsKernelModeDriver.cmake1
-rw-r--r--Modules/Platform/visionOS-Determine-CXX.cmake1
-rw-r--r--Modules/Platform/visionOS-Initialize.cmake7
-rw-r--r--Modules/Platform/visionOS.cmake1
-rw-r--r--Modules/UsePkgConfig.cmake10
-rw-r--r--Modules/UseSWIG.cmake4
-rw-r--r--README.rst4
-rw-r--r--Source/CMakeLists.txt88
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx153
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx10
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx6
-rw-r--r--Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx12
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx11
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx17
-rw-r--r--Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx9
-rw-r--r--Source/CPack/WiX/cmWIXShortcut.cxx2
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx36
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx56
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx140
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h2
-rw-r--r--Source/CPack/cmCPackGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackInnoSetupGenerator.cxx8
-rw-r--r--Source/CPack/cmCPackNuGetGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx43
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.cxx62
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx2
-rw-r--r--Source/CPack/cpack.cxx4
-rw-r--r--Source/CTest/cmCTestBZR.cxx32
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx15
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx292
-rw-r--r--Source/CTest/cmCTestBuildHandler.h6
-rw-r--r--Source/CTest/cmCTestCVS.cxx19
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx1
-rw-r--r--Source/CTest/cmCTestConfigureHandler.cxx2
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx113
-rw-r--r--Source/CTest/cmCTestGIT.cxx131
-rw-r--r--Source/CTest/cmCTestHG.cxx36
-rw-r--r--Source/CTest/cmCTestLaunch.cxx126
-rw-r--r--Source/CTest/cmCTestLaunch.h5
-rw-r--r--Source/CTest/cmCTestLaunchReporter.cxx50
-rw-r--r--Source/CTest/cmCTestLaunchReporter.h4
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx1
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx100
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h21
-rw-r--r--Source/CTest/cmCTestP4.cxx67
-rw-r--r--Source/CTest/cmCTestP4.h2
-rw-r--r--Source/CTest/cmCTestRunTest.cxx33
-rw-r--r--Source/CTest/cmCTestRunTest.h5
-rw-r--r--Source/CTest/cmCTestSVN.cxx37
-rw-r--r--Source/CTest/cmCTestSVN.h2
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx84
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx8
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx40
-rw-r--r--Source/CTest/cmCTestTestHandler.h8
-rw-r--r--Source/CTest/cmCTestVC.cxx45
-rw-r--r--Source/CTest/cmCTestVC.h9
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx1
-rw-r--r--Source/CTest/cmProcess.cxx1
-rw-r--r--Source/Checks/Curses/CMakeLists.txt2
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx1
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx68
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h6
-rw-r--r--Source/LexerParser/cmCTestResourceGroupsLexer.cxx4
-rw-r--r--Source/LexerParser/cmCTestResourceGroupsLexer.in.l4
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.cxx105
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.y1
-rw-r--r--Source/LexerParser/cmDependsJavaParser.cxx1431
-rw-r--r--Source/LexerParser/cmDependsJavaParser.y1
-rw-r--r--Source/LexerParser/cmExprParser.cxx105
-rw-r--r--Source/LexerParser/cmExprParser.y1
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.cxx33
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.h7
-rw-r--r--Source/cmAddCustomCommandCommand.cxx11
-rw-r--r--Source/cmAddCustomTargetCommand.cxx9
-rw-r--r--Source/cmArgumentParser.h32
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx3
-rw-r--r--Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx9
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.cxx1
-rw-r--r--Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx17
-rw-r--r--Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx9
-rw-r--r--Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx9
-rw-r--r--Source/cmBlockCommand.cxx3
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx121
-rw-r--r--Source/cmCMakeLanguageCommand.cxx49
-rw-r--r--Source/cmCMakePath.cxx2
-rw-r--r--Source/cmCMakePath.h213
-rw-r--r--Source/cmCMakePresetErrors.h245
-rw-r--r--Source/cmCMakePresetsErrors.cxx305
-rw-r--r--Source/cmCMakePresetsErrors.h116
-rw-r--r--Source/cmCMakePresetsGraph.cxx91
-rw-r--r--Source/cmCMakePresetsGraph.h4
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx114
-rw-r--r--Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx12
-rw-r--r--Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx33
-rw-r--r--Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx13
-rw-r--r--Source/cmCMakePresetsGraphReadJSONTestPresets.cxx29
-rw-r--r--Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx15
-rw-r--r--Source/cmCPackPropertiesGenerator.cxx1
-rw-r--r--Source/cmCPluginAPI.cxx4
-rw-r--r--Source/cmCTest.cxx430
-rw-r--r--Source/cmCTest.h16
-rw-r--r--Source/cmCacheManager.cxx7
-rw-r--r--Source/cmCacheManager.h4
-rw-r--r--Source/cmCallVisualStudioMacro.cxx4
-rw-r--r--Source/cmCommands.cxx4
-rw-r--r--Source/cmCommonTargetGenerator.cxx9
-rw-r--r--Source/cmComputeLinkDepends.cxx1
-rw-r--r--Source/cmComputeLinkInformation.cxx150
-rw-r--r--Source/cmComputeLinkInformation.h8
-rw-r--r--Source/cmConditionEvaluator.h2
-rw-r--r--Source/cmCoreTryCompile.cxx207
-rw-r--r--Source/cmCoreTryCompile.h33
-rw-r--r--Source/cmCustomCommand.cxx10
-rw-r--r--Source/cmCustomCommand.h6
-rw-r--r--Source/cmCxxModuleMapper.cxx105
-rw-r--r--Source/cmCxxModuleMapper.h3
-rw-r--r--Source/cmCxxModuleUsageEffects.cxx21
-rw-r--r--Source/cmCxxModuleUsageEffects.h22
-rw-r--r--Source/cmDebuggerAdapter.h2
-rw-r--r--Source/cmDebuggerBreakpointManager.cxx1
-rw-r--r--Source/cmDebuggerBreakpointManager.h6
-rw-r--r--Source/cmDebuggerExceptionManager.h3
-rw-r--r--Source/cmDebuggerPipeConnection.cxx293
-rw-r--r--Source/cmDebuggerPipeConnection.h139
-rw-r--r--Source/cmDebuggerPosixPipeConnection.cxx205
-rw-r--r--Source/cmDebuggerPosixPipeConnection.h81
-rw-r--r--Source/cmDebuggerProtocol.h2
-rw-r--r--Source/cmDebuggerVariablesHelper.cxx15
-rw-r--r--Source/cmDebuggerVariablesManager.h9
-rw-r--r--Source/cmDebuggerWindowsPipeConnection.cxx287
-rw-r--r--Source/cmDebuggerWindowsPipeConnection.h103
-rw-r--r--Source/cmDefinitions.cxx1
-rw-r--r--Source/cmDefinitions.h1
-rw-r--r--Source/cmDependsCompiler.cxx1
-rw-r--r--Source/cmDependsFortran.cxx1
-rw-r--r--Source/cmDocumentationFormatter.cxx2
-rw-r--r--Source/cmDocumentationFormatter.h1
-rw-r--r--Source/cmDyndepCollation.cxx53
-rw-r--r--Source/cmDyndepCollation.h5
-rw-r--r--Source/cmExecuteProcessCommand.cxx385
-rw-r--r--Source/cmExperimental.cxx34
-rw-r--r--Source/cmExperimental.h23
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx1
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.h1
-rw-r--r--Source/cmExportBuildFileGenerator.cxx16
-rw-r--r--Source/cmExportCommand.cxx4
-rw-r--r--Source/cmExportFileGenerator.cxx80
-rw-r--r--Source/cmExportFileGenerator.h3
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.h1
-rw-r--r--Source/cmExportInstallFileGenerator.cxx37
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx1
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx6
-rw-r--r--Source/cmFileAPI.cxx1
-rw-r--r--Source/cmFileAPICodemodel.cxx2
-rw-r--r--Source/cmFileCommand.cxx77
-rw-r--r--Source/cmFileLock.cxx12
-rw-r--r--Source/cmFileLock.h6
-rw-r--r--Source/cmFileLockResult.cxx4
-rw-r--r--Source/cmFileLockResult.h8
-rw-r--r--Source/cmFileLockWin32.cxx2
-rw-r--r--Source/cmFileSet.cxx7
-rw-r--r--Source/cmFileSet.h2
-rw-r--r--Source/cmFileTime.cxx1
-rw-r--r--Source/cmFindBase.cxx1
-rw-r--r--Source/cmFindLibraryCommand.cxx26
-rw-r--r--Source/cmFindPackageCommand.cxx1
-rw-r--r--Source/cmFunctionCommand.cxx5
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx1
-rw-r--r--Source/cmGeneratedFileStream.cxx7
-rw-r--r--Source/cmGeneratedFileStream.h10
-rw-r--r--Source/cmGeneratorExpressionNode.cxx14
-rw-r--r--Source/cmGeneratorExpressionParser.h3
-rw-r--r--Source/cmGeneratorTarget.cxx258
-rw-r--r--Source/cmGeneratorTarget.h24
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx4
-rw-r--r--Source/cmGetPropertyCommand.cxx32
-rw-r--r--Source/cmGetTestPropertyCommand.cxx27
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx1
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h2
-rw-r--r--Source/cmGlobalGenerator.cxx141
-rw-r--r--Source/cmGlobalGenerator.h19
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx2
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx3
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h2
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx6
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx3
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h9
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx46
-rw-r--r--Source/cmGlobalNinjaGenerator.h19
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx499
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx180
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h9
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx58
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx45
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx16
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx76
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx32
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx13
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx54
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h7
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx153
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx5
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx503
-rw-r--r--Source/cmGlobalXCodeGenerator.h4
-rw-r--r--Source/cmImportedCxxModuleInfo.cxx76
-rw-r--r--Source/cmImportedCxxModuleInfo.h37
-rw-r--r--Source/cmIncludeGuardCommand.cxx13
-rw-r--r--Source/cmInstallCxxModuleBmiGenerator.cxx1
-rw-r--r--Source/cmInstallCxxModuleBmiGenerator.h1
-rw-r--r--Source/cmInstallDirectoryGenerator.h1
-rw-r--r--Source/cmInstallExportGenerator.cxx7
-rw-r--r--Source/cmInstallExportGenerator.h1
-rw-r--r--Source/cmInstallFileSetGenerator.h1
-rw-r--r--Source/cmInstallFilesGenerator.h1
-rw-r--r--Source/cmInstallGetRuntimeDependenciesGenerator.cxx1
-rw-r--r--Source/cmInstallGetRuntimeDependenciesGenerator.h1
-rw-r--r--Source/cmInstallImportedRuntimeArtifactsGenerator.h1
-rw-r--r--Source/cmInstallRuntimeDependencySetGenerator.h1
-rw-r--r--Source/cmInstallScriptGenerator.h1
-rw-r--r--Source/cmInstallTargetGenerator.cxx1
-rw-r--r--Source/cmInstallTargetGenerator.h1
-rw-r--r--Source/cmInstalledFile.h3
-rw-r--r--Source/cmJSONHelpers.cxx113
-rw-r--r--Source/cmJSONHelpers.h114
-rw-r--r--Source/cmJSONState.cxx3
-rw-r--r--Source/cmJSONState.h1
-rw-r--r--Source/cmLDConfigLDConfigTool.cxx9
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx3
-rw-r--r--Source/cmLinkLineComputer.cxx3
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx1
-rw-r--r--Source/cmList.cxx6
-rw-r--r--Source/cmList.h21
-rw-r--r--Source/cmLocalGenerator.cxx87
-rw-r--r--Source/cmLocalGenerator.h17
-rw-r--r--Source/cmLocalNinjaGenerator.cxx5
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx9
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx47
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx3
-rw-r--r--Source/cmLocalXCodeGenerator.cxx8
-rw-r--r--Source/cmMachO.cxx2
-rw-r--r--Source/cmMacroCommand.cxx6
-rw-r--r--Source/cmMakefile.cxx97
-rw-r--r--Source/cmMakefile.h13
-rw-r--r--Source/cmMakefileProfilingData.cxx1
-rw-r--r--Source/cmMakefileTargetGenerator.cxx20
-rw-r--r--Source/cmMessenger.cxx1
-rw-r--r--Source/cmMessenger.h2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx110
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h3
-rw-r--r--Source/cmNinjaTargetGenerator.cxx226
-rw-r--r--Source/cmNinjaTargetGenerator.h12
-rw-r--r--Source/cmOrderDirectories.cxx1
-rw-r--r--Source/cmOutputConverter.cxx1
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx1
-rw-r--r--Source/cmParseArgumentsCommand.cxx17
-rw-r--r--Source/cmPlistParser.cxx33
-rw-r--r--Source/cmPlistParser.h13
-rw-r--r--Source/cmPolicies.cxx160
-rw-r--r--Source/cmPolicies.h8
-rw-r--r--Source/cmProcessTools.cxx82
-rw-r--r--Source/cmProcessTools.h8
-rw-r--r--Source/cmProjectCommand.cxx1
-rw-r--r--Source/cmPropertyMap.cxx4
-rw-r--r--Source/cmPropertyMap.h2
-rw-r--r--Source/cmQtAutoGenerator.cxx2
-rw-r--r--Source/cmQtAutoMocUic.cxx3
-rw-r--r--Source/cmQtAutoRcc.cxx1
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx3
-rw-r--r--Source/cmSetCommand.cxx20
-rw-r--r--Source/cmSetPropertyCommand.cxx90
-rw-r--r--Source/cmSetPropertyCommand.h12
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx30
-rw-r--r--Source/cmSourceFile.cxx7
-rw-r--r--Source/cmSourceFile.h3
-rw-r--r--Source/cmSourceGroupCommand.cxx23
-rw-r--r--Source/cmStandardLevelResolver.cxx157
-rw-r--r--Source/cmStandardLevelResolver.h3
-rw-r--r--Source/cmState.cxx8
-rw-r--r--Source/cmState.h1
-rw-r--r--Source/cmStateDirectory.cxx24
-rw-r--r--Source/cmStateSnapshot.cxx1
-rw-r--r--Source/cmStateSnapshot.h1
-rw-r--r--Source/cmString.hxx5
-rw-r--r--Source/cmSyntheticTargetCache.h15
-rw-r--r--Source/cmSystemTools.cxx386
-rw-r--r--Source/cmSystemTools.h41
-rw-r--r--Source/cmTarget.cxx314
-rw-r--r--Source/cmTarget.h15
-rw-r--r--Source/cmTargetCompileFeaturesCommand.cxx3
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx3
-rw-r--r--Source/cmTargetLinkDirectoriesCommand.cxx3
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx1
-rw-r--r--Source/cmTargetLinkOptionsCommand.cxx3
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx3
-rw-r--r--Source/cmTargetSourcesCommand.cxx2
-rw-r--r--Source/cmTransformDepfile.cxx1
-rw-r--r--Source/cmUVHandlePtr.cxx3
-rw-r--r--Source/cmUVProcessChain.cxx254
-rw-r--r--Source/cmUVProcessChain.h14
-rw-r--r--Source/cmUVStream.h154
-rw-r--r--Source/cmUVStreambuf.h3
-rw-r--r--Source/cmUuid.cxx10
-rw-r--r--Source/cmVSSetupHelper.cxx11
-rw-r--r--Source/cmValue.h1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx619
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx50
-rw-r--r--Source/cmVisualStudioSlnData.cxx4
-rw-r--r--Source/cmVisualStudioSlnParser.cxx59
-rw-r--r--Source/cmVisualStudioWCEPlatformParser.cxx28
-rw-r--r--Source/cmWindowsRegistry.cxx1
-rw-r--r--Source/cmWindowsRegistry.h1
-rw-r--r--Source/cmXCode21Object.cxx4
-rw-r--r--Source/cmXCodeObject.cxx12
-rw-r--r--Source/cmXCodeObject.h2
-rw-r--r--Source/cmXCodeScheme.cxx7
-rw-r--r--Source/cmXcFramework.cxx209
-rw-r--r--Source/cmXcFramework.h52
-rw-r--r--Source/cm_codecvt.cxx14
-rw-r--r--Source/cm_codecvt.hxx13
-rw-r--r--Source/cm_codecvt_Encoding.hxx12
-rw-r--r--Source/cm_fileno.cxx15
-rw-r--r--Source/cm_fileno.hxx7
-rw-r--r--Source/cmake.cxx42
-rw-r--r--Source/cmake.h4
-rw-r--r--Source/cmcmd.cxx140
-rw-r--r--Source/kwsys/CMakeLists.txt38
-rw-r--r--Source/kwsys/SystemInformation.cxx16
-rw-r--r--Tests/CMakeLib/CMakeLists.txt14
-rw-r--r--Tests/CMakeLib/testCMExtAlgorithm.cxx1
-rw-r--r--Tests/CMakeLib/testCMakePath.cxx441
-rw-r--r--Tests/CMakeLib/testDebuggerAdapterPipe.cxx6
-rw-r--r--Tests/CMakeLib/testDebuggerNamedPipe.cxx9
-rw-r--r--Tests/CMakeLib/testEncoding.cxx1
-rw-r--r--Tests/CMakeLib/testGccDepfileReader.cxx1
-rw-r--r--Tests/CMakeLib/testList.cxx1
-rw-r--r--Tests/CMakeLib/testOptional.cxx1
-rw-r--r--Tests/CMakeLib/testString.cxx2
-rw-r--r--Tests/CMakeLib/testUTF8.cxx107
-rw-r--r--Tests/CMakeLib/testUVProcessChain.cxx368
-rw-r--r--Tests/CMakeLib/testUVProcessChainHelper.cxx8
-rw-r--r--Tests/CMakeLib/testUVStreambuf.cxx151
-rw-r--r--Tests/CMakeLists.txt83
-rw-r--r--Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt6
-rw-r--r--Tests/CTestTestFailure/CMakeLists.txt8
-rw-r--r--Tests/CTestTestFailure/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestFailure/testNoBuild.cmake.in23
-rw-r--r--Tests/CTestTestFailure/testNoExe.cmake.in21
-rw-r--r--Tests/CommandLineTest/CMakeLists.txt68
-rw-r--r--Tests/Complex/CMakeLists.txt6
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt6
-rw-r--r--Tests/Cuda/CMakeLists.txt1
-rw-r--r--Tests/Cuda/StubRPATH/CMakeLists.txt21
-rw-r--r--Tests/Cuda/StubRPATH/main.cxx17
-rw-r--r--Tests/ExternalOBJ/CMakeLists.txt2
-rw-r--r--Tests/ExternalOBJ/Object/CMakeLists.txt2
-rw-r--r--Tests/FindPython/ArtifactsInteractive/CMakeLists.txt6
-rw-r--r--Tests/FindPython/CMakeLists.txt620
-rw-r--r--Tests/FindPython/CustomFailureMessage/CMakeLists.txt2
-rw-r--r--Tests/FindPython/IronPython3/CMakeLists.txt31
-rw-r--r--Tests/FindPython/MultiplePackages/CMakeLists.txt52
-rw-r--r--Tests/FindPython/NumPy/CMakeLists.txt37
-rw-r--r--Tests/FindPython/NumPyOnly/CMakeLists.txt20
-rw-r--r--Tests/FindPython/RequiredArtifacts/CMakeLists.txt27
-rw-r--r--Tests/FindPython/SOABI/CMakeLists.txt51
-rw-r--r--Tests/FindPython/VirtualEnv/CMakeLists.txt26
-rw-r--r--Tests/FindPython/VirtualEnvConda/CMakeLists.txt26
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt21
-rw-r--r--Tests/GeneratorExpression/check-part3.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/FortranInclude.cmake5
-rw-r--r--Tests/RunCMake/CMP0111/CMP0111-Common.cmake3
-rw-r--r--Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt19
-rw-r--r--Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt32
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt11
-rw-r--r--Tests/RunCMake/CMP0116/CMP0116-Mixed-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0116/CMP0116-OLD-WARN-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test1-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test10-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test11-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test12-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test13-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test14-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test15-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test2-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test3-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test3b-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test4-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test4b-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test5-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test6-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test7-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test8-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/CMP0118-OLD-Test9-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0118/GenInSubdir-OLD-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0119/CMP0119-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-Common.cmake5
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt (renamed from Tests/RunCMake/CommandLine/DeprecateVS11-WARN-OFF.cmake)0
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt0
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt27
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0152/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0152/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-NEW-stderr.txt3
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-NEW-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-OLD-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-WARN-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-WARN-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0153/CMP0153-WARN.cmake1
-rw-r--r--Tests/RunCMake/CMP0153/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0153/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/CMakeLists.txt37
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt3
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-stderr.txt3
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures.cmake11
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular.cmake12
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec.cmake10
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-stdout.txt24
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators.cmake11
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures.cmake10
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture.cmake9
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture.cmake9
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stderr.txt7
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stdout.txt5
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile.cmake10
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stderr.txt14
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stdout.txt4
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough.cmake10
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path.cmake10
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resource.cmake10
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/dynamic-resspec.json16
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/resource-common.cmake (renamed from Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake)0
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/test.cmake.in12
-rw-r--r--Tests/RunCMake/CXXModules/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX-stderr.txt12
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20-stderr.txt14
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt12
-rw-r--r--Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt8
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake30
-rw-r--r--Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake2
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt8
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt4
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt110
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx10
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt69
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt4
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt114
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx10
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt69
-rw-r--r--Tests/RunCMake/CXXModules/examples/generated-stderr.txt2
-rw-r--r--Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt12
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt7
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt7
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt7
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt7
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt7
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt7
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt24
-rw-r--r--Tests/RunCMake/CXXModules/examples/import-modules/use.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt4
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt19
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run-stderr.txt4
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt23
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run/main.cxx6
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON-stderr.txt5
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS12-WARN-OFF.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON-stderr.txt5
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator-stdout.txt2
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator.cmake6
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake18
-rw-r--r--Tests/RunCMake/DependencyGraph/bottom.c7
-rw-r--r--Tests/RunCMake/DependencyGraph/middle.c9
-rw-r--r--Tests/RunCMake/DependencyGraph/neverbuild.c1
-rw-r--r--Tests/RunCMake/DependencyGraph/top.c9
-rw-r--r--Tests/RunCMake/ExternalProject/DetectJobServer.cmake16
-rw-r--r--Tests/RunCMake/ExternalProject/Foo/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake16
-rw-r--r--Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake16
-rw-r--r--Tests/RunCMake/ExternalProject/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json41
-rw-r--r--Tests/RunCMake/FileAPI/include_test.cmake2
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt3
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-stdout.txt4
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH.cmake (renamed from Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake)8
-rw-r--r--Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/Framework/FrameworkConsumption.cmake4
-rw-r--r--Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake12
-rw-r--r--Tests/RunCMake/Framework/ImportedFrameworkConsumption.cmake7
-rw-r--r--Tests/RunCMake/Framework/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1.cmake1
-rw-r--r--Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/Make/DetectJobServer-present.cmake13
-rw-r--r--Tests/RunCMake/Make/Foo/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/Make/GNUMakeJobServerAware-check.cmake18
-rw-r--r--Tests/RunCMake/Make/GNUMakeJobServerAware.cmake31
-rw-r--r--Tests/RunCMake/Make/RunCMakeTest.cmake19
-rw-r--r--Tests/RunCMake/Ninja/QtAutoMocDeps-stderr.txt8
-rw-r--r--Tests/RunCMake/RunCMake.cmake12
-rw-r--r--Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/UseSWIG/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-Direct-stderr.txt10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/XcFramework/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/XcFramework/RunCMakeTest.cmake107
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-framework-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-result.txt1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-stderr.txt11
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-incomplete-result.txt1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-incomplete-stderr.txt10
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-incomplete.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-library-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-link-phase.cmake2
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-framework-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-result.txt1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-stderr.txt11
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-incomplete-result.txt1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-incomplete-stderr.txt10
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-incomplete.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-library-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target-link-phase.cmake2
-rw-r--r--Tests/RunCMake/XcFramework/create-executable-target.cmake21
-rw-r--r--Tests/RunCMake/XcFramework/create-executable.cmake18
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-framework.cmake3
-rw-r--r--Tests/RunCMake/XcFramework/create-library-common.cmake12
-rw-r--r--Tests/RunCMake/XcFramework/create-library-ios-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-ios.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-macos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-tvos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-tvos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-visionos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-visionos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-watchos-simulator.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library-watchos.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/create-library.cmake1
-rw-r--r--Tests/RunCMake/XcFramework/find-library.cmake5
-rw-r--r--Tests/RunCMake/XcFramework/myexe/myexe.c7
-rw-r--r--Tests/RunCMake/XcFramework/mylib/include/mylib/mylib.h3
-rw-r--r--Tests/RunCMake/XcFramework/mylib/mylib.c3
-rw-r--r--Tests/RunCMake/XcodeProject-Device/DeploymentTarget.c4
-rw-r--r--Tests/RunCMake/XcodeProject-Device/DeploymentTarget.cmake6
-rw-r--r--Tests/RunCMake/XcodeProject-Device/RunCMakeTest.cmake29
-rw-r--r--Tests/RunCMake/XcodeProject-Device/XcodeBundles.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns-macOS-check.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS-check.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS-check.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/EmbedResources.cmake18
-rw-r--r--Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake3
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt3
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake2
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt2
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/ctest_build/BuildFailure.cxx (renamed from Tests/CTestTestFailure/badCode.cxx)0
-rw-r--r--Tests/RunCMake/ctest_build/RunCMakeTest.cmake21
-rw-r--r--Tests/RunCMake/ctest_test/NotRun-result.txt1
-rw-r--r--Tests/RunCMake/ctest_test/NotRun-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_test/NotRun-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_test/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatNotRun-stderr.txt3
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatNotRun-stdout.txt4
-rw-r--r--Tests/RunCMake/detect_jobserver.c179
-rw-r--r--Tests/RunCMake/execute_process/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/execute_process/Stdin-stdin.txt1
-rw-r--r--Tests/RunCMake/execute_process/Stdin-stdout.txt1
-rw-r--r--Tests/RunCMake/execute_process/Stdin.cmake1
-rw-r--r--Tests/RunCMake/file/REAL_PATH.cmake37
-rw-r--r--Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt2
-rw-r--r--Tests/RunCMake/find_library/FromScriptMode-stderr.txt2
-rw-r--r--Tests/RunCMake/get_property/test_properties-stderr.txt10
-rw-r--r--Tests/RunCMake/get_property/test_properties.cmake19
-rw-r--r--Tests/RunCMake/get_property/test_properties/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/property_init/Always.cmake15
-rw-r--r--Tests/RunCMake/property_init/CMakeLists.txt9
-rw-r--r--Tests/RunCMake/property_init/CompileSources.cmake274
-rw-r--r--Tests/RunCMake/property_init/Executable.cmake25
-rw-r--r--Tests/RunCMake/property_init/ImportedTargets.cmake9
-rw-r--r--Tests/RunCMake/property_init/LibraryArtifact.cmake10
-rw-r--r--Tests/RunCMake/property_init/Linkable.cmake12
-rw-r--r--Tests/RunCMake/property_init/NonImportedNormalTarget.cmake9
-rw-r--r--Tests/RunCMake/property_init/NonImportedTarget.cmake11
-rw-r--r--Tests/RunCMake/property_init/NormalTarget.cmake10
-rw-r--r--Tests/RunCMake/property_init/PICTargets.cmake21
-rw-r--r--Tests/RunCMake/property_init/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/property_init/SharedLibrary.cmake12
-rw-r--r--Tests/RunCMake/property_init/TargetsWithArtifact.cmake19
-rw-r--r--Tests/RunCMake/property_init/TargetsWithCommands.cmake13
-rw-r--r--Tests/RunCMake/property_init/TargetsWithExports.cmake51
-rw-r--r--Tests/RunCMake/property_init/library.c4
-rw-r--r--Tests/RunCMake/property_init/main.c4
-rw-r--r--Tests/RunCMake/property_init/util.cmake191
-rw-r--r--Tests/RunCMake/set/CacheErrors-result.txt1
-rw-r--r--Tests/RunCMake/set/CacheErrors-stderr.txt19
-rw-r--r--Tests/RunCMake/set/CacheErrors.cmake4
-rw-r--r--Tests/RunCMake/set/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/set_property/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/set_property/TEST-invalid-result.txt1
-rw-r--r--Tests/RunCMake/set_property/TEST-invalid-stderr.txt11
-rw-r--r--Tests/RunCMake/set_property/TEST-invalid.cmake4
-rw-r--r--Tests/RunCMake/set_property/TEST-subdir1/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/set_property/TEST-subdir2/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/set_property/TEST.cmake9
-rw-r--r--Tests/RunCMake/set_tests_properties/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-result.txt1
-rw-r--r--Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-stderr.txt13
-rw-r--r--Tests/RunCMake/set_tests_properties/DIRECTORY-invalid.cmake4
-rw-r--r--Tests/RunCMake/set_tests_properties/DIRECTORY-subdir1/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/set_tests_properties/DIRECTORY-subdir2/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/set_tests_properties/DIRECTORY.cmake9
-rw-r--r--Tests/RunCMake/set_tests_properties/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake2
-rw-r--r--Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirExport.cmake16
-rw-r--r--Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirImport.cmake9
-rw-r--r--Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake2
-rw-r--r--Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake2
-rw-r--r--Tests/RunCMake/target_sources/RunCMakeTest.cmake1
-rw-r--r--Tests/SourceGroups/CMakeLists.txt2
-rw-r--r--Tests/SourceGroups/sub2/CMakeLists.txt4
-rw-r--r--Tests/SourceGroups/sub2/main.c11
-rw-r--r--Tests/SourceGroups/sub2/qux.c4
-rw-r--r--Tests/SourceGroups/sub2/subsub/qax.c4
-rw-r--r--Tests/UseSWIG/AlternateLibraryName/CMakeLists.txt6
-rw-r--r--Tests/UseSWIG/CMakeLists.txt44
-rw-r--r--Tests/UseSWIG/ModuleName/CMakeLists.txt15
-rw-r--r--Tests/UseSWIG/ModuleVersion2/CMakeLists.txt98
-rw-r--r--Tests/UseSWIG/MultipleFiles/CMakeLists.txt4
-rw-r--r--Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt6
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/IWYU/mapping.imp78
-rw-r--r--Utilities/Release/linux/x86_64/Dockerfile7
-rw-r--r--Utilities/Release/linux/x86_64/base/Dockerfile11
-rw-r--r--Utilities/Release/linux/x86_64/deps/Dockerfile26
-rw-r--r--Utilities/Release/linux/x86_64/test/Dockerfile4
-rw-r--r--Utilities/Release/win/qt-5.15.10-win-x86-msvc-install.patch (renamed from Utilities/Release/win/qt-5.12.1-win-x86-msvc-install.patch)20
-rwxr-xr-xUtilities/Release/win/qt-5.15.10-win-x86-msvc.ps1 (renamed from Utilities/Release/win/qt-5.12.1-win-x86-msvc.ps1)17
-rwxr-xr-xUtilities/Scripts/update-curl.bash2
-rwxr-xr-xUtilities/Scripts/update-libuv.bash4
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
-rw-r--r--Utilities/cmbzip2/CMakeLists.txt4
-rw-r--r--Utilities/cmcppdap/CMakeLists.txt4
-rw-r--r--Utilities/cmcurl/CMake/FindNGTCP2.cmake4
-rw-r--r--Utilities/cmcurl/CMakeLists.txt10
-rw-r--r--Utilities/cmcurl/include/curl/curl.h16
-rw-r--r--Utilities/cmcurl/include/curl/curlver.h8
-rw-r--r--Utilities/cmcurl/include/curl/system.h47
-rw-r--r--Utilities/cmcurl/include/curl/typecheck-gcc.h1
-rw-r--r--Utilities/cmcurl/include/curl/websockets.h12
-rw-r--r--Utilities/cmcurl/lib/CMakeLists.txt23
-rw-r--r--Utilities/cmcurl/lib/Makefile.inc3
-rw-r--r--Utilities/cmcurl/lib/altsvc.c5
-rw-r--r--Utilities/cmcurl/lib/amigaos.c1
-rw-r--r--Utilities/cmcurl/lib/base64.c6
-rw-r--r--Utilities/cmcurl/lib/bufq.c29
-rw-r--r--Utilities/cmcurl/lib/c-hyper.c11
-rw-r--r--Utilities/cmcurl/lib/cf-h1-proxy.c124
-rw-r--r--Utilities/cmcurl/lib/cf-h2-proxy.c531
-rw-r--r--Utilities/cmcurl/lib/cf-haproxy.c11
-rw-r--r--Utilities/cmcurl/lib/cf-https-connect.c12
-rw-r--r--Utilities/cmcurl/lib/cf-socket.c77
-rw-r--r--Utilities/cmcurl/lib/cfilters.c14
-rw-r--r--Utilities/cmcurl/lib/cfilters.h4
-rw-r--r--Utilities/cmcurl/lib/conncache.h3
-rw-r--r--Utilities/cmcurl/lib/connect.c6
-rw-r--r--Utilities/cmcurl/lib/cookie.c9
-rw-r--r--Utilities/cmcurl/lib/curl_config.h.cmake6
-rw-r--r--Utilities/cmcurl/lib/curl_log.c6
-rw-r--r--Utilities/cmcurl/lib/curl_log.h31
-rw-r--r--Utilities/cmcurl/lib/curl_memory.h58
-rw-r--r--Utilities/cmcurl/lib/curl_printf.h1
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.c18
-rw-r--r--Utilities/cmcurl/lib/curl_setup.h3
-rw-r--r--Utilities/cmcurl/lib/curl_setup_once.h6
-rw-r--r--Utilities/cmcurl/lib/dynbuf.h2
-rw-r--r--Utilities/cmcurl/lib/easy.c18
-rw-r--r--Utilities/cmcurl/lib/easy_lock.h4
-rw-r--r--Utilities/cmcurl/lib/easyoptions.c7
-rw-r--r--Utilities/cmcurl/lib/fopen.c14
-rw-r--r--Utilities/cmcurl/lib/ftp.c130
-rw-r--r--Utilities/cmcurl/lib/getinfo.c7
-rw-r--r--Utilities/cmcurl/lib/hostip.c30
-rw-r--r--Utilities/cmcurl/lib/hsts.c5
-rw-r--r--Utilities/cmcurl/lib/http.c32
-rw-r--r--Utilities/cmcurl/lib/http1.c129
-rw-r--r--Utilities/cmcurl/lib/http1.h4
-rw-r--r--Utilities/cmcurl/lib/http2.c332
-rw-r--r--Utilities/cmcurl/lib/http_proxy.c4
-rw-r--r--Utilities/cmcurl/lib/imap.c96
-rw-r--r--Utilities/cmcurl/lib/krb5.c2
-rw-r--r--Utilities/cmcurl/lib/ldap.c8
-rw-r--r--Utilities/cmcurl/lib/macos.c62
-rw-r--r--Utilities/cmcurl/lib/macos.h38
-rw-r--r--Utilities/cmcurl/lib/mime.c16
-rw-r--r--Utilities/cmcurl/lib/mqtt.c2
-rw-r--r--Utilities/cmcurl/lib/multi.c57
-rw-r--r--Utilities/cmcurl/lib/pop3.c44
-rw-r--r--Utilities/cmcurl/lib/sendf.c2
-rw-r--r--Utilities/cmcurl/lib/setopt.c11
-rw-r--r--Utilities/cmcurl/lib/smb.c195
-rw-r--r--Utilities/cmcurl/lib/smb.h197
-rw-r--r--Utilities/cmcurl/lib/smtp.c44
-rw-r--r--Utilities/cmcurl/lib/socks.c19
-rw-r--r--Utilities/cmcurl/lib/telnet.c5
-rw-r--r--Utilities/cmcurl/lib/timeval.c16
-rw-r--r--Utilities/cmcurl/lib/transfer.c16
-rw-r--r--Utilities/cmcurl/lib/url.c38
-rw-r--r--Utilities/cmcurl/lib/urlapi.c93
-rw-r--r--Utilities/cmcurl/lib/urldata.h16
-rw-r--r--Utilities/cmcurl/lib/version.c4
-rw-r--r--Utilities/cmcurl/lib/vquic/curl_msh3.c5
-rw-r--r--Utilities/cmcurl/lib/vquic/curl_ngtcp2.c429
-rw-r--r--Utilities/cmcurl/lib/vquic/curl_quiche.c52
-rw-r--r--Utilities/cmcurl/lib/vquic/vquic.c6
-rw-r--r--Utilities/cmcurl/lib/vssh/libssh2.c26
-rw-r--r--Utilities/cmcurl/lib/vssh/wolfssh.c2
-rw-r--r--Utilities/cmcurl/lib/vtls/bearssl.c32
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.c14
-rw-r--r--Utilities/cmcurl/lib/vtls/gtls.c42
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls.c32
-rw-r--r--Utilities/cmcurl/lib/vtls/nss.c81
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c81
-rw-r--r--Utilities/cmcurl/lib/vtls/rustls.c34
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.c64
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.h116
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel_int.h142
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel_verify.c4
-rw-r--r--Utilities/cmcurl/lib/vtls/sectransp.c43
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.c27
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls_int.h3
-rw-r--r--Utilities/cmcurl/lib/vtls/wolfssl.c73
-rw-r--r--Utilities/cmcurl/lib/warnless.c10
-rw-r--r--Utilities/cmcurl/lib/warnless.h10
-rw-r--r--Utilities/cmcurl/lib/ws.c56
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt4
-rw-r--r--Utilities/cmliblzma/CMakeLists.txt4
-rw-r--r--Utilities/cmlibuv/CMakeLists.txt28
-rw-r--r--Utilities/cmlibuv/src/unix/process.c4
-rw-r--r--Utilities/cmlibuv/src/win/process.c29
-rw-r--r--Utilities/std/cmext/algorithm9
-rw-r--r--Utilities/std/cmext/iterator15
-rwxr-xr-xbootstrap63
-rw-r--r--cmake_uninstall.cmake.in6
1128 files changed, 21319 insertions, 10824 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 297afda..7a66494 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -96,9 +96,9 @@ l:codespell:
- .linux_x86_64_tags
- .run_automatically
-l:iwyu-debian10:
+l:iwyu-debian12:
extends:
- - .debian10_iwyu
+ - .debian12_iwyu
- .cmake_build_linux
- .linux_x86_64_tags
- .run_automatically
@@ -132,7 +132,7 @@ l:clang-analyzer-fedora38:
# Linux builds
-b:centos6-x86_64:
+b:centos7-x86_64:
extends:
- .linux_release_x86_64
- .cmake_build_linux_release
@@ -140,7 +140,7 @@ b:centos6-x86_64:
- .linux_x86_64_tags
- .run_manually
variables:
- CMAKE_CI_ARTIFACTS_NAME: "artifacts-centos6-x86_64"
+ CMAKE_CI_ARTIFACTS_NAME: "artifacts-centos7-x86_64"
b:centos7-aarch64:
extends:
@@ -153,20 +153,20 @@ b:centos7-aarch64:
CMAKE_CI_ARTIFACTS_NAME: "artifacts-centos7-aarch64"
CMAKE_CI_NO_MR: "true"
-t:debian10-ninja:
+t:debian12-ninja:
extends:
- - .debian10_ninja
+ - .debian12_ninja
- .cmake_test_linux_release
- .linux_x86_64_tags
- .cmake_junit_artifacts
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY_NINJA: "true"
-t:debian10-aarch64-ninja:
+t:debian12-aarch64-ninja:
extends:
- - .debian10_aarch64_ninja
+ - .debian12_aarch64_ninja
- .cmake_test_linux_release
- .linux_aarch64_tags
- .cmake_junit_artifacts
@@ -175,33 +175,53 @@ t:debian10-aarch64-ninja:
variables:
CMAKE_CI_NO_MR: "true"
-t:debian10-ninja-clang:
+t:debian12-ninja-clang:
extends:
- - .debian10_ninja_clang
+ - .debian12_ninja_clang
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-t:debian10-makefiles-clang:
+t:debian12-makefiles-clang:
extends:
- - .debian10_makefiles_clang
+ - .debian12_makefiles_clang
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
+t:debian12-hip-radeon:
+ extends:
+ - .debian12_hip_radeon
+ - .cmake_test_linux_release
+ - .linux_x86_64_tags_radeon
+ - .run_dependent
+ - .needs_centos7_x86_64
+ variables:
+ CMAKE_CI_NO_MR: "true"
+
+t:fedora38-hip-radeon:
+ extends:
+ - .fedora38_hip_radeon
+ - .cmake_test_linux_release
+ - .linux_x86_64_tags_radeon
+ - .run_dependent
+ - .needs_centos7_x86_64
+ variables:
+ CMAKE_CI_NO_MR: "true"
+
t:fedora38-ninja-clang:
extends:
- .fedora38_ninja_clang
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -211,7 +231,7 @@ t:fedora38-ninja-multi-clang:
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -221,7 +241,7 @@ t:fedora38-makefiles-clang:
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -231,7 +251,7 @@ t:fedora38-makefiles:
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
t:fedora38-makefiles-nospace:
extends:
@@ -240,7 +260,7 @@ t:fedora38-makefiles-nospace:
- .linux_x86_64_tags
- .cmake_junit_artifacts
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
CMAKE_CI_BUILD_NAME: fedora38_makefiles_nospace
@@ -252,7 +272,7 @@ t:nvhpc22.11-ninja:
- .cmake_test_linux_release
- .linux_x86_64_v3_tags_cuda
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -262,7 +282,7 @@ t:cuda9.2-nvidia:
- .cmake_test_linux_release
- .linux_x86_64_tags_cuda
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_NO_MR: "true"
@@ -273,7 +293,7 @@ t:cuda10.2-nvidia:
- .linux_x86_64_tags_cuda
- .cmake_junit_artifacts
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
t:cuda10.2-clang:
extends:
@@ -281,7 +301,7 @@ t:cuda10.2-clang:
- .cmake_test_linux_release
- .linux_x86_64_tags_cuda
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_NO_MR: "true"
@@ -292,7 +312,7 @@ t:cuda11.6-nvidia:
- .linux_x86_64_tags_cuda
- .cmake_junit_artifacts
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
t:cuda11.6-clang:
extends:
@@ -300,7 +320,7 @@ t:cuda11.6-clang:
- .cmake_test_linux_release
- .linux_x86_64_tags_cuda
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_NO_MR: "true"
@@ -310,7 +330,7 @@ t:cuda11.8-minimal-ninja:
- .cmake_test_linux_release
- .linux_x86_64_tags_cuda
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_NO_MR: "true"
@@ -320,7 +340,7 @@ t:hip5.5-radeon:
- .cmake_test_linux_release
- .linux_x86_64_tags_radeon
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_NO_MR: "true"
@@ -330,7 +350,7 @@ t:linux-gcc-cxx-modules-ninja:
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -340,7 +360,18 @@ t:linux-gcc-cxx-modules-ninja-multi:
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_dependent
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:debian10-legacy:
+ extends:
+ - .debian10_legacy
+ - .cmake_test_linux_release
+ - .linux_x86_64_tags
+ - .cmake_junit_artifacts
+ - .run_dependent
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -354,27 +385,27 @@ b:fedora38-ninja:
variables:
CMAKE_CI_JOB_CONTINUOUS: "true"
-b:debian10-makefiles-inplace:
+b:debian12-makefiles-inplace:
extends:
- - .debian10_makefiles_inplace
+ - .debian12_makefiles_inplace
- .cmake_build_linux_standalone
- .linux_x86_64_tags
- .run_manually
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-b:debian10-extdeps:
+b:debian12-extdeps:
extends:
- - .debian10_extdeps
+ - .debian12_extdeps
- .cmake_build_linux_standalone
- .linux_x86_64_tags
- .run_manually
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-b:debian10-aarch64-extdeps:
+b:debian12-aarch64-extdeps:
extends:
- - .debian10_aarch64_extdeps
+ - .debian12_aarch64_extdeps
- .cmake_build_linux_standalone
- .linux_aarch64_tags
- .run_manually
@@ -826,6 +857,15 @@ b:macos-arm64-ninja:
variables:
CMAKE_CI_JOB_CONTINUOUS: "true"
+b:macos-arm64-pch:
+ extends:
+ - .macos_arm64_pch
+ - .cmake_build_macos
+ - .macos_arm64_tags
+ - .run_manually
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
t:macos-x86_64-ninja:
extends:
- .macos_x86_64_ninja
@@ -998,6 +1038,15 @@ b:windows-vs2022-x64-ninja:
- .windows_x86_64_tags_nonconcurrent_vs2022
- .run_manually
+b:windows-vs2022-x64-pch:
+ extends:
+ - .windows_vs2022_x64_pch
+ - .cmake_build_windows
+ - .windows_x86_64_tags_nonconcurrent_vs2022
+ - .run_manually
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
t:windows-vs2022-x64-ninja:
extends:
- .windows_vs2022_x64_ninja
diff --git a/.gitlab/ci/configure_common.cmake b/.gitlab/ci/configure_common.cmake
index c207a74..f03c4b8 100644
--- a/.gitlab/ci/configure_common.cmake
+++ b/.gitlab/ci/configure_common.cmake
@@ -13,6 +13,10 @@ set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY "ON" CACHE BOOL "")
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "")
set(CMake_TEST_INSTALL "OFF" CACHE BOOL "")
+set(CTEST_TEST_CTEST ON CACHE BOOL "")
+set(CMAKE_RUN_LONG_TESTS ON CACHE BOOL "")
+set(CMAKE_TESTS_CDASH_SERVER "NOTFOUND" CACHE STRING "")
+
if (NOT "$ENV{CMAKE_CI_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE "$ENV{CMAKE_CI_BUILD_TYPE}" CACHE STRING "")
endif ()
diff --git a/.gitlab/ci/configure_debian10_legacy.cmake b/.gitlab/ci/configure_debian10_legacy.cmake
new file mode 100644
index 0000000..11a5dc0
--- /dev/null
+++ b/.gitlab/ci/configure_debian10_legacy.cmake
@@ -0,0 +1,6 @@
+set(CMake_TEST_FindPython2 "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython2_IronPython "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython2_NumPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython2_PyPy "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian10_extdeps.cmake b/.gitlab/ci/configure_debian12_aarch64_extdeps.cmake
index 8e545f5..8e545f5 100644
--- a/.gitlab/ci/configure_debian10_extdeps.cmake
+++ b/.gitlab/ci/configure_debian12_aarch64_extdeps.cmake
diff --git a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake b/.gitlab/ci/configure_debian12_aarch64_ninja.cmake
index dff0db1..5b97e4f 100644
--- a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
+++ b/.gitlab/ci/configure_debian12_aarch64_ninja.cmake
@@ -28,14 +28,14 @@ set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5 "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_MPICH_C_COMPILER "/usr/bin/h5pcc.mpich" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_MPICH_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-# set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER "/usr/bin/h5c++.mpich" CACHE FILEPATH "") # h5c++.mpich does not exist
-# set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER "/usr/bin/h5c++.mpich" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER "/usr/bin/h5pfc.mpich" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER "/usr/bin/h5pcc.openmpi" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-# set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER "/usr/bin/h5c++.openmpi" CACHE FILEPATH "") # h5c++.openmpi does not exist
-# set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER "/usr/bin/h5c++.openmpi" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER "/usr/bin/h5pfc.openmpi" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_Serial_C_COMPILER "/usr/bin/h5cc" CACHE FILEPATH "")
@@ -74,9 +74,9 @@ set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "")
set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "")
set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_NumPy "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_PyPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3 "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_NumPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_PyPy "ON" CACHE BOOL "")
set(CMake_TEST_FindRuby "ON" CACHE BOOL "")
set(CMake_TEST_FindSDL "ON" CACHE BOOL "")
set(CMake_TEST_FindSQLite3 "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_debian10_aarch64_extdeps.cmake b/.gitlab/ci/configure_debian12_extdeps.cmake
index 8e545f5..8e545f5 100644
--- a/.gitlab/ci/configure_debian10_aarch64_extdeps.cmake
+++ b/.gitlab/ci/configure_debian12_extdeps.cmake
diff --git a/.gitlab/ci/configure_debian12_hip_radeon.cmake b/.gitlab/ci/configure_debian12_hip_radeon.cmake
new file mode 100644
index 0000000..58036b0
--- /dev/null
+++ b/.gitlab/ci/configure_debian12_hip_radeon.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_HIP "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian10_iwyu.cmake b/.gitlab/ci/configure_debian12_iwyu.cmake
index abe750d..37ccbf4 100644
--- a/.gitlab/ci/configure_debian10_iwyu.cmake
+++ b/.gitlab/ci/configure_debian12_iwyu.cmake
@@ -1,6 +1,7 @@
set(CMake_RUN_IWYU ON CACHE BOOL "")
+set(CMake_IWYU_OPTIONS "-DCMAKE_IWYU_FORWARD_STD_HASH" CACHE STRING "")
# Uncomment to diagnose IWYU problems as needed.
#set(CMake_IWYU_VERBOSE ON CACHE BOOL "")
-set(IWYU_COMMAND "/usr/bin/include-what-you-use-6.0" CACHE FILEPATH "")
+set(IWYU_COMMAND "/usr/bin/include-what-you-use-15" CACHE FILEPATH "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_debian10_ninja_clang.cmake b/.gitlab/ci/configure_debian12_makefiles_clang.cmake
index 20863a2..20863a2 100644
--- a/.gitlab/ci/configure_debian10_ninja_clang.cmake
+++ b/.gitlab/ci/configure_debian12_makefiles_clang.cmake
diff --git a/.gitlab/ci/configure_debian10_makefiles_inplace.cmake b/.gitlab/ci/configure_debian12_makefiles_inplace.cmake
index 33f0db0..33f0db0 100644
--- a/.gitlab/ci/configure_debian10_makefiles_inplace.cmake
+++ b/.gitlab/ci/configure_debian12_makefiles_inplace.cmake
diff --git a/.gitlab/ci/configure_debian10_ninja.cmake b/.gitlab/ci/configure_debian12_ninja.cmake
index 211a2a7..f70e3d5 100644
--- a/.gitlab/ci/configure_debian10_ninja.cmake
+++ b/.gitlab/ci/configure_debian12_ninja.cmake
@@ -32,14 +32,14 @@ set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5 "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_MPICH_C_COMPILER "/usr/bin/h5pcc.mpich" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_MPICH_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-# set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER "/usr/bin/h5c++.mpich" CACHE FILEPATH "") # h5c++.mpich does not exist
-# set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER "/usr/bin/h5c++.mpich" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER "/usr/bin/h5pfc.mpich" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER "/usr/bin/h5pcc.openmpi" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-# set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER "/usr/bin/h5c++.openmpi" CACHE FILEPATH "") # h5c++.openmpi does not exist
-# set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER "/usr/bin/h5c++.openmpi" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER "/usr/bin/h5pfc.openmpi" CACHE FILEPATH "")
set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
set(CMake_TEST_FindHDF5_Serial_C_COMPILER "/usr/bin/h5cc" CACHE FILEPATH "")
@@ -78,10 +78,9 @@ set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "")
set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "")
set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_IronPython "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_NumPy "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_PyPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3 "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_IronPython "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_PyPy "ON" CACHE BOOL "")
set(CMake_TEST_FindRuby "ON" CACHE BOOL "")
set(CMake_TEST_FindRuby_RVM "ON" CACHE BOOL "")
set(CMake_TEST_FindSDL "ON" CACHE BOOL "")
@@ -104,4 +103,8 @@ if (NOT "$ENV{SWIFTC}" STREQUAL "")
set(CMAKE_Swift_COMPILER "$ENV{SWIFTC}" CACHE FILEPATH "")
endif()
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+ set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
+endif()
+
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian10_makefiles_clang.cmake b/.gitlab/ci/configure_debian12_ninja_clang.cmake
index 20863a2..20863a2 100644
--- a/.gitlab/ci/configure_debian10_makefiles_clang.cmake
+++ b/.gitlab/ci/configure_debian12_ninja_clang.cmake
diff --git a/.gitlab/ci/configure_fedora38_hip_radeon.cmake b/.gitlab/ci/configure_fedora38_hip_radeon.cmake
new file mode 100644
index 0000000..58036b0
--- /dev/null
+++ b/.gitlab/ci/configure_fedora38_hip_radeon.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_HIP "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora38_makefiles.cmake b/.gitlab/ci/configure_fedora38_makefiles.cmake
index c2f9982..a3881cf 100644
--- a/.gitlab/ci/configure_fedora38_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora38_makefiles.cmake
@@ -74,9 +74,12 @@ set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "")
set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "")
set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_NumPy "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython_PyPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython2 "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3 "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython2_NumPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_NumPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython2_PyPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_PyPy "ON" CACHE BOOL "")
set(CMake_TEST_FindRuby "ON" CACHE BOOL "")
set(CMake_TEST_FindRuby_RVM "ON" CACHE BOOL "")
set(CMake_TEST_FindSDL "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_fedora38_makefiles_clang.cmake b/.gitlab/ci/configure_fedora38_makefiles_clang.cmake
index ff30ad9..3ac23be 100644
--- a/.gitlab/ci/configure_fedora38_makefiles_clang.cmake
+++ b/.gitlab/ci/configure_fedora38_makefiles_clang.cmake
@@ -1 +1,5 @@
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+ set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
+endif()
+
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora38_ninja_clang.cmake b/.gitlab/ci/configure_fedora38_ninja_clang.cmake
index 4454647..848c5b6 100644
--- a/.gitlab/ci/configure_fedora38_ninja_clang.cmake
+++ b/.gitlab/ci/configure_fedora38_ninja_clang.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake b/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake
index 4454647..848c5b6 100644
--- a/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake
+++ b/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
index e9121ae..8342db6 100644
--- a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,bmionly" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
index e9121ae..8342db6 100644
--- a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,bmionly" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_macos_arm64_ninja_multi.cmake b/.gitlab/ci/configure_macos_arm64_ninja_multi.cmake
index b22285c..5b19c60 100644
--- a/.gitlab/ci/configure_macos_arm64_ninja_multi.cmake
+++ b/.gitlab/ci/configure_macos_arm64_ninja_multi.cmake
@@ -1,6 +1,11 @@
if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
set(CMake_TEST_ISPC "ON" CACHE STRING "")
+ set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
endif()
+# FIXME: sccache sometimes fails with "Compiler killed by signal 9".
+# This job does not compile much anyway, so suppress it for now.
+set(configure_no_sccache 1)
+
include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_macos_arm64_pch.cmake b/.gitlab/ci/configure_macos_arm64_pch.cmake
new file mode 100644
index 0000000..e2676ba
--- /dev/null
+++ b/.gitlab/ci/configure_macos_arm64_pch.cmake
@@ -0,0 +1,7 @@
+set(CMake_BUILD_PCH "ON" CACHE BOOL "")
+
+# sccache does not forward the PCH '-Xarch_arm64 "-include/..."' flag correctly.
+set(configure_no_sccache 1)
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_mingw_osdn_io_common.cmake b/.gitlab/ci/configure_mingw_osdn_io_common.cmake
index 55dce1d..d316233 100644
--- a/.gitlab/ci/configure_mingw_osdn_io_common.cmake
+++ b/.gitlab/ci/configure_mingw_osdn_io_common.cmake
@@ -1,5 +1,8 @@
set(CMake_TEST_Java OFF CACHE BOOL "")
+get_filename_component(mingw_dir "${CMAKE_CURRENT_LIST_DIR}/../mingw" ABSOLUTE)
+set(CMake_TEST_MSYSTEM_PREFIX "${mingw_dir}" CACHE STRING "")
+
set(configure_no_sccache 1)
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_windows_clang_ninja.cmake b/.gitlab/ci/configure_windows_clang_ninja.cmake
index d1f0f52..8a65eef 100644
--- a/.gitlab/ci/configure_windows_clang_ninja.cmake
+++ b/.gitlab/ci/configure_windows_clang_ninja.cmake
@@ -1,5 +1,5 @@
if("$ENV{CMAKE_CI_BUILD_NAME}" MATCHES "(^|_)gnu(_|$)")
- set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+ set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_clang_common.cmake")
diff --git a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
index 5f2a215..2349bfd 100644
--- a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
+++ b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
@@ -1,2 +1,2 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi,bmionly" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_msvc.cmake" CACHE STRING "")
diff --git a/.gitlab/ci/configure_windows_vs2019_x64.cmake b/.gitlab/ci/configure_windows_vs2019_x64.cmake
index c7d41ea..b859525 100644
--- a/.gitlab/ci/configure_windows_vs2019_x64.cmake
+++ b/.gitlab/ci/configure_windows_vs2019_x64.cmake
@@ -1 +1,5 @@
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+ set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
+endif()
+
include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_pch.cmake b/.gitlab/ci/configure_windows_vs2022_x64_pch.cmake
new file mode 100644
index 0000000..2a2eed7
--- /dev/null
+++ b/.gitlab/ci/configure_windows_vs2022_x64_pch.cmake
@@ -0,0 +1,2 @@
+set(CMake_BUILD_PCH "ON" CACHE BOOL "")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_common.cmake")
diff --git a/.gitlab/ci/cxx_modules_rules_gcc.cmake b/.gitlab/ci/cxx_modules_rules_gcc.cmake
index 3777506..020cb1f 100644
--- a/.gitlab/ci/cxx_modules_rules_gcc.cmake
+++ b/.gitlab/ci/cxx_modules_rules_gcc.cmake
@@ -3,7 +3,18 @@ set(CMake_TEST_CXXModules_UUID "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E -x c++ <SOURCE>"
" -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>"
- " -fmodules-ts -fdep-file=<DYNDEP_FILE> -fdep-output=<OBJECT> -fdep-format=trtbd"
+ " -fmodules-ts -fdeps-file=<DYNDEP_FILE> -fdeps-target=<OBJECT> -fdeps-format=p1689r5"
" -o <PREPROCESSED_SOURCE>")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "-fmodules-ts -fmodule-mapper=<MODULE_MAP_FILE> -fdep-format=trtbd -x c++")
+string(CONCAT CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
+ # Turn on modules.
+ "-fmodules-ts"
+ # Read the module mapper file.
+ " -fmodule-mapper=<MODULE_MAP_FILE>"
+ # Make sure dependency tracking is enabled (missing from `try_*`).
+ " -MD"
+ # Suppress `CXX_MODULES +=` from generated depfile snippets.
+ " -fdeps-format=p1689r5"
+ # Force C++ as a language.
+ " -x c++")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG "-fmodule-only")
diff --git a/.gitlab/ci/docker/debian10-aarch64/Dockerfile b/.gitlab/ci/docker/debian10-x86_64/Dockerfile
index a0687e3..c39b380 100644
--- a/.gitlab/ci/docker/debian10-aarch64/Dockerfile
+++ b/.gitlab/ci/docker/debian10-x86_64/Dockerfile
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
-ARG BASE_IMAGE=arm64v8/debian:10
+ARG BASE_IMAGE=debian:10
FROM ${BASE_IMAGE} AS apt-cache
# Populate APT cache w/ the fresh metadata and prefetch packages.
@@ -12,6 +12,7 @@ RUN --mount=type=tmpfs,target=/var/log \
apt-get update \
&& apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
+
FROM ${BASE_IMAGE}
LABEL maintainer="Brad King <brad.king@kitware.com>"
diff --git a/.gitlab/ci/docker/debian10-x86_64/deps_packages.lst b/.gitlab/ci/docker/debian10-x86_64/deps_packages.lst
new file mode 100644
index 0000000..b415421
--- /dev/null
+++ b/.gitlab/ci/docker/debian10-x86_64/deps_packages.lst
@@ -0,0 +1,16 @@
+# Install build requirements.
+libssl-dev
+
+# Install development tools.
+g++
+curl
+git
+
+# Tools needed for the test suite.
+jq
+
+# Packages needed to test find modules.
+python2 python2-dev python-numpy pypy pypy-dev
+
+# CMake_TEST_FindPython2_IronPython
+libmono-system-windows-forms4.0-cil
diff --git a/.gitlab/ci/docker/debian10/docker-clean b/.gitlab/ci/docker/debian10-x86_64/docker-clean
index e69de29..e69de29 100644
--- a/.gitlab/ci/docker/debian10/docker-clean
+++ b/.gitlab/ci/docker/debian10-x86_64/docker-clean
diff --git a/.gitlab/ci/docker/debian10/dpkg-exclude b/.gitlab/ci/docker/debian10-x86_64/dpkg-exclude
index 60b6565..60b6565 100644
--- a/.gitlab/ci/docker/debian10/dpkg-exclude
+++ b/.gitlab/ci/docker/debian10-x86_64/dpkg-exclude
diff --git a/.gitlab/ci/docker/debian10-x86_64/install_deps.sh b/.gitlab/ci/docker/debian10-x86_64/install_deps.sh
new file mode 100755
index 0000000..002f136
--- /dev/null
+++ b/.gitlab/ci/docker/debian10-x86_64/install_deps.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+set -e
+
+apt-get install -y $(grep '^[^#]\+$' /root/deps_packages.lst)
+
+curl -L -O https://github.com/IronLanguages/ironpython2/releases/download/ipy-2.7.12/ironpython_2.7.12.deb
+echo 'b7b90c82cf311dd3faf290ce3f274af5128b96db884a88dd643ce141bbf12fb9 ironpython_2.7.12.deb' > ironpython.sha256sum
+sha256sum --check ironpython.sha256sum
+dpkg -i ironpython_2.7.12.deb
+rm ironpython_2.7.12.deb ironpython.sha256sum
diff --git a/.gitlab/ci/docker/debian10/install_deps.sh b/.gitlab/ci/docker/debian10/install_deps.sh
deleted file mode 100755
index a00e322..0000000
--- a/.gitlab/ci/docker/debian10/install_deps.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-set -e
-
-apt-get install -y $(grep '^[^#]\+$' /root/deps_packages.lst)
-
-curl -L -O https://github.com/IronLanguages/ironpython2/releases/download/ipy-2.7.10/ironpython_2.7.10.deb
-echo 'e1aceec1d49ffa66e9059a52168a734999dcccc50164a60e2936649cae698f3e ironpython_2.7.10.deb' > ironpython.sha256sum
-sha256sum --check ironpython.sha256sum
-dpkg -i ironpython_2.7.10.deb
-rm ironpython_2.7.10.deb ironpython.sha256sum
-
-# Perforce
-curl -L https://www.perforce.com/downloads/perforce/r21.2/bin.linux26x86_64/helix-core-server.tgz -o - \
- | tar -C /usr/local/bin -xvzf - -- p4 p4d
diff --git a/.gitlab/ci/docker/debian12-aarch64/Dockerfile b/.gitlab/ci/docker/debian12-aarch64/Dockerfile
new file mode 100644
index 0000000..58b5e0e
--- /dev/null
+++ b/.gitlab/ci/docker/debian12-aarch64/Dockerfile
@@ -0,0 +1,26 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=arm64v8/debian:12
+
+FROM ${BASE_IMAGE} AS apt-cache
+# Populate APT cache w/ the fresh metadata and prefetch packages.
+# Use an empty `docker-clean` file to "hide" the image-provided
+# file to disallow removing packages after `apt-get` operations.
+RUN --mount=type=tmpfs,target=/var/log \
+ --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+ --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+ apt-get update \
+ && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
+
+FROM ${BASE_IMAGE}
+LABEL maintainer="Brad King <brad.king@kitware.com>"
+
+RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
+ --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+ --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
+ --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+ --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+ --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+ --mount=type=tmpfs,target=/var/log \
+ --mount=type=tmpfs,target=/tmp \
+ sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/debian10-aarch64/deps_packages.lst b/.gitlab/ci/docker/debian12-aarch64/deps_packages.lst
index ca83323..c92c715 100644
--- a/.gitlab/ci/docker/debian10-aarch64/deps_packages.lst
+++ b/.gitlab/ci/docker/debian12-aarch64/deps_packages.lst
@@ -20,14 +20,14 @@ libzstd-dev
zlib1g-dev
# Install iwyu runtime deps.
-clang-6.0
+clang-15
libncurses6
# Tools needed for the test suite.
jq
# Packages needed to test CTest.
-bzr bzr-xmloutput
+bzr
cvs
subversion
mercurial
@@ -73,20 +73,19 @@ libopenal-dev
libopenmpi-dev openmpi-bin
libosp-dev
libpng-dev
-libpq-dev postgresql-server-dev-11
+libpq-dev postgresql-server-dev-15
libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc
-libsdl-dev
+libsdl1.2-dev
libsqlite3-dev
libtiff-dev
libuv1-dev
-libwxgtk3.0-dev
+libwxgtk3.2-dev
libx11-dev
libxalan-c-dev
libxerces-c-dev
libxml2-dev libxml2-utils
libxslt-dev xsltproc
-openjdk-11-jdk
-python2 python2-dev python-numpy pypy pypy-dev
+openjdk-17-jdk
python3 python3-dev python3-numpy pypy3 pypy3-dev python3-venv
qtbase5-dev qtbase5-dev-tools
ruby ruby-dev
diff --git a/.gitlab/ci/docker/debian10-aarch64/docker-clean b/.gitlab/ci/docker/debian12-aarch64/docker-clean
index e69de29..e69de29 100644
--- a/.gitlab/ci/docker/debian10-aarch64/docker-clean
+++ b/.gitlab/ci/docker/debian12-aarch64/docker-clean
diff --git a/.gitlab/ci/docker/debian10-aarch64/dpkg-exclude b/.gitlab/ci/docker/debian12-aarch64/dpkg-exclude
index 60b6565..60b6565 100644
--- a/.gitlab/ci/docker/debian10-aarch64/dpkg-exclude
+++ b/.gitlab/ci/docker/debian12-aarch64/dpkg-exclude
diff --git a/.gitlab/ci/docker/debian10-aarch64/install_deps.sh b/.gitlab/ci/docker/debian12-aarch64/install_deps.sh
index d1c8aed..d1c8aed 100755
--- a/.gitlab/ci/docker/debian10-aarch64/install_deps.sh
+++ b/.gitlab/ci/docker/debian12-aarch64/install_deps.sh
diff --git a/.gitlab/ci/docker/debian10/Dockerfile b/.gitlab/ci/docker/debian12-x86_64/Dockerfile
index d866428..477e763 100644
--- a/.gitlab/ci/docker/debian10/Dockerfile
+++ b/.gitlab/ci/docker/debian12-x86_64/Dockerfile
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
-ARG BASE_IMAGE=debian:10
+ARG BASE_IMAGE=debian:12
FROM ${BASE_IMAGE} AS apt-cache
# Populate APT cache w/ the fresh metadata and prefetch packages.
@@ -56,7 +56,7 @@ RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
RUN --mount=type=bind,from=iwyu-build,source=/root,target=/root \
tar -C / -xf /root/iwyu.tar \
- && ln -s /usr/lib/llvm-6.0/bin/include-what-you-use /usr/bin/include-what-you-use-6.0
+ && ln -s /usr/lib/llvm-15/bin/include-what-you-use /usr/bin/include-what-you-use-15
RUN --mount=type=bind,from=rvm-build,source=/root,target=/root \
tar -C /usr/local -xf /root/rvm.tar
diff --git a/.gitlab/ci/docker/debian10/deps_packages.lst b/.gitlab/ci/docker/debian12-x86_64/deps_packages.lst
index 0b79675..a59f2c9 100644
--- a/.gitlab/ci/docker/debian10/deps_packages.lst
+++ b/.gitlab/ci/docker/debian12-x86_64/deps_packages.lst
@@ -20,18 +20,21 @@ libzstd-dev
zlib1g-dev
# Install iwyu runtime deps.
-clang-6.0
+clang-15
libncurses6
# Tools needed for the test suite.
jq
# Packages needed to test CTest.
-bzr bzr-xmloutput
+bzr
cvs
subversion
mercurial
+# Install HIP language toolchain.
+hipcc
+
# Install swift runtime deps.
libncurses5
@@ -76,25 +79,24 @@ libopenal-dev
libopenmpi-dev openmpi-bin
libosp-dev
libpng-dev
-libpq-dev postgresql-server-dev-11
+libpq-dev postgresql-server-dev-15
libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc
-libsdl-dev
+libsdl1.2-dev
libsqlite3-dev
libtiff-dev
libuv1-dev
-libwxgtk3.0-dev
+libwxgtk3.2-dev
libx11-dev
libxalan-c-dev
libxerces-c-dev
libxml2-dev libxml2-utils
libxslt-dev xsltproc
-openjdk-11-jdk
-python2 python2-dev python-numpy pypy pypy-dev
+openjdk-17-jdk
python3 python3-dev python3-numpy pypy3 pypy3-dev python3-venv
qtbase5-dev qtbase5-dev-tools
ruby ruby-dev
swig
unixodbc-dev
-# CMake_TEST_FindPython_IronPython
+# Packages needed to test ironpython.
libmono-system-windows-forms4.0-cil
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON.cmake b/.gitlab/ci/docker/debian12-x86_64/docker-clean
index e69de29..e69de29 100644
--- a/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON.cmake
+++ b/.gitlab/ci/docker/debian12-x86_64/docker-clean
diff --git a/.gitlab/ci/docker/debian12-x86_64/dpkg-exclude b/.gitlab/ci/docker/debian12-x86_64/dpkg-exclude
new file mode 100644
index 0000000..60b6565
--- /dev/null
+++ b/.gitlab/ci/docker/debian12-x86_64/dpkg-exclude
@@ -0,0 +1,21 @@
+# Drop all man pages
+path-exclude=/usr/share/man/*
+
+# Drop all info pages
+path-exclude=/usr/share/info/*
+
+# Drop all README files except from the some packages
+path-exclude=/usr/**/*README*
+path-include=/usr/share/devscripts/templates/README.mk-build-deps
+path-include=/usr/share/equivs/template/debian/README.Debian.in
+
+# Drop all translations
+path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo
+
+# Drop all documentation ...
+path-exclude=/usr/share/doc/*
+path-exclude=/usr/share/doc-base/*
+path-exclude=/usr/share/gtk-doc/*
+
+# Per package excludes
+path-exclude=/usr/share/gnupg/help.*.txt
diff --git a/.gitlab/ci/docker/debian12-x86_64/install_deps.sh b/.gitlab/ci/docker/debian12-x86_64/install_deps.sh
new file mode 100755
index 0000000..7bfcacd
--- /dev/null
+++ b/.gitlab/ci/docker/debian12-x86_64/install_deps.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -e
+
+apt-get install -y $(grep '^[^#]\+$' /root/deps_packages.lst)
+
+curl -L -O https://github.com/IronLanguages/ironpython3/releases/download/v3.4.0/ironpython_3.4.0.deb
+echo '7dcd10b7a0ec0342bd7e20eebb597a96bb15267eb797d59358a3b1cfaa3e1adc ironpython_3.4.0.deb' > ironpython.sha256sum
+sha256sum --check ironpython.sha256sum
+dpkg -i ironpython_3.4.0.deb
+rm ironpython_3.4.0.deb ironpython.sha256sum
+
+# Perforce
+curl -L https://www.perforce.com/downloads/perforce/r21.2/bin.linux26x86_64/helix-core-server.tgz -o - \
+ | tar -C /usr/local/bin -xvzf - -- p4 p4d
diff --git a/.gitlab/ci/docker/debian10/install_iwyu.sh b/.gitlab/ci/docker/debian12-x86_64/install_iwyu.sh
index 4814a71..bbeceb8 100755
--- a/.gitlab/ci/docker/debian10/install_iwyu.sh
+++ b/.gitlab/ci/docker/debian12-x86_64/install_iwyu.sh
@@ -8,7 +8,7 @@ apt-get install -y $(grep '^[^#]\+$' /root/iwyu_packages.lst)
cd /root
git clone "https://github.com/include-what-you-use/include-what-you-use.git"
cd include-what-you-use
-readonly llvm_version="$( clang-6.0 --version | head -n1 | cut -d' ' -f3 | cut -d. -f-2 )"
+readonly llvm_version="$( clang-15 --version | head -n1 | cut -d' ' -f4 | cut -d. -f-1 )"
git checkout "clang_$llvm_version"
mkdir build
cd build
@@ -16,7 +16,6 @@ cd build
cmake -GNinja \
-DCMAKE_BUILD_TYPE=Release \
"-DCMAKE_INSTALL_PREFIX=/usr/lib/llvm-$llvm_version" \
- "-DIWYU_LLVM_ROOT_PATH=/usr/lib/llvm-$llvm_version" \
..
ninja
DESTDIR=/root/iwyu-destdir ninja install
diff --git a/.gitlab/ci/docker/debian10/install_rvm.sh b/.gitlab/ci/docker/debian12-x86_64/install_rvm.sh
index c6fff70..1ad42c4 100755
--- a/.gitlab/ci/docker/debian10/install_rvm.sh
+++ b/.gitlab/ci/docker/debian12-x86_64/install_rvm.sh
@@ -11,7 +11,7 @@ gpg2 --keyserver hkps://keyserver.ubuntu.com \
curl -sSL https://get.rvm.io | bash -s stable
# keep version in sync with `env_debian*_ninja.sh`
-/usr/local/rvm/bin/rvm install ruby-2.7.0
+/usr/local/rvm/bin/rvm install ruby-3.2.2
for p in archives examples gem-cache log src; do
touch /usr/local/rvm/${p}/.tar_exclude
diff --git a/.gitlab/ci/docker/debian10/iwyu_packages.lst b/.gitlab/ci/docker/debian12-x86_64/iwyu_packages.lst
index 9e291c9..2dbddba 100644
--- a/.gitlab/ci/docker/debian10/iwyu_packages.lst
+++ b/.gitlab/ci/docker/debian12-x86_64/iwyu_packages.lst
@@ -1,7 +1,7 @@
# Install development tools.
-clang-6.0
-libclang-6.0-dev
-llvm-6.0-dev
+clang-15
+libclang-15-dev
+llvm-15-dev
libz-dev
g++
cmake
diff --git a/.gitlab/ci/docker/debian10/rvm_packages.lst b/.gitlab/ci/docker/debian12-x86_64/rvm_packages.lst
index 80f079c..80f079c 100644
--- a/.gitlab/ci/docker/debian10/rvm_packages.lst
+++ b/.gitlab/ci/docker/debian12-x86_64/rvm_packages.lst
diff --git a/.gitlab/ci/docker/fedora38/deps_packages.lst b/.gitlab/ci/docker/fedora38/deps_packages.lst
index c7c1385..da050d9 100644
--- a/.gitlab/ci/docker/fedora38/deps_packages.lst
+++ b/.gitlab/ci/docker/fedora38/deps_packages.lst
@@ -44,6 +44,13 @@ file
jq
which
+# Install HIP language toolchain.
+hsakmt-devel
+lld
+rocm-comgr-devel
+rocm-hip-devel
+rocm-runtime-devel
+
# Packages needed to test CTest.
breezy
subversion
diff --git a/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile b/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile
index e0af0b9..d8e8238 100644
--- a/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile
+++ b/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile
@@ -1,4 +1,4 @@
-FROM fedora:36
+FROM fedora:38
MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
# Install build dependencies for packages.
diff --git a/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh b/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh
index 20ea35f..529626e 100755
--- a/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh
+++ b/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh
@@ -2,7 +2,7 @@
set -e
-readonly revision="p1689r5-cmake-ci-20220614" # 3075e510e3d29583f8886b95aff044c0474c84a5
+readonly revision="p1689r5-cmake-ci-20230814" # 9fd54ccc390ab4eb3c48186b7bf15e02632cc76c
readonly tarball="https://github.com/mathstuf/gcc/archive/$revision.tar.gz"
readonly workdir="$HOME/gcc"
diff --git a/.gitlab/ci/download_qt.cmake b/.gitlab/ci/download_qt.cmake
index b02ceb0..28a3e27 100644
--- a/.gitlab/ci/download_qt.cmake
+++ b/.gitlab/ci/download_qt.cmake
@@ -15,11 +15,11 @@ if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows.*package")
set(qt_url_root "https://cmake.org/files/dependencies")
set(qt_url_path "")
if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows_x86_64_package")
- list(APPEND qt_files "qt-5.12.1-win-x86_64-msvc_v142-1.zip")
- set(qt_subdir "qt-5.12.1-win-x86_64-msvc_v142-1")
+ list(APPEND qt_files "qt-5.15.10-win-x86_64-msvc_v142-1.zip")
+ set(qt_subdir "qt-5.15.10-win-x86_64-msvc_v142-1")
elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows_i386_package")
- list(APPEND qt_files "qt-5.12.1-win-i386-msvc_v142-1.zip")
- set(qt_subdir "qt-5.12.1-win-i386-msvc_v142-1")
+ list(APPEND qt_files "qt-5.15.10-win-i386-msvc_v142-1.zip")
+ set(qt_subdir "qt-5.15.10-win-i386-msvc_v142-1")
elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows_arm64_package")
list(APPEND qt_files "qt-6.3.0-win-arm64-msvc_v143-1.zip")
set(qt_subdir "qt-6.3.0-win-arm64-msvc_v143-1")
diff --git a/.gitlab/ci/download_qt_hashes.cmake b/.gitlab/ci/download_qt_hashes.cmake
index 4c48a47..1b9cf14 100644
--- a/.gitlab/ci/download_qt_hashes.cmake
+++ b/.gitlab/ci/download_qt_hashes.cmake
@@ -13,8 +13,8 @@ set("5.15.1-0-202009071110qtbase-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_6
set("qt-5.9.9-macosx10.10-x86_64-arm64.tar.xz_hash" d4449771afa0bc6a809c14f1e6d939e7732494cf059503ae451e2bfe8fc60cc1)
set("qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz_hash" 7b9463a01c8beeee5bf8d01c70deff2d08561cd20aaf6f7a2f41cf8b68ce8a6b)
-set("qt-5.12.1-win-i386-msvc_v142-1.zip_hash" aa78711fdaa5d9b146bf7ddcf15983f9fbb3f995462f2d043f8cca74b40ddd11)
-set("qt-5.12.1-win-x86_64-msvc_v142-1.zip_hash" c2fc068b9dac40bb420e28e1ee15ce4f2ccfc866d767f3b99b6bb435b7c4f44b)
+set("qt-5.15.10-win-i386-msvc_v142-1.zip_hash" c158cebc054d3f4f09733772a8a04789e2884912d45782e8c0c5e6a0b2773e92)
+set("qt-5.15.10-win-x86_64-msvc_v142-1.zip_hash" d55c017aef359f6aa8c592b18ba13cc120c749417b55671548970690126cd139)
set("qt-6.3.0-win-arm64-msvc_v143-1.zip_hash" f794c035fd4ff9f04468e1787a60d93d7496119c0060c3173a76d24a6b551b14)
set("qt-6.3.0-win-i386-msvc_v143-1.zip_hash" 972bc707f78d11b44f360643ca4d0c898e761f7add43b96117d958c70d84a443)
diff --git a/.gitlab/ci/env_debian10_makefiles_clang.sh b/.gitlab/ci/env_debian10_makefiles_clang.sh
deleted file mode 100644
index e0d5d61..0000000
--- a/.gitlab/ci/env_debian10_makefiles_clang.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-export CC=/usr/bin/clang-7
-export CXX=/usr/bin/clang++-7
diff --git a/.gitlab/ci/env_debian10_ninja_clang.sh b/.gitlab/ci/env_debian10_ninja_clang.sh
deleted file mode 100644
index e0d5d61..0000000
--- a/.gitlab/ci/env_debian10_ninja_clang.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-export CC=/usr/bin/clang-7
-export CXX=/usr/bin/clang++-7
diff --git a/.gitlab/ci/env_debian10_extdeps.sh b/.gitlab/ci/env_debian12_aarch64_extdeps.sh
index 7076e18..7076e18 100644
--- a/.gitlab/ci/env_debian10_extdeps.sh
+++ b/.gitlab/ci/env_debian12_aarch64_extdeps.sh
diff --git a/.gitlab/ci/env_debian10_aarch64_extdeps.sh b/.gitlab/ci/env_debian12_extdeps.sh
index 7076e18..7076e18 100644
--- a/.gitlab/ci/env_debian10_aarch64_extdeps.sh
+++ b/.gitlab/ci/env_debian12_extdeps.sh
diff --git a/.gitlab/ci/env_debian12_hip_radeon.sh b/.gitlab/ci/env_debian12_hip_radeon.sh
new file mode 100644
index 0000000..793c985
--- /dev/null
+++ b/.gitlab/ci/env_debian12_hip_radeon.sh
@@ -0,0 +1,9 @@
+export HIPCXX=/usr/bin/clang++-15
+export HIPFLAGS='--rocm-path=/usr --rocm-device-lib-path=/usr/lib/x86_64-linux-gnu/amdgcn/bitcode'
+
+# FIXME(debian): Clang is supposed to automatically parse a HIP version file.
+# The ROCm installer places it at '$prefix/bin/.hipVersion', but the package
+# on Debian moves it to '$prefix/share/hip/version'. llvm-toolchain package
+# version 15.0.7-4 has 'debian/patches/amdgpu/usr-search-paths.patch' for this,
+# but Debian 12 currently provides version 15.0.6-4 without the patch.
+export HIPFLAGS="$HIPFLAGS --hip-version=5.2"
diff --git a/.gitlab/ci/env_debian12_makefiles_clang.sh b/.gitlab/ci/env_debian12_makefiles_clang.sh
new file mode 100644
index 0000000..eda7c1f
--- /dev/null
+++ b/.gitlab/ci/env_debian12_makefiles_clang.sh
@@ -0,0 +1,2 @@
+export CC=/usr/bin/clang-15
+export CXX=/usr/bin/clang++-15
diff --git a/.gitlab/ci/env_debian10_ninja.sh b/.gitlab/ci/env_debian12_ninja.sh
index ba8ad47..b2b471d 100644
--- a/.gitlab/ci/env_debian10_ninja.sh
+++ b/.gitlab/ci/env_debian12_ninja.sh
@@ -1,4 +1,4 @@
-export MY_RUBY_HOME="/usr/local/rvm/rubies/ruby-2.7.0"
+export MY_RUBY_HOME="/usr/local/rvm/rubies/ruby-3.2.2"
if test -z "$CI_MERGE_REQUEST_ID"; then
curl -L -O "https://download.swift.org/swift-5.7.1-release/ubuntu1804/swift-5.7.1-RELEASE/swift-5.7.1-RELEASE-ubuntu18.04.tar.gz"
diff --git a/.gitlab/ci/env_debian12_ninja_clang.sh b/.gitlab/ci/env_debian12_ninja_clang.sh
new file mode 100644
index 0000000..eda7c1f
--- /dev/null
+++ b/.gitlab/ci/env_debian12_ninja_clang.sh
@@ -0,0 +1,2 @@
+export CC=/usr/bin/clang-15
+export CXX=/usr/bin/clang++-15
diff --git a/.gitlab/ci/env_fedora38_hip_radeon.sh b/.gitlab/ci/env_fedora38_hip_radeon.sh
new file mode 100644
index 0000000..812ef5a
--- /dev/null
+++ b/.gitlab/ci/env_fedora38_hip_radeon.sh
@@ -0,0 +1 @@
+export HIPCXX=/usr/bin/clang++-16
diff --git a/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1 b/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1
index e2d573e..f6e1f0a 100755
--- a/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1
+++ b/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1
@@ -1,3 +1 @@
-$pwdpath = $pwd.Path
-& "$pwsh" -File ".gitlab/ci/mingw.ps1"
-Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\mingw\bin;$env:PATH"
+. .gitlab/ci/mingw-env.ps1
diff --git a/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1 b/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1
index 6eccb72..f6e1f0a 100755
--- a/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1
+++ b/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1
@@ -1,5 +1 @@
-$pwdpath = $pwd.Path
-& "$pwsh" -File ".gitlab/ci/mingw.ps1"
-Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\mingw\msys\1.0\bin;$pwdpath\.gitlab\mingw\bin;$env:PATH"
-$env:MSYSTEM = 'MINGW32'
-$env:MAKE_MODE = 'unix'
+. .gitlab/ci/mingw-env.ps1
diff --git a/.gitlab/ci/env_windows_vs2022_x64.ps1 b/.gitlab/ci/env_windows_vs2022_x64.ps1
new file mode 100755
index 0000000..42aec11
--- /dev/null
+++ b/.gitlab/ci/env_windows_vs2022_x64.ps1
@@ -0,0 +1,4 @@
+if ("$env:CMAKE_CI_NIGHTLY" -eq "true") {
+ $cmake = "build\install\bin\cmake"
+ . ".gitlab/ci/qt-env.ps1"
+}
diff --git a/.gitlab/ci/ispc.sh b/.gitlab/ci/ispc.sh
index 59ee200..c1e3793 100755
--- a/.gitlab/ci/ispc.sh
+++ b/.gitlab/ci/ispc.sh
@@ -12,12 +12,12 @@ case "$(uname -s)-$(uname -m)" in
;;
Darwin-arm64)
shatool="shasum -a 256"
- sha256sum="62cee043a3a4dbff8c2f6d3885a7e573901bbc1325dd93d50f92904b7ea67fec"
+ sha256sum="c423a5a88d7a9a6ed667e41d025801c123fa0c5fd384d4ea138fa1fcf2bc24c9"
platform="macOS.arm64"
;;
Darwin-x86_64)
shatool="shasum -a 256"
- sha256sum="da0f11a048a316081a8ad8170d48b170b2ed7efc3b140fc88b8611238809c8e4"
+ sha256sum="e25222d2d6f4f8e3561556ac73f88721ceb5486439d6c2a566d37407ad9a5907"
platform="macOS.x86_64"
;;
*)
diff --git a/.gitlab/ci/mingw-env.ps1 b/.gitlab/ci/mingw-env.ps1
new file mode 100755
index 0000000..d68a7f7
--- /dev/null
+++ b/.gitlab/ci/mingw-env.ps1
@@ -0,0 +1,5 @@
+$pwdpath = $pwd.Path
+& "$pwsh" -File ".gitlab/ci/mingw.ps1"
+Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\mingw\bin;$pwdpath\.gitlab\mingw\msys\1.0\bin;$env:PATH"
+$env:MSYSTEM = 'MINGW32'
+$env:MAKE_MODE = 'unix'
diff --git a/.gitlab/ci/qt-env.ps1 b/.gitlab/ci/qt-env.ps1
index 7eff55f..22b1099 100755
--- a/.gitlab/ci/qt-env.ps1
+++ b/.gitlab/ci/qt-env.ps1
@@ -1,6 +1,9 @@
+if ($cmake -eq $null) {
+ throw ('$cmake powershell variable not set ')
+}
if ("$env:PROCESSOR_ARCHITECTURE" -eq "AMD64") {
$pwdpath = $pwd.Path
- cmake -P .gitlab/ci/download_qt.cmake
+ & $cmake -P .gitlab/ci/download_qt.cmake
Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\qt\bin;$env:PATH"
qmake -v
} elseif ("$env:PROCESSOR_ARCHITECTURE" -eq "ARM64") {
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 451a8e2..8398108 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -11,11 +11,11 @@
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
.linux_release_x86_64:
- image: "kitware/cmake:build-linux-x86_64-deps-2020-04-02@sha256:77e9ab183f34680990db9da5945473e288f0d6556bce79ecc1589670d656e157"
+ image: "kitware/cmake:build-linux-x86_64-deps-2023-08-16@sha256:aa0ebdbd90a51cc83d31f393c5c48ec4599a28f7ccdc288558522c6265b24fae"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
- LAUNCHER: "scl enable devtoolset-6 rh-python36 --"
+ LAUNCHER: "scl enable devtoolset-7 --"
CMAKE_ARCH: x86_64
.linux_release_aarch64:
@@ -30,11 +30,11 @@
variables:
BOOTSTRAP_ARGS: '-- "-DCMake_DOC_ARTIFACT_PREFIX=$CI_PROJECT_DIR/build/install-doc"'
-.needs_centos6_x86_64:
+.needs_centos7_x86_64:
dependencies:
- - b:centos6-x86_64
+ - b:centos7-x86_64
needs:
- - b:centos6-x86_64
+ - b:centos7-x86_64
.needs_centos7_aarch64:
dependencies:
@@ -44,23 +44,23 @@
### Debian
-.debian10:
- image: "kitware/cmake:ci-debian10-x86_64-2023-03-29"
+.debian12:
+ image: "kitware/cmake:ci-debian12-x86_64-2023-07-27"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
CMAKE_ARCH: x86_64
-.debian10_iwyu:
- extends: .debian10
+.debian12_iwyu:
+ extends: .debian12
variables:
- CMAKE_CONFIGURATION: debian10_iwyu
+ CMAKE_CONFIGURATION: debian12_iwyu
CTEST_NO_WARNINGS_ALLOWED: 1
CMAKE_CI_NO_INSTALL: 1
-.debian10_aarch64:
- image: "kitware/cmake:ci-debian10-aarch64-2023-03-29"
+.debian12_aarch64:
+ image: "kitware/cmake:ci-debian12-aarch64-2023-07-27"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -69,7 +69,7 @@
### Fedora
.fedora38:
- image: "kitware/cmake:ci-fedora38-x86_64-2023-05-22"
+ image: "kitware/cmake:ci-fedora38-x86_64-2023-08-07"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
@@ -112,44 +112,44 @@
#### Build and test
-.debian10_ninja:
- extends: .debian10
+.debian12_ninja:
+ extends: .debian12
variables:
- CMAKE_CONFIGURATION: debian10_ninja
+ CMAKE_CONFIGURATION: debian12_ninja
CTEST_NO_WARNINGS_ALLOWED: 1
-.debian10_aarch64_ninja:
- extends: .debian10_aarch64
+.debian12_aarch64_ninja:
+ extends: .debian12_aarch64
variables:
- CMAKE_CONFIGURATION: debian10_aarch64_ninja
+ CMAKE_CONFIGURATION: debian12_aarch64_ninja
CTEST_NO_WARNINGS_ALLOWED: 1
-.debian10_makefiles_inplace:
- extends: .debian10
+.debian12_makefiles_inplace:
+ extends: .debian12
variables:
- CMAKE_CONFIGURATION: debian10_makefiles_inplace
+ CMAKE_CONFIGURATION: debian12_makefiles_inplace
CMAKE_GENERATOR: "Unix Makefiles"
CMAKE_CI_BOOTSTRAP: 1
CMAKE_CI_INPLACE: 1
CMAKE_CI_NO_INSTALL: 1
CTEST_NO_WARNINGS_ALLOWED: 1
-.debian10_extdeps:
- extends: .debian10
+.debian12_extdeps:
+ extends: .debian12
variables:
- CMAKE_CONFIGURATION: debian10_extdeps
+ CMAKE_CONFIGURATION: debian12_extdeps
CMAKE_CI_BUILD_TYPE: Release
CTEST_NO_WARNINGS_ALLOWED: 1
-.debian10_aarch64_extdeps:
- extends: .debian10_aarch64
+.debian12_aarch64_extdeps:
+ extends: .debian12_aarch64
variables:
- CMAKE_CONFIGURATION: debian10_aarch64_extdeps
+ CMAKE_CONFIGURATION: debian12_aarch64_extdeps
CMAKE_CI_BUILD_TYPE: Release
CTEST_NO_WARNINGS_ALLOWED: 1
@@ -187,18 +187,18 @@
### Clang Compiler
-.debian10_makefiles_clang:
- extends: .debian10
+.debian12_makefiles_clang:
+ extends: .debian12
variables:
- CMAKE_CONFIGURATION: debian10_makefiles_clang
+ CMAKE_CONFIGURATION: debian12_makefiles_clang
CMAKE_GENERATOR: "Unix Makefiles"
-.debian10_ninja_clang:
- extends: .debian10
+.debian12_ninja_clang:
+ extends: .debian12
variables:
- CMAKE_CONFIGURATION: debian10_ninja_clang
+ CMAKE_CONFIGURATION: debian12_ninja_clang
.fedora38_makefiles_clang:
extends: .fedora38
@@ -359,10 +359,24 @@
CMAKE_CONFIGURATION: hip5.5_radeon
CMAKE_GENERATOR: "Ninja Multi-Config"
+.debian12_hip_radeon:
+ extends: .debian12
+
+ variables:
+ CMAKE_CONFIGURATION: debian12_hip_radeon
+ CTEST_LABELS: "HIP"
+
+.fedora38_hip_radeon:
+ extends: .fedora38
+
+ variables:
+ CMAKE_CONFIGURATION: fedora38_hip_radeon
+ CTEST_LABELS: "HIP"
+
### C++ modules
.gcc_cxx_modules_x86_64:
- image: "kitware/cmake:ci-gcc_cxx_modules-x86_64-2022-06-21"
+ image: "kitware/cmake:ci-gcc_cxx_modules-x86_64-2023-08-15"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -383,6 +397,22 @@
CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja_multi
CMAKE_GENERATOR: "Ninja Multi-Config"
+### Debian 10 legacy packages
+
+.debian10:
+ image: "kitware/cmake:ci-debian10-x86_64-2023-07-31"
+
+ variables:
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+ CMAKE_ARCH: x86_64
+
+.debian10_legacy:
+ extends: .debian10
+
+ variables:
+ CMAKE_CONFIGURATION: debian10_legacy
+ CTEST_LABELS: "Python2"
+
## Tags
.linux_x86_64_tags:
@@ -588,7 +618,7 @@
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_manually
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -598,7 +628,7 @@
- .cmake_test_linux_release
- .linux_x86_64_tags
- .run_manually
- - .needs_centos6_x86_64
+ - .needs_centos7_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml
index 09d7598..fbba288 100644
--- a/.gitlab/os-macos.yml
+++ b/.gitlab/os-macos.yml
@@ -38,6 +38,12 @@
CMAKE_CONFIGURATION: macos_arm64_ninja
CTEST_NO_WARNINGS_ALLOWED: 1
+.macos_arm64_pch:
+ extends: .macos_arm64_ninja
+
+ variables:
+ CMAKE_CONFIGURATION: macos_arm64_pch
+
.macos_x86_64_makefiles:
extends: .macos_build
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index 026f2f4..81944cb 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -55,6 +55,13 @@
VCVARSPLATFORM: "arm64"
VCVARSVERSION: "14.36.32532"
+.windows_vs2022_x64_pch:
+ extends:
+ - .windows_vs2022_x64_ninja
+
+ variables:
+ CMAKE_CONFIGURATION: windows_vs2022_x64_pch
+
.windows_vs2022_x64_ninja:
extends:
- .windows_build_ninja
@@ -359,6 +366,7 @@
- Set-Item -Force -Path "env:WIX" -Value "$pwdpath\.gitlab\wix"
- (& "$pwsh" -File ".gitlab/ci/cmake.ps1")
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\cmake\bin;$env:PATH"
+ - $cmake = "cmake"
- . .gitlab/ci/ninja-env.ps1
- (& "$env:WIX\bin\light.exe" -help) | Select -First 1
- cmake --version
diff --git a/Auxiliary/vim/cmake.vim.in b/Auxiliary/vim/cmake.vim.in
index 6edc040..39d7193 100644
--- a/Auxiliary/vim/cmake.vim.in
+++ b/Auxiliary/vim/cmake.vim.in
@@ -22,20 +22,20 @@ set cpo&vim
syn region cmakeBracketArgument start="\[\z(=\?\|=[0-9]*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
syn region cmakeComment start="#" end="$" contains=cmakeTodo,@Spell
-syn region cmakeBracketComment start="#\[\z(=\?\|=[0-9]*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
+syn region cmakeBracketComment start="\[\z(=*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
syn match cmakeEscaped /\(\\\\\|\\"\|\\n\|\\t\)/ contained
syn region cmakeRegistry start="\[" end="]" contained oneline contains=cmakeTodo,cmakeEscaped
syn region cmakeGeneratorExpression start="$<" end=">" contained oneline contains=cmakeVariableValue,cmakeProperty,cmakeGeneratorExpressions,cmakeTodo
-syn region cmakeString start='"' end='"' contained contains=cmakeTodo,cmakeVariableValue,cmakeEscaped
+syn region cmakeString start='"' end='"' contained contains=cmakeTodo,cmakeVariableValue,cmakeEscaped,@Spell
syn region cmakeVariableValue start="${" end="}" contained oneline contains=cmakeVariable,cmakeTodo,cmakeVariableValue
syn region cmakeEnvironment start="$ENV{" end="}" contained oneline contains=cmakeTodo
-syn region cmakeArguments start="(" end=")" contains=ALLBUT,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo
+syn region cmakeArguments start="(" end=")" contains=ALLBUT,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo,@Spell
syn case match
diff --git a/Auxiliary/vim/extract-upper-case.pl b/Auxiliary/vim/extract-upper-case.pl
index 1179199..7f40b74 100755
--- a/Auxiliary/vim/extract-upper-case.pl
+++ b/Auxiliary/vim/extract-upper-case.pl
@@ -16,10 +16,10 @@ my @modules;
my %keywords; # command => keyword-list
# find cmake/Modules/ | sed -rn 's/.*CMakeDetermine(.+)Compiler.cmake/\1/p' | sort
-my @languages = qw(ASM ASM_MASM ASM_NASM C CSharp CUDA CXX Fortran Java RC Swift);
+my @languages = qw(ASM ASM_MASM ASM_NASM C CSharp CUDA CXX Fortran Java RC Swift HIP);
# unwanted upper-cases
-my %unwanted = map { $_ => 1 } qw(VS CXX IDE NOTFOUND NO_ DFOO DBAR NEW);
+my %unwanted = map { $_ => 1 } qw(VS CXX IDE NOTFOUND NO_ DFOO DBAR NEW GNU);
# cannot remove ALL - exists for add_custom_command
# control-statements
@@ -30,7 +30,7 @@ my %loop = map { $_ => 1 } qw(foreach while endforeach endwhile);
my %deprecated = map { $_ => 1 } qw(build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory output_required_files remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file);
# add some (popular) modules
-push @modules, "ExternalProject";
+push @modules, "ExternalProject", "FetchContent";
# variables
open(CMAKE, "$cmake --help-variable-list|") or die "could not run cmake";
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 83f13d8..82dc563 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -1,13 +1,13 @@
" Vim syntax file
" Program: CMake - Cross-Platform Makefile Generator
-" Version: cmake version 3.19.20201028-gdab947f
+" Version: cmake version 3.27.20230713-gdc88dd5
" Language: CMake
" Author: Andy Cedilnik <andy.cedilnik@kitware.com>,
" Nicholas Hutchinson <nshutchinson@gmail.com>,
" Patrick Boettcher <patrick.boettcher@posteo.de>
" Maintainer: Dimitri Merejkowsky <d.merej@gmail.com>
" Former Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
-" Last Change: 2020 oct. 28
+" Last Change: 2023 Jul 13
"
" License: The CMake license applies to this file. See
" https://cmake.org/licensing
@@ -22,20 +22,20 @@ set cpo&vim
syn region cmakeBracketArgument start="\[\z(=\?\|=[0-9]*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
syn region cmakeComment start="#" end="$" contains=cmakeTodo,@Spell
-syn region cmakeBracketComment start="#\[\z(=\?\|=[0-9]*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
+syn region cmakeBracketComment start="\[\z(=*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
syn match cmakeEscaped /\(\\\\\|\\"\|\\n\|\\t\)/ contained
syn region cmakeRegistry start="\[" end="]" contained oneline contains=cmakeTodo,cmakeEscaped
syn region cmakeGeneratorExpression start="$<" end=">" contained oneline contains=cmakeVariableValue,cmakeProperty,cmakeGeneratorExpressions,cmakeTodo
-syn region cmakeString start='"' end='"' contained contains=cmakeTodo,cmakeVariableValue,cmakeEscaped
+syn region cmakeString start='"' end='"' contained contains=cmakeTodo,cmakeVariableValue,cmakeEscaped,@Spell
syn region cmakeVariableValue start="${" end="}" contained oneline contains=cmakeVariable,cmakeTodo,cmakeVariableValue
syn region cmakeEnvironment start="$ENV{" end="}" contained oneline contains=cmakeTodo
-syn region cmakeArguments start="(" end=")" contains=ALLBUT,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo
+syn region cmakeArguments start="(" end=")" contains=ALLBUT,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo,@Spell
syn case match
@@ -76,6 +76,7 @@ syn keyword cmakeProperty contained
\ AUTOGEN_USE_SYSTEM_INCLUDE
\ AUTOGEN_TARGETS_FOLDER
\ AUTOGEN_TARGET_DEPENDS
+ \ AUTOGEN_USE_SYSTEM_INCLUDE
\ AUTOMOC
\ AUTOMOC_COMPILER_PREDEFINES
\ AUTOMOC_DEPEND_FILTERS
@@ -120,6 +121,7 @@ syn keyword cmakeProperty contained
\ COMPILE_OPTIONS
\ COMPILE_PDB_NAME
\ COMPILE_PDB_OUTPUT_DIRECTORY
+ \ COMPILE_WARNING_AS_ERROR
\ COST
\ CPACK_DESKTOP_SHORTCUTS
\ CPACK_NEVER_OVERWRITE
@@ -140,6 +142,10 @@ syn keyword cmakeProperty contained
\ CUDA_STANDARD
\ CUDA_STANDARD_REQUIRED
\ CXX_EXTENSIONS
+ \ CXX_MODULE_DIRS
+ \ CXX_MODULE_SET
+ \ CXX_MODULE_SETS
+ \ CXX_SCAN_FOR_MODULES
\ CXX_STANDARD
\ CXX_STANDARD_REQUIRED
\ C_EXTENSIONS
@@ -156,6 +162,7 @@ syn keyword cmakeProperty contained
\ DISABLED
\ DISABLED_FEATURES
\ DISABLE_PRECOMPILE_HEADERS
+ \ DLL_NAME_WITH_SOVERSION
\ DOTNET_SDK
\ DOTNET_TARGET_FRAMEWORK
\ DOTNET_TARGET_FRAMEWORK_VERSION
@@ -168,7 +175,9 @@ syn keyword cmakeProperty contained
\ ENVIRONMENT_MODIFICATION
\ EXCLUDE_FROM_ALL
\ EXCLUDE_FROM_DEFAULT_BUILD
+ \ EXPORT_COMPILE_COMMANDS
\ EXPORT_NAME
+ \ EXPORT_NO_SYSTEM
\ EXPORT_PROPERTIES
\ EXTERNAL_OBJECT
\ EchoString
@@ -183,6 +192,7 @@ syn keyword cmakeProperty contained
\ FOLDER
\ FRAMEWORK
\ FRAMEWORK_VERSION
+ \ Fortran_BUILDING_INSTRINSIC_MODULES
\ Fortran_FORMAT
\ Fortran_MODULE_DIRECTORY
\ Fortran_PREPROCESS
@@ -195,7 +205,10 @@ syn keyword cmakeProperty contained
\ GLOBAL_DEPENDS_NO_CYCLES
\ GNUtoMS
\ HAS_CXX
+ \ HEADER_DIRS
\ HEADER_FILE_ONLY
+ \ HEADER_SET
+ \ HEADER_SETS
\ HELPSTRING
\ HIP_ARCHITECTURES
\ HIP_EXTENSIONS
@@ -214,8 +227,10 @@ syn keyword cmakeProperty contained
\ IMPORTED_LINK_INTERFACE_MULTIPLICITY
\ IMPORTED_LOCATION
\ IMPORTED_NO_SONAME
+ \ IMPORTED_NO_SYSTEM
\ IMPORTED_OBJECTS
\ IMPORTED_SONAME
+ \ IMPORTED_TARGETS
\ IMPORT_PREFIX
\ IMPORT_SUFFIX
\ INCLUDE_DIRECTORIES
@@ -224,15 +239,21 @@ syn keyword cmakeProperty contained
\ INSTALL_REMOVE_ENVIRONMENT_RPATH
\ INSTALL_RPATH
\ INSTALL_RPATH_USE_LINK_PATH
+ \ INTERFACE_AUTOMOC_MACRO_NAMES
\ INTERFACE_AUTOUIC_OPTIONS
\ INTERFACE_AUTOMOC_MACRO_NAMES
\ INTERFACE_COMPILE_DEFINITIONS
\ INTERFACE_COMPILE_FEATURES
\ INTERFACE_COMPILE_OPTIONS
+ \ INTERFACE_CXX_MODULE_SETS
+ \ INTERFACE_HEADER_SETS
+ \ INTERFACE_HEADER_SETS_TO_VERIFY
\ INTERFACE_INCLUDE_DIRECTORIES
\ INTERFACE_LINK_DEPENDS
\ INTERFACE_LINK_DIRECTORIES
\ INTERFACE_LINK_LIBRARIES
+ \ INTERFACE_LINK_LIBRARIES_DIRECT
+ \ INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
\ INTERFACE_LINK_OPTIONS
\ INTERFACE_POSITION_INDEPENDENT_CODE
\ INTERFACE_PRECOMPILE_HEADERS
@@ -242,6 +263,7 @@ syn keyword cmakeProperty contained
\ IN_TRY_COMPILE
\ IOS_INSTALL_COMBINED
\ ISPC_HEADER_DIRECTORY
+ \ ISPC_HEADER_SUFFIX
\ ISPC_INSTRUCTION_SETS
\ JOB_POOLS
\ JOB_POOL_COMPILE
@@ -260,6 +282,8 @@ syn keyword cmakeProperty contained
\ LINK_INTERFACE_LIBRARIES
\ LINK_INTERFACE_MULTIPLICITY
\ LINK_LIBRARIES
+ \ LINK_LIBRARIES_ONLY_TARGETS
+ \ LINK_LIBRARY_OVERRIDE
\ LINK_OPTIONS
\ LINK_SEARCH_END_STATIC
\ LINK_SEARCH_START_STATIC
@@ -277,6 +301,7 @@ syn keyword cmakeProperty contained
\ MANUALLY_ADDED_DEPENDENCIES
\ MEASUREMENT
\ MODIFIED
+ \ MSVC_DEBUG_INFORMATION_FORMAT
\ MSVC_RUNTIME_LIBRARY
\ NAME
\ NO_SONAME
@@ -343,6 +368,7 @@ syn keyword cmakeProperty contained
\ SUBDIRECTORIES
\ SUFFIX
\ SYMBOLIC
+ \ SYSTEM
\ Swift_DEPENDENCIES_FILE
\ Swift_DIAGNOSTICS_FILE
\ Swift_LANGUAGE_VERSION
@@ -356,16 +382,20 @@ syn keyword cmakeProperty contained
\ TEST_INCLUDE_FILES
\ TIMEOUT
\ TIMEOUT_AFTER_MATCH
+ \ TIMEOUT_SIGNAL_GRACE_PERIOD
+ \ TIMEOUT_SIGNAL_NAME
\ TYPE
\ UNITY_BUILD
\ UNITY_BUILD_BATCH_SIZE
\ UNITY_BUILD_CODE_AFTER_INCLUDE
\ UNITY_BUILD_CODE_BEFORE_INCLUDE
\ UNITY_BUILD_MODE
+ \ UNITY_BUILD_UNIQUE_ID
\ UNITY_GROUP
\ USE_FOLDERS
\ VALUE
\ VARIABLES
+ \ VERIFY_INTERFACE_HEADER_SETS
\ VERSION
\ VISIBILITY_INLINES_HIDDEN
\ VS_CONFIGURATION_TYPE
@@ -422,11 +452,14 @@ syn keyword cmakeProperty contained
\ VS_WINRT_EXTENSIONS
\ VS_WINRT_REFERENCES
\ VS_XAML_TYPE
+ \ WATCOM_RUNTIME_LIBRARY
\ WILL_FAIL
\ WIN32_EXECUTABLE
\ WINDOWS_EXPORT_ALL_SYMBOLS
\ WORKING_DIRECTORY
\ WRAP_EXCLUDE
+ \ XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY
+ \ XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY
\ XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
\ XCODE_EXPLICIT_FILE_TYPE
\ XCODE_FILE_ATTRIBUTES
@@ -443,9 +476,13 @@ syn keyword cmakeProperty contained
\ XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
\ XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
\ XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
+ \ XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+ \ XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
+ \ XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
\ XCODE_SCHEME_ENVIRONMENT
\ XCODE_SCHEME_EXECUTABLE
\ XCODE_SCHEME_GUARD_MALLOC
+ \ XCODE_SCHEME_LAUNCH_CONFIGURATION
\ XCODE_SCHEME_LAUNCH_MODE
\ XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
\ XCODE_SCHEME_MALLOC_GUARD_EDGES
@@ -460,16 +497,19 @@ syn keyword cmakeProperty contained
\ XCODE_SCHEME_LAUNCH_CONFIGURATION
\ XCODE_SCHEME_WORKING_DIRECTORY
\ XCODE_SCHEME_ZOMBIE_OBJECTS
+ \ XCODE_XCCONFIG
\ XCTEST
syn keyword cmakeVariable contained
\ ANDROID
\ APPLE
\ BORLAND
+ \ BSD
\ BUILD_SHARED_LIBS
\ CACHE
\ CMAKE_ABSOLUTE_DESTINATION_FILES
\ CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
+ \ CMAKE_ADSP_ROOT
\ CMAKE_AIX_EXPORT_ALL_SYMBOLS
\ CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
\ CMAKE_ANDROID_API
@@ -479,6 +519,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ANDROID_ARM_MODE
\ CMAKE_ANDROID_ARM_NEON
\ CMAKE_ANDROID_ASSETS_DIRECTORIES
+ \ CMAKE_ANDROID_EXCEPTIONS
\ CMAKE_ANDROID_GUI
\ CMAKE_ANDROID_JAR_DEPENDENCIES
\ CMAKE_ANDROID_JAR_DIRECTORIES
@@ -489,14 +530,17 @@ syn keyword cmakeVariable contained
\ CMAKE_ANDROID_NDK_DEPRECATED_HEADERS
\ CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG
\ CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION
+ \ CMAKE_ANDROID_NDK_VERSION
\ CMAKE_ANDROID_PROCESS_MAX
\ CMAKE_ANDROID_PROGUARD
\ CMAKE_ANDROID_PROGUARD_CONFIG_PATH
+ \ CMAKE_ANDROID_RTTI
\ CMAKE_ANDROID_SECURE_PROPS_PATH
\ CMAKE_ANDROID_SKIP_ANT_STEP
\ CMAKE_ANDROID_STANDALONE_TOOLCHAIN
\ CMAKE_ANDROID_STL_TYPE
\ CMAKE_APPBUNDLE_PATH
+ \ CMAKE_APPLE_SILICON_PROCESSOR
\ CMAKE_AR
\ CMAKE_ARCHIVE_OUTPUT_DIRECTORY
\ CMAKE_ARGC
@@ -508,12 +552,15 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_ARCHIVE_APPEND
\ CMAKE_ASM_ARCHIVE_CREATE
\ CMAKE_ASM_ARCHIVE_FINISH
+ \ CMAKE_ASM_BYTE_ORDER
\ CMAKE_ASM_CLANG_TIDY
+ \ CMAKE_ASM_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_ASM_COMPILER
\ CMAKE_ASM_COMPILER_ABI
\ CMAKE_ASM_COMPILER_AR
\ CMAKE_ASM_COMPILER_ARCHITECTURE_ID
\ CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_ASM_COMPILER_FRONTEND_VARIANT
\ CMAKE_ASM_COMPILER_ID
\ CMAKE_ASM_COMPILER_LAUNCHER
\ CMAKE_ASM_COMPILER_LOADED
@@ -528,6 +575,8 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_CREATE_SHARED_LIBRARY
\ CMAKE_ASM_CREATE_SHARED_MODULE
\ CMAKE_ASM_CREATE_STATIC_LIBRARY
+ \ CMAKE_ASM_EXTENSIONS
+ \ CMAKE_ASM_EXTENSIONS_DEFAULT
\ CMAKE_ASM_FLAGS
\ CMAKE_ASM_FLAGS_DEBUG
\ CMAKE_ASM_FLAGS_DEBUG_INIT
@@ -546,6 +595,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_INCLUDE_WHAT_YOU_USE
\ CMAKE_ASM_INIT
\ CMAKE_ASM_LIBRARY_ARCHITECTURE
+ \ CMAKE_ASM_LINKER_LAUNCHER
\ CMAKE_ASM_LINKER_PREFERENCE
\ CMAKE_ASM_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_ASM_LINKER_WRAPPER_FLAG
@@ -554,6 +604,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_LINK_LIBRARY_FILE_FLAG
\ CMAKE_ASM_LINK_LIBRARY_FLAG
\ CMAKE_ASM_LINK_LIBRARY_SUFFIX
+ \ CMAKE_ASM_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_ASM_MASM
\ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_MACHINE
\ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_PREFIX
@@ -561,12 +612,15 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_MASM_ARCHIVE_APPEND
\ CMAKE_ASM_MASM_ARCHIVE_CREATE
\ CMAKE_ASM_MASM_ARCHIVE_FINISH
+ \ CMAKE_ASM_MASM_BYTE_ORDER
\ CMAKE_ASM_MASM_CLANG_TIDY
+ \ CMAKE_ASM_MASM_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_ASM_MASM_COMPILER
\ CMAKE_ASM_MASM_COMPILER_ABI
\ CMAKE_ASM_MASM_COMPILER_AR
\ CMAKE_ASM_MASM_COMPILER_ARCHITECTURE_ID
\ CMAKE_ASM_MASM_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_ASM_MASM_COMPILER_FRONTEND_VARIANT
\ CMAKE_ASM_MASM_COMPILER_ID
\ CMAKE_ASM_MASM_COMPILER_LAUNCHER
\ CMAKE_ASM_MASM_COMPILER_LOADED
@@ -581,6 +635,8 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_MASM_CREATE_SHARED_LIBRARY
\ CMAKE_ASM_MASM_CREATE_SHARED_MODULE
\ CMAKE_ASM_MASM_CREATE_STATIC_LIBRARY
+ \ CMAKE_ASM_MASM_EXTENSIONS
+ \ CMAKE_ASM_MASM_EXTENSIONS_DEFAULT
\ CMAKE_ASM_MASM_FLAGS
\ CMAKE_ASM_MASM_FLAGS_DEBUG
\ CMAKE_ASM_MASM_FLAGS_DEBUG_INIT
@@ -599,6 +655,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_MASM_INCLUDE_WHAT_YOU_USE
\ CMAKE_ASM_MASM_INIT
\ CMAKE_ASM_MASM_LIBRARY_ARCHITECTURE
+ \ CMAKE_ASM_MASM_LINKER_LAUNCHER
\ CMAKE_ASM_MASM_LINKER_PREFERENCE
\ CMAKE_ASM_MASM_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_ASM_MASM_LINKER_WRAPPER_FLAG
@@ -607,14 +664,19 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_MASM_LINK_LIBRARY_FILE_FLAG
\ CMAKE_ASM_MASM_LINK_LIBRARY_FLAG
\ CMAKE_ASM_MASM_LINK_LIBRARY_SUFFIX
+ \ CMAKE_ASM_MASM_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_ASM_MASM_OUTPUT_EXTENSION
\ CMAKE_ASM_MASM_PLATFORM_ID
\ CMAKE_ASM_MASM_SIMULATE_ID
\ CMAKE_ASM_MASM_SIMULATE_VERSION
\ CMAKE_ASM_MASM_SIZEOF_DATA_PTR
\ CMAKE_ASM_MASM_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_ASM_MASM_STANDARD
+ \ CMAKE_ASM_MASM_STANDARD_DEFAULT
\ CMAKE_ASM_MASM_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_ASM_MASM_STANDARD_LIBRARIES
+ \ CMAKE_ASM_MASM_STANDARD_REQUIRED
+ \ CMAKE_ASM_MASM_SUPPORTED
\ CMAKE_ASM_MASM_VISIBILITY_PRESET
\ CMAKE_ASM_NASM
\ CMAKE_ASM_NASM_ANDROID_TOOLCHAIN_MACHINE
@@ -623,12 +685,15 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_NASM_ARCHIVE_APPEND
\ CMAKE_ASM_NASM_ARCHIVE_CREATE
\ CMAKE_ASM_NASM_ARCHIVE_FINISH
+ \ CMAKE_ASM_NASM_BYTE_ORDER
\ CMAKE_ASM_NASM_CLANG_TIDY
+ \ CMAKE_ASM_NASM_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_ASM_NASM_COMPILER
\ CMAKE_ASM_NASM_COMPILER_ABI
\ CMAKE_ASM_NASM_COMPILER_AR
\ CMAKE_ASM_NASM_COMPILER_ARCHITECTURE_ID
\ CMAKE_ASM_NASM_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_ASM_NASM_COMPILER_FRONTEND_VARIANT
\ CMAKE_ASM_NASM_COMPILER_ID
\ CMAKE_ASM_NASM_COMPILER_LAUNCHER
\ CMAKE_ASM_NASM_COMPILER_LOADED
@@ -643,6 +708,8 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY
\ CMAKE_ASM_NASM_CREATE_SHARED_MODULE
\ CMAKE_ASM_NASM_CREATE_STATIC_LIBRARY
+ \ CMAKE_ASM_NASM_EXTENSIONS
+ \ CMAKE_ASM_NASM_EXTENSIONS_DEFAULT
\ CMAKE_ASM_NASM_FLAGS
\ CMAKE_ASM_NASM_FLAGS_DEBUG
\ CMAKE_ASM_NASM_FLAGS_DEBUG_INIT
@@ -661,6 +728,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_NASM_INCLUDE_WHAT_YOU_USE
\ CMAKE_ASM_NASM_INIT
\ CMAKE_ASM_NASM_LIBRARY_ARCHITECTURE
+ \ CMAKE_ASM_NASM_LINKER_LAUNCHER
\ CMAKE_ASM_NASM_LINKER_PREFERENCE
\ CMAKE_ASM_NASM_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_ASM_NASM_LINKER_WRAPPER_FLAG
@@ -669,14 +737,19 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_NASM_LINK_LIBRARY_FILE_FLAG
\ CMAKE_ASM_NASM_LINK_LIBRARY_FLAG
\ CMAKE_ASM_NASM_LINK_LIBRARY_SUFFIX
+ \ CMAKE_ASM_NASM_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_ASM_NASM_OUTPUT_EXTENSION
\ CMAKE_ASM_NASM_PLATFORM_ID
\ CMAKE_ASM_NASM_SIMULATE_ID
\ CMAKE_ASM_NASM_SIMULATE_VERSION
\ CMAKE_ASM_NASM_SIZEOF_DATA_PTR
\ CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_ASM_NASM_STANDARD
+ \ CMAKE_ASM_NASM_STANDARD_DEFAULT
\ CMAKE_ASM_NASM_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_ASM_NASM_STANDARD_LIBRARIES
+ \ CMAKE_ASM_NASM_STANDARD_REQUIRED
+ \ CMAKE_ASM_NASM_SUPPORTED
\ CMAKE_ASM_NASM_VISIBILITY_PRESET
\ CMAKE_ASM_OUTPUT_EXTENSION
\ CMAKE_ASM_PLATFORM_ID
@@ -684,8 +757,12 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_SIMULATE_VERSION
\ CMAKE_ASM_SIZEOF_DATA_PTR
\ CMAKE_ASM_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_ASM_STANDARD
+ \ CMAKE_ASM_STANDARD_DEFAULT
\ CMAKE_ASM_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_ASM_STANDARD_LIBRARIES
+ \ CMAKE_ASM_STANDARD_REQUIRED
+ \ CMAKE_ASM_SUPPORTED
\ CMAKE_ASM_VISIBILITY_PRESET
\ CMAKE_AUTOGEN_ORIGIN_DEPENDS
\ CMAKE_AUTOGEN_PARALLEL
@@ -694,15 +771,18 @@ syn keyword cmakeVariable contained
\ CMAKE_AUTOMOC
\ CMAKE_AUTOMOC_COMPILER_PREDEFINES
\ CMAKE_AUTOMOC_DEPEND_FILTERS
+ \ CMAKE_AUTOMOC_EXECUTABLE
\ CMAKE_AUTOMOC_MACRO_NAMES
\ CMAKE_AUTOMOC_MOC_OPTIONS
\ CMAKE_AUTOMOC_PATH_PREFIX
\ CMAKE_AUTOMOC_RELAXED_MODE
\ CMAKE_AUTOMOC_EXECUTABLE
\ CMAKE_AUTORCC
+ \ CMAKE_AUTORCC_EXECUTABLE
\ CMAKE_AUTORCC_OPTIONS
\ CMAKE_AUTORCC_EXECUTABLE
\ CMAKE_AUTOUIC
+ \ CMAKE_AUTOUIC_EXECUTABLE
\ CMAKE_AUTOUIC_OPTIONS
\ CMAKE_AUTOUIC_SEARCH_PATHS
\ CMAKE_AUTOUIC_EXECUTABLE
@@ -733,6 +813,7 @@ syn keyword cmakeVariable contained
\ CMAKE_COMPILER_IS_GNUCXX
\ CMAKE_COMPILER_IS_GNUG77
\ CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
+ \ CMAKE_COMPILE_WARNING_AS_ERROR
\ CMAKE_CONFIGURATION_TYPES
\ CMAKE_CPACK_COMMAND
\ CMAKE_CROSSCOMPILING
@@ -745,12 +826,15 @@ syn keyword cmakeVariable contained
\ CMAKE_CSharp_ARCHIVE_APPEND
\ CMAKE_CSharp_ARCHIVE_CREATE
\ CMAKE_CSharp_ARCHIVE_FINISH
+ \ CMAKE_CSharp_BYTE_ORDER
\ CMAKE_CSharp_CLANG_TIDY
+ \ CMAKE_CSharp_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_CSharp_COMPILER
\ CMAKE_CSharp_COMPILER_ABI
\ CMAKE_CSharp_COMPILER_AR
\ CMAKE_CSharp_COMPILER_ARCHITECTURE_ID
\ CMAKE_CSharp_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_CSharp_COMPILER_FRONTEND_VARIANT
\ CMAKE_CSharp_COMPILER_ID
\ CMAKE_CSharp_COMPILER_LAUNCHER
\ CMAKE_CSharp_COMPILER_LOADED
@@ -765,6 +849,8 @@ syn keyword cmakeVariable contained
\ CMAKE_CSharp_CREATE_SHARED_LIBRARY
\ CMAKE_CSharp_CREATE_SHARED_MODULE
\ CMAKE_CSharp_CREATE_STATIC_LIBRARY
+ \ CMAKE_CSharp_EXTENSIONS
+ \ CMAKE_CSharp_EXTENSIONS_DEFAULT
\ CMAKE_CSharp_FLAGS
\ CMAKE_CSharp_FLAGS_DEBUG
\ CMAKE_CSharp_FLAGS_DEBUG_INIT
@@ -783,6 +869,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CSharp_INCLUDE_WHAT_YOU_USE
\ CMAKE_CSharp_INIT
\ CMAKE_CSharp_LIBRARY_ARCHITECTURE
+ \ CMAKE_CSharp_LINKER_LAUNCHER
\ CMAKE_CSharp_LINKER_PREFERENCE
\ CMAKE_CSharp_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_CSharp_LINKER_WRAPPER_FLAG
@@ -791,14 +878,19 @@ syn keyword cmakeVariable contained
\ CMAKE_CSharp_LINK_LIBRARY_FILE_FLAG
\ CMAKE_CSharp_LINK_LIBRARY_FLAG
\ CMAKE_CSharp_LINK_LIBRARY_SUFFIX
+ \ CMAKE_CSharp_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_CSharp_OUTPUT_EXTENSION
\ CMAKE_CSharp_PLATFORM_ID
\ CMAKE_CSharp_SIMULATE_ID
\ CMAKE_CSharp_SIMULATE_VERSION
\ CMAKE_CSharp_SIZEOF_DATA_PTR
\ CMAKE_CSharp_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_CSharp_STANDARD
+ \ CMAKE_CSharp_STANDARD_DEFAULT
\ CMAKE_CSharp_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_CSharp_STANDARD_LIBRARIES
+ \ CMAKE_CSharp_STANDARD_REQUIRED
+ \ CMAKE_CSharp_SUPPORTED
\ CMAKE_CSharp_VISIBILITY_PRESET
\ CMAKE_CTEST_ARGUMENTS
\ CMAKE_CTEST_COMMAND
@@ -810,12 +902,15 @@ syn keyword cmakeVariable contained
\ CMAKE_CUDA_ARCHIVE_APPEND
\ CMAKE_CUDA_ARCHIVE_CREATE
\ CMAKE_CUDA_ARCHIVE_FINISH
+ \ CMAKE_CUDA_BYTE_ORDER
\ CMAKE_CUDA_CLANG_TIDY
+ \ CMAKE_CUDA_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_CUDA_COMPILER
\ CMAKE_CUDA_COMPILER_ABI
\ CMAKE_CUDA_COMPILER_AR
\ CMAKE_CUDA_COMPILER_ARCHITECTURE_ID
\ CMAKE_CUDA_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_CUDA_COMPILER_FRONTEND_VARIANT
\ CMAKE_CUDA_COMPILER_ID
\ CMAKE_CUDA_COMPILER_LAUNCHER
\ CMAKE_CUDA_COMPILER_LOADED
@@ -832,6 +927,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CUDA_CREATE_SHARED_MODULE
\ CMAKE_CUDA_CREATE_STATIC_LIBRARY
\ CMAKE_CUDA_EXTENSIONS
+ \ CMAKE_CUDA_EXTENSIONS_DEFAULT
\ CMAKE_CUDA_FLAGS
\ CMAKE_CUDA_FLAGS_DEBUG
\ CMAKE_CUDA_FLAGS_DEBUG_INIT
@@ -851,6 +947,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CUDA_INCLUDE_WHAT_YOU_USE
\ CMAKE_CUDA_INIT
\ CMAKE_CUDA_LIBRARY_ARCHITECTURE
+ \ CMAKE_CUDA_LINKER_LAUNCHER
\ CMAKE_CUDA_LINKER_PREFERENCE
\ CMAKE_CUDA_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_CUDA_LINKER_WRAPPER_FLAG
@@ -859,6 +956,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CUDA_LINK_LIBRARY_FILE_FLAG
\ CMAKE_CUDA_LINK_LIBRARY_FLAG
\ CMAKE_CUDA_LINK_LIBRARY_SUFFIX
+ \ CMAKE_CUDA_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_CUDA_OUTPUT_EXTENSION
\ CMAKE_CUDA_PLATFORM_ID
\ CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
@@ -869,9 +967,11 @@ syn keyword cmakeVariable contained
\ CMAKE_CUDA_SIZEOF_DATA_PTR
\ CMAKE_CUDA_SOURCE_FILE_EXTENSIONS
\ CMAKE_CUDA_STANDARD
+ \ CMAKE_CUDA_STANDARD_DEFAULT
\ CMAKE_CUDA_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_CUDA_STANDARD_LIBRARIES
\ CMAKE_CUDA_STANDARD_REQUIRED
+ \ CMAKE_CUDA_SUPPORTED
\ CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
\ CMAKE_CUDA_VISIBILITY_PRESET
\ CMAKE_CURRENT_BINARY_DIR
@@ -890,12 +990,15 @@ syn keyword cmakeVariable contained
\ CMAKE_CXX_ARCHIVE_APPEND
\ CMAKE_CXX_ARCHIVE_CREATE
\ CMAKE_CXX_ARCHIVE_FINISH
+ \ CMAKE_CXX_BYTE_ORDER
\ CMAKE_CXX_CLANG_TIDY
+ \ CMAKE_CXX_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_CXX_COMPILER
\ CMAKE_CXX_COMPILER_ABI
\ CMAKE_CXX_COMPILER_AR
\ CMAKE_CXX_COMPILER_ARCHITECTURE_ID
\ CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_CXX_COMPILER_FRONTEND_VARIANT
\ CMAKE_CXX_COMPILER_ID
\ CMAKE_CXX_COMPILER_LAUNCHER
\ CMAKE_CXX_COMPILER_LOADED
@@ -912,6 +1015,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CXX_CREATE_SHARED_MODULE
\ CMAKE_CXX_CREATE_STATIC_LIBRARY
\ CMAKE_CXX_EXTENSIONS
+ \ CMAKE_CXX_EXTENSIONS_DEFAULT
\ CMAKE_CXX_FLAGS
\ CMAKE_CXX_FLAGS_DEBUG
\ CMAKE_CXX_FLAGS_DEBUG_INIT
@@ -939,16 +1043,20 @@ syn keyword cmakeVariable contained
\ CMAKE_CXX_LINK_LIBRARY_FILE_FLAG
\ CMAKE_CXX_LINK_LIBRARY_FLAG
\ CMAKE_CXX_LINK_LIBRARY_SUFFIX
+ \ CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_CXX_OUTPUT_EXTENSION
\ CMAKE_CXX_PLATFORM_ID
+ \ CMAKE_CXX_SCAN_FOR_MODULES
\ CMAKE_CXX_SIMULATE_ID
\ CMAKE_CXX_SIMULATE_VERSION
\ CMAKE_CXX_SIZEOF_DATA_PTR
\ CMAKE_CXX_SOURCE_FILE_EXTENSIONS
\ CMAKE_CXX_STANDARD
+ \ CMAKE_CXX_STANDARD_DEFAULT
\ CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_CXX_STANDARD_LIBRARIES
\ CMAKE_CXX_STANDARD_REQUIRED
+ \ CMAKE_CXX_SUPPORTED
\ CMAKE_CXX_VISIBILITY_PRESET
\ CMAKE_C_ANDROID_TOOLCHAIN_MACHINE
\ CMAKE_C_ANDROID_TOOLCHAIN_PREFIX
@@ -956,12 +1064,15 @@ syn keyword cmakeVariable contained
\ CMAKE_C_ARCHIVE_APPEND
\ CMAKE_C_ARCHIVE_CREATE
\ CMAKE_C_ARCHIVE_FINISH
+ \ CMAKE_C_BYTE_ORDER
\ CMAKE_C_CLANG_TIDY
+ \ CMAKE_C_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_C_COMPILER
\ CMAKE_C_COMPILER_ABI
\ CMAKE_C_COMPILER_AR
\ CMAKE_C_COMPILER_ARCHITECTURE_ID
\ CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_C_COMPILER_FRONTEND_VARIANT
\ CMAKE_C_COMPILER_ID
\ CMAKE_C_COMPILER_LAUNCHER
\ CMAKE_C_COMPILER_LOADED
@@ -978,6 +1089,7 @@ syn keyword cmakeVariable contained
\ CMAKE_C_CREATE_SHARED_MODULE
\ CMAKE_C_CREATE_STATIC_LIBRARY
\ CMAKE_C_EXTENSIONS
+ \ CMAKE_C_EXTENSIONS_DEFAULT
\ CMAKE_C_FLAGS
\ CMAKE_C_FLAGS_DEBUG
\ CMAKE_C_FLAGS_DEBUG_INIT
@@ -1005,6 +1117,7 @@ syn keyword cmakeVariable contained
\ CMAKE_C_LINK_LIBRARY_FILE_FLAG
\ CMAKE_C_LINK_LIBRARY_FLAG
\ CMAKE_C_LINK_LIBRARY_SUFFIX
+ \ CMAKE_C_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_C_OUTPUT_EXTENSION
\ CMAKE_C_PLATFORM_ID
\ CMAKE_C_SIMULATE_ID
@@ -1012,17 +1125,21 @@ syn keyword cmakeVariable contained
\ CMAKE_C_SIZEOF_DATA_PTR
\ CMAKE_C_SOURCE_FILE_EXTENSIONS
\ CMAKE_C_STANDARD
+ \ CMAKE_C_STANDARD_DEFAULT
\ CMAKE_C_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_C_STANDARD_LIBRARIES
\ CMAKE_C_STANDARD_REQUIRED
+ \ CMAKE_C_SUPPORTED
\ CMAKE_C_VISIBILITY_PRESET
\ CMAKE_DEBUG_POSTFIX
\ CMAKE_DEBUG_TARGET_PROPERTIES
\ CMAKE_DEFAULT_BUILD_TYPE
\ CMAKE_DEFAULT_CONFIGS
\ CMAKE_DEPENDS_IN_PROJECT_ONLY
+ \ CMAKE_DEPENDS_USE_COMPILER
\ CMAKE_DIRECTORY_LABELS
\ CMAKE_DISABLE_PRECOMPILE_HEADERS
+ \ CMAKE_DLL_NAME_WITH_SOVERSION
\ CMAKE_DL_LIBS
\ CMAKE_DOTNET_SDK
\ CMAKE_DOTNET_TARGET_FRAMEWORK
@@ -1036,7 +1153,20 @@ syn keyword cmakeVariable contained
\ CMAKE_ENABLE_EXPORTS
\ CMAKE_ERROR_DEPRECATED
\ CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+ \ CMAKE_EXECUTABLE_ENABLE_EXPORTS
\ CMAKE_EXECUTABLE_SUFFIX
+ \ CMAKE_EXECUTABLE_SUFFIX_ASM
+ \ CMAKE_EXECUTABLE_SUFFIX_ASM_MASM
+ \ CMAKE_EXECUTABLE_SUFFIX_ASM_NASM
+ \ CMAKE_EXECUTABLE_SUFFIX_C
+ \ CMAKE_EXECUTABLE_SUFFIX_CSharp
+ \ CMAKE_EXECUTABLE_SUFFIX_CUDA
+ \ CMAKE_EXECUTABLE_SUFFIX_CXX
+ \ CMAKE_EXECUTABLE_SUFFIX_Fortran
+ \ CMAKE_EXECUTABLE_SUFFIX_HIP
+ \ CMAKE_EXECUTABLE_SUFFIX_Java
+ \ CMAKE_EXECUTABLE_SUFFIX_RC
+ \ CMAKE_EXECUTABLE_SUFFIX_Swift
\ CMAKE_EXECUTE_PROCESS_COMMAND_ECHO
\ CMAKE_EXE_LINKER_FLAGS
\ CMAKE_EXE_LINKER_FLAGS_INIT
@@ -1056,9 +1186,11 @@ syn keyword cmakeVariable contained
\ CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
\ CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
\ CMAKE_FIND_PACKAGE_PREFER_CONFIG
+ \ CMAKE_FIND_PACKAGE_REDIRECTS_DIR
\ CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
\ CMAKE_FIND_PACKAGE_SORT_DIRECTION
\ CMAKE_FIND_PACKAGE_SORT_ORDER
+ \ CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
\ CMAKE_FIND_PACKAGE_WARN_NO_MODULE
\ CMAKE_FIND_ROOT_PATH
\ CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
@@ -1069,6 +1201,7 @@ syn keyword cmakeVariable contained
\ CMAKE_FIND_USE_INSTALL_PREFIX
\ CMAKE_FIND_USE_CMAKE_PATH
\ CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
+ \ CMAKE_FIND_USE_INSTALL_PREFIX
\ CMAKE_FIND_USE_PACKAGE_REGISTRY
\ CMAKE_FIND_USE_PACKAGE_ROOT_PATH
\ CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH
@@ -1083,12 +1216,15 @@ syn keyword cmakeVariable contained
\ CMAKE_Fortran_ARCHIVE_APPEND
\ CMAKE_Fortran_ARCHIVE_CREATE
\ CMAKE_Fortran_ARCHIVE_FINISH
+ \ CMAKE_Fortran_BYTE_ORDER
\ CMAKE_Fortran_CLANG_TIDY
+ \ CMAKE_Fortran_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_Fortran_COMPILER
\ CMAKE_Fortran_COMPILER_ABI
\ CMAKE_Fortran_COMPILER_AR
\ CMAKE_Fortran_COMPILER_ARCHITECTURE_ID
\ CMAKE_Fortran_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_Fortran_COMPILER_FRONTEND_VARIANT
\ CMAKE_Fortran_COMPILER_ID
\ CMAKE_Fortran_COMPILER_LAUNCHER
\ CMAKE_Fortran_COMPILER_LOADED
@@ -1103,6 +1239,8 @@ syn keyword cmakeVariable contained
\ CMAKE_Fortran_CREATE_SHARED_LIBRARY
\ CMAKE_Fortran_CREATE_SHARED_MODULE
\ CMAKE_Fortran_CREATE_STATIC_LIBRARY
+ \ CMAKE_Fortran_EXTENSIONS
+ \ CMAKE_Fortran_EXTENSIONS_DEFAULT
\ CMAKE_Fortran_FLAGS
\ CMAKE_Fortran_FLAGS_DEBUG
\ CMAKE_Fortran_FLAGS_DEBUG_INIT
@@ -1122,6 +1260,7 @@ syn keyword cmakeVariable contained
\ CMAKE_Fortran_INCLUDE_WHAT_YOU_USE
\ CMAKE_Fortran_INIT
\ CMAKE_Fortran_LIBRARY_ARCHITECTURE
+ \ CMAKE_Fortran_LINKER_LAUNCHER
\ CMAKE_Fortran_LINKER_PREFERENCE
\ CMAKE_Fortran_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_Fortran_LINKER_WRAPPER_FLAG
@@ -1130,6 +1269,7 @@ syn keyword cmakeVariable contained
\ CMAKE_Fortran_LINK_LIBRARY_FILE_FLAG
\ CMAKE_Fortran_LINK_LIBRARY_FLAG
\ CMAKE_Fortran_LINK_LIBRARY_SUFFIX
+ \ CMAKE_Fortran_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_Fortran_MODDIR_DEFAULT
\ CMAKE_Fortran_MODDIR_FLAG
\ CMAKE_Fortran_MODOUT_FLAG
@@ -1141,8 +1281,12 @@ syn keyword cmakeVariable contained
\ CMAKE_Fortran_SIMULATE_VERSION
\ CMAKE_Fortran_SIZEOF_DATA_PTR
\ CMAKE_Fortran_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_Fortran_STANDARD
+ \ CMAKE_Fortran_STANDARD_DEFAULT
\ CMAKE_Fortran_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_Fortran_STANDARD_LIBRARIES
+ \ CMAKE_Fortran_STANDARD_REQUIRED
+ \ CMAKE_Fortran_SUPPORTED
\ CMAKE_Fortran_VISIBILITY_PRESET
\ CMAKE_GENERATOR
\ CMAKE_GENERATOR_INSTANCE
@@ -1162,12 +1306,15 @@ syn keyword cmakeVariable contained
\ CMAKE_HIP_ARCHIVE_APPEND
\ CMAKE_HIP_ARCHIVE_CREATE
\ CMAKE_HIP_ARCHIVE_FINISH
+ \ CMAKE_HIP_BYTE_ORDER
\ CMAKE_HIP_CLANG_TIDY
+ \ CMAKE_HIP_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_HIP_COMPILER
\ CMAKE_HIP_COMPILER_ABI
\ CMAKE_HIP_COMPILER_AR
\ CMAKE_HIP_COMPILER_ARCHITECTURE_ID
\ CMAKE_HIP_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_HIP_COMPILER_FRONTEND_VARIANT
\ CMAKE_HIP_COMPILER_ID
\ CMAKE_HIP_COMPILER_LAUNCHER
\ CMAKE_HIP_COMPILER_LOADED
@@ -1184,6 +1331,7 @@ syn keyword cmakeVariable contained
\ CMAKE_HIP_CREATE_SHARED_MODULE
\ CMAKE_HIP_CREATE_STATIC_LIBRARY
\ CMAKE_HIP_EXTENSIONS
+ \ CMAKE_HIP_EXTENSIONS_DEFAULT
\ CMAKE_HIP_FLAGS
\ CMAKE_HIP_FLAGS_DEBUG
\ CMAKE_HIP_FLAGS_DEBUG_INIT
@@ -1211,6 +1359,7 @@ syn keyword cmakeVariable contained
\ CMAKE_HIP_LINK_LIBRARY_FILE_FLAG
\ CMAKE_HIP_LINK_LIBRARY_FLAG
\ CMAKE_HIP_LINK_LIBRARY_SUFFIX
+ \ CMAKE_HIP_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_HIP_OUTPUT_EXTENSION
\ CMAKE_HIP_PLATFORM_ID
\ CMAKE_HIP_SIMULATE_ID
@@ -1218,12 +1367,16 @@ syn keyword cmakeVariable contained
\ CMAKE_HIP_SIZEOF_DATA_PTR
\ CMAKE_HIP_SOURCE_FILE_EXTENSIONS
\ CMAKE_HIP_STANDARD
+ \ CMAKE_HIP_STANDARD_DEFAULT
\ CMAKE_HIP_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_HIP_STANDARD_LIBRARIES
\ CMAKE_HIP_STANDARD_REQUIRED
+ \ CMAKE_HIP_SUPPORTED
\ CMAKE_HIP_VISIBILITY_PRESET
\ CMAKE_HOME_DIRECTORY
\ CMAKE_HOST_APPLE
+ \ CMAKE_HOST_BSD
+ \ CMAKE_HOST_LINUX
\ CMAKE_HOST_SOLARIS
\ CMAKE_HOST_SYSTEM
\ CMAKE_HOST_SYSTEM_NAME
@@ -1232,6 +1385,7 @@ syn keyword cmakeVariable contained
\ CMAKE_HOST_UNIX
\ CMAKE_HOST_WIN32
\ CMAKE_IGNORE_PATH
+ \ CMAKE_IGNORE_PREFIX_PATH
\ CMAKE_IMPORT_LIBRARY_PREFIX
\ CMAKE_IMPORT_LIBRARY_SUFFIX
\ CMAKE_INCLUDE_CURRENT_DIR
@@ -1252,6 +1406,7 @@ syn keyword cmakeVariable contained
\ CMAKE_INTERPROCEDURAL_OPTIMIZATION
\ CMAKE_IOS_INSTALL_COMBINED
\ CMAKE_ISPC_HEADER_DIRECTORY
+ \ CMAKE_ISPC_HEADER_SUFFIX
\ CMAKE_ISPC_INSTRUCTION_SETS
\ CMAKE_JOB_POOLS
\ CMAKE_JOB_POOL_COMPILE
@@ -1264,12 +1419,15 @@ syn keyword cmakeVariable contained
\ CMAKE_Java_ARCHIVE_APPEND
\ CMAKE_Java_ARCHIVE_CREATE
\ CMAKE_Java_ARCHIVE_FINISH
+ \ CMAKE_Java_BYTE_ORDER
\ CMAKE_Java_CLANG_TIDY
+ \ CMAKE_Java_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_Java_COMPILER
\ CMAKE_Java_COMPILER_ABI
\ CMAKE_Java_COMPILER_AR
\ CMAKE_Java_COMPILER_ARCHITECTURE_ID
\ CMAKE_Java_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_Java_COMPILER_FRONTEND_VARIANT
\ CMAKE_Java_COMPILER_ID
\ CMAKE_Java_COMPILER_LAUNCHER
\ CMAKE_Java_COMPILER_LOADED
@@ -1284,6 +1442,8 @@ syn keyword cmakeVariable contained
\ CMAKE_Java_CREATE_SHARED_LIBRARY
\ CMAKE_Java_CREATE_SHARED_MODULE
\ CMAKE_Java_CREATE_STATIC_LIBRARY
+ \ CMAKE_Java_EXTENSIONS
+ \ CMAKE_Java_EXTENSIONS_DEFAULT
\ CMAKE_Java_FLAGS
\ CMAKE_Java_FLAGS_DEBUG
\ CMAKE_Java_FLAGS_DEBUG_INIT
@@ -1302,6 +1462,7 @@ syn keyword cmakeVariable contained
\ CMAKE_Java_INCLUDE_WHAT_YOU_USE
\ CMAKE_Java_INIT
\ CMAKE_Java_LIBRARY_ARCHITECTURE
+ \ CMAKE_Java_LINKER_LAUNCHER
\ CMAKE_Java_LINKER_PREFERENCE
\ CMAKE_Java_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_Java_LINKER_WRAPPER_FLAG
@@ -1310,15 +1471,22 @@ syn keyword cmakeVariable contained
\ CMAKE_Java_LINK_LIBRARY_FILE_FLAG
\ CMAKE_Java_LINK_LIBRARY_FLAG
\ CMAKE_Java_LINK_LIBRARY_SUFFIX
+ \ CMAKE_Java_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_Java_OUTPUT_EXTENSION
\ CMAKE_Java_PLATFORM_ID
\ CMAKE_Java_SIMULATE_ID
\ CMAKE_Java_SIMULATE_VERSION
\ CMAKE_Java_SIZEOF_DATA_PTR
\ CMAKE_Java_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_Java_STANDARD
+ \ CMAKE_Java_STANDARD_DEFAULT
\ CMAKE_Java_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_Java_STANDARD_LIBRARIES
+ \ CMAKE_Java_STANDARD_REQUIRED
+ \ CMAKE_Java_SUPPORTED
\ CMAKE_Java_VISIBILITY_PRESET
+ \ CMAKE_KATE_FILES_MODE
+ \ CMAKE_KATE_MAKE_ARGUMENTS
\ CMAKE_LIBRARY_ARCHITECTURE
\ CMAKE_LIBRARY_ARCHITECTURE_REGEX
\ CMAKE_LIBRARY_OUTPUT_DIRECTORY
@@ -1326,14 +1494,17 @@ syn keyword cmakeVariable contained
\ CMAKE_LIBRARY_PATH_FLAG
\ CMAKE_LINK_DEF_FILE_FLAG
\ CMAKE_LINK_DEPENDS_NO_SHARED
+ \ CMAKE_LINK_DEPENDS_USE_LINKER
\ CMAKE_LINK_DIRECTORIES_BEFORE
\ CMAKE_LINK_INTERFACE_LIBRARIES
+ \ CMAKE_LINK_LIBRARIES_ONLY_TARGETS
\ CMAKE_LINK_LIBRARY_FILE_FLAG
\ CMAKE_LINK_LIBRARY_FLAG
\ CMAKE_LINK_LIBRARY_SUFFIX
\ CMAKE_LINK_SEARCH_END_STATIC
\ CMAKE_LINK_SEARCH_START_STATIC
\ CMAKE_LINK_WHAT_YOU_USE
+ \ CMAKE_LINK_WHAT_YOU_USE_CHECK
\ CMAKE_MACOSX_BUNDLE
\ CMAKE_MACOSX_RPATH
\ CMAKE_MAJOR_VERSION
@@ -1351,6 +1522,7 @@ syn keyword cmakeVariable contained
\ CMAKE_MODULE_LINKER_FLAGS_INIT
\ CMAKE_MODULE_PATH
\ CMAKE_MSVCIDE_RUN_PATH
+ \ CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
\ CMAKE_MSVC_RUNTIME_LIBRARY
\ CMAKE_NETRC
\ CMAKE_NETRC_FILE
@@ -1378,6 +1550,7 @@ syn keyword cmakeVariable contained
\ CMAKE_PCH_INSTANTIATE_TEMPLATES
\ CMAKE_PCH_WARN_INVALID
\ CMAKE_PDB_OUTPUT_DIRECTORY
+ \ CMAKE_PLATFORM_NO_VERSIONED_SONAME
\ CMAKE_POSITION_INDEPENDENT_CODE
\ CMAKE_PREFIX_PATH
\ CMAKE_PROGRAM_PATH
@@ -1386,6 +1559,7 @@ syn keyword cmakeVariable contained
\ CMAKE_PROJECT_INCLUDE
\ CMAKE_PROJECT_INCLUDE_BEFORE
\ CMAKE_PROJECT_NAME
+ \ CMAKE_PROJECT_TOP_LEVEL_INCLUDES
\ CMAKE_PROJECT_VERSION
\ CMAKE_PROJECT_VERSION_MAJOR
\ CMAKE_PROJECT_VERSION_MINOR
@@ -1399,12 +1573,15 @@ syn keyword cmakeVariable contained
\ CMAKE_RC_ARCHIVE_APPEND
\ CMAKE_RC_ARCHIVE_CREATE
\ CMAKE_RC_ARCHIVE_FINISH
+ \ CMAKE_RC_BYTE_ORDER
\ CMAKE_RC_CLANG_TIDY
+ \ CMAKE_RC_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_RC_COMPILER
\ CMAKE_RC_COMPILER_ABI
\ CMAKE_RC_COMPILER_AR
\ CMAKE_RC_COMPILER_ARCHITECTURE_ID
\ CMAKE_RC_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_RC_COMPILER_FRONTEND_VARIANT
\ CMAKE_RC_COMPILER_ID
\ CMAKE_RC_COMPILER_LAUNCHER
\ CMAKE_RC_COMPILER_LOADED
@@ -1419,6 +1596,8 @@ syn keyword cmakeVariable contained
\ CMAKE_RC_CREATE_SHARED_LIBRARY
\ CMAKE_RC_CREATE_SHARED_MODULE
\ CMAKE_RC_CREATE_STATIC_LIBRARY
+ \ CMAKE_RC_EXTENSIONS
+ \ CMAKE_RC_EXTENSIONS_DEFAULT
\ CMAKE_RC_FLAGS
\ CMAKE_RC_FLAGS_DEBUG
\ CMAKE_RC_FLAGS_DEBUG_INIT
@@ -1437,6 +1616,7 @@ syn keyword cmakeVariable contained
\ CMAKE_RC_INCLUDE_WHAT_YOU_USE
\ CMAKE_RC_INIT
\ CMAKE_RC_LIBRARY_ARCHITECTURE
+ \ CMAKE_RC_LINKER_LAUNCHER
\ CMAKE_RC_LINKER_PREFERENCE
\ CMAKE_RC_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_RC_LINKER_WRAPPER_FLAG
@@ -1445,19 +1625,25 @@ syn keyword cmakeVariable contained
\ CMAKE_RC_LINK_LIBRARY_FILE_FLAG
\ CMAKE_RC_LINK_LIBRARY_FLAG
\ CMAKE_RC_LINK_LIBRARY_SUFFIX
+ \ CMAKE_RC_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_RC_OUTPUT_EXTENSION
\ CMAKE_RC_PLATFORM_ID
\ CMAKE_RC_SIMULATE_ID
\ CMAKE_RC_SIMULATE_VERSION
\ CMAKE_RC_SIZEOF_DATA_PTR
\ CMAKE_RC_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_RC_STANDARD
+ \ CMAKE_RC_STANDARD_DEFAULT
\ CMAKE_RC_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_RC_STANDARD_LIBRARIES
+ \ CMAKE_RC_STANDARD_REQUIRED
+ \ CMAKE_RC_SUPPORTED
\ CMAKE_RC_VISIBILITY_PRESET
\ CMAKE_ROOT
\ CMAKE_RULE_MESSAGES
\ CMAKE_RUNTIME_OUTPUT_DIRECTORY
\ CMAKE_SCRIPT_MODE_FILE
+ \ CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS
\ CMAKE_SHARED_LIBRARY_PREFIX
\ CMAKE_SHARED_LIBRARY_SUFFIX
\ CMAKE_SHARED_LINKER_FLAGS
@@ -1486,6 +1672,7 @@ syn keyword cmakeVariable contained
\ CMAKE_SYSTEM_APPBUNDLE_PATH
\ CMAKE_SYSTEM_FRAMEWORK_PATH
\ CMAKE_SYSTEM_IGNORE_PATH
+ \ CMAKE_SYSTEM_IGNORE_PREFIX_PATH
\ CMAKE_SYSTEM_INCLUDE_PATH
\ CMAKE_SYSTEM_LIBRARY_PATH
\ CMAKE_SYSTEM_NAME
@@ -1500,12 +1687,15 @@ syn keyword cmakeVariable contained
\ CMAKE_Swift_ARCHIVE_APPEND
\ CMAKE_Swift_ARCHIVE_CREATE
\ CMAKE_Swift_ARCHIVE_FINISH
+ \ CMAKE_Swift_BYTE_ORDER
\ CMAKE_Swift_CLANG_TIDY
+ \ CMAKE_Swift_CLANG_TIDY_EXPORT_FIXES_DIR
\ CMAKE_Swift_COMPILER
\ CMAKE_Swift_COMPILER_ABI
\ CMAKE_Swift_COMPILER_AR
\ CMAKE_Swift_COMPILER_ARCHITECTURE_ID
\ CMAKE_Swift_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_Swift_COMPILER_FRONTEND_VARIANT
\ CMAKE_Swift_COMPILER_ID
\ CMAKE_Swift_COMPILER_LAUNCHER
\ CMAKE_Swift_COMPILER_LOADED
@@ -1520,6 +1710,8 @@ syn keyword cmakeVariable contained
\ CMAKE_Swift_CREATE_SHARED_LIBRARY
\ CMAKE_Swift_CREATE_SHARED_MODULE
\ CMAKE_Swift_CREATE_STATIC_LIBRARY
+ \ CMAKE_Swift_EXTENSIONS
+ \ CMAKE_Swift_EXTENSIONS_DEFAULT
\ CMAKE_Swift_FLAGS
\ CMAKE_Swift_FLAGS_DEBUG
\ CMAKE_Swift_FLAGS_DEBUG_INIT
@@ -1539,6 +1731,7 @@ syn keyword cmakeVariable contained
\ CMAKE_Swift_INIT
\ CMAKE_Swift_LANGUAGE_VERSION
\ CMAKE_Swift_LIBRARY_ARCHITECTURE
+ \ CMAKE_Swift_LINKER_LAUNCHER
\ CMAKE_Swift_LINKER_PREFERENCE
\ CMAKE_Swift_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_Swift_LINKER_WRAPPER_FLAG
@@ -1547,6 +1740,7 @@ syn keyword cmakeVariable contained
\ CMAKE_Swift_LINK_LIBRARY_FILE_FLAG
\ CMAKE_Swift_LINK_LIBRARY_FLAG
\ CMAKE_Swift_LINK_LIBRARY_SUFFIX
+ \ CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG
\ CMAKE_Swift_MODULE_DIRECTORY
\ CMAKE_Swift_NUM_THREADS
\ CMAKE_Swift_OUTPUT_EXTENSION
@@ -1555,16 +1749,25 @@ syn keyword cmakeVariable contained
\ CMAKE_Swift_SIMULATE_VERSION
\ CMAKE_Swift_SIZEOF_DATA_PTR
\ CMAKE_Swift_SOURCE_FILE_EXTENSIONS
+ \ CMAKE_Swift_STANDARD
+ \ CMAKE_Swift_STANDARD_DEFAULT
\ CMAKE_Swift_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_Swift_STANDARD_LIBRARIES
+ \ CMAKE_Swift_STANDARD_REQUIRED
+ \ CMAKE_Swift_SUPPORTED
\ CMAKE_Swift_VISIBILITY_PRESET
+ \ CMAKE_TASKING_TOOLSET
+ \ CMAKE_TLS_CAINFO
+ \ CMAKE_TLS_VERIFY
\ CMAKE_TOOLCHAIN_FILE
\ CMAKE_TRY_COMPILE_CONFIGURATION
+ \ CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
\ CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
\ CMAKE_TRY_COMPILE_TARGET_TYPE
\ CMAKE_TWEAK_VERSION
\ CMAKE_UNITY_BUILD
\ CMAKE_UNITY_BUILD_BATCH_SIZE
+ \ CMAKE_UNITY_BUILD_UNIQUE_ID
\ CMAKE_USER_MAKE_RULES_OVERRIDE
\ CMAKE_USER_MAKE_RULES_OVERRIDE_ASM
\ CMAKE_USER_MAKE_RULES_OVERRIDE_ASM_MASM
@@ -1580,8 +1783,13 @@ syn keyword cmakeVariable contained
\ CMAKE_USER_MAKE_RULES_OVERRIDE_Swift
\ CMAKE_USE_RELATIVE_PATHS
\ CMAKE_VERBOSE_MAKEFILE
+ \ CMAKE_VERIFY_INTERFACE_HEADER_SETS
\ CMAKE_VERSION
\ CMAKE_VISIBILITY_INLINES_HIDDEN
+ \ CMAKE_VS_DEBUGGER_COMMAND
+ \ CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS
+ \ CMAKE_VS_DEBUGGER_ENVIRONMENT
+ \ CMAKE_VS_DEBUGGER_WORKING_DIRECTORY
\ CMAKE_VS_DEVENV_COMMAND
\ CMAKE_VS_GLOBALS
\ CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
@@ -1589,6 +1797,8 @@ syn keyword cmakeVariable contained
\ CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
\ CMAKE_VS_JUST_MY_CODE_DEBUGGING
\ CMAKE_VS_MSBUILD_COMMAND
+ \ CMAKE_VS_NO_COMPILE_BATCHING
+ \ CMAKE_VS_NUGET_PACKAGE_RESTORE
\ CMAKE_VS_NsightTegra_VERSION
\ CMAKE_VS_PLATFORM_NAME
\ CMAKE_VS_PLATFORM_NAME_DEFAULT
@@ -1604,11 +1814,17 @@ syn keyword cmakeVariable contained
\ CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES
\ CMAKE_VS_SDK_REFERENCE_DIRECTORIES
\ CMAKE_VS_SDK_SOURCE_DIRECTORIES
+ \ CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER
+ \ CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION
+ \ CMAKE_VS_TARGET_FRAMEWORK_VERSION
+ \ CMAKE_VS_VERSION_BUILD_NUMBER
+ \ CMAKE_VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
\ CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
\ CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM
\ CMAKE_VS_WINRT_BY_DEFAULT
\ CMAKE_WARN_DEPRECATED
\ CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
+ \ CMAKE_WATCOM_RUNTIME_LIBRARY
\ CMAKE_WIN32_EXECUTABLE
\ CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
\ CMAKE_XCODE_BUILD_SYSTEM
@@ -1623,8 +1839,12 @@ syn keyword cmakeVariable contained
\ CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
\ CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
\ CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
+ \ CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+ \ CMAKE_XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
+ \ CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
\ CMAKE_XCODE_SCHEME_ENVIRONMENT
\ CMAKE_XCODE_SCHEME_GUARD_MALLOC
+ \ CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
\ CMAKE_XCODE_SCHEME_LAUNCH_MODE
\ CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
\ CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
@@ -1639,8 +1859,10 @@ syn keyword cmakeVariable contained
\ CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
\ CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
\ CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
+ \ CMAKE_XCODE_XCCONFIG
\ CPACK_ABSOLUTE_DESTINATION_FILES
\ CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
+ \ CPACK_CUSTOM_INSTALL_VARIABLES
\ CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
\ CPACK_INCLUDE_TOPLEVEL_DIRECTORY
\ CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
@@ -1675,6 +1897,7 @@ syn keyword cmakeVariable contained
\ CTEST_CUSTOM_PRE_MEMCHECK
\ CTEST_CUSTOM_PRE_TEST
\ CTEST_CUSTOM_TESTS_IGNORE
+ \ CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION
\ CTEST_CUSTOM_WARNING_EXCEPTION
\ CTEST_CUSTOM_WARNING_MATCH
\ CTEST_CVS_CHECKOUT
@@ -1707,6 +1930,7 @@ syn keyword cmakeVariable contained
\ CTEST_RESOURCE_SPEC_FILE
\ CTEST_RUN_CURRENT_SCRIPT
\ CTEST_SCP_COMMAND
+ \ CTEST_SCRIPT_DIRECTORY
\ CTEST_SITE
\ CTEST_SOURCE_DIRECTORY
\ CTEST_SUBMIT_INACTIVITY_TIMEOUT
@@ -2005,6 +2229,7 @@ syn keyword cmakeVariable contained
\ GHSMULTI
\ IOS
\ LIBRARY_OUTPUT_PATH
+ \ LINUX
\ MINGW
\ MSVC
\ MSVC10
@@ -2023,6 +2248,7 @@ syn keyword cmakeVariable contained
\ PROJECT_BINARY_DIR
\ PROJECT_DESCRIPTION
\ PROJECT_HOMEPAGE_URL
+ \ PROJECT_IS_TOP_LEVEL
\ PROJECT_NAME
\ PROJECT_SOURCE_DIR
\ PROJECT_VERSION
@@ -2040,6 +2266,7 @@ syn keyword cmakeVariable contained
syn keyword cmakeModule contained
\ ExternalProject
+ \ FetchContent
syn keyword cmakeKWExternalProject contained
\ AWS
@@ -2053,10 +2280,10 @@ syn keyword cmakeKWExternalProject contained
\ CMAKE_CACHE_ARGS
\ CMAKE_CACHE_DEFAULT_ARGS
\ CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY
- \ CMAKE_TLS_CAINFO
- \ CMAKE_TLS_VERIFY
+ \ CMAKE_INSTALL_MODE
\ COMMENT
\ CONFIGURE_COMMAND
+ \ CONFIGURE_HANDLED_BY_BUILD
\ CVS
\ CVSROOT
\ CVS_MODULE
@@ -2068,6 +2295,7 @@ syn keyword cmakeKWExternalProject contained
\ DOWNLOADED_FILE
\ DOWNLOAD_COMMAND
\ DOWNLOAD_DIR
+ \ DOWNLOAD_EXTRACT_TIMESTAMP
\ DOWNLOAD_NAME
\ DOWNLOAD_NO_EXTRACT
\ DOWNLOAD_NO_PROGRESS
@@ -2159,24 +2387,90 @@ syn keyword cmakeKWExternalProject contained
\ USES_TERMINAL_UPDATE
\ WORKING_DIRECTORY
+syn keyword cmakeKWFetchContent contained
+ \ ALWAYS
+ \ BINARY_DIR
+ \ BUILD_COMMAND
+ \ BYPASS_PROVIDER
+ \ CMAKE_PROJECT_
+ \ CONFIGURE_COMMAND
+ \ COPY
+ \ CORRECT
+ \ DCMAKE_TOOLCHAIN_FILE
+ \ DESTINATION
+ \ DOWNLOAD_NO_EXTRACT
+ \ EXISTS
+ \ FETCHCONTENT_BASE_DIR
+ \ FETCHCONTENT_FULLY_DISCONNECTED
+ \ FETCHCONTENT_MAKEAVAILABLE_SERIAL
+ \ FETCHCONTENT_QUIET
+ \ FETCHCONTENT_SOURCE_DIR_
+ \ FETCHCONTENT_TRY_FIND_PACKAGE_MODE
+ \ FETCHCONTENT_UPDATES_DISCONNECTED
+ \ FETCHCONTENT_UPDATES_DISCONNECTED_
+ \ FIND_PACKAGE_ARGS
+ \ GIT_REPOSITORY
+ \ GIT_TAG
+ \ GLOBAL
+ \ GTEST_BOTH_LIBRARIES
+ \ GTEST_LIBRARIES
+ \ GTEST_MAIN_LIBRARIES
+ \ INSTALL_COMMAND
+ \ INTERNAL
+ \ NAME
+ \ NAMES
+ \ NEVER
+ \ NOTE
+ \ OFF
+ \ OPTIONAL
+ \ OPT_IN
+ \ OVERRIDE_FIND_PACKAGE
+ \ PACKAGE_VERSION_COMPATIBLE
+ \ PACKAGE_VERSION_EXACT
+ \ QUIET
+ \ SOURCE_SUBDIR
+ \ STREQUAL
+ \ SUBBUILD_DIR
+ \ SVN_REPOSITORY
+ \ SVN_REVISION
+ \ SYSTEM
+ \ TARGET
+ \ TEST_COMMAND
+ \ TRUE
+ \ URL
+ \ URL_HASH
+ \ VERIFY_INTERFACE_HEADER_SETS
+ \ WRITE
+ \ WRONG
+ \ _BINARY_DIR
+ \ _INCLUDE
+ \ _POPULATED
+ \ _SOURCE_DIR
+
syn keyword cmakeKWadd_compile_definitions contained
\ COMPILE_DEFINITIONS
\ VAR
syn keyword cmakeKWadd_compile_options contained
+ \ CMAKE_
+ \ COMPILE_LANGUAGE
\ COMPILE_OPTIONS
+ \ CONFIG
\ SHELL
\ UNIX_COMMAND
- \ WX
+ \ _FLAGS
+ \ _FLAGS_
syn keyword cmakeKWadd_custom_command contained
\ APPEND
\ ARGS
+ \ BNF
\ BYPRODUCTS
\ CC
\ COMMAND
\ COMMAND_EXPAND_LISTS
\ COMMENT
+ \ CONFIG
\ CROSSCOMPILING_EMULATOR
\ DEPENDS
\ DEPENDS_EXPLICIT_ONLY
@@ -2188,6 +2482,7 @@ syn keyword cmakeKWadd_custom_command contained
\ JOB_POOLS
\ JOIN
\ MAIN_DEPENDENCY
+ \ MODULE
\ NOT
\ OUTPUT
\ PATH
@@ -2263,17 +2558,21 @@ syn keyword cmakeKWadd_library contained
\ FRAMEWORK
\ GLOBAL
\ HEADER_FILE_ONLY
+ \ HEADER_SETS
\ IMPORTED
\ IMPORTED_
\ IMPORTED_IMPLIB
\ IMPORTED_IMPLIB_
\ IMPORTED_LOCATION
\ IMPORTED_LOCATION_
+ \ IMPORTED_NO_SONAME
\ IMPORTED_OBJECTS
\ IMPORTED_OBJECTS_
+ \ IMPORTED_SONAME
\ INTERFACE
\ INTERFACE_
\ INTERFACE_SOURCES
+ \ LC_ID_DYLIB
\ LIBRARY_OUTPUT_DIRECTORY
\ MODULE
\ OBJECT
@@ -2283,22 +2582,25 @@ syn keyword cmakeKWadd_library contained
\ POST_BUILD
\ PRE_BUILD
\ PRE_LINK
- \ PRIVATE
- \ PUBLIC
+ \ PRIVATE_HEADER
+ \ PUBLIC_HEADER
\ RUNTIME_OUTPUT_DIRECTORY
\ SHARED
+ \ SONAME
\ SOURCES
\ STATIC
+ \ TARGETS
\ TARGET_OBJECTS
+ \ TARGET_RUNTIME_DLLS
\ UNKNOWN
syn keyword cmakeKWadd_link_options contained
\ CMAKE_
+ \ CONFIG
\ CUDA_RESOLVE_DEVICE_SYMBOLS
\ CUDA_SEPARABLE_COMPILATION
\ DEVICE_LINK
\ GCC
- \ GNU
\ HOST_LINK
\ LANG
\ LINKER
@@ -2306,11 +2608,14 @@ syn keyword cmakeKWadd_link_options contained
\ SHELL
\ STATIC_LIBRARY_OPTIONS
\ UNIX_COMMAND
+ \ _FLAGS
+ \ _FLAGS_
\ _LINKER_WRAPPER_FLAG
\ _LINKER_WRAPPER_FLAG_SEP
syn keyword cmakeKWadd_subdirectory contained
\ EXCLUDE_FROM_ALL
+ \ SYSTEM
syn keyword cmakeKWadd_test contained
\ BUILD_TESTING
@@ -2324,15 +2629,64 @@ syn keyword cmakeKWadd_test contained
\ SKIP_REGULAR_EXPRESSION
\ TARGET_FILE
\ WILL_FAIL
+ \ WILL_FALL
\ WORKING_DIRECTORY
+syn keyword cmakeKWblock contained
+ \ PARENT_SCOPE
+ \ POLICIES
+ \ PROPAGATE
+ \ PUSH
+ \ SCOPE_FOR
+ \ TRUE
+ \ VARIABLES
+
syn keyword cmakeKWbuild_command contained
\ CONFIGURATION
+ \ PARALLEL_LEVEL
\ TARGET
+syn keyword cmakeKWcmake_file_api contained
+ \ API
+ \ API_VERSION
+ \ BUILD_DIR
+ \ CMAKEFILES
+ \ CODEMODEL
+ \ COMMAND
+ \ CONFIG
+ \ QUERY
+ \ TOOLCHAINS
+
syn keyword cmakeKWcmake_host_system_information contained
+ \ APPEND
\ AVAILABLE_PHYSICAL_MEMORY
\ AVAILABLE_VIRTUAL_MEMORY
+ \ BOTH
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
+ \ CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS
+ \ DISTRIB_INFO
+ \ DISTRIB_PRETTY_NAME
+ \ DISTRO
+ \ DISTRO_BUG_REPORT_URL
+ \ DISTRO_HOME_URL
+ \ DISTRO_ID
+ \ DISTRO_ID_LIKE
+ \ DISTRO_NAME
+ \ DISTRO_PRETTY_NAME
+ \ DISTRO_PRIVACY_POLICY_URL
+ \ DISTRO_SUPPORT_URL
+ \ DISTRO_UBUNTU_CODENAME
+ \ DISTRO_VERSION
+ \ DISTRO_VERSION_CODENAME
+ \ DISTRO_VERSION_ID
+ \ ERROR_VARIABLE
+ \ EXISTS
\ FQDN
\ HAS_FPU
\ HAS_MMX
@@ -2341,38 +2695,101 @@ syn keyword cmakeKWcmake_host_system_information contained
\ HAS_SSE
\ HAS_SSE_FP
\ HAS_SSE_MMX
+ \ HKCC
+ \ HKCR
+ \ HKCU
+ \ HKEY_CLASSES_ROOT
+ \ HKEY_CURRENT_CONFIG
+ \ HKEY_CURRENT_USER
+ \ HKEY_LOCAL_MACHINE
+ \ HKEY_USERS
+ \ HKLM
+ \ HKU
\ HOSTNAME
\ ID
+ \ LIMIT_COUNT
+ \ LISTS
+ \ LTS
+ \ MATCHES
+ \ NNN
+ \ NOT
\ NUMBER_OF_LOGICAL_CORES
\ NUMBER_OF_PHYSICAL_CORES
\ OS_NAME
\ OS_PLATFORM
\ OS_RELEASE
\ OS_VERSION
+ \ PRETTY_NAME
\ PROCESSOR_DESCRIPTION
\ PROCESSOR_NAME
\ PROCESSOR_SERIAL_NUMBER
\ QUERY
+ \ REG_DWORD
+ \ REG_EXPAND_SZ
+ \ REG_MULTI_SZ
+ \ REG_QWORD
+ \ REG_SZ
\ RESULT
+ \ SEPARATOR
+ \ SOFTWARE
+ \ STATUS
+ \ STRINGS
+ \ SUBKEYS
+ \ TARGET
\ TOTAL_PHYSICAL_MEMORY
\ TOTAL_VIRTUAL_MEMORY
+ \ VALUE_NAMES
+ \ VAR
+ \ VIEW
+ \ WINDOWS_REGISTRY
syn keyword cmakeKWcmake_language contained
\ AND
+ \ ANY
+ \ APPEND
+ \ ARGN
+ \ BINARY_DIR
+ \ BYPASS_PROVIDER
\ CALL
\ CANCEL_CALL
\ CODE
+ \ COMMAND
+ \ COMMAND_ERROR_IS_FATAL
+ \ DCMAKE_PROJECT_TOP_LEVEL_INCLUDES
\ DEFER
\ DIRECTORY
\ EVAL
\ FALSE
+ \ FETCHCONTENT_MAKEAVAILABE_SERIAL
+ \ FETCHCONTENT_MAKEAVAILABLE_SERIAL
+ \ FETCHCONTENT_SOURCE_DIR_
+ \ FETCHCONTENT_TRY_FIND_PACKAGE_MODE
+ \ FIND_PACKAGE
+ \ FIND_PACKAGE_ARGS
\ GET_CALL_IDS
- \ ID
+ \ GET_MESSAGE_LOG_LEVEL
+ \ GIT_REPOSITORY
+ \ GIT_SUBMODULES
+ \ GIT_TAG
\ ID_VAR
- \ OR
+ \ MATCHES
+ \ MYCOMP_PROVIDER_INSTALL_DIR
+ \ NEVER
+ \ NOT
+ \ OVERRIDE_FIND_PACKAGE
+ \ PATH
+ \ POP_BACK
+ \ QUIET
+ \ SET_DEPENDENCY_PROVIDER
+ \ SOURCE_DIR
\ STATUS
+ \ STREQUAL
+ \ SUPPORTED_METHODS
\ TRUE
+ \ VERSION
\ WRITE
+ \ _FOUND
+ \ _PATH
syn keyword cmakeKWcmake_minimum_required contained
\ FATAL_ERROR
@@ -2407,22 +2824,21 @@ syn keyword cmakeKWcmake_path contained
\ ABSOLUTE_PATH
\ AND
\ APPEND
+ \ APPEND_STRING
\ BASE_DIRECTORY
- \ CMAKE_PATH
\ COMPARE
- \ CONCAT
\ CONVERT
- \ ELSEIF
- \ ENDIF
+ \ EQUAL
\ EXTENSION
\ EXTENSION_DEF
\ FALSE
+ \ FILENAME
\ FILENAME_DEF
\ GET
\ GET_EXTENSION
\ GET_FILENAME
\ GET_PARENT_PATH
- \ GET_RELATIVE_PATH
+ \ GET_RELATIVE_PART
\ GET_ROOT_DIRECTORY
\ GET_ROOT_NAME
\ GET_ROOT_PATH
@@ -2431,12 +2847,11 @@ syn keyword cmakeKWcmake_path contained
\ HAS_EXTENSION
\ HAS_FILENAME
\ HAS_PARENT_PATH
- \ HAS_RELATIVE_PATH
+ \ HAS_RELATIVE_PART
\ HAS_ROOT_DIRECTORY
\ HAS_ROOT_NAME
\ HAS_ROOT_PATH
\ HAS_STEM
- \ IF
\ IS_ABSOLUTE
\ IS_PREFIX
\ IS_RELATIVE
@@ -2445,23 +2860,21 @@ syn keyword cmakeKWcmake_path contained
\ NATIVE_PATH
\ NORMALIZE
\ NORMAL_PATH
- \ NOT
\ NOT_EQUAL
\ OP
- \ OS
\ OUTPUT_VARIABLE
\ PARENT_PATH
- \ PROXIMATE_PATH
\ REAL_PATH
+ \ RELATIVE_PART
\ RELATIVE_PATH
\ REMOVE_EXTENSION
\ REMOVE_FILENAME
\ REPLACE_EXTENSION
\ REPLACE_FILENAME
- \ RETURN
\ ROOT_DIRECTORY
\ ROOT_NAME
\ ROOT_PATH
+ \ SET
\ STEM
\ STREQUAL
\ TO_CMAKE_PATH_LIST
@@ -2476,8 +2889,10 @@ syn keyword cmakeKWcmake_policy contained
\ NNNN
\ NO_POLICY_SCOPE
\ OLD
+ \ POLICIES
\ POP
\ PUSH
+ \ SCOPE_FOR
\ SET
\ VERSION
@@ -2489,9 +2904,14 @@ syn keyword cmakeKWconfigure_file contained
\ FILE_PERMISSIONS
\ FOO_ENABLE
\ FOO_STRING
+ \ GENERATE
+ \ INTERFACE
\ LF
\ NEWLINE_STYLE
\ NO_SOURCE_PERMISSIONS
+ \ PRIVATE
+ \ PUBLIC
+ \ SYSTEM
\ USE_SOURCE_PERMISSIONS
\ VAR
@@ -2506,6 +2926,7 @@ syn keyword cmakeKWctest_build contained
\ APPEND
\ BUILD
\ CAPTURE_CMAKE_ERROR
+ \ CMAKE_BUILD_PARALLEL_LEVEL
\ CONFIGURATION
\ CTEST_BUILD_CONFIGURATION
\ CTEST_BUILD_FLAGS
@@ -2513,6 +2934,7 @@ syn keyword cmakeKWctest_build contained
\ FLAGS
\ NUMBER_ERRORS
\ NUMBER_WARNINGS
+ \ PARALLEL_LEVEL
\ QUIET
\ RETURN_VALUE
\ TARGET
@@ -2537,6 +2959,7 @@ syn keyword cmakeKWctest_coverage contained
syn keyword cmakeKWctest_memcheck contained
\ APPEND
\ BUILD
+ \ CAPTURE_CMAKE_ERROR
\ DEFECT_COUNT
\ EXCLUDE
\ EXCLUDE_FIXTURE
@@ -2547,11 +2970,15 @@ syn keyword cmakeKWctest_memcheck contained
\ INCLUDE_LABEL
\ OFF
\ ON
+ \ OUTPUT_JUNIT
\ PARALLEL_LEVEL
\ QUIET
+ \ REPEAT
+ \ RESOURCE_SPEC_FILE
\ RETURN_VALUE
\ SCHEDULE_RANDOM
\ START
+ \ STOP_ON_FAILURE
\ STOP_TIME
\ STRIDE
\ TEST_LOAD
@@ -2587,6 +3014,8 @@ syn keyword cmakeKWctest_submit contained
syn keyword cmakeKWctest_test contained
\ AFTER_TIMEOUT
\ APPEND
+ \ ATTACHED_FILES
+ \ ATTACHED_FILES_ON_FAIL
\ BUILD
\ CAPTURE_CMAKE_ERROR
\ CPU
@@ -2597,8 +3026,10 @@ syn keyword cmakeKWctest_test contained
\ EXCLUDE_LABEL
\ INCLUDE
\ INCLUDE_LABEL
+ \ LABELS
\ OFF
\ ON
+ \ OUTPUT_JUNIT
\ PARALLEL_LEVEL
\ QUIET
\ REPEAT
@@ -2612,6 +3043,8 @@ syn keyword cmakeKWctest_test contained
\ TEST_LOAD
\ UNTIL_FAIL
\ UNTIL_PASS
+ \ URL
+ \ XML
syn keyword cmakeKWctest_update contained
\ CAPTURE_CMAKE_ERROR
@@ -2629,15 +3062,18 @@ syn keyword cmakeKWdefine_property contained
\ APPEND_STRING
\ BRIEF_DOCS
\ CACHED_VARIABLE
+ \ CMAKE_
\ DIRECTORY
\ FULL_DOCS
\ GLOBAL
\ INHERITED
+ \ INITIALIZE_FROM_VARIABLE
\ PROPERTY
\ SOURCE
\ TARGET
\ TEST
\ VARIABLE
+ \ _CMAKE_
syn keyword cmakeKWdoxygen_add_docs contained
\ ALL
@@ -2647,6 +3083,10 @@ syn keyword cmakeKWdoxygen_add_docs contained
syn keyword cmakeKWenable_language contained
\ ASM
+ \ ASM_MARMASM
+ \ ASM_MASM
+ \ ASM_NASM
+ \ ATT
\ CUDA
\ HIP
\ ISPC
@@ -2684,6 +3124,7 @@ syn keyword cmakeKWexecute_process contained
\ OUTPUT_QUIET
\ OUTPUT_STRIP_TRAILING_WHITESPACE
\ OUTPUT_VARIABLE
+ \ POSIX
\ RESULTS_VARIABLE
\ RESULT_VARIABLE
\ RFC
@@ -2691,17 +3132,17 @@ syn keyword cmakeKWexecute_process contained
\ STDOUT
\ TIMEOUT
\ UTF
- \ VERBATIM
\ WORKING_DIRECTORY
syn keyword cmakeKWexport contained
\ ANDROID_MK
\ APPEND
+ \ CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API
\ CONFIG
+ \ CXX_MODULES_DIRECTORY
\ EXPORT
\ EXPORT_LINK_INTERFACE_LIBRARIES
\ FILE
- \ IMPORTED
\ IMPORTED_
\ NAMESPACE
\ NDK
@@ -2717,7 +3158,6 @@ syn keyword cmakeKWexport_library_dependencies contained
\ SET
syn keyword cmakeKWfile contained
- \ ALGO
\ APPEND
\ ARCHIVE_CREATE
\ ARCHIVE_EXTRACT
@@ -2729,9 +3169,8 @@ syn keyword cmakeKWfile contained
\ CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND
\ CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM
\ CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL
+ \ CMAKE_INSTALL_MODE
\ CMAKE_OBJDUMP
- \ CMAKE_TLS_CAINFO
- \ CMAKE_TLS_VERIFY
\ CODE
\ COMPILE_FEATURES
\ COMPRESSION
@@ -2742,7 +3181,8 @@ syn keyword cmakeKWfile contained
\ CONFLICTING_DEPENDENCIES_PREFIX
\ CONTENT
\ CONVERT
- \ COPY
+ \ COPYONLY
+ \ COPY_FILE
\ COPY_ON_ERROR
\ CREATE_LINK
\ CRLF
@@ -2755,6 +3195,7 @@ syn keyword cmakeKWfile contained
\ ENCODING
\ ESCAPE_QUOTES
\ EXECUTABLES
+ \ EXPAND_TILDE
\ EXPECTED_HASH
\ FILES_MATCHING
\ FILE_PERMISSIONS
@@ -2772,10 +3213,12 @@ syn keyword cmakeKWfile contained
\ GUARD
\ HASH
\ HEX
+ \ HOME
\ HTTPHEADER
\ IGNORED
\ INACTIVITY_TIMEOUT
\ INPUT
+ \ INPUT_MAY_BE_RECENT
\ INSTALL
\ IS_ABSOLUTE
\ LENGTH_MAXIMUM
@@ -2800,9 +3243,11 @@ syn keyword cmakeKWfile contained
\ NEWLINE_STYLE
\ NOT
\ NO_HEX_CONVERSION
+ \ NO_REPLACE
\ NO_SOURCE_PERMISSIONS
\ OFFSET
\ ONLY
+ \ ONLY_IF_DIFFERENT
\ OPTIONAL
\ OUTPUT
\ OWNER_EXECUTE
@@ -2812,11 +3257,15 @@ syn keyword cmakeKWfile contained
\ PATTERN
\ PATTERNS
\ PERMISSIONS
+ \ POST_EXCLUDE_FILES
\ POST_EXCLUDE_REGEXES
+ \ POST_INCLUDE_FILES
\ POST_INCLUDE_REGEXES
\ PRE_EXCLUDE_REGEXES
\ PRE_INCLUDE_REGEXES
\ PROCESS
+ \ RANGE_END
+ \ RANGE_START
\ READ
\ READ_SYMLINK
\ REAL_PATH
@@ -2833,7 +3282,10 @@ syn keyword cmakeKWfile contained
\ RESULT_VARIABLE
\ RPATH
\ RUNPATH
+ \ RUNTIME_DEPENDENCY_SET
\ SCRIPT
+ \ SETGID
+ \ SETUID
\ SHARED
\ SHOW_PROGRESS
\ SIZE
@@ -2856,6 +3308,7 @@ syn keyword cmakeKWfile contained
\ UNRESOLVED_DEPENDENCIES_VAR
\ UPLOAD
\ URL
+ \ USERPROFILE
\ USERPWD
\ USE_SOURCE_PERMISSIONS
\ UTC
@@ -2869,54 +3322,87 @@ syn keyword cmakeKWfile contained
\ _FILENAMES
syn keyword cmakeKWfind_file contained
+ \ BOTH
+ \ CATEGORY
\ CMAKE_FIND_ROOT_PATH_BOTH
+ \ CMAKE_FIND_USE_
\ DOC
\ DVAR
\ FALSE
+ \ FIND_XXX_REGISTRY_VIEW
\ HINTS
+ \ HOST
\ INCLUDE
+ \ MATCHES
\ NAMES
+ \ NOT
+ \ NO_CACHE
\ NO_CMAKE_ENVIRONMENT_PATH
\ NO_CMAKE_FIND_ROOT_PATH
+ \ NO_CMAKE_INSTALL_PREFIX
\ NO_CMAKE_PATH
\ NO_CMAKE_SYSTEM_PATH
\ NO_DEFAULT_PATH
\ NO_PACKAGE_ROOT_PATH
\ NO_SYSTEM_ENVIRONMENT_PATH
\ ONLY_CMAKE_FIND_ROOT_PATH
+ \ PACKAGENAME
+ \ PARENT_SCOPE
\ PATHS
\ PATH_SUFFIXES
+ \ REGISTRY_VIEW
\ REQUIRED
+ \ TARGET
+ \ VALIDATOR
\ VAR
syn keyword cmakeKWfind_library contained
+ \ BOTH
+ \ CATEGORY
\ CMAKE_FIND_ROOT_PATH_BOTH
+ \ CMAKE_FIND_USE_
\ DOC
\ DVAR
\ FALSE
+ \ FIND_XXX_REGISTRY_VIEW
\ HINTS
- \ INCLUDE
+ \ HOST
+ \ LIB
+ \ MATCHES
\ NAMES
\ NAMES_PER_DIR
+ \ NOT
+ \ NO_CACHE
\ NO_CMAKE_ENVIRONMENT_PATH
\ NO_CMAKE_FIND_ROOT_PATH
+ \ NO_CMAKE_INSTALL_PREFIX
\ NO_CMAKE_PATH
\ NO_CMAKE_SYSTEM_PATH
\ NO_DEFAULT_PATH
\ NO_PACKAGE_ROOT_PATH
\ NO_SYSTEM_ENVIRONMENT_PATH
\ ONLY_CMAKE_FIND_ROOT_PATH
+ \ PACKAGENAME
+ \ PARENT_SCOPE
\ PATHS
\ PATH_SUFFIXES
+ \ REGISTRY_VIEW
\ REQUIRED
+ \ TARGET
+ \ VALIDATOR
\ VAR
syn keyword cmakeKWfind_package contained
\ ABI
+ \ BOTH
\ BUNDLE
+ \ BYPASS_PROVIDER
+ \ CATEGORY
\ CMAKE_DISABLE_FIND_PACKAGE_
\ CMAKE_REQUIRE_FIND_PACKAGE_
\ CMAKE_FIND_ROOT_PATH_BOTH
+ \ CMAKE_FIND_USE_
+ \ CMAKE_REQUIRE_FIND_PACKAGE_
\ COMPONENTS
\ CONFIG
\ CONFIGS
@@ -2927,7 +3413,9 @@ syn keyword cmakeKWfind_package contained
\ FALSE
\ FIND_PACKAGE_VERSION_FORMAT
\ FRAMEWORK
+ \ GLOBAL
\ HINTS
+ \ HOST
\ INCLUDE
\ MODULE
\ NAMES
@@ -2935,6 +3423,7 @@ syn keyword cmakeKWfind_package contained
\ NO_CMAKE_BUILDS_PATH
\ NO_CMAKE_ENVIRONMENT_PATH
\ NO_CMAKE_FIND_ROOT_PATH
+ \ NO_CMAKE_INSTALL_PREFIX
\ NO_CMAKE_PACKAGE_REGISTRY
\ NO_CMAKE_PATH
\ NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
@@ -2944,8 +3433,10 @@ syn keyword cmakeKWfind_package contained
\ NO_PACKAGE_ROOT_PATH
\ NO_POLICY_SCOPE
\ NO_SYSTEM_ENVIRONMENT_PATH
+ \ OLD
\ ONLY_CMAKE_FIND_ROOT_PATH
\ OPTIONAL_COMPONENTS
+ \ PACKAGENAME
\ PACKAGE_FIND_NAME
\ PACKAGE_FIND_VERSION
\ PACKAGE_FIND_VERSION_COMPLETE
@@ -2974,60 +3465,92 @@ syn keyword cmakeKWfind_package contained
\ PATHS
\ PATH_SUFFIXES
\ QUIET
+ \ REGISTRY_VIEW
\ REQUIRED
\ SET
+ \ TARGET
\ TRUE
+ \ VALUE
\ _CONFIG
\ _CONSIDERED_CONFIGS
\ _CONSIDERED_VERSIONS
\ _DIR
\ _FIND_COMPONENTS
\ _FIND_QUIETLY
+ \ _FIND_REGISTRY_VIEW
\ _FIND_REQUIRED
\ _FIND_REQUIRED_
\ _FIND_VERSION_EXACT
\ _FOUND
syn keyword cmakeKWfind_path contained
+ \ BOTH
+ \ CATEGORY
\ CMAKE_FIND_ROOT_PATH_BOTH
+ \ CMAKE_FIND_USE_
\ DOC
\ DVAR
\ FALSE
+ \ FIND_XXX_REGISTRY_VIEW
\ HINTS
+ \ HOST
\ INCLUDE
+ \ MATCHES
\ NAMES
+ \ NOT
+ \ NO_CACHE
\ NO_CMAKE_ENVIRONMENT_PATH
\ NO_CMAKE_FIND_ROOT_PATH
+ \ NO_CMAKE_INSTALL_PREFIX
\ NO_CMAKE_PATH
\ NO_CMAKE_SYSTEM_PATH
\ NO_DEFAULT_PATH
\ NO_PACKAGE_ROOT_PATH
\ NO_SYSTEM_ENVIRONMENT_PATH
\ ONLY_CMAKE_FIND_ROOT_PATH
+ \ PACKAGENAME
+ \ PARENT_SCOPE
\ PATHS
\ PATH_SUFFIXES
+ \ REGISTRY_VIEW
\ REQUIRED
+ \ TARGET
+ \ VALIDATOR
\ VAR
syn keyword cmakeKWfind_program contained
+ \ BOTH
+ \ CATEGORY
\ CMAKE_FIND_ROOT_PATH_BOTH
+ \ CMAKE_FIND_USE_
\ DOC
\ DVAR
\ FALSE
+ \ FIND_XXX_REGISTRY_VIEW
\ HINTS
+ \ HOST
+ \ MATCHES
\ NAMES
\ NAMES_PER_DIR
+ \ NOT
+ \ NO_CACHE
\ NO_CMAKE_ENVIRONMENT_PATH
\ NO_CMAKE_FIND_ROOT_PATH
+ \ NO_CMAKE_INSTALL_PREFIX
\ NO_CMAKE_PATH
\ NO_CMAKE_SYSTEM_PATH
\ NO_DEFAULT_PATH
\ NO_PACKAGE_ROOT_PATH
\ NO_SYSTEM_ENVIRONMENT_PATH
\ ONLY_CMAKE_FIND_ROOT_PATH
+ \ PACKAGENAME
+ \ PARENT_SCOPE
\ PATHS
\ PATH_SUFFIXES
+ \ REGISTRY_VIEW
\ REQUIRED
+ \ TARGET
+ \ VALIDATOR
\ VAR
syn keyword cmakeKWfltk_wrap_ui contained
@@ -3070,17 +3593,19 @@ syn keyword cmakeKWget_filename_component contained
\ NAME
\ NAME_WE
\ NAME_WLE
- \ PATH
\ PROGRAM
\ PROGRAM_ARGS
+ \ QUERY
\ REALPATH
\ REAL_PATH
+ \ WINDOWS_REGISTRY
syn keyword cmakeKWget_property contained
\ BRIEF_DOCS
\ DEFINED
\ DIRECTORY
\ FULL_DOCS
+ \ GENERATED
\ GLOBAL
\ INSTALL
\ PROPERTY
@@ -3093,6 +3618,7 @@ syn keyword cmakeKWget_property contained
syn keyword cmakeKWget_source_file_property contained
\ DIRECTORY
+ \ GENERATED
\ INHERITED
\ LOCATION
\ TARGET_DIRECTORY
@@ -3109,6 +3635,7 @@ syn keyword cmakeKWif contained
\ CMAKE_MATCH_
\ CMP
\ COMMAND
+ \ COMPARE
\ DEFINED
\ EQUAL
\ EXISTS
@@ -3128,6 +3655,7 @@ syn keyword cmakeKWif contained
\ NOT
\ OFF
\ OR
+ \ PATH_EQUAL
\ POLICY
\ STREQUAL
\ STRGREATER
@@ -3172,11 +3700,14 @@ syn keyword cmakeKWinclude_guard contained
syn keyword cmakeKWinstall contained
\ AFTER
\ AIX
+ \ ALL_COMPONENTS
\ APT
\ ARCHIVE
\ BEFORE
\ BUILD_TYPE
\ BUNDLE
+ \ BUNDLE_EXECUTABLE
+ \ CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API
\ CMAKE_INSTALL_BINDIR
\ CMAKE_INSTALL_DATADIR
\ CMAKE_INSTALL_DATAROOTDIR
@@ -3187,6 +3718,7 @@ syn keyword cmakeKWinstall contained
\ CMAKE_INSTALL_LOCALEDIR
\ CMAKE_INSTALL_LOCALSTATEDIR
\ CMAKE_INSTALL_MANDIR
+ \ CMAKE_INSTALL_MODE
\ CMAKE_INSTALL_RUNSTATEDIR
\ CMAKE_INSTALL_SBINDIR
\ CMAKE_INSTALL_SHARESTATEDIR
@@ -3195,6 +3727,8 @@ syn keyword cmakeKWinstall contained
\ COMPONENT
\ CONFIGURATIONS
\ CVS
+ \ CXX_MODULES_BMI
+ \ CXX_MODULES_DIRECTORY
\ DATA
\ DATAROOT
\ DBUILD_TYPE
@@ -3207,6 +3741,7 @@ syn keyword cmakeKWinstall contained
\ DOC
\ ENABLE_EXPORTS
\ EXCLUDE_FROM_ALL
+ \ EXECUTABLES
\ EXPORT
\ EXPORT_ANDROID_MK
\ EXPORT_LINK_INTERFACE_LIBRARIES
@@ -3214,14 +3749,18 @@ syn keyword cmakeKWinstall contained
\ FILES
\ FILES_MATCHING
\ FILE_PERMISSIONS
+ \ FILE_SET
\ FRAMEWORK
+ \ GET_RUNTIME_DEPENDENCIES
\ GROUP_EXECUTE
\ GROUP_READ
\ GROUP_WRITE
- \ IMPORTED_
+ \ HEADERS
+ \ IMPORTED_RUNTIME_ARTIFACTS
\ INCLUDES
\ INFO
\ INSTALL_PREFIX
+ \ INTERFACE
\ INTERFACE_INCLUDE_DIRECTORIES
\ LIBRARY
\ LOCALE
@@ -3241,18 +3780,24 @@ syn keyword cmakeKWinstall contained
\ OWNER_WRITE
\ PATTERN
\ PERMISSIONS
+ \ POST_EXCLUDE_FILES
+ \ POST_EXCLUDE_REGEXES
+ \ POST_INCLUDE_FILES
+ \ POST_INCLUDE_REGEXES
\ POST_INSTALL_SCRIPT
+ \ PRE_EXCLUDE_REGEXES
+ \ PRE_INCLUDE_REGEXES
\ PRE_INSTALL_SCRIPT
\ PRIVATE_HEADER
\ PROGRAMS
\ PROPERTIES
\ PUBLIC_HEADER
- \ REGEX
\ RENAME
\ RESOURCE
\ RPM
\ RUNSTATE
- \ RUNTIME
+ \ RUNTIME_DEPENDENCIES
+ \ RUNTIME_DEPENDENCY_SET
\ SBIN
\ SCRIPT
\ SETGID
@@ -3333,6 +3878,11 @@ syn keyword cmakeKWlist contained
\ TOLOWER
\ TOUPPER
\ TRANSFORM
+ \ TRANSFORM_APPEND
+ \ TRANSFORM_GENEX_STRIP
+ \ TRANSFORM_REPLACE
+ \ TRANSFORM_STRIP
+ \ TRANSFORM_TOLOWER
syn keyword cmakeKWload_cache contained
\ EXCLUDE
@@ -3370,10 +3920,15 @@ syn keyword cmakeKWmessage contained
\ CHECK_FAIL
\ CHECK_PASS
\ CHECK_START
+ \ CONFIGURE_LOG
\ DEBUG
+ \ DEFINED
\ DEPRECATION
\ FATAL_ERROR
+ \ GET_MESSAGE_LOG_LEVEL
\ GUI
+ \ INTERNAL
+ \ MY_CHECK_RESULT
\ NOTICE
\ POP_BACK
\ SEND_ERROR
@@ -3384,10 +3939,13 @@ syn keyword cmakeKWmessage contained
syn keyword cmakeKWoption contained
\ OFF
- \ ON
syn keyword cmakeKWproject contained
\ ASM
+ \ ASM_MARMASM
+ \ ASM_MASM
+ \ ASM_NASM
+ \ ATT
\ CMAKE_PROJECT_
\ CUDA
\ DESCRIPTION
@@ -3405,6 +3963,7 @@ syn keyword cmakeKWproject contained
\ _DESCRIPTION
\ _HOMEPAGE_URL
\ _INCLUDE_BEFORE
+ \ _IS_TOP_LEVEL
\ _SOURCE_DIR
\ _VERSION
\ _VERSION_MAJOR
@@ -3424,6 +3983,11 @@ syn keyword cmakeKWremove contained
syn keyword cmakeKWreturn contained
\ DEFER
+ \ PARENT_SCOPE
+ \ PROPAGATE
+ \ SCOPE_FOR
+ \ VARIABLES
+ \ VERSION
syn keyword cmakeKWseparate_arguments contained
\ MSDN
@@ -3439,10 +4003,13 @@ syn keyword cmakeKWset contained
\ FORCE
\ INTERNAL
\ OFF
+ \ OLD
\ ON
\ PARENT_SCOPE
+ \ PROPAGATE
\ STRING
\ STRINGS
+ \ VAR
syn keyword cmakeKWset_directory_properties contained
\ DIRECTORY
@@ -3452,9 +4019,11 @@ syn keyword cmakeKWset_property contained
\ APPEND
\ APPEND_STRING
\ DIRECTORY
+ \ GENERATED
\ GLOBAL
\ INHERITED
\ INSTALL
+ \ NAME
\ PROPERTY
\ SOURCE
\ TARGET
@@ -3464,17 +4033,17 @@ syn keyword cmakeKWset_property contained
syn keyword cmakeKWset_source_files_properties contained
\ DIRECTORY
+ \ GENERATED
\ PROPERTIES
\ SOURCE
\ TARGET_DIRECTORY
syn keyword cmakeKWset_target_properties contained
\ PROPERTIES
- \ TARGET
syn keyword cmakeKWset_tests_properties contained
+ \ NAME
\ PROPERTIES
- \ TEST
syn keyword cmakeKWsite_name contained
\ HOSTNAME
@@ -3506,9 +4075,9 @@ syn keyword cmakeKWstring contained
\ GUID
\ HASH
\ HEX
+ \ ISO
\ JOIN
\ JSON
- \ JSONLENGTH
\ LENGTH
\ LESS
\ LESS_EQUAL
@@ -3573,7 +4142,10 @@ syn keyword cmakeKWtarget_compile_features contained
syn keyword cmakeKWtarget_compile_options contained
\ ALIAS
\ BEFORE
+ \ CMAKE_
+ \ COMPILE_LANGUAGE
\ COMPILE_OPTIONS
+ \ CONFIG
\ IMPORTED
\ INTERFACE
\ INTERFACE_COMPILE_OPTIONS
@@ -3581,8 +4153,11 @@ syn keyword cmakeKWtarget_compile_options contained
\ PUBLIC
\ SHELL
\ UNIX_COMMAND
+ \ _FLAGS
+ \ _FLAGS_
syn keyword cmakeKWtarget_include_directories contained
+ \ AFTER
\ ALIAS
\ BEFORE
\ BUILD_INTERFACE
@@ -3619,6 +4194,7 @@ syn keyword cmakeKWtarget_link_libraries contained
\ IMPORTED_NO_SONAME
\ INTERFACE
\ INTERFACE_LINK_LIBRARIES
+ \ LINK_FLAGS
\ LINK_INTERFACE_LIBRARIES
\ LINK_INTERFACE_LIBRARIES_DEBUG
\ LINK_INTERFACE_MULTIPLICITY
@@ -3631,16 +4207,17 @@ syn keyword cmakeKWtarget_link_libraries contained
\ PUBLIC
\ SHARED
\ STATIC
+ \ TARGET_OBJECTS
syn keyword cmakeKWtarget_link_options contained
\ ALIAS
\ BEFORE
\ CMAKE_
+ \ CONFIG
\ CUDA_RESOLVE_DEVICE_SYMBOLS
\ CUDA_SEPARABLE_COMPILATION
\ DEVICE_LINK
\ GCC
- \ GNU
\ HOST_LINK
\ IMPORTED
\ INTERFACE
@@ -3653,6 +4230,8 @@ syn keyword cmakeKWtarget_link_options contained
\ SHELL
\ STATIC_LIBRARY_OPTIONS
\ UNIX_COMMAND
+ \ _FLAGS
+ \ _FLAGS_
\ _LINKER_WRAPPER_FLAG
\ _LINKER_WRAPPER_FLAG_SEP
@@ -3677,15 +4256,46 @@ syn keyword cmakeKWtarget_precompile_headers contained
syn keyword cmakeKWtarget_sources contained
\ ALIAS
+ \ BASE_DIRS
+ \ BUILD_INTERFACE
+ \ CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API
+ \ CONFIG
+ \ CORRECT
+ \ CXX_MODULES
+ \ CXX_MODULE_DIRS
+ \ CXX_MODULE_DIRS_
+ \ CXX_MODULE_SETS
+ \ CXX_MODULE_SET_
+ \ EXPORT
+ \ FILES
+ \ FILE_SET
+ \ FRAMEWORK
+ \ HEADERS
+ \ HEADER_DIRS
+ \ HEADER_DIRS_
+ \ HEADER_FILE_ONLY
+ \ HEADER_SETS
+ \ HEADER_SET_
\ IMPORTED
+ \ INCLUDE_DIRECTORIES
\ INTERFACE
+ \ INTERFACE_CXX_MODULE_SETS
+ \ INTERFACE_HEADER_SETS
+ \ INTERFACE_INCLUDE_DIRECTORIES
\ INTERFACE_SOURCES
+ \ NAME
\ PRIVATE
\ PUBLIC
\ SOURCES
+ \ SOURCE_DIR
+ \ TARGETS
+ \ TRUE
+ \ TYPE
+ \ WRONG
syn keyword cmakeKWtry_compile contained
\ ALL_BUILD
+ \ BINARY_DIR
\ CMAKE_FLAGS
\ COMPILE_DEFINITIONS
\ COPY_FILE
@@ -3713,8 +4323,11 @@ syn keyword cmakeKWtry_compile contained
\ LINK_DIRECTORIES
\ LINK_LIBRARIES
\ LINK_OPTIONS
+ \ LOG_DESCRIPTION
\ MULTI
\ NOT
+ \ NO_CACHE
+ \ NO_LOG
\ OBJCXX_EXTENSIONS
\ OBJCXX_STANDARD
\ OBJCXX_STANDARD_REQUIRED
@@ -3723,9 +4336,16 @@ syn keyword cmakeKWtry_compile contained
\ OBJC_STANDARD_REQUIRED
\ OUTPUT_VARIABLE
\ PRIVATE
+ \ PROJECT
+ \ RESULTVAR
\ SOURCES
+ \ SOURCE_DIR
+ \ SOURCE_FROM_CONTENT
+ \ SOURCE_FROM_FILE
+ \ SOURCE_FROM_VAR
\ STATIC_LIBRARY
\ STATIC_LIBRARY_OPTIONS
+ \ TARGET
\ TRUE
\ TYPE
\ VALUE
@@ -3738,18 +4358,28 @@ syn keyword cmakeKWtry_run contained
\ CMAKE_FLAGS
\ COMPILE_DEFINITIONS
\ COMPILE_OUTPUT_VARIABLE
- \ DLINK_LIBRARIES
- \ DVAR
+ \ COPY_FILE
+ \ COPY_FILE_ERROR
\ FAILED_TO_RUN
\ FALSE
- \ INCLUDE_DIRECTORIES
- \ LINK_DIRECTORIES
+ \ LANG
\ LINK_LIBRARIES
\ LINK_OPTIONS
+ \ LOG_DESCRIPTION
+ \ NO_CACHE
+ \ NO_LOG
+ \ RUN_OUTPUT_STDERR_VARIABLE
+ \ RUN_OUTPUT_STDOUT_VARIABLE
\ RUN_OUTPUT_VARIABLE
+ \ SOURCES
+ \ SOURCE_FROM_CONTENT
+ \ SOURCE_FROM_FILE
+ \ SOURCE_FROM_VAR
\ TRUE
- \ TYPE
- \ VALUE
+ \ WORKING_DIRECTORY
+ \ _EXTENSIONS
+ \ _STANDARD
+ \ _STANDARD_REQUIRED
\ __TRYRUN_OUTPUT
syn keyword cmakeKWunset contained
@@ -3783,26 +4413,38 @@ syn keyword cmakeKWwrite_file contained
syn keyword cmakeGeneratorExpressions contained
- \ AND
+ \ ABSOLUTE_PATH
+ \ ACTION
+ \ AIX
\ ANGLE
+ \ APPEND
\ ARCHIVE_OUTPUT_NAME
\ ARCHIVE_OUTPUT_NAME_
+ \ ASCENDING
\ BAR
\ BOOL
\ BUILD_INTERFACE
- \ CMAKE_
- \ COMMA
- \ COMMAND
+ \ BUILD_LOCAL_INTERFACE
+ \ CMAKE_LINK_GROUP_USING_
+ \ CMAKE_LINK_LIBRARY_USING_
+ \ CMAKE_PATH
+ \ CODE
+ \ COMMAND_CONFIG
+ \ COMMAND_EXPAND_LISTS
+ \ COMPARE
\ COMPILE_DEFINITIONS
\ COMPILE_FEATURES
\ COMPILE_LANGUAGE
\ COMPILE_LANG_AND_ID
+ \ COMPILE_ONLY
\ COMPILING_CUDA
+ \ COMPILING_CXX
\ COMPILING_CXX_WITH_CLANG
\ COMPILING_CXX_WITH_INTEL
\ COMPILING_C_WITH_CLANG
\ CONFIG
\ CONFIGURATION
+ \ CONTENT
\ CUDA_COMPILER_ID
\ CUDA_COMPILER_VERSION
\ CUDA_RESOLVE_DEVICE_SYMBOLS
@@ -3817,71 +4459,146 @@ syn keyword cmakeGeneratorExpressions contained
\ C_STANDARD
\ DEBUG_MODE
\ DEBUG_POSTFIX
+ \ DENABLE_SOME_FEATURE
+ \ DESCENDING
\ DEVICE_LINK
\ DLL
+ \ ENABLE_EXPORTS
\ EXCLUDE
\ EXPORT
+ \ EXTENSION_DEF
\ FALSE
+ \ FILENAME_DEF
+ \ FILE_BASENAME
\ FILTER
+ \ FIND
\ FOO_EXTRA_THINGS
\ GENERATE
\ GENEX_EVAL
- \ GNU
+ \ GET_EXTENSION
+ \ GET_FILENAME
+ \ GET_PARENT_PATH
+ \ GET_RELATIVE_PART
+ \ GET_ROOT_DIRECTORY
+ \ GET_ROOT_NAME
+ \ GET_ROOT_PATH
+ \ GET_STEM
+ \ HAS_
+ \ HAS_EXTENSION
+ \ HAS_FILENAME
+ \ HAS_PARENT_PATH
+ \ HAS_RELATIVE_PART
+ \ HAS_ROOT_DIRECTORY
+ \ HAS_ROOT_NAME
+ \ HAS_ROOT_PATH
+ \ HAS_STEM
+ \ HAVE_SOME_FEATURE
\ HIP_COMPILER_ID
\ HIP_COMPILER_VERSION
\ HIP_STANDARD
\ HOST_LINK
\ IF
\ IGNORE
+ \ IMPORTED_LOCATION
\ IMPORT_PREFIX
\ IMPORT_SUFFIX
\ INCLUDE_DIRECTORIES
+ \ INSENSITIVE
+ \ INSERT
\ INSTALL_INTERFACE
\ INSTALL_NAME_DIR
\ INSTALL_PREFIX
- \ INTERFACE
+ \ INSTALL_RPATH
\ INTERFACE_LINK_LIBRARIES
+ \ INTERFACE_LINK_LIBRARIES_DIRECT
\ IN_LIST
\ ISPC_COMPILER_ID
\ ISPC_COMPILER_VERSION
+ \ IS_ABSOLUTE
+ \ IS_PREFIX
+ \ IS_RELATIVE
\ JOIN
\ LANG
\ LANG_COMPILER_ID
+ \ LAST_ONLY
+ \ LENGTH
\ LIBRARY_OUTPUT_NAME
\ LIBRARY_OUTPUT_NAME_
+ \ LINK_GROUP
+ \ LINK_GROUP_PREDEFINED_FEATURES
\ LINK_LANGUAGE
\ LINK_LANG_AND_ID
\ LINK_LIBRARIES
+ \ LINK_LIBRARY
+ \ LINK_LIBRARY_OVERRIDE
+ \ LINK_LIBRARY_OVERRIDE_
+ \ LINK_LIBRARY_PREDEFINED_FEATURES
\ LINK_ONLY
\ LOWER_CASE
\ MAKE_C_IDENTIFIER
\ MAP_IMPORTED_CONFIG_
+ \ MODULE
+ \ NATURAL
\ NO
+ \ NORMALIZE
+ \ NORMAL_PATH
\ NOT
\ OBJCXX_COMPILER_ID
\ OBJCXX_COMPILER_VERSION
\ OBJC_COMPILER_ID
\ OBJC_COMPILER_VERSION
+ \ OBJECT
\ OFF
\ OLD_COMPILER
+ \ ORDER
+ \ OUTPUT
+ \ OUTPUT_CONFIG
\ OUTPUT_NAME
\ OUTPUT_NAME_
+ \ PATH
+ \ PATH_EQUAL
\ PDB_NAME
\ PDB_NAME_
\ PDB_OUTPUT_DIRECTORY
\ PDB_OUTPUT_DIRECTORY_
\ PLATFORM_ID
+ \ POP_BACK
+ \ POP_FRONT
\ POSIX
+ \ POST_BUILD
+ \ PREPEND
\ PRIVATE
\ PUBLIC
+ \ REGEX
+ \ RELATIVE_PATH
+ \ REMOVE_AT
\ REMOVE_DUPLICATES
+ \ REMOVE_EXTENSION
+ \ REMOVE_FILENAME
+ \ REMOVE_ITEM
+ \ REPLACE
+ \ REPLACE_EXTENSION
+ \ REPLACE_FILENAME
+ \ REQUIRED
+ \ RESCAN
+ \ REVERSE
+ \ RPATH
+ \ RUNTIME_DEPENDENCY_SET
\ RUNTIME_OUTPUT_NAME
\ RUNTIME_OUTPUT_NAME_
+ \ SCRIPT
\ SDK
+ \ SELECTOR
\ SEMICOLON
+ \ SENSITIVE
+ \ SHARED
\ SHELL_PATH
+ \ SORT
\ STATIC
\ STREQUAL
+ \ STRING
+ \ STRIP
+ \ SUBLIST
\ TARGET_BUNDLE_CONTENT_DIR
\ TARGET_BUNDLE_DIR
\ TARGET_BUNDLE_DIR_NAME
@@ -3893,12 +4610,30 @@ syn keyword cmakeGeneratorExpressions contained
\ TARGET_FILE_PREFIX
\ TARGET_FILE_SUFFIX
\ TARGET_GENEX_EVAL
+ \ TARGET_IMPORT_FILE
+ \ TARGET_IMPORT_FILE_BASE_NAME
+ \ TARGET_IMPORT_FILE_DIR
+ \ TARGET_IMPORT_FILE_NAME
+ \ TARGET_IMPORT_FILE_PREFIX
+ \ TARGET_IMPORT_FILE_SUFFIX
\ TARGET_LINKER_FILE
\ TARGET_LINKER_FILE_BASE_NAME
\ TARGET_LINKER_FILE_DIR
\ TARGET_LINKER_FILE_NAME
\ TARGET_LINKER_FILE_PREFIX
\ TARGET_LINKER_FILE_SUFFIX
+ \ TARGET_LINKER_IMPORT_FILE
+ \ TARGET_LINKER_IMPORT_FILE_BASE_NAME
+ \ TARGET_LINKER_IMPORT_FILE_DIR
+ \ TARGET_LINKER_IMPORT_FILE_NAME
+ \ TARGET_LINKER_IMPORT_FILE_PREFIX
+ \ TARGET_LINKER_IMPORT_FILE_SUFFIX
+ \ TARGET_LINKER_LIBRARY_FILE
+ \ TARGET_LINKER_LIBRARY_FILE_BASE_NAME
+ \ TARGET_LINKER_LIBRARY_FILE_DIR
+ \ TARGET_LINKER_LIBRARY_FILE_NAME
+ \ TARGET_LINKER_LIBRARY_FILE_PREFIX
+ \ TARGET_LINKER_LIBRARY_FILE_SUFFIX
\ TARGET_NAME_IF_EXISTS
\ TARGET_OBJECTS
\ TARGET_PDB_FILE
@@ -3907,16 +4642,34 @@ syn keyword cmakeGeneratorExpressions contained
\ TARGET_PDB_FILE_NAME
\ TARGET_POLICY
\ TARGET_PROPERTY
+ \ TARGET_RUNTIME_DLLS
+ \ TARGET_RUNTIME_DLL_DIRS
\ TARGET_SONAME_FILE
\ TARGET_SONAME_FILE_DIR
\ TARGET_SONAME_FILE_NAME
+ \ TARGET_SONAME_IMPORT_FILE
+ \ TARGET_SONAME_IMPORT_FILE_DIR
+ \ TARGET_SONAME_IMPORT_FILE_NAME
+ \ TOLOWER
+ \ TOUPPER
+ \ TRANSFORM
+ \ TRANSFORM_APPEND
+ \ TRANSFORM_REPLACE
+ \ TRANSFORM_STRIP
+ \ TRANSFORM_TOLOWER
+ \ UNKNOWN
\ UPPER_CASE
+ \ VERBATIM
\ VERSION_EQUAL
- \ VERSION_GREATER
\ VERSION_GREATER_EQUAL
\ VERSION_LESS
\ VERSION_LESS_EQUAL
+ \ WHOLE_ARCHIVE
+ \ WRONG
+ \ _LINK_GROUP_USING_
+ \ _LINK_LIBRARY_USING_
\ _POSTFIX
+ \ _SUPPORTED
syn case ignore
@@ -3936,6 +4689,7 @@ syn keyword cmakeCommand
\ block
\ break
\ build_command
+ \ cmake_file_api
\ cmake_host_system_information
\ cmake_language
\ cmake_minimum_required
@@ -4085,6 +4839,7 @@ hi def link cmakeVariableValue Type
hi def link cmakeVariable Identifier
hi def link cmakeKWExternalProject ModeMsg
+hi def link cmakeKWFetchContent ModeMsg
hi def link cmakeKWadd_compile_definitions ModeMsg
hi def link cmakeKWadd_compile_options ModeMsg
hi def link cmakeKWadd_custom_command ModeMsg
@@ -4096,7 +4851,9 @@ hi def link cmakeKWadd_library ModeMsg
hi def link cmakeKWadd_link_options ModeMsg
hi def link cmakeKWadd_subdirectory ModeMsg
hi def link cmakeKWadd_test ModeMsg
+hi def link cmakeKWblock ModeMsg
hi def link cmakeKWbuild_command ModeMsg
+hi def link cmakeKWcmake_file_api ModeMsg
hi def link cmakeKWcmake_host_system_information ModeMsg
hi def link cmakeKWcmake_language ModeMsg
hi def link cmakeKWcmake_minimum_required ModeMsg
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d559c08..2823ca4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.13...3.25 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
@@ -131,6 +131,8 @@ if(CMake_BUILD_LTO)
endif()
endif()
+option(CMake_BUILD_PCH "Compile CMake with precompiled headers" OFF)
+
# Check whether to build support for the debugger mode.
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(NOT DEFINED CMake_ENABLE_DEBUGGER)
@@ -153,7 +155,6 @@ endif()
# simply to improve readability of the main script
#-----------------------------------------------------------------------
macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
- # Options have dependencies.
include(CMakeDependentOption)
# Allow the user to enable/disable all system utility library options by
@@ -324,6 +325,9 @@ configure_file(.clang-tidy .clang-tidy COPYONLY)
option(CMake_RUN_IWYU "Run include-what-you-use with the compiler." OFF)
if(CMake_RUN_IWYU)
+ if(CMake_BUILD_PCH)
+ message(FATAL_ERROR "CMake_RUN_IWYU and CMake_BUILD_PCH are ON, but they are incompatible!")
+ endif()
find_program(IWYU_COMMAND NAMES include-what-you-use iwyu)
if(NOT IWYU_COMMAND)
message(FATAL_ERROR "CMake_RUN_IWYU is ON but include-what-you-use is not found!")
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 9bc88d6..1fcf06c 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -24,6 +24,7 @@ The first signature is for adding a custom command to produce an output:
[COMMENT comment]
[DEPFILE depfile]
[JOB_POOL job_pool]
+ [JOB_SERVER_AWARE <bool>]
[VERBATIM] [APPEND] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS]
[DEPENDS_EXPLICIT_ONLY])
@@ -221,6 +222,19 @@ The options are:
Using a pool that is not defined by :prop_gbl:`JOB_POOLS` causes
an error by ninja at build time.
+``JOB_SERVER_AWARE``
+ .. versionadded:: 3.28
+
+ Specify that the command is GNU Make job server aware.
+
+ For the :generator:`Unix Makefiles`, :generator:`MSYS Makefiles`, and
+ :generator:`MinGW Makefiles` generators this will add the ``+`` prefix to the
+ recipe line. See the `GNU Make Documentation`_ for more information.
+
+ This option is silently ignored by other generators.
+
+.. _`GNU Make Documentation`: https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html
+
``MAIN_DEPENDENCY``
Specify the primary input source file to the command. This is
treated just like any value given to the ``DEPENDS`` option
@@ -516,7 +530,7 @@ one of the keywords to make clear the behavior they expect.
Because generator expressions can be used in custom commands,
it is possible to define ``COMMAND`` lines or whole custom commands
which evaluate to empty strings for certain configurations.
- For **Visual Studio 11 2012 (and newer)** generators these command
+ For **Visual Studio 12 2013 (and newer)** generators these command
lines or custom commands will be omitted for the specific
configuration and no "empty-string-command" will be added.
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index 545b9a5..ef0c8d9 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -12,6 +12,7 @@ Add a target with no output so it will always be built.
[WORKING_DIRECTORY dir]
[COMMENT comment]
[JOB_POOL job_pool]
+ [JOB_SERVER_AWARE <bool>]
[VERBATIM] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS]
[SOURCES src1 [src2...]])
@@ -146,6 +147,19 @@ The options are:
Using a pool that is not defined by :prop_gbl:`JOB_POOLS` causes
an error by ninja at build time.
+``JOB_SERVER_AWARE``
+ .. versionadded:: 3.28
+
+ Specify that the command is GNU Make job server aware.
+
+ For the :generator:`Unix Makefiles`, :generator:`MSYS Makefiles`, and
+ :generator:`MinGW Makefiles` generators this will add the ``+`` prefix to the
+ recipe line. See the `GNU Make Documentation`_ for more information.
+
+ This option is silently ignored by other generators.
+
+.. _`GNU Make Documentation`: https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html
+
``SOURCES``
Specify additional source files to be included in the custom target.
Specified source files will be added to IDE project files for
diff --git a/Help/command/block.rst b/Help/command/block.rst
index a352e83..4c6e111 100644
--- a/Help/command/block.rst
+++ b/Help/command/block.rst
@@ -21,7 +21,8 @@ scopes created by the ``block()`` command are removed.
``POLICIES``
Create a new policy scope. This is equivalent to
- :command:`cmake_policy(PUSH)`.
+ :command:`cmake_policy(PUSH)` with an automatic
+ :command:`cmake_policy(POP)` when leaving the block scope.
``VARIABLES``
Create a new variable scope.
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
index 76824ef..dad0833 100644
--- a/Help/command/cmake_host_system_information.rst
+++ b/Help/command/cmake_host_system_information.rst
@@ -146,6 +146,13 @@ queried. The list of queried values is stored in ``<variable>``.
See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR`
+``MSYSTEM_PREFIX``
+ .. versionadded:: 3.28
+
+ Available only on Windows hosts. In a MSYS or MinGW development
+ environment that sets the ``MSYSTEM`` environment variable, this
+ is its installation prefix. Otherwise, this is the empty string.
+
``DISTRIB_INFO``
.. versionadded:: 3.22
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst
index d7880bc..4a08c01 100644
--- a/Help/command/cmake_policy.rst
+++ b/Help/command/cmake_policy.rst
@@ -24,9 +24,8 @@ The ``cmake_policy`` command is used to set policies to ``OLD`` or ``NEW``
behavior. While setting policies individually is supported, we
encourage projects to set policies based on CMake versions:
-.. code-block:: cmake
-
- cmake_policy(VERSION <min>[...<max>])
+.. signature:: cmake_policy(VERSION <min>[...<max>])
+ :target: VERSION
.. versionadded:: 3.12
The optional ``<max>`` version.
@@ -57,10 +56,8 @@ command implicitly calls ``cmake_policy(VERSION)`` too.
Setting Policies Explicitly
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block:: cmake
-
- cmake_policy(SET CMP<NNNN> NEW)
- cmake_policy(SET CMP<NNNN> OLD)
+.. signature:: cmake_policy(SET CMP<NNNN> NEW|OLD)
+ :target: SET
Tell CMake to use the ``OLD`` or ``NEW`` behavior for a given policy.
Projects depending on the old behavior of a given policy may silence a
@@ -73,9 +70,8 @@ policy state to ``NEW``.
Checking Policy Settings
^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block:: cmake
-
- cmake_policy(GET CMP<NNNN> <variable>)
+.. signature:: cmake_policy(GET CMP<NNNN> <variable>)
+ :target: GET
Check whether a given policy is set to ``OLD`` or ``NEW`` behavior.
The output ``<variable>`` value will be ``OLD`` or ``NEW`` if the
@@ -94,23 +90,27 @@ except when invoked with the ``NO_POLICY_SCOPE`` option
The ``cmake_policy`` command provides an interface to manage custom
entries on the policy stack:
-.. code-block:: cmake
+.. signature:: cmake_policy(PUSH)
+ :target: PUSH
+
+ Create a new entry on the policy stack.
+
+.. signature:: cmake_policy(POP)
+ :target: POP
- cmake_policy(PUSH)
- cmake_policy(POP)
+ Remove the last policy stack entry created with ``cmake_policy(PUSH)``.
Each ``PUSH`` must have a matching ``POP`` to erase any changes.
This is useful to make temporary changes to policy settings.
Calls to the :command:`cmake_minimum_required(VERSION)`,
-``cmake_policy(VERSION)``, or ``cmake_policy(SET)`` commands
+:command:`cmake_policy(VERSION)`, or :command:`cmake_policy(SET)` commands
influence only the current top of the policy stack.
.. versionadded:: 3.25
- The :command:`block` and :command:`endblock` commands offer a more flexible
+ The :command:`block(SCOPE_FOR POLICIES)` command offers a more flexible
and more secure way to manage the policy stack. The pop action is done
- automatically when the :command:`endblock` command is executed, so it avoid
- to call the :command:`cmake_policy(POP)` command before each
- :command:`return` command.
+ automatically when leaving the block scope, so there is no need to
+ precede each :command:`return` with a call to :command:`cmake_policy(POP)`.
.. code-block:: cmake
diff --git a/Help/command/exec_program.rst b/Help/command/exec_program.rst
index 983a6df..6010176 100644
--- a/Help/command/exec_program.rst
+++ b/Help/command/exec_program.rst
@@ -1,6 +1,10 @@
exec_program
------------
+.. versionchanged:: 3.28
+ This command is available only if policy :policy:`CMP0153` is not set to ``NEW``.
+ Port projects to the :command:`execute_process` command.
+
.. deprecated:: 3.0
Use the :command:`execute_process` command instead.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 30a7f4d..f9d1a79 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -981,6 +981,11 @@ Path Conversion
if ``USERPROFILE`` is not defined. On all other platforms, only ``HOME``
is used.
+ .. versionchanged:: 3.28
+
+ All symlinks are resolved before collapsing ``../`` components.
+ See policy :policy:`CMP0152`.
+
.. signature::
file(RELATIVE_PATH <variable> <directory> <file>)
diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst
index 99e36a4..fb2c2f1 100644
--- a/Help/command/find_library.rst
+++ b/Help/command/find_library.rst
@@ -60,6 +60,10 @@ path to the framework ``<fullPath>/A.framework``. When a full path to a
framework is used as a library, CMake will use a ``-framework A``, and a
``-F<fullPath>`` to link the framework to the target.
+.. versionadded:: 3.28
+
+ The library found can now be a ``.xcframework`` folder.
+
If the :variable:`CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX` variable is set all
search paths will be tested as normal, with the suffix appended, and with
all matches of ``lib/`` replaced with
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index 6b9931e..a0a12bb 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -12,7 +12,8 @@ Get a property.
SOURCE <source>
[DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
INSTALL <file> |
- TEST <test> |
+ TEST <test>
+ [DIRECTORY <dir>] |
CACHE <entry> |
VARIABLE >
PROPERTY <name>
@@ -73,6 +74,16 @@ It must be one of the following:
Scope must name one existing test.
See also the :command:`get_test_property` command.
+ .. versionadded:: 3.28
+ Directory scope can be overridden with the following sub-option:
+
+ ``DIRECTORY <dir>``
+ The test property will be read from the ``<dir>`` directory's
+ scope. CMake must already know about the directory, either by having added
+ it through a call to :command:`add_subdirectory` or ``<dir>`` being the top
+ level directory. Relative paths are treated as relative to the current
+ source directory. ``<dir>`` may reference a binary directory.
+
``CACHE``
Scope must name one cache entry.
diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst
index 2b6f354..1fcf24e 100644
--- a/Help/command/get_test_property.rst
+++ b/Help/command/get_test_property.rst
@@ -5,7 +5,7 @@ Get a property of the test.
.. code-block:: cmake
- get_test_property(test property VAR)
+ get_test_property(test property [DIRECTORY <dir>] VAR)
Get a property from the test. The value of the property is stored in
the variable ``VAR``. If the test property is not found, the behavior
@@ -19,6 +19,17 @@ an empty string.
For a list of standard properties you can type
:option:`cmake --help-property-list`.
+.. versionadded:: 3.28
+ Directory scope can be overridden with the following sub-option:
+
+ ``DIRECTORY <dir>``
+ The test property will be read from the ``<dir>`` directory's
+ scope. CMake must already know about that source directory, either by
+ having added it through a call to :command:`add_subdirectory` or ``<dir>``
+ being the top level source directory. Relative paths are treated as
+ relative to the current source directory. ``<dir>`` may reference a binary
+ directory.
+
See Also
^^^^^^^^
diff --git a/Help/command/if.rst b/Help/command/if.rst
index c47c71b..5d85a1f 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -228,36 +228,36 @@ Comparisons
.. signature:: if(<variable|string> LESS <variable|string>)
:target: LESS
- True if the given string or variable's value is a valid number and less
- than that on the right.
+ True if the given string or variable's value parses as a real number
+ (like a C ``double``) and less than that on the right.
.. signature:: if(<variable|string> GREATER <variable|string>)
:target: GREATER
- True if the given string or variable's value is a valid number and greater
- than that on the right.
+ True if the given string or variable's value parses as a real number
+ (like a C ``double``) and greater than that on the right.
.. signature:: if(<variable|string> EQUAL <variable|string>)
:target: EQUAL
- True if the given string or variable's value is a valid number and equal
- to that on the right.
+ True if the given string or variable's value parses as a real number
+ (like a C ``double``) and equal to that on the right.
.. signature:: if(<variable|string> LESS_EQUAL <variable|string>)
:target: LESS_EQUAL
.. versionadded:: 3.7
- True if the given string or variable's value is a valid number and less
- than or equal to that on the right.
+ True if the given string or variable's value parses as a real number
+ (like a C ``double``) and less than or equal to that on the right.
.. signature:: if(<variable|string> GREATER_EQUAL <variable|string>)
:target: GREATER_EQUAL
.. versionadded:: 3.7
- True if the given string or variable's value is a valid number and greater
- than or equal to that on the right.
+ True if the given string or variable's value parses as a real number
+ (like a C ``double``) and greater than or equal to that on the right.
.. signature:: if(<variable|string> STRLESS <variable|string>)
:target: STRLESS
diff --git a/Help/command/install.rst b/Help/command/install.rst
index b56f20c..4de3ce1 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -1,6 +1,10 @@
install
-------
+.. only:: html
+
+ .. contents::
+
Specify rules to run at install time.
Synopsis
@@ -34,12 +38,14 @@ are executed in order during installation.
The environment variable :envvar:`CMAKE_INSTALL_MODE` can override the
default copying behavior of ``install()``.
+.. _`common options`:
+
There are multiple signatures for this command. Some of them define
installation options for files and targets. Options common to
multiple signatures are covered here but they are valid only for
signatures that specify them. The common options are:
-``DESTINATION``
+``DESTINATION <dir>``
Specify the directory on disk to which a file will be installed.
Arguments can be relative or absolute paths.
@@ -58,32 +64,28 @@ signatures that specify them. The common options are:
:variable:`CMAKE_INSTALL_PREFIX`; this prefix is used by default if
the DESTINATION is a relative path.
-``PERMISSIONS``
+``PERMISSIONS <permission>...``
Specify permissions for installed files. Valid permissions are
``OWNER_READ``, ``OWNER_WRITE``, ``OWNER_EXECUTE``, ``GROUP_READ``,
``GROUP_WRITE``, ``GROUP_EXECUTE``, ``WORLD_READ``, ``WORLD_WRITE``,
``WORLD_EXECUTE``, ``SETUID``, and ``SETGID``. Permissions that do
not make sense on certain platforms are ignored on those platforms.
-``CONFIGURATIONS``
- Specify a list of build configurations for which the install rule
- applies (Debug, Release, etc.). Note that the values specified for
- this option only apply to options listed AFTER the ``CONFIGURATIONS``
- option. For example, to set separate install paths for the Debug and
- Release configurations, do the following:
-
- .. code-block:: cmake
+ If this option is used multiple times in a single call, its list
+ of permissions accumulates. If an :command:`install(TARGETS)` call
+ uses `\<artifact-kind\>`_ arguments, a separate list of permissions
+ is accumulated for each kind of artifact.
- install(TARGETS target
- CONFIGURATIONS Debug
- RUNTIME DESTINATION Debug/bin)
- install(TARGETS target
- CONFIGURATIONS Release
- RUNTIME DESTINATION Release/bin)
+``CONFIGURATIONS <config>...``
+ Specify a list of build configurations for which the install rule
+ applies (Debug, Release, etc.).
- Note that ``CONFIGURATIONS`` appears BEFORE ``RUNTIME DESTINATION``.
+ If this option is used multiple times in a single call, its list
+ of configurations accumulates. If an :command:`install(TARGETS)`
+ call uses `\<artifact-kind\>`_ arguments, a separate list of
+ configurations is accumulated for each kind of artifact.
-``COMPONENT``
+``COMPONENT <component>``
Specify an installation component name with which the install rule
is associated, such as ``Runtime`` or ``Development``. During
component-specific installation only install rules associated with
@@ -99,7 +101,7 @@ signatures that specify them. The common options are:
Specify that the file is excluded from a full installation and only
installed as part of a component-specific installation
-``RENAME``
+``RENAME <name>``
Specify a name for an installed file that may be different from the
original file. Renaming is allowed only when a single file is
installed by the command.
@@ -121,861 +123,917 @@ signatures that specify them. The common options are:
they will be created according to the uname rules on Unix-like platforms.
Windows platforms are unaffected.
-Installing Targets
-^^^^^^^^^^^^^^^^^^
-
-.. _`install(TARGETS)`:
-.. _TARGETS:
-
-.. code-block:: cmake
-
- install(TARGETS targets... [EXPORT <export-name>]
- [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET <set-name>]
- [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
- PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET <set-name>|CXX_MODULES_BMI]
- [DESTINATION <dir>]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT <component>]
- [NAMELINK_COMPONENT <component>]
- [OPTIONAL] [EXCLUDE_FROM_ALL]
- [NAMELINK_ONLY|NAMELINK_SKIP]
- ] [...]
- [INCLUDES DESTINATION [<dir> ...]]
- )
-
-The ``TARGETS`` form specifies rules for installing targets from a
-project. There are several kinds of target :ref:`Output Artifacts`
-that may be installed:
-
-``ARCHIVE``
- Target artifacts of this kind include:
-
- * *Static libraries*
- (except on macOS when marked as ``FRAMEWORK``, see below);
- * *DLL import libraries*
- (on all Windows-based systems including Cygwin; they have extension
- ``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``);
- * On AIX, the *linker import file* created for executables with
- :prop_tgt:`ENABLE_EXPORTS` enabled.
- * On macOS, the *linker import file* created for shared libraries with
- :prop_tgt:`ENABLE_EXPORTS` enabled (except when marked as ``FRAMEWORK``,
- see below).
-
-``LIBRARY``
- Target artifacts of this kind include:
-
- * *Shared libraries*, except
-
- - DLLs (these go to ``RUNTIME``, see below),
- - on macOS when marked as ``FRAMEWORK`` (see below).
-
-``RUNTIME``
- Target artifacts of this kind include:
-
- * *Executables*
- (except on macOS when marked as ``MACOSX_BUNDLE``, see ``BUNDLE`` below);
- * DLLs (on all Windows-based systems including Cygwin; note that the
- accompanying import libraries are of kind ``ARCHIVE``).
-
-``OBJECTS``
- .. versionadded:: 3.9
-
- Object files associated with *object libraries*.
-
-``FRAMEWORK``
- Both static and shared libraries marked with the ``FRAMEWORK``
- property are treated as ``FRAMEWORK`` targets on macOS.
-
-``BUNDLE``
- Executables marked with the :prop_tgt:`MACOSX_BUNDLE` property are treated as
- ``BUNDLE`` targets on macOS.
-
-``PUBLIC_HEADER``
- Any :prop_tgt:`PUBLIC_HEADER` files associated with a library are installed in
- the destination specified by the ``PUBLIC_HEADER`` argument on non-Apple
- platforms. Rules defined by this argument are ignored for :prop_tgt:`FRAMEWORK`
- libraries on Apple platforms because the associated files are installed
- into the appropriate locations inside the framework folder. See
- :prop_tgt:`PUBLIC_HEADER` for details.
-
-``PRIVATE_HEADER``
- Similar to ``PUBLIC_HEADER``, but for ``PRIVATE_HEADER`` files. See
- :prop_tgt:`PRIVATE_HEADER` for details.
-
-``RESOURCE``
- Similar to ``PUBLIC_HEADER`` and ``PRIVATE_HEADER``, but for
- ``RESOURCE`` files. See :prop_tgt:`RESOURCE` for details.
-
-``FILE_SET <set>``
- .. versionadded:: 3.23
-
- File sets are defined by the :command:`target_sources(FILE_SET)` command.
- If the file set ``<set>`` exists and is ``PUBLIC`` or ``INTERFACE``, any
- files in the set are installed under the destination (see below).
- The directory structure relative to the file set's base directories is
- preserved. For example, a file added to the file set as
- ``/blah/include/myproj/here.h`` with a base directory ``/blah/include``
- would be installed to ``myproj/here.h`` below the destination.
-
-``CXX_MODULES_BMI``
-
- .. note ::
-
- Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
-
- Any module files from C++ modules from ``PUBLIC`` sources in a file set of
- type ``CXX_MODULES`` will be installed to the given ``DESTINATION``. All
- modules are placed directly in the destination as no directory structure is
- derived from the names of the modules. An empty ``DESTINATION`` may be used
- to suppress installing these files (for use in generic code).
-
-For each of these arguments given, the arguments following them only apply
-to the target or file type specified in the argument. If none is given, the
-installation properties apply to all target types.
-
-For regular executables, static libraries and shared libraries, the
-``DESTINATION`` argument is not required. For these target types, when
-``DESTINATION`` is omitted, a default destination will be taken from the
-appropriate variable from :module:`GNUInstallDirs`, or set to a built-in
-default value if that variable is not defined. The same is true for file
-sets, and the public and private headers associated with the installed
-targets through the :prop_tgt:`PUBLIC_HEADER` and :prop_tgt:`PRIVATE_HEADER`
-target properties. A destination must always be provided for module libraries,
-Apple bundles and frameworks. A destination can be omitted for interface and
-object libraries, but they are handled differently (see the discussion of this
-topic toward the end of this section).
-
-For shared libraries on DLL platforms, if neither ``RUNTIME`` nor ``ARCHIVE``
-destinations are specified, both the ``RUNTIME`` and ``ARCHIVE`` components are
-installed to their default destinations. If either a ``RUNTIME`` or ``ARCHIVE``
-destination is specified, the component is installed to that destination, and
-the other component is not installed. If both ``RUNTIME`` and ``ARCHIVE``
-destinations are specified, then both components are installed to their
-respective destinations.
-
-The following table shows the target types with their associated variables and
-built-in defaults that apply when no destination is given:
-
-=============================== =============================== ======================
- Target Type GNUInstallDirs Variable Built-In Default
-=============================== =============================== ======================
-``RUNTIME`` ``${CMAKE_INSTALL_BINDIR}`` ``bin``
-``LIBRARY`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
-``ARCHIVE`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
-``PRIVATE_HEADER`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
-``PUBLIC_HEADER`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
-``FILE_SET`` (type ``HEADERS``) ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
-=============================== =============================== ======================
-
-Projects wishing to follow the common practice of installing headers into a
-project-specific subdirectory may prefer using file sets with appropriate
-paths and base directories. Otherwise, they must provide a ``DESTINATION``
-instead of being able to rely on the above (see next example below).
-
-To make packages compliant with distribution filesystem layout policies, if
-projects must specify a ``DESTINATION``, it is recommended that they use a
-path that begins with the appropriate :module:`GNUInstallDirs` variable.
-This allows package maintainers to control the install destination by setting
-the appropriate cache variables. The following example shows a static library
-being installed to the default destination provided by
-:module:`GNUInstallDirs`, but with its headers installed to a project-specific
-subdirectory without using file sets:
-
-.. code-block:: cmake
-
- add_library(mylib STATIC ...)
- set_target_properties(mylib PROPERTIES PUBLIC_HEADER mylib.h)
- include(GNUInstallDirs)
- install(TARGETS mylib
- PUBLIC_HEADER
- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproj
- )
+Signatures
+^^^^^^^^^^
-In addition to the common options listed above, each target can accept
-the following additional arguments:
+.. signature::
+ install(TARGETS <target>... [...])
-``NAMELINK_COMPONENT``
- .. versionadded:: 3.12
+ Install target :ref:`Output Artifacts` and associated files:
- On some platforms a versioned shared library has a symbolic link such
- as::
+ .. code-block:: cmake
- lib<name>.so -> lib<name>.so.1
+ install(TARGETS <target>... [EXPORT <export-name>]
+ [RUNTIME_DEPENDENCIES <arg>...|RUNTIME_DEPENDENCY_SET <set-name>]
+ [<artifact-option>...]
+ [<artifact-kind> <artifact-option>...]...
+ [INCLUDES DESTINATION [<dir> ...]]
+ )
- where ``lib<name>.so.1`` is the soname of the library and ``lib<name>.so``
- is a "namelink" allowing linkers to find the library when given
- ``-l<name>``. The ``NAMELINK_COMPONENT`` option is similar to the
- ``COMPONENT`` option, but it changes the installation component of a shared
- library namelink if one is generated. If not specified, this defaults to the
- value of ``COMPONENT``. It is an error to use this parameter outside of a
- ``LIBRARY`` block.
+ where ``<artifact-option>...`` group may contain:
- .. versionchanged:: 3.27
- This parameter is also usable for an ``ARCHIVE`` block to manage
- the linker import file created, on macOS, for shared libraries with
- :prop_tgt:`ENABLE_EXPORTS` enabled.
+ .. code-block:: cmake
- Consider the following example:
+ [DESTINATION <dir>]
+ [PERMISSIONS <permission>...]
+ [CONFIGURATIONS <config>...]
+ [COMPONENT <component>]
+ [NAMELINK_COMPONENT <component>]
+ [OPTIONAL] [EXCLUDE_FROM_ALL]
+ [NAMELINK_ONLY|NAMELINK_SKIP]
+
+ The first ``<artifact-option>...`` group applies to target
+ :ref:`Output Artifacts` that do not have a dedicated group specified
+ later in the same call.
+
+ .. _`<artifact-kind>`:
+
+ Each ``<artifact-kind> <artifact-option>...`` group applies to
+ :ref:`Output Artifacts` of the specified artifact kind:
+
+ ``ARCHIVE``
+ Target artifacts of this kind include:
+
+ * *Static libraries*
+ (except on macOS when marked as ``FRAMEWORK``, see below);
+ * *DLL import libraries*
+ (on all Windows-based systems including Cygwin; they have extension
+ ``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``);
+ * On AIX, the *linker import file* created for executables with
+ :prop_tgt:`ENABLE_EXPORTS` enabled.
+ * On macOS, the *linker import file* created for shared libraries with
+ :prop_tgt:`ENABLE_EXPORTS` enabled (except when marked as ``FRAMEWORK``,
+ see below).
+
+ ``LIBRARY``
+ Target artifacts of this kind include:
+
+ * *Shared libraries*, except
+
+ - DLLs (these go to ``RUNTIME``, see below),
+ - on macOS when marked as ``FRAMEWORK`` (see below).
+
+ ``RUNTIME``
+ Target artifacts of this kind include:
+
+ * *Executables*
+ (except on macOS when marked as ``MACOSX_BUNDLE``, see ``BUNDLE`` below);
+ * DLLs (on all Windows-based systems including Cygwin; note that the
+ accompanying import libraries are of kind ``ARCHIVE``).
+
+ ``OBJECTS``
+ .. versionadded:: 3.9
+
+ Object files associated with *object libraries*.
+
+ ``FRAMEWORK``
+ Both static and shared libraries marked with the ``FRAMEWORK``
+ property are treated as ``FRAMEWORK`` targets on macOS.
+
+ ``BUNDLE``
+ Executables marked with the :prop_tgt:`MACOSX_BUNDLE` property are treated as
+ ``BUNDLE`` targets on macOS.
+
+ ``PUBLIC_HEADER``
+ Any :prop_tgt:`PUBLIC_HEADER` files associated with a library are installed in
+ the destination specified by the ``PUBLIC_HEADER`` argument on non-Apple
+ platforms. Rules defined by this argument are ignored for :prop_tgt:`FRAMEWORK`
+ libraries on Apple platforms because the associated files are installed
+ into the appropriate locations inside the framework folder. See
+ :prop_tgt:`PUBLIC_HEADER` for details.
+
+ ``PRIVATE_HEADER``
+ Similar to ``PUBLIC_HEADER``, but for ``PRIVATE_HEADER`` files. See
+ :prop_tgt:`PRIVATE_HEADER` for details.
+
+ ``RESOURCE``
+ Similar to ``PUBLIC_HEADER`` and ``PRIVATE_HEADER``, but for
+ ``RESOURCE`` files. See :prop_tgt:`RESOURCE` for details.
+
+ ``FILE_SET <set-name>``
+ .. versionadded:: 3.23
+
+ File sets are defined by the :command:`target_sources(FILE_SET)` command.
+ If the file set ``<set-name>`` exists and is ``PUBLIC`` or ``INTERFACE``,
+ any files in the set are installed under the destination (see below).
+ The directory structure relative to the file set's base directories is
+ preserved. For example, a file added to the file set as
+ ``/blah/include/myproj/here.h`` with a base directory ``/blah/include``
+ would be installed to ``myproj/here.h`` below the destination.
+
+ ``CXX_MODULES_BMI``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ Any module files from C++ modules from ``PUBLIC`` sources in a file set of
+ type ``CXX_MODULES`` will be installed to the given ``DESTINATION``. All
+ modules are placed directly in the destination as no directory structure is
+ derived from the names of the modules. An empty ``DESTINATION`` may be used
+ to suppress installing these files (for use in generic code).
+
+ For regular executables, static libraries and shared libraries, the
+ ``DESTINATION`` argument is not required. For these target types, when
+ ``DESTINATION`` is omitted, a default destination will be taken from the
+ appropriate variable from :module:`GNUInstallDirs`, or set to a built-in
+ default value if that variable is not defined. The same is true for file
+ sets, and the public and private headers associated with the installed
+ targets through the :prop_tgt:`PUBLIC_HEADER` and :prop_tgt:`PRIVATE_HEADER`
+ target properties. A destination must always be provided for module libraries,
+ Apple bundles and frameworks. A destination can be omitted for interface and
+ object libraries, but they are handled differently (see the discussion of this
+ topic toward the end of this section).
+
+ For shared libraries on DLL platforms, if neither ``RUNTIME`` nor ``ARCHIVE``
+ destinations are specified, both the ``RUNTIME`` and ``ARCHIVE`` components are
+ installed to their default destinations. If either a ``RUNTIME`` or ``ARCHIVE``
+ destination is specified, the component is installed to that destination, and
+ the other component is not installed. If both ``RUNTIME`` and ``ARCHIVE``
+ destinations are specified, then both components are installed to their
+ respective destinations.
+
+ The following table shows the target types with their associated variables and
+ built-in defaults that apply when no destination is given:
+
+ =============================== =============================== ======================
+ Target Type GNUInstallDirs Variable Built-In Default
+ =============================== =============================== ======================
+ ``RUNTIME`` ``${CMAKE_INSTALL_BINDIR}`` ``bin``
+ ``LIBRARY`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
+ ``ARCHIVE`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
+ ``PRIVATE_HEADER`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+ ``PUBLIC_HEADER`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+ ``FILE_SET`` (type ``HEADERS``) ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+ =============================== =============================== ======================
+
+ Projects wishing to follow the common practice of installing headers into a
+ project-specific subdirectory may prefer using file sets with appropriate
+ paths and base directories. Otherwise, they must provide a ``DESTINATION``
+ instead of being able to rely on the above (see next example below).
+
+ To make packages compliant with distribution filesystem layout policies, if
+ projects must specify a ``DESTINATION``, it is recommended that they use a
+ path that begins with the appropriate :module:`GNUInstallDirs` variable.
+ This allows package maintainers to control the install destination by setting
+ the appropriate cache variables. The following example shows a static library
+ being installed to the default destination provided by
+ :module:`GNUInstallDirs`, but with its headers installed to a project-specific
+ subdirectory without using file sets:
.. code-block:: cmake
+ add_library(mylib STATIC ...)
+ set_target_properties(mylib PROPERTIES PUBLIC_HEADER mylib.h)
+ include(GNUInstallDirs)
install(TARGETS mylib
- LIBRARY
- COMPONENT Libraries
- NAMELINK_COMPONENT Development
PUBLIC_HEADER
- COMPONENT Development
- )
-
- In this scenario, if you choose to install only the ``Development``
- component, both the headers and namelink will be installed without the
- library. (If you don't also install the ``Libraries`` component, the
- namelink will be a dangling symlink, and projects that link to the library
- will have build errors.) If you install only the ``Libraries`` component,
- only the library will be installed, without the headers and namelink.
-
- This option is typically used for package managers that have separate
- runtime and development packages. For example, on Debian systems, the
- library is expected to be in the runtime package, and the headers and
- namelink are expected to be in the development package.
-
- See the :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` target properties for
- details on creating versioned shared libraries.
-
-``NAMELINK_ONLY``
- This option causes the installation of only the namelink when a library
- target is installed. On platforms where versioned shared libraries do not
- have namelinks or when a library is not versioned, the ``NAMELINK_ONLY``
- option installs nothing. It is an error to use this parameter outside of a
- ``LIBRARY`` block.
-
- .. versionchanged:: 3.27
- This parameter is also usable for an ``ARCHIVE`` block to manage
- the linker import file created, on macOS, for shared libraries with
- :prop_tgt:`ENABLE_EXPORTS` enabled.
-
- When ``NAMELINK_ONLY`` is given, either ``NAMELINK_COMPONENT`` or
- ``COMPONENT`` may be used to specify the installation component of the
- namelink, but ``COMPONENT`` should generally be preferred.
-
-``NAMELINK_SKIP``
- Similar to ``NAMELINK_ONLY``, but it has the opposite effect: it causes the
- installation of library files other than the namelink when a library target
- is installed. When neither ``NAMELINK_ONLY`` or ``NAMELINK_SKIP`` are given,
- both portions are installed. On platforms where versioned shared libraries
- do not have symlinks or when a library is not versioned, ``NAMELINK_SKIP``
- installs the library. It is an error to use this parameter outside of a
- ``LIBRARY`` block.
-
- .. versionchanged:: 3.27
- This parameter is also usable for an ``ARCHIVE`` block to manage
- the linker import file created, on macOS, for shared libraries with
- :prop_tgt:`ENABLE_EXPORTS` enabled.
-
- If ``NAMELINK_SKIP`` is specified, ``NAMELINK_COMPONENT`` has no effect. It
- is not recommended to use ``NAMELINK_SKIP`` in conjunction with
- ``NAMELINK_COMPONENT``.
-
-The `install(TARGETS)`_ command can also accept the following options at the
-top level:
-
-``EXPORT``
- This option associates the installed target files with an export called
- ``<export-name>``. It must appear before any target options. To actually
- install the export file itself, call `install(EXPORT)`_, documented below.
- See documentation of the :prop_tgt:`EXPORT_NAME` target property to change
- the name of the exported target.
-
- If ``EXPORT`` is used and the targets include ``PUBLIC`` or ``INTERFACE``
- file sets, all of them must be specified with ``FILE_SET`` arguments. All
- ``PUBLIC`` or ``INTERFACE`` file sets associated with a target are included
- in the export.
-
-``INCLUDES DESTINATION``
- This option specifies a list of directories which will be added to the
- :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property of the
- ``<targets>`` when exported by the `install(EXPORT)`_ command. If a
- relative path is specified, it is treated as relative to the
- :genex:`$<INSTALL_PREFIX>`.
-
-``RUNTIME_DEPENDENCY_SET``
- .. versionadded:: 3.21
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproj
+ )
+
+ In addition to the `common options`_ listed above, each target can accept
+ the following additional arguments:
+
+ ``NAMELINK_COMPONENT``
+ .. versionadded:: 3.12
+
+ On some platforms a versioned shared library has a symbolic link such
+ as::
+
+ lib<name>.so -> lib<name>.so.1
+
+ where ``lib<name>.so.1`` is the soname of the library and ``lib<name>.so``
+ is a "namelink" allowing linkers to find the library when given
+ ``-l<name>``. The ``NAMELINK_COMPONENT`` option is similar to the
+ ``COMPONENT`` option, but it changes the installation component of a shared
+ library namelink if one is generated. If not specified, this defaults to the
+ value of ``COMPONENT``. It is an error to use this parameter outside of a
+ ``LIBRARY`` block.
+
+ .. versionchanged:: 3.27
+ This parameter is also usable for an ``ARCHIVE`` block to manage
+ the linker import file created, on macOS, for shared libraries with
+ :prop_tgt:`ENABLE_EXPORTS` enabled.
+
+ See the `Example: Install Targets with Per-Artifact Components`_
+ for an example using ``NAMELINK_COMPONENT``.
+
+ This option is typically used for package managers that have separate
+ runtime and development packages. For example, on Debian systems, the
+ library is expected to be in the runtime package, and the headers and
+ namelink are expected to be in the development package.
+
+ See the :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` target properties for
+ details on creating versioned shared libraries.
+
+ ``NAMELINK_ONLY``
+ This option causes the installation of only the namelink when a library
+ target is installed. On platforms where versioned shared libraries do not
+ have namelinks or when a library is not versioned, the ``NAMELINK_ONLY``
+ option installs nothing. It is an error to use this parameter outside of a
+ ``LIBRARY`` block.
+
+ .. versionchanged:: 3.27
+ This parameter is also usable for an ``ARCHIVE`` block to manage
+ the linker import file created, on macOS, for shared libraries with
+ :prop_tgt:`ENABLE_EXPORTS` enabled.
+
+ When ``NAMELINK_ONLY`` is given, either ``NAMELINK_COMPONENT`` or
+ ``COMPONENT`` may be used to specify the installation component of the
+ namelink, but ``COMPONENT`` should generally be preferred.
+
+ ``NAMELINK_SKIP``
+ Similar to ``NAMELINK_ONLY``, but it has the opposite effect: it causes the
+ installation of library files other than the namelink when a library target
+ is installed. When neither ``NAMELINK_ONLY`` or ``NAMELINK_SKIP`` are given,
+ both portions are installed. On platforms where versioned shared libraries
+ do not have symlinks or when a library is not versioned, ``NAMELINK_SKIP``
+ installs the library. It is an error to use this parameter outside of a
+ ``LIBRARY`` block.
+
+ .. versionchanged:: 3.27
+ This parameter is also usable for an ``ARCHIVE`` block to manage
+ the linker import file created, on macOS, for shared libraries with
+ :prop_tgt:`ENABLE_EXPORTS` enabled.
+
+ If ``NAMELINK_SKIP`` is specified, ``NAMELINK_COMPONENT`` has no effect. It
+ is not recommended to use ``NAMELINK_SKIP`` in conjunction with
+ ``NAMELINK_COMPONENT``.
+
+ The :command:`install(TARGETS)` command can also accept the following
+ options at the top level:
+
+ ``EXPORT``
+ This option associates the installed target files with an export called
+ ``<export-name>``. It must appear before any target options.
+ To actually install the export file itself, call
+ :command:`install(EXPORT)`, documented below.
+ See documentation of the :prop_tgt:`EXPORT_NAME` target property to change
+ the name of the exported target.
+
+ If ``EXPORT`` is used and the targets include ``PUBLIC`` or ``INTERFACE``
+ file sets, all of them must be specified with ``FILE_SET`` arguments. All
+ ``PUBLIC`` or ``INTERFACE`` file sets associated with a target are included
+ in the export.
+
+ ``INCLUDES DESTINATION``
+ This option specifies a list of directories which will be added to the
+ :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property of the
+ ``<targets>`` when exported by the :command:`install(EXPORT)` command.
+ If a relative path is specified, it is treated as relative to the
+ :genex:`$<INSTALL_PREFIX>`.
+
+ ``RUNTIME_DEPENDENCY_SET <set-name>``
+ .. versionadded:: 3.21
+
+ This option causes all runtime dependencies of installed executable, shared
+ library, and module targets to be added to the specified runtime dependency
+ set. This set can then be installed with an
+ :command:`install(RUNTIME_DEPENDENCY_SET)` command.
+
+ This keyword and the ``RUNTIME_DEPENDENCIES`` keyword are mutually
+ exclusive.
+
+ ``RUNTIME_DEPENDENCIES <arg>...``
+ .. versionadded:: 3.21
+
+ This option causes all runtime dependencies of installed executable, shared
+ library, and module targets to be installed along with the targets
+ themselves. The ``RUNTIME``, ``LIBRARY``, ``FRAMEWORK``, and generic
+ arguments are used to determine the properties (``DESTINATION``,
+ ``COMPONENT``, etc.) of the installation of these dependencies.
+
+ ``RUNTIME_DEPENDENCIES`` is semantically equivalent to the following pair
+ of calls:
+
+ .. code-block:: cmake
+
+ install(TARGETS ... RUNTIME_DEPENDENCY_SET <set-name>)
+ install(RUNTIME_DEPENDENCY_SET <set-name> <arg>...)
+
+ where ``<set-name>`` will be a randomly generated set name.
+ ``<arg>...`` may include any of the following keywords supported by
+ the :command:`install(RUNTIME_DEPENDENCY_SET)` command:
+
+ * ``DIRECTORIES``
+ * ``PRE_INCLUDE_REGEXES``
+ * ``PRE_EXCLUDE_REGEXES``
+ * ``POST_INCLUDE_REGEXES``
+ * ``POST_EXCLUDE_REGEXES``
+ * ``POST_INCLUDE_FILES``
+ * ``POST_EXCLUDE_FILES``
+
+ The ``RUNTIME_DEPENDENCIES`` and ``RUNTIME_DEPENDENCY_SET`` keywords are
+ mutually exclusive.
+
+ :ref:`Interface Libraries` may be listed among the targets to install.
+ They install no artifacts but will be included in an associated ``EXPORT``.
+ If :ref:`Object Libraries` are listed but given no destination for their
+ object files, they will be exported as :ref:`Interface Libraries`.
+ This is sufficient to satisfy transitive usage requirements of other
+ targets that link to the object libraries in their implementation.
+
+ Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
+ set to ``TRUE`` has undefined behavior.
+
+ .. versionadded:: 3.3
+ An install destination given as a ``DESTINATION`` argument may
+ use "generator expressions" with the syntax ``$<...>``. See the
+ :manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+ .. versionadded:: 3.13
+ :command:`install(TARGETS)` can install targets that were created in
+ other directories. When using such cross-directory install rules, running
+ ``make install`` (or similar) from a subdirectory will not guarantee that
+ targets from other directories are up-to-date. You can use
+ :command:`target_link_libraries` or :command:`add_dependencies`
+ to ensure that such out-of-directory targets are built before the
+ subdirectory-specific install rules are run.
+
+.. signature::
+ install(IMPORTED_RUNTIME_ARTIFACTS <target>... [...])
- This option causes all runtime dependencies of installed executable, shared
- library, and module targets to be added to the specified runtime dependency
- set. This set can then be installed with an
- `install(RUNTIME_DEPENDENCY_SET)`_ command.
-
- This keyword and the ``RUNTIME_DEPENDENCIES`` keyword are mutually
- exclusive.
-
-``RUNTIME_DEPENDENCIES``
.. versionadded:: 3.21
- This option causes all runtime dependencies of installed executable, shared
- library, and module targets to be installed along with the targets
- themselves. The ``RUNTIME``, ``LIBRARY``, ``FRAMEWORK``, and generic
- arguments are used to determine the properties (``DESTINATION``,
- ``COMPONENT``, etc.) of the installation of these dependencies.
-
- ``RUNTIME_DEPENDENCIES`` is semantically equivalent to the following pair
- of calls:
+ Install runtime artifacts of imported targets:
.. code-block:: cmake
- install(TARGETS ... RUNTIME_DEPENDENCY_SET <set-name>)
- install(RUNTIME_DEPENDENCY_SET <set-name> args...)
-
- where ``<set-name>`` will be a randomly generated set name.
- The ``args...`` may include any of the following keywords supported by
- the `install(RUNTIME_DEPENDENCY_SET)`_ command:
+ install(IMPORTED_RUNTIME_ARTIFACTS <target>...
+ [RUNTIME_DEPENDENCY_SET <set-name>]
+ [[LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]
+ [DESTINATION <dir>]
+ [PERMISSIONS <permission>...]
+ [CONFIGURATIONS <config>...]
+ [COMPONENT <component>]
+ [OPTIONAL] [EXCLUDE_FROM_ALL]
+ ] [...]
+ )
+
+ The ``IMPORTED_RUNTIME_ARTIFACTS`` form specifies rules for installing the
+ runtime artifacts of imported targets. Projects may do this if they want to
+ bundle outside executables or modules inside their installation. The
+ ``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE`` arguments have the
+ same semantics that they do in the `TARGETS`_ mode. Only the runtime artifacts
+ of imported targets are installed (except in the case of :prop_tgt:`FRAMEWORK`
+ libraries, :prop_tgt:`MACOSX_BUNDLE` executables, and :prop_tgt:`BUNDLE`
+ CFBundles.) For example, headers and import libraries associated with DLLs are
+ not installed. In the case of :prop_tgt:`FRAMEWORK` libraries,
+ :prop_tgt:`MACOSX_BUNDLE` executables, and :prop_tgt:`BUNDLE` CFBundles, the
+ entire directory is installed.
+
+ The ``RUNTIME_DEPENDENCY_SET`` option causes the runtime artifacts of the
+ imported executable, shared library, and module library ``targets`` to be
+ added to the ``<set-name>`` runtime dependency set. This set can then be
+ installed with an :command:`install(RUNTIME_DEPENDENCY_SET)` command.
+
+.. signature::
+ install(FILES <file>... [...])
+ install(PROGRAMS <program>... [...])
+
+ .. note::
+
+ If installing header files, consider using file sets defined by
+ :command:`target_sources(FILE_SET)` instead. File sets associate
+ headers with a target and they install as part of the target.
+
+ Install files or programs:
- * ``DIRECTORIES``
- * ``PRE_INCLUDE_REGEXES``
- * ``PRE_EXCLUDE_REGEXES``
- * ``POST_INCLUDE_REGEXES``
- * ``POST_EXCLUDE_REGEXES``
- * ``POST_INCLUDE_FILES``
- * ``POST_EXCLUDE_FILES``
-
- The ``RUNTIME_DEPENDENCIES`` and ``RUNTIME_DEPENDENCY_SET`` keywords are
- mutually exclusive.
+ .. code-block:: cmake
-One or more groups of properties may be specified in a single call to
-the ``TARGETS`` form of this command. A target may be installed more than
-once to different locations. Consider hypothetical targets ``myExe``,
-``mySharedLib``, and ``myStaticLib``. The code:
+ install(<FILES|PROGRAMS> <file>...
+ TYPE <type> | DESTINATION <dir>
+ [PERMISSIONS <permission>...]
+ [CONFIGURATIONS <config>...]
+ [COMPONENT <component>]
+ [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
+
+ The ``FILES`` form specifies rules for installing files for a project.
+ File names given as relative paths are interpreted with respect to the
+ current source directory. Files installed by this form are by default
+ given permissions ``OWNER_WRITE``, ``OWNER_READ``, ``GROUP_READ``, and
+ ``WORLD_READ`` if no ``PERMISSIONS`` argument is given.
+
+ The ``PROGRAMS`` form is identical to the ``FILES`` form except that the
+ default permissions for the installed file also include ``OWNER_EXECUTE``,
+ ``GROUP_EXECUTE``, and ``WORLD_EXECUTE``. This form is intended to install
+ programs that are not targets, such as shell scripts. Use the ``TARGETS``
+ form to install targets built within the project.
+
+ The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use
+ "generator expressions" with the syntax ``$<...>``. See the
+ :manual:`cmake-generator-expressions(7)` manual for available expressions.
+ However, if any item begins in a generator expression it must evaluate
+ to a full path.
+
+ Either a ``TYPE`` or a ``DESTINATION`` must be provided, but not both.
+ A ``TYPE`` argument specifies the generic file type of the files being
+ installed. A destination will then be set automatically by taking the
+ corresponding variable from :module:`GNUInstallDirs`, or by using a
+ built-in default if that variable is not defined. See the table below for
+ the supported file types and their corresponding variables and built-in
+ defaults. Projects can provide a ``DESTINATION`` argument instead of a
+ file type if they wish to explicitly define the install destination.
+
+ ======================= ================================== =========================
+ ``TYPE`` Argument GNUInstallDirs Variable Built-In Default
+ ======================= ================================== =========================
+ ``BIN`` ``${CMAKE_INSTALL_BINDIR}`` ``bin``
+ ``SBIN`` ``${CMAKE_INSTALL_SBINDIR}`` ``sbin``
+ ``LIB`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
+ ``INCLUDE`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+ ``SYSCONF`` ``${CMAKE_INSTALL_SYSCONFDIR}`` ``etc``
+ ``SHAREDSTATE`` ``${CMAKE_INSTALL_SHARESTATEDIR}`` ``com``
+ ``LOCALSTATE`` ``${CMAKE_INSTALL_LOCALSTATEDIR}`` ``var``
+ ``RUNSTATE`` ``${CMAKE_INSTALL_RUNSTATEDIR}`` ``<LOCALSTATE dir>/run``
+ ``DATA`` ``${CMAKE_INSTALL_DATADIR}`` ``<DATAROOT dir>``
+ ``INFO`` ``${CMAKE_INSTALL_INFODIR}`` ``<DATAROOT dir>/info``
+ ``LOCALE`` ``${CMAKE_INSTALL_LOCALEDIR}`` ``<DATAROOT dir>/locale``
+ ``MAN`` ``${CMAKE_INSTALL_MANDIR}`` ``<DATAROOT dir>/man``
+ ``DOC`` ``${CMAKE_INSTALL_DOCDIR}`` ``<DATAROOT dir>/doc``
+ ======================= ================================== =========================
+
+ Projects wishing to follow the common practice of installing headers into a
+ project-specific subdirectory will need to provide a destination rather than
+ rely on the above. Using file sets for headers instead of ``install(FILES)``
+ would be even better (see :command:`target_sources(FILE_SET)`).
+
+ Note that some of the types' built-in defaults use the ``DATAROOT`` directory as
+ a prefix. The ``DATAROOT`` prefix is calculated similarly to the types, with
+ ``CMAKE_INSTALL_DATAROOTDIR`` as the variable and ``share`` as the built-in
+ default. You cannot use ``DATAROOT`` as a ``TYPE`` parameter; please use
+ ``DATA`` instead.
+
+ To make packages compliant with distribution filesystem layout policies, if
+ projects must specify a ``DESTINATION``, it is recommended that they use a
+ path that begins with the appropriate :module:`GNUInstallDirs` variable.
+ This allows package maintainers to control the install destination by setting
+ the appropriate cache variables. The following example shows how to follow
+ this advice while installing an image to a project-specific documentation
+ subdirectory:
-.. code-block:: cmake
+ .. code-block:: cmake
- install(TARGETS myExe mySharedLib myStaticLib
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib/static)
- install(TARGETS mySharedLib DESTINATION /some/full/path)
-
-will install ``myExe`` to ``<prefix>/bin`` and ``myStaticLib`` to
-``<prefix>/lib/static``. On non-DLL platforms ``mySharedLib`` will be
-installed to ``<prefix>/lib`` and ``/some/full/path``. On DLL platforms
-the ``mySharedLib`` DLL will be installed to ``<prefix>/bin`` and
-``/some/full/path`` and its import library will be installed to
-``<prefix>/lib/static`` and ``/some/full/path``.
-
-:ref:`Interface Libraries` may be listed among the targets to install.
-They install no artifacts but will be included in an associated ``EXPORT``.
-If :ref:`Object Libraries` are listed but given no destination for their
-object files, they will be exported as :ref:`Interface Libraries`.
-This is sufficient to satisfy transitive usage requirements of other
-targets that link to the object libraries in their implementation.
-
-Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
-set to ``TRUE`` has undefined behavior.
-
-.. versionadded:: 3.3
- An install destination given as a ``DESTINATION`` argument may
- use "generator expressions" with the syntax ``$<...>``. See the
- :manual:`cmake-generator-expressions(7)` manual for available expressions.
+ include(GNUInstallDirs)
+ install(FILES logo.png
+ DESTINATION ${CMAKE_INSTALL_DOCDIR}/myproj
+ )
-.. versionadded:: 3.13
- `install(TARGETS)`_ can install targets that were created in
- other directories. When using such cross-directory install rules, running
- ``make install`` (or similar) from a subdirectory will not guarantee that
- targets from other directories are up-to-date. You can use
- :command:`target_link_libraries` or :command:`add_dependencies`
- to ensure that such out-of-directory targets are built before the
- subdirectory-specific install rules are run.
+ .. versionadded:: 3.4
+ An install destination given as a ``DESTINATION`` argument may
+ use "generator expressions" with the syntax ``$<...>``. See the
+ :manual:`cmake-generator-expressions(7)` manual for available expressions.
-Installing Imported Runtime Artifacts
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ .. versionadded:: 3.20
+ An install rename given as a ``RENAME`` argument may
+ use "generator expressions" with the syntax ``$<...>``. See the
+ :manual:`cmake-generator-expressions(7)` manual for available expressions.
-.. _`install(IMPORTED_RUNTIME_ARTIFACTS)`:
-.. _IMPORTED_RUNTIME_ARTIFACTS:
+.. signature::
+ install(DIRECTORY <dir>... [...])
-.. versionadded:: 3.21
+ .. note::
-.. code-block:: cmake
+ To install a directory sub-tree of headers, consider using file sets
+ defined by :command:`target_sources(FILE_SET)` instead. File sets not only
+ preserve directory structure, they also associate headers with a target
+ and install as part of the target.
- install(IMPORTED_RUNTIME_ARTIFACTS targets...
- [RUNTIME_DEPENDENCY_SET <set-name>]
- [[LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]
- [DESTINATION <dir>]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT <component>]
- [OPTIONAL] [EXCLUDE_FROM_ALL]
- ] [...]
- )
+ Install the contents of one or more directories:
-The ``IMPORTED_RUNTIME_ARTIFACTS`` form specifies rules for installing the
-runtime artifacts of imported targets. Projects may do this if they want to
-bundle outside executables or modules inside their installation. The
-``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE`` arguments have the
-same semantics that they do in the `TARGETS`_ mode. Only the runtime artifacts
-of imported targets are installed (except in the case of :prop_tgt:`FRAMEWORK`
-libraries, :prop_tgt:`MACOSX_BUNDLE` executables, and :prop_tgt:`BUNDLE`
-CFBundles.) For example, headers and import libraries associated with DLLs are
-not installed. In the case of :prop_tgt:`FRAMEWORK` libraries,
-:prop_tgt:`MACOSX_BUNDLE` executables, and :prop_tgt:`BUNDLE` CFBundles, the
-entire directory is installed.
-
-The ``RUNTIME_DEPENDENCY_SET`` option causes the runtime artifacts of the
-imported executable, shared library, and module library ``targets`` to be
-added to the ``<set-name>`` runtime dependency set. This set can then be
-installed with an `install(RUNTIME_DEPENDENCY_SET)`_ command.
-
-Installing Files
-^^^^^^^^^^^^^^^^
-
-.. _`install(FILES)`:
-.. _`install(PROGRAMS)`:
-.. _FILES:
-.. _PROGRAMS:
+ .. code-block:: cmake
-.. note::
+ install(DIRECTORY dirs...
+ TYPE <type> | DESTINATION <dir>
+ [FILE_PERMISSIONS <permission>...]
+ [DIRECTORY_PERMISSIONS <permission>...]
+ [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
+ [CONFIGURATIONS <config>...]
+ [COMPONENT <component>] [EXCLUDE_FROM_ALL]
+ [FILES_MATCHING]
+ [[PATTERN <pattern> | REGEX <regex>]
+ [EXCLUDE] [PERMISSIONS <permission>...]] [...])
+
+ The ``DIRECTORY`` form installs contents of one or more directories to a
+ given destination. The directory structure is copied verbatim to the
+ destination. The last component of each directory name is appended to
+ the destination directory but a trailing slash may be used to avoid
+ this because it leaves the last component empty. Directory names
+ given as relative paths are interpreted with respect to the current
+ source directory. If no input directory names are given the
+ destination directory will be created but nothing will be installed
+ into it. The ``FILE_PERMISSIONS`` and ``DIRECTORY_PERMISSIONS`` options
+ specify permissions given to files and directories in the destination.
+ If ``USE_SOURCE_PERMISSIONS`` is specified and ``FILE_PERMISSIONS`` is not,
+ file permissions will be copied from the source directory structure.
+ If no permissions are specified files will be given the default
+ permissions specified in the ``FILES`` form of the command, and the
+ directories will be given the default permissions specified in the
+ ``PROGRAMS`` form of the command.
+
+ .. versionadded:: 3.1
+ The ``MESSAGE_NEVER`` option disables file installation status output.
+
+ Installation of directories may be controlled with fine granularity
+ using the ``PATTERN`` or ``REGEX`` options. These "match" options specify a
+ globbing pattern or regular expression to match directories or files
+ encountered within input directories. They may be used to apply
+ certain options (see below) to a subset of the files and directories
+ encountered. The full path to each input file or directory (with
+ forward slashes) is matched against the expression. A ``PATTERN`` will
+ match only complete file names: the portion of the full path matching
+ the pattern must occur at the end of the file name and be preceded by
+ a slash. A ``REGEX`` will match any portion of the full path but it may
+ use ``/`` and ``$`` to simulate the ``PATTERN`` behavior. By default all
+ files and directories are installed whether or not they are matched.
+ The ``FILES_MATCHING`` option may be given before the first match option
+ to disable installation of files (but not directories) not matched by
+ any expression. For example, the code
- If installing header files, consider using file sets defined by
- :command:`target_sources(FILE_SET)` instead. File sets associate
- headers with a target and they install as part of the target.
+ .. code-block:: cmake
-.. code-block:: cmake
+ install(DIRECTORY src/ DESTINATION doc/myproj
+ FILES_MATCHING PATTERN "*.png")
- install(<FILES|PROGRAMS> files...
- TYPE <type> | DESTINATION <dir>
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT <component>]
- [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
-
-The ``FILES`` form specifies rules for installing files for a project.
-File names given as relative paths are interpreted with respect to the
-current source directory. Files installed by this form are by default
-given permissions ``OWNER_WRITE``, ``OWNER_READ``, ``GROUP_READ``, and
-``WORLD_READ`` if no ``PERMISSIONS`` argument is given.
-
-The ``PROGRAMS`` form is identical to the ``FILES`` form except that the
-default permissions for the installed file also include ``OWNER_EXECUTE``,
-``GROUP_EXECUTE``, and ``WORLD_EXECUTE``. This form is intended to install
-programs that are not targets, such as shell scripts. Use the ``TARGETS``
-form to install targets built within the project.
-
-The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use
-"generator expressions" with the syntax ``$<...>``. See the
-:manual:`cmake-generator-expressions(7)` manual for available expressions.
-However, if any item begins in a generator expression it must evaluate
-to a full path.
-
-Either a ``TYPE`` or a ``DESTINATION`` must be provided, but not both.
-A ``TYPE`` argument specifies the generic file type of the files being
-installed. A destination will then be set automatically by taking the
-corresponding variable from :module:`GNUInstallDirs`, or by using a
-built-in default if that variable is not defined. See the table below for
-the supported file types and their corresponding variables and built-in
-defaults. Projects can provide a ``DESTINATION`` argument instead of a
-file type if they wish to explicitly define the install destination.
-
-======================= ================================== =========================
- ``TYPE`` Argument GNUInstallDirs Variable Built-In Default
-======================= ================================== =========================
-``BIN`` ``${CMAKE_INSTALL_BINDIR}`` ``bin``
-``SBIN`` ``${CMAKE_INSTALL_SBINDIR}`` ``sbin``
-``LIB`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
-``INCLUDE`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
-``SYSCONF`` ``${CMAKE_INSTALL_SYSCONFDIR}`` ``etc``
-``SHAREDSTATE`` ``${CMAKE_INSTALL_SHARESTATEDIR}`` ``com``
-``LOCALSTATE`` ``${CMAKE_INSTALL_LOCALSTATEDIR}`` ``var``
-``RUNSTATE`` ``${CMAKE_INSTALL_RUNSTATEDIR}`` ``<LOCALSTATE dir>/run``
-``DATA`` ``${CMAKE_INSTALL_DATADIR}`` ``<DATAROOT dir>``
-``INFO`` ``${CMAKE_INSTALL_INFODIR}`` ``<DATAROOT dir>/info``
-``LOCALE`` ``${CMAKE_INSTALL_LOCALEDIR}`` ``<DATAROOT dir>/locale``
-``MAN`` ``${CMAKE_INSTALL_MANDIR}`` ``<DATAROOT dir>/man``
-``DOC`` ``${CMAKE_INSTALL_DOCDIR}`` ``<DATAROOT dir>/doc``
-======================= ================================== =========================
-
-Projects wishing to follow the common practice of installing headers into a
-project-specific subdirectory will need to provide a destination rather than
-rely on the above. Using file sets for headers instead of ``install(FILES)``
-would be even better (see :command:`target_sources(FILE_SET)`).
-
-Note that some of the types' built-in defaults use the ``DATAROOT`` directory as
-a prefix. The ``DATAROOT`` prefix is calculated similarly to the types, with
-``CMAKE_INSTALL_DATAROOTDIR`` as the variable and ``share`` as the built-in
-default. You cannot use ``DATAROOT`` as a ``TYPE`` parameter; please use
-``DATA`` instead.
-
-To make packages compliant with distribution filesystem layout policies, if
-projects must specify a ``DESTINATION``, it is recommended that they use a
-path that begins with the appropriate :module:`GNUInstallDirs` variable.
-This allows package maintainers to control the install destination by setting
-the appropriate cache variables. The following example shows how to follow
-this advice while installing an image to a project-specific documentation
-subdirectory:
+ will extract and install images from a source tree.
-.. code-block:: cmake
+ Some options may follow a ``PATTERN`` or ``REGEX`` expression as described
+ under :ref:`string(REGEX) <Regex Specification>` and are applied
+ only to files or directories matching them. The ``EXCLUDE`` option will
+ skip the matched file or directory. The ``PERMISSIONS`` option overrides
+ the permissions setting for the matched file or directory. For
+ example the code
- include(GNUInstallDirs)
- install(FILES logo.png
- DESTINATION ${CMAKE_INSTALL_DOCDIR}/myproj
- )
+ .. code-block:: cmake
-.. versionadded:: 3.4
- An install destination given as a ``DESTINATION`` argument may
- use "generator expressions" with the syntax ``$<...>``. See the
- :manual:`cmake-generator-expressions(7)` manual for available expressions.
+ install(DIRECTORY icons scripts/ DESTINATION share/myproj
+ PATTERN "CVS" EXCLUDE
+ PATTERN "scripts/*"
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ)
+
+ will install the ``icons`` directory to ``share/myproj/icons`` and the
+ ``scripts`` directory to ``share/myproj``. The icons will get default
+ file permissions, the scripts will be given specific permissions, and any
+ ``CVS`` directories will be excluded.
+
+ Either a ``TYPE`` or a ``DESTINATION`` must be provided, but not both.
+ A ``TYPE`` argument specifies the generic file type of the files within the
+ listed directories being installed. A destination will then be set
+ automatically by taking the corresponding variable from
+ :module:`GNUInstallDirs`, or by using a built-in default if that variable
+ is not defined. See the table below for the supported file types and their
+ corresponding variables and built-in defaults. Projects can provide a
+ ``DESTINATION`` argument instead of a file type if they wish to explicitly
+ define the install destination.
+
+ ======================= ================================== =========================
+ ``TYPE`` Argument GNUInstallDirs Variable Built-In Default
+ ======================= ================================== =========================
+ ``BIN`` ``${CMAKE_INSTALL_BINDIR}`` ``bin``
+ ``SBIN`` ``${CMAKE_INSTALL_SBINDIR}`` ``sbin``
+ ``LIB`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
+ ``INCLUDE`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+ ``SYSCONF`` ``${CMAKE_INSTALL_SYSCONFDIR}`` ``etc``
+ ``SHAREDSTATE`` ``${CMAKE_INSTALL_SHARESTATEDIR}`` ``com``
+ ``LOCALSTATE`` ``${CMAKE_INSTALL_LOCALSTATEDIR}`` ``var``
+ ``RUNSTATE`` ``${CMAKE_INSTALL_RUNSTATEDIR}`` ``<LOCALSTATE dir>/run``
+ ``DATA`` ``${CMAKE_INSTALL_DATADIR}`` ``<DATAROOT dir>``
+ ``INFO`` ``${CMAKE_INSTALL_INFODIR}`` ``<DATAROOT dir>/info``
+ ``LOCALE`` ``${CMAKE_INSTALL_LOCALEDIR}`` ``<DATAROOT dir>/locale``
+ ``MAN`` ``${CMAKE_INSTALL_MANDIR}`` ``<DATAROOT dir>/man``
+ ``DOC`` ``${CMAKE_INSTALL_DOCDIR}`` ``<DATAROOT dir>/doc``
+ ======================= ================================== =========================
+
+ Note that some of the types' built-in defaults use the ``DATAROOT`` directory as
+ a prefix. The ``DATAROOT`` prefix is calculated similarly to the types, with
+ ``CMAKE_INSTALL_DATAROOTDIR`` as the variable and ``share`` as the built-in
+ default. You cannot use ``DATAROOT`` as a ``TYPE`` parameter; please use
+ ``DATA`` instead.
+
+ To make packages compliant with distribution filesystem layout policies, if
+ projects must specify a ``DESTINATION``, it is recommended that they use a
+ path that begins with the appropriate :module:`GNUInstallDirs` variable.
+ This allows package maintainers to control the install destination by setting
+ the appropriate cache variables.
+
+ .. versionadded:: 3.4
+ An install destination given as a ``DESTINATION`` argument may
+ use "generator expressions" with the syntax ``$<...>``. See the
+ :manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+ .. versionadded:: 3.5
+ The list of ``dirs...`` given to ``DIRECTORY`` may use
+ "generator expressions" too.
+
+.. signature::
+ install(SCRIPT <file> [...])
+ install(CODE <code> [...])
+
+ Invoke CMake scripts or code during installation:
-.. versionadded:: 3.20
- An install rename given as a ``RENAME`` argument may
- use "generator expressions" with the syntax ``$<...>``. See the
- :manual:`cmake-generator-expressions(7)` manual for available expressions.
+ .. code-block:: cmake
-Installing Directories
-^^^^^^^^^^^^^^^^^^^^^^
+ install([[SCRIPT <file>] [CODE <code>]]
+ [ALL_COMPONENTS | COMPONENT <component>]
+ [EXCLUDE_FROM_ALL] [...])
-.. _`install(DIRECTORY)`:
-.. _DIRECTORY:
+ The ``SCRIPT`` form will invoke the given CMake script files during
+ installation. If the script file name is a relative path it will be
+ interpreted with respect to the current source directory. The ``CODE``
+ form will invoke the given CMake code during installation. Code is
+ specified as a single argument inside a double-quoted string. For
+ example, the code
-.. note::
+ .. code-block:: cmake
- To install a directory sub-tree of headers, consider using file sets
- defined by :command:`target_sources(FILE_SET)` instead. File sets not only
- preserve directory structure, they also associate headers with a target
- and install as part of the target.
+ install(CODE "MESSAGE(\"Sample install message.\")")
-.. code-block:: cmake
+ will print a message during installation.
- install(DIRECTORY dirs...
- TYPE <type> | DESTINATION <dir>
- [FILE_PERMISSIONS permissions...]
- [DIRECTORY_PERMISSIONS permissions...]
- [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT <component>] [EXCLUDE_FROM_ALL]
- [FILES_MATCHING]
- [[PATTERN <pattern> | REGEX <regex>]
- [EXCLUDE] [PERMISSIONS permissions...]] [...])
-
-The ``DIRECTORY`` form installs contents of one or more directories to a
-given destination. The directory structure is copied verbatim to the
-destination. The last component of each directory name is appended to
-the destination directory but a trailing slash may be used to avoid
-this because it leaves the last component empty. Directory names
-given as relative paths are interpreted with respect to the current
-source directory. If no input directory names are given the
-destination directory will be created but nothing will be installed
-into it. The ``FILE_PERMISSIONS`` and ``DIRECTORY_PERMISSIONS`` options
-specify permissions given to files and directories in the destination.
-If ``USE_SOURCE_PERMISSIONS`` is specified and ``FILE_PERMISSIONS`` is not,
-file permissions will be copied from the source directory structure.
-If no permissions are specified files will be given the default
-permissions specified in the ``FILES`` form of the command, and the
-directories will be given the default permissions specified in the
-``PROGRAMS`` form of the command.
+ .. versionadded:: 3.21
+ When the ``ALL_COMPONENTS`` option is given, the custom installation
+ script code will be executed for every component of a component-specific
+ installation. This option is mutually exclusive with the ``COMPONENT``
+ option.
-.. versionadded:: 3.1
- The ``MESSAGE_NEVER`` option disables file installation status output.
-
-Installation of directories may be controlled with fine granularity
-using the ``PATTERN`` or ``REGEX`` options. These "match" options specify a
-globbing pattern or regular expression to match directories or files
-encountered within input directories. They may be used to apply
-certain options (see below) to a subset of the files and directories
-encountered. The full path to each input file or directory (with
-forward slashes) is matched against the expression. A ``PATTERN`` will
-match only complete file names: the portion of the full path matching
-the pattern must occur at the end of the file name and be preceded by
-a slash. A ``REGEX`` will match any portion of the full path but it may
-use ``/`` and ``$`` to simulate the ``PATTERN`` behavior. By default all
-files and directories are installed whether or not they are matched.
-The ``FILES_MATCHING`` option may be given before the first match option
-to disable installation of files (but not directories) not matched by
-any expression. For example, the code
+ .. versionadded:: 3.14
+ ``<file>`` or ``<code>`` may use "generator expressions" with the syntax
+ ``$<...>`` (in the case of ``<file>``, this refers to their use in the file
+ name, not the file's contents). See the
+ :manual:`cmake-generator-expressions(7)` manual for available expressions.
-.. code-block:: cmake
+.. signature::
+ install(EXPORT <export-name> [...])
- install(DIRECTORY src/ DESTINATION doc/myproj
- FILES_MATCHING PATTERN "*.png")
+ Install a CMake file exporting targets for dependent projects:
-will extract and install images from a source tree.
+ .. code-block:: cmake
-Some options may follow a ``PATTERN`` or ``REGEX`` expression as described
-under :ref:`string(REGEX) <Regex Specification>` and are applied
-only to files or directories matching them. The ``EXCLUDE`` option will
-skip the matched file or directory. The ``PERMISSIONS`` option overrides
-the permissions setting for the matched file or directory. For
-example the code
+ install(EXPORT <export-name> DESTINATION <dir>
+ [NAMESPACE <namespace>] [FILE <name>.cmake]
+ [PERMISSIONS <permission>...]
+ [CONFIGURATIONS <config>...]
+ [CXX_MODULES_DIRECTORY <directory>]
+ [EXPORT_LINK_INTERFACE_LIBRARIES]
+ [COMPONENT <component>]
+ [EXCLUDE_FROM_ALL])
+ install(EXPORT_ANDROID_MK <export-name> DESTINATION <dir> [...])
+
+ The ``EXPORT`` form generates and installs a CMake file containing code to
+ import targets from the installation tree into another project.
+ Target installations are associated with the export ``<export-name>``
+ using the ``EXPORT`` option of the :command:`install(TARGETS)` signature
+ documented above. The ``NAMESPACE`` option will prepend ``<namespace>`` to
+ the target names as they are written to the import file. By default
+ the generated file will be called ``<export-name>.cmake`` but the ``FILE``
+ option may be used to specify a different name. The value given to
+ the ``FILE`` option must be a file name with the ``.cmake`` extension.
+ If a ``CONFIGURATIONS`` option is given then the file will only be installed
+ when one of the named configurations is installed. Additionally, the
+ generated import file will reference only the matching target
+ configurations. See the :variable:`CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>`
+ variable to map configurations of dependent projects to the installed
+ configurations. The ``EXPORT_LINK_INTERFACE_LIBRARIES`` keyword, if
+ present, causes the contents of the properties matching
+ ``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
+ policy :policy:`CMP0022` is ``NEW``.
+
+ .. note::
+ The installed ``<export-name>.cmake`` file may come with additional
+ per-configuration ``<export-name>-*.cmake`` files to be loaded by
+ globbing. Do not use an export name that is the same as the package
+ name in combination with installing a ``<package-name>-config.cmake``
+ file or the latter may be incorrectly matched by the glob and loaded.
+
+ When a ``COMPONENT`` option is given, the listed ``<component>`` implicitly
+ depends on all components mentioned in the export set. The exported
+ ``<name>.cmake`` file will require each of the exported components to be
+ present in order for dependent projects to build properly. For example, a
+ project may define components ``Runtime`` and ``Development``, with shared
+ libraries going into the ``Runtime`` component and static libraries and
+ headers going into the ``Development`` component. The export set would also
+ typically be part of the ``Development`` component, but it would export
+ targets from both the ``Runtime`` and ``Development`` components. Therefore,
+ the ``Runtime`` component would need to be installed if the ``Development``
+ component was installed, but not vice versa. If the ``Development`` component
+ was installed without the ``Runtime`` component, dependent projects that try
+ to link against it would have build errors. Package managers, such as APT and
+ RPM, typically handle this by listing the ``Runtime`` component as a dependency
+ of the ``Development`` component in the package metadata, ensuring that the
+ library is always installed if the headers and CMake export file are present.
+
+ .. versionadded:: 3.7
+ In addition to cmake language files, the ``EXPORT_ANDROID_MK`` mode may be
+ used to specify an export to the android ndk build system. This mode
+ accepts the same options as the normal export mode. The Android
+ NDK supports the use of prebuilt libraries, both static and shared. This
+ allows cmake to build the libraries of a project and make them available
+ to an ndk build system complete with transitive dependencies, include flags
+ and defines required to use the libraries.
+
+ ``CXX_MODULES_DIRECTORY``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ Specify a subdirectory to store C++ module information for targets in the
+ export set. This directory will be populated with files which add the
+ necessary target property information to the relevant targets. Note that
+ without this information, none of the C++ modules which are part of the
+ targets in the export set will support being imported in consuming targets.
+
+ The ``EXPORT`` form is useful to help outside projects use targets built
+ and installed by the current project. For example, the code
-.. code-block:: cmake
+ .. code-block:: cmake
- install(DIRECTORY icons scripts/ DESTINATION share/myproj
- PATTERN "CVS" EXCLUDE
- PATTERN "scripts/*"
- PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ)
-
-will install the ``icons`` directory to ``share/myproj/icons`` and the
-``scripts`` directory to ``share/myproj``. The icons will get default
-file permissions, the scripts will be given specific permissions, and any
-``CVS`` directories will be excluded.
-
-Either a ``TYPE`` or a ``DESTINATION`` must be provided, but not both.
-A ``TYPE`` argument specifies the generic file type of the files within the
-listed directories being installed. A destination will then be set
-automatically by taking the corresponding variable from
-:module:`GNUInstallDirs`, or by using a built-in default if that variable
-is not defined. See the table below for the supported file types and their
-corresponding variables and built-in defaults. Projects can provide a
-``DESTINATION`` argument instead of a file type if they wish to explicitly
-define the install destination.
-
-======================= ================================== =========================
- ``TYPE`` Argument GNUInstallDirs Variable Built-In Default
-======================= ================================== =========================
-``BIN`` ``${CMAKE_INSTALL_BINDIR}`` ``bin``
-``SBIN`` ``${CMAKE_INSTALL_SBINDIR}`` ``sbin``
-``LIB`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib``
-``INCLUDE`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
-``SYSCONF`` ``${CMAKE_INSTALL_SYSCONFDIR}`` ``etc``
-``SHAREDSTATE`` ``${CMAKE_INSTALL_SHARESTATEDIR}`` ``com``
-``LOCALSTATE`` ``${CMAKE_INSTALL_LOCALSTATEDIR}`` ``var``
-``RUNSTATE`` ``${CMAKE_INSTALL_RUNSTATEDIR}`` ``<LOCALSTATE dir>/run``
-``DATA`` ``${CMAKE_INSTALL_DATADIR}`` ``<DATAROOT dir>``
-``INFO`` ``${CMAKE_INSTALL_INFODIR}`` ``<DATAROOT dir>/info``
-``LOCALE`` ``${CMAKE_INSTALL_LOCALEDIR}`` ``<DATAROOT dir>/locale``
-``MAN`` ``${CMAKE_INSTALL_MANDIR}`` ``<DATAROOT dir>/man``
-``DOC`` ``${CMAKE_INSTALL_DOCDIR}`` ``<DATAROOT dir>/doc``
-======================= ================================== =========================
-
-Note that some of the types' built-in defaults use the ``DATAROOT`` directory as
-a prefix. The ``DATAROOT`` prefix is calculated similarly to the types, with
-``CMAKE_INSTALL_DATAROOTDIR`` as the variable and ``share`` as the built-in
-default. You cannot use ``DATAROOT`` as a ``TYPE`` parameter; please use
-``DATA`` instead.
-
-To make packages compliant with distribution filesystem layout policies, if
-projects must specify a ``DESTINATION``, it is recommended that they use a
-path that begins with the appropriate :module:`GNUInstallDirs` variable.
-This allows package maintainers to control the install destination by setting
-the appropriate cache variables.
-
-.. versionadded:: 3.4
- An install destination given as a ``DESTINATION`` argument may
- use "generator expressions" with the syntax ``$<...>``. See the
- :manual:`cmake-generator-expressions(7)` manual for available expressions.
+ install(TARGETS myexe EXPORT myproj DESTINATION bin)
+ install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)
+ install(EXPORT_ANDROID_MK myproj DESTINATION share/ndk-modules)
+
+ will install the executable ``myexe`` to ``<prefix>/bin`` and code to import
+ it in the file ``<prefix>/lib/myproj/myproj.cmake`` and
+ ``<prefix>/share/ndk-modules/Android.mk``. An outside project
+ may load this file with the include command and reference the ``myexe``
+ executable from the installation tree using the imported target name
+ ``mp_myexe`` as if the target were built in its own tree.
+
+ .. note::
+ This command supersedes the :command:`install_targets` command and
+ the :prop_tgt:`PRE_INSTALL_SCRIPT` and :prop_tgt:`POST_INSTALL_SCRIPT`
+ target properties. It also replaces the ``FILES`` forms of the
+ :command:`install_files` and :command:`install_programs` commands.
+ The processing order of these install rules relative to
+ those generated by :command:`install_targets`,
+ :command:`install_files`, and :command:`install_programs` commands
+ is not defined.
+
+.. signature::
+ install(RUNTIME_DEPENDENCY_SET <set-name> [...])
-.. versionadded:: 3.5
- The list of ``dirs...`` given to ``DIRECTORY`` may use
- "generator expressions" too.
+ .. versionadded:: 3.21
-Custom Installation Logic
-^^^^^^^^^^^^^^^^^^^^^^^^^
+ Installs a runtime dependency set:
-.. _`install(CODE)`:
-.. _`install(SCRIPT)`:
-.. _CODE:
-.. _SCRIPT:
+ .. code-block:: cmake
-.. code-block:: cmake
+ install(RUNTIME_DEPENDENCY_SET <set-name>
+ [[LIBRARY|RUNTIME|FRAMEWORK]
+ [DESTINATION <dir>]
+ [PERMISSIONS <permission>...]
+ [CONFIGURATIONS <config>...]
+ [COMPONENT <component>]
+ [NAMELINK_COMPONENT <component>]
+ [OPTIONAL] [EXCLUDE_FROM_ALL]
+ ] [...]
+ [PRE_INCLUDE_REGEXES <regex>...]
+ [PRE_EXCLUDE_REGEXES <regex>...]
+ [POST_INCLUDE_REGEXES <regex>...]
+ [POST_EXCLUDE_REGEXES <regex>...]
+ [POST_INCLUDE_FILES <file>...]
+ [POST_EXCLUDE_FILES <file>...]
+ [DIRECTORIES <dir>...]
+ )
+
+ Installs a runtime dependency set previously created by one or more
+ :command:`install(TARGETS)` or :command:`install(IMPORTED_RUNTIME_ARTIFACTS)`
+ commands. The dependencies of targets belonging to a runtime dependency set
+ are installed in the ``RUNTIME`` destination and component on DLL platforms,
+ and in the ``LIBRARY`` destination and component on non-DLL platforms.
+ macOS frameworks are installed in the ``FRAMEWORK`` destination and component.
+ Targets built within the build tree will never be installed as runtime
+ dependencies, nor will their own dependencies, unless the targets themselves
+ are installed with :command:`install(TARGETS)`.
+
+ The generated install script calls :command:`file(GET_RUNTIME_DEPENDENCIES)`
+ on the build-tree files to calculate the runtime dependencies. The build-tree
+ executable files are passed as the ``EXECUTABLES`` argument, the build-tree
+ shared libraries as the ``LIBRARIES`` argument, and the build-tree modules as
+ the ``MODULES`` argument. On macOS, if one of the executables is a
+ :prop_tgt:`MACOSX_BUNDLE`, that executable is passed as the
+ ``BUNDLE_EXECUTABLE`` argument. At most one such bundle executable may be in
+ the runtime dependency set on macOS. The :prop_tgt:`MACOSX_BUNDLE` property
+ has no effect on other platforms. Note that
+ :command:`file(GET_RUNTIME_DEPENDENCIES)` only supports collecting the runtime
+ dependencies for Windows, Linux and macOS platforms, so
+ ``install(RUNTIME_DEPENDENCY_SET)`` has the same limitation.
+
+ The following sub-arguments are forwarded through as the corresponding
+ arguments to :command:`file(GET_RUNTIME_DEPENDENCIES)` (for those that provide
+ a non-empty list of directories, regular expressions or files). They all
+ support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+ * ``DIRECTORIES <dir>...``
+ * ``PRE_INCLUDE_REGEXES <regex>...``
+ * ``PRE_EXCLUDE_REGEXES <regex>...``
+ * ``POST_INCLUDE_REGEXES <regex>...``
+ * ``POST_EXCLUDE_REGEXES <regex>...``
+ * ``POST_INCLUDE_FILES <file>...``
+ * ``POST_EXCLUDE_FILES <file>...``
+
+Examples
+^^^^^^^^
- install([[SCRIPT <file>] [CODE <code>]]
- [ALL_COMPONENTS | COMPONENT <component>]
- [EXCLUDE_FROM_ALL] [...])
+Example: Install Targets with Per-Artifact Components
+"""""""""""""""""""""""""""""""""""""""""""""""""""""
-The ``SCRIPT`` form will invoke the given CMake script files during
-installation. If the script file name is a relative path it will be
-interpreted with respect to the current source directory. The ``CODE``
-form will invoke the given CMake code during installation. Code is
-specified as a single argument inside a double-quoted string. For
-example, the code
+Consider a project that defines targets with different artifact kinds:
.. code-block:: cmake
- install(CODE "MESSAGE(\"Sample install message.\")")
+ add_executable(myExe myExe.c)
+ add_library(myStaticLib STATIC myStaticLib.c)
+ target_sources(myStaticLib PUBLIC FILE_SET HEADERS FILES myStaticLib.h)
+ add_library(mySharedLib SHARED mySharedLib.c)
+ target_sources(mySharedLib PUBLIC FILE_SET HEADERS FILES mySharedLib.h)
+ set_property(TARGET mySharedLib PROPERTY SOVERSION 1)
-will print a message during installation.
+We may call :command:`install(TARGETS)` with `\<artifact-kind\>`_ arguments
+to specify different options for each kind of artifact:
-.. versionadded:: 3.21
- When the ``ALL_COMPONENTS`` option is given, the custom installation
- script code will be executed for every component of a component-specific
- installation. This option is mutually exclusive with the ``COMPONENT``
- option.
+.. code-block:: cmake
-.. versionadded:: 3.14
- ``<file>`` or ``<code>`` may use "generator expressions" with the syntax
- ``$<...>`` (in the case of ``<file>``, this refers to their use in the file
- name, not the file's contents). See the
- :manual:`cmake-generator-expressions(7)` manual for available expressions.
+ install(TARGETS
+ myExe
+ mySharedLib
+ myStaticLib
+ RUNTIME # Following options apply to runtime artifacts.
+ COMPONENT Runtime
+ LIBRARY # Following options apply to library artifacts.
+ COMPONENT Runtime
+ NAMELINK_COMPONENT Development
+ ARCHIVE # Following options apply to archive artifacts.
+ COMPONENT Development
+ DESTINATION lib/static
+ FILE_SET HEADERS # Following options apply to file set HEADERS.
+ COMPONENT Development
+ )
-Installing Exports
-^^^^^^^^^^^^^^^^^^
+This will:
-.. _`install(EXPORT)`:
-.. _EXPORT:
+* Install ``myExe`` to ``<prefix>/bin``, the default RUNTIME artifact
+ destination, as part of the ``Runtime`` component.
-.. code-block:: cmake
+* On non-DLL platforms:
- install(EXPORT <export-name> DESTINATION <dir>
- [NAMESPACE <namespace>] [FILE <name>.cmake]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]
- [CXX_MODULES_DIRECTORY <directory>]
- [EXPORT_LINK_INTERFACE_LIBRARIES]
- [COMPONENT <component>]
- [EXCLUDE_FROM_ALL])
- install(EXPORT_ANDROID_MK <export-name> DESTINATION <dir> [...])
-
-The ``EXPORT`` form generates and installs a CMake file containing code to
-import targets from the installation tree into another project.
-Target installations are associated with the export ``<export-name>``
-using the ``EXPORT`` option of the `install(TARGETS)`_ signature
-documented above. The ``NAMESPACE`` option will prepend ``<namespace>`` to
-the target names as they are written to the import file. By default
-the generated file will be called ``<export-name>.cmake`` but the ``FILE``
-option may be used to specify a different name. The value given to
-the ``FILE`` option must be a file name with the ``.cmake`` extension.
-If a ``CONFIGURATIONS`` option is given then the file will only be installed
-when one of the named configurations is installed. Additionally, the
-generated import file will reference only the matching target
-configurations. See the :variable:`CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>`
-variable to map configurations of dependent projects to the installed
-configurations. The ``EXPORT_LINK_INTERFACE_LIBRARIES`` keyword, if
-present, causes the contents of the properties matching
-``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
-policy :policy:`CMP0022` is ``NEW``.
+ * Install ``libmySharedLib.so.1`` to ``<prefix>/lib``, the default
+ LIBRARY artifact destination, as part of the ``Runtime`` component.
-.. note::
- The installed ``<export-name>.cmake`` file may come with additional
- per-configuration ``<export-name>-*.cmake`` files to be loaded by
- globbing. Do not use an export name that is the same as the package
- name in combination with installing a ``<package-name>-config.cmake``
- file or the latter may be incorrectly matched by the glob and loaded.
-
-When a ``COMPONENT`` option is given, the listed ``<component>`` implicitly
-depends on all components mentioned in the export set. The exported
-``<name>.cmake`` file will require each of the exported components to be
-present in order for dependent projects to build properly. For example, a
-project may define components ``Runtime`` and ``Development``, with shared
-libraries going into the ``Runtime`` component and static libraries and
-headers going into the ``Development`` component. The export set would also
-typically be part of the ``Development`` component, but it would export
-targets from both the ``Runtime`` and ``Development`` components. Therefore,
-the ``Runtime`` component would need to be installed if the ``Development``
-component was installed, but not vice versa. If the ``Development`` component
-was installed without the ``Runtime`` component, dependent projects that try
-to link against it would have build errors. Package managers, such as APT and
-RPM, typically handle this by listing the ``Runtime`` component as a dependency
-of the ``Development`` component in the package metadata, ensuring that the
-library is always installed if the headers and CMake export file are present.
-
-.. versionadded:: 3.7
- In addition to cmake language files, the ``EXPORT_ANDROID_MK`` mode may be
- used to specify an export to the android ndk build system. This mode
- accepts the same options as the normal export mode. The Android
- NDK supports the use of prebuilt libraries, both static and shared. This
- allows cmake to build the libraries of a project and make them available
- to an ndk build system complete with transitive dependencies, include flags
- and defines required to use the libraries.
-
-``CXX_MODULES_DIRECTORY``
-
- .. note ::
-
- Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
-
- Specify a subdirectory to store C++ module information for targets in the
- export set. This directory will be populated with files which add the
- necessary target property information to the relevant targets. Note that
- without this information, none of the C++ modules which are part of the
- targets in the export set will support being imported in consuming targets.
-
-The ``EXPORT`` form is useful to help outside projects use targets built
-and installed by the current project. For example, the code
+ * Install the ``libmySharedLib.so`` "namelink" (symbolic link) to
+ ``<prefix>/lib``, the default LIBRARY artifact destination, as part
+ of the ``Development`` component.
-.. code-block:: cmake
+* On DLL platforms:
- install(TARGETS myexe EXPORT myproj DESTINATION bin)
- install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)
- install(EXPORT_ANDROID_MK myproj DESTINATION share/ndk-modules)
+ * Install ``mySharedLib.dll`` to ``<prefix>/bin``, the default RUNTIME
+ artifact destination, as part of the ``Runtime`` component.
-will install the executable ``myexe`` to ``<prefix>/bin`` and code to import
-it in the file ``<prefix>/lib/myproj/myproj.cmake`` and
-``<prefix>/share/ndk-modules/Android.mk``. An outside project
-may load this file with the include command and reference the ``myexe``
-executable from the installation tree using the imported target name
-``mp_myexe`` as if the target were built in its own tree.
+ * Install ``mySharedLib.lib`` to ``<prefix>/lib/static``, the specified
+ ARCHIVE artifact destination, as part of the ``Development`` component.
-.. note::
- This command supersedes the :command:`install_targets` command and
- the :prop_tgt:`PRE_INSTALL_SCRIPT` and :prop_tgt:`POST_INSTALL_SCRIPT`
- target properties. It also replaces the ``FILES`` forms of the
- :command:`install_files` and :command:`install_programs` commands.
- The processing order of these install rules relative to
- those generated by :command:`install_targets`,
- :command:`install_files`, and :command:`install_programs` commands
- is not defined.
+* Install ``myStaticLib`` to ``<prefix>/lib/static``, the specified
+ ARCHIVE artifact destination, as part of the ``Development`` component.
-Installing Runtime Dependencies
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* Install ``mySharedLib.h`` and ``myStaticLib.h`` to ``<prefix>/include``,
+ the default destination for a file set of type HEADERS, as part of the
+ ``Development`` component.
-.. _`install(RUNTIME_DEPENDENCY_SET)`:
-.. _RUNTIME_DEPENDENCY_SET:
+Example: Install Targets to Per-Config Destinations
+"""""""""""""""""""""""""""""""""""""""""""""""""""
-.. versionadded:: 3.21
+Each :command:`install(TARGETS)` call installs a given target
+:ref:`output artifact <Output Artifacts>` to at most one ``DESTINATION``,
+but the install rule itself may be filtered by the ``CONFIGURATIONS`` option.
+In order to install to a different destination for each configuration, one
+call per configuration is needed. For example, the code:
.. code-block:: cmake
- install(RUNTIME_DEPENDENCY_SET <set-name>
- [[LIBRARY|RUNTIME|FRAMEWORK]
- [DESTINATION <dir>]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT <component>]
- [NAMELINK_COMPONENT <component>]
- [OPTIONAL] [EXCLUDE_FROM_ALL]
- ] [...]
- [PRE_INCLUDE_REGEXES regexes...]
- [PRE_EXCLUDE_REGEXES regexes...]
- [POST_INCLUDE_REGEXES regexes...]
- [POST_EXCLUDE_REGEXES regexes...]
- [POST_INCLUDE_FILES files...]
- [POST_EXCLUDE_FILES files...]
- [DIRECTORIES directories...]
+ install(TARGETS myExe
+ CONFIGURATIONS Debug
+ RUNTIME
+ DESTINATION Debug/bin
+ )
+ install(TARGETS myExe
+ CONFIGURATIONS Release
+ RUNTIME
+ DESTINATION Release/bin
)
-Installs a runtime dependency set previously created by one or more
-`install(TARGETS)`_ or `install(IMPORTED_RUNTIME_ARTIFACTS)`_ commands. The
-dependencies of targets belonging to a runtime dependency set are installed in
-the ``RUNTIME`` destination and component on DLL platforms, and in the
-``LIBRARY`` destination and component on non-DLL platforms. macOS frameworks
-are installed in the ``FRAMEWORK`` destination and component.
-Targets built within the build tree will never be installed as runtime
-dependencies, nor will their own dependencies, unless the targets themselves
-are installed with `install(TARGETS)`_.
-
-The generated install script calls :command:`file(GET_RUNTIME_DEPENDENCIES)`
-on the build-tree files to calculate the runtime dependencies. The build-tree
-executable files are passed as the ``EXECUTABLES`` argument, the build-tree
-shared libraries as the ``LIBRARIES`` argument, and the build-tree modules as
-the ``MODULES`` argument. On macOS, if one of the executables is a
-:prop_tgt:`MACOSX_BUNDLE`, that executable is passed as the
-``BUNDLE_EXECUTABLE`` argument. At most one such bundle executable may be in
-the runtime dependency set on macOS. The :prop_tgt:`MACOSX_BUNDLE` property
-has no effect on other platforms. Note that
-:command:`file(GET_RUNTIME_DEPENDENCIES)` only supports collecting the runtime
-dependencies for Windows, Linux and macOS platforms, so
-``install(RUNTIME_DEPENDENCY_SET)`` has the same limitation.
-
-The following sub-arguments are forwarded through as the corresponding
-arguments to :command:`file(GET_RUNTIME_DEPENDENCIES)` (for those that provide
-a non-empty list of directories, regular expressions or files). They all
-support :manual:`generator expressions <cmake-generator-expressions(7)>`.
-
-* ``DIRECTORIES <directories>``
-* ``PRE_INCLUDE_REGEXES <regexes>``
-* ``PRE_EXCLUDE_REGEXES <regexes>``
-* ``POST_INCLUDE_REGEXES <regexes>``
-* ``POST_EXCLUDE_REGEXES <regexes>``
-* ``POST_INCLUDE_FILES <files>``
-* ``POST_EXCLUDE_FILES <files>``
+will install ``myExe`` to ``<prefix>/Debug/bin`` in the Debug configuration,
+and to ``<prefix>/Release/bin`` in the Release configuration.
Generated Installation Script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/command/set.rst b/Help/command/set.rst
index aeb88b3..fa635c6 100644
--- a/Help/command/set.rst
+++ b/Help/command/set.rst
@@ -27,11 +27,12 @@ Set Normal Variable
If the ``PARENT_SCOPE`` option is given the variable will be set in
the scope above the current scope. Each new directory or :command:`function`
command creates a new scope. A scope can also be created with the
- :command:`block` command. This command will set the value of a variable into
- the parent directory, calling function or encompassing scope (whichever is
- applicable to the case at hand). The previous state of the variable's value
- stays the same in the current scope (e.g., if it was undefined before, it is
- still undefined and if it had a value, it is still that value).
+ :command:`block` command. ``set(PARENT_SCOPE)`` will set the value
+ of a variable into the parent directory, calling function, or
+ encompassing scope (whichever is applicable to the case at hand).
+ The previous state of the variable's value stays the same in the
+ current scope (e.g., if it was undefined before, it is still undefined
+ and if it had a value, it is still that value).
The :command:`block(PROPAGATE)` and :command:`return(PROPAGATE)` commands
can be used as an alternate method to the :command:`set(PARENT_SCOPE)`
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index fc43974..f14b63d 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -12,7 +12,8 @@ Set a named property in a given scope.
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...] |
INSTALL [<file1> ...] |
- TEST [<test1> ...] |
+ TEST [<test1> ...]
+ [DIRECTORY <dir>] |
CACHE [<entry1> ...] >
[APPEND] [APPEND_STRING]
PROPERTY <name> [<value1> ...])
@@ -91,6 +92,17 @@ It must be one of the following:
:manual:`generator expressions <cmake-generator-expressions(7)>`
for tests created by the :command:`add_test(NAME)` signature.
+ .. versionadded:: 3.28
+
+ Visibility can be set in other directory scopes using the following sub-option:
+
+ ``DIRECTORY <dir>``
+ The test property will be set in the ``<dir>`` directory's scope. CMake must
+ already know about this directory, either by having added it through a call
+ to :command:`add_subdirectory` or it being the top level source directory.
+ Relative paths are treated as relative to the current source directory.
+ ``<dir>`` may reference a binary directory.
+
``CACHE``
Scope must name zero or more existing cache entries.
diff --git a/Help/command/set_tests_properties.rst b/Help/command/set_tests_properties.rst
index 125e460..da750e3 100644
--- a/Help/command/set_tests_properties.rst
+++ b/Help/command/set_tests_properties.rst
@@ -14,10 +14,20 @@ Test property values may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`
for tests created by the :command:`add_test(NAME)` signature.
+.. versionadded:: 3.28
+ Visibility can be set in other directory scopes using the following option:
+
+ ``DIRECTORY <dir>``
+ The test properties will be set in the ``<dir>`` directory's scope.
+ CMake must already know about this directory, either by having added it
+ through a call to :command:`add_subdirectory` or it being the top level
+ source directory. Relative paths are treated as relative to the current
+ source directory. ``<dir>`` may reference a binary directory.
+
See Also
^^^^^^^^
* :command:`add_test`
* :command:`define_property`
* the more general :command:`set_property` command
-* :ref:`Target Properties` for the list of properties known to CMake
+* :ref:`Test Properties` for the list of properties known to CMake
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index 1d27660..cc6bc0f 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -66,6 +66,12 @@ Each ``<item>`` may be:
:ref:`usage requirement <Target Usage Requirements>`. This has the same
effect as passing the framework directory as an include directory.
+ .. versionadded:: 3.28
+
+ The library file may point to a ``.xcframework`` folder on macOS. If it
+ does, the target will get the selected library's ``Headers`` directory as
+ a usage requirement.
+
.. versionadded:: 3.8
On :ref:`Visual Studio Generators` for VS 2010 and above, library files
ending in ``.targets`` will be treated as MSBuild targets files and
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst
index c795713..db55bc2 100644
--- a/Help/command/target_precompile_headers.rst
+++ b/Help/command/target_precompile_headers.rst
@@ -33,7 +33,7 @@ property of ``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
Repeated calls for the same ``<target>`` will append items in the order called.
Projects should generally avoid using ``PUBLIC`` or ``INTERFACE`` for targets
-that will be :ref:`exported <install(EXPORT)>`, or they should at least use
+that will be :command:`exported <install(EXPORT)>`, or they should at least use
the :genex:`$<BUILD_INTERFACE:...>` generator expression to prevent precompile
headers from appearing in an installed exported target. Consumers of a target
should typically be in control of what precompile headers they use, not have
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 8abb6e0..bc2b0af 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -65,6 +65,7 @@ Try Compiling Source Files
.. code-block:: cmake
try_compile(<compileResultVar>
+ [SOURCES_TYPE <type>]
<SOURCES <srcfile...> |
SOURCE_FROM_CONTENT <name> <content> |
SOURCE_FROM_VAR <name> <var> |
@@ -143,7 +144,12 @@ single output directory, such that you can only debug one such ``try_compile``
call at a time. Use of the newer signature is recommended to simplify
debugging of multiple ``try_compile`` operations.
-The options are:
+.. _`try_compile Options`:
+
+Options
+^^^^^^^
+
+The options for the above signatures are:
``CMAKE_FLAGS <flags>...``
Specify flags of the form :option:`-DVAR:TYPE=VALUE <cmake -D>` to be passed
@@ -244,6 +250,27 @@ The options are:
``SOURCE_FROM_VAR`` may be specified multiple times.
+``SOURCES_TYPE <type>``
+ .. versionadded:: 3.28
+
+ Sources may be classified using the ``SOURCES_TYPE`` argument. Once
+ specified, all subsequent sources specified will be treated as that type
+ until another ``SOURCES_TYPE`` is given. Available types are:
+
+ ``NORMAL``
+ Sources are not added to any ``FILE_SET`` in the generated project.
+
+ ``CXX_MODULE``
+ Sources are added to a ``FILE_SET`` of type ``CXX_MODULES`` in the
+ generated project.
+
+ .. note ::
+
+ Experimental. Sources of type ``CXX_MODULE`` are gated by
+ ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ The default type of sources is ``NORMAL``.
+
``<LANG>_STANDARD <std>``
.. versionadded:: 3.8
diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst
index 3a4e203..1b5087d 100644
--- a/Help/command/try_run.rst
+++ b/Help/command/try_run.rst
@@ -13,6 +13,7 @@ Try Compiling and Running Source Files
.. code-block:: cmake
try_run(<runResultVar> <compileResultVar>
+ [SOURCES_TYPE <type>]
<SOURCES <srcfile...> |
SOURCE_FROM_CONTENT <name> <content> |
SOURCE_FROM_VAR <name> <var> |
@@ -77,6 +78,11 @@ The signature above is recommended for clarity.
[ARGS <args>...]
)
+.. _`try_run Options`:
+
+Options
+^^^^^^^
+
The options specific to ``try_run`` are:
``COMPILE_OUTPUT_VARIABLE <var>``
diff --git a/Help/dev/documentation.rst b/Help/dev/documentation.rst
index c6fb7a6..65c0ccf 100644
--- a/Help/dev/documentation.rst
+++ b/Help/dev/documentation.rst
@@ -431,6 +431,7 @@ The section header underline character hierarchy is
* ``-``: Subsection or `CMake Domain`_ object document title
* ``^``: Subsubsection or `CMake Domain`_ object document section
* ``"``: Paragraph or `CMake Domain`_ object document subsection
+* ``~``: `CMake Domain`_ object document subsubsection
Style: Whitespace
^^^^^^^^^^^^^^^^^
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index eac86ab..046d214 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -18,7 +18,7 @@ C++20 Module APIs
=================
Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
-Value: ``aa1f7df0-828a-4fcd-9afc-2dc80491aca7``
+Value: ``ac01f462-0f5f-432a-86aa-acef252918a6``
In order to support C++20 modules, there are a number of behaviors that have
CMake APIs to provide the required features to build and export them from a
@@ -99,6 +99,10 @@ dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder. The
``CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT`` file may be set to ``msvc``
for scandep rules which use ``msvc``-style dependency reporting.
+In order to support ``IMPORTED`` targets with associated C++20 module sources,
+the ``CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG`` variable must be provided
+to have the compiler only output a BMI instead of a BMI and an object file.
+
The module dependencies should be written in the format described
by the `P1689r5`_ paper.
@@ -113,6 +117,8 @@ For compilers that generate module maps, tell CMake as follows:
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
"${compiler_flags_for_module_map} -fmodule-mapper=<MODULE_MAP_FILE>")
+ set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG
+ "-fmodule-only")
Currently, the only supported formats are, ``clang``, ``gcc``, and ``msvc``.
The ``gcc`` format is described in the GCC documentation, but the relevant
diff --git a/Help/envvar/CMAKE_CROSSCOMPILING_EMULATOR.rst b/Help/envvar/CMAKE_CROSSCOMPILING_EMULATOR.rst
new file mode 100644
index 0000000..3e397d8
--- /dev/null
+++ b/Help/envvar/CMAKE_CROSSCOMPILING_EMULATOR.rst
@@ -0,0 +1,11 @@
+CMAKE_CROSSCOMPILING_EMULATOR
+-----------------------------
+
+.. versionadded:: 3.28
+
+.. include:: ENV_VAR.txt
+
+The default value for :variable:`CMAKE_CROSSCOMPILING_EMULATOR` when there
+is no explicit configuration given on the first run while creating a new
+build tree. On later runs in an existing build tree the value persists in
+the cache as :variable:`CMAKE_CROSSCOMPILING_EMULATOR`.
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
index 888164f..a36046a 100644
--- a/Help/generator/Visual Studio 10 2010.rst
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -3,6 +3,6 @@ Visual Studio 10 2010
Removed. This once generated Visual Studio 10 2010 project files, but
the generator has been removed since CMake 3.25. It is still possible
-to build with VS 10 2010 tools using the :generator:`Visual Studio 12 2013`
+to build with VS 10 2010 tools using the :generator:`Visual Studio 14 2015`
(or above) generator with :variable:`CMAKE_GENERATOR_TOOLSET` set to
``v100``, or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst
index 4e7195c..5ded24c 100644
--- a/Help/generator/Visual Studio 11 2012.rst
+++ b/Help/generator/Visual Studio 11 2012.rst
@@ -1,57 +1,8 @@
Visual Studio 11 2012
---------------------
-Deprecated. Generates Visual Studio 11 (VS 2012) project files.
-
-.. note::
- This generator is deprecated and will be removed in a future version
- of CMake. It will still be possible to build with VS 11 2012 tools
- using the :generator:`Visual Studio 12 2013` (or above) generator
- with :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v110``, or by
- using the :generator:`NMake Makefiles` generator.
-
-For compatibility with CMake versions prior to 3.0, one may specify this
-generator using the name "Visual Studio 11" without the year component.
-
-Project Types
-^^^^^^^^^^^^^
-
-Only Visual C++ and C# projects may be generated (and Fortran with
-Intel compiler integration). Other types of projects (JavaScript,
-Database, Website, etc.) are not supported.
-
-Platform Selection
-^^^^^^^^^^^^^^^^^^
-
-The default target platform name (architecture) is ``Win32``.
-
-.. versionadded:: 3.1
- The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
- via the :option:`cmake -A` option, to specify a target platform
- name (architecture). For example:
-
- * ``cmake -G "Visual Studio 11 2012" -A Win32``
- * ``cmake -G "Visual Studio 11 2012" -A x64``
- * ``cmake -G "Visual Studio 11 2012" -A ARM``
- * ``cmake -G "Visual Studio 11 2012" -A <WinCE-SDK>``
- (Specify a target platform matching a Windows CE SDK name.)
-
-For compatibility with CMake versions prior to 3.1, one may specify
-a target platform name optionally at the end of the generator name.
-This is supported only for:
-
-``Visual Studio 11 2012 Win64``
- Specify target platform ``x64``.
-
-``Visual Studio 11 2012 ARM``
- Specify target platform ``ARM``.
-
-``Visual Studio 11 2012 <WinCE-SDK>``
- Specify target platform matching a Windows CE SDK name.
-
-Toolset Selection
-^^^^^^^^^^^^^^^^^
-
-The ``v110`` toolset that comes with Visual Studio 11 2012 is selected by
-default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :option:`cmake -T` option, to specify another toolset.
+Removed. This once generated Visual Studio 11 2012 project files, but
+the generator has been removed since CMake 3.28. It is still possible
+to build with VS 11 2012 tools using the :generator:`Visual Studio 14 2015`
+(or above) generator with :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v110``,
+or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst
index 3dbcfe6..522522c 100644
--- a/Help/generator/Visual Studio 12 2013.rst
+++ b/Help/generator/Visual Studio 12 2013.rst
@@ -1,7 +1,14 @@
Visual Studio 12 2013
---------------------
-Generates Visual Studio 12 (VS 2013) project files.
+Deprecated. Generates Visual Studio 12 (VS 2013) project files.
+
+.. note::
+ This generator is deprecated and will be removed in a future version
+ of CMake. It will still be possible to build with VS 12 2013 tools
+ using the :generator:`Visual Studio 14 2015` (or above) generator
+ with :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v120``, or by
+ using the :generator:`NMake Makefiles` generator.
For compatibility with CMake versions prior to 3.0, one may specify this
generator using the name "Visual Studio 12" without the year component.
diff --git a/Help/generator/Visual Studio 9 2008.rst b/Help/generator/Visual Studio 9 2008.rst
index 816969d..1439270 100644
--- a/Help/generator/Visual Studio 9 2008.rst
+++ b/Help/generator/Visual Studio 9 2008.rst
@@ -6,7 +6,7 @@ Deprecated. Generates Visual Studio 9 2008 project files.
.. note::
This generator is deprecated and will be removed in a future version
of CMake. It will still be possible to build with VS 9 2008 tools
- using the :generator:`Visual Studio 12 2013` generator (or above,
+ using the :generator:`Visual Studio 14 2015` generator (or above,
and with VS 10 2010 also installed) with
:variable:`CMAKE_GENERATOR_TOOLSET` set to ``v90``,
or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst
index 37b0668..2325e9e 100644
--- a/Help/guide/tutorial/A Basic Starting Point.rst
+++ b/Help/guide/tutorial/A Basic Starting Point.rst
@@ -102,7 +102,14 @@ Then call that build system to actually compile/link the project:
cmake --build .
-Finally, try to use the newly built ``Tutorial`` with these commands:
+For multi-config generators (e.g. Visual Studio), first navigate to the
+appropriate subdirectory, for example:
+
+.. code-block:: console
+
+ cd Debug
+
+Finally, try to use the newly built ``Tutorial``:
.. code-block:: console
@@ -110,6 +117,11 @@ Finally, try to use the newly built ``Tutorial`` with these commands:
Tutorial 10
Tutorial
+
+**Note:** Depending on the shell, the correct syntax may be ``Tutorial``,
+``./Tutorial`` or ``.\Tutorial``. For simplicity, the exercises will use
+``Tutorial`` throughout.
+
Solution
--------
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index 3dab97f..910eacb 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -149,8 +149,8 @@ interface library.
Lastly, we only want these warning flags to be used during builds. Consumers
of our installed project should not inherit our warning flags. To specify
-this, we wrap our flags in a generator expression using the ``BUILD_INTERFACE``
-condition. The resulting full code looks like the following:
+this, we wrap our flags from TODO 3 in a generator expression using the
+``BUILD_INTERFACE`` condition. The resulting full code looks like the following:
.. raw:: html
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 2273063..e7aff9c 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -127,7 +127,7 @@ Remove this line:
</details>
-And the lines:
+And remove ``EXTRA_INCLUDES`` from ``target_include_directories``:
.. raw:: html
@@ -143,23 +143,6 @@ And the lines:
</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
@@ -262,10 +245,9 @@ then use :command:`target_compile_features` to add the compiler feature
</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:
+executable ``Tutorial``, our ``SqrtLibrary`` library and our ``MathFunctions``
+library to our new ``tutorial_compiler_flags`` library. Respectively, the code
+will look like this:
.. raw:: html
@@ -292,7 +274,7 @@ this:
:caption: TODO 6: MathFunctions/CMakeLists.txt
:name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
:language: cmake
- :start-after: # link our compiler flags interface library
+ :start-after: # link SqrtLibrary to tutorial_compiler_flags
:end-before: target_link_libraries(MathFunctions
.. raw:: html
@@ -309,8 +291,7 @@ and this:
:caption: TODO 7: MathFunctions/CMakeLists.txt
:name: MathFunctions-SqrtLibrary-target_link_libraries-step4
:language: cmake
- :start-after: target_link_libraries(SqrtLibrary
- :end-before: endif()
+ :start-after: # link MathFunctions to tutorial_compiler_flags
.. raw:: html
diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst
index 694dfaf..18ced97 100644
--- a/Help/guide/tutorial/Adding a Library.rst
+++ b/Help/guide/tutorial/Adding a Library.rst
@@ -96,7 +96,7 @@ a library target called ``MathFunctions`` with :command:`add_library`. The
source files for the library are passed as an argument to
:command:`add_library`. This looks like the following line:
-.. raw:: html/
+.. raw:: html
<details><summary>TODO 1: Click to show/hide answer</summary>
@@ -184,7 +184,7 @@ Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:
</details>
-Lastly, replace ``sqrt`` with our library function ``mathfunctions::mysqrt``.
+Lastly, replace ``sqrt`` with the wrapper function ``mathfunctions::sqrt``.
.. raw:: html
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index b221506..1654564 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -33,10 +33,13 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
index 504e42f..a2f5e2a 100644
--- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
+++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
@@ -44,7 +44,18 @@ SqrtLibrary to be ``True`` when building shared libraries.
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-POSITION_INDEPENDENT_CODE
:language: cmake
- :lines: 37-42
+ :start-at: # state that SqrtLibrary need PIC when the default is shared libraries
+ :end-at: )
+
+Define ``EXPORTING_MYMATH`` stating we are using ``declspec(dllexport)`` when
+building on Windows.
+
+.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
+ :caption: MathFunctions/CMakeLists.txt
+ :name: MathFunctions/CMakeLists.txt-dll-export
+ :language: cmake
+ :start-at: # define the symbol stating we are using the declspec(dllexport) when
+ :end-at: target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
**Exercise**: We modified ``MathFunctions.h`` to use dll export defines.
Using CMake documentation can you find a helper module to simplify this?
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index 36b3fe1..210563a 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -26,10 +26,13 @@ if(USE_MYMATH)
${CMAKE_CURRENT_BINARY_DIR}
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index 813bf90..eacc538 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -31,10 +31,13 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
diff --git a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
index 38694dd..8aa5904 100644
--- a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
@@ -33,10 +33,13 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
index 0ffb9e1..ffb2f35 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -16,7 +16,7 @@ if (USE_MYMATH)
# TODO 7: Link SqrtLibrary to tutorial_compiler_flags
- target_link_libraries(MathFunctions PUBLIC SqrtLibrary)
+ target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
# TODO 6: Link MathFunctions to tutorial_compiler_flags
diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
index 48561eb..6931898 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -17,10 +17,11 @@ if (USE_MYMATH)
mysqrt.cxx
)
- # link our compiler flags interface library
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
- target_link_libraries(MathFunctions PUBLIC SqrtLibrary)
+
+ target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
-# link our compiler flags interface library
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
index 0c688f2..61b3899 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -16,12 +16,13 @@ if (USE_MYMATH)
mysqrt.cxx
)
- # link our compiler flags interface library
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
-# link our compiler flags interface library
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# TODO 1: Create a variable called installable_libs that is a list of all
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index b1b925e..8499a51 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -16,11 +16,13 @@ if (USE_MYMATH)
mysqrt.cxx
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
-# link our compiler flags interface library
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index 897ec0e..a0b3037 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -16,6 +16,7 @@ if (USE_MYMATH)
mysqrt.cxx
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
# TODO 1: Include CheckCXXSourceCompiles
@@ -41,7 +42,7 @@ if (USE_MYMATH)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
-# link our compiler flags interface library
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
index 872a24a..b14d180 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
@@ -10,6 +10,7 @@ if (USE_MYMATH)
mysqrt.cxx
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
# does this system provide the log and exp functions?
@@ -45,7 +46,7 @@ target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
-# link our compiler flags interface library
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
index 54cecf8..5addc6d 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
@@ -25,10 +25,13 @@ if (USE_MYMATH)
${CMAKE_CURRENT_BINARY_DIR}
)
+ # link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
+# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index 197e56e..356e73d 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -43,6 +43,7 @@ Environment Variables that Control the Build
/envvar/CMAKE_COLOR_DIAGNOSTICS
/envvar/CMAKE_CONFIGURATION_TYPES
/envvar/CMAKE_CONFIG_TYPE
+ /envvar/CMAKE_CROSSCOMPILING_EMULATOR
/envvar/CMAKE_EXPORT_COMPILE_COMMANDS
/envvar/CMAKE_GENERATOR
/envvar/CMAKE_GENERATOR_INSTANCE
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 7c48806..a018aff 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,15 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.28
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0153: The exec_program command should not be called. </policy/CMP0153>
+ CMP0152: file(REAL_PATH) resolves symlinks before collapsing ../ components. </policy/CMP0152>
+
Policies Introduced by CMake 3.27
=================================
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 4df0547..fa1d297 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -240,6 +240,11 @@ Properties on Targets
/prop_tgt/IMPORTED
/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME
/prop_tgt/IMPORTED_CONFIGURATIONS
+ /prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS
+ /prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES
+ /prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS
+ /prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES
+ /prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES
/prop_tgt/IMPORTED_GLOBAL
/prop_tgt/IMPORTED_IMPLIB
/prop_tgt/IMPORTED_IMPLIB_CONFIG
@@ -503,6 +508,7 @@ Properties on Tests
/prop_test/FIXTURES_CLEANUP
/prop_test/FIXTURES_REQUIRED
/prop_test/FIXTURES_SETUP
+ /prop_test/GENERATED_RESOURCE_SPEC_FILE
/prop_test/LABELS
/prop_test/MEASUREMENT
/prop_test/PASS_REGULAR_EXPRESSION
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst
index d0d6ea0..e5a39f5 100644
--- a/Help/manual/cmake-qt.7.rst
+++ b/Help/manual/cmake-qt.7.rst
@@ -14,7 +14,7 @@ CMake can find and use Qt 4 and Qt 5 libraries. The Qt 4 libraries are found
by the :module:`FindQt4` find-module shipped with CMake, whereas the
Qt 5 libraries are found using "Config-file Packages" shipped with Qt 5. See
:manual:`cmake-packages(7)` for more information about CMake packages, and
-see `the Qt cmake manual <https://contribute.qt-project.org/doc/qt-5/cmake-manual.html>`_
+see `the Qt cmake manual <https://doc.qt.io/qt-5/cmake-manual.html>`_
for your Qt version.
Qt 4 and Qt 5 may be used together in the same
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index a831fa6..e32bd29 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -573,12 +573,12 @@ See also target properties:
* :prop_tgt:`ANDROID_SKIP_ANT_STEP`
* :prop_tgt:`ANDROID_STL_TYPE`
-.. _`Cross Compiling for iOS, tvOS, or watchOS`:
+.. _`Cross Compiling for iOS, tvOS, visionOS, or watchOS`:
-Cross Compiling for iOS, tvOS, or watchOS
------------------------------------------
+Cross Compiling for iOS, tvOS, visionOS, or watchOS
+---------------------------------------------------
-For cross-compiling to iOS, tvOS, or watchOS, the :generator:`Xcode`
+For cross-compiling to iOS, tvOS, visionOS, or watchOS, the :generator:`Xcode`
generator is recommended. The :generator:`Unix Makefiles` or
:generator:`Ninja` generators can also be used, but they require the
project to handle more areas like target CPU selection and code signing.
@@ -591,13 +591,14 @@ a different SDK (e.g. a simulator) can be selected by setting the
necessary (see :ref:`Switching Between Device and Simulator` below).
A list of available SDKs can be obtained by running ``xcodebuild -showsdks``.
-======= ================= ==================== ================
-OS CMAKE_SYSTEM_NAME Device SDK (default) Simulator SDK
-======= ================= ==================== ================
-iOS iOS iphoneos iphonesimulator
-tvOS tvOS appletvos appletvsimulator
-watchOS watchOS watchos watchsimulator
-======= ================= ==================== ================
+======== ================= ==================== ================
+OS CMAKE_SYSTEM_NAME Device SDK (default) Simulator SDK
+======== ================= ==================== ================
+iOS iOS iphoneos iphonesimulator
+tvOS tvOS appletvos appletvsimulator
+visionOS visionOS xros xrsimulator
+watchOS watchOS watchos watchsimulator
+======== ================= ==================== ================
For example, to create a CMake configuration for iOS, the following
command is sufficient:
@@ -608,7 +609,7 @@ command is sufficient:
Variable :variable:`CMAKE_OSX_ARCHITECTURES` can be used to set architectures
for both device and simulator. Variable :variable:`CMAKE_OSX_DEPLOYMENT_TARGET`
-can be used to set an iOS/tvOS/watchOS deployment target.
+can be used to set an iOS/tvOS/visionOS/watchOS deployment target.
Next configuration will install fat 5 architectures iOS library
and add the ``-miphoneos-version-min=9.3``/``-mios-simulator-version-min=9.3``
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 994ae47..effe4b1 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -1817,6 +1817,25 @@ The following variables are passed to the test process:
uppercase in the ``CTEST_RESOURCE_GROUP_<num>_<resource-type>`` environment
variable.
+.. _`ctest-resource-dynamically-generated-spec-file`:
+
+Dynamically-Generated Resource Specification File
+-------------------------------------------------
+
+.. versionadded:: 3.28
+
+A project may optionally specify a single test which will be used to
+dynamically generate the resource specification file that CTest will use for
+scheduling tests that use resources. The test that generates the file must
+have the :prop_test:`GENERATED_RESOURCE_SPEC_FILE` property set, and must have
+exactly one fixture in its :prop_test:`FIXTURES_SETUP` property. This fixture
+is considered by CTest to have special meaning: it's the fixture that generates
+the resource spec file. The fixture may have any name. If such a fixture
+exists, all tests that have :prop_test:`RESOURCE_GROUPS` set must have the
+fixture in their :prop_test:`FIXTURES_REQUIRED`, and a resource spec file may
+not be specified with the ``--resource-spec-file`` argument or the
+:variable:`CTEST_RESOURCE_SPEC_FILE` variable.
+
See Also
========
diff --git a/Help/policy/CMP0152.rst b/Help/policy/CMP0152.rst
new file mode 100644
index 0000000..d7e8692
--- /dev/null
+++ b/Help/policy/CMP0152.rst
@@ -0,0 +1,20 @@
+CMP0152
+-------
+
+.. versionadded:: 3.28
+
+:command:`file(REAL_PATH)` resolves symlinks before collapsing ../ components.
+
+In CMake 3.27 and below, :command:`file(REAL_PATH)` collapsed any ``../``
+components in a path before resolving symlinks. This produced incorrect
+results when the ``../`` collapsed away a symlink.
+
+The ``OLD`` behavior for this policy is to collapse ``../`` components before
+resolving symlinks.
+The ``NEW`` behavior for this policy is to resolve all symlinks before
+collapsing ``../`` components.
+
+This policy was introduced in CMake version 3.28. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0153.rst b/Help/policy/CMP0153.rst
new file mode 100644
index 0000000..4c9f3dc
--- /dev/null
+++ b/Help/policy/CMP0153.rst
@@ -0,0 +1,12 @@
+CMP0153
+-------
+
+The :command:`exec_program` command should not be called.
+
+This command has long been superseded by the :command:`execute_process`
+command and has been deprecated since CMake 3.0.
+
+.. |disallowed_version| replace:: 3.28
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
index 392b704..6794a26 100644
--- a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
+++ b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
@@ -16,8 +16,8 @@ generator emits the ``EFFECTIVE_PLATFORM_NAME`` variable:
- If set to ``ON`` it will always be emitted
- If set to ``OFF`` it will never be emitted
- If unset (the default) it will only be emitted when the project was
- configured for an embedded Xcode SDK like iOS, tvOS, watchOS or any
- of the simulators.
+ configured for an embedded Xcode SDK like iOS, tvOS, visionOS, watchOS
+ or any of the simulators.
.. note::
diff --git a/Help/prop_test/GENERATED_RESOURCE_SPEC_FILE.rst b/Help/prop_test/GENERATED_RESOURCE_SPEC_FILE.rst
new file mode 100644
index 0000000..89596ac
--- /dev/null
+++ b/Help/prop_test/GENERATED_RESOURCE_SPEC_FILE.rst
@@ -0,0 +1,7 @@
+GENERATED_RESOURCE_SPEC_FILE
+----------------------------
+
+.. versionadded:: 3.28
+
+Path to the :ref:`dynamically-generated resource spec file
+<ctest-resource-dynamically-generated-spec-file>` generated by this test.
diff --git a/Help/prop_tgt/DLL_NAME_WITH_SOVERSION.rst b/Help/prop_tgt/DLL_NAME_WITH_SOVERSION.rst
index 59ef00f..c86b218 100644
--- a/Help/prop_tgt/DLL_NAME_WITH_SOVERSION.rst
+++ b/Help/prop_tgt/DLL_NAME_WITH_SOVERSION.rst
@@ -3,8 +3,8 @@ DLL_NAME_WITH_SOVERSION
.. versionadded:: 3.27
-This property control whether the :prop_tgt:`SOVERSION` target
-property are added to the filename of generated DLL filenames
+This property controls whether the :prop_tgt:`SOVERSION` target
+property is added to the filename of generated DLL filenames
for the Windows platform, which is selected when the
:variable:`WIN32` variable is set.
diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst
new file mode 100644
index 0000000..88687b2
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst
@@ -0,0 +1,14 @@
+IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS
+----------------------------------------
+
+.. versionadded:: 3.28
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Preprocessor definitions for compiling an ``IMPORTED`` target's C++ module
+sources.
+
+CMake will automatically drop some definitions that are not supported
+by the native build tool.
diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst
new file mode 100644
index 0000000..c3eb7fb
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst
@@ -0,0 +1,13 @@
+IMPORTED_CXX_MODULES_COMPILE_FEATURES
+-------------------------------------
+
+.. versionadded:: 3.28
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Compiler features enabled for this ``IMPORTED`` target's C++ modules.
+
+The value of this property is used by the generators to set the include
+paths for the compiler.
diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst
new file mode 100644
index 0000000..5c62c77
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst
@@ -0,0 +1,13 @@
+IMPORTED_CXX_MODULES_COMPILE_OPTIONS
+------------------------------------
+
+.. versionadded:: 3.28
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+List of options to pass to the compiler for this ``IMPORTED`` target's C++
+modules.
+
+.. include:: ../command/OPTIONS_SHELL.txt
diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst
new file mode 100644
index 0000000..08a993d
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,14 @@
+IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES
+----------------------------------------
+
+.. versionadded:: 3.28
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+List of preprocessor include file search directories when compiling C++
+modules for ``IMPORTED`` targets.
+
+The value of this property is used by the generators to set the include
+paths for the compiler.
diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst
new file mode 100644
index 0000000..5111dc5
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst
@@ -0,0 +1,11 @@
+IMPORTED_CXX_MODULES_LINK_LIBRARIES
+-----------------------------------
+
+.. versionadded:: 3.28
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+List of direct dependencies to use for usage requirements for C++ modules in
+the target's C++ modules.
diff --git a/Help/prop_tgt/IMPORTED_IMPLIB.rst b/Help/prop_tgt/IMPORTED_IMPLIB.rst
index e67acba..27601d2 100644
--- a/Help/prop_tgt/IMPORTED_IMPLIB.rst
+++ b/Help/prop_tgt/IMPORTED_IMPLIB.rst
@@ -11,6 +11,12 @@ This property may be set:
* On macOS, to an import file (e.g. ``.tbd``) created for shared libraries (see
the :prop_tgt:`ENABLE_EXPORTS` target property). For frameworks this is the
location of the ``.tbd`` file symlink just inside the framework folder.
+* .. versionadded:: 3.28
+ On non-DLL platforms, to the location of a shared library.
+ When set without also specifying an :prop_tgt:`IMPORTED_LOCATION`,
+ the library is considered to be a stub, and its location will not
+ be added as a runtime search path to dependents that link it.
+
The ``IMPORTED_IMPLIB`` target property may be overridden for a
given configuration ``<CONFIG>`` by the configuration-specific
diff --git a/Help/prop_tgt/IMPORTED_LOCATION.rst b/Help/prop_tgt/IMPORTED_LOCATION.rst
index a7207d8..915085b 100644
--- a/Help/prop_tgt/IMPORTED_LOCATION.rst
+++ b/Help/prop_tgt/IMPORTED_LOCATION.rst
@@ -15,6 +15,17 @@ is the location of the ``.dll`` part of the library. For ``UNKNOWN``
libraries this is the location of the file to be linked. Ignored for
non-imported targets.
+.. versionadded:: 3.28
+
+ For frameworks on macOS, this may be the location of the framework folder
+ itself.
+
+.. versionadded:: 3.28
+
+ This may be the location of a ``.xcframework`` folder on macOS. If it is,
+ any target that links against it will get the selected library's ``Headers``
+ directory as a usage requirement.
+
The ``IMPORTED_LOCATION`` target property may be overridden for a
given configuration ``<CONFIG>`` by the configuration-specific
:prop_tgt:`IMPORTED_LOCATION_<CONFIG>` target property. Furthermore,
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS.rst b/Help/prop_tgt/IMPORTED_OBJECTS.rst
index d71c219..9aacea7 100644
--- a/Help/prop_tgt/IMPORTED_OBJECTS.rst
+++ b/Help/prop_tgt/IMPORTED_OBJECTS.rst
@@ -31,7 +31,7 @@ once per architecture for each source file. Unlike the other generators,
it does not generate universal object file binaries.
A further complication with the :generator:`Xcode` generator is that when
-targeting device platforms (iOS, tvOS or watchOS), the :generator:`Xcode`
+targeting device platforms (iOS, tvOS, visionOS or watchOS), the :generator:`Xcode`
generator has the ability to use either the device or simulator SDK without
needing CMake to be re-run. The SDK can be selected at build time.
But since some architectures can be supported by both the device and the
diff --git a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
index 92d60dc..c296691 100644
--- a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
+++ b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
@@ -2,18 +2,27 @@ IOS_INSTALL_COMBINED
--------------------
.. versionadded:: 3.5
+.. deprecated:: 3.28
+
+ :prop_tgt:`IOS_INSTALL_COMBINED` was designed to make universal binaries
+ containing iOS/arm* device code paired with iOS Simulator/x86_64 code
+ (or similar for other Apple embedded platforms). Universal binaries can only
+ differentiate code based on CPU type, so this only made sense before the
+ days of arm64 macOS machines (i.e. iOS Simulator/arm64). Apple now
+ recommends xcframeworks, which contain multiple binaries for different
+ platforms, for this use case.
Build a combined (device and simulator) target when installing.
-When this property is set to set to false (which is the default) then it will
+When this property is set to false, which is the default, then it will
either be built with the device SDK or the simulator SDK depending on the SDK
set. But if this property is set to true then the target will at install time
-also be built for the corresponding SDK and combined into one library.
+also be built for the other SDK and combined into one library.
.. note::
- If a selected architecture is available for both: device SDK and simulator
+ If a selected architecture is available for both device SDK and simulator
SDK it will be built for the SDK selected by :variable:`CMAKE_OSX_SYSROOT`
- and removed from the corresponding SDK.
+ and removed from the other SDK.
This feature requires at least Xcode version 6.
diff --git a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
index afc6b31..d1d80a8 100644
--- a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
+++ b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
@@ -4,5 +4,6 @@ Swift_LANGUAGE_VERSION
.. versionadded:: 3.16
This property sets the language version for the Swift sources in the target. If
-one is not specified, it will default to ``<CMAKE_Swift_LANGUAGE_VERSION>`` if
-specified, otherwise it is the latest version supported by the compiler.
+one is not specified, it will default to
+:variable:`CMAKE_Swift_LANGUAGE_VERSION` if specified, otherwise it is the
+latest version supported by the compiler.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
index 5bf47a3..8c136f2 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
@@ -11,5 +11,5 @@ 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;
+This property only works for Visual Studio 12 2013 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 4b9dff7..2656826 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
@@ -11,5 +11,5 @@ 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;
+This property only works for Visual Studio 12 2013 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 8373dbb..d78d594 100644
--- a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
@@ -11,5 +11,5 @@ 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;
+This property only works for Visual Studio 12 2013 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 3942047..1026dfa 100644
--- a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
@@ -11,5 +11,5 @@ 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;
+This property only works for Visual Studio 12 2013 and above;
it is ignored on other generators.
diff --git a/Help/prop_tgt/VS_DOTNET_STARTUP_OBJECT.rst b/Help/prop_tgt/VS_DOTNET_STARTUP_OBJECT.rst
index 8a85ba4..eeb7dda 100644
--- a/Help/prop_tgt/VS_DOTNET_STARTUP_OBJECT.rst
+++ b/Help/prop_tgt/VS_DOTNET_STARTUP_OBJECT.rst
@@ -12,7 +12,7 @@ If the property is unset, Visual Studio uses the first matching
than one ``Main()`` method is available in the current project, the property
becomes mandatory for building the project.
-This property only works for Visual Studio 11 2012 and above;
+This property only works for Visual Studio 12 2013 and above;
it is ignored on other generators.
.. code-block:: cmake
diff --git a/Help/prop_tgt/VS_KEYWORD.rst b/Help/prop_tgt/VS_KEYWORD.rst
index 221b986..f04d109 100644
--- a/Help/prop_tgt/VS_KEYWORD.rst
+++ b/Help/prop_tgt/VS_KEYWORD.rst
@@ -7,4 +7,4 @@ Can be set to change the visual studio keyword, for example Qt
integration works better if this is set to Qt4VSv1.0.
Use the :prop_tgt:`VS_GLOBAL_KEYWORD` target property to set the
-keyword for Visual Studio 11 (2012) and newer.
+keyword for Visual Studio 12 (2013) and newer.
diff --git a/Help/prop_tgt/XCODE_EMBED_type.rst b/Help/prop_tgt/XCODE_EMBED_type.rst
index da744c2..76b0e3d 100644
--- a/Help/prop_tgt/XCODE_EMBED_type.rst
+++ b/Help/prop_tgt/XCODE_EMBED_type.rst
@@ -37,6 +37,12 @@ The supported values for ``<type>`` are:
The specified items will be added to the ``Embed PlugIns`` build phase.
They must be CMake target names.
+``RESOURCES``
+ .. versionadded:: 3.28
+
+ The specified items will be added to the ``Embed Resources`` build phase.
+ They must be CMake target names.
+
See also :prop_tgt:`XCODE_EMBED_<type>_PATH`,
:prop_tgt:`XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY` and
:prop_tgt:`XCODE_EMBED_<type>_CODE_SIGN_ON_COPY`.
diff --git a/Help/prop_tgt/XCODE_EMBED_type_PATH.rst b/Help/prop_tgt/XCODE_EMBED_type_PATH.rst
index 5a5c65f..ef04d14 100644
--- a/Help/prop_tgt/XCODE_EMBED_type_PATH.rst
+++ b/Help/prop_tgt/XCODE_EMBED_type_PATH.rst
@@ -22,3 +22,6 @@ The supported values for ``<type>`` are:
``PLUGINS``
.. versionadded:: 3.23
+
+``RESOURCES``
+ .. versionadded:: 3.28
diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst
index 8a9738c..5fedf7d 100644
--- a/Help/release/3.14.rst
+++ b/Help/release/3.14.rst
@@ -63,7 +63,8 @@ File-Based API
Platforms
---------
-* CMake now supports :ref:`Cross Compiling for iOS, tvOS, or watchOS`
+* CMake now supports
+ :ref:`Cross Compiling for iOS, tvOS, or watchOS <Cross Compiling for iOS, tvOS, visionOS, or watchOS>`
using simple toolchain files.
Command-Line
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+ Developers should add similar notes for each topic branch
+ making a noteworthy change. Each document should be named
+ and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/CMAKE_CROSSCOMPILING_EMULATOR-env-variable.rst b/Help/release/dev/CMAKE_CROSSCOMPILING_EMULATOR-env-variable.rst
new file mode 100644
index 0000000..269e739
--- /dev/null
+++ b/Help/release/dev/CMAKE_CROSSCOMPILING_EMULATOR-env-variable.rst
@@ -0,0 +1,6 @@
+CMAKE_CROSSCOMPILING_EMULATOR-env-variable
+------------------------------------------
+
+* The :envvar:`CMAKE_CROSSCOMPILING_EMULATOR` environment variable
+ was added to initialize the :variable:`CMAKE_CROSSCOMPILING_EMULATOR`
+ cache variable.
diff --git a/Help/release/dev/ExternalProject-build-jobserver.rst b/Help/release/dev/ExternalProject-build-jobserver.rst
new file mode 100644
index 0000000..357da42
--- /dev/null
+++ b/Help/release/dev/ExternalProject-build-jobserver.rst
@@ -0,0 +1,10 @@
+ExternalProject-build-jobserver
+-------------------------------
+
+* The :module:`ExternalProject` module now includes the
+ ``BUILD_JOB_SERVER_AWARE`` option for the
+ :command:`ExternalProject_Add` command. This option enables
+ the integration of the GNU Make job server when using an
+ explicit ``BUILD_COMMAND`` with certain :ref:`Makefile Generators`.
+ Additionally, the :command:`ExternalProject_Add_Step` command
+ has been updated to support the new ``JOB_SERVER_AWARE`` option.
diff --git a/Help/release/dev/FindCURL-static.rst b/Help/release/dev/FindCURL-static.rst
new file mode 100644
index 0000000..3c369d2
--- /dev/null
+++ b/Help/release/dev/FindCURL-static.rst
@@ -0,0 +1,5 @@
+FindCURL-static
+---------------
+
+* The :module:`FindCURL` module gained a ``CURL_USE_STATIC_LIBS`` hint
+ to select static libraries.
diff --git a/Help/release/dev/FindEXPAT-static.rst b/Help/release/dev/FindEXPAT-static.rst
new file mode 100644
index 0000000..8808ebd
--- /dev/null
+++ b/Help/release/dev/FindEXPAT-static.rst
@@ -0,0 +1,5 @@
+FindEXPAT-static
+----------------
+
+* The :module:`FindEXPAT` module gained a ``EXPAT_USE_STATIC_LIBS`` hint
+ to select static libraries.
diff --git a/Help/release/dev/apple-visionos.rst b/Help/release/dev/apple-visionos.rst
new file mode 100644
index 0000000..db76248
--- /dev/null
+++ b/Help/release/dev/apple-visionos.rst
@@ -0,0 +1,7 @@
+apple-visionos
+--------------
+
+* CMake learned about Apple visionOS and its `xros` and `xrsimulator` SDKs.
+ Compiling for Apple visionOS can be requested by setting
+ :variable:`CMAKE_SYSTEM_NAME` to ``visionOS``. For more
+ information see :manual:`cmake-toolchains(7)`.
diff --git a/Help/release/dev/command-job-server-aware.rst b/Help/release/dev/command-job-server-aware.rst
new file mode 100644
index 0000000..224c739
--- /dev/null
+++ b/Help/release/dev/command-job-server-aware.rst
@@ -0,0 +1,5 @@
+command-job-server-aware
+------------------------
+
+* The :command:`add_custom_command` and :command:`add_custom_target`
+ commands gained a ``JOB_SERVER_AWARE`` option.
diff --git a/Help/release/dev/deprecate-install-combined.rst b/Help/release/dev/deprecate-install-combined.rst
new file mode 100644
index 0000000..12a0a43
--- /dev/null
+++ b/Help/release/dev/deprecate-install-combined.rst
@@ -0,0 +1,6 @@
+deprecate-install-combined
+--------------------------
+
+* The :prop_tgt:`IOS_INSTALL_COMBINED` target property and corresponding
+ :variable:`CMAKE_IOS_INSTALL_COMBINED` variable have been deprecated.
+ Their functionality does not make sense on Apple Silicon hosts.
diff --git a/Help/release/dev/dynamically-generated-resource-spec-file.rst b/Help/release/dev/dynamically-generated-resource-spec-file.rst
new file mode 100644
index 0000000..c4b3899
--- /dev/null
+++ b/Help/release/dev/dynamically-generated-resource-spec-file.rst
@@ -0,0 +1,6 @@
+dynamically-generated-resource-spec-file
+----------------------------------------
+
+* CTest may now take a :ref:`dynamically-generated resource spec file
+ <ctest-resource-dynamically-generated-spec-file>`, which can be specified by the
+ :prop_test:`GENERATED_RESOURCE_SPEC_FILE` test property.
diff --git a/Help/release/dev/exec_program-policy.rst b/Help/release/dev/exec_program-policy.rst
new file mode 100644
index 0000000..8ddae5b
--- /dev/null
+++ b/Help/release/dev/exec_program-policy.rst
@@ -0,0 +1,6 @@
+exec_program-policy
+-------------------
+
+* The :command:`exec_program` command, which has been deprecated since CMake
+ 3.0, has been removed by policy :policy:`CMP0153`. Use the
+ :command:`execute_process` command instead.
diff --git a/Help/release/dev/host-msystem-prefix.rst b/Help/release/dev/host-msystem-prefix.rst
new file mode 100644
index 0000000..4377144
--- /dev/null
+++ b/Help/release/dev/host-msystem-prefix.rst
@@ -0,0 +1,6 @@
+host-msystem-prefix
+-------------------
+
+* The :command:`cmake_host_system_information` command gained a
+ ``MSYSTEM_PREFIX`` query for the installation prefix of a MSYS
+ or MinGW development environment on Windows hosts.
diff --git a/Help/release/dev/imported-implib-only.rst b/Help/release/dev/imported-implib-only.rst
new file mode 100644
index 0000000..aa817b7
--- /dev/null
+++ b/Help/release/dev/imported-implib-only.rst
@@ -0,0 +1,7 @@
+imported-implib-only
+--------------------
+
+* On imported shared libraries, the :prop_tgt:`IMPORTED_IMPLIB` target
+ property may now be used without :prop_tgt:`IMPORTED_LOCATION`.
+ This can be used to represent a stub library whose location should not
+ be added as a runtime search path to dependents that link it.
diff --git a/Help/release/dev/imported-target-framework-path.rst b/Help/release/dev/imported-target-framework-path.rst
new file mode 100644
index 0000000..68c3431
--- /dev/null
+++ b/Help/release/dev/imported-target-framework-path.rst
@@ -0,0 +1,5 @@
+imported-target-framework-path
+------------------------------
+
+* The :prop_tgt:`IMPORTED_LOCATION` property of a macOS framework may now be
+ the location of the framework folder itself.
diff --git a/Help/release/dev/rel-linux-x86_64.rst b/Help/release/dev/rel-linux-x86_64.rst
new file mode 100644
index 0000000..8302a1c
--- /dev/null
+++ b/Help/release/dev/rel-linux-x86_64.rst
@@ -0,0 +1,5 @@
+rel-linux-x86_64
+----------------
+
+* The precompiled Linux ``x86_64`` binaries provided on
+ `cmake.org <https://cmake.org/download/>`_ now require GLIBC 2.17 or higher.
diff --git a/Help/release/dev/remove-vs11-generator.rst b/Help/release/dev/remove-vs11-generator.rst
new file mode 100644
index 0000000..971d679
--- /dev/null
+++ b/Help/release/dev/remove-vs11-generator.rst
@@ -0,0 +1,4 @@
+remove-vs11-generator
+---------------------
+
+* The :generator:`Visual Studio 11 2012` generator has been removed.
diff --git a/Help/release/dev/test-properties-directory.rst b/Help/release/dev/test-properties-directory.rst
new file mode 100644
index 0000000..9df7051
--- /dev/null
+++ b/Help/release/dev/test-properties-directory.rst
@@ -0,0 +1,15 @@
+test-properties-directory
+-------------------------
+
+* The ``TEST`` mode of the :command:`set_property` command gained a
+ ``DIRECTORY`` sub-option, which allows you to set properties on tests in
+ other directories.
+* The :command:`set_tests_properties` command gained a ``DIRECTORY``
+ sub-option, which allows you to set properties on tests in other
+ directories.
+* The ``TEST`` mode of the :command:`get_property` command gained a
+ ``DIRECTORY`` sub-option, which allows you to get properties on tests in
+ other directories.
+* The :command:`get_test_property` command gained a ``DIRECTORY``
+ sub-option, which allows you to get properties on tests in other
+ directories.
diff --git a/Help/release/dev/vs12-deprecate.rst b/Help/release/dev/vs12-deprecate.rst
new file mode 100644
index 0000000..23d7e2a
--- /dev/null
+++ b/Help/release/dev/vs12-deprecate.rst
@@ -0,0 +1,5 @@
+vs12-deprecate
+--------------
+
+* The :generator:`Visual Studio 12 2013` generator is now deprecated
+ and will be removed in a future version of CMake.
diff --git a/Help/release/dev/xcframework-find-library.rst b/Help/release/dev/xcframework-find-library.rst
new file mode 100644
index 0000000..527270e
--- /dev/null
+++ b/Help/release/dev/xcframework-find-library.rst
@@ -0,0 +1,5 @@
+xcframework-find-library
+------------------------
+
+* The :command:`find_library` command can now find ``.xcframework`` folders on
+ Apple platforms.
diff --git a/Help/release/dev/xcframework-target-link-libraries.rst b/Help/release/dev/xcframework-target-link-libraries.rst
new file mode 100644
index 0000000..7edded5
--- /dev/null
+++ b/Help/release/dev/xcframework-target-link-libraries.rst
@@ -0,0 +1,7 @@
+xcframework-target-link-libraries
+---------------------------------
+
+* Targets may now link against an ``.xcframework`` folder in
+ :command:`target_link_libraries`.
+* The :prop_tgt:`IMPORTED_LOCATION` property of a target may now be an
+ ``.xcframework`` folder.
diff --git a/Help/release/dev/xcode-embed-resources.rst b/Help/release/dev/xcode-embed-resources.rst
new file mode 100644
index 0000000..2678cfd
--- /dev/null
+++ b/Help/release/dev/xcode-embed-resources.rst
@@ -0,0 +1,6 @@
+xcode-embed-resources
+---------------------
+
+* The :prop_tgt:`XCODE_EMBED_RESOURCES <XCODE_EMBED_<type>>` target property
+ was added to tell the :generator:`Xcode` generator what targets to put in
+ the ``Embed Resources`` build phase.
diff --git a/Help/release/dev/xcode-no-legacy-buildsystem.rst b/Help/release/dev/xcode-no-legacy-buildsystem.rst
new file mode 100644
index 0000000..f3d1f67
--- /dev/null
+++ b/Help/release/dev/xcode-no-legacy-buildsystem.rst
@@ -0,0 +1,8 @@
+xcode-no-legacy-buildsystem
+---------------------------
+
+* The :generator:`Xcode` generator will now issue a fatal error if
+ the Legacy Build System has been selected for Xcode 14 and
+ newer. Those Xcode versions dropped support for the Legacy Build
+ System and expect the project being set-up for their current
+ Build System.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index fc1f744..3851b7e 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@ CMake Release Notes
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Help/variable/APPLE.rst b/Help/variable/APPLE.rst
index 810d5fc..e799397 100644
--- a/Help/variable/APPLE.rst
+++ b/Help/variable/APPLE.rst
@@ -2,4 +2,4 @@ APPLE
-----
Set to ``True`` when the target system is an Apple platform
-(macOS, iOS, tvOS or watchOS).
+(macOS, iOS, tvOS, visionOS or watchOS).
diff --git a/Help/variable/CMAKE_CFG_INTDIR.rst b/Help/variable/CMAKE_CFG_INTDIR.rst
index 3a57659..3045d91 100644
--- a/Help/variable/CMAKE_CFG_INTDIR.rst
+++ b/Help/variable/CMAKE_CFG_INTDIR.rst
@@ -19,7 +19,7 @@ Example values:
::
$(ConfigurationName) = Visual Studio 9
- $(Configuration) = Visual Studio 11 and above
+ $(Configuration) = Visual Studio 12 and above
$(CONFIGURATION) = Xcode
. = Make-based tools
. = Ninja
diff --git a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
index e21b35d..1c3a26c 100644
--- a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
+++ b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
@@ -12,6 +12,10 @@ for the target system.
Lists>`, then the first value is the command and remaining values are its
arguments.
+.. versionadded:: 3.28
+ This variable can be initialized via an
+ :envvar:`CMAKE_CROSSCOMPILING_EMULATOR` environment variable.
+
The command will be used to run :command:`try_run` generated executables,
which avoids manual population of the ``TryRunResults.cmake`` file.
diff --git a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
index 9817b1a..6e2d756 100644
--- a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
+++ b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
@@ -26,4 +26,11 @@ is read-only and changes to it are undefined behavior.
.. note::
+ Projects should not try to set ``CMAKE_CUDA_HOST_COMPILER`` to match
+ :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` themselves.
+ It is the end-user's responsibility, not the project's, to ensure that
+ the C++ and CUDA compilers target the same ABI.
+
+.. note::
+
Ignored when using :ref:`Visual Studio Generators`.
diff --git a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
index cd7fd8d..0024ba9 100644
--- a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
+++ b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
@@ -2,6 +2,9 @@ CMAKE_IOS_INSTALL_COMBINED
--------------------------
.. versionadded:: 3.5
+.. deprecated:: 3.28
+
+ This is deprecated because :prop_tgt:`IOS_INSTALL_COMBINED` is deprecated.
Default value for :prop_tgt:`IOS_INSTALL_COMBINED` of targets.
diff --git a/Help/variable/CMAKE_MACOSX_BUNDLE.rst b/Help/variable/CMAKE_MACOSX_BUNDLE.rst
index 43ddff5..483c5b3 100644
--- a/Help/variable/CMAKE_MACOSX_BUNDLE.rst
+++ b/Help/variable/CMAKE_MACOSX_BUNDLE.rst
@@ -7,4 +7,4 @@ This variable is used to initialize the :prop_tgt:`MACOSX_BUNDLE` property on
all the targets. See that target property for additional information.
This variable is set to ``ON`` by default if :variable:`CMAKE_SYSTEM_NAME`
-equals to :ref:`iOS, tvOS or watchOS <Cross Compiling for iOS, tvOS, or watchOS>`.
+equals to :ref:`iOS, tvOS, visionOS or watchOS <Cross Compiling for iOS, tvOS, visionOS, or watchOS>`.
diff --git a/Help/variable/CMAKE_OSX_VARIABLE.txt b/Help/variable/CMAKE_OSX_VARIABLE.txt
index 5670980..962fcd3 100644
--- a/Help/variable/CMAKE_OSX_VARIABLE.txt
+++ b/Help/variable/CMAKE_OSX_VARIABLE.txt
@@ -7,6 +7,6 @@ remove it while initializing a cache entry of the same name) unless
policy :policy:`CMP0126` is set to ``NEW``.
Despite the ``OSX`` part in the variable name(s) they apply also to
-other SDKs than macOS like iOS, tvOS, or watchOS.
+other SDKs than macOS like iOS, tvOS, visionOS, or watchOS.
This variable is ignored on platforms other than Apple.
diff --git a/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst b/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
index 2bb97c4..155931f 100644
--- a/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
+++ b/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
@@ -10,5 +10,5 @@ This variable is not defined by other generators even if ``devenv.com``
is installed on the computer.
The :variable:`CMAKE_VS_MSBUILD_COMMAND` is also provided for
-:generator:`Visual Studio 11 2012` and above.
+:generator:`Visual Studio 12 2013` and above.
See also the :variable:`CMAKE_MAKE_PROGRAM` variable.
diff --git a/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst b/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst
index 8a521a3..96924d5 100644
--- a/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst
+++ b/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst
@@ -1,7 +1,7 @@
CMAKE_VS_MSBUILD_COMMAND
------------------------
-The generators for :generator:`Visual Studio 11 2012` and above set this
+The generators for :generator:`Visual Studio 12 2013` and above set this
variable to the ``MSBuild.exe`` command installed with the corresponding
Visual Studio version.
diff --git a/Help/variable/CMAKE_XCODE_BUILD_SYSTEM.rst b/Help/variable/CMAKE_XCODE_BUILD_SYSTEM.rst
index d153061..f3c213c 100644
--- a/Help/variable/CMAKE_XCODE_BUILD_SYSTEM.rst
+++ b/Help/variable/CMAKE_XCODE_BUILD_SYSTEM.rst
@@ -12,7 +12,8 @@ mature enough for use by CMake. The possible values are:
``1``
The original Xcode build system.
- This is the default when using Xcode 11.x or below.
+ This is the default when using Xcode 11.x or below and supported
+ up to Xcode 13.x.
``12``
The Xcode "new build system" introduced by Xcode 10.
diff --git a/Help/variable/ENV.rst b/Help/variable/ENV.rst
index 6791853..71df3dd 100644
--- a/Help/variable/ENV.rst
+++ b/Help/variable/ENV.rst
@@ -8,6 +8,17 @@ Use the syntax ``$ENV{VAR}`` to read environment variable ``VAR``.
To test whether an environment variable is defined, use the signature
``if(DEFINED ENV{<name>})`` of the :command:`if` command.
+.. note::
+
+ Environment variable names containing special characters like parentheses
+ may need to be escaped. (Policy :policy:`CMP0053` must also be enabled.)
+ For example, to get the value of the Windows environment variable
+ ``ProgramFiles(x86)``, use:
+
+ .. code-block:: cmake
+
+ set(ProgramFiles_x86 "$ENV{ProgramFiles\(x86\)}")
+
For general information on environment variables, see the
:ref:`Environment Variables <CMake Language Environment Variables>`
section in the :manual:`cmake-language(7)` manual.
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index 75d33e8..5fec06f 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -102,6 +102,10 @@ function(compiler_id_detection outvar lang)
set(ordered_compilers NVIDIA Clang)
endif()
+ if("x${lang}" STREQUAL "xHIP")
+ set(ordered_compilers Clang)
+ endif()
+
if(CID_ID_DEFINE)
foreach(Id ${ordered_compilers})
string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n")
diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake
index fe98469..652eb63 100644
--- a/Modules/CMakeDetermineCSharpCompiler.cmake
+++ b/Modules/CMakeDetermineCSharpCompiler.cmake
@@ -3,7 +3,7 @@
if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
message(FATAL_ERROR
- "C# is currently only supported for Microsoft Visual Studio 11 2012 and later.")
+ "C# is currently only supported for Microsoft Visual Studio 12 2013 and later.")
endif()
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 2cf9853..9d3b60f 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -605,6 +605,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
if(CMAKE_OSX_SYSROOT)
set(id_sdkroot "SDKROOT = \"${CMAKE_OSX_SYSROOT}\";")
if(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ii][Pp][Hh][Oo][Nn][Ee]" OR
+ CMAKE_OSX_SYSROOT MATCHES "(^|/)[Xx][Rr]" OR
CMAKE_OSX_SYSROOT MATCHES "(^|/)[Aa][Pp][Pp][Ll][Ee][Tt][Vv]")
set(id_product_type "com.apple.product-type.bundle.unit-test")
elseif(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ww][Aa][Tt][Cc][Hh]")
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index 386be73..fff4e9d 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -47,6 +47,28 @@ if(CMAKE_HOST_UNIX)
set(CMAKE_HOST_SYSTEM_VERSION "${_CMAKE_HOST_SYSTEM_MAJOR_VERSION}.${_CMAKE_HOST_SYSTEM_MINOR_VERSION}")
unset(_CMAKE_HOST_SYSTEM_MAJOR_VERSION)
unset(_CMAKE_HOST_SYSTEM_MINOR_VERSION)
+ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ execute_process(COMMAND getprop ro.build.version.sdk
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+
+ if(NOT DEFINED CMAKE_SYSTEM_VERSION)
+ set(_ANDROID_API_LEVEL_H $ENV{PREFIX}/include/android/api-level.h)
+ set(_ANDROID_API_REGEX "#define __ANDROID_API__ ([0-9]+)")
+ file(READ ${_ANDROID_API_LEVEL_H} _ANDROID_API_LEVEL_H_CONTENT)
+ string(REGEX MATCH ${_ANDROID_API_REGEX} _ANDROID_API_LINE "${_ANDROID_API_LEVEL_H_CONTENT}")
+ string(REGEX REPLACE ${_ANDROID_API_REGEX} "\\1" _ANDROID_API "${_ANDROID_API_LINE}")
+ if(_ANDROID_API)
+ set(CMAKE_SYSTEM_VERSION "${_ANDROID_API}")
+ endif()
+
+ unset(_ANDROID_API_LEVEL_H)
+ unset(_ANDROID_API_LEVEL_H_CONTENT)
+ unset(_ANDROID_API_REGEX)
+ unset(_ANDROID_API_LINE)
+ unset(_ANDROID_API)
+ endif()
else()
execute_process(COMMAND ${CMAKE_UNAME} -r
OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index f778891..431d00b 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -82,7 +82,7 @@ if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND
if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xClang")
set(_CMAKE_NM_NAMES "llvm-nm" "nm")
list(PREPEND _CMAKE_AR_NAMES "llvm-lib")
- # llvm-mt does not support all flags we need in vs_link_exe
+ # llvm-mt is not ready to be used as a replacement for mt.exe
# list(PREPEND _CMAKE_MT_NAMES "llvm-mt")
list(PREPEND _CMAKE_LINKER_NAMES "lld-link")
list(APPEND _CMAKE_TOOL_VARS NM)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 777c680..1c6f0df 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -21,7 +21,8 @@ set(CMAKE_INCLUDE_FLAG_Swift "-I ")
# FIXME: Move compiler- and platform-specific flags to the above-included modules.
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS"
- OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
+ OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS"
+ OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -install_name -Xlinker ")
elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Windows)
set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -soname -Xlinker ")
@@ -30,7 +31,8 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows)
set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG "-Xlinker -rpath -Xlinker ")
set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG "-Xlinker -rpath -Xlinker ")
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS"
- OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
+ OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS"
+ OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG_SEP "")
set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG_SEP "")
else()
diff --git a/Modules/CMakeSystemSpecificInitialize.cmake b/Modules/CMakeSystemSpecificInitialize.cmake
index e87d868..ee8cb86 100644
--- a/Modules/CMakeSystemSpecificInitialize.cmake
+++ b/Modules/CMakeSystemSpecificInitialize.cmake
@@ -25,7 +25,7 @@ unset(LINUX)
# It is useful to share the same aforementioned configuration files and
# avoids duplicating them in case of tightly related platforms.
#
-# An example are the platforms supported by Xcode (macOS, iOS, tvOS,
+# An example are the platforms supported by Xcode (macOS, iOS, tvOS, visionOS
# and watchOS). For all of those the CMAKE_EFFECTIVE_SYSTEM_NAME is
# set to Apple which results in using
# Platform/Apple-AppleClang-CXX.cmake for the Apple C++ compiler.
diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake
index 569dafd..d807c17 100644
--- a/Modules/CheckCXXSymbolExists.cmake
+++ b/Modules/CheckCXXSymbolExists.cmake
@@ -33,7 +33,7 @@ Check if a symbol exists as a function, variable, or macro in ``C++``.
function. Since there is no reliable way to predict whether a given function
in the system environment may be defined as an overloaded function or may be
an overloaded function on other systems or will become so in the future, it
- is generally advised to use the :module:`CheckCXXSourceCompiles` module for
+ is generally advised to use the :module:`CheckSourceCompiles` module for
checking any function symbol (unless somehow you surely know the checked
function is not overloaded on other systems or will not be so in the
future).
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index 69913a3..04e721c 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -5,26 +5,45 @@
CheckLanguage
-------------
-Check if a language can be enabled
+Check whether a language can be enabled by the :command:`enable_language`
+or :command:`project` commands:
-Usage:
+.. command:: check_language
-::
+ .. code-block:: cmake
- check_language(<lang>)
+ check_language(<lang>)
-where ``<lang>`` is a language that may be passed to :command:`enable_language`
-such as ``Fortran``. If :variable:`CMAKE_<LANG>_COMPILER` is already defined
-the check does nothing. Otherwise it tries enabling the language in a
-test project. The result is cached in :variable:`CMAKE_<LANG>_COMPILER`
-as the compiler that was found, or ``NOTFOUND`` if the language cannot be
-enabled. For CUDA which can have an explicit host compiler, the cache
-:variable:`CMAKE_CUDA_HOST_COMPILER` variable will be set if it was required
-for compilation (and cleared if it was not).
+ Try enabling language ``<lang>`` in a test project and record results
+ in the cache:
-Example:
+ :variable:`CMAKE_<LANG>_COMPILER`
+ If the language can be enabled, this variable is set to the compiler
+ that was found. If the language cannot be enabled, this variable is
+ set to ``NOTFOUND``.
-::
+ If this variable is already set, either explicitly or cached by
+ a previous call, the check is skipped.
+
+ :variable:`CMAKE_CUDA_HOST_COMPILER`
+ This variable is set when ``<lang>`` is ``CUDA``.
+
+ If the check detects an explicit host compiler that is required for
+ compilation, this variable will be set to that compiler.
+ If the check detects that no explicit host compiler is needed,
+ this variable will be cleared.
+
+ If this variable is already set, its value is preserved only if
+ :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>` is also set.
+ Otherwise, the check runs and overwrites
+ :variable:`CMAKE_CUDA_HOST_COMPILER` with a new result.
+ Note that :variable:`CMAKE_CUDA_HOST_COMPILER` documents it should
+ not be set without also setting
+ :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>` to a NVCC compiler.
+
+For example:
+
+.. code-block:: cmake
check_language(Fortran)
if(CMAKE_Fortran_COMPILER)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index a74e90b..1167ba8 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -43,5 +43,6 @@ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
" > <DYNDEP_FILE>")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "clang")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>")
+ set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG "--precompile")
endif()
endif()
diff --git a/Modules/Compiler/IntelLLVM.cmake b/Modules/Compiler/IntelLLVM.cmake
index e256c8f..f3c0bf4 100644
--- a/Modules/Compiler/IntelLLVM.cmake
+++ b/Modules/Compiler/IntelLLVM.cmake
@@ -44,6 +44,13 @@ else()
string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g")
+ if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2023.0.0)
+ if("x${lang}" STREQUAL "xFortran")
+ string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -diag-disable:10440")
+ else()
+ string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -Rno-debug-disables-optimization")
+ endif()
+ endif()
string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os")
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g")
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index 10a9073..b03f826 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -87,4 +87,5 @@ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34")
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT "msvc")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "msvc")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>")
+ set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG "-ifcOnly;-ifcOutput;<OBJECT>")
endif ()
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index c839d1c..13d8d8e 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -1,4 +1,5 @@
-include(Compiler/CMakeCommonCompilerMacros)
+include(Compiler/NVIDIA)
+__compiler_nvidia_cxx_standards(CUDA)
set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True)
set(CMAKE_CUDA_VERBOSE_FLAG "-v")
@@ -98,65 +99,6 @@ if(UNIX AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX"))
list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl")
endif()
-if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
- # MSVC requires c++14 as the minimum level
- set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
-
- # MSVC requires c++14 as the minimum level
- set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "")
-
- if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
- if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.10.25017)
- set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14")
- set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14")
- else()
- set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "")
- endif()
- endif()
-
- if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0)
- if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505)
- set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17")
- set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17")
- endif()
- endif()
-
- if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0)
- if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505)
- set(CMAKE_CUDA20_STANDARD_COMPILE_OPTION "-std=c++20")
- set(CMAKE_CUDA20_EXTENSION_COMPILE_OPTION "-std=c++20")
- endif()
- endif()
-
-else()
- set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
-
- set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11")
- set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11")
-
- if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
- set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03")
- set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=c++03")
- set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14")
- set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14")
- endif()
-
- if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0)
- set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17")
- set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17")
- endif()
-
- if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0)
- set(CMAKE_CUDA20_STANDARD_COMPILE_OPTION "-std=c++20")
- set(CMAKE_CUDA20_EXTENSION_COMPILE_OPTION "-std=c++20")
- endif()
-
-endif()
-
if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0")
set(CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ")
set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ")
@@ -171,5 +113,3 @@ else()
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
endif()
-
-__compiler_check_default_language_standard(CUDA 6.0 03)
diff --git a/Modules/Compiler/NVIDIA.cmake b/Modules/Compiler/NVIDIA.cmake
new file mode 100644
index 0000000..686c03d
--- /dev/null
+++ b/Modules/Compiler/NVIDIA.cmake
@@ -0,0 +1,69 @@
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_NVIDIA)
+ return()
+endif()
+set(__COMPILER_NVIDIA 1)
+
+include(Compiler/CMakeCommonCompilerMacros)
+
+macro(__compiler_nvidia_cxx_standards lang)
+ if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
+ # MSVC requires c++14 as the minimum level
+ set(CMAKE_${lang}03_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}03_EXTENSION_COMPILE_OPTION "")
+
+ # MSVC requires c++14 as the minimum level
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "")
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 9.0)
+ if(CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.10.25017)
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=c++14")
+ else()
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "")
+ endif()
+ endif()
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 11.0)
+ if(CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505)
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=c++17")
+ endif()
+ endif()
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)
+ if(CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505)
+ set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++20")
+ set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=c++20")
+ endif()
+ endif()
+ else()
+ set(CMAKE_${lang}03_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}03_EXTENSION_COMPILE_OPTION "")
+
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=c++11")
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 9.0)
+ set(CMAKE_${lang}03_STANDARD_COMPILE_OPTION "-std=c++03")
+ set(CMAKE_${lang}03_EXTENSION_COMPILE_OPTION "-std=c++03")
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=c++14")
+ endif()
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 11.0)
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=c++17")
+ endif()
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)
+ set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++20")
+ set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=c++20")
+ endif()
+ endif()
+
+ __compiler_check_default_language_standard(${lang} 6.0 03)
+endmacro()
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 605908d..36eb70e 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -11,11 +11,8 @@ ExternalProject
.. contents::
-Commands
-^^^^^^^^
-
External Project Definition
-"""""""""""""""""""""""""""
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. command:: ExternalProject_Add
@@ -34,866 +31,908 @@ External Project Definition
customized. The function supports a large number of options which can be used
to tailor the external project behavior.
- **Directory Options:**
- Most of the time, the default directory layout is sufficient. It is largely
- an implementation detail that the main project usually doesn't need to
- change. In some circumstances, however, control over the directory layout
- can be useful or necessary. The directory options are potentially more
- useful from the point of view that the main build can use the
- :command:`ExternalProject_Get_Property` command to retrieve their values,
- thereby allowing the main project to refer to build artifacts of the
- external project.
-
- ``PREFIX <dir>``
- Root directory for the external project. Unless otherwise noted below,
- all other directories associated with the external project will be
- created under here.
-
- ``TMP_DIR <dir>``
- Directory in which to store temporary files.
-
- ``STAMP_DIR <dir>``
- Directory in which to store the timestamps of each step. Log files from
- individual steps are also created in here unless overridden by LOG_DIR
- (see *Logging Options* below).
-
- ``LOG_DIR <dir>``
- .. versionadded:: 3.14
-
- Directory in which to store the logs of each step.
-
- ``DOWNLOAD_DIR <dir>``
- Directory in which to store downloaded files before unpacking them. This
- directory is only used by the URL download method, all other download
- methods use ``SOURCE_DIR`` directly instead.
-
- ``SOURCE_DIR <dir>``
- Source directory into which downloaded contents will be unpacked, or for
- non-URL download methods, the directory in which the repository should be
- checked out, cloned, etc. If no download method is specified, this must
- point to an existing directory where the external project has already
- been unpacked or cloned/checked out.
-
- .. note::
- If a download method is specified, any existing contents of the source
- directory may be deleted. Only the URL download method checks whether
- this directory is either missing or empty before initiating the
- download, stopping with an error if it is not empty. All other
- download methods silently discard any previous contents of the source
- directory.
-
- ``BINARY_DIR <dir>``
- Specify the build directory location. This option is ignored if
- ``BUILD_IN_SOURCE`` is enabled.
-
- ``INSTALL_DIR <dir>``
- Installation prefix to be placed in the ``<INSTALL_DIR>`` placeholder.
- This does not actually configure the external project to install to
- the given prefix. That must be done by passing appropriate arguments
- to the external project configuration step, e.g. using ``<INSTALL_DIR>``.
-
- If any of the above ``..._DIR`` options are not specified, their defaults
- are computed as follows. If the ``PREFIX`` option is given or the
- ``EP_PREFIX`` directory property is set, then an external project is built
- and installed under the specified prefix::
-
- TMP_DIR = <prefix>/tmp
- STAMP_DIR = <prefix>/src/<name>-stamp
- DOWNLOAD_DIR = <prefix>/src
- SOURCE_DIR = <prefix>/src/<name>
- BINARY_DIR = <prefix>/src/<name>-build
- INSTALL_DIR = <prefix>
- LOG_DIR = <STAMP_DIR>
-
- Otherwise, if the ``EP_BASE`` directory property is set then components
- of an external project are stored under the specified base::
-
- TMP_DIR = <base>/tmp/<name>
- STAMP_DIR = <base>/Stamp/<name>
- DOWNLOAD_DIR = <base>/Download/<name>
- SOURCE_DIR = <base>/Source/<name>
- BINARY_DIR = <base>/Build/<name>
- INSTALL_DIR = <base>/Install/<name>
- LOG_DIR = <STAMP_DIR>
-
- If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified, then the
- default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are
- interpreted with respect to :variable:`CMAKE_CURRENT_BINARY_DIR` at the
- point where ``ExternalProject_Add()`` is called.
-
- **Download Step Options:**
- A download method can be omitted if the ``SOURCE_DIR`` option is used to
- point to an existing non-empty directory. Otherwise, one of the download
- methods below must be specified (multiple download methods should not be
- given) or a custom ``DOWNLOAD_COMMAND`` provided.
-
- ``DOWNLOAD_COMMAND <cmd>...``
- Overrides the command used for the download step
- (:manual:`generator expressions <cmake-generator-expressions(7)>` are
- supported). If this option is specified, all other download options will
- be ignored. Providing an empty string for ``<cmd>`` effectively disables
- the download step.
-
- *URL Download*
- ``URL <url1> [<url2>...]``
- List of paths and/or URL(s) of the external project's source. When more
- than one URL is given, they are tried in turn until one succeeds. A URL
- may be an ordinary path in the local file system (in which case it
- must be the only URL provided) or any downloadable URL supported by the
- :command:`file(DOWNLOAD)` command. A local filesystem path may refer to
- either an existing directory or to an archive file, whereas a URL is
- expected to point to a file which can be treated as an archive. When an
- archive is used, it will be unpacked automatically unless the
- ``DOWNLOAD_NO_EXTRACT`` option is set to prevent it. The archive type
- is determined by inspecting the actual content rather than using logic
- based on the file extension.
-
- .. versionchanged:: 3.7
- Multiple URLs are allowed.
-
- ``URL_HASH <algo>=<hashValue>``
- Hash of the archive file to be downloaded. The argument should be of
- the form ``<algo>=<hashValue>`` where ``algo`` can be any of the hashing
- algorithms supported by the :command:`file()` command. Specifying this
- option is strongly recommended for URL downloads, as it ensures the
- integrity of the downloaded content. It is also used as a check for a
- previously downloaded file, allowing connection to the remote location
- to be avoided altogether if the local directory already has a file from
- an earlier download that matches the specified hash.
-
- ``URL_MD5 <md5>``
- Equivalent to ``URL_HASH MD5=<md5>``.
-
- ``DOWNLOAD_NAME <fname>``
- File name to use for the downloaded file. If not given, the end of the
- URL is used to determine the file name. This option is rarely needed,
- the default name is generally suitable and is not normally used outside
- of code internal to the ``ExternalProject`` module.
-
- ``DOWNLOAD_EXTRACT_TIMESTAMP <bool>``
- .. versionadded:: 3.24
-
- When specified with a true value, the timestamps of the extracted
- files will match those in the archive. When false, the timestamps of
- the extracted files will reflect the time at which the extraction
- was performed. If the download URL changes, timestamps based off
- those in the archive can result in dependent targets not being rebuilt
- when they potentially should have been. Therefore, unless the file
- timestamps are significant to the project in some way, use a false
- value for this option. If ``DOWNLOAD_EXTRACT_TIMESTAMP`` is not given,
- the default is false. See policy :policy:`CMP0135`.
-
- ``DOWNLOAD_NO_EXTRACT <bool>``
- .. versionadded:: 3.6
-
- Allows the extraction part of the download step to be disabled by
- passing a boolean true value for this option. If this option is not
- given, the downloaded contents will be unpacked automatically if
- required. If extraction has been disabled, the full path to the
- downloaded file is available as ``<DOWNLOADED_FILE>`` in subsequent
- steps or as the property ``DOWNLOADED_FILE`` with the
- :command:`ExternalProject_Get_Property` command.
-
- ``DOWNLOAD_NO_PROGRESS <bool>``
- Can be used to disable logging the download progress. If this option is
- not given, download progress messages will be logged.
-
- ``TIMEOUT <seconds>``
- Maximum time allowed for file download operations.
-
- ``INACTIVITY_TIMEOUT <seconds>``
- .. versionadded:: 3.19
-
- Terminate the operation after a period of inactivity.
-
- ``HTTP_USERNAME <username>``
- .. versionadded:: 3.7
-
- Username for the download operation if authentication is required.
-
- ``HTTP_PASSWORD <password>``
- .. versionadded:: 3.7
-
- Password for the download operation if authentication is required.
-
- ``HTTP_HEADER <header1> [<header2>...]``
- .. versionadded:: 3.7
-
- Provides an arbitrary list of HTTP headers for the download operation.
- This can be useful for accessing content in systems like AWS, etc.
-
- ``TLS_VERIFY <bool>``
- Specifies whether certificate verification should be performed for
- https URLs. If this option is not provided, the default behavior is
- determined by the :variable:`CMAKE_TLS_VERIFY` variable (see
- :command:`file(DOWNLOAD)`). If that is also not set, certificate
- verification will not be performed. In situations where ``URL_HASH``
- cannot be provided, this option can be an alternative verification
- measure.
-
- .. versionchanged:: 3.6
- This option also applies to ``git clone`` invocations, although the
- default behavior is different. If ``TLS_VERIFY`` is not given and
- :variable:`CMAKE_TLS_VERIFY` is not set, the behavior will be
- determined by git's defaults. Normally, the ``sslVerify`` git
- config setting defaults to true, but the user may have overridden
- this at a global level.
-
- ``TLS_CAINFO <file>``
- Specify a custom certificate authority file to use if ``TLS_VERIFY``
- is enabled. If this option is not specified, the value of the
- :variable:`CMAKE_TLS_CAINFO` variable will be used instead (see
- :command:`file(DOWNLOAD)`)
-
- ``NETRC <level>``
- .. versionadded:: 3.11
-
- Specify whether the ``.netrc`` file is to be used for operation.
- If this option is not specified, the value of the
- :variable:`CMAKE_NETRC` variable will be used instead
- (see :command:`file(DOWNLOAD)`). Valid levels are:
-
- ``IGNORED``
- The ``.netrc`` file is ignored.
- This is the default.
- ``OPTIONAL``
- The ``.netrc`` file is optional, and information in the URL
- is preferred. The file will be scanned to find which ever
- information is not specified in the URL.
- ``REQUIRED``
- The ``.netrc`` file is required, and information in the URL
- is ignored.
-
- ``NETRC_FILE <file>``
- .. versionadded:: 3.11
-
- Specify an alternative ``.netrc`` file to the one in your home directory
- if the ``NETRC`` level is ``OPTIONAL`` or ``REQUIRED``. If this option
- is not specified, the value of the :variable:`CMAKE_NETRC_FILE` variable
- will be used instead (see :command:`file(DOWNLOAD)`)
-
- .. versionadded:: 3.1
- Added support for `tbz2`, `.tar.xz`, `.txz`, and `.7z` extensions.
-
- *Git*
- NOTE: A git version of 1.6.5 or later is required if this download method
- is used.
-
- ``GIT_REPOSITORY <url>``
- 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``
- rather than simply ``myBranch``). This ensures that if the remote end
- has its tag moved or branch rebased or history rewritten, the local
- clone will still be updated correctly. In general, however, specifying
- a commit hash should be preferred for a number of reasons:
-
- - If the local clone already has the commit corresponding to the hash,
- no ``git fetch`` needs to be performed to check for changes each time
- CMake is re-run. This can result in a significant speed up if many
- external projects are being used.
- - Using a specific git hash ensures that the main project's own history
- is fully traceable to a specific point in the external project's
- evolution. If a branch or tag name is used instead, then checking out
- a specific commit of the main project doesn't necessarily pin the
- whole build to a specific point in the life of the external project.
- The lack of such deterministic behavior makes the main project lose
- traceability and repeatability.
-
- If ``GIT_SHALLOW`` is enabled then ``GIT_TAG`` works only with
- branch names and tags. A commit hash is not allowed.
-
- Note that if not provided, ``GIT_TAG`` defaults to ``master``, not the
- default Git branch name.
-
- ``GIT_REMOTE_NAME <name>``
- The optional name of the remote. If this option is not specified, it
- defaults to ``origin``.
-
- ``GIT_SUBMODULES <module>...``
- Specific git submodules that should also be updated. If this option is
- not provided, all git submodules will be updated.
-
- .. versionchanged:: 3.16
- When :policy:`CMP0097` is set to ``NEW``, if this value is set
- to an empty string then no submodules are initialized or updated.
-
- ``GIT_SUBMODULES_RECURSE <bool>``
- .. versionadded:: 3.17
-
- Specify whether git submodules (if any) should update recursively by
- passing the ``--recursive`` flag to ``git submodule update``.
- If not specified, the default is on.
-
- ``GIT_SHALLOW <bool>``
- .. versionadded:: 3.6
-
- When this option is enabled, the ``git clone`` operation will be given
- the ``--depth 1`` option. This performs a shallow clone, which avoids
- downloading the whole history and instead retrieves just the commit
- denoted by the ``GIT_TAG`` option.
-
- ``GIT_PROGRESS <bool>``
- .. versionadded:: 3.8
-
- When enabled, this option instructs the ``git clone`` operation to
- report its progress by passing it the ``--progress`` option. Without
- this option, the clone step for large projects may appear to make the
- build stall, since nothing will be logged until the clone operation
- finishes. While this option can be used to provide progress to prevent
- the appearance of the build having stalled, it may also make the build
- overly noisy if lots of external projects are used.
-
- ``GIT_CONFIG <option1> [<option2>...]``
- .. versionadded:: 3.8
-
- Specify a list of config options to pass to ``git clone``. Each option
- listed will be transformed into its own ``--config <option>`` on the
- ``git clone`` command line, with each option required to be in the
- form ``key=value``.
-
- ``GIT_REMOTE_UPDATE_STRATEGY <strategy>``
- .. versionadded:: 3.18
-
- When ``GIT_TAG`` refers to a remote branch, this option can be used to
- specify how the update step behaves. The ``<strategy>`` must be one of
- the following:
-
- ``CHECKOUT``
- Ignore the local branch and always checkout the branch specified by
- ``GIT_TAG``.
-
- ``REBASE``
- Try to rebase the current branch to the one specified by ``GIT_TAG``.
- If there are local uncommitted changes, they will be stashed first
- and popped again after rebasing. If rebasing or popping stashed
- changes fail, abort the rebase and halt with an error.
- When ``GIT_REMOTE_UPDATE_STRATEGY`` is not present, this is the
- default strategy unless the default has been overridden with
- ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` (see below).
- Note that if the branch specified in ``GIT_TAG`` is different to
- the upstream branch currently being tracked, it is not safe to
- perform a rebase. In that situation, ``REBASE`` will silently be
- treated as ``CHECKOUT`` instead.
-
- ``REBASE_CHECKOUT``
- Same as ``REBASE`` except if the rebase fails, an annotated tag will
- be created at the original ``HEAD`` position from before the rebase
- and then checkout ``GIT_TAG`` just like the ``CHECKOUT`` strategy.
- The message stored on the annotated tag will give information about
- what was attempted and the tag name will include a timestamp so that
- each failed run will add a new tag. This strategy ensures no changes
- will be lost, but updates should always succeed if ``GIT_TAG`` refers
- to a valid ref unless there are uncommitted changes that cannot be
- popped successfully.
-
- The variable ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` can be set to
- override the default strategy. This variable should not be set by a
- project, it is intended for the user to set. It is primarily intended
- for use in continuous integration scripts to ensure that when history
- is rewritten on a remote branch, the build doesn't end up with
- unintended changes or failed builds resulting from conflicts during
- rebase operations.
-
- *Subversion*
- ``SVN_REPOSITORY <url>``
- URL of the Subversion repository.
-
- ``SVN_REVISION -r<rev>``
- Revision to checkout from the Subversion repository.
-
- ``SVN_USERNAME <username>``
- Username for the Subversion checkout and update.
-
- ``SVN_PASSWORD <password>``
- Password for the Subversion checkout and update.
-
- ``SVN_TRUST_CERT <bool>``
- Specifies whether to trust the Subversion server site certificate. If
- enabled, the ``--trust-server-cert`` option is passed to the ``svn``
- checkout and update commands.
-
- *Mercurial*
- ``HG_REPOSITORY <url>``
- URL of the mercurial repository.
-
- ``HG_TAG <tag>``
- Mercurial branch name, tag or commit id.
-
- *CVS*
- ``CVS_REPOSITORY <cvsroot>``
- CVSROOT of the CVS repository.
-
- ``CVS_MODULE <mod>``
- Module to checkout from the CVS repository.
-
- ``CVS_TAG <tag>``
- Tag to checkout from the CVS repository.
-
- **Update Step Options:**
- Whenever CMake is re-run, by default the external project's sources will be
- updated if the download method supports updates (e.g. a git repository
- would be checked if the ``GIT_TAG`` does not refer to a specific commit).
-
- ``UPDATE_COMMAND <cmd>...``
- Overrides the download method's update step with a custom command.
- The command may use
- :manual:`generator expressions <cmake-generator-expressions(7)>`.
-
- ``UPDATE_DISCONNECTED <bool>``
- .. versionadded:: 3.2
-
- When enabled, this option causes the update step to be skipped (but see
- below for changed behavior where this is not the case). It does not
- prevent the download step. The update step can still be
- added as a step target (see :command:`ExternalProject_Add_StepTargets`)
- and called manually. This is useful if you want to allow developers to
- build the project when disconnected from the network (the network may
- still be needed for the download step though).
-
- .. versionchanged:: 3.27
-
- When ``UPDATE_DISCONNECTED`` is true, the update step will be executed
- if any details about the update or download step are changed.
- Furthermore, if using the git download/update method, the update
- logic will be modified to skip attempts to contact the remote.
- If the ``GIT_TAG`` mentions a ref that is not known locally, the
- update step will halt with a fatal error.
-
- When this option is present, it is generally advisable to make the value
- a cache variable under the developer's control rather than hard-coding
- it. If this option is not present, the default value is taken from the
- ``EP_UPDATE_DISCONNECTED`` directory property. If that is also not
- defined, updates are performed as normal. The ``EP_UPDATE_DISCONNECTED``
- directory property is intended as a convenience for controlling the
- ``UPDATE_DISCONNECTED`` behavior for an entire section of a project's
- directory hierarchy and may be a more convenient method of giving
- developers control over whether or not to perform updates (assuming the
- project also provides a cache variable or some other convenient method
- for setting the directory property).
-
- This may cause a step target to be created automatically for the
- ``download`` step. See policy :policy:`CMP0114`.
-
- **Patch Step Options:**
- ``PATCH_COMMAND <cmd>...``
- Specifies a custom command to patch the sources after an update. By
- default, no patch command is defined. Note that it can be quite difficult
- to define an appropriate patch command that performs robustly, especially
- for download methods such as git where changing the ``GIT_TAG`` will not
- discard changes from a previous patch, but the patch command will be
- called again after updating to the new tag.
-
- **Configure Step Options:**
- The configure step is run after the download and update steps. By default,
- the external project is assumed to be a CMake project, but this can be
- overridden if required.
-
- ``CONFIGURE_COMMAND <cmd>...``
- The default configure command runs CMake with a few options based on
- the main project. The options added are typically only those needed to
- use the same generator as the main project, but the ``CMAKE_GENERATOR``
- option can be given to override this. The project is responsible for
- adding any toolchain details, flags or other settings it wants to
- re-use from the main project or otherwise specify (see ``CMAKE_ARGS``,
- ``CMAKE_CACHE_ARGS`` and ``CMAKE_CACHE_DEFAULT_ARGS`` below).
-
- For non-CMake external projects, the ``CONFIGURE_COMMAND`` option must
- be used to override the default configure command
- (:manual:`generator expressions <cmake-generator-expressions(7)>` are
- supported). For projects that require no configure step, specify this
- option with an empty string as the command to execute.
-
- ``CMAKE_COMMAND /.../cmake``
- Specify an alternative cmake executable for the configure step (use an
- absolute path). This is generally not recommended, since it is
- usually desirable to use the same CMake version throughout the whole
- build. This option is ignored if a custom configure command has been
- specified with ``CONFIGURE_COMMAND``.
-
- ``CMAKE_GENERATOR <gen>``
- Override the CMake generator used for the configure step. Without this
- option, the same generator as the main build will be used. This option is
- ignored if a custom configure command has been specified with the
- ``CONFIGURE_COMMAND`` option.
-
- ``CMAKE_GENERATOR_PLATFORM <platform>``
- .. versionadded:: 3.1
-
- Pass a generator-specific platform name to the CMake command (see
- :variable:`CMAKE_GENERATOR_PLATFORM`). It is an error to provide this
- option without the ``CMAKE_GENERATOR`` option.
-
- ``CMAKE_GENERATOR_TOOLSET <toolset>``
- Pass a generator-specific toolset name to the CMake command (see
- :variable:`CMAKE_GENERATOR_TOOLSET`). It is an error to provide this
- option without the ``CMAKE_GENERATOR`` option.
-
- ``CMAKE_GENERATOR_INSTANCE <instance>``
- .. versionadded:: 3.11
-
- Pass a generator-specific instance selection to the CMake command (see
- :variable:`CMAKE_GENERATOR_INSTANCE`). It is an error to provide this
- option without the ``CMAKE_GENERATOR`` option.
-
- ``CMAKE_ARGS <arg>...``
- The specified arguments are passed to the :program:`cmake` command line.
- They can be any argument the :program:`cmake` command understands, not just
- cache values defined by ``-D...`` arguments (see also
- :manual:`CMake Options <cmake(1)>`).
-
- .. versionadded:: 3.3
- Arguments may use
- :manual:`generator expressions <cmake-generator-expressions(7)>`.
-
- ``CMAKE_CACHE_ARGS <arg>...``
- This is an alternate way of specifying cache variables where command line
- length issues may become a problem. The arguments are expected to be in
- the form ``-Dvar:STRING=value``, which are then transformed into
- CMake :command:`set` commands with the ``FORCE`` option used. These
- ``set()`` commands are written to a pre-load script which is then applied
- using the :manual:`cmake -C <cmake(1)>` command line option.
-
- .. versionadded:: 3.3
- Arguments may use
- :manual:`generator expressions <cmake-generator-expressions(7)>`.
-
- ``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
- .. versionadded:: 3.2
-
- This is the same as the ``CMAKE_CACHE_ARGS`` option except the ``set()``
- commands do not include the ``FORCE`` keyword. This means the values act
- as initial defaults only and will not override any variables already set
- from a previous run. Use this option with care, as it can lead to
- different behavior depending on whether the build starts from a fresh
- build directory or re-uses previous build contents.
-
- .. versionadded:: 3.15
- If the CMake generator is the ``Green Hills MULTI`` and not overridden,
- the original project's settings for the GHS toolset and target system
- customization cache variables are propagated into the external project.
-
- ``SOURCE_SUBDIR <dir>``
- .. versionadded:: 3.7
-
- When no ``CONFIGURE_COMMAND`` option is specified, the configure step
- assumes the external project has a ``CMakeLists.txt`` file at the top of
- its source tree (i.e. in ``SOURCE_DIR``). The ``SOURCE_SUBDIR`` option
- can be used to point to an alternative directory within the source tree
- to use as the top of the CMake source tree instead. This must be a
- relative path and it will be interpreted as being relative to
- ``SOURCE_DIR``.
-
- .. versionadded:: 3.14
- When ``BUILD_IN_SOURCE`` option is enabled, the ``BUILD_COMMAND``
- is used to point to an alternative directory within the source tree.
-
- ``CONFIGURE_HANDLED_BY_BUILD <bool>``
- .. versionadded:: 3.20
-
- Enabling this option relaxes the dependencies of the configure step on
- other external projects to order-only. This means the configure step will
- be executed after its external project dependencies are built but it will
- not be marked dirty when one of its external project dependencies is
- rebuilt. This option can be enabled when the build step is smart enough
- to figure out if the configure step needs to be rerun. CMake and Meson are
- examples of build systems whose build step is smart enough to know if the
- configure step needs to be rerun.
-
- **Build Step Options:**
- If the configure step assumed the external project uses CMake as its build
- system, the build step will also. Otherwise, the build step will assume a
- Makefile-based build and simply run ``make`` with no arguments as the
- default build step. This can be overridden with custom build commands if
- required.
-
- If both the main project and the external project use make as their build
- tool, the build step of the external project is invoked as a recursive
- make using ``$(MAKE)``. This will communicate some build tool settings
- from the main project to the external project. If either the main project
- or external project is not using make, no build tool settings will be
- passed to the external project other than those established by the
- configure step (i.e. running ``ninja -v`` in the main project will not
- pass ``-v`` to the external project's build step, even if it also uses
- ``ninja`` as its build tool).
-
- ``BUILD_COMMAND <cmd>...``
- Overrides the default build command
- (:manual:`generator expressions <cmake-generator-expressions(7)>` are
- supported). If this option is not given, the default build command will
- be chosen to integrate with the main build in the most appropriate way
- (e.g. using recursive ``make`` for Makefile generators or
- :option:`cmake --build` if the project uses a CMake build). This option
- can be specified with an empty string as the command to make the build
- step do nothing.
-
- ``BUILD_IN_SOURCE <bool>``
- When this option is enabled, the build will be done directly within the
- external project's source tree. This should generally be avoided, the use
- of a separate build directory is usually preferred, but it can be useful
- when the external project assumes an in-source build. The ``BINARY_DIR``
- option should not be specified if building in-source.
-
- ``BUILD_ALWAYS <bool>``
- Enabling this option forces the build step to always be run. This can be
- the easiest way to robustly ensure that the external project's own build
- dependencies are evaluated rather than relying on the default
- success timestamp-based method. This option is not normally needed unless
- developers are expected to modify something the external project's build
- depends on in a way that is not detectable via the step target
- dependencies (e.g. ``SOURCE_DIR`` is used without a download method and
- developers might modify the sources in ``SOURCE_DIR``).
-
- ``BUILD_BYPRODUCTS <file>...``
- .. versionadded:: 3.2
-
- Specifies files that will be generated by the build command but which
- might or might not have their modification time updated by subsequent
- builds. This may also be required to explicitly declare dependencies
- when using the :generator:`Ninja` generator.
- These ultimately get passed through as ``BYPRODUCTS`` to the
- build step's own underlying call to :command:`add_custom_command`, which
- has additional documentation.
-
- **Install Step Options:**
- If the configure step assumed the external project uses CMake as its build
- system, the install step will also. Otherwise, the install step will assume
- a Makefile-based build and simply run ``make install`` as the default build
- step. This can be overridden with custom install commands if required.
-
- ``INSTALL_COMMAND <cmd>...``
- The external project's own install step is invoked as part of the main
- project's *build*. It is done after the external project's build step
- and may be before or after the external project's test step (see the
- ``TEST_BEFORE_INSTALL`` option below). The external project's install
- rules are not part of the main project's install rules, so if anything
- from the external project should be installed as part of the main build,
- these need to be specified in the main build as additional
- :command:`install` commands. The default install step builds the
- ``install`` target of the external project, but this can be overridden
- with a custom command using this option
- (:manual:`generator expressions <cmake-generator-expressions(7)>` are
- supported). Passing an empty string as the ``<cmd>`` makes the install
- step do nothing.
-
- ``INSTALL_BYPRODUCTS <file>...``
- .. versionadded:: 3.26
-
- Specifies files that will be generated by the install command but which
- might or might not have their modification time updated by subsequent
- installs. This may also be required to explicitly declare dependencies
- when using the :generator:`Ninja` generator.
- These ultimately get passed through as ``BYPRODUCTS`` to the
- install step's own underlying call to :command:`add_custom_command`, which
- has additional documentation.
-
- .. note::
- If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
- main project is built, it will only have an effect if the following
- conditions are met:
-
- * The main project's configure step assumed the external project uses
- CMake as its build system.
- * The external project's install command actually runs. Note that due
- to the way ``ExternalProject`` may use timestamps internally, if
- nothing the install step depends on needs to be re-executed, the
- install command might also not need to run.
-
- Note also that ``ExternalProject`` does not check whether the
- :envvar:`CMAKE_INSTALL_MODE` environment variable changes from one run
- to another.
-
- **Test Step Options:**
- The test step is only defined if at least one of the following ``TEST_...``
- options are provided.
-
- ``TEST_COMMAND <cmd>...``
- Overrides the default test command
- (:manual:`generator expressions <cmake-generator-expressions(7)>` are
- supported). If this option is not given, the default behavior of the test
- step is to build the external project's own ``test`` target. This option
- can be specified with ``<cmd>`` as an empty string, which allows the test
- step to still be defined, but it will do nothing. Do not specify any of
- the other ``TEST_...`` options if providing an empty string as the test
- command, but prefer to omit all ``TEST_...`` options altogether if the
- test step target is not needed.
-
- ``TEST_BEFORE_INSTALL <bool>``
- When this option is enabled, the test step will be executed before the
- install step. The default behavior is for the test step to run after the
- install step.
-
- ``TEST_AFTER_INSTALL <bool>``
- This option is mainly useful as a way to indicate that the test step is
- desired but all default behavior is sufficient. Specifying this option
- with a boolean true value ensures the test step is defined and that it
- comes after the install step. If both ``TEST_BEFORE_INSTALL`` and
- ``TEST_AFTER_INSTALL`` are enabled, the latter is silently ignored.
-
- ``TEST_EXCLUDE_FROM_MAIN <bool>``
- .. versionadded:: 3.2
-
- If enabled, the main build's default ALL target will not depend on the
- test step. This can be a useful way of ensuring the test step is defined
- but only gets invoked when manually requested.
- This may cause a step target to be created automatically for either
- the ``install`` or ``build`` step. See policy :policy:`CMP0114`.
-
- **Output Logging Options:**
- Each of the following ``LOG_...`` options can be used to wrap the relevant
- step in a script to capture its output to files. The log files will be
- created in ``LOG_DIR`` if supplied or otherwise the ``STAMP_DIR``
- directory with step-specific file names.
-
- ``LOG_DOWNLOAD <bool>``
- When enabled, the output of the download step is logged to files.
-
- ``LOG_UPDATE <bool>``
- When enabled, the output of the update step is logged to files.
-
- ``LOG_PATCH <bool>``
- .. versionadded:: 3.14
-
- When enabled, the output of the patch step is logged to files.
-
- ``LOG_CONFIGURE <bool>``
- When enabled, the output of the configure step is logged to files.
-
- ``LOG_BUILD <bool>``
- When enabled, the output of the build step is logged to files.
-
- ``LOG_INSTALL <bool>``
- When enabled, the output of the install step is logged to files.
-
- ``LOG_TEST <bool>``
- When enabled, the output of the test step is logged to files.
-
- ``LOG_MERGED_STDOUTERR <bool>``
- .. versionadded:: 3.14
-
- When enabled, stdout and stderr will be merged for any step whose
- output is being logged to files.
-
- ``LOG_OUTPUT_ON_FAILURE <bool>``
- .. versionadded:: 3.14
-
- This option only has an effect if at least one of the other ``LOG_<step>``
- options is enabled. If an error occurs for a step which has logging to
- file enabled, that step's output will be printed to the console if
- ``LOG_OUTPUT_ON_FAILURE`` is set to true. For cases where a large amount
- of output is recorded, just the end of that output may be printed to the
- console.
-
- **Terminal Access Options:**
- .. versionadded:: 3.4
-
- Steps can be given direct access to the terminal in some cases. Giving a
- step access to the terminal may allow it to receive terminal input if
- required, such as for authentication details not provided by other options.
- With the :generator:`Ninja` generator, these options place the steps in the
- ``console`` :prop_gbl:`job pool <JOB_POOLS>`. Each step can be given access
- to the terminal individually via the following options:
-
- ``USES_TERMINAL_DOWNLOAD <bool>``
- Give the download step access to the terminal.
-
- ``USES_TERMINAL_UPDATE <bool>``
- Give the update step access to the terminal.
-
- ``USES_TERMINAL_PATCH <bool>``
- .. versionadded:: 3.23
-
- Give the patch step access to the terminal.
-
- ``USES_TERMINAL_CONFIGURE <bool>``
- Give the configure step access to the terminal.
-
- ``USES_TERMINAL_BUILD <bool>``
- Give the build step access to the terminal.
-
- ``USES_TERMINAL_INSTALL <bool>``
- Give the install step access to the terminal.
-
- ``USES_TERMINAL_TEST <bool>``
- Give the test step access to the terminal.
-
- **Target Options:**
- ``DEPENDS <targets>...``
- Specify other targets on which the external project depends. The other
- targets will be brought up to date before any of the external project's
- steps are executed. Because the external project uses additional custom
- targets internally for each step, the ``DEPENDS`` option is the most
- convenient way to ensure all of those steps depend on the other targets.
- Simply doing
- :command:`add_dependencies(\<name\> \<targets\>) <add_dependencies>` will
- not make any of the steps dependent on ``<targets>``.
-
- ``EXCLUDE_FROM_ALL <bool>``
- When enabled, this option excludes the external project from the default
- ALL target of the main build.
-
- ``STEP_TARGETS <step-target>...``
- Generate custom targets for the specified steps. This is required if the
- steps need to be triggered manually or if they need to be used as
- dependencies of other targets. If this option is not specified, the
- default value is taken from the ``EP_STEP_TARGETS`` directory property.
- See :command:`ExternalProject_Add_StepTargets` below for further
- discussion of the effects of this option.
-
- ``INDEPENDENT_STEP_TARGETS <step-target>...``
- .. deprecated:: 3.19
- This is allowed only if policy :policy:`CMP0114` is not set to ``NEW``.
-
- Generates custom targets for the specified steps and prevent these targets
- from having the usual dependencies applied to them. If this option is not
- specified, the default value is taken from the
- ``EP_INDEPENDENT_STEP_TARGETS`` directory property. This option is mostly
- useful for allowing individual steps to be driven independently, such as
- for a CDash setup where each step should be initiated and reported
- individually rather than as one whole build. See
- :command:`ExternalProject_Add_StepTargets` below for further discussion
- of the effects of this option.
-
- **Miscellaneous Options:**
- ``LIST_SEPARATOR <sep>``
- For any of the various ``..._COMMAND`` options, and ``CMAKE_ARGS``,
- replace ``;`` with ``<sep>`` in the specified command lines.
- This can be useful where list variables may be given in commands where
- they should end up as space-separated arguments (``<sep>`` would be a
- single space character string in this case).
-
- ``COMMAND <cmd>...``
- Any of the other ``..._COMMAND`` options can have additional commands
- appended to them by following them with as many ``COMMAND ...`` options
- as needed
- (:manual:`generator expressions <cmake-generator-expressions(7)>` are
- supported). For example:
-
- .. code-block:: cmake
-
- ExternalProject_Add(example
- ... # Download options, etc.
- BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build"
- COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>
- COMMAND ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete"
- )
+Directory Options
+"""""""""""""""""
+
+Most of the time, the default directory layout is sufficient. It is largely
+an implementation detail that the main project usually doesn't need to
+change. In some circumstances, however, control over the directory layout
+can be useful or necessary. The directory options are potentially more
+useful from the point of view that the main build can use the
+:command:`ExternalProject_Get_Property` command to retrieve their values,
+thereby allowing the main project to refer to build artifacts of the
+external project.
+
+``PREFIX <dir>``
+ Root directory for the external project. Unless otherwise noted below,
+ all other directories associated with the external project will be
+ created under here.
+
+``TMP_DIR <dir>``
+ Directory in which to store temporary files.
+
+``STAMP_DIR <dir>``
+ Directory in which to store the timestamps of each step. Log files from
+ individual steps are also created in here unless overridden by LOG_DIR
+ (see *Logging Options* below).
+
+``LOG_DIR <dir>``
+ .. versionadded:: 3.14
+
+ Directory in which to store the logs of each step.
+
+``DOWNLOAD_DIR <dir>``
+ Directory in which to store downloaded files before unpacking them. This
+ directory is only used by the URL download method, all other download
+ methods use ``SOURCE_DIR`` directly instead.
+
+``SOURCE_DIR <dir>``
+ Source directory into which downloaded contents will be unpacked, or for
+ non-URL download methods, the directory in which the repository should be
+ checked out, cloned, etc. If no download method is specified, this must
+ point to an existing directory where the external project has already
+ been unpacked or cloned/checked out.
+
+ .. note::
+ If a download method is specified, any existing contents of the source
+ directory may be deleted. Only the URL download method checks whether
+ this directory is either missing or empty before initiating the
+ download, stopping with an error if it is not empty. All other
+ download methods silently discard any previous contents of the source
+ directory.
+
+``BINARY_DIR <dir>``
+ Specify the build directory location. This option is ignored if
+ ``BUILD_IN_SOURCE`` is enabled.
+
+``INSTALL_DIR <dir>``
+ Installation prefix to be placed in the ``<INSTALL_DIR>`` placeholder.
+ This does not actually configure the external project to install to
+ the given prefix. That must be done by passing appropriate arguments
+ to the external project configuration step, e.g. using ``<INSTALL_DIR>``.
+
+If any of the above ``..._DIR`` options are not specified, their defaults
+are computed as follows. If the ``PREFIX`` option is given or the
+``EP_PREFIX`` directory property is set, then an external project is built
+and installed under the specified prefix::
+
+ TMP_DIR = <prefix>/tmp
+ STAMP_DIR = <prefix>/src/<name>-stamp
+ DOWNLOAD_DIR = <prefix>/src
+ SOURCE_DIR = <prefix>/src/<name>
+ BINARY_DIR = <prefix>/src/<name>-build
+ INSTALL_DIR = <prefix>
+ LOG_DIR = <STAMP_DIR>
+
+Otherwise, if the ``EP_BASE`` directory property is set then components
+of an external project are stored under the specified base::
+
+ TMP_DIR = <base>/tmp/<name>
+ STAMP_DIR = <base>/Stamp/<name>
+ DOWNLOAD_DIR = <base>/Download/<name>
+ SOURCE_DIR = <base>/Source/<name>
+ BINARY_DIR = <base>/Build/<name>
+ INSTALL_DIR = <base>/Install/<name>
+ LOG_DIR = <STAMP_DIR>
+
+If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified, then the
+default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are
+interpreted with respect to :variable:`CMAKE_CURRENT_BINARY_DIR` at the
+point where ``ExternalProject_Add()`` is called.
+
+Download Step Options
+"""""""""""""""""""""
+
+A download method can be omitted if the ``SOURCE_DIR`` option is used to
+point to an existing non-empty directory. Otherwise, one of the download
+methods below must be specified (multiple download methods should not be
+given) or a custom ``DOWNLOAD_COMMAND`` provided.
+
+``DOWNLOAD_COMMAND <cmd>...``
+ Overrides the command used for the download step
+ (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+ supported). If this option is specified, all other download options will
+ be ignored. Providing an empty string for ``<cmd>`` effectively disables
+ the download step.
+
+URL
+~~~
+
+``URL <url1> [<url2>...]``
+ List of paths and/or URL(s) of the external project's source. When more
+ than one URL is given, they are tried in turn until one succeeds. A URL
+ may be an ordinary path in the local file system (in which case it
+ must be the only URL provided) or any downloadable URL supported by the
+ :command:`file(DOWNLOAD)` command. A local filesystem path may refer to
+ either an existing directory or to an archive file, whereas a URL is
+ expected to point to a file which can be treated as an archive. When an
+ archive is used, it will be unpacked automatically unless the
+ ``DOWNLOAD_NO_EXTRACT`` option is set to prevent it. The archive type
+ is determined by inspecting the actual content rather than using logic
+ based on the file extension.
+
+ .. versionchanged:: 3.7
+ Multiple URLs are allowed.
+
+``URL_HASH <algo>=<hashValue>``
+ Hash of the archive file to be downloaded. The argument should be of
+ the form ``<algo>=<hashValue>`` where ``algo`` can be any of the hashing
+ algorithms supported by the :command:`file()` command. Specifying this
+ option is strongly recommended for URL downloads, as it ensures the
+ integrity of the downloaded content. It is also used as a check for a
+ previously downloaded file, allowing connection to the remote location
+ to be avoided altogether if the local directory already has a file from
+ an earlier download that matches the specified hash.
+
+``URL_MD5 <md5>``
+ Equivalent to ``URL_HASH MD5=<md5>``.
+
+``DOWNLOAD_NAME <fname>``
+ File name to use for the downloaded file. If not given, the end of the
+ URL is used to determine the file name. This option is rarely needed,
+ the default name is generally suitable and is not normally used outside
+ of code internal to the ``ExternalProject`` module.
+
+``DOWNLOAD_EXTRACT_TIMESTAMP <bool>``
+ .. versionadded:: 3.24
+
+ When specified with a true value, the timestamps of the extracted
+ files will match those in the archive. When false, the timestamps of
+ the extracted files will reflect the time at which the extraction
+ was performed. If the download URL changes, timestamps based off
+ those in the archive can result in dependent targets not being rebuilt
+ when they potentially should have been. Therefore, unless the file
+ timestamps are significant to the project in some way, use a false
+ value for this option. If ``DOWNLOAD_EXTRACT_TIMESTAMP`` is not given,
+ the default is false. See policy :policy:`CMP0135`.
+
+``DOWNLOAD_NO_EXTRACT <bool>``
+ .. versionadded:: 3.6
+
+ Allows the extraction part of the download step to be disabled by
+ passing a boolean true value for this option. If this option is not
+ given, the downloaded contents will be unpacked automatically if
+ required. If extraction has been disabled, the full path to the
+ downloaded file is available as ``<DOWNLOADED_FILE>`` in subsequent
+ steps or as the property ``DOWNLOADED_FILE`` with the
+ :command:`ExternalProject_Get_Property` command.
+
+``DOWNLOAD_NO_PROGRESS <bool>``
+ Can be used to disable logging the download progress. If this option is
+ not given, download progress messages will be logged.
+
+``TIMEOUT <seconds>``
+ Maximum time allowed for file download operations.
+
+``INACTIVITY_TIMEOUT <seconds>``
+ .. versionadded:: 3.19
+
+ Terminate the operation after a period of inactivity.
+
+``HTTP_USERNAME <username>``
+ .. versionadded:: 3.7
+
+ Username for the download operation if authentication is required.
+
+``HTTP_PASSWORD <password>``
+ .. versionadded:: 3.7
+
+ Password for the download operation if authentication is required.
+
+``HTTP_HEADER <header1> [<header2>...]``
+ .. versionadded:: 3.7
+
+ Provides an arbitrary list of HTTP headers for the download operation.
+ This can be useful for accessing content in systems like AWS, etc.
+
+``TLS_VERIFY <bool>``
+ Specifies whether certificate verification should be performed for
+ https URLs. If this option is not provided, the default behavior is
+ determined by the :variable:`CMAKE_TLS_VERIFY` variable (see
+ :command:`file(DOWNLOAD)`). If that is also not set, certificate
+ verification will not be performed. In situations where ``URL_HASH``
+ cannot be provided, this option can be an alternative verification
+ measure.
+
+ .. versionchanged:: 3.6
+ This option also applies to ``git clone`` invocations, although the
+ default behavior is different. If ``TLS_VERIFY`` is not given and
+ :variable:`CMAKE_TLS_VERIFY` is not set, the behavior will be
+ determined by git's defaults. Normally, the ``sslVerify`` git
+ config setting defaults to true, but the user may have overridden
+ this at a global level.
+
+``TLS_CAINFO <file>``
+ Specify a custom certificate authority file to use if ``TLS_VERIFY``
+ is enabled. If this option is not specified, the value of the
+ :variable:`CMAKE_TLS_CAINFO` variable will be used instead (see
+ :command:`file(DOWNLOAD)`)
+
+``NETRC <level>``
+ .. versionadded:: 3.11
+
+ Specify whether the ``.netrc`` file is to be used for operation.
+ If this option is not specified, the value of the
+ :variable:`CMAKE_NETRC` variable will be used instead
+ (see :command:`file(DOWNLOAD)`). Valid levels are:
+
+ ``IGNORED``
+ The ``.netrc`` file is ignored.
+ This is the default.
+ ``OPTIONAL``
+ The ``.netrc`` file is optional, and information in the URL
+ is preferred. The file will be scanned to find which ever
+ information is not specified in the URL.
+ ``REQUIRED``
+ The ``.netrc`` file is required, and information in the URL
+ is ignored.
+
+``NETRC_FILE <file>``
+ .. versionadded:: 3.11
+
+ Specify an alternative ``.netrc`` file to the one in your home directory
+ if the ``NETRC`` level is ``OPTIONAL`` or ``REQUIRED``. If this option
+ is not specified, the value of the :variable:`CMAKE_NETRC_FILE` variable
+ will be used instead (see :command:`file(DOWNLOAD)`)
+
+.. versionadded:: 3.1
+ Added support for `tbz2`, `.tar.xz`, `.txz`, and `.7z` extensions.
+
+Git
+~~~
+
+NOTE: A git version of 1.6.5 or later is required if this download method
+is used.
+
+``GIT_REPOSITORY <url>``
+ 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``
+ rather than simply ``myBranch``). This ensures that if the remote end
+ has its tag moved or branch rebased or history rewritten, the local
+ clone will still be updated correctly. In general, however, specifying
+ a commit hash should be preferred for a number of reasons:
+
+ - If the local clone already has the commit corresponding to the hash,
+ no ``git fetch`` needs to be performed to check for changes each time
+ CMake is re-run. This can result in a significant speed up if many
+ external projects are being used.
+ - Using a specific git hash ensures that the main project's own history
+ is fully traceable to a specific point in the external project's
+ evolution. If a branch or tag name is used instead, then checking out
+ a specific commit of the main project doesn't necessarily pin the
+ whole build to a specific point in the life of the external project.
+ The lack of such deterministic behavior makes the main project lose
+ traceability and repeatability.
+
+ If ``GIT_SHALLOW`` is enabled then ``GIT_TAG`` works only with
+ branch names and tags. A commit hash is not allowed.
+
+ Note that if not provided, ``GIT_TAG`` defaults to ``master``, not the
+ default Git branch name.
+
+``GIT_REMOTE_NAME <name>``
+ The optional name of the remote. If this option is not specified, it
+ defaults to ``origin``.
+
+``GIT_SUBMODULES <module>...``
+ Specific git submodules that should also be updated. If this option is
+ not provided, all git submodules will be updated.
+
+ .. versionchanged:: 3.16
+ When :policy:`CMP0097` is set to ``NEW``, if this value is set
+ to an empty string then no submodules are initialized or updated.
+
+``GIT_SUBMODULES_RECURSE <bool>``
+ .. versionadded:: 3.17
+
+ Specify whether git submodules (if any) should update recursively by
+ passing the ``--recursive`` flag to ``git submodule update``.
+ If not specified, the default is on.
+
+``GIT_SHALLOW <bool>``
+ .. versionadded:: 3.6
+
+ When this option is enabled, the ``git clone`` operation will be given
+ the ``--depth 1`` option. This performs a shallow clone, which avoids
+ downloading the whole history and instead retrieves just the commit
+ denoted by the ``GIT_TAG`` option.
+
+``GIT_PROGRESS <bool>``
+ .. versionadded:: 3.8
+
+ When enabled, this option instructs the ``git clone`` operation to
+ report its progress by passing it the ``--progress`` option. Without
+ this option, the clone step for large projects may appear to make the
+ build stall, since nothing will be logged until the clone operation
+ finishes. While this option can be used to provide progress to prevent
+ the appearance of the build having stalled, it may also make the build
+ overly noisy if lots of external projects are used.
+
+``GIT_CONFIG <option1> [<option2>...]``
+ .. versionadded:: 3.8
+
+ Specify a list of config options to pass to ``git clone``. Each option
+ listed will be transformed into its own ``--config <option>`` on the
+ ``git clone`` command line, with each option required to be in the
+ form ``key=value``.
+
+``GIT_REMOTE_UPDATE_STRATEGY <strategy>``
+ .. versionadded:: 3.18
+
+ When ``GIT_TAG`` refers to a remote branch, this option can be used to
+ specify how the update step behaves. The ``<strategy>`` must be one of
+ the following:
+
+ ``CHECKOUT``
+ Ignore the local branch and always checkout the branch specified by
+ ``GIT_TAG``.
+
+ ``REBASE``
+ Try to rebase the current branch to the one specified by ``GIT_TAG``.
+ If there are local uncommitted changes, they will be stashed first
+ and popped again after rebasing. If rebasing or popping stashed
+ changes fail, abort the rebase and halt with an error.
+ When ``GIT_REMOTE_UPDATE_STRATEGY`` is not present, this is the
+ default strategy unless the default has been overridden with
+ ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` (see below).
+ Note that if the branch specified in ``GIT_TAG`` is different to
+ the upstream branch currently being tracked, it is not safe to
+ perform a rebase. In that situation, ``REBASE`` will silently be
+ treated as ``CHECKOUT`` instead.
+
+ ``REBASE_CHECKOUT``
+ Same as ``REBASE`` except if the rebase fails, an annotated tag will
+ be created at the original ``HEAD`` position from before the rebase
+ and then checkout ``GIT_TAG`` just like the ``CHECKOUT`` strategy.
+ The message stored on the annotated tag will give information about
+ what was attempted and the tag name will include a timestamp so that
+ each failed run will add a new tag. This strategy ensures no changes
+ will be lost, but updates should always succeed if ``GIT_TAG`` refers
+ to a valid ref unless there are uncommitted changes that cannot be
+ popped successfully.
+
+ The variable ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` can be set to
+ override the default strategy. This variable should not be set by a
+ project, it is intended for the user to set. It is primarily intended
+ for use in continuous integration scripts to ensure that when history
+ is rewritten on a remote branch, the build doesn't end up with
+ unintended changes or failed builds resulting from conflicts during
+ rebase operations.
+
+Subversion
+~~~~~~~~~~
+
+``SVN_REPOSITORY <url>``
+ URL of the Subversion repository.
+
+``SVN_REVISION -r<rev>``
+ Revision to checkout from the Subversion repository.
+
+``SVN_USERNAME <username>``
+ Username for the Subversion checkout and update.
+
+``SVN_PASSWORD <password>``
+ Password for the Subversion checkout and update.
+
+``SVN_TRUST_CERT <bool>``
+ Specifies whether to trust the Subversion server site certificate. If
+ enabled, the ``--trust-server-cert`` option is passed to the ``svn``
+ checkout and update commands.
+
+Mercurial
+~~~~~~~~~
+
+``HG_REPOSITORY <url>``
+ URL of the mercurial repository.
+
+``HG_TAG <tag>``
+ Mercurial branch name, tag or commit id.
+
+CVS
+~~~
+
+``CVS_REPOSITORY <cvsroot>``
+ CVSROOT of the CVS repository.
+
+``CVS_MODULE <mod>``
+ Module to checkout from the CVS repository.
+
+``CVS_TAG <tag>``
+ Tag to checkout from the CVS repository.
+
+Update Step Options
+"""""""""""""""""""
+
+Whenever CMake is re-run, by default the external project's sources will be
+updated if the download method supports updates (e.g. a git repository
+would be checked if the ``GIT_TAG`` does not refer to a specific commit).
+
+``UPDATE_COMMAND <cmd>...``
+ Overrides the download method's update step with a custom command.
+ The command may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+``UPDATE_DISCONNECTED <bool>``
+ .. versionadded:: 3.2
+
+ When enabled, this option causes the update step to be skipped (but see
+ below for changed behavior where this is not the case). It does not
+ prevent the download step. The update step can still be
+ added as a step target (see :command:`ExternalProject_Add_StepTargets`)
+ and called manually. This is useful if you want to allow developers to
+ build the project when disconnected from the network (the network may
+ still be needed for the download step though).
+
+ .. versionchanged:: 3.27
+
+ When ``UPDATE_DISCONNECTED`` is true, the update step will be executed
+ if any details about the update or download step are changed.
+ Furthermore, if using the git download/update method, the update
+ logic will be modified to skip attempts to contact the remote.
+ If the ``GIT_TAG`` mentions a ref that is not known locally, the
+ update step will halt with a fatal error.
+
+ When this option is present, it is generally advisable to make the value
+ a cache variable under the developer's control rather than hard-coding
+ it. If this option is not present, the default value is taken from the
+ ``EP_UPDATE_DISCONNECTED`` directory property. If that is also not
+ defined, updates are performed as normal. The ``EP_UPDATE_DISCONNECTED``
+ directory property is intended as a convenience for controlling the
+ ``UPDATE_DISCONNECTED`` behavior for an entire section of a project's
+ directory hierarchy and may be a more convenient method of giving
+ developers control over whether or not to perform updates (assuming the
+ project also provides a cache variable or some other convenient method
+ for setting the directory property).
+
+ This may cause a step target to be created automatically for the
+ ``download`` step. See policy :policy:`CMP0114`.
+
+Patch Step Options
+""""""""""""""""""
+
+``PATCH_COMMAND <cmd>...``
+ Specifies a custom command to patch the sources after an update. By
+ default, no patch command is defined. Note that it can be quite difficult
+ to define an appropriate patch command that performs robustly, especially
+ for download methods such as git where changing the ``GIT_TAG`` will not
+ discard changes from a previous patch, but the patch command will be
+ called again after updating to the new tag.
+
+Configure Step Options
+""""""""""""""""""""""
+
+The configure step is run after the download and update steps. By default,
+the external project is assumed to be a CMake project, but this can be
+overridden if required.
+
+``CONFIGURE_COMMAND <cmd>...``
+ The default configure command runs CMake with a few options based on
+ the main project. The options added are typically only those needed to
+ use the same generator as the main project, but the ``CMAKE_GENERATOR``
+ option can be given to override this. The project is responsible for
+ adding any toolchain details, flags or other settings it wants to
+ re-use from the main project or otherwise specify (see ``CMAKE_ARGS``,
+ ``CMAKE_CACHE_ARGS`` and ``CMAKE_CACHE_DEFAULT_ARGS`` below).
+
+ For non-CMake external projects, the ``CONFIGURE_COMMAND`` option must
+ be used to override the default configure command
+ (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+ supported). For projects that require no configure step, specify this
+ option with an empty string as the command to execute.
+
+``CMAKE_COMMAND /.../cmake``
+ Specify an alternative cmake executable for the configure step (use an
+ absolute path). This is generally not recommended, since it is
+ usually desirable to use the same CMake version throughout the whole
+ build. This option is ignored if a custom configure command has been
+ specified with ``CONFIGURE_COMMAND``.
+
+``CMAKE_GENERATOR <gen>``
+ Override the CMake generator used for the configure step. Without this
+ option, the same generator as the main build will be used. This option is
+ ignored if a custom configure command has been specified with the
+ ``CONFIGURE_COMMAND`` option.
+
+``CMAKE_GENERATOR_PLATFORM <platform>``
+ .. versionadded:: 3.1
+
+ Pass a generator-specific platform name to the CMake command (see
+ :variable:`CMAKE_GENERATOR_PLATFORM`). It is an error to provide this
+ option without the ``CMAKE_GENERATOR`` option.
+
+``CMAKE_GENERATOR_TOOLSET <toolset>``
+ Pass a generator-specific toolset name to the CMake command (see
+ :variable:`CMAKE_GENERATOR_TOOLSET`). It is an error to provide this
+ option without the ``CMAKE_GENERATOR`` option.
+
+``CMAKE_GENERATOR_INSTANCE <instance>``
+ .. versionadded:: 3.11
+
+ Pass a generator-specific instance selection to the CMake command (see
+ :variable:`CMAKE_GENERATOR_INSTANCE`). It is an error to provide this
+ option without the ``CMAKE_GENERATOR`` option.
+
+``CMAKE_ARGS <arg>...``
+ The specified arguments are passed to the :program:`cmake` command line.
+ They can be any argument the :program:`cmake` command understands, not just
+ cache values defined by ``-D...`` arguments (see also
+ :manual:`CMake Options <cmake(1)>`).
+
+ .. versionadded:: 3.3
+ Arguments may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+``CMAKE_CACHE_ARGS <arg>...``
+ This is an alternate way of specifying cache variables where command line
+ length issues may become a problem. The arguments are expected to be in
+ the form ``-Dvar:STRING=value``, which are then transformed into
+ CMake :command:`set` commands with the ``FORCE`` option used. These
+ ``set()`` commands are written to a pre-load script which is then applied
+ using the :manual:`cmake -C <cmake(1)>` command line option.
+
+ .. versionadded:: 3.3
+ Arguments may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
+ .. versionadded:: 3.2
+
+ This is the same as the ``CMAKE_CACHE_ARGS`` option except the ``set()``
+ commands do not include the ``FORCE`` keyword. This means the values act
+ as initial defaults only and will not override any variables already set
+ from a previous run. Use this option with care, as it can lead to
+ different behavior depending on whether the build starts from a fresh
+ build directory or re-uses previous build contents.
+
+ .. versionadded:: 3.15
+ If the CMake generator is the ``Green Hills MULTI`` and not overridden,
+ the original project's settings for the GHS toolset and target system
+ customization cache variables are propagated into the external project.
+
+``SOURCE_SUBDIR <dir>``
+ .. versionadded:: 3.7
+
+ When no ``CONFIGURE_COMMAND`` option is specified, the configure step
+ assumes the external project has a ``CMakeLists.txt`` file at the top of
+ its source tree (i.e. in ``SOURCE_DIR``). The ``SOURCE_SUBDIR`` option
+ can be used to point to an alternative directory within the source tree
+ to use as the top of the CMake source tree instead. This must be a
+ relative path and it will be interpreted as being relative to
+ ``SOURCE_DIR``.
+
+ .. versionadded:: 3.14
+ When ``BUILD_IN_SOURCE`` option is enabled, the ``BUILD_COMMAND``
+ is used to point to an alternative directory within the source tree.
+
+``CONFIGURE_HANDLED_BY_BUILD <bool>``
+ .. versionadded:: 3.20
+
+ Enabling this option relaxes the dependencies of the configure step on
+ other external projects to order-only. This means the configure step will
+ be executed after its external project dependencies are built but it will
+ not be marked dirty when one of its external project dependencies is
+ rebuilt. This option can be enabled when the build step is smart enough
+ to figure out if the configure step needs to be rerun. CMake and Meson are
+ examples of build systems whose build step is smart enough to know if the
+ configure step needs to be rerun.
+
+Build Step Options
+""""""""""""""""""
+
+If the configure step assumed the external project uses CMake as its build
+system, the build step will also. Otherwise, the build step will assume a
+Makefile-based build and simply run ``make`` with no arguments as the
+default build step. This can be overridden with custom build commands if
+required.
+
+If both the main project and the external project use make as their build
+tool, the build step of the external project is invoked as a recursive
+make using ``$(MAKE)``. This will communicate some build tool settings
+from the main project to the external project. If either the main project
+or external project is not using make, no build tool settings will be
+passed to the external project other than those established by the
+configure step (i.e. running ``ninja -v`` in the main project will not
+pass ``-v`` to the external project's build step, even if it also uses
+``ninja`` as its build tool).
+
+``BUILD_COMMAND <cmd>...``
+ Overrides the default build command
+ (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+ supported). If this option is not given, the default build command will
+ be chosen to integrate with the main build in the most appropriate way
+ (e.g. using recursive ``make`` for Makefile generators or
+ :option:`cmake --build` if the project uses a CMake build). This option
+ can be specified with an empty string as the command to make the build
+ step do nothing.
+
+``BUILD_IN_SOURCE <bool>``
+ When this option is enabled, the build will be done directly within the
+ external project's source tree. This should generally be avoided, the use
+ of a separate build directory is usually preferred, but it can be useful
+ when the external project assumes an in-source build. The ``BINARY_DIR``
+ option should not be specified if building in-source.
+
+``BUILD_ALWAYS <bool>``
+ Enabling this option forces the build step to always be run. This can be
+ the easiest way to robustly ensure that the external project's own build
+ dependencies are evaluated rather than relying on the default
+ success timestamp-based method. This option is not normally needed unless
+ developers are expected to modify something the external project's build
+ depends on in a way that is not detectable via the step target
+ dependencies (e.g. ``SOURCE_DIR`` is used without a download method and
+ developers might modify the sources in ``SOURCE_DIR``).
+
+``BUILD_BYPRODUCTS <file>...``
+ .. versionadded:: 3.2
+
+ Specifies files that will be generated by the build command but which
+ might or might not have their modification time updated by subsequent
+ builds. This may also be required to explicitly declare dependencies
+ when using the :generator:`Ninja` generator.
+ These ultimately get passed through as ``BYPRODUCTS`` to the
+ build step's own underlying call to :command:`add_custom_command`, which
+ has additional documentation.
+
+``BUILD_JOB_SERVER_AWARE <bool>``
+ .. versionadded:: 3.28
+
+ Specifies that the build step is aware of the GNU Make job server.
+ See the :command:`add_custom_command` documentation of its
+ ``JOB_SERVER_AWARE`` option for details. This option is relevant
+ only when an explicit ``BUILD_COMMAND`` is specified.
+
+Install Step Options
+""""""""""""""""""""
+
+If the configure step assumed the external project uses CMake as its build
+system, the install step will also. Otherwise, the install step will assume
+a Makefile-based build and simply run ``make install`` as the default build
+step. This can be overridden with custom install commands if required.
+
+``INSTALL_COMMAND <cmd>...``
+ The external project's own install step is invoked as part of the main
+ project's *build*. It is done after the external project's build step
+ and may be before or after the external project's test step (see the
+ ``TEST_BEFORE_INSTALL`` option below). The external project's install
+ rules are not part of the main project's install rules, so if anything
+ from the external project should be installed as part of the main build,
+ these need to be specified in the main build as additional
+ :command:`install` commands. The default install step builds the
+ ``install`` target of the external project, but this can be overridden
+ with a custom command using this option
+ (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+ supported). Passing an empty string as the ``<cmd>`` makes the install
+ step do nothing.
+
+``INSTALL_BYPRODUCTS <file>...``
+ .. versionadded:: 3.26
+
+ Specifies files that will be generated by the install command but which
+ might or might not have their modification time updated by subsequent
+ installs. This may also be required to explicitly declare dependencies
+ when using the :generator:`Ninja` generator.
+ These ultimately get passed through as ``BYPRODUCTS`` to the
+ install step's own underlying call to :command:`add_custom_command`, which
+ has additional documentation.
+
+.. note::
+ If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
+ main project is built, it will only have an effect if the following
+ conditions are met:
+
+ * The main project's configure step assumed the external project uses
+ CMake as its build system.
+ * The external project's install command actually runs. Note that due
+ to the way ``ExternalProject`` may use timestamps internally, if
+ nothing the install step depends on needs to be re-executed, the
+ install command might also not need to run.
+
+ Note also that ``ExternalProject`` does not check whether the
+ :envvar:`CMAKE_INSTALL_MODE` environment variable changes from one run
+ to another.
+
+Test Step Options
+"""""""""""""""""
+
+The test step is only defined if at least one of the following ``TEST_...``
+options are provided.
+
+``TEST_COMMAND <cmd>...``
+ Overrides the default test command
+ (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+ supported). If this option is not given, the default behavior of the test
+ step is to build the external project's own ``test`` target. This option
+ can be specified with ``<cmd>`` as an empty string, which allows the test
+ step to still be defined, but it will do nothing. Do not specify any of
+ the other ``TEST_...`` options if providing an empty string as the test
+ command, but prefer to omit all ``TEST_...`` options altogether if the
+ test step target is not needed.
+
+``TEST_BEFORE_INSTALL <bool>``
+ When this option is enabled, the test step will be executed before the
+ install step. The default behavior is for the test step to run after the
+ install step.
+
+``TEST_AFTER_INSTALL <bool>``
+ This option is mainly useful as a way to indicate that the test step is
+ desired but all default behavior is sufficient. Specifying this option
+ with a boolean true value ensures the test step is defined and that it
+ comes after the install step. If both ``TEST_BEFORE_INSTALL`` and
+ ``TEST_AFTER_INSTALL`` are enabled, the latter is silently ignored.
+
+``TEST_EXCLUDE_FROM_MAIN <bool>``
+ .. versionadded:: 3.2
+
+ If enabled, the main build's default ALL target will not depend on the
+ test step. This can be a useful way of ensuring the test step is defined
+ but only gets invoked when manually requested.
+ This may cause a step target to be created automatically for either
+ the ``install`` or ``build`` step. See policy :policy:`CMP0114`.
+
+Output Logging Options
+""""""""""""""""""""""
+
+Each of the following ``LOG_...`` options can be used to wrap the relevant
+step in a script to capture its output to files. The log files will be
+created in ``LOG_DIR`` if supplied or otherwise the ``STAMP_DIR``
+directory with step-specific file names.
+
+``LOG_DOWNLOAD <bool>``
+ When enabled, the output of the download step is logged to files.
+
+``LOG_UPDATE <bool>``
+ When enabled, the output of the update step is logged to files.
+
+``LOG_PATCH <bool>``
+ .. versionadded:: 3.14
+
+ When enabled, the output of the patch step is logged to files.
- It should also be noted that each build step is created via a call to
- :command:`ExternalProject_Add_Step`. See that command's documentation for the
- automatic substitutions that are supported for some options.
+``LOG_CONFIGURE <bool>``
+ When enabled, the output of the configure step is logged to files.
+
+``LOG_BUILD <bool>``
+ When enabled, the output of the build step is logged to files.
+
+``LOG_INSTALL <bool>``
+ When enabled, the output of the install step is logged to files.
+
+``LOG_TEST <bool>``
+ When enabled, the output of the test step is logged to files.
+
+``LOG_MERGED_STDOUTERR <bool>``
+ .. versionadded:: 3.14
+
+ When enabled, stdout and stderr will be merged for any step whose
+ output is being logged to files.
+
+``LOG_OUTPUT_ON_FAILURE <bool>``
+ .. versionadded:: 3.14
+
+ This option only has an effect if at least one of the other ``LOG_<step>``
+ options is enabled. If an error occurs for a step which has logging to
+ file enabled, that step's output will be printed to the console if
+ ``LOG_OUTPUT_ON_FAILURE`` is set to true. For cases where a large amount
+ of output is recorded, just the end of that output may be printed to the
+ console.
+
+Terminal Access Options
+"""""""""""""""""""""""
+
+.. versionadded:: 3.4
+
+Steps can be given direct access to the terminal in some cases. Giving a
+step access to the terminal may allow it to receive terminal input if
+required, such as for authentication details not provided by other options.
+With the :generator:`Ninja` generator, these options place the steps in the
+``console`` :prop_gbl:`job pool <JOB_POOLS>`. Each step can be given access
+to the terminal individually via the following options:
+
+``USES_TERMINAL_DOWNLOAD <bool>``
+ Give the download step access to the terminal.
+
+``USES_TERMINAL_UPDATE <bool>``
+ Give the update step access to the terminal.
+
+``USES_TERMINAL_PATCH <bool>``
+ .. versionadded:: 3.23
+
+ Give the patch step access to the terminal.
+
+``USES_TERMINAL_CONFIGURE <bool>``
+ Give the configure step access to the terminal.
+
+``USES_TERMINAL_BUILD <bool>``
+ Give the build step access to the terminal.
+
+``USES_TERMINAL_INSTALL <bool>``
+ Give the install step access to the terminal.
+
+``USES_TERMINAL_TEST <bool>``
+ Give the test step access to the terminal.
+
+Target Options
+""""""""""""""
+
+``DEPENDS <targets>...``
+ Specify other targets on which the external project depends. The other
+ targets will be brought up to date before any of the external project's
+ steps are executed. Because the external project uses additional custom
+ targets internally for each step, the ``DEPENDS`` option is the most
+ convenient way to ensure all of those steps depend on the other targets.
+ Simply doing
+ :command:`add_dependencies(\<name\> \<targets\>) <add_dependencies>` will
+ not make any of the steps dependent on ``<targets>``.
+
+``EXCLUDE_FROM_ALL <bool>``
+ When enabled, this option excludes the external project from the default
+ ALL target of the main build.
+
+``STEP_TARGETS <step-target>...``
+ Generate custom targets for the specified steps. This is required if the
+ steps need to be triggered manually or if they need to be used as
+ dependencies of other targets. If this option is not specified, the
+ default value is taken from the ``EP_STEP_TARGETS`` directory property.
+ See :command:`ExternalProject_Add_StepTargets` below for further
+ discussion of the effects of this option.
+
+``INDEPENDENT_STEP_TARGETS <step-target>...``
+ .. deprecated:: 3.19
+ This is allowed only if policy :policy:`CMP0114` is not set to ``NEW``.
+
+ Generates custom targets for the specified steps and prevent these targets
+ from having the usual dependencies applied to them. If this option is not
+ specified, the default value is taken from the
+ ``EP_INDEPENDENT_STEP_TARGETS`` directory property. This option is mostly
+ useful for allowing individual steps to be driven independently, such as
+ for a CDash setup where each step should be initiated and reported
+ individually rather than as one whole build. See
+ :command:`ExternalProject_Add_StepTargets` below for further discussion
+ of the effects of this option.
+
+Miscellaneous Options
+"""""""""""""""""""""
+
+``LIST_SEPARATOR <sep>``
+ For any of the various ``..._COMMAND`` options, and ``CMAKE_ARGS``,
+ replace ``;`` with ``<sep>`` in the specified command lines.
+ This can be useful where list variables may be given in commands where
+ they should end up as space-separated arguments (``<sep>`` would be a
+ single space character string in this case).
+
+``COMMAND <cmd>...``
+ Any of the other ``..._COMMAND`` options can have additional commands
+ appended to them by following them with as many ``COMMAND ...`` options
+ as needed
+ (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+ supported). For example:
+
+ .. code-block:: cmake
+
+ ExternalProject_Add(example
+ ... # Download options, etc.
+ BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build"
+ COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>
+ COMMAND ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete"
+ )
+
+It should also be noted that each build step is created via a call to
+:command:`ExternalProject_Add_Step`. See that command's documentation for the
+automatic substitutions that are supported for some options.
Obtaining Project Properties
-""""""""""""""""""""""""""""
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. command:: ExternalProject_Get_Property
@@ -914,7 +953,7 @@ Obtaining Project Properties
message("Source dir of myExtProj = ${SOURCE_DIR}")
Explicit Step Management
-""""""""""""""""""""""""
+^^^^^^^^^^^^^^^^^^^^^^^^
The ``ExternalProject_Add()`` function on its own is often sufficient for
incorporating an external project into the main build. Certain scenarios
@@ -990,6 +1029,13 @@ control needed to implement such step-level capabilities.
When enabled, this option specifies that the custom step should always be
run (i.e. that it is always considered out of date).
+ ``JOB_SERVER_AWARE <bool>``
+ .. versionadded:: 3.28
+
+ Specifies that the custom step is aware of the GNU Make job server.
+ See the :command:`add_custom_command` documentation of its
+ ``JOB_SERVER_AWARE`` option for details.
+
``EXCLUDE_FROM_MAIN <bool>``
When enabled, this option specifies that the external project's main target
does not depend on the custom step.
@@ -2335,6 +2381,7 @@ function(ExternalProject_Add_Step name step)
INDEPENDENT
BYPRODUCTS
ALWAYS
+ JOB_SERVER_AWARE
EXCLUDE_FROM_MAIN
WORKING_DIRECTORY
LOG
@@ -2514,6 +2561,16 @@ function(ExternalProject_Add_Step name step)
set(maybe_COMMAND_touch "COMMAND \${CMAKE_COMMAND} -E touch \${stamp_file}")
endif()
+ get_property(job_server_aware
+ TARGET ${name}
+ PROPERTY _EP_${step}_JOB_SERVER_AWARE
+ )
+ if(job_server_aware)
+ set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
+ else()
+ set(maybe_JOB_SERVER_AWARE "")
+ endif()
+
# Wrap with log script?
get_property(log TARGET ${name} PROPERTY _EP_${step}_LOG)
if(command AND log)
@@ -2540,6 +2597,7 @@ function(ExternalProject_Add_Step name step)
COMMENT \${comment}
COMMAND ${__cmdQuoted}
${maybe_COMMAND_touch}
+ ${maybe_JOB_SERVER_AWARE}
DEPENDS \${depends}
WORKING_DIRECTORY \${work_dir}
VERBATIM
@@ -2811,7 +2869,8 @@ function(_ep_add_download_command name)
TARGET ${name}
PROPERTY _EP_USES_TERMINAL_DOWNLOAD
)
- if(uses_terminal)
+ # The --trust-server-cert option requires --non-interactive
+ if(uses_terminal AND NOT svn_trust_cert)
set(svn_interactive_args "")
else()
set(svn_interactive_args "--non-interactive")
@@ -3299,7 +3358,8 @@ function(_ep_add_update_command name)
get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD)
get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT)
get_property(uses_terminal TARGET ${name} PROPERTY _EP_USES_TERMINAL_UPDATE)
- if(uses_terminal)
+ # The --trust-server-cert option requires --non-interactive
+ if(uses_terminal AND NOT svn_trust_cert)
set(svn_interactive_args "")
else()
set(svn_interactive_args "--non-interactive")
@@ -3914,6 +3974,17 @@ function(_ep_add_build_command name)
PROPERTY _EP_BUILD_BYPRODUCTS
)
+ get_property(build_job_server_aware
+ TARGET ${name}
+ PROPERTY _EP_BUILD_JOB_SERVER_AWARE
+ )
+ if(build_job_server_aware)
+ set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
+ else()
+ set(maybe_JOB_SERVER_AWARE "")
+ endif()
+
+
set(__cmdQuoted)
foreach(__item IN LISTS cmd)
string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -3927,6 +3998,7 @@ function(_ep_add_build_command name)
DEPENDEES configure
DEPENDS \${file_deps}
ALWAYS \${always}
+ ${maybe_JOB_SERVER_AWARE}
${log}
${uses_terminal}
)"
@@ -4221,6 +4293,7 @@ function(ExternalProject_Add name)
BUILD_IN_SOURCE
BUILD_ALWAYS
BUILD_BYPRODUCTS
+ BUILD_JOB_SERVER_AWARE
#
# Install step options
#
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index f2e4804..1f82bb5 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -1365,7 +1365,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret)
set(_Boost_TIMER_DEPENDENCIES chrono)
set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- else()
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.83.0)
set(_Boost_CONTRACT_DEPENDENCIES thread chrono)
set(_Boost_COROUTINE_DEPENDENCIES context)
set(_Boost_FIBER_DEPENDENCIES context)
@@ -1380,7 +1380,21 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret)
set(_Boost_TIMER_DEPENDENCIES chrono)
set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.83.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)
+ else()
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono)
+ set(_Boost_COROUTINE_DEPENDENCIES context)
+ set(_Boost_FIBER_DEPENDENCIES context)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_JSON_DEPENDENCIES container)
+ set(_Boost_LOG_DEPENDENCIES log_setup filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_THREAD_DEPENDENCIES chrono atomic)
+ set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.84.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)
message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
endif()
endif()
@@ -1655,7 +1669,7 @@ else()
# _Boost_COMPONENT_HEADERS. See the instructions at the top of
# _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
- "1.82.0" "1.82" "1.81.0" "1.81" "1.80.0" "1.80" "1.79.0" "1.79"
+ "1.83.0" "1.83" "1.82.0" "1.82" "1.81.0" "1.81" "1.80.0" "1.80" "1.79.0" "1.79"
"1.78.0" "1.78" "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" "1.74.0" "1.74"
"1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
"1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index c2627e7..12aca8d 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -965,12 +965,15 @@ if(CUDAToolkit_FOUND)
# search paths without symlinks
if(CUDAToolkit_LIBRARY_DIR MATCHES ".*/cuda/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64$")
# Search location for math_libs/
- file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../" _cmake_search_dir)
- list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
-
- # Search location for extras like cupti
- file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../" _cmake_search_dir)
- list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
+ block(SCOPE_FOR POLICIES)
+ cmake_policy(SET CMP0152 NEW)
+ file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../../../" _cmake_search_dir)
+ list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
+
+ # Search location for extras like cupti
+ file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../" _cmake_search_dir)
+ list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
+ endblock()
endif()
# If no `CUDAToolkit_LIBRARY_ROOT` exists set it based on CUDAToolkit_LIBRARY_DIR
@@ -1009,17 +1012,26 @@ if(CUDAToolkit_FOUND)
)
# Don't try any stub directories until we have exhausted all other
# search locations.
- find_library(CUDA_${lib_name}_LIBRARY
- NAMES ${search_names}
- HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
- ENV CUDA_PATH
- PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
- )
+ set(CUDA_IMPORT_PROPERTY IMPORTED_LOCATION)
+ set(CUDA_IMPORT_TYPE UNKNOWN)
+ if(NOT CUDA_${lib_name}_LIBRARY)
+ find_library(CUDA_${lib_name}_LIBRARY
+ NAMES ${search_names}
+ HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
+ ENV CUDA_PATH
+ PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
+ )
+ if(CUDA_${lib_name}_LIBRARY AND NOT WIN32)
+ # Use `IMPORTED_IMPLIB` so that we don't add a `-rpath` entry for stub directories
+ set(CUDA_IMPORT_PROPERTY IMPORTED_IMPLIB)
+ set(CUDA_IMPORT_TYPE SHARED)
+ endif()
+ endif()
mark_as_advanced(CUDA_${lib_name}_LIBRARY)
if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY)
- add_library(CUDA::${lib_name} UNKNOWN IMPORTED)
+ add_library(CUDA::${lib_name} ${CUDA_IMPORT_TYPE} IMPORTED)
target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
if(DEFINED CUDAToolkit_MATH_INCLUDE_DIR)
string(FIND ${CUDA_${lib_name}_LIBRARY} "math_libs" math_libs)
@@ -1027,7 +1039,7 @@ if(CUDAToolkit_FOUND)
target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_MATH_INCLUDE_DIR}")
endif()
endif()
- set_property(TARGET CUDA::${lib_name} PROPERTY IMPORTED_LOCATION "${CUDA_${lib_name}_LIBRARY}")
+ set_property(TARGET CUDA::${lib_name} PROPERTY ${CUDA_IMPORT_PROPERTY} "${CUDA_${lib_name}_LIBRARY}")
foreach(dep ${arg_DEPS})
if(TARGET CUDA::${dep})
target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep})
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index acb87dc..2f33dac 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -58,6 +58,18 @@ returns its results with no further action.
Set ``CURL_NO_CURL_CMAKE`` to ``ON`` to disable this search.
+Hints
+^^^^^
+
+``CURL_USE_STATIC_LIBS``
+
+ .. versionadded:: 3.28
+
+ Set to ``TRUE`` to use static libraries.
+
+ This is meaningful only when CURL is not found via its
+ CMake Package Configuration file.
+
#]=======================================================================]
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
@@ -193,6 +205,11 @@ if(CURL_FOUND)
set_target_properties(CURL::libcurl PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}")
+ if(CURL_USE_STATIC_LIBS)
+ set_property(TARGET CURL::libcurl APPEND PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
+ endif()
+
if(EXISTS "${CURL_LIBRARY}")
set_target_properties(CURL::libcurl PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
@@ -212,5 +229,11 @@ if(CURL_FOUND)
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}")
endif()
+
+ if(CURL_USE_STATIC_LIBS AND MSVC)
+ set_target_properties(CURL::libcurl PROPERTIES
+ INTERFACE_LINK_LIBRARIES "normaliz.lib;ws2_32.lib;wldap32.lib")
+ endif()
+
endif()
endif()
diff --git a/Modules/FindEXPAT.cmake b/Modules/FindEXPAT.cmake
index 3bedc73..762931e 100644
--- a/Modules/FindEXPAT.cmake
+++ b/Modules/FindEXPAT.cmake
@@ -30,6 +30,15 @@ This module will set the following variables in your project:
``EXPAT_FOUND``
true if the Expat headers and libraries were found.
+Hints
+^^^^^
+
+``EXPAT_USE_STATIC_LIBS``
+
+ .. versionadded:: 3.28
+
+ Set to ``TRUE`` to use static libraries.
+
#]=======================================================================]
find_package(PkgConfig QUIET)
@@ -43,8 +52,13 @@ set(EXPAT_NAMES expat expatw)
set(EXPAT_NAMES_DEBUG expatd expatwd)
if(WIN32)
- list(APPEND EXPAT_NAMES expatMT expatMD expatwMT expatwMD)
- list(APPEND EXPAT_NAMES_DEBUG expatdMT expatdMD expatwdMT expatwdMD)
+ if(EXPAT_USE_STATIC_LIBS)
+ list(APPEND EXPAT_NAMES expatMT expatwMT)
+ list(APPEND EXPAT_NAMES_DEBUG expatdMT expatwdMT)
+ else()
+ list(APPEND EXPAT_NAMES expatMT expatMD expatwMT expatwMD)
+ list(APPEND EXPAT_NAMES_DEBUG expatdMT expatdMD expatwdMT expatwdMD)
+ endif()
endif()
# Allow EXPAT_LIBRARY to be set manually, as the location of the expat library
@@ -115,6 +129,11 @@ if(EXPAT_FOUND)
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
INTERFACE_INCLUDE_DIRECTORIES "${EXPAT_INCLUDE_DIRS}")
+ if(EXPAT_USE_STATIC_LIBS)
+ set_property(TARGET EXPAT::EXPAT APPEND PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS "XML_STATIC")
+ endif()
+
if(EXPAT_LIBRARY_RELEASE)
set_property(TARGET EXPAT::EXPAT APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
diff --git a/Modules/FindFLTK.cmake b/Modules/FindFLTK.cmake
index d54d2f6..a245c6c 100644
--- a/Modules/FindFLTK.cmake
+++ b/Modules/FindFLTK.cmake
@@ -232,7 +232,7 @@ else()
find_program(FLTK_CONFIG_SCRIPT fltk-config PATHS ${FLTK_BIN_DIR})
if(FLTK_CONFIG_SCRIPT)
if(NOT FLTK_INCLUDE_DIR)
- exec_program(${FLTK_CONFIG_SCRIPT} ARGS --cxxflags OUTPUT_VARIABLE FLTK_CXXFLAGS)
+ execute_process(COMMAND ${FLTK_CONFIG_SCRIPT} --cxxflags OUTPUT_VARIABLE FLTK_CXXFLAGS)
if(FLTK_CXXFLAGS)
string(REGEX MATCHALL "-I[^ ]*" _fltk_temp_dirs ${FLTK_CXXFLAGS})
string(REPLACE "-I" "" _fltk_temp_dirs "${_fltk_temp_dirs}")
@@ -256,7 +256,7 @@ else()
# Try to find FLTK library
if(UNIX)
if(FLTK_CONFIG_SCRIPT)
- exec_program(${FLTK_CONFIG_SCRIPT} ARGS --libs OUTPUT_VARIABLE _FLTK_POSSIBLE_LIBS)
+ execute_process(COMMAND ${FLTK_CONFIG_SCRIPT} --libs OUTPUT_VARIABLE _FLTK_POSSIBLE_LIBS)
if(_FLTK_POSSIBLE_LIBS)
get_filename_component(_FLTK_POSSIBLE_LIBRARY_DIR ${_FLTK_POSSIBLE_LIBS} PATH)
endif()
@@ -292,12 +292,12 @@ else()
# Find the extra libraries needed for the fltk_images library.
if(UNIX)
if(FLTK_CONFIG_SCRIPT)
- exec_program(${FLTK_CONFIG_SCRIPT} ARGS --use-images --ldflags
+ execute_process(COMMAND ${FLTK_CONFIG_SCRIPT} --use-images --ldflags
OUTPUT_VARIABLE FLTK_IMAGES_LDFLAGS)
set(FLTK_LIBS_EXTRACT_REGEX ".*-lfltk_images (.*) -lfltk.*")
if("${FLTK_IMAGES_LDFLAGS}" MATCHES "${FLTK_LIBS_EXTRACT_REGEX}")
string(REGEX REPLACE " +" ";" FLTK_IMAGES_LIBS "${CMAKE_MATCH_1}")
- # The EXEC_PROGRAM will not be inherited into subdirectories from
+ # The execute_process() will not be inherited into subdirectories from
# the file that originally included this module. Save the answer.
set(FLTK_IMAGES_LIBS "${FLTK_IMAGES_LIBS}" CACHE INTERNAL
"Extra libraries for fltk_images library.")
diff --git a/Modules/FindFLTK2.cmake b/Modules/FindFLTK2.cmake
index a43f7a4..2f6e41d 100644
--- a/Modules/FindFLTK2.cmake
+++ b/Modules/FindFLTK2.cmake
@@ -191,12 +191,12 @@ if(FLTK2_DIR)
if(UNIX)
find_program(FLTK2_CONFIG_SCRIPT fltk2-config PATHS ${FLTK2_BIN_DIR})
if(FLTK2_CONFIG_SCRIPT)
- exec_program(${FLTK2_CONFIG_SCRIPT} ARGS --use-images --ldflags
+ execute_process(COMMAND ${FLTK2_CONFIG_SCRIPT} --use-images --ldflags
OUTPUT_VARIABLE FLTK2_IMAGES_LDFLAGS)
set(FLTK2_LIBS_EXTRACT_REGEX ".*-lfltk2_images (.*) -lfltk2.*")
if("${FLTK2_IMAGES_LDFLAGS}" MATCHES "${FLTK2_LIBS_EXTRACT_REGEX}")
string(REGEX REPLACE " +" ";" FLTK2_IMAGES_LIBS "${CMAKE_MATCH_1}")
- # The EXEC_PROGRAM will not be inherited into subdirectories from
+ # The execute_process() will not be inherited into subdirectories from
# the file that originally included this module. Save the answer.
set(FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LIBS}" CACHE INTERNAL
"Extra libraries for fltk_images library.")
diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake
index 82885cb..dcf271d 100644
--- a/Modules/FindFreetype.cmake
+++ b/Modules/FindFreetype.cmake
@@ -65,6 +65,64 @@ directory of a Freetype installation.
# I'm going to attempt to cut out the middleman and hope
# everything still works.
+set(_Freetype_args)
+if (Freetype_FIND_QUIETLY)
+ list(APPEND _Freetype_args
+ QUIET)
+endif ()
+if (Freetype_FIND_VERSION)
+ list(APPEND _Freetype_args
+ "${Freetype_FIND_VERSION}")
+ if (Freetype_FIND_VERSION_EXACT)
+ list(APPEND _Freetype_args
+ EXACT)
+ endif ()
+endif ()
+set(_Freetype_component_req)
+set(_Freetype_component_opt)
+foreach (_Freetype_component IN LISTS Freetype_FIND_COMPONENTS)
+ if (Freetype_FIND_REQUIRE_${_Freetype_component})
+ list(APPEND _Freetype_component_req
+ "${_Freetype_component}")
+ else ()
+ list(APPEND _Freetype_component_opt
+ "${_Freetype_component}")
+ endif ()
+endforeach ()
+unset(_Freetype_component)
+if (_Freetype_component_req)
+ list(APPEND _Freetype_args
+ COMPONENTS "${_Freetype_component_req}")
+endif ()
+unset(_Freetype_component_req)
+if (_Freetype_component_opt)
+ list(APPEND _Freetype_args
+ OPTIONAL_COMPONENTS "${_Freetype_component_opt}")
+endif ()
+unset(_Freetype_component_opt)
+find_package(freetype CONFIG ${_Freetype_args})
+unset(_Freetype_args)
+if (freetype_FOUND)
+ if (NOT TARGET Freetype::Freetype)
+ add_library(Freetype::Freetype IMPORTED INTERFACE)
+ set_target_properties(Freetype::Freetype PROPERTIES
+ INTERFACE_LINK_LIBRARIES freetype)
+ endif ()
+ get_property(FREETYPE_INCLUDE_DIRS TARGET freetype PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+ get_property(FREETYPE_LIBRARIES TARGET freetype PROPERTY INTERFACE_LINK_LIBRARIES)
+ get_property(_Freetype_location TARGET freetype PROPERTY LOCATION)
+ list(APPEND FREETYPE_LIBRARIES
+ "${_Freetype_location}")
+ unset(_Freetype_location)
+ set(Freetype_FOUND 1)
+ set(FREETYPE_VERSION_STRING "${freetype_VERSION}")
+ foreach (_Freetype_component IN LISTS Freetype_FIND_COMPONENTS)
+ set(Freetype_${_Freetype_component}_FOUND "${freetype_${_Freetype_component}_FOUND}")
+ endforeach ()
+ unset(_Freetype_component)
+ return ()
+endif ()
+
set(FREETYPE_FIND_ARGS
HINTS
ENV FREETYPE_DIR
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index bfde40b..dff53e1 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -126,6 +126,10 @@ function(__glew_set_find_library_suffix shared_or_static)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so" PARENT_SCOPE)
elseif(APPLE AND "${shared_or_static}" MATCHES "STATIC")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
+ elseif(WIN32 AND MINGW AND "${shared_or_static}" MATCHES "SHARED")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" PARENT_SCOPE)
+ elseif(WIN32 AND MINGW AND "${shared_or_static}" MATCHES "STATIC")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
elseif(WIN32 AND "${shared_or_static}" MATCHES "SHARED")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" PARENT_SCOPE)
elseif(WIN32 AND "${shared_or_static}" MATCHES "STATIC")
diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake
index 09403bc..613d315 100644
--- a/Modules/FindGLUT.cmake
+++ b/Modules/FindGLUT.cmake
@@ -107,18 +107,8 @@ elseif(APPLE)
if(GLUT_cocoa_LIBRARY AND NOT TARGET GLUT::Cocoa)
add_library(GLUT::Cocoa UNKNOWN IMPORTED)
- # Cocoa should always be a Framework, but we check to make sure.
- if(GLUT_cocoa_LIBRARY MATCHES "/([^/]+)\\.framework$")
- set(_glut_cocoa "${GLUT_cocoa_LIBRARY}/${CMAKE_MATCH_1}")
- if(EXISTS "${_glut_cocoa}.tbd")
- string(APPEND _glut_cocoa ".tbd")
- endif()
- set_target_properties(GLUT::Cocoa PROPERTIES
- IMPORTED_LOCATION "${_glut_cocoa}")
- else()
- set_target_properties(GLUT::Cocoa PROPERTIES
- IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}")
- endif()
+ set_target_properties(GLUT::Cocoa PROPERTIES
+ IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}")
endif()
else()
if(BEOS)
@@ -196,32 +186,23 @@ if (GLUT_FOUND)
add_library(GLUT::GLUT UNKNOWN IMPORTED)
set_target_properties(GLUT::GLUT PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GLUT_INCLUDE_DIRS}")
- if(GLUT_glut_LIBRARY MATCHES "/([^/]+)\\.framework$")
- set(_glut_glut "${GLUT_glut_LIBRARY}/${CMAKE_MATCH_1}")
- if(EXISTS "${_glut_glut}.tbd")
- string(APPEND _glut_glut ".tbd")
- endif()
+ if(GLUT_glut_LIBRARY_RELEASE)
+ set_property(TARGET GLUT::GLUT APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(GLUT::GLUT PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${GLUT_glut_LIBRARY_RELEASE}")
+ endif()
+
+ if(GLUT_glut_LIBRARY_DEBUG)
+ set_property(TARGET GLUT::GLUT APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(GLUT::GLUT PROPERTIES
- IMPORTED_LOCATION "${_glut_glut}")
- else()
- if(GLUT_glut_LIBRARY_RELEASE)
- set_property(TARGET GLUT::GLUT APPEND PROPERTY
- IMPORTED_CONFIGURATIONS RELEASE)
- set_target_properties(GLUT::GLUT PROPERTIES
- IMPORTED_LOCATION_RELEASE "${GLUT_glut_LIBRARY_RELEASE}")
- endif()
-
- if(GLUT_glut_LIBRARY_DEBUG)
- set_property(TARGET GLUT::GLUT APPEND PROPERTY
- IMPORTED_CONFIGURATIONS DEBUG)
- set_target_properties(GLUT::GLUT PROPERTIES
- IMPORTED_LOCATION_DEBUG "${GLUT_glut_LIBRARY_DEBUG}")
- endif()
-
- if(NOT GLUT_glut_LIBRARY_RELEASE AND NOT GLUT_glut_LIBRARY_DEBUG)
- set_property(TARGET GLUT::GLUT APPEND PROPERTY
- IMPORTED_LOCATION "${GLUT_glut_LIBRARY}")
- endif()
+ IMPORTED_LOCATION_DEBUG "${GLUT_glut_LIBRARY_DEBUG}")
+ endif()
+
+ if(NOT GLUT_glut_LIBRARY_RELEASE AND NOT GLUT_glut_LIBRARY_DEBUG)
+ set_property(TARGET GLUT::GLUT APPEND PROPERTY
+ IMPORTED_LOCATION "${GLUT_glut_LIBRARY}")
endif()
if(TARGET GLUT::Xmu)
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake
index 0575caa..6ba9008 100644
--- a/Modules/FindLua50.cmake
+++ b/Modules/FindLua50.cmake
@@ -5,28 +5,19 @@
FindLua50
---------
-
-
Locate Lua library.
-This module defines::
-::
+This module defines::
LUA50_FOUND, if false, do not try to link to Lua
LUA_LIBRARIES, both lua and lualib
LUA_INCLUDE_DIR, where to find lua.h and lualib.h (and probably lauxlib.h)
-
-
-Note that the expected include convention is
-
-::
+Note that the expected include convention is::
#include "lua.h"
-and not
-
-::
+and not::
#include <lua/lua.h>
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake
index 283a3eb..405a7a7 100644
--- a/Modules/FindLua51.cmake
+++ b/Modules/FindLua51.cmake
@@ -5,29 +5,20 @@
FindLua51
---------
-
-
Locate Lua library.
This module defines::
-::
-
LUA51_FOUND, if false, do not try to link to Lua
LUA_LIBRARIES
LUA_INCLUDE_DIR, where to find lua.h
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
-
-Note that the expected include convention is
-
-::
+Note that the expected include convention is::
#include "lua.h"
-and not
-
-::
+and not::
#include <lua/lua.h>
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 3ab6bc1..fcd30ff 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -336,9 +336,7 @@ set(MATLAB_VERSIONS_MAPPING
# temporary folder for all Matlab runs
set(_matlab_temporary_folder ${CMAKE_BINARY_DIR}/Matlab)
-if(NOT EXISTS "${_matlab_temporary_folder}")
- file(MAKE_DIRECTORY "${_matlab_temporary_folder}")
-endif()
+file(MAKE_DIRECTORY "${_matlab_temporary_folder}")
#[=======================================================================[.rst:
.. command:: matlab_get_version_from_release_name
@@ -567,7 +565,7 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${_matlab_current_version};MATLABROOT]"
ABSOLUTE)
- if(EXISTS "${current_MATLAB_ROOT}")
+ if(IS_DIRECTORY "${current_MATLAB_ROOT}")
list(APPEND _matlab_roots_list "MATLAB" ${_matlab_current_version} ${current_MATLAB_ROOT})
endif()
@@ -583,7 +581,7 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_
# remove the dot
string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}")
- if(EXISTS "${current_MATLAB_ROOT}")
+ if(IS_DIRECTORY "${current_MATLAB_ROOT}")
list(APPEND _matlab_roots_list "MCR" ${_matlab_current_version} "${current_MATLAB_ROOT}/v${_matlab_current_version_without_dot}")
endif()
@@ -599,7 +597,7 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_
# remove the dot
string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}")
- if(EXISTS "${current_MATLAB_ROOT}")
+ if(IS_DIRECTORY "${current_MATLAB_ROOT}")
list(APPEND _matlab_roots_list "MCR" ${_matlab_current_version} "${current_MATLAB_ROOT}/v${_matlab_current_version_without_dot}")
endif()
@@ -1292,7 +1290,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve
if(EXISTS "${matlab_root}/appdata/version.xml")
# we inspect the application version.xml file that contains the product information
- file(STRINGS "${matlab_root}/appdata/version.xml" productinfo_string NEWLINE_CONSUME)
+ file(READ "${matlab_root}/appdata/version.xml" productinfo_string)
string(REGEX MATCH "<installedProductData.*displayedString=\"([a-zA-Z ]+)\".*/>"
product_reg_match
${productinfo_string}
@@ -1325,7 +1323,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve
if(NOT _matlab_current_program)
set(_find_matlab_options)
- if(matlab_root AND EXISTS ${matlab_root})
+ if(IS_DIRECTORY "${matlab_root}")
set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH)
endif()
@@ -1337,7 +1335,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve
)
endif()
- if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program})
+ if(NOT _matlab_current_program)
# if not found, clear the dependent variables
if(MATLAB_FIND_DEBUG)
message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}")
@@ -1365,8 +1363,14 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve
${_matlab_main_real_path_tmp}
CACHE INTERNAL "internal matlab location for the discovered version" FORCE)
- set(matlab_list_of_all_versions)
- matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions)
+ _Matlab_VersionInfoXML()
+ if(Matlab_VERSION_STRING_INTERNAL AND NOT Matlab_VERSION_STRING_INTERNAL STREQUAL "unknown")
+ # at least back to R2016 VersionInfo.xml exists
+ set(matlab_list_of_all_versions ${Matlab_VERSION_STRING_INTERNAL})
+ else()
+ # time consuming, less stable way to find Matlab version by running Matlab
+ matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions)
+ endif()
list(LENGTH matlab_list_of_all_versions list_of_all_versions_length)
if(list_of_all_versions_length GREATER 0)
@@ -1383,32 +1387,45 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve
message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})")
endif()
- # return the updated value
- set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE)
- elseif(EXISTS "${matlab_root}/VersionInfo.xml")
+ else()
# MCR
# we cannot run anything in order to extract the version. We assume that the file
# VersionInfo.xml exists under the MatlabRoot, we look for it and extract the version from there
- set(_matlab_version_tmp "unknown")
- file(STRINGS "${matlab_root}/VersionInfo.xml" versioninfo_string NEWLINE_CONSUME)
-
- if(versioninfo_string)
- # parses "<version>9.2.0.538062</version>"
- string(REGEX MATCH "<version>(.*)</version>"
- version_reg_match
- ${versioninfo_string}
- )
+ _Matlab_VersionInfoXML()
+ endif() # Matlab or MCR
- if(CMAKE_MATCH_1 MATCHES "(([0-9]+)\\.([0-9]+))[\\.0-9]*")
- set(_matlab_version_tmp "${CMAKE_MATCH_1}")
- endif()
+ # return the updated value
+ set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE)
+
+endfunction()
+
+
+function(_Matlab_VersionInfoXML)
+
+ set(_matlab_version_tmp "unknown")
+
+ set(_XMLfile ${matlab_root}/VersionInfo.xml)
+ if(NOT EXISTS ${_XMLfile})
+ return()
+ endif()
+
+ file(READ ${_XMLfile} versioninfo_string)
+
+ if(versioninfo_string)
+ # parses "<version>9.2.0.538062</version>"
+ string(REGEX MATCH "<version>(.*)</version>"
+ version_reg_match
+ ${versioninfo_string}
+ )
+
+ if(CMAKE_MATCH_1 MATCHES "(([0-9]+)\\.([0-9]+))[\\.0-9]*")
+ set(_matlab_version_tmp "${CMAKE_MATCH_1}")
endif()
- set(${matlab_final_version} "${_matlab_version_tmp}" PARENT_SCOPE)
- set(Matlab_VERSION_STRING_INTERNAL
- "${_matlab_version_tmp}"
- CACHE INTERNAL "Matlab (MCR) version (automatically determined)"
- FORCE)
- endif() # Matlab or MCR
+ endif()
+
+ if(_matlab_version_tmp)
+ set(Matlab_VERSION_STRING_INTERNAL "${_matlab_version_tmp}" CACHE INTERNAL "Matlab version" FORCE)
+ endif()
endfunction()
@@ -1463,7 +1480,7 @@ function(_Matlab_find_instances_osx matlab_roots)
set(_matlab_base_path "/Applications/MATLAB_${_matlab_current_release}.app")
# Check Matlab, has precedence over MCR
- if(EXISTS ${_matlab_base_path})
+ if(IS_DIRECTORY "${_matlab_base_path}")
if(MATLAB_FIND_DEBUG)
message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_base_path}")
endif()
@@ -1472,7 +1489,7 @@ function(_Matlab_find_instances_osx matlab_roots)
# Checks MCR
set(_mcr_path "/Applications/MATLAB/MATLAB_Runtime/v${_matlab_current_version_without_dot}")
- if(EXISTS "${_mcr_path}")
+ if(IS_DIRECTORY "${_mcr_path}")
if(MATLAB_FIND_DEBUG)
message(STATUS "[MATLAB] Found MCR version ${_matlab_current_release} (${_matlab_current_version}) in ${_mcr_path}")
endif()
@@ -1565,7 +1582,7 @@ endif()
if(Matlab_ROOT_DIR)
# if the user specifies a possible root, we keep this one
- if(NOT EXISTS "${Matlab_ROOT_DIR}")
+ if(NOT IS_DIRECTORY "${Matlab_ROOT_DIR}")
# if Matlab_ROOT_DIR specified but erroneous
if(MATLAB_FIND_DEBUG)
message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})")
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index 3d58569..c8e295b 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -106,15 +106,9 @@ find_package_handle_standard_args(
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
if(OPENAL_FOUND AND NOT TARGET OpenAL::OpenAL)
- if(OPENAL_LIBRARY MATCHES "/([^/]+)\\.framework$")
- add_library(OpenAL::OpenAL INTERFACE IMPORTED)
- set_target_properties(OpenAL::OpenAL PROPERTIES
- INTERFACE_LINK_LIBRARIES "${OPENAL_LIBRARY}")
- else()
- add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
- set_target_properties(OpenAL::OpenAL PROPERTIES
- IMPORTED_LOCATION "${OPENAL_LIBRARY}")
- endif()
+ add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
+ set_target_properties(OpenAL::OpenAL PROPERTIES
+ IMPORTED_LOCATION "${OPENAL_LIBRARY}")
set_target_properties(OpenAL::OpenAL PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}")
endif()
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index 843f787..1527c31 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -655,17 +655,8 @@ if(OPENGL_FOUND)
# A legacy GL library is available, so use it for the legacy GL target.
if(IS_ABSOLUTE "${OPENGL_gl_LIBRARY}")
add_library(OpenGL::GL UNKNOWN IMPORTED)
- if(OPENGL_gl_LIBRARY MATCHES "/([^/]+)\\.framework$")
- set(_gl_fw "${OPENGL_gl_LIBRARY}/${CMAKE_MATCH_1}")
- if(EXISTS "${_gl_fw}.tbd")
- string(APPEND _gl_fw ".tbd")
- endif()
- set_target_properties(OpenGL::GL PROPERTIES
- IMPORTED_LOCATION "${_gl_fw}")
- else()
- set_target_properties(OpenGL::GL PROPERTIES
- IMPORTED_LOCATION "${OPENGL_gl_LIBRARY}")
- endif()
+ set_target_properties(OpenGL::GL PROPERTIES
+ IMPORTED_LOCATION "${OPENGL_gl_LIBRARY}")
else()
add_library(OpenGL::GL INTERFACE IMPORTED)
set_target_properties(OpenGL::GL PROPERTIES
@@ -709,17 +700,8 @@ if(OPENGL_FOUND)
if(OPENGL_GLU_FOUND AND NOT TARGET OpenGL::GLU)
if(IS_ABSOLUTE "${OPENGL_glu_LIBRARY}")
add_library(OpenGL::GLU UNKNOWN IMPORTED)
- if(OPENGL_glu_LIBRARY MATCHES "/([^/]+)\\.framework$")
- set(_glu_fw "${OPENGL_glu_LIBRARY}/${CMAKE_MATCH_1}")
- if(EXISTS "${_glu_fw}.tbd")
- string(APPEND _glu_fw ".tbd")
- endif()
- set_target_properties(OpenGL::GLU PROPERTIES
- IMPORTED_LOCATION "${_glu_fw}")
- else()
- set_target_properties(OpenGL::GLU PROPERTIES
- IMPORTED_LOCATION "${OPENGL_glu_LIBRARY}")
- endif()
+ set_target_properties(OpenGL::GLU PROPERTIES
+ IMPORTED_LOCATION "${OPENGL_glu_LIBRARY}")
else()
add_library(OpenGL::GLU INTERFACE IMPORTED)
set_target_properties(OpenGL::GLU PROPERTIES
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 02f7fb4..6e8b784 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -425,13 +425,19 @@ macro(_pkg_set_path_internal)
unset(_pkgconfig_path)
endif()
- # Tell pkg-config not to strip any -L paths so we can search them all.
+ # Tell pkg-config not to strip any -I or -L paths so we can search them all.
if(DEFINED ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS})
set(_pkgconfig_allow_system_libs_old "$ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS}")
else()
unset(_pkgconfig_allow_system_libs_old)
endif()
set(ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS} 1)
+ if(DEFINED ENV{PKG_CONFIG_ALLOW_SYSTEM_CFLAGS})
+ set(_pkgconfig_allow_system_cflags_old "$ENV{PKG_CONFIG_ALLOW_SYSTEM_CFLAGS}")
+ else()
+ unset(_pkgconfig_allow_system_cflags_old)
+ endif()
+ set(ENV{PKG_CONFIG_ALLOW_SYSTEM_CFLAGS} 1)
endmacro()
macro(_pkg_restore_path_internal)
@@ -445,6 +451,12 @@ macro(_pkg_restore_path_internal)
else()
unset(ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS})
endif()
+ if(DEFINED _pkgconfig_allow_system_cflags_old)
+ set(ENV{PKG_CONFIG_ALLOW_SYSTEM_CFLAGS} "${_pkgconfig_allow_system_cflags_old}")
+ unset(_pkgconfig_allow_system_cflags_old)
+ else()
+ unset(ENV{PKG_CONFIG_ALLOW_SYSTEM_CFLAGS})
+ endif()
unset(_extra_paths)
unset(_pkgconfig_path_old)
@@ -551,8 +563,8 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
foreach (_pkg_check_modules_pkg ${_pkg_check_modules_list})
set(_pkg_check_modules_exist_query)
- # check whether version is given
- if (_pkg_check_modules_pkg MATCHES "(.*[^><])(=|[><]=?)(.*)")
+ # check whether version is given while ignoring whitespace
+ if (_pkg_check_modules_pkg MATCHES "(.*[^>< \t])[ \t]*(=|[><]=?)[ \t]*(.*)")
set(_pkg_check_modules_pkg_name "${CMAKE_MATCH_1}")
set(_pkg_check_modules_pkg_op "${CMAKE_MATCH_2}")
set(_pkg_check_modules_pkg_ver "${CMAKE_MATCH_3}")
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index a92fb52..008b537 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -136,15 +136,95 @@ Example:
Variable to define with autogenerated Python files
``ARGN``
``.proto`` files
+
+.. command:: protobuf_generate
+
+ .. versionadded:: 3.13
+
+ Automatically generate source files from ``.proto`` schema files at build time::
+
+ protobuf_generate (
+ TARGET <target>
+ [LANGUAGE <lang>]
+ [OUT_VAR <out_var>]
+ [EXPORT_MACRO <macro>]
+ [PROTOC_OUT_DIR <dir>]
+ [PLUGIN <plugin>]
+ [PLUGIN_OPTIONS <plugin_options>]
+ [DEPENDENCIES <depends]
+ [PROTOS <protobuf_files>]
+ [IMPORT_DIRS <dirs>]
+ [GENERATE_EXTENSIONS <extensions>]
+ [PROTOC_OPTIONS <protoc_options>]
+ [APPEND_PATH])
+
+ ``APPEND_PATH``
+ A flag that causes the base path of all proto schema files to be added to
+ ``IMPORT_DIRS``.
+ ``LANGUAGE``
+ A single value: cpp or python. Determines what kind of source files are
+ being generated. Defaults to cpp.
+ ``OUT_VAR``
+ Name of a CMake variable that will be filled with the paths to the generated
+ source files.
+ ``EXPORT_MACRO``
+ Name of a macro that is applied to all generated Protobuf message classes
+ and extern variables. It can, for example, be used to declare DLL exports.
+ ``PROTOC_OUT_DIR``
+ Output directory of generated source files. Defaults to ``CMAKE_CURRENT_BINARY_DIR``.
+ ``PLUGIN``
+ .. versionadded:: 3.21
+
+ An optional plugin executable. This could, for example, be the path to
+ ``grpc_cpp_plugin``.
+ ``PLUGIN_OPTIONS``
+ .. versionadded:: 3.28
+
+ Additional options provided to the plugin, such as ``generate_mock_code=true``
+ for the gRPC cpp plugin.
+ ``DEPENDENCIES``
+ .. versionadded:: 3.28
+
+ Arguments forwarded to the ``DEPENDS`` of the underlying ``add_custom_command``
+ invocation.
+ ``TARGET``
+ CMake target that will have the generated files added as sources.
+ ``PROTOS``
+ List of proto schema files. If omitted, then every source file ending in *proto* of ``TARGET`` will be used.
+ ``IMPORT_DIRS``
+ A common parent directory for the schema files. For example, if the schema file is
+ ``proto/helloworld/helloworld.proto`` and the import directory ``proto/`` then the
+ generated files are ``${PROTOC_OUT_DIR}/helloworld/helloworld.pb.h`` and
+ ``${PROTOC_OUT_DIR}/helloworld/helloworld.pb.cc``.
+ ``GENERATE_EXTENSIONS``
+ If LANGUAGE is omitted then this must be set to the extensions that protoc generates.
+ ``PROTOC_OPTIONS``
+ .. versionadded:: 3.28
+
+ Additional arguments that are forwarded to protoc.
+
+ Example::
+
+ find_package(gRPC CONFIG REQUIRED)
+ find_package(Protobuf REQUIRED)
+ add_library(ProtoTest Test.proto)
+ target_link_libraries(ProtoTest PUBLIC gRPC::grpc++)
+ protobuf_generate(TARGET ProtoTest)
+ protobuf_generate(
+ TARGET ProtoTest
+ LANGUAGE grpc
+ PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
+ PLUGIN_OPTIONS generate_mock_code=true
+ GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc)
#]=======================================================================]
function(protobuf_generate)
set(_options APPEND_PATH DESCRIPTORS)
- set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN)
+ set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES)
if(COMMAND target_sources)
list(APPEND _singleargs TARGET)
endif()
- set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS)
+ set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
@@ -168,9 +248,18 @@ function(protobuf_generate)
endif()
if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp)
- set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:")
+ set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}")
endif()
+ foreach(_option ${_dll_export_decl} ${protobuf_generate_PLUGIN_OPTIONS})
+ # append comma - not using CMake lists and string replacement as users
+ # might have semicolons in options
+ if(_plugin_options)
+ set( _plugin_options "${_plugin_options},")
+ endif()
+ set(_plugin_options "${_plugin_options}${_option}")
+ endforeach()
+
if(protobuf_generate_PLUGIN)
set(_plugin "--plugin=${protobuf_generate_PLUGIN}")
endif()
@@ -204,14 +293,12 @@ function(protobuf_generate)
# Create an include path for each file specified
foreach(_file ${protobuf_generate_PROTOS})
get_filename_component(_abs_file ${_file} ABSOLUTE)
- get_filename_component(_abs_path ${_abs_file} PATH)
- list(FIND _protobuf_include_path ${_abs_path} _contains_already)
+ get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
+ list(FIND _protobuf_include_path ${_abs_dir} _contains_already)
if(${_contains_already} EQUAL -1)
- list(APPEND _protobuf_include_path -I ${_abs_path})
+ list(APPEND _protobuf_include_path -I ${_abs_dir})
endif()
endforeach()
- else()
- set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
foreach(DIR ${protobuf_generate_IMPORT_DIRS})
@@ -222,6 +309,10 @@ function(protobuf_generate)
endif()
endforeach()
+ if(NOT _protobuf_include_path)
+ set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+
set(_generated_srcs_all)
foreach(_proto ${protobuf_generate_PROTOS})
get_filename_component(_abs_file ${_proto} ABSOLUTE)
@@ -246,12 +337,20 @@ function(protobuf_generate)
endif()
list(APPEND _generated_srcs_all ${_generated_srcs})
+ set(_comment "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}")
+ if(protobuf_generate_PROTOC_OPTIONS)
+ set(_comment "${_comment}, protoc-options: ${protobuf_generate_PROTOC_OPTIONS}")
+ endif()
+ if(_plugin_options)
+ set(_comment "${_comment}, plugin-options: ${_plugin_options}")
+ endif()
+
add_custom_command(
OUTPUT ${_generated_srcs}
- COMMAND protobuf::protoc
- ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file}
- DEPENDS ${_abs_file} protobuf::protoc
- COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
+ COMMAND protobuf::protoc
+ ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file}
+ DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_DEPENDENCIES}
+ COMMENT ${_comment}
VERBATIM )
endforeach()
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index d483d7f..08ab9c0 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -474,7 +474,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
set (config_flag "--${NAME}")
endif()
string (TOLOWER "${config_flag}" config_flag)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" ${config_flag}
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} ${config_flag}
RESULT_VARIABLE _result
OUTPUT_VARIABLE _values
ERROR_QUIET
@@ -752,12 +752,43 @@ function (_PYTHON_GET_VERSION)
endfunction()
function (_PYTHON_GET_LAUNCHER _PYTHON_PGL_NAME)
- cmake_parse_arguments (PARSE_ARGV 1 _PGL "INTERPRETER;COMPILER" "" "")
+ cmake_parse_arguments (PARSE_ARGV 1 _PGL "INTERPRETER;COMPILER" "CONFIG" "")
unset (${_PYTHON_PGL_NAME} PARENT_SCOPE)
if ((_PGL_INTERPRETER AND NOT _${_PYTHON_PREFIX}_EXECUTABLE)
- OR (_PGL_COMPILER AND NOT _${_PYTHON_PREFIX}_COMPILER))
+ OR (_PGL_COMPILER AND NOT _${_PYTHON_PREFIX}_COMPILER)
+ OR (_PGL_CONFIG AND NOT _${_PYTHON_PREFIX}_CONFIG))
+ return()
+ endif()
+
+ if (_PGL_CONFIG)
+ # default config script can be launched directly
+ set (${_PYTHON_PGL_NAME} "${_${_PYTHON_PREFIX}_CONFIG}" PARENT_SCOPE)
+
+ if (NOT MINGW)
+ return()
+ endif()
+ # on MINGW environment, python-config script may require bash to be launched
+ execute_process (COMMAND cygpath.exe -u "${_${_PYTHON_PREFIX}_CONFIG}"
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _config
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ # impossible to convert path, keep default config
+ return()
+ endif()
+ execute_process (COMMAND bash.exe "${_config}" --prefix
+ RESULT_VARIABLE _result
+ OUTPUT_QUIET
+ ERROR_QUIET)
+ if (_result)
+ # fail to execute through bash, keep default config
+ return()
+ endif()
+
+ set(${_PYTHON_PGL_NAME} bash.exe "${_config}" PARENT_SCOPE)
return()
endif()
@@ -770,7 +801,7 @@ function (_PYTHON_GET_LAUNCHER _PYTHON_PGL_NAME)
AND ext STREQUAL ".exe")
set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE)
endif()
- else()
+ elseif (_PGL_COMPILER)
get_filename_component (name "${_${_PYTHON_PREFIX}_COMPILER}" NAME)
get_filename_component (ext "${_${_PYTHON_PREFIX}_COMPILER}" LAST_EXT)
if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES
@@ -981,7 +1012,7 @@ function (_PYTHON_VALIDATE_COMPILER)
# retrieve python environment version from compiler
set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
- file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n")
+ file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]])); sys.stdout.flush()\n")
execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_COMPILER}"
${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS}
/target:exe /embed "${working_dir}/version.py"
@@ -2520,7 +2551,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# retrieve python environment version from compiler
_python_get_launcher (_${_PYTHON_PREFIX}_COMPILER_LAUNCHER COMPILER)
set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
- file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n")
+ file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]])); sys.stdout.flush()\n")
execute_process (COMMAND ${_${_PYTHON_PREFIX}_COMPILER_LAUNCHER} "${_${_PYTHON_PREFIX}_COMPILER}"
${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS}
/target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
@@ -2731,20 +2762,23 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
NO_DEFAULT_PATH)
endif()
+ _python_get_launcher (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER CONFIG "${_${_PYTHON_PREFIX}_CONFIG}")
+
if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --prefix
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP
- ERROR_QUIET
+ ERROR_VARIABLE __${_PYTHON_PREFIX}_HELP
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_${_PYTHON_PREFIX}_RESULT)
# assume config tool is not usable
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
endif()
endif()
if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --abiflags
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
ERROR_QUIET
@@ -2756,22 +2790,25 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# Wrong ABI
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
endif()
endif()
if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
# check that config tool match library architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --configdir
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_${_PYTHON_PREFIX}_RESULT)
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
else()
string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
endif()
endif()
endif()
@@ -2817,8 +2854,10 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
unset (_${_PYTHON_PREFIX}_CONFIG_NAMES)
+ _python_get_launcher (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER CONFIG "${_${_PYTHON_PREFIX}_CONFIG}")
+
if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --prefix
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP
ERROR_QUIET
@@ -2826,6 +2865,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
if (_${_PYTHON_PREFIX}_RESULT)
# assume config tool is not usable
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
endif()
endif()
@@ -2833,7 +2873,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
continue()
endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --abiflags
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
ERROR_QUIET
@@ -2845,23 +2885,26 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# Wrong ABI
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
continue()
endif()
if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
# check that config tool match library architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --configdir
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_${_PYTHON_PREFIX}_RESULT)
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
continue()
endif()
string (FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER)
continue()
endif()
endif()
diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake
index 44a1f41..604f8e3 100644
--- a/Modules/FindQt.cmake
+++ b/Modules/FindQt.cmake
@@ -91,7 +91,7 @@ endif ()
# now find qmake
find_program(QT_QMAKE_EXECUTABLE_FINDQT NAMES qmake PATHS "${QT_SEARCH_PATH}/bin" "$ENV{QTDIR}/bin")
if(QT_QMAKE_EXECUTABLE_FINDQT)
- exec_program(${QT_QMAKE_EXECUTABLE_FINDQT} ARGS "-query QT_VERSION"
+ execute_process(COMMAND ${QT_QMAKE_EXECUTABLE_FINDQT} -query QT_VERSION
OUTPUT_VARIABLE QTVERSION)
if(QTVERSION MATCHES "4")
set(QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE_FINDQT} CACHE PATH "Qt4 qmake program.")
@@ -103,8 +103,8 @@ if(QT_QMAKE_EXECUTABLE_FINDQT)
endif()
if(QT_QMAKE_EXECUTABLE_FINDQT)
- exec_program( ${QT_QMAKE_EXECUTABLE_FINDQT}
- ARGS "-query QT_INSTALL_HEADERS"
+ execute_process(COMMAND ${QT_QMAKE_EXECUTABLE_FINDQT}
+ -query QT_INSTALL_HEADERS
OUTPUT_VARIABLE qt_headers )
endif()
diff --git a/Modules/Findosg.cmake b/Modules/Findosg.cmake
index 027f315..c9daece 100644
--- a/Modules/Findosg.cmake
+++ b/Modules/Findosg.cmake
@@ -11,16 +11,16 @@ NOTE: It is highly recommended that you use the new
FindOpenSceneGraph.cmake introduced in CMake 2.6.3 and not use this
Find module directly.
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osg This module defines
diff --git a/Modules/FindosgAnimation.cmake b/Modules/FindosgAnimation.cmake
index 65e3016..9fa4281 100644
--- a/Modules/FindosgAnimation.cmake
+++ b/Modules/FindosgAnimation.cmake
@@ -7,16 +7,16 @@ FindosgAnimation
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgAnimation This module defines
diff --git a/Modules/FindosgFX.cmake b/Modules/FindosgFX.cmake
index 438fab7..d9e223a 100644
--- a/Modules/FindosgFX.cmake
+++ b/Modules/FindosgFX.cmake
@@ -7,16 +7,16 @@ FindosgFX
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgFX This module defines
diff --git a/Modules/FindosgGA.cmake b/Modules/FindosgGA.cmake
index 7b6ef30..8a7c7ec 100644
--- a/Modules/FindosgGA.cmake
+++ b/Modules/FindosgGA.cmake
@@ -7,16 +7,16 @@ FindosgGA
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgGA This module defines
diff --git a/Modules/FindosgIntrospection.cmake b/Modules/FindosgIntrospection.cmake
index 625e4c2..e41c64f 100644
--- a/Modules/FindosgIntrospection.cmake
+++ b/Modules/FindosgIntrospection.cmake
@@ -7,16 +7,16 @@ FindosgIntrospection
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgINTROSPECTION This module defines
diff --git a/Modules/FindosgManipulator.cmake b/Modules/FindosgManipulator.cmake
index 857ff5d..1c0058f 100644
--- a/Modules/FindosgManipulator.cmake
+++ b/Modules/FindosgManipulator.cmake
@@ -7,16 +7,16 @@ FindosgManipulator
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgManipulator This module defines
diff --git a/Modules/FindosgParticle.cmake b/Modules/FindosgParticle.cmake
index 91a30dc..74ef254 100644
--- a/Modules/FindosgParticle.cmake
+++ b/Modules/FindosgParticle.cmake
@@ -7,16 +7,16 @@ FindosgParticle
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgParticle This module defines
diff --git a/Modules/FindosgPresentation.cmake b/Modules/FindosgPresentation.cmake
index eae75d6..82d86cd 100644
--- a/Modules/FindosgPresentation.cmake
+++ b/Modules/FindosgPresentation.cmake
@@ -7,16 +7,16 @@ FindosgPresentation
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgPresentation This module defines
diff --git a/Modules/FindosgProducer.cmake b/Modules/FindosgProducer.cmake
index 33b9f73..43ccd78 100644
--- a/Modules/FindosgProducer.cmake
+++ b/Modules/FindosgProducer.cmake
@@ -7,16 +7,16 @@ FindosgProducer
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgProducer This module defines
diff --git a/Modules/FindosgQt.cmake b/Modules/FindosgQt.cmake
index cf35630..e89add0 100644
--- a/Modules/FindosgQt.cmake
+++ b/Modules/FindosgQt.cmake
@@ -7,16 +7,16 @@ FindosgQt
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgQt This module defines
diff --git a/Modules/FindosgShadow.cmake b/Modules/FindosgShadow.cmake
index 0049c4e..90f477b 100644
--- a/Modules/FindosgShadow.cmake
+++ b/Modules/FindosgShadow.cmake
@@ -7,16 +7,16 @@ FindosgShadow
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgShadow This module defines
diff --git a/Modules/FindosgSim.cmake b/Modules/FindosgSim.cmake
index 43ba542..66e461b 100644
--- a/Modules/FindosgSim.cmake
+++ b/Modules/FindosgSim.cmake
@@ -7,16 +7,16 @@ FindosgSim
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgSim This module defines
diff --git a/Modules/FindosgTerrain.cmake b/Modules/FindosgTerrain.cmake
index c6f5b69..07bdeb7 100644
--- a/Modules/FindosgTerrain.cmake
+++ b/Modules/FindosgTerrain.cmake
@@ -7,16 +7,16 @@ FindosgTerrain
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgTerrain This module defines
diff --git a/Modules/FindosgText.cmake b/Modules/FindosgText.cmake
index fd3c232..793709a 100644
--- a/Modules/FindosgText.cmake
+++ b/Modules/FindosgText.cmake
@@ -7,16 +7,16 @@ FindosgText
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgText This module defines
diff --git a/Modules/FindosgUtil.cmake b/Modules/FindosgUtil.cmake
index e84727a..c0f633b 100644
--- a/Modules/FindosgUtil.cmake
+++ b/Modules/FindosgUtil.cmake
@@ -7,16 +7,16 @@ FindosgUtil
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgUtil This module defines
diff --git a/Modules/FindosgViewer.cmake b/Modules/FindosgViewer.cmake
index 2174357..824edbf 100644
--- a/Modules/FindosgViewer.cmake
+++ b/Modules/FindosgViewer.cmake
@@ -7,16 +7,16 @@ FindosgViewer
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgViewer This module defines
diff --git a/Modules/FindosgVolume.cmake b/Modules/FindosgVolume.cmake
index 35defef..8f3ef37 100644
--- a/Modules/FindosgVolume.cmake
+++ b/Modules/FindosgVolume.cmake
@@ -7,16 +7,16 @@ FindosgVolume
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgVolume This module defines
diff --git a/Modules/FindosgWidget.cmake b/Modules/FindosgWidget.cmake
index c7aae44..eabf079 100644
--- a/Modules/FindosgWidget.cmake
+++ b/Modules/FindosgWidget.cmake
@@ -7,16 +7,16 @@ FindosgWidget
-This is part of the Findosg* suite used to find OpenSceneGraph
+This is part of the ``Findosg*`` suite used to find OpenSceneGraph
components. Each component is separate and you must opt in to each
module. You must also opt into OpenGL and OpenThreads (and Producer
if needed) as these modules won't do it for you. This is to allow you
control over your own system piece by piece in case you need to opt
out of certain components or change the Find behavior for a particular
-module (perhaps because the default FindOpenGL.cmake module doesn't
+module (perhaps because the default :module:`FindOpenGL` module doesn't
work with your system as an example). If you want to use a more
convenient module that includes everything, use the
-FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+:module:`FindOpenSceneGraph` instead of the ``Findosg*.cmake`` modules.
Locate osgWidget This module defines
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index cc76b35..78fa481 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -848,7 +848,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "unix")
DBG_MSG_V("wxWidgets required components : ${_cmp_req}")
DBG_MSG_V("wxWidgets optional components : ${_cmp_opt}")
if(DEFINED _cmp_opt)
- string(REPLACE ";" "," _cmp_opt "--optional-libs ${_cmp_opt}")
+ string(REPLACE ";" "," _cmp_opt "${_cmp_opt}")
+ set(_cmp_opt "--optional-libs" ${_cmp_opt})
endif()
string(REPLACE ";" "," _cmp_req "${_cmp_req}")
execute_process(
diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake
index 6e4be91..d1b25e1 100644
--- a/Modules/FindwxWindows.cmake
+++ b/Modules/FindwxWindows.cmake
@@ -635,14 +635,14 @@ else()
# remember: always link shared to use systems GL etc. libs (no static
# linking, just link *against* static .a libs)
if(WXWINDOWS_USE_SHARED_LIBS)
- set(WX_CONFIG_ARGS_LIBS "--libs")
+ set(WX_CONFIG_ARGS_LIBS --libs)
else()
- set(WX_CONFIG_ARGS_LIBS "--static --libs")
+ set(WX_CONFIG_ARGS_LIBS --static --libs)
endif()
# do we need additionial wx GL stuff like GLCanvas ?
if(WXWINDOWS_USE_GL)
- string(APPEND WX_CONFIG_ARGS_LIBS " --gl-libs" )
+ list(APPEND WX_CONFIG_ARGS_LIBS --gl-libs)
endif()
##message("DBG: WX_CONFIG_ARGS_LIBS=${WX_CONFIG_ARGS_LIBS}===")
@@ -662,14 +662,15 @@ else()
##CMAKE_WXWINDOWS_CXX_FLAGS=${CMAKE_WXWINDOWS_CXX_FLAGS}===")
# keep the back-quoted string for clarity
- set(WXWINDOWS_LIBRARIES "`${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} ${WX_CONFIG_ARGS_LIBS}`")
+ string(REPLACE ";" " " _wx_config_args_libs "${WX_CONFIG_ARGS_LIBS}")
+ set(WXWINDOWS_LIBRARIES "`${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} ${_wx_config_args_libs}`")
##message("DBG2: for linking:
##WXWINDOWS_LIBRARIES=${WXWINDOWS_LIBRARIES}===")
# evaluate wx-config output to separate linker flags and linkdirs for
# rpath:
- exec_program(${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE}
- ARGS ${WX_CONFIG_ARGS_LIBS}
+ execute_process(COMMAND ${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE}
+ ${WX_CONFIG_ARGS_LIBS}
OUTPUT_VARIABLE WX_CONFIG_LIBS )
## extract linkdirs (-L) for rpath
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index 2c85029..81481a7 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -374,6 +374,7 @@ function(FortranCInterface_VERIFY)
"-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}"
"-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}"
"-DFortranCInterface_BINARY_DIR=${FortranCInterface_BINARY_DIR}"
+ "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
${_FortranCInterface_OSX_ARCH}
${_FortranCInterface_EXE_LINKER_FLAGS}
OUTPUT_VARIABLE _output)
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index 21753af..6349f9d 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -981,7 +981,7 @@ inst:
;MessageBox MB_OK 'User "$0" is in the Admin group'
StrCpy $SV_ALLUSERS "AllUsers"
Goto done
- StrCmp $1 "Power" 0 +4
+ StrCmp $1 "Power" 0 +3
SetShellVarContext all
;MessageBox MB_OK 'User "$0" is in the Power Users group'
StrCpy $SV_ALLUSERS "AllUsers"
diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake
index 1a8a27e..c2bd14f 100644
--- a/Modules/Internal/FeatureTesting.cmake
+++ b/Modules/Internal/FeatureTesting.cmake
@@ -37,6 +37,7 @@ macro(_record_compiler_features lang compile_flags feature_list)
LINK_LIBRARIES "${compile_flags_for_link}"
COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
COPY_FILE_ERROR _copy_error
+ __CMAKE_INTERNAL FEATURE_TESTING
)
if(NOT CMAKE_${lang}_FEATURE_TEST)
set(_result 255)
diff --git a/Modules/Platform/Apple-Clang.cmake b/Modules/Platform/Apple-Clang.cmake
index 0681bfb..4d7546a 100644
--- a/Modules/Platform/Apple-Clang.cmake
+++ b/Modules/Platform/Apple-Clang.cmake
@@ -22,6 +22,10 @@ macro(__apple_compiler_clang lang)
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mtvos-version-min=")
elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/AppleTVSimulator")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mtvos-simulator-version-min=")
+ elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/XROS")
+ set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mtargetos=xros")
+ elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/XRSimulator")
+ set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mtargetos=xros")
elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/WatchOS")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mwatchos-version-min=")
elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/WatchSimulator")
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index e253392..8d5bf8c 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -43,7 +43,7 @@ if(NOT CMAKE_CROSSCOMPILING AND
unset(_sysctl_stdout)
endif()
-# macOS, iOS, tvOS, and watchOS should lookup compilers from
+# macOS, iOS, tvOS, visionOS, and watchOS should lookup compilers from
# Platform/Apple-${CMAKE_CXX_COMPILER_ID}-<LANG>
set(CMAKE_EFFECTIVE_SYSTEM_NAME "Apple")
@@ -76,6 +76,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL iOS)
set(_CMAKE_OSX_SYSROOT_DEFAULT "iphoneos")
elseif(CMAKE_SYSTEM_NAME STREQUAL tvOS)
set(_CMAKE_OSX_SYSROOT_DEFAULT "appletvos")
+elseif(CMAKE_SYSTEM_NAME STREQUAL visionOS)
+ set(_CMAKE_OSX_SYSROOT_DEFAULT "xros")
elseif(CMAKE_SYSTEM_NAME STREQUAL watchOS)
set(_CMAKE_OSX_SYSROOT_DEFAULT "watchos")
elseif("${CMAKE_GENERATOR}" MATCHES Xcode
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 48a9065..d614182 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -1,4 +1,4 @@
-if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
+if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
if(NOT DEFINED CMAKE_MACOSX_BUNDLE)
set(CMAKE_MACOSX_BUNDLE ON)
endif()
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 8e96bf4..829ab9b 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -28,6 +28,8 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsCE")
set(_PLATFORM_LINK_FLAGS " /subsystem:windowsce")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+ set(_PLATFORM_LINK_FLAGS " -subsystem:native -kernel -MANIFEST:NO")
else()
set(_PLATFORM_LINK_FLAGS "")
endif()
@@ -223,6 +225,18 @@ elseif(WINDOWS_PHONE OR WINDOWS_STORE)
else()
set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
endif()
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "")
+ set(_FLAGS_C " -kernel")
+ set(_FLAGS_CXX " -kernel")
+ foreach(t EXE SHARED MODULE)
+ string(APPEND CMAKE_${t}_LINKER_FLAGS_INIT " -NODEFAULTLIB")
+ endforeach()
+ if((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "x64") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "x64"))
+ set(_PLATFORM_DEFINES "${_PLATFORM_DEFINES} -D_AMD64_ -DAMD64")
+ elseif((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64"))
+ set(_PLATFORM_DEFINES "${_PLATFORM_DEFINES} -D_ARM64_ -DARM64")
+ endif()
else()
set(_PLATFORM_DEFINES "/DWIN32")
if((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64EC") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64EC"))
@@ -294,7 +308,7 @@ endif()
# add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype
# on versions that support it
set( MSVC_INCREMENTAL_YES_FLAG "")
-if(NOT WINDOWS_PHONE AND NOT WINDOWS_STORE)
+if(NOT WINDOWS_PHONE AND NOT WINDOWS_STORE AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
if(NOT MSVC_INCREMENTAL_DEFAULT)
set( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES")
else()
@@ -353,8 +367,14 @@ macro(__windows_compiler_msvc lang)
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
endif()
+ if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+ set(_DLL_DRIVER "-driver")
+ else()
+ set(_DLL_DRIVER "/dll")
+ endif()
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> ${_DLL_DRIVER} /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ unset(_DLL_DRIVER)
set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
diff --git a/Modules/Platform/Windows.cmake b/Modules/Platform/Windows.cmake
index 8697e7a..1bf39cf 100644
--- a/Modules/Platform/Windows.cmake
+++ b/Modules/Platform/Windows.cmake
@@ -1,7 +1,11 @@
set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
set(CMAKE_SHARED_LIBRARY_PREFIX "") # lib
-set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") # .so
+if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+ set(CMAKE_SHARED_LIBRARY_SUFFIX ".sys") # .so
+else()
+ set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") # .so
+endif()
set(CMAKE_IMPORT_LIBRARY_PREFIX "")
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
set(CMAKE_EXECUTABLE_SUFFIX ".exe") # .exe
diff --git a/Modules/Platform/WindowsKernelModeDriver-Initialize.cmake b/Modules/Platform/WindowsKernelModeDriver-Initialize.cmake
new file mode 100644
index 0000000..6f0ef33
--- /dev/null
+++ b/Modules/Platform/WindowsKernelModeDriver-Initialize.cmake
@@ -0,0 +1,11 @@
+# undocumented, do not use outside of CMake
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED "WindowsKernelModeDriver" _cmake_windows_kernel_mode_driver_enabled)
+if(NOT _cmake_windows_kernel_mode_driver_enabled)
+ message(FATAL_ERROR "Windows kernel-mode driver experimental support is not enabled.")
+endif()
+
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ message(FATAL_ERROR "Visual Studio generators do not yet support CMAKE_SYSTEM_NAME=WindowsKernelModeDriver.")
+endif()
+
+set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)
diff --git a/Modules/Platform/WindowsKernelModeDriver-MSVC-C.cmake b/Modules/Platform/WindowsKernelModeDriver-MSVC-C.cmake
new file mode 100644
index 0000000..ce8060b
--- /dev/null
+++ b/Modules/Platform/WindowsKernelModeDriver-MSVC-C.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-C)
diff --git a/Modules/Platform/WindowsKernelModeDriver-MSVC-CXX.cmake b/Modules/Platform/WindowsKernelModeDriver-MSVC-CXX.cmake
new file mode 100644
index 0000000..281eadc
--- /dev/null
+++ b/Modules/Platform/WindowsKernelModeDriver-MSVC-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-CXX)
diff --git a/Modules/Platform/WindowsKernelModeDriver.cmake b/Modules/Platform/WindowsKernelModeDriver.cmake
new file mode 100644
index 0000000..65b2eae
--- /dev/null
+++ b/Modules/Platform/WindowsKernelModeDriver.cmake
@@ -0,0 +1 @@
+include(Platform/Windows)
diff --git a/Modules/Platform/visionOS-Determine-CXX.cmake b/Modules/Platform/visionOS-Determine-CXX.cmake
new file mode 100644
index 0000000..ac80fa6
--- /dev/null
+++ b/Modules/Platform/visionOS-Determine-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Darwin-Determine-CXX)
diff --git a/Modules/Platform/visionOS-Initialize.cmake b/Modules/Platform/visionOS-Initialize.cmake
new file mode 100644
index 0000000..e8431bc
--- /dev/null
+++ b/Modules/Platform/visionOS-Initialize.cmake
@@ -0,0 +1,7 @@
+include(Platform/Darwin-Initialize)
+
+if(NOT _CMAKE_OSX_SYSROOT_PATH MATCHES "/XR(OS|Simulator)")
+ message(FATAL_ERROR "${CMAKE_OSX_SYSROOT} is not an visionOS SDK")
+endif()
+
+set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)
diff --git a/Modules/Platform/visionOS.cmake b/Modules/Platform/visionOS.cmake
new file mode 100644
index 0000000..850ddc2
--- /dev/null
+++ b/Modules/Platform/visionOS.cmake
@@ -0,0 +1 @@
+include(Platform/Darwin)
diff --git a/Modules/UsePkgConfig.cmake b/Modules/UsePkgConfig.cmake
index 32d228d..b020259 100644
--- a/Modules/UsePkgConfig.cmake
+++ b/Modules/UsePkgConfig.cmake
@@ -35,25 +35,25 @@ macro(PKGCONFIG _package _include_DIR _link_DIR _link_FLAGS _cflags)
# if pkg-config has been found
if(PKGCONFIG_EXECUTABLE)
- exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull )
+ execute_process(COMMAND ${PKGCONFIG_EXECUTABLE} ${_package} --exists RESULT_VARIABLE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull )
# and if the package of interest also exists for pkg-config, then get the information
if(NOT _return_VALUE)
- exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=includedir
+ execute_process(COMMAND ${PKGCONFIG_EXECUTABLE} ${_package} --variable=includedir
OUTPUT_VARIABLE ${_include_DIR} )
string(REGEX REPLACE "[\r\n]" " " ${_include_DIR} "${${_include_DIR}}")
- exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=libdir
+ execute_process(COMMAND ${PKGCONFIG_EXECUTABLE} ${_package} --variable=libdir
OUTPUT_VARIABLE ${_link_DIR} )
string(REGEX REPLACE "[\r\n]" " " ${_link_DIR} "${${_link_DIR}}")
- exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --libs
+ execute_process(COMMAND ${PKGCONFIG_EXECUTABLE} ${_package} --libs
OUTPUT_VARIABLE ${_link_FLAGS} )
string(REGEX REPLACE "[\r\n]" " " ${_link_FLAGS} "${${_link_FLAGS}}")
- exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --cflags
+ execute_process(COMMAND ${PKGCONFIG_EXECUTABLE} ${_package} --cflags
OUTPUT_VARIABLE ${_cflags} )
string(REGEX REPLACE "[\r\n]" " " ${_cflags} "${${_cflags}}")
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index ca16bc2..cece973 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -189,7 +189,7 @@ ensure generated files will receive the required settings.
:ref:`Makefile <Makefile Generators>`,
:ref:`Ninja <Ninja Generators>`, :generator:`Xcode`, and
:ref:`Visual Studio <Visual Studio Generators>`
- (:generator:`Visual Studio 11 2012` and above) generators. Default value is
+ (:generator:`Visual Studio 12 2013` and above) generators. Default value is
``FALSE``.
.. versionadded:: 3.21
@@ -353,7 +353,7 @@ as well as ``SWIG``:
:ref:`Makefile <Makefile Generators>`,
:ref:`Ninja <Ninja Generators>`, :generator:`Xcode`, and
:ref:`Visual Studio <Visual Studio Generators>`
- (:generator:`Visual Studio 11 2012` and above) generators. Default value is
+ (:generator:`Visual Studio 12 2013` and above) generators. Default value is
``FALSE``.
Source file property ``USE_SWIG_DEPENDENCIES``, if not defined, will be
diff --git a/README.rst b/README.rst
index 64e2353..d885740 100644
--- a/README.rst
+++ b/README.rst
@@ -68,8 +68,8 @@ you can build directly in the source tree::
Or, if you plan to develop CMake or otherwise run the test suite, create
a separate build tree::
- $ mkdir cmake-build && cd cmake-build
- $ ../cmake-source/bootstrap && make
+ $ mkdir build && cd build
+ $ ../bootstrap && make
Windows
^^^^^^^
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index f022dda..37d407b 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -128,7 +128,8 @@ add_library(
cmCLocaleEnvironmentScope.cxx
cmCMakePath.h
cmCMakePath.cxx
- cmCMakePresetErrors.h
+ cmCMakePresetsErrors.cxx
+ cmCMakePresetsErrors.h
cmCMakePresetsGraph.cxx
cmCMakePresetsGraph.h
cmCMakePresetsGraphInternal.h
@@ -170,6 +171,8 @@ add_library(
cmCustomCommandTypes.h
cmCxxModuleMapper.cxx
cmCxxModuleMapper.h
+ cmCxxModuleUsageEffects.cxx
+ cmCxxModuleUsageEffects.h
cmDefinitions.cxx
cmDefinitions.h
cmDependencyProvider.h
@@ -298,6 +301,8 @@ add_library(
cmGraphAdjacencyList.h
cmGraphVizWriter.cxx
cmGraphVizWriter.h
+ cmImportedCxxModuleInfo.cxx
+ cmImportedCxxModuleInfo.h
cmInstallGenerator.h
cmInstallGenerator.cxx
cmInstallGetRuntimeDependenciesGenerator.h
@@ -323,6 +328,7 @@ add_library(
cmInstallTargetGenerator.cxx
cmInstallDirectoryGenerator.h
cmInstallDirectoryGenerator.cxx
+ cmJSONHelpers.cxx
cmJSONHelpers.h
cmJSONState.cxx
cmJSONState.h
@@ -371,6 +377,8 @@ add_library(
cmNewLineStyle.cxx
cmOrderDirectories.cxx
cmOrderDirectories.h
+ cmPlistParser.cxx
+ cmPlistParser.h
cmPolicies.h
cmPolicies.cxx
cmProcessOutput.cxx
@@ -420,6 +428,7 @@ add_library(
cmStateTypes.h
cmStringAlgorithms.cxx
cmStringAlgorithms.h
+ cmSyntheticTargetCache.h
cmSystemTools.cxx
cmSystemTools.h
cmTarget.cxx
@@ -438,6 +447,7 @@ add_library(
cmUVHandlePtr.h
cmUVProcessChain.cxx
cmUVProcessChain.h
+ cmUVStream.h
cmUVStreambuf.h
cmUVSignalHackRAII.h
cmVariableWatch.cxx
@@ -450,6 +460,8 @@ add_library(
cmWorkerPool.h
cmWorkingDirectory.cxx
cmWorkingDirectory.h
+ cmXcFramework.cxx
+ cmXcFramework.h
cmXMLParser.cxx
cmXMLParser.h
cmXMLSafe.cxx
@@ -733,6 +745,8 @@ add_library(
cm_utf8.c
cm_codecvt.hxx
cm_codecvt.cxx
+ cm_fileno.hxx
+ cm_fileno.cxx
cmDuration.h
cmDuration.cxx
@@ -774,8 +788,6 @@ if(CMake_ENABLE_DEBUGGER)
cmDebuggerBreakpointManager.h
cmDebuggerExceptionManager.cxx
cmDebuggerExceptionManager.h
- cmDebuggerPipeConnection.cxx
- cmDebuggerPipeConnection.h
cmDebuggerProtocol.cxx
cmDebuggerProtocol.h
cmDebuggerSourceBreakpoint.cxx
@@ -793,6 +805,21 @@ if(CMake_ENABLE_DEBUGGER)
cmDebuggerVariablesManager.cxx
cmDebuggerVariablesManager.h
)
+ if(WIN32)
+ target_sources(
+ CMakeLib
+ PRIVATE
+ cmDebuggerWindowsPipeConnection.cxx
+ cmDebuggerWindowsPipeConnection.h
+ )
+ else()
+ target_sources(
+ CMakeLib
+ PRIVATE
+ cmDebuggerPosixPipeConnection.cxx
+ cmDebuggerPosixPipeConnection.h
+ )
+ endif()
target_link_libraries(CMakeLib PUBLIC cppdap::cppdap)
endif()
@@ -928,6 +955,43 @@ if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
)
endif()
+if(CMake_BUILD_PCH)
+ target_precompile_headers(CMakeLib PRIVATE
+ "$<$<COMPILE_LANGUAGE:CXX>:<string$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:<iostream$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:<sstream$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:<iomanip$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:<cm/memory$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:<cm3p/cppdap/protocol.h$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmMakefile.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmGlobalGenerator.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmLocalGenerator.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmGeneratorTarget.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmGeneratorExpression.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmArgumentParser.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmake.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmCMakePath.h>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmCurl.h>")
+
+ set_source_files_properties(
+ "LexerParser/cmFortranLexer.cxx"
+ PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
+
+ if(WIN32)
+ target_precompile_headers(CMakeLib PRIVATE
+ "$<$<COMPILE_LANGUAGE:CXX>:<cm3p/uv.h$<ANGLE-R>>"
+ "$<$<COMPILE_LANGUAGE:CXX>:cmVSSetupHelper.h>")
+ set_source_files_properties("LexerParser/cmFortranParser.cxx" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
+ else()
+ set_source_files_properties(
+ "LexerParser/cmCommandArgumentLexer.cxx"
+ "LexerParser/cmGccDepfileLexer.cxx"
+ "LexerParser/cmExprLexer.cxx"
+ "LexerParser/cmDependsJavaLexer.cxx"
+ PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
+ endif()
+endif()
+
# Temporary variable for tools targets
set(_tools)
@@ -1036,6 +1100,24 @@ target_include_directories(
)
target_link_libraries(CTestLib PUBLIC CMakeLib)
+if(CMake_BUILD_PCH)
+ target_precompile_headers(CTestLib PRIVATE
+ "cmDuration.h"
+ "cmMakefile.h"
+ "cmSystemTools.h"
+ "cmGlobalGenerator.h"
+ "cmake.h"
+ "CTest/cmCTestGenericHandler.h"
+ "<sstream>"
+ "<cm3p/uv.h>")
+
+ if(WIN32)
+ target_precompile_headers(CTestLib PRIVATE "cmCurl.h" "CTest/cmCTestMultiProcessHandler.h")
+ else()
+ set_source_files_properties("LexerParser/cmCTestResourceGroupsLexer.cxx" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
+ endif()
+endif()
+
#
# Build CPackLib
#
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 650ecf6..df094db 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 27)
-set(CMake_VERSION_PATCH 4)
+set(CMake_VERSION_PATCH 20230912)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 1ea78fd..5077596 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -7,6 +7,7 @@
#include <cm/memory>
#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
@@ -54,7 +55,7 @@ int cmCPackWIXGenerator::InitializeInternal()
bool cmCPackWIXGenerator::RunWiXCommand(std::string const& command)
{
- std::string logFileName = this->CPackTopLevel + "/wix.log";
+ std::string logFileName = cmStrCat(this->CPackTopLevel, "/wix.log");
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Running WiX command: " << command << std::endl);
@@ -62,8 +63,9 @@ bool cmCPackWIXGenerator::RunWiXCommand(std::string const& command)
std::string output;
int returnValue = 0;
- bool status = cmSystemTools::RunSingleCommand(
- command, &output, &output, &returnValue, 0, cmSystemTools::OUTPUT_NONE);
+ bool status =
+ cmSystemTools::RunSingleCommand(command, &output, &output, &returnValue,
+ nullptr, cmSystemTools::OUTPUT_NONE);
cmsys::ofstream logFile(logFileName.c_str(), std::ios::app);
logFile << command << std::endl;
@@ -102,22 +104,22 @@ bool cmCPackWIXGenerator::RunCandleCommand(std::string const& sourceFile,
}
std::ostringstream command;
- command << QuotePath(executable);
- command << " -nologo";
- command << " -arch " << arch;
- command << " -out " << QuotePath(objectFile);
+ command << QuotePath(executable)
+ << " -nologo"
+ " -arch "
+ << arch << " -out " << QuotePath(objectFile);
for (std::string const& ext : CandleExtensions) {
command << " -ext " << QuotePath(ext);
}
if (!cmHasSuffix(sourceFile, this->CPackTopLevel)) {
- command << " " << QuotePath("-I" + this->CPackTopLevel);
+ command << ' ' << QuotePath(cmStrCat("-I", this->CPackTopLevel));
}
AddCustomFlags("CPACK_WIX_CANDLE_EXTRA_FLAGS", command);
- command << " " << QuotePath(sourceFile);
+ command << ' ' << QuotePath(sourceFile);
return RunWiXCommand(command.str());
}
@@ -130,9 +132,10 @@ bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
}
std::ostringstream command;
- command << QuotePath(executable);
- command << " -nologo";
- command << " -out " << QuotePath(CMakeToWixPath(packageFileNames.at(0)));
+ command << QuotePath(executable)
+ << " -nologo"
+ " -out "
+ << QuotePath(CMakeToWixPath(packageFileNames.at(0)));
for (std::string const& ext : this->LightExtensions) {
command << " -ext " << QuotePath(ext);
@@ -145,7 +148,7 @@ bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
AddCustomFlags("CPACK_WIX_LIGHT_EXTRA_FLAGS", command);
- command << " " << objectFiles;
+ command << ' ' << objectFiles;
return RunWiXCommand(command.str());
}
@@ -196,7 +199,8 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
}
if (!GetOption("CPACK_WIX_LICENSE_RTF")) {
- std::string licenseFilename = this->CPackTopLevel + "/License.rtf";
+ std::string licenseFilename =
+ cmStrCat(this->CPackTopLevel, "/License.rtf");
SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename);
if (!CreateLicenseFile()) {
@@ -293,14 +297,14 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
usedBaseNames.insert(uniqueBaseName);
std::string objectFilename =
- this->CPackTopLevel + "/" + uniqueBaseName + ".wixobj";
+ cmStrCat(this->CPackTopLevel, '/', uniqueBaseName, ".wixobj");
if (!RunCandleCommand(CMakeToWixPath(sourceFilename),
CMakeToWixPath(objectFilename))) {
return false;
}
- objectFiles << " " << QuotePath(CMakeToWixPath(objectFilename));
+ objectFiles << ' ' << QuotePath(CMakeToWixPath(objectFilename));
}
AppendUserSuppliedExtraObjects(objectFiles);
@@ -311,8 +315,9 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
void cmCPackWIXGenerator::AppendUserSuppliedExtraSources()
{
cmValue cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES");
- if (!cpackWixExtraSources)
+ if (!cpackWixExtraSources) {
return;
+ }
cmExpandList(cpackWixExtraSources, this->WixSources);
}
@@ -320,8 +325,9 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraSources()
void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
{
cmValue cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS");
- if (!cpackWixExtraObjects)
+ if (!cpackWixExtraObjects) {
return;
+ }
cmList expandedExtraObjects{ cpackWixExtraObjects };
@@ -332,7 +338,8 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
{
- std::string includeFilename = this->CPackTopLevel + "/cpack_variables.wxi";
+ std::string includeFilename =
+ cmStrCat(this->CPackTopLevel, "/cpack_variables.wxi");
cmWIXSourceWriter includeFile(this->Logger, includeFilename,
this->ComponentGuidType,
@@ -356,7 +363,8 @@ void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
{
- std::string includeFilename = this->CPackTopLevel + "/properties.wxi";
+ std::string includeFilename =
+ cmStrCat(this->CPackTopLevel, "/properties.wxi");
cmWIXSourceWriter includeFile(this->Logger, includeFilename,
this->ComponentGuidType,
@@ -405,7 +413,8 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
{
- std::string includeFilename = this->CPackTopLevel + "/product_fragment.wxi";
+ std::string includeFilename =
+ cmStrCat(this->CPackTopLevel, "/product_fragment.wxi");
cmWIXSourceWriter includeFile(this->Logger, includeFilename,
this->ComponentGuidType,
@@ -444,7 +453,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
// if install folder is supposed to be set absolutely, the default
// component guid "*" cannot be used
std::string directoryDefinitionsFilename =
- this->CPackTopLevel + "/directories.wxs";
+ cmStrCat(this->CPackTopLevel, "/directories.wxs");
this->WixSources.push_back(directoryDefinitionsFilename);
@@ -466,7 +475,8 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
directoryDefinitions.BeginInstallationPrefixDirectory(GetRootFolderId(),
installRoot);
- std::string fileDefinitionsFilename = this->CPackTopLevel + "/files.wxs";
+ std::string fileDefinitionsFilename =
+ cmStrCat(this->CPackTopLevel, "/files.wxs");
this->WixSources.push_back(fileDefinitionsFilename);
@@ -477,7 +487,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
fileDefinitions.BeginElement("Fragment");
std::string featureDefinitionsFilename =
- this->CPackTopLevel + "/features.wxs";
+ cmStrCat(this->CPackTopLevel, "/features.wxs");
this->WixSources.push_back(featureDefinitionsFilename);
@@ -536,7 +546,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
std::string componentPath = cmStrCat(toplevel, '/', component.Name);
- std::string const componentFeatureId = "CM_C_" + component.Name;
+ std::string const componentFeatureId = cmStrCat("CM_C_", component.Name);
cmWIXShortcuts featureShortcuts;
AddComponentsToFeature(componentPath, componentFeatureId,
@@ -556,7 +566,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
bool emitUninstallShortcut = true;
cmValue cpackWixProgramMenuFolder =
GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
- if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == ".") {
+ if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == "."_s) {
emitUninstallShortcut = false;
} else if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) ==
emittedShortcutTypes.end()) {
@@ -613,7 +623,7 @@ std::string cmCPackWIXGenerator::GetRootFolderId() const
result = *rootFolderId;
}
- if (GetArchitecture() == "x86") {
+ if (GetArchitecture() == "x86"_s) {
cmSystemTools::ReplaceString(result, "<64>", "");
} else {
cmSystemTools::ReplaceString(result, "<64>", "64");
@@ -636,7 +646,7 @@ bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate()
return false;
}
- std::string mainSourceFilePath = this->CPackTopLevel + "/main.wxs";
+ std::string mainSourceFilePath = cmStrCat(this->CPackTopLevel, "/main.wxs");
if (!ConfigureFile(wixTemplate, mainSourceFilePath)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -656,7 +666,7 @@ bool cmCPackWIXGenerator::CreateFeatureHierarchy(
{
for (auto const& i : ComponentGroups) {
cmCPackComponentGroup const& group = i.second;
- if (group.ParentGroup == 0) {
+ if (group.ParentGroup == nullptr) {
featureDefinitions.EmitFeatureForComponentGroup(group, *this->Patch);
}
}
@@ -757,7 +767,7 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
case cmWIXShortcuts::START_MENU: {
cmValue cpackWixProgramMenuFolder =
GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
- if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == ".") {
+ if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == "."_s) {
directoryId = "ProgramMenuFolder";
} else {
directoryId = "PROGRAM_MENU_FOLDER";
@@ -788,13 +798,13 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
std::string idSuffix;
if (!cpackComponentName.empty()) {
- idSuffix += "_";
+ idSuffix += '_';
idSuffix += cpackComponentName;
}
std::string componentId = "CM_SHORTCUT";
- if (idPrefix.size()) {
- componentId += "_" + idPrefix;
+ if (!idPrefix.empty()) {
+ componentId += cmStrCat('_', idPrefix);
}
componentId += idSuffix;
@@ -810,7 +820,7 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
this->Patch->ApplyFragment(componentId, fileDefinitions);
std::string registryKey =
- std::string("Software\\") + cpackVendor + "\\" + cpackPackageName;
+ cmStrCat("Software\\", cpackVendor, '\\', cpackPackageName);
shortcuts.EmitShortcuts(type, registryKey, cpackComponentName,
fileDefinitions);
@@ -818,9 +828,9 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
if (type == cmWIXShortcuts::START_MENU) {
cmValue cpackWixProgramMenuFolder =
GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
- if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder != ".") {
- fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" +
- idSuffix);
+ if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder != "."_s) {
+ fileDefinitions.EmitRemoveFolder(
+ cmStrCat("CM_REMOVE_PROGRAM_MENU_FOLDER", idSuffix));
}
}
@@ -851,10 +861,10 @@ bool cmCPackWIXGenerator::CreateLicenseFile()
std::string extension = GetRightmostExtension(licenseSourceFilename);
- if (extension == ".rtf") {
+ if (extension == ".rtf"_s) {
cmSystemTools::CopyAFile(licenseSourceFilename.c_str(),
licenseDestinationFilename.c_str());
- } else if (extension == ".txt") {
+ } else if (extension == ".txt"_s) {
cmWIXRichTextFormatWriter rtfWriter(licenseDestinationFilename);
cmsys::ifstream licenseSource(licenseSourceFilename.c_str());
@@ -923,19 +933,18 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
for (size_t i = 0; i < dir.GetNumberOfFiles(); ++i) {
std::string fileName = dir.GetFile(static_cast<unsigned long>(i));
- if (fileName == "." || fileName == "..") {
+ if (fileName == "."_s || fileName == ".."_s) {
continue;
}
- std::string fullPath = topdir + "/" + fileName;
+ std::string fullPath = cmStrCat(topdir, '/', fileName);
- std::string relativePath =
- cmSystemTools::RelativePath(toplevel.c_str(), fullPath.c_str());
+ std::string relativePath = cmSystemTools::RelativePath(toplevel, fullPath);
std::string id = PathToId(relativePath);
- if (cmSystemTools::FileIsDirectory(fullPath.c_str())) {
- std::string subDirectoryId = std::string("CM_D") + id;
+ if (cmSystemTools::FileIsDirectory(fullPath)) {
+ std::string subDirectoryId = cmStrCat("CM_D", id);
directoryDefinitions.BeginElement("Directory");
directoryDefinitions.AddAttribute("Id", subDirectoryId);
@@ -965,7 +974,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
std::string const& textLabel = packageExecutables[j];
if (cmSystemTools::LowerCase(fileName) ==
- cmSystemTools::LowerCase(executableName) + ".exe") {
+ cmStrCat(cmSystemTools::LowerCase(executableName), ".exe")) {
cmWIXShortcut shortcut;
shortcut.label = textLabel;
shortcut.workingDirectoryId = directoryId;
@@ -988,12 +997,12 @@ bool cmCPackWIXGenerator::RequireOption(std::string const& name,
value = *tmp;
return true;
- } else {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Required variable " << name << " not set" << std::endl);
-
- return false;
}
+
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Required variable " << name << " not set" << std::endl);
+
+ return false;
}
std::string cmCPackWIXGenerator::GetArchitecture() const
@@ -1001,11 +1010,10 @@ std::string cmCPackWIXGenerator::GetArchitecture() const
std::string void_p_size;
RequireOption("CPACK_WIX_SIZEOF_VOID_P", void_p_size);
- if (void_p_size == "8") {
+ if (void_p_size == "8"_s) {
return "x64";
- } else {
- return "x86";
}
+ return "x86";
}
std::string cmCPackWIXGenerator::GenerateGUID()
@@ -1034,7 +1042,7 @@ std::string cmCPackWIXGenerator::GenerateGUID()
std::string cmCPackWIXGenerator::QuotePath(std::string const& path)
{
- return std::string("\"") + path + '"';
+ return cmStrCat('"', path, '"');
}
std::string cmCPackWIXGenerator::GetRightmostExtension(
@@ -1042,7 +1050,7 @@ std::string cmCPackWIXGenerator::GetRightmostExtension(
{
std::string extension;
- std::string::size_type i = filename.rfind(".");
+ std::string::size_type i = filename.rfind('.');
if (i != std::string::npos) {
extension = filename.substr(i);
}
@@ -1052,9 +1060,10 @@ std::string cmCPackWIXGenerator::GetRightmostExtension(
std::string cmCPackWIXGenerator::PathToId(std::string const& path)
{
- id_map_t::const_iterator i = PathToIdMap.find(path);
- if (i != PathToIdMap.end())
+ auto i = PathToIdMap.find(path);
+ if (i != PathToIdMap.end()) {
return i->second;
+ }
std::string id = CreateNewIdForPath(path);
return id;
@@ -1063,7 +1072,7 @@ std::string cmCPackWIXGenerator::PathToId(std::string const& path)
std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
{
std::vector<std::string> components;
- cmSystemTools::SplitPath(path.c_str(), components, false);
+ cmSystemTools::SplitPath(path, components, false);
size_t replacementCount = 0;
@@ -1071,8 +1080,9 @@ std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
std::string currentComponent;
for (size_t i = 1; i < components.size(); ++i) {
- if (i != 1)
+ if (i != 1) {
identifier += '.';
+ }
currentComponent =
NormalizeComponentForId(components[i], replacementCount);
@@ -1088,18 +1098,19 @@ std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
}
std::ostringstream result;
- result << idPrefix << "_" << identifier;
+ result << idPrefix << '_' << identifier;
size_t ambiguityCount = ++IdAmbiguityCounter[identifier];
if (ambiguityCount > 999) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while trying to generate a unique Id for '"
- << path << "'" << std::endl);
+ << path << '\'' << std::endl);
return std::string();
- } else if (ambiguityCount > 1) {
- result << "_" << ambiguityCount;
+ }
+ if (ambiguityCount > 1) {
+ result << '_' << ambiguityCount;
}
std::string resultString = result.str();
@@ -1157,8 +1168,9 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName,
extension_set_t& extensions)
{
cmValue variableContent = GetOption(variableName);
- if (!variableContent)
+ if (!variableContent) {
return;
+ }
cmList list{ variableContent };
extensions.insert(list.begin(), list.end());
@@ -1182,7 +1194,8 @@ void cmCPackWIXGenerator::CollectXmlNamespaces(std::string const& variableName,
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Invalid element in CPACK_WIX_CUSTOM_XMLNS ignored: "
- << "\"" << str << "\"" << std::endl);
+ "\""
+ << str << '"' << std::endl);
}
}
std::ostringstream oss;
@@ -1197,13 +1210,14 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName,
std::ostream& stream)
{
cmValue variableContent = GetOption(variableName);
- if (!variableContent)
+ if (!variableContent) {
return;
+ }
cmList list{ variableContent };
for (std::string const& i : list) {
- stream << " " << QuotePath(i);
+ stream << ' ' << QuotePath(i);
}
}
@@ -1222,6 +1236,7 @@ std::string cmCPackWIXGenerator::RelativePathWithoutComponentPrefix(
void cmCPackWIXGenerator::InjectXmlNamespaces(cmWIXSourceWriter& sourceWriter)
{
for (auto& ns : this->CustomXmlNamespaces) {
- sourceWriter.AddAttributeUnlessEmpty("xmlns:" + ns.first, ns.second);
+ sourceWriter.AddAttributeUnlessEmpty(cmStrCat("xmlns:", ns.first),
+ ns.second);
}
}
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 2261a66..0ebe2f4 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -102,13 +102,14 @@ bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name)
"Write",
"WriteAttributes",
"WriteExtendedAttributes",
- 0
+ nullptr
};
size_t i = 0;
while (validAttributes[i]) {
- if (name == validAttributes[i++])
+ if (name == validAttributes[i++]) {
return true;
+ }
}
return false;
@@ -118,9 +119,8 @@ void cmWIXAccessControlList::EmitBooleanAttribute(std::string const& entry,
std::string const& name)
{
if (!this->IsBooleanAttribute(name)) {
- std::ostringstream message;
- message << "Unknown boolean attribute '" << name << "'";
- this->ReportError(entry, message.str());
+ this->ReportError(entry,
+ cmStrCat("Unknown boolean attribute '", name, '\''));
}
this->SourceWriter.AddAttribute(name, "yes");
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
index 0a83ca2..a655d86 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXDirectoriesSourceWriter.h"
+#include <cmext/string_view>
+
cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter(
cmCPackLog* logger, std::string const& filename, GuidType componentGuidType)
: cmWIXSourceWriter(logger, filename, componentGuidType)
@@ -14,7 +16,7 @@ void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
BeginElement("Directory");
AddAttribute("Id", "ProgramMenuFolder");
- if (startMenuFolder != ".") {
+ if (startMenuFolder != "."_s) {
BeginElement("Directory");
AddAttribute("Id", "PROGRAM_MENU_FOLDER");
AddAttribute("Name", startMenuFolder);
@@ -53,7 +55,7 @@ size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
std::vector<std::string> installRoot;
- cmSystemTools::SplitPath(installRootString.c_str(), installRoot);
+ cmSystemTools::SplitPath(installRootString, installRoot);
if (!installRoot.empty() && installRoot.back().empty()) {
installRoot.pop_back();
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
index a7a0648..78c2208 100644
--- a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXFeaturesSourceWriter.h"
+#include "cmStringAlgorithms.h"
+
cmWIXFeaturesSourceWriter::cmWIXFeaturesSourceWriter(
cmCPackLog* logger, std::string const& filename, GuidType componentGuidType)
: cmWIXSourceWriter(logger, filename, componentGuidType)
@@ -17,7 +19,7 @@ void cmWIXFeaturesSourceWriter::CreateCMakePackageRegistryEntry(
AddAttribute("Guid", CreateGuidFromComponentId("CM_PACKAGE_REGISTRY"));
std::string registryKey =
- std::string("Software\\Kitware\\CMake\\Packages\\") + package;
+ cmStrCat(R"(Software\Kitware\CMake\Packages\)", package);
BeginElement("RegistryValue");
AddAttribute("Root", "HKLM");
@@ -35,7 +37,7 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponentGroup(
cmCPackComponentGroup const& group, cmWIXPatch& patch)
{
BeginElement("Feature");
- AddAttribute("Id", "CM_G_" + group.Name);
+ AddAttribute("Id", cmStrCat("CM_G_", group.Name));
if (group.IsExpandedByDefault) {
AddAttribute("Display", "expand");
@@ -44,7 +46,7 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponentGroup(
AddAttributeUnlessEmpty("Title", group.DisplayName);
AddAttributeUnlessEmpty("Description", group.Description);
- patch.ApplyFragment("CM_G_" + group.Name, *this);
+ patch.ApplyFragment(cmStrCat("CM_G_", group.Name), *this);
for (cmCPackComponentGroup* subgroup : group.Subgroups) {
EmitFeatureForComponentGroup(*subgroup, patch);
@@ -61,7 +63,7 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponent(
cmCPackComponent const& component, cmWIXPatch& patch)
{
BeginElement("Feature");
- AddAttribute("Id", "CM_C_" + component.Name);
+ AddAttribute("Id", cmStrCat("CM_C_", component.Name));
AddAttributeUnlessEmpty("Title", component.DisplayName);
AddAttributeUnlessEmpty("Description", component.Description);
@@ -78,7 +80,7 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponent(
AddAttribute("Level", "2");
}
- patch.ApplyFragment("CM_C_" + component.Name, *this);
+ patch.ApplyFragment(cmStrCat("CM_C_", component.Name), *this);
EndElement("Feature");
}
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index 122ffaf..c65449c 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -14,7 +14,7 @@ bool cmWIXPatch::LoadFragments(std::string const& patchFilePath)
cmWIXPatchParser parser(Fragments, Logger);
if (!parser.ParseFile(patchFilePath.c_str())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Failed parsing XML patch file: '" << patchFilePath << "'"
+ "Failed parsing XML patch file: '" << patchFilePath << '\''
<< std::endl);
return false;
}
@@ -25,9 +25,10 @@ bool cmWIXPatch::LoadFragments(std::string const& patchFilePath)
void cmWIXPatch::ApplyFragment(std::string const& id,
cmWIXSourceWriter& writer)
{
- cmWIXPatchParser::fragment_map_t::iterator i = Fragments.find(id);
- if (i == Fragments.end())
+ auto i = Fragments.find(id);
+ if (i == Fragments.end()) {
return;
+ }
const cmWIXPatchElement& fragment = i->second;
for (auto const& attr : fragment.attributes) {
@@ -75,9 +76,9 @@ bool cmWIXPatch::CheckForUnappliedFragments()
fragmentList += ", ";
}
- fragmentList += "'";
+ fragmentList += '\'';
fragmentList += fragment.first;
- fragmentList += "'";
+ fragmentList += '\'';
}
if (!fragmentList.empty()) {
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index 8b26c4e..136eaac 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -5,6 +5,7 @@
#include <utility>
#include <cm/memory>
+#include <cmext/string_view>
#include <cm3p/expat.h>
@@ -20,9 +21,7 @@ cmWIXPatchNode::Type cmWIXPatchElement::type()
return cmWIXPatchNode::ELEMENT;
}
-cmWIXPatchNode::~cmWIXPatchNode()
-{
-}
+cmWIXPatchNode::~cmWIXPatchNode() = default;
cmWIXPatchElement::cmWIXPatchElement() = default;
cmWIXPatchElement::~cmWIXPatchElement() = default;
@@ -39,13 +38,13 @@ cmWIXPatchParser::cmWIXPatchParser(fragment_map_t& fragments,
void cmWIXPatchParser::StartElement(const std::string& name, const char** atts)
{
if (State == BEGIN_DOCUMENT) {
- if (name == "CPackWiXPatch") {
+ if (name == "CPackWiXPatch"_s) {
State = BEGIN_FRAGMENTS;
} else {
ReportValidationError("Expected root element 'CPackWiXPatch'");
}
} else if (State == BEGIN_FRAGMENTS) {
- if (name == "CPackWiXFragment") {
+ if (name == "CPackWiXFragment"_s) {
State = INSIDE_FRAGMENT;
StartFragment(atts);
} else {
@@ -78,7 +77,7 @@ void cmWIXPatchParser::StartFragment(const char** attributes)
const std::string key = attributes[i];
const std::string value = attributes[i + 1];
- if (key == "Id") {
+ if (key == "Id"_s) {
if (Fragments.find(value) != Fragments.end()) {
std::ostringstream tmp;
tmp << "Invalid reuse of 'CPackWixFragment' 'Id': " << value;
@@ -98,7 +97,7 @@ void cmWIXPatchParser::StartFragment(const char** attributes)
const std::string key = attributes[i];
const std::string value = attributes[i + 1];
- if (key != "Id") {
+ if (key != "Id"_s) {
new_element->attributes[key] = value;
}
}
@@ -108,7 +107,7 @@ void cmWIXPatchParser::StartFragment(const char** attributes)
void cmWIXPatchParser::EndElement(const std::string& name)
{
if (State == INSIDE_FRAGMENT) {
- if (name == "CPackWiXFragment") {
+ if (name == "CPackWiXFragment"_s) {
State = BEGIN_FRAGMENTS;
ElementStack.clear();
} else {
@@ -142,7 +141,7 @@ void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while processing XML patch file at "
- << line << ":" << column << ": " << msg << std::endl);
+ << line << ':' << column << ": " << msg << std::endl);
Valid = false;
}
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
index d7e534a..8a63239 100644
--- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
@@ -135,7 +135,7 @@ void cmWIXRichTextFormatWriter::WriteDocumentPrefix()
void cmWIXRichTextFormatWriter::ControlWord(std::string const& keyword)
{
- File << "\\" << keyword;
+ File << '\\' << keyword;
}
void cmWIXRichTextFormatWriter::NewControlWord(std::string const& keyword)
@@ -158,7 +158,8 @@ void cmWIXRichTextFormatWriter::EmitUnicodeCodepoint(int c)
// Do not emit byte order mark (BOM)
if (c == 0xFEFF) {
return;
- } else if (c <= 0xFFFF) {
+ }
+ if (c <= 0xFFFF) {
EmitUnicodeSurrogate(c);
} else {
c -= 0x10000;
@@ -175,12 +176,12 @@ void cmWIXRichTextFormatWriter::EmitUnicodeSurrogate(int c)
} else {
File << (c - 65536);
}
- File << "?";
+ File << '?';
}
void cmWIXRichTextFormatWriter::EmitInvalidCodepoint(int c)
{
ControlWord("cf1 ");
- File << "[INVALID-BYTE-" << int(c) << "]";
+ File << "[INVALID-BYTE-" << c << ']';
ControlWord("cf0 ");
}
diff --git a/Source/CPack/WiX/cmWIXShortcut.cxx b/Source/CPack/WiX/cmWIXShortcut.cxx
index c3eb219..1cfb6c1 100644
--- a/Source/CPack/WiX/cmWIXShortcut.cxx
+++ b/Source/CPack/WiX/cmWIXShortcut.cxx
@@ -20,7 +20,7 @@ bool cmWIXShortcuts::EmitShortcuts(
std::string const& cpackComponentName,
cmWIXFilesSourceWriter& fileDefinitions) const
{
- shortcut_type_map_t::const_iterator i = this->Shortcuts.find(type);
+ auto i = this->Shortcuts.find(type);
if (i == this->Shortcuts.end()) {
return false;
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index 8e9bfdf..ef6712a 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -5,6 +5,7 @@
#include <windows.h>
#include "cmCPackGenerator.h"
+#include "cmCryptoHash.h"
#include "cmUuid.h"
cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
@@ -34,7 +35,7 @@ cmWIXSourceWriter::~cmWIXSourceWriter()
cmCPackLogger(cmCPackLog::LOG_ERROR,
Elements.size() - 1
<< " WiX elements were still open when closing '"
- << SourceFilename << "'" << std::endl);
+ << SourceFilename << '\'' << std::endl);
return;
}
@@ -44,12 +45,12 @@ cmWIXSourceWriter::~cmWIXSourceWriter()
void cmWIXSourceWriter::BeginElement(std::string const& name)
{
if (State == BEGIN) {
- File << ">";
+ File << '>';
}
- File << "\n";
+ File << '\n';
Indent(Elements.size());
- File << "<" << name;
+ File << '<' << name;
Elements.push_back(name);
State = BEGIN;
@@ -60,7 +61,7 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
if (Elements.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"can not end WiX element with no open elements in '"
- << SourceFilename << "'" << std::endl);
+ << SourceFilename << '\'' << std::endl);
return;
}
@@ -68,14 +69,14 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
cmCPackLogger(cmCPackLog::LOG_ERROR,
"WiX element <"
<< Elements.back() << "> can not be closed by </" << name
- << "> in '" << SourceFilename << "'" << std::endl);
+ << "> in '" << SourceFilename << '\'' << std::endl);
return;
}
if (State == DEFAULT) {
- File << "\n";
+ File << '\n';
Indent(Elements.size() - 1);
- File << "</" << Elements.back() << ">";
+ File << "</" << Elements.back() << '>';
} else {
File << "/>";
}
@@ -87,17 +88,17 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
void cmWIXSourceWriter::AddTextNode(std::string const& text)
{
if (State == BEGIN) {
- File << ">";
+ File << '>';
}
if (Elements.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"can not add text without open WiX element in '"
- << SourceFilename << "'" << std::endl);
+ << SourceFilename << '\'' << std::endl);
return;
}
- File << this->EscapeAttributeValue(text);
+ File << cmWIXSourceWriter::EscapeAttributeValue(text);
State = DEFAULT;
}
@@ -105,12 +106,12 @@ void cmWIXSourceWriter::AddProcessingInstruction(std::string const& target,
std::string const& content)
{
if (State == BEGIN) {
- File << ">";
+ File << '>';
}
- File << "\n";
+ File << '\n';
Indent(Elements.size());
- File << "<?" << target << " " << content << "?>";
+ File << "<?" << target << ' ' << content << "?>";
State = DEFAULT;
}
@@ -118,7 +119,7 @@ void cmWIXSourceWriter::AddProcessingInstruction(std::string const& target,
void cmWIXSourceWriter::AddAttribute(std::string const& key,
std::string const& value)
{
- File << " " << key << "=\"" << EscapeAttributeValue(value) << '"';
+ File << ' ' << key << "=\"" << EscapeAttributeValue(value) << '"';
}
void cmWIXSourceWriter::AddAttributeUnlessEmpty(std::string const& key,
@@ -134,7 +135,8 @@ std::string cmWIXSourceWriter::CreateGuidFromComponentId(
{
std::string guid = "*";
if (this->ComponentGuidType == CMAKE_GENERATED_GUID) {
- std::string md5 = cmSystemTools::ComputeStringMD5(componentId);
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ std::string md5 = hasher.HashString(componentId);
cmUuid uuid;
std::vector<unsigned char> ns;
guid = uuid.FromMd5(ns, md5);
@@ -144,7 +146,7 @@ std::string cmWIXSourceWriter::CreateGuidFromComponentId(
void cmWIXSourceWriter::WriteXMLDeclaration()
{
- File << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
+ File << R"(<?xml version="1.0" encoding="UTF-8"?>)" << std::endl;
}
void cmWIXSourceWriter::Indent(size_t count)
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index 7e6e473..37be798 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -86,24 +86,28 @@ int cmCPackBundleGenerator::ConstructBundle()
std::string const staging = toplevel;
std::ostringstream contents;
- contents << staging << "/" << cpack_bundle_name << ".app/"
- << "Contents";
+ contents << staging << "/" << cpack_bundle_name
+ << ".app/"
+ "Contents";
std::ostringstream application;
- application << contents.str() << "/"
- << "MacOS";
+ application << contents.str()
+ << "/"
+ "MacOS";
std::ostringstream resources;
- resources << contents.str() << "/"
- << "Resources";
+ resources << contents.str()
+ << "/"
+ "Resources";
// Install a required, user-provided bundle metadata file ...
std::ostringstream plist_source;
plist_source << cpack_bundle_plist;
std::ostringstream plist_target;
- plist_target << contents.str() << "/"
- << "Info.plist";
+ plist_target << contents.str()
+ << "/"
+ "Info.plist";
if (!this->CopyFile(plist_source, plist_target)) {
cmCPackLogger(
@@ -196,15 +200,11 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
// sign the files supplied by the user, ie. frameworks.
for (auto const& file : relFiles) {
- std::ostringstream temp_sign_file_cmd;
- temp_sign_file_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
- temp_sign_file_cmd << " " << sign_parameter << " -s \""
- << cpack_apple_cert_app;
- temp_sign_file_cmd << "\" -i ";
- temp_sign_file_cmd << this->GetOption("CPACK_APPLE_BUNDLE_ID");
- temp_sign_file_cmd << " \"";
- temp_sign_file_cmd << bundle_path;
- temp_sign_file_cmd << file << "\"";
+ auto temp_sign_file_cmd =
+ cmStrCat(this->GetOption("CPACK_COMMAND_CODESIGN"), ' ',
+ sign_parameter, " -s \"", cpack_apple_cert_app, "\" -i ",
+ this->GetOption("CPACK_APPLE_BUNDLE_ID"), " \"", bundle_path,
+ file, '"');
if (!this->RunCommand(temp_sign_file_cmd, &output)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -216,11 +216,9 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
}
// sign main binary
- std::ostringstream temp_sign_binary_cmd;
- temp_sign_binary_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
- temp_sign_binary_cmd << " " << sign_parameter << " -s \""
- << cpack_apple_cert_app;
- temp_sign_binary_cmd << "\" \"" << bundle_path << "\"";
+ auto temp_sign_binary_cmd =
+ cmStrCat(this->GetOption("CPACK_COMMAND_CODESIGN"), ' ', sign_parameter,
+ " -s \"", cpack_apple_cert_app, "\" \"", bundle_path, '"');
if (!this->RunCommand(temp_sign_binary_cmd, &output)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -232,15 +230,15 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
}
// sign app bundle
- std::ostringstream temp_codesign_cmd;
- temp_codesign_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
- temp_codesign_cmd << " " << sign_parameter << " -s \""
- << cpack_apple_cert_app << "\"";
+ auto temp_codesign_cmd =
+ cmStrCat(this->GetOption("CPACK_COMMAND_CODESIGN"), ' ', sign_parameter,
+ " -s \"", cpack_apple_cert_app, "\"");
if (this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS")) {
- temp_codesign_cmd << " --entitlements ";
- temp_codesign_cmd << this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS");
+ temp_codesign_cmd +=
+ cmStrCat(" --entitlements ",
+ this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS"));
}
- temp_codesign_cmd << " \"" << bundle_path << "\"";
+ temp_codesign_cmd += cmStrCat(" \"", bundle_path, '"');
if (!this->RunCommand(temp_codesign_cmd, &output)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
index fabf4c5..fcb79a2 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
@@ -44,9 +44,9 @@ int cmCPackCygwinBinaryGenerator::PackageFiles()
cmGeneratedFileStream ofs(manifestFile);
for (std::string const& file : files) {
// remove the temp dir and replace with /usr
- ofs << file.substr(tempdir.size()) << "\n";
+ ofs << file.substr(tempdir.size()) << '\n';
}
- ofs << manifest << "\n";
+ ofs << manifest << '\n';
}
// add the manifest file to the list of all files
files.push_back(manifestFile);
@@ -60,7 +60,7 @@ const char* cmCPackCygwinBinaryGenerator::GetOutputExtension()
this->OutputExtension = "-";
cmValue patchNumber = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
if (!patchNumber) {
- this->OutputExtension += "1";
+ this->OutputExtension += '1';
cmCPackLogger(cmCPackLog::LOG_WARNING,
"CPACK_CYGWIN_PATCH_NUMBER not specified using 1"
<< std::endl);
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
index a5863ff..f025a6c 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
@@ -98,7 +98,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
cmCPackLogger(cmCPackLog::LOG_WARNING,
"CPACK_CYGWIN_PATCH_NUMBER"
<< " not specified, defaulting to 1\n");
- outerTarFile += "1";
+ outerTarFile += '1';
} else {
outerTarFile += patch;
}
@@ -150,7 +150,7 @@ const char* cmCPackCygwinSourceGenerator::GetOutputExtension()
cmCPackLogger(cmCPackLog::LOG_WARNING,
"CPACK_CYGWIN_PATCH_NUMBER"
<< " not specified, defaulting to 1\n");
- this->OutputExtension += "1";
+ this->OutputExtension += '1';
} else {
this->OutputExtension += patch;
}
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 34c56c9..8d16428 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -290,8 +290,8 @@ std::string DebGenerator::generateMD5File() const
continue;
}
- std::string output =
- cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5);
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ std::string output = hasher.HashFile(file);
if (output.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem computing the md5 of " << file << std::endl);
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 768bfbe..b4cada3 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -7,6 +7,9 @@
#include <iomanip>
#include <map>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include <CoreFoundation/CoreFoundation.h>
#include <cm3p/kwiml/abi.h>
@@ -136,8 +139,10 @@ int cmCPackDragNDropGenerator::InitializeInternal()
return 0;
}
for (auto const& language : languages) {
- std::string license = slaDirectory + "/" + language + ".license.txt";
- std::string license_rtf = slaDirectory + "/" + language + ".license.rtf";
+ std::string license =
+ cmStrCat(slaDirectory, '/', language, ".license.txt");
+ std::string license_rtf =
+ cmStrCat(slaDirectory, '/', language, ".license.rtf");
if (!singleLicense) {
if (!cmSystemTools::FileExists(license) &&
!cmSystemTools::FileExists(license_rtf)) {
@@ -148,7 +153,7 @@ int cmCPackDragNDropGenerator::InitializeInternal()
return 0;
}
}
- std::string menu = slaDirectory + "/" + language + ".menu.txt";
+ std::string menu = cmStrCat(slaDirectory, '/', language, ".menu.txt");
if (!cmSystemTools::FileExists(menu)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Missing menu file " << language << ".menu.txt"
@@ -192,13 +197,13 @@ int cmCPackDragNDropGenerator::PackageFiles()
// loop to create dmg files
packageFileNames.clear();
for (auto const& package_file : package_files) {
- std::string full_package_name = std::string(toplevel) + std::string("/");
- if (package_file == "ALL_IN_ONE") {
+ std::string full_package_name = cmStrCat(toplevel, '/');
+ if (package_file == "ALL_IN_ONE"_s) {
full_package_name += this->GetOption("CPACK_PACKAGE_FILE_NAME");
} else {
full_package_name += package_file;
}
- full_package_name += std::string(GetOutputExtension());
+ full_package_name += GetOutputExtension();
packageFileNames.push_back(full_package_name);
std::string src_dir = cmStrCat(toplevel, '/', package_file);
@@ -241,18 +246,18 @@ bool cmCPackDragNDropGenerator::CreateEmptyFile(std::ostringstream& target,
return true;
}
-bool cmCPackDragNDropGenerator::RunCommand(std::ostringstream& command,
+bool cmCPackDragNDropGenerator::RunCommand(std::string const& command,
std::string* output)
{
int exit_code = 1;
bool result = cmSystemTools::RunSingleCommand(
- command.str(), output, output, &exit_code, nullptr, this->GeneratorVerbose,
+ command, output, output, &exit_code, nullptr, this->GeneratorVerbose,
cmDuration::zero());
if (!result || exit_code) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error executing: " << command.str() << std::endl);
+ "Error executing: " << command << std::endl);
return false;
}
@@ -410,15 +415,21 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp.dmg");
std::string create_error;
- std::ostringstream temp_image_command;
- temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
- temp_image_command << " create";
- temp_image_command << " -ov";
- temp_image_command << " -srcfolder \"" << staging.str() << "\"";
- temp_image_command << " -volname \"" << cpack_dmg_volume_name << "\"";
- temp_image_command << " -fs \"" << cpack_dmg_filesystem << "\"";
- temp_image_command << " -format " << temp_image_format;
- temp_image_command << " \"" << temp_image << "\"";
+ auto temp_image_command =
+ cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
+ " create"
+ " -ov"
+ " -srcfolder \"",
+ staging.str(),
+ "\""
+ " -volname \"",
+ cpack_dmg_volume_name,
+ "\""
+ " -fs \"",
+ cpack_dmg_filesystem,
+ "\""
+ " -format ",
+ temp_image_format, " \"", temp_image, '"');
if (!this->RunCommand(temp_image_command, &create_error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -434,10 +445,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
// before we exit.
bool had_error = false;
- std::ostringstream attach_command;
- attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
- attach_command << " attach";
- attach_command << " \"" << temp_image << "\"";
+ auto attach_command = cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
+ " attach"
+ " \"",
+ temp_image, '"');
std::string attach_output;
if (!this->RunCommand(attach_command, &attach_output)) {
@@ -466,10 +477,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
// Optionally set the custom icon flag for the image ...
if (!had_error && !cpack_package_icon->empty()) {
std::string error;
- std::ostringstream setfile_command;
- setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
- setfile_command << " -a C";
- setfile_command << " \"" << temp_mount << "\"";
+ auto setfile_command = cmStrCat(this->GetOption("CPACK_COMMAND_SETFILE"),
+ " -a C"
+ " \"",
+ temp_mount, '"');
if (!this->RunCommand(setfile_command, &error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -484,10 +495,12 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
// Optionally we can execute a custom apple script to generate
// the .DS_Store for the volume folder ...
if (!had_error && !cpack_dmg_ds_store_setup_script->empty()) {
- std::ostringstream setup_script_command;
- setup_script_command << "osascript"
- << " \"" << cpack_dmg_ds_store_setup_script << "\""
- << " \"" << temp_mount_name << "\"";
+ auto setup_script_command = cmStrCat("osascript"
+ " \"",
+ cpack_dmg_ds_store_setup_script,
+ "\""
+ " \"",
+ temp_mount_name, '"');
std::string error;
if (!this->RunCommand(setup_script_command, &error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -499,10 +512,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
}
- std::ostringstream detach_command;
- detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
- detach_command << " detach";
- detach_command << " \"" << temp_mount << "\"";
+ auto detach_command = cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
+ " detach"
+ " \"",
+ temp_mount, '\"');
if (!this->RunCommand(detach_command)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -517,14 +530,15 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
// Create the final compressed read-only disk image ...
- std::ostringstream final_image_command;
- final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
- final_image_command << " convert \"" << temp_image << "\"";
- final_image_command << " -format ";
- final_image_command << cpack_dmg_format;
- final_image_command << " -imagekey";
- final_image_command << " zlib-level=9";
- final_image_command << " -o \"" << output_file << "\"";
+ auto final_image_command = cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
+ " convert \"", temp_image,
+ "\""
+ " -format ",
+ cpack_dmg_format,
+ " -imagekey"
+ " zlib-level=9"
+ " -o \"",
+ output_file, '"');
std::string convert_error;
@@ -574,16 +588,18 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
header_data.push_back(0);
header_data.push_back(languages.size());
+ // NOLINTNEXTLINE(modernize-loop-convert): `HAVE_CoreServices` needs `i`
for (cmList::size_type i = 0; i < languages.size(); ++i) {
+ auto const& language = languages[i];
CFStringRef language_cfstring = CFStringCreateWithCString(
- nullptr, languages[i].c_str(), kCFStringEncodingUTF8);
+ nullptr, language.c_str(), kCFStringEncodingUTF8);
CFStringRef iso_language =
CFLocaleCreateCanonicalLanguageIdentifierFromString(
nullptr, language_cfstring);
if (!iso_language) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- languages[i] << " is not a recognized language"
- << std::endl);
+ language << " is not a recognized language"
+ << std::endl);
}
char iso_language_cstr[65];
CFStringGetCString(iso_language, iso_language_cstr,
@@ -663,13 +679,15 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
this->WriteRezXML(sla_xml, rez);
// Create the final compressed read-only disk image ...
- std::ostringstream embed_sla_command;
- embed_sla_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
- embed_sla_command << " udifrez";
- embed_sla_command << " -xml";
- embed_sla_command << " \"" << sla_xml << "\"";
- embed_sla_command << " FIXME_WHY_IS_THIS_ARGUMENT_NEEDED";
- embed_sla_command << " \"" << output_file << "\"";
+ auto embed_sla_command = cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
+ " udifrez"
+ " -xml"
+ " \"",
+ sla_xml,
+ "\""
+ " FIXME_WHY_IS_THIS_ARGUMENT_NEEDED"
+ " \"",
+ output_file, '"');
std::string embed_error;
if (!this->RunCommand(embed_sla_command, &embed_error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -709,8 +727,8 @@ std::string cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
if (this->componentPackageMethod == ONE_PACKAGE_PER_GROUP) {
// We have to find the name of the COMPONENT GROUP
// the current COMPONENT belongs to.
- std::string groupVar =
- "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP";
+ std::string groupVar = cmStrCat(
+ "CPACK_COMPONENT_", cmSystemTools::UpperCase(componentName), "_GROUP");
cmValue _groupName = this->GetOption(groupVar);
if (_groupName) {
std::string groupName = _groupName;
@@ -721,8 +739,8 @@ std::string cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
}
}
- std::string componentFileName =
- "CPACK_DMG_" + cmSystemTools::UpperCase(componentName) + "_FILE_NAME";
+ std::string componentFileName = cmStrCat(
+ "CPACK_DMG_", cmSystemTools::UpperCase(componentName), "_FILE_NAME");
if (this->IsSet(componentFileName)) {
return this->GetOption(componentFileName);
}
@@ -806,12 +824,12 @@ bool cmCPackDragNDropGenerator::WriteLicense(RezDoc& rez, size_t licenseNumber,
actual_license = licenseFile;
} else {
std::string license_wo_ext =
- slaDirectory + "/" + licenseLanguage + ".license";
- if (cmSystemTools::FileExists(license_wo_ext + ".txt")) {
- actual_license = license_wo_ext + ".txt";
+ cmStrCat(slaDirectory, '/', licenseLanguage, ".license");
+ if (cmSystemTools::FileExists(cmStrCat(license_wo_ext, ".txt"))) {
+ actual_license = cmStrCat(license_wo_ext, ".txt");
} else {
licenseArray = &rez.RTF;
- actual_license = license_wo_ext + ".rtf";
+ actual_license = cmStrCat(license_wo_ext, ".rtf");
}
}
@@ -834,7 +852,7 @@ bool cmCPackDragNDropGenerator::WriteLicense(RezDoc& rez, size_t licenseNumber,
} else {
std::vector<std::string> lines;
std::string actual_menu =
- slaDirectory + "/" + licenseLanguage + ".menu.txt";
+ cmStrCat(slaDirectory, '/', licenseLanguage, ".menu.txt");
if (!this->ReadFile(actual_menu, lines, error)) {
return false;
}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index 6d1267b..6089ae5 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -33,7 +33,7 @@ protected:
bool CopyFile(std::ostringstream& source, std::ostringstream& target);
bool CreateEmptyFile(std::ostringstream& target, size_t size);
- bool RunCommand(std::ostringstream& command, std::string* output = nullptr);
+ bool RunCommand(std::string const& command, std::string* output = nullptr);
std::string GetComponentInstallDirNameSuffix(
const std::string& componentName) override;
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index afd85cd..11d90c0 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -1119,8 +1119,8 @@ int cmCPackGenerator::DoPackage()
// Run post-build actions
cmValue postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS");
if (postBuildScripts) {
- this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
- cmJoin(this->packageFileNames, ";"));
+ this->MakefileMap->AddDefinition(
+ "CPACK_PACKAGE_FILES", cmList::to_string(this->packageFileNames));
const cmList scripts{ postBuildScripts };
for (const auto& script : scripts) {
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.cxx b/Source/CPack/cmCPackInnoSetupGenerator.cxx
index ada9a5b..b8bf070 100644
--- a/Source/CPack/cmCPackInnoSetupGenerator.cxx
+++ b/Source/CPack/cmCPackInnoSetupGenerator.cxx
@@ -106,7 +106,7 @@ int cmCPackInnoSetupGenerator::PackageFiles()
const cmList extraScripts(GetOption("CPACK_INNOSETUP_EXTRA_SCRIPTS"));
for (const std::string& i : extraScripts) {
- includeDirectives.push_back(cmStrCat(
+ includeDirectives.emplace_back(cmStrCat(
"#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
}
}
@@ -142,7 +142,7 @@ int cmCPackInnoSetupGenerator::PackageFiles()
const cmList codeFiles(GetOption("CPACK_INNOSETUP_CODE_FILES"));
for (const std::string& i : codeFiles) {
- codeIncludes.push_back(cmStrCat(
+ codeIncludes.emplace_back(cmStrCat(
"#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
}
}
@@ -781,7 +781,7 @@ bool cmCPackInnoSetupGenerator::ConfigureISScript()
// Create internal variables
std::vector<std::string> setupSection;
for (const auto& i : setupDirectives) {
- setupSection.push_back(cmStrCat(i.first, '=', TranslateBool(i.second)));
+ setupSection.emplace_back(cmStrCat(i.first, '=', TranslateBool(i.second)));
}
// Also create comments if the sections are empty
@@ -1082,7 +1082,7 @@ std::string cmCPackInnoSetupGenerator::ISKeyValueLine(
std::vector<std::string> keys;
for (const char* i : availableKeys) {
if (params.count(i)) {
- keys.push_back(cmStrCat(i, ": ", params.at(i)));
+ keys.emplace_back(cmStrCat(i, ": ", params.at(i)));
}
}
diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx
index 5de8179..aa99fb6 100644
--- a/Source/CPack/cmCPackNuGetGenerator.cxx
+++ b/Source/CPack/cmCPackNuGetGenerator.cxx
@@ -12,7 +12,7 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
-#include "cmStringAlgorithms.h"
+#include "cmList.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -82,10 +82,10 @@ void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup)
std::back_inserter(components),
[](cmCPackComponent const* comp) { return comp->Name; });
this->SetOption("CPACK_NUGET_" + compGUp + "_GROUP_COMPONENTS",
- cmJoin(components, ";"));
+ cmList::to_string(components));
}
if (!groups.empty()) {
- this->SetOption("CPACK_NUGET_GROUPS", cmJoin(groups, ";"));
+ this->SetOption("CPACK_NUGET_GROUPS", cmList::to_string(groups));
}
// Handle Orphan components (components not belonging to any groups)
@@ -103,7 +103,7 @@ void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup)
}
}
if (!components.empty()) {
- this->SetOption("CPACK_NUGET_COMPONENTS", cmJoin(components, ";"));
+ this->SetOption("CPACK_NUGET_COMPONENTS", cmList::to_string(components));
}
} else {
@@ -114,7 +114,7 @@ void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup)
[](std::pair<std::string, cmCPackComponent> const& comp) {
return comp.first;
});
- this->SetOption("CPACK_NUGET_COMPONENTS", cmJoin(components, ";"));
+ this->SetOption("CPACK_NUGET_COMPONENTS", cmList::to_string(components));
}
}
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 76ef091..4d60c6c 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -4,6 +4,8 @@
#include <vector>
+#include <cmext/string_view>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -38,13 +40,12 @@ std::string cmCPackPKGGenerator::GetPackageName(
if (component.ArchiveFile.empty()) {
std::string packagesDir =
cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy");
- std::ostringstream out;
- out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-"
- << component.Name << ".pkg";
- return out.str();
+ return cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(packagesDir), '-',
+ component.Name, ".pkg");
}
- return component.ArchiveFile + ".pkg";
+ return cmStrCat(component.ArchiveFile, ".pkg");
}
void cmCPackPKGGenerator::CreateBackground(const char* themeName,
@@ -160,14 +161,15 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile,
for (auto const& comp : this->Components) {
if (!comp.second.Group) {
xChoiceOut.StartElement("line");
- xChoiceOut.Attribute("choice", comp.first + "Choice");
+ xChoiceOut.Attribute("choice", cmStrCat(comp.first, "Choice"));
xChoiceOut.Content(""); // Avoid self-closing tag.
xChoiceOut.EndElement();
}
}
if (!this->PostFlightComponent.Name.empty()) {
xChoiceOut.StartElement("line");
- xChoiceOut.Attribute("choice", PostFlightComponent.Name + "Choice");
+ xChoiceOut.Attribute("choice",
+ cmStrCat(PostFlightComponent.Name, "Choice"));
xChoiceOut.Content(""); // Avoid self-closing tag.
xChoiceOut.EndElement();
}
@@ -207,14 +209,14 @@ void cmCPackPKGGenerator::CreateChoiceOutline(
const cmCPackComponentGroup& group, cmXMLWriter& xout)
{
xout.StartElement("line");
- xout.Attribute("choice", group.Name + "Choice");
+ xout.Attribute("choice", cmStrCat(group.Name, "Choice"));
for (cmCPackComponentGroup* subgroup : group.Subgroups) {
CreateChoiceOutline(*subgroup, xout);
}
for (cmCPackComponent* comp : group.Components) {
xout.StartElement("line");
- xout.Attribute("choice", comp->Name + "Choice");
+ xout.Attribute("choice", cmStrCat(comp->Name, "Choice"));
xout.Content(""); // Avoid self-closing tag.
xout.EndElement();
}
@@ -225,7 +227,7 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponentGroup& group,
cmXMLWriter& xout)
{
xout.StartElement("choice");
- xout.Attribute("id", group.Name + "Choice");
+ xout.Attribute("id", cmStrCat(group.Name, "Choice"));
xout.Attribute("title", group.DisplayName);
xout.Attribute("start_selected", "true");
xout.Attribute("start_enabled", "true");
@@ -249,7 +251,7 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
}
xout.StartElement("choice");
- xout.Attribute("id", component.Name + "Choice");
+ xout.Attribute("id", cmStrCat(component.Name, "Choice"));
xout.Attribute("title", component.DisplayName);
xout.Attribute(
"start_selected",
@@ -381,15 +383,14 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name,
const std::string& dirName)
{
std::string uname = cmSystemTools::UpperCase(name);
- std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
+ std::string cpackVar = cmStrCat("CPACK_RESOURCE_FILE_", uname);
cmValue inFileName = this->GetOption(cpackVar);
if (!inFileName) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPack option: " << cpackVar.c_str()
- << " not specified. It should point to "
- << (!name.empty() ? name : "<empty>")
- << ".rtf, " << name << ".html, or " << name
- << ".txt file" << std::endl);
+ "CPack option: "
+ << cpackVar << " not specified. It should point to "
+ << (!name.empty() ? name : "<empty>") << ".rtf, " << name
+ << ".html, or " << name << ".txt file" << std::endl);
return false;
}
if (!cmSystemTools::FileExists(inFileName)) {
@@ -400,7 +401,8 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name,
return false;
}
std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
- if (ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt") {
+ if (ext != ".rtfd"_s && ext != ".rtf"_s && ext != ".html"_s &&
+ ext != ".txt"_s) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"Bad file extension specified: "
@@ -414,7 +416,8 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name,
// Set this so that distribution.dist gets the right name (without
// the path).
- this->SetOption("CPACK_RESOURCE_FILE_" + uname + "_NOPATH", (name + ext));
+ this->SetOption(cmStrCat("CPACK_RESOURCE_FILE_", uname, "_NOPATH"),
+ cmStrCat(name, ext));
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Configure file: " << (inFileName ? *inFileName : "(NULL)")
@@ -454,7 +457,7 @@ int cmCPackPKGGenerator::CopyInstallScript(const std::string& resdir,
{
std::string dst = cmStrCat(resdir, '/', name);
cmSystemTools::CopyFileAlways(script, dst);
- cmSystemTools::SetPermissions(dst.c_str(), 0777);
+ cmSystemTools::SetPermissions(dst, 0777);
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"copy script : " << script << "\ninto " << dst << std::endl);
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index 4ad616d..ae3c50e 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.cxx
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -58,7 +58,7 @@ int cmCPackProductBuildGenerator::PackageFiles()
}
}
- std::string resDir = packageDirFileName + "/Contents";
+ std::string resDir = cmStrCat(packageDirFileName, "/Contents");
if (this->IsSet("CPACK_PRODUCTBUILD_RESOURCES_DIR")) {
std::string userResDir =
@@ -102,15 +102,24 @@ int cmCPackProductBuildGenerator::PackageFiles()
pkgCmd << productbuild << " --distribution \"" << packageDirFileName
<< "/Contents/distribution.dist\""
- << " --package-path \"" << packageDirFileName << "/Contents/Packages"
+ " --package-path \""
+ << packageDirFileName
+ << "/Contents/Packages"
+ "\""
+ " --resources \""
+ << resDir
<< "\""
- << " --resources \"" << resDir << "\""
- << " --version \"" << version << "\""
- << (identifier.empty() ? "" : " --identifier \"" + identifier + "\"")
- << (identityName.empty() ? "" : " --sign \"" + identityName + "\"")
- << (keychainPath.empty() ? ""
- : " --keychain \"" + keychainPath + "\"")
- << " \"" << packageFileNames[0] << "\"";
+ " --version \""
+ << version << "\""
+ << (identifier.empty()
+ ? std::string{}
+ : cmStrCat(" --identifier \"", identifier, '"'))
+ << (identityName.empty() ? std::string{}
+ : cmStrCat(" --sign \"", identityName, '"'))
+ << (keychainPath.empty()
+ ? std::string{}
+ : cmStrCat(" --keychain \"", keychainPath, '"'))
+ << " \"" << packageFileNames[0] << '"';
// Run ProductBuild
return RunProductBuild(pkgCmd.str());
@@ -184,10 +193,10 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage(
std::string resDir = packageFileDir;
if (component) {
- resDir += "/";
+ resDir += '/';
resDir += component->Name;
}
- std::string scriptDir = resDir + "/scripts";
+ std::string scriptDir = cmStrCat(resDir, "/scripts");
if (!cmsys::SystemTools::MakeDirectory(scriptDir.c_str())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -232,15 +241,24 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage(
keychainPath = p;
}
- pkgCmd << pkgbuild << " --root \"" << packageDir << "\""
- << " --identifier \"" << pkgId << "\""
- << " --scripts \"" << scriptDir << "\""
- << " --version \"" << version << "\""
- << " --install-location \"/\""
- << (identityName.empty() ? "" : " --sign \"" + identityName + "\"")
- << (keychainPath.empty() ? ""
- : " --keychain \"" + keychainPath + "\"")
- << " \"" << packageFile << "\"";
+ pkgCmd << pkgbuild << " --root \"" << packageDir
+ << "\""
+ " --identifier \""
+ << pkgId
+ << "\""
+ " --scripts \""
+ << scriptDir
+ << "\""
+ " --version \""
+ << version
+ << "\""
+ " --install-location \"/\""
+ << (identityName.empty() ? std::string{}
+ : cmStrCat(" --sign \"", identityName, "\""))
+ << (keychainPath.empty()
+ ? std::string{}
+ : cmStrCat(" --keychain \"", keychainPath, "\""))
+ << " \"" << packageFile << '"';
if (component && !component->Plist.empty()) {
pkgCmd << " --component-plist \"" << component->Plist << "\"";
@@ -253,10 +271,10 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage(
cmValue cmCPackProductBuildGenerator::GetComponentScript(
const char* script, const char* component_name)
{
- std::string scriptname = std::string("CPACK_") + script + "_";
+ std::string scriptname = cmStrCat("CPACK_", script, '_');
if (component_name) {
scriptname += cmSystemTools::UpperCase(component_name);
- scriptname += "_";
+ scriptname += '_';
}
scriptname += "SCRIPT";
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index 6ad3755..1248d17 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -7,6 +7,8 @@
#include <string>
#include <vector>
+#include <fcntl.h>
+
#include "cmsys/FStream.hxx"
#include "cm_sys_stat.h"
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 90716e6..00c8fa2 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -363,11 +363,11 @@ int main(int argc, char const* const* argv)
}
if (!expandedPreset->Generators.empty() && generator.empty()) {
- generator = cmJoin(expandedPreset->Generators, ";");
+ generator = cmList::to_string(expandedPreset->Generators);
}
if (!expandedPreset->Configurations.empty() && cpackBuildConfig.empty()) {
- cpackBuildConfig = cmJoin(expandedPreset->Configurations, ";");
+ cpackBuildConfig = cmList::to_string(expandedPreset->Configurations);
}
definitions.insert(expandedPreset->Variables.begin(),
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 81a866a..36df344 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -16,7 +16,6 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
-#include "cmProcessTools.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -136,14 +135,14 @@ private:
std::string cmCTestBZR::LoadInfo()
{
// Run "bzr info" to get the repository info from the work tree.
- const char* bzr = this->CommandLineTool.c_str();
- const char* bzr_info[] = { bzr, "info", nullptr };
+ std::string bzr = this->CommandLineTool;
+ std::vector<std::string> bzr_info = { bzr, "info" };
InfoParser iout(this, "info-out> ");
OutputLogger ierr(this->Log, "info-err> ");
this->RunChild(bzr_info, &iout, &ierr);
// Run "bzr revno" to get the repository revision number from the work tree.
- const char* bzr_revno[] = { bzr, "revno", nullptr };
+ std::vector<std::string> bzr_revno = { bzr, "revno" };
std::string rev;
RevnoParser rout(this, "revno-out> ", rev);
OutputLogger rerr(this->Log, "revno-err> ");
@@ -373,22 +372,18 @@ bool cmCTestBZR::UpdateImpl()
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
// Use "bzr pull" to update the working tree.
- std::vector<char const*> bzr_update;
- bzr_update.push_back(this->CommandLineTool.c_str());
+ std::vector<std::string> bzr_update;
+ bzr_update.push_back(this->CommandLineTool);
bzr_update.push_back("pull");
- for (std::string const& arg : args) {
- bzr_update.push_back(arg.c_str());
- }
-
- bzr_update.push_back(this->URL.c_str());
+ cm::append(bzr_update, args);
- bzr_update.push_back(nullptr);
+ bzr_update.push_back(this->URL);
// For some reason bzr uses stderr to display the update status.
OutputLogger out(this->Log, "pull-out> ");
UpdateParser err(this, "pull-err> ");
- return this->RunUpdateCommand(bzr_update.data(), &out, &err);
+ return this->RunUpdateCommand(bzr_update, &out, &err);
}
bool cmCTestBZR::LoadRevisions()
@@ -409,10 +404,9 @@ bool cmCTestBZR::LoadRevisions()
}
// Run "bzr log" to get all global revisions of interest.
- const char* bzr = this->CommandLineTool.c_str();
- const char* bzr_log[] = {
- bzr, "log", "-v", "-r", revs.c_str(), "--xml", this->URL.c_str(), nullptr
- };
+ std::string bzr = this->CommandLineTool;
+ std::vector<std::string> bzr_log = { bzr, "log", "-v", "-r",
+ revs, "--xml", this->URL };
{
LogParser out(this, "log-out> ");
OutputLogger err(this->Log, "log-err> ");
@@ -468,8 +462,8 @@ private:
bool cmCTestBZR::LoadModifications()
{
// Run "bzr status" which reports local modifications.
- const char* bzr = this->CommandLineTool.c_str();
- const char* bzr_status[] = { bzr, "status", "-SV", nullptr };
+ std::string bzr = this->CommandLineTool;
+ std::vector<std::string> bzr_status = { bzr, "status", "-SV" };
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
this->RunChild(bzr_status, &out, &err);
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 5feb953..bb6ccc3 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -7,8 +7,6 @@
#include <cstring>
#include <ratio>
-#include "cmsys/Process.h"
-
#include "cmBuildOptions.h"
#include "cmCTest.h"
#include "cmCTestTestHandler.h"
@@ -308,12 +306,11 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1;
}
- std::vector<const char*> testCommand;
- testCommand.push_back(fullPath.c_str());
+ std::vector<std::string> testCommand;
+ testCommand.push_back(fullPath);
for (std::string const& testCommandArg : this->TestCommandArgs) {
- testCommand.push_back(testCommandArg.c_str());
+ testCommand.push_back(testCommandArg);
}
- testCommand.push_back(nullptr);
std::string outs;
int retval = 0;
// run the test from the this->BuildRunDir if set
@@ -349,10 +346,10 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
}
}
- int runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, nullptr,
- remainingTime, nullptr);
+ bool runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, nullptr,
+ remainingTime, nullptr);
- if (runTestRes != cmsysProcess_State_Exited || retval != 0) {
+ if (!runTestRes || retval != 0) {
out << "Test command failed: " << testCommand[0] << "\n";
retval = 1;
}
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 882b579..859798e 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -3,14 +3,17 @@
#include "cmCTestBuildHandler.h"
#include <cstdlib>
+#include <memory>
+#include <ratio>
#include <set>
#include <utility>
#include <cmext/algorithm>
+#include <cm3p/uv.h>
+
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestLaunchReporter.h"
@@ -23,6 +26,9 @@
#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
#include "cmValue.h"
#include "cmXMLWriter.h"
@@ -419,7 +425,7 @@ int cmCTestBuildHandler::ProcessHandler()
cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr);
this->ColorRemover = &colorRemover;
int retVal = 0;
- int res = cmsysProcess_State_Exited;
+ bool res = true;
if (!this->CTest->GetShowOnly()) {
res = this->RunMakeCommand(makeCommand, &retVal, buildDirectory.c_str(), 0,
ofs);
@@ -474,7 +480,7 @@ int cmCTestBuildHandler::ProcessHandler()
}
this->GenerateXMLFooter(xml, elapsed_build_time);
- if (res != cmsysProcess_State_Exited || retVal || this->TotalErrors > 0) {
+ if (!res || retVal || this->TotalErrors > 0) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Error(s) when building project" << std::endl);
}
@@ -763,10 +769,10 @@ void cmCTestBuildHandler::LaunchHelper::WriteScrapeMatchers(
}
}
-int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
- int* retVal, const char* dir,
- int timeout, std::ostream& ofs,
- Encoding encoding)
+bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
+ int* retVal, const char* dir,
+ int timeout, std::ostream& ofs,
+ Encoding encoding)
{
// First generate the command and arguments
std::vector<std::string> args = cmSystemTools::ParseArguments(command);
@@ -775,19 +781,9 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
return false;
}
- std::vector<const char*> argv;
- argv.reserve(args.size() + 1);
- for (std::string const& arg : args) {
- argv.push_back(arg.c_str());
- }
- argv.push_back(nullptr);
-
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run command:", this->Quiet);
- for (char const* arg : argv) {
- if (!arg) {
- break;
- }
+ for (auto const& arg : args) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" \"" << arg << "\"", this->Quiet);
}
@@ -799,21 +795,20 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
static_cast<void>(launchHelper);
// Now create process object
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, argv.data());
- cmsysProcess_SetWorkingDirectory(cp, dir);
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
- cmsysProcess_SetTimeout(cp, timeout);
- cmsysProcess_Execute(cp);
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(args)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+ if (dir) {
+ builder.SetWorkingDirectory(dir);
+ }
+ auto chain = builder.Start();
// Initialize tick's
std::string::size_type tick = 0;
- const std::string::size_type tick_len = 1024;
+ static constexpr std::string::size_type tick_len = 1024;
- char* data;
- int length;
cmProcessOutput processOutput(encoding);
- std::string strdata;
cmCTestOptionalLog(
this->CTest, HANDLER_PROGRESS_OUTPUT,
" Each symbol represents "
@@ -835,39 +830,65 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
this->WarningQuotaReached = false;
this->ErrorQuotaReached = false;
+ cm::uv_timer_ptr timer;
+ bool timedOut = false;
+ timer.init(chain.GetLoop(), &timedOut);
+ if (timeout > 0) {
+ timer.start(
+ [](uv_timer_t* t) {
+ auto* timedOutPtr = static_cast<bool*>(t->data);
+ *timedOutPtr = true;
+ },
+ timeout * 1000, 0);
+ }
+
// For every chunk of data
- int res;
- while ((res = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
- // Replace '\0' with '\n', since '\0' does not really make sense. This is
- // for Visual Studio output
- for (int cc = 0; cc < length; ++cc) {
- if (data[cc] == 0) {
- data[cc] = '\n';
- }
- }
+ cm::uv_pipe_ptr outputStream;
+ bool outFinished = false;
+ cm::uv_pipe_ptr errorStream;
+ bool errFinished = false;
+ auto startRead = [this, &chain, &processOutput, &tick,
+ &ofs](cm::uv_pipe_ptr& pipe, int stream,
+ t_BuildProcessingQueueType& queue, bool& finished,
+ int id) -> std::unique_ptr<cmUVStreamReadHandle> {
+ pipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(pipe, stream);
+ return cmUVStreamRead(
+ pipe,
+ [this, &processOutput, &queue, id, &tick, &ofs](std::vector<char> data) {
+ // Replace '\0' with '\n', since '\0' does not really make sense. This
+ // is for Visual Studio output
+ for (auto& c : data) {
+ if (c == 0) {
+ c = '\n';
+ }
+ }
- // Process the chunk of data
- if (res == cmsysProcess_Pipe_STDERR) {
- processOutput.DecodeText(data, length, strdata, 1);
- this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
- &this->BuildProcessingErrorQueue);
- } else {
- processOutput.DecodeText(data, length, strdata, 2);
- this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
- &this->BuildProcessingQueue);
- }
- }
- processOutput.DecodeText(std::string(), strdata, 1);
- if (!strdata.empty()) {
- this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
- &this->BuildProcessingErrorQueue);
- }
- processOutput.DecodeText(std::string(), strdata, 2);
- if (!strdata.empty()) {
- this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
- &this->BuildProcessingQueue);
+ // Process the chunk of data
+ std::string strdata;
+ processOutput.DecodeText(data.data(), data.size(), strdata, id);
+ this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len,
+ ofs, &queue);
+ },
+ [this, &processOutput, &queue, id, &tick, &ofs, &finished]() {
+ std::string strdata;
+ processOutput.DecodeText(std::string(), strdata, id);
+ if (!strdata.empty()) {
+ this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len,
+ ofs, &queue);
+ }
+ finished = true;
+ });
+ };
+ auto outputHandle = startRead(outputStream, chain.OutputStream(),
+ this->BuildProcessingQueue, outFinished, 1);
+ auto errorHandle =
+ startRead(errorStream, chain.ErrorStream(),
+ this->BuildProcessingErrorQueue, errFinished, 2);
+
+ while (!timedOut && !(outFinished && errFinished && chain.Finished())) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
}
-
this->ProcessBuffer(nullptr, 0, tick, tick_len, ofs,
&this->BuildProcessingQueue);
this->ProcessBuffer(nullptr, 0, tick, tick_len, ofs,
@@ -878,90 +899,93 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
<< std::endl,
this->Quiet);
- // Properly handle output of the build command
- cmsysProcess_WaitForExit(cp, nullptr);
- int result = cmsysProcess_GetState(cp);
-
- if (result == cmsysProcess_State_Exited) {
- if (retVal) {
- *retVal = cmsysProcess_GetExitValue(cp);
- cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Command exited with the value: " << *retVal
- << std::endl,
- this->Quiet);
- // if a non zero return value
- if (*retVal) {
- // If there was an error running command, report that on the
- // dashboard.
- if (this->UseCTestLaunch) {
- // For launchers, do not record this top-level error if other
- // more granular build errors have already been captured.
- bool launcherXMLFound = false;
- cmsys::Directory launchDir;
- launchDir.Load(this->CTestLaunchDir);
- unsigned long n = launchDir.GetNumberOfFiles();
- for (unsigned long i = 0; i < n; ++i) {
- const char* fname = launchDir.GetFile(i);
- if (cmHasLiteralSuffix(fname, ".xml")) {
- launcherXMLFound = true;
- break;
+ if (chain.Finished()) {
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ if (retVal) {
+ *retVal = static_cast<int>(status.ExitStatus);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Command exited with the value: " << *retVal
+ << std::endl,
+ this->Quiet);
+ // if a non zero return value
+ if (*retVal) {
+ // If there was an error running command, report that on the
+ // dashboard.
+ if (this->UseCTestLaunch) {
+ // For launchers, do not record this top-level error if other
+ // more granular build errors have already been captured.
+ bool launcherXMLFound = false;
+ cmsys::Directory launchDir;
+ launchDir.Load(this->CTestLaunchDir);
+ unsigned long n = launchDir.GetNumberOfFiles();
+ for (unsigned long i = 0; i < n; ++i) {
+ const char* fname = launchDir.GetFile(i);
+ if (cmHasLiteralSuffix(fname, ".xml")) {
+ launcherXMLFound = true;
+ break;
+ }
+ }
+ if (!launcherXMLFound) {
+ cmCTestLaunchReporter reporter;
+ reporter.RealArgs = args;
+ reporter.ComputeFileNames();
+ reporter.ExitCode = *retVal;
+ reporter.Status = status;
+ // Use temporary BuildLog file to populate this error for
+ // CDash.
+ ofs.flush();
+ reporter.LogOut = this->LogFileNames["Build"];
+ reporter.LogOut += ".tmp";
+ reporter.WriteXML();
+ }
+ } else {
+ cmCTestBuildErrorWarning errorwarning;
+ errorwarning.LineNumber = 0;
+ errorwarning.LogLine = 1;
+ errorwarning.Text = cmStrCat(
+ "*** WARNING non-zero return value in ctest from: ", args[0]);
+ errorwarning.PreContext.clear();
+ errorwarning.PostContext.clear();
+ errorwarning.Error = false;
+ this->ErrorsAndWarnings.push_back(std::move(errorwarning));
+ this->TotalWarnings++;
}
}
- if (!launcherXMLFound) {
- cmCTestLaunchReporter reporter;
- reporter.RealArgs = args;
- reporter.ComputeFileNames();
- reporter.ExitCode = *retVal;
- reporter.Process = cp;
- // Use temporary BuildLog file to populate this error for CDash.
- ofs.flush();
- reporter.LogOut = this->LogFileNames["Build"];
- reporter.LogOut += ".tmp";
- reporter.WriteXML();
- }
- } else {
- cmCTestBuildErrorWarning errorwarning;
- errorwarning.LineNumber = 0;
- errorwarning.LogLine = 1;
- errorwarning.Text = cmStrCat(
- "*** WARNING non-zero return value in ctest from: ", argv[0]);
- errorwarning.PreContext.clear();
- errorwarning.PostContext.clear();
- errorwarning.Error = false;
- this->ErrorsAndWarnings.push_back(std::move(errorwarning));
- this->TotalWarnings++;
}
- }
- }
- } else if (result == cmsysProcess_State_Exception) {
- if (retVal) {
- *retVal = cmsysProcess_GetExitException(cp);
- cmCTestOptionalLog(this->CTest, WARNING,
- "There was an exception: " << *retVal << std::endl,
- this->Quiet);
+ break;
+ case cmUVProcessChain::ExceptionCode::Spawn: {
+ // If there was an error running command, report that on the dashboard.
+ cmCTestBuildErrorWarning errorwarning;
+ errorwarning.LineNumber = 0;
+ errorwarning.LogLine = 1;
+ errorwarning.Text =
+ cmStrCat("*** ERROR executing: ", exception.second);
+ errorwarning.PreContext.clear();
+ errorwarning.PostContext.clear();
+ errorwarning.Error = true;
+ this->ErrorsAndWarnings.push_back(std::move(errorwarning));
+ this->TotalErrors++;
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "There was an error: " << exception.second << std::endl);
+ } break;
+ default:
+ if (retVal) {
+ *retVal = status.TermSignal;
+ cmCTestOptionalLog(
+ this->CTest, WARNING,
+ "There was an exception: " << *retVal << std::endl, this->Quiet);
+ }
+ break;
}
- } else if (result == cmsysProcess_State_Expired) {
+ } else {
cmCTestOptionalLog(this->CTest, WARNING,
"There was a timeout" << std::endl, this->Quiet);
- } else if (result == cmsysProcess_State_Error) {
- // If there was an error running command, report that on the dashboard.
- cmCTestBuildErrorWarning errorwarning;
- errorwarning.LineNumber = 0;
- errorwarning.LogLine = 1;
- errorwarning.Text =
- cmStrCat("*** ERROR executing: ", cmsysProcess_GetErrorString(cp));
- errorwarning.PreContext.clear();
- errorwarning.PostContext.clear();
- errorwarning.Error = true;
- this->ErrorsAndWarnings.push_back(std::move(errorwarning));
- this->TotalErrors++;
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "There was an error: " << cmsysProcess_GetErrorString(cp)
- << std::endl);
}
- cmsysProcess_Delete(cp);
- return result;
+ return true;
}
// ######################################################################
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index e33294d..90945b1 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -53,9 +53,9 @@ private:
//! Run command specialized for make and configure. Returns process status
// and retVal is return value or exception.
- int RunMakeCommand(const std::string& command, int* retVal, const char* dir,
- int timeout, std::ostream& ofs,
- Encoding encoding = cmProcessOutput::Auto);
+ bool RunMakeCommand(const std::string& command, int* retVal, const char* dir,
+ int timeout, std::ostream& ofs,
+ Encoding encoding = cmProcessOutput::Auto);
enum
{
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 87ab762..ef95b25 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -5,12 +5,12 @@
#include <utility>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmCTest.h"
-#include "cmProcessTools.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
@@ -90,18 +90,15 @@ bool cmCTestCVS::UpdateImpl()
}
// Run "cvs update" to update the work tree.
- std::vector<char const*> cvs_update;
- cvs_update.push_back(this->CommandLineTool.c_str());
+ std::vector<std::string> cvs_update;
+ cvs_update.push_back(this->CommandLineTool);
cvs_update.push_back("-z3");
cvs_update.push_back("update");
- for (std::string const& arg : args) {
- cvs_update.push_back(arg.c_str());
- }
- cvs_update.push_back(nullptr);
+ cm::append(cvs_update, args);
UpdateParser out(this, "up-out> ");
UpdateParser err(this, "up-err> ");
- return this->RunUpdateCommand(cvs_update.data(), &out, &err);
+ return this->RunUpdateCommand(cvs_update, &out, &err);
}
class cmCTestCVS::LogParser : public cmCTestVC::LineParser
@@ -222,10 +219,8 @@ void cmCTestCVS::LoadRevisions(std::string const& file, const char* branchFlag,
cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
// Run "cvs log" to get revisions of this file on this branch.
- const char* cvs = this->CommandLineTool.c_str();
- const char* cvs_log[] = {
- cvs, "log", "-N", branchFlag, file.c_str(), nullptr
- };
+ std::string cvs = this->CommandLineTool;
+ std::vector<std::string> cvs_log = { cvs, "log", "-N", branchFlag, file };
LogParser out(this, "log-out> ", revisions);
OutputLogger err(this->Log, "log-err> ");
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index bae1f54..e0326a9 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -4,6 +4,7 @@
#include <cstring>
#include <sstream>
+#include <vector>
#include <cmext/string_view>
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index 914930e..dd8952f 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -45,7 +45,7 @@ int cmCTestConfigureHandler::ProcessHandler()
auto elapsed_time_start = std::chrono::steady_clock::now();
std::string output;
int retVal = 0;
- int res = 0;
+ bool res = false;
if (!this->CTest->GetShowOnly()) {
cmGeneratedFileStream os;
if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", os)) {
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 5c48cbf..1aa49cf 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -9,16 +9,20 @@
#include <cstring>
#include <iomanip>
#include <iterator>
+#include <memory>
+#include <ratio>
#include <sstream>
+#include <type_traits>
#include <utility>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
-#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
+#include "cm_fileno.hxx"
+
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
@@ -31,6 +35,7 @@
#include "cmParsePHPCoverage.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
@@ -38,85 +43,6 @@ class cmMakefile;
#define SAFEDIV(x, y) (((y) != 0) ? ((x) / (y)) : (0))
-class cmCTestRunProcess
-{
-public:
- cmCTestRunProcess()
- {
- this->Process = cmsysProcess_New();
- this->PipeState = -1;
- this->TimeOut = cmDuration(-1);
- }
- ~cmCTestRunProcess()
- {
- if (this->PipeState != -1 && this->PipeState != cmsysProcess_Pipe_None &&
- this->PipeState != cmsysProcess_Pipe_Timeout) {
- this->WaitForExit();
- }
- cmsysProcess_Delete(this->Process);
- }
- cmCTestRunProcess(const cmCTestRunProcess&) = delete;
- cmCTestRunProcess& operator=(const cmCTestRunProcess&) = delete;
- void SetCommand(const char* command)
- {
- this->CommandLineStrings.clear();
- this->CommandLineStrings.emplace_back(command);
- }
- void AddArgument(const char* arg)
- {
- if (arg) {
- this->CommandLineStrings.emplace_back(arg);
- }
- }
- void SetWorkingDirectory(const char* dir) { this->WorkingDirectory = dir; }
- void SetTimeout(cmDuration t) { this->TimeOut = t; }
- bool StartProcess()
- {
- std::vector<const char*> args;
- args.reserve(this->CommandLineStrings.size());
- for (std::string const& cl : this->CommandLineStrings) {
- args.push_back(cl.c_str());
- }
- args.push_back(nullptr); // null terminate
- cmsysProcess_SetCommand(this->Process, args.data());
- if (!this->WorkingDirectory.empty()) {
- cmsysProcess_SetWorkingDirectory(this->Process,
- this->WorkingDirectory.c_str());
- }
-
- cmsysProcess_SetOption(this->Process, cmsysProcess_Option_HideWindow, 1);
- if (this->TimeOut >= cmDuration::zero()) {
- cmsysProcess_SetTimeout(this->Process, this->TimeOut.count());
- }
- cmsysProcess_Execute(this->Process);
- this->PipeState = cmsysProcess_GetState(this->Process);
- // if the process is running or exited return true
- return this->PipeState == cmsysProcess_State_Executing ||
- this->PipeState == cmsysProcess_State_Exited;
- }
- void SetStdoutFile(const char* fname)
- {
- cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDOUT, fname);
- }
- void SetStderrFile(const char* fname)
- {
- cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDERR, fname);
- }
- int WaitForExit(double* timeout = nullptr)
- {
- this->PipeState = cmsysProcess_WaitForExit(this->Process, timeout);
- return this->PipeState;
- }
- int GetProcessState() const { return this->PipeState; }
-
-private:
- int PipeState;
- cmsysProcess* Process;
- std::vector<std::string> CommandLineStrings;
- std::string WorkingDirectory;
- cmDuration TimeOut;
-};
-
cmCTestCoverageHandler::cmCTestCoverageHandler() = default;
void cmCTestCoverageHandler::Initialize()
@@ -1938,34 +1864,35 @@ int cmCTestCoverageHandler::RunBullseyeCommand(
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find :" << cmd << "\n");
return 0;
}
+ std::vector<std::string> args{ cmd };
if (arg) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run : " << program << " " << arg << "\n", this->Quiet);
+ args.emplace_back(arg);
} else {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run : " << program << "\n", this->Quiet);
}
// create a process object and start it
- cmCTestRunProcess runCoverageSrc;
- runCoverageSrc.SetCommand(program.c_str());
- runCoverageSrc.AddArgument(arg);
+ cmUVProcessChainBuilder builder;
std::string stdoutFile =
cmStrCat(cont->BinaryDir, "/Testing/Temporary/",
this->GetCTestInstance()->GetCurrentTag(), '-', cmd);
std::string stderrFile = stdoutFile;
stdoutFile += ".stdout";
stderrFile += ".stderr";
- runCoverageSrc.SetStdoutFile(stdoutFile.c_str());
- runCoverageSrc.SetStderrFile(stderrFile.c_str());
- if (!runCoverageSrc.StartProcess()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Could not run : " << program << " " << arg << "\n"
- << "kwsys process state : "
- << runCoverageSrc.GetProcessState());
- return 0;
- }
+ std::unique_ptr<FILE, int (*)(FILE*)> stdoutHandle(
+ cmsys::SystemTools::Fopen(stdoutFile, "w"), fclose);
+ std::unique_ptr<FILE, int (*)(FILE*)> stderrHandle(
+ cmsys::SystemTools::Fopen(stderrFile, "w"), fclose);
+ builder.AddCommand(args)
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ cm_fileno(stdoutHandle.get()))
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(stderrHandle.get()));
// since we set the output file names wait for it to end
- runCoverageSrc.WaitForExit();
+ auto chain = builder.Start();
+ chain.Wait();
outputFile = stdoutFile;
return 1;
}
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index a6e7ac5..ca8659e 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -9,16 +9,17 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmList.h"
#include "cmProcessOutput.h"
-#include "cmProcessTools.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
#include "cmValue.h"
static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
@@ -59,9 +60,9 @@ private:
std::string cmCTestGIT::GetWorkingRevision()
{
// Run plumbing "git rev-list" to get work tree revision.
- const char* git = this->CommandLineTool.c_str();
- const char* git_rev_list[] = { git, "rev-list", "-n", "1",
- "HEAD", "--", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_list = { git, "rev-list", "-n",
+ "1", "HEAD", "--" };
std::string rev;
OneLineParser out(this, "rl-out> ", rev);
OutputLogger err(this->Log, "rl-err> ");
@@ -93,13 +94,13 @@ std::string cmCTestGIT::FindGitDir()
std::string git_dir;
// Run "git rev-parse --git-dir" to locate the real .git directory.
- const char* git = this->CommandLineTool.c_str();
- char const* git_rev_parse[] = { git, "rev-parse", "--git-dir", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_parse = { git, "rev-parse", "--git-dir" };
std::string git_dir_line;
OneLineParser rev_parse_out(this, "rev-parse-out> ", git_dir_line);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
- if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, nullptr,
- cmProcessOutput::UTF8)) {
+ if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err,
+ std::string{}, cmProcessOutput::UTF8)) {
git_dir = git_dir_line;
}
if (git_dir.empty()) {
@@ -118,11 +119,10 @@ std::string cmCTestGIT::FindGitDir()
std::string cygpath_exe =
cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe");
if (cmSystemTools::FileExists(cygpath_exe)) {
- char const* cygpath[] = { cygpath_exe.c_str(), "-w", git_dir.c_str(),
- 0 };
+ std::vector<std::string> cygpath = { cygpath_exe, "-w", git_dir };
OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line);
OutputLogger cygpath_err(this->Log, "cygpath-err> ");
- if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, nullptr,
+ if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, std::string{},
cmProcessOutput::UTF8)) {
git_dir = git_dir_line;
}
@@ -137,12 +137,12 @@ std::string cmCTestGIT::FindTopDir()
std::string top_dir = this->SourceDirectory;
// Run "git rev-parse --show-cdup" to locate the top of the tree.
- const char* git = this->CommandLineTool.c_str();
- char const* git_rev_parse[] = { git, "rev-parse", "--show-cdup", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_parse = { git, "rev-parse", "--show-cdup" };
std::string cdup;
OneLineParser rev_parse_out(this, "rev-parse-out> ", cdup);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
- if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, nullptr,
+ if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, "",
cmProcessOutput::UTF8) &&
!cdup.empty()) {
top_dir += "/";
@@ -154,10 +154,10 @@ std::string cmCTestGIT::FindTopDir()
bool cmCTestGIT::UpdateByFetchAndReset()
{
- const char* git = this->CommandLineTool.c_str();
+ std::string git = this->CommandLineTool;
// Use "git fetch" to get remote commits.
- std::vector<char const*> git_fetch;
+ std::vector<std::string> git_fetch;
git_fetch.push_back(git);
git_fetch.push_back("fetch");
@@ -167,17 +167,12 @@ bool cmCTestGIT::UpdateByFetchAndReset()
opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- for (std::string const& arg : args) {
- git_fetch.push_back(arg.c_str());
- }
-
- // Sentinel argument.
- git_fetch.push_back(nullptr);
+ cm::append(git_fetch, args);
// Fetch upstream refs.
OutputLogger fetch_out(this->Log, "fetch-out> ");
OutputLogger fetch_err(this->Log, "fetch-err> ");
- if (!this->RunUpdateCommand(git_fetch.data(), &fetch_out, &fetch_err)) {
+ if (!this->RunUpdateCommand(git_fetch, &fetch_out, &fetch_err)) {
return false;
}
@@ -208,25 +203,22 @@ bool cmCTestGIT::UpdateByFetchAndReset()
}
// Reset the local branch to point at that tracked from upstream.
- char const* git_reset[] = { git, "reset", "--hard", sha1.c_str(), nullptr };
+ std::vector<std::string> git_reset = { git, "reset", "--hard", sha1 };
OutputLogger reset_out(this->Log, "reset-out> ");
OutputLogger reset_err(this->Log, "reset-err> ");
- return this->RunChild(&git_reset[0], &reset_out, &reset_err);
+ return this->RunChild(git_reset, &reset_out, &reset_err);
}
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
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) {
- git_custom.push_back(i.c_str());
- }
- git_custom.push_back(nullptr);
+ std::vector<std::string> git_custom;
+ git_custom.reserve(git_custom_command.size());
+ cm::append(git_custom, git_custom_command);
OutputLogger custom_out(this->Log, "custom-out> ");
OutputLogger custom_err(this->Log, "custom-err> ");
- return this->RunUpdateCommand(git_custom.data(), &custom_out, &custom_err);
+ return this->RunUpdateCommand(git_custom, &custom_out, &custom_err);
}
bool cmCTestGIT::UpdateInternal()
@@ -245,13 +237,14 @@ bool cmCTestGIT::UpdateImpl()
}
std::string top_dir = this->FindTopDir();
- const char* git = this->CommandLineTool.c_str();
- const char* recursive = "--recursive";
- const char* sync_recursive = "--recursive";
+ std::string git = this->CommandLineTool;
+ std::string recursive = "--recursive";
+ std::string sync_recursive = "--recursive";
// Git < 1.6.5 did not support submodule --recursive
+ bool support_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 6, 5, 0)) {
- recursive = nullptr;
+ support_recursive = false;
// No need to require >= 1.6.5 if there are no submodules.
if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) {
this->Log << "Git < 1.6.5 cannot update submodules recursively\n";
@@ -259,8 +252,9 @@ bool cmCTestGIT::UpdateImpl()
}
// Git < 1.8.1 did not support sync --recursive
+ bool support_sync_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 8, 1, 0)) {
- sync_recursive = nullptr;
+ support_sync_recursive = false;
// No need to require >= 1.8.1 if there are no submodules.
if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) {
this->Log << "Git < 1.8.1 cannot synchronize submodules recursively\n";
@@ -275,35 +269,39 @@ bool cmCTestGIT::UpdateImpl()
std::string init_submodules =
this->CTest->GetCTestConfiguration("GITInitSubmodules");
if (cmIsOn(init_submodules)) {
- char const* git_submodule_init[] = { git, "submodule", "init", nullptr };
+ std::vector<std::string> git_submodule_init = { git, "submodule", "init" };
ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err,
- top_dir.c_str());
+ top_dir);
if (!ret) {
return false;
}
}
- char const* git_submodule_sync[] = { git, "submodule", "sync",
- sync_recursive, nullptr };
+ std::vector<std::string> git_submodule_sync = { git, "submodule", "sync" };
+ if (support_sync_recursive) {
+ git_submodule_sync.push_back(sync_recursive);
+ }
ret = this->RunChild(git_submodule_sync, &submodule_out, &submodule_err,
- top_dir.c_str());
+ top_dir);
if (!ret) {
return false;
}
- char const* git_submodule[] = { git, "submodule", "update", recursive,
- nullptr };
+ std::vector<std::string> git_submodule = { git, "submodule", "update" };
+ if (support_recursive) {
+ git_submodule.push_back(recursive);
+ }
return this->RunChild(git_submodule, &submodule_out, &submodule_err,
- top_dir.c_str());
+ top_dir);
}
unsigned int cmCTestGIT::GetGitVersion()
{
if (!this->CurrentGitVersion) {
- const char* git = this->CommandLineTool.c_str();
- char const* git_version[] = { git, "--version", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_version = { git, "--version" };
std::string version;
OneLineParser version_out(this, "version-out> ", version);
OutputLogger version_err(this->Log, "version-err> ");
@@ -606,50 +604,49 @@ bool cmCTestGIT::LoadRevisions()
{
// Use 'git rev-list ... | git diff-tree ...' to get revisions.
std::string range = this->OldRevision + ".." + this->NewRevision;
- const char* git = this->CommandLineTool.c_str();
- const char* git_rev_list[] = { git, "rev-list", "--reverse",
- range.c_str(), "--", nullptr };
- const char* git_diff_tree[] = {
- git, "diff-tree", "--stdin", "--always", "-z",
- "-r", "--pretty=raw", "--encoding=utf-8", nullptr
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_list = { git, "rev-list", "--reverse",
+ range, "--" };
+ std::vector<std::string> git_diff_tree = {
+ git, "diff-tree", "--stdin", "--always",
+ "-z", "-r", "--pretty=raw", "--encoding=utf-8"
};
this->Log << cmCTestGIT::ComputeCommandLine(git_rev_list) << " | "
<< cmCTestGIT::ComputeCommandLine(git_diff_tree) << "\n";
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_AddCommand(cp, git_rev_list);
- cmsysProcess_AddCommand(cp, git_diff_tree);
- cmsysProcess_SetWorkingDirectory(cp, this->SourceDirectory.c_str());
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(git_rev_list)
+ .AddCommand(git_diff_tree)
+ .SetWorkingDirectory(this->SourceDirectory);
CommitParser out(this, "dt-out> ");
OutputLogger err(this->Log, "dt-err> ");
- cmCTestGIT::RunProcess(cp, &out, &err, cmProcessOutput::UTF8);
+ cmCTestGIT::RunProcess(builder, &out, &err, cmProcessOutput::UTF8);
// Send one extra zero-byte to terminate the last record.
out.Process("", 1);
- cmsysProcess_Delete(cp);
return true;
}
bool cmCTestGIT::LoadModifications()
{
- const char* git = this->CommandLineTool.c_str();
+ std::string git = this->CommandLineTool;
// Use 'git update-index' to refresh the index w.r.t. the work tree.
- const char* git_update_index[] = { git, "update-index", "--refresh",
- nullptr };
+ std::vector<std::string> git_update_index = { git, "update-index",
+ "--refresh" };
OutputLogger ui_out(this->Log, "ui-out> ");
OutputLogger ui_err(this->Log, "ui-err> ");
- this->RunChild(git_update_index, &ui_out, &ui_err, nullptr,
+ this->RunChild(git_update_index, &ui_out, &ui_err, "",
cmProcessOutput::UTF8);
// Use 'git diff-index' to get modified files.
- const char* git_diff_index[] = { git, "diff-index", "-z",
- "HEAD", "--", nullptr };
+ std::vector<std::string> git_diff_index = { git, "diff-index", "-z", "HEAD",
+ "--" };
DiffParser out(this, "di-out> ");
OutputLogger err(this->Log, "di-err> ");
- this->RunChild(git_diff_index, &out, &err, nullptr, cmProcessOutput::UTF8);
+ this->RunChild(git_diff_index, &out, &err, "", cmProcessOutput::UTF8);
for (Change const& c : out.Changes) {
this->DoModification(PathModified, c.Path);
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 97b01ba..e1a945d 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -11,7 +11,6 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
-#include "cmProcessTools.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -96,8 +95,8 @@ private:
std::string cmCTestHG::GetWorkingRevision()
{
// Run plumbing "hg identify" to get work tree revision.
- const char* hg = this->CommandLineTool.c_str();
- const char* hg_identify[] = { hg, "identify", "-i", nullptr };
+ std::string hg = this->CommandLineTool;
+ std::vector<std::string> hg_identify = { hg, "identify", "-i" };
std::string rev;
IdentifyParser out(this, "rev-out> ", rev);
OutputLogger err(this->Log, "rev-err> ");
@@ -128,16 +127,16 @@ bool cmCTestHG::UpdateImpl()
{
// Use "hg pull" followed by "hg update" to update the working tree.
{
- const char* hg = this->CommandLineTool.c_str();
- const char* hg_pull[] = { hg, "pull", "-v", nullptr };
+ std::string hg = this->CommandLineTool;
+ std::vector<std::string> hg_pull = { hg, "pull", "-v" };
OutputLogger out(this->Log, "pull-out> ");
OutputLogger err(this->Log, "pull-err> ");
- this->RunChild(&hg_pull[0], &out, &err);
+ this->RunChild(hg_pull, &out, &err);
}
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
- std::vector<char const*> hg_update;
+ std::vector<std::string> hg_update;
hg_update.push_back(this->CommandLineTool.c_str());
hg_update.push_back("update");
hg_update.push_back("-v");
@@ -148,16 +147,11 @@ bool cmCTestHG::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- for (std::string const& arg : args) {
- hg_update.push_back(arg.c_str());
- }
-
- // Sentinel argument.
- hg_update.push_back(nullptr);
+ cm::append(hg_update, args);
OutputLogger out(this->Log, "update-out> ");
OutputLogger err(this->Log, "update-err> ");
- return this->RunUpdateCommand(hg_update.data(), &out, &err);
+ return this->RunUpdateCommand(hg_update, &out, &err);
}
class cmCTestHG::LogParser
@@ -278,8 +272,8 @@ bool cmCTestHG::LoadRevisions()
// the project has spaces in the path. Also, they may not have
// proper XML escapes.
std::string range = this->OldRevision + ":" + this->NewRevision;
- const char* hg = this->CommandLineTool.c_str();
- const char* hgXMLTemplate = "<logentry\n"
+ std::string hg = this->CommandLineTool;
+ std::string hgXMLTemplate = "<logentry\n"
" revision=\"{node|short}\">\n"
" <author>{author|person}</author>\n"
" <email>{author|email}</email>\n"
@@ -289,10 +283,8 @@ bool cmCTestHG::LoadRevisions()
" <file_adds>{file_adds}</file_adds>\n"
" <file_dels>{file_dels}</file_dels>\n"
"</logentry>\n";
- const char* hg_log[] = {
- hg, "log", "--removed", "-r", range.c_str(),
- "--template", hgXMLTemplate, nullptr
- };
+ std::vector<std::string> hg_log = { hg, "log", "--removed", "-r",
+ range, "--template", hgXMLTemplate };
LogParser out(this, "log-out> ");
out.Process("<?xml version=\"1.0\"?>\n"
@@ -306,8 +298,8 @@ bool cmCTestHG::LoadRevisions()
bool cmCTestHG::LoadModifications()
{
// Use 'hg status' to get modified files.
- const char* hg = this->CommandLineTool.c_str();
- const char* hg_status[] = { hg, "status", nullptr };
+ std::string hg = this->CommandLineTool;
+ std::vector<std::string> hg_status = { hg, "status" };
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
this->RunChild(hg_status, &out, &err);
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 4a33869..6b13ad1 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -2,13 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestLaunch.h"
+#include <cstdio>
#include <cstring>
#include <iostream>
+#include <memory>
+#include <utility>
+
+#include <cm3p/uv.h>
#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
+#include "cm_fileno.hxx"
+
#include "cmCTestLaunchReporter.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -17,6 +23,9 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
#include "cmake.h"
#ifdef _WIN32
@@ -28,8 +37,6 @@
cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
{
- this->Process = nullptr;
-
if (!this->ParseArguments(argc, argv)) {
return;
}
@@ -40,13 +47,9 @@ cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
this->ScrapeRulesLoaded = false;
this->HaveOut = false;
this->HaveErr = false;
- this->Process = cmsysProcess_New();
}
-cmCTestLaunch::~cmCTestLaunch()
-{
- cmsysProcess_Delete(this->Process);
-}
+cmCTestLaunch::~cmCTestLaunch() = default;
bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
{
@@ -113,15 +116,12 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
// Extract the real command line.
if (arg0) {
- this->RealArgC = argc - arg0;
- this->RealArgV = argv + arg0;
- for (int i = 0; i < this->RealArgC; ++i) {
- this->HandleRealArg(this->RealArgV[i]);
+ for (int i = 0; i < argc - arg0; ++i) {
+ this->RealArgV.emplace_back((argv + arg0)[i]);
+ this->HandleRealArg((argv + arg0)[i]);
}
return true;
}
- this->RealArgC = 0;
- this->RealArgV = nullptr;
std::cerr << "No launch/command separator ('--') found!\n";
return false;
}
@@ -151,17 +151,22 @@ void cmCTestLaunch::RunChild()
}
// Prepare to run the real command.
- cmsysProcess* cp = this->Process;
- cmsysProcess_SetCommand(cp, this->RealArgV);
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(this->RealArgV);
cmsys::ofstream fout;
cmsys::ofstream ferr;
if (this->Reporter.Passthru) {
// In passthru mode we just share the output pipes.
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
+ builder
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ cm_fileno(stdout))
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(stderr));
} else {
// In full mode we record the child output pipes to log files.
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
fout.open(this->Reporter.LogOut.c_str(), std::ios::out | std::ios::binary);
ferr.open(this->Reporter.LogErr.c_str(), std::ios::out | std::ios::binary);
}
@@ -174,51 +179,65 @@ void cmCTestLaunch::RunChild()
#endif
// Run the real command.
- cmsysProcess_Execute(cp);
+ auto chain = builder.Start();
// Record child stdout and stderr if necessary.
+ cm::uv_pipe_ptr outPipe;
+ cm::uv_pipe_ptr errPipe;
+ bool outFinished = true;
+ bool errFinished = true;
+ cmProcessOutput processOutput;
+ std::unique_ptr<cmUVStreamReadHandle> outputHandle;
+ std::unique_ptr<cmUVStreamReadHandle> errorHandle;
if (!this->Reporter.Passthru) {
- char* data = nullptr;
- int length = 0;
- cmProcessOutput processOutput;
- std::string strdata;
- while (int p = cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
- if (p == cmsysProcess_Pipe_STDOUT) {
- processOutput.DecodeText(data, length, strdata, 1);
- fout.write(strdata.c_str(), strdata.size());
- std::cout.write(strdata.c_str(), strdata.size());
- this->HaveOut = true;
- } else if (p == cmsysProcess_Pipe_STDERR) {
- processOutput.DecodeText(data, length, strdata, 2);
- ferr.write(strdata.c_str(), strdata.size());
- std::cerr.write(strdata.c_str(), strdata.size());
- this->HaveErr = true;
- }
- }
- processOutput.DecodeText(std::string(), strdata, 1);
- if (!strdata.empty()) {
- fout.write(strdata.c_str(), strdata.size());
- std::cout.write(strdata.c_str(), strdata.size());
- }
- processOutput.DecodeText(std::string(), strdata, 2);
- if (!strdata.empty()) {
- ferr.write(strdata.c_str(), strdata.size());
- std::cerr.write(strdata.c_str(), strdata.size());
- }
+ auto beginRead = [&chain, &processOutput](
+ cm::uv_pipe_ptr& pipe, int stream, std::ostream& out,
+ cmsys::ofstream& file, bool& haveData, bool& finished,
+ int id) -> std::unique_ptr<cmUVStreamReadHandle> {
+ pipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(pipe, stream);
+ finished = false;
+ return cmUVStreamRead(
+ pipe,
+ [&processOutput, &out, &file, id, &haveData](std::vector<char> data) {
+ std::string strdata;
+ processOutput.DecodeText(data.data(), data.size(), strdata, id);
+ file.write(strdata.c_str(), strdata.size());
+ out.write(strdata.c_str(), strdata.size());
+ haveData = true;
+ },
+ [&processOutput, &out, &file, &finished, id]() {
+ std::string strdata;
+ processOutput.DecodeText(std::string(), strdata, id);
+ if (!strdata.empty()) {
+ file.write(strdata.c_str(), strdata.size());
+ out.write(strdata.c_str(), strdata.size());
+ }
+ finished = true;
+ });
+ };
+ outputHandle = beginRead(outPipe, chain.OutputStream(), std::cout, fout,
+ this->HaveOut, outFinished, 1);
+ errorHandle = beginRead(errPipe, chain.ErrorStream(), std::cerr, ferr,
+ this->HaveErr, errFinished, 2);
}
// Wait for the real command to finish.
- cmsysProcess_WaitForExit(cp, nullptr);
- this->Reporter.ExitCode = cmsysProcess_GetExitValue(cp);
+ while (!(chain.Finished() && outFinished && errFinished)) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
+ }
+ this->Reporter.Status = chain.GetStatus(0);
+ if (this->Reporter.Status.GetException().first ==
+ cmUVProcessChain::ExceptionCode::Spawn) {
+ this->Reporter.ExitCode = 1;
+ } else {
+ this->Reporter.ExitCode =
+ static_cast<int>(this->Reporter.Status.ExitStatus);
+ }
}
int cmCTestLaunch::Run()
{
- if (!this->Process) {
- std::cerr << "Could not allocate cmsysProcess instance!\n";
- return -1;
- }
-
this->RunChild();
if (this->CheckResults()) {
@@ -226,7 +245,6 @@ int cmCTestLaunch::Run()
}
this->LoadConfig();
- this->Reporter.Process = this->Process;
this->Reporter.WriteXML();
return this->Reporter.ExitCode;
diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h
index c5a6476..ef21a26 100644
--- a/Source/CTest/cmCTestLaunch.h
+++ b/Source/CTest/cmCTestLaunch.h
@@ -43,15 +43,12 @@ private:
bool ParseArguments(int argc, const char* const* argv);
// The real command line appearing after launcher arguments.
- int RealArgC;
- const char* const* RealArgV;
+ std::vector<std::string> RealArgV;
// The real command line after response file expansion.
std::vector<std::string> RealArgs;
void HandleRealArg(const char* arg);
- struct cmsysProcess_s* Process;
-
// Whether or not any data have been written to stdout or stderr.
bool HaveOut;
bool HaveErr;
diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx
index 149ba5d..4b4e5c5 100644
--- a/Source/CTest/cmCTestLaunchReporter.cxx
+++ b/Source/CTest/cmCTestLaunchReporter.cxx
@@ -2,8 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestLaunchReporter.h"
+#include <utility>
+
#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmCryptoHash.h"
@@ -22,6 +23,7 @@
cmCTestLaunchReporter::cmCTestLaunchReporter()
{
this->Passthru = true;
+ this->Status.Finished = true;
this->ExitCode = 1;
this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
@@ -231,35 +233,23 @@ void cmCTestLaunchReporter::WriteXMLResult(cmXMLElement& e2)
// ExitCondition
cmXMLElement e4(e3, "ExitCondition");
- cmsysProcess* cp = this->Process;
- switch (cmsysProcess_GetState(cp)) {
- case cmsysProcess_State_Starting:
- e4.Content("No process has been executed");
- break;
- case cmsysProcess_State_Executing:
- e4.Content("The process is still executing");
- break;
- case cmsysProcess_State_Disowned:
- e4.Content("Disowned");
- break;
- case cmsysProcess_State_Killed:
- e4.Content("Killed by parent");
- break;
-
- case cmsysProcess_State_Expired:
- e4.Content("Killed when timeout expired");
- break;
- case cmsysProcess_State_Exited:
- e4.Content(this->ExitCode);
- break;
- case cmsysProcess_State_Exception:
- e4.Content("Terminated abnormally: ");
- e4.Content(cmsysProcess_GetExceptionString(cp));
- break;
- case cmsysProcess_State_Error:
- e4.Content("Error administrating child process: ");
- e4.Content(cmsysProcess_GetErrorString(cp));
- break;
+ if (this->Status.Finished) {
+ auto exception = this->Status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ e4.Content(this->ExitCode);
+ break;
+ case cmUVProcessChain::ExceptionCode::Spawn:
+ e4.Content("Error administrating child process: ");
+ e4.Content(exception.second);
+ break;
+ default:
+ e4.Content("Terminated abnormally: ");
+ e4.Content(exception.second);
+ break;
+ }
+ } else {
+ e4.Content("Killed when timeout expired");
}
}
diff --git a/Source/CTest/cmCTestLaunchReporter.h b/Source/CTest/cmCTestLaunchReporter.h
index 4be0d9b..2bb78f8 100644
--- a/Source/CTest/cmCTestLaunchReporter.h
+++ b/Source/CTest/cmCTestLaunchReporter.h
@@ -10,6 +10,8 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmUVProcessChain.h"
+
class cmXMLElement;
/** \class cmCTestLaunchReporter
@@ -48,7 +50,7 @@ public:
void ComputeFileNames();
bool Passthru;
- struct cmsysProcess_s* Process;
+ cmUVProcessChain::Status Status;
int ExitCode;
// Temporary log files for stdout and stderr of real command.
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 6f6a642..b51de84 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -7,6 +7,7 @@
#include <cstring>
#include <iostream>
#include <iterator>
+#include <ratio>
#include <sstream>
#include <utility>
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 7d22a87..ca07a08 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -35,6 +35,7 @@
#include "cmCTestRunTest.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
+#include "cmJSONState.h"
#include "cmListFileCache.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -75,6 +76,7 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
this->ProcessorsAvailable = cmAffinity::GetProcessorsAvailable();
this->HaveAffinity = this->ProcessorsAvailable.size();
this->HasCycles = false;
+ this->HasInvalidGeneratedResourceSpec = false;
this->SerialTestRunning = false;
}
@@ -95,7 +97,9 @@ void cmCTestMultiProcessHandler::SetTests(TestMap& tests,
if (!this->CTest->GetShowOnly()) {
this->ReadCostData();
this->HasCycles = !this->CheckCycles();
- if (this->HasCycles) {
+ this->HasInvalidGeneratedResourceSpec =
+ !this->CheckGeneratedResourceSpec();
+ if (this->HasCycles || this->HasInvalidGeneratedResourceSpec) {
return;
}
this->CreateTestCostList();
@@ -125,7 +129,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
void cmCTestMultiProcessHandler::RunTests()
{
this->CheckResume();
- if (this->HasCycles) {
+ if (this->HasCycles || this->HasInvalidGeneratedResourceSpec) {
return;
}
#ifdef CMAKE_UV_SIGNAL_HACK
@@ -180,7 +184,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
}
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
- if (this->TestHandler->UseResourceSpec) {
+ if (this->UseResourceSpec) {
testRun->SetUseAllocatedResources(true);
testRun->SetAllocatedResources(this->AllocatedResources[test]);
}
@@ -229,15 +233,15 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
}
e << "\n";
}
- e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
- cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+ e << "Resource spec file:\n\n " << this->ResourceSpecFile;
+ cmCTestRunTest::StartFailure(std::move(testRun), this->Total, e.str(),
"Insufficient resources");
return false;
}
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
- cmCTestRunTest::StartFailure(std::move(testRun),
+ cmCTestRunTest::StartFailure(std::move(testRun), this->Total,
"Failed to change working directory to " +
this->Properties[test]->Directory + " : " +
std::strerror(workdir.GetLastResult()),
@@ -253,7 +257,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
bool cmCTestMultiProcessHandler::AllocateResources(int index)
{
- if (!this->TestHandler->UseResourceSpec) {
+ if (!this->UseResourceSpec) {
return true;
}
@@ -322,7 +326,7 @@ bool cmCTestMultiProcessHandler::TryAllocateResources(
void cmCTestMultiProcessHandler::DeallocateResources(int index)
{
- if (!this->TestHandler->UseResourceSpec) {
+ if (!this->UseResourceSpec) {
return;
}
@@ -358,7 +362,7 @@ bool cmCTestMultiProcessHandler::AllResourcesAvailable()
void cmCTestMultiProcessHandler::CheckResourcesAvailable()
{
- if (this->TestHandler->UseResourceSpec) {
+ if (this->UseResourceSpec) {
for (auto test : this->SortedTests) {
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>
allocations;
@@ -1445,3 +1449,81 @@ bool cmCTestMultiProcessHandler::CheckCycles()
this->Quiet);
return true;
}
+
+bool cmCTestMultiProcessHandler::CheckGeneratedResourceSpec()
+{
+ for (auto& test : this->Properties) {
+ if (!test.second->GeneratedResourceSpecFile.empty()) {
+ if (this->ResourceSpecSetupTest) {
+ cmCTestLog(
+ this->CTest, ERROR_MESSAGE,
+ "Only one test may define the GENERATED_RESOURCE_SPEC_FILE property"
+ << std::endl);
+ return false;
+ }
+
+ if (test.second->FixturesSetup.size() != 1) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Test that defines GENERATED_RESOURCE_SPEC_FILE must have "
+ "exactly one FIXTURES_SETUP"
+ << std::endl);
+ return false;
+ }
+
+ if (!cmSystemTools::FileIsFullPath(
+ test.second->GeneratedResourceSpecFile)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "GENERATED_RESOURCE_SPEC_FILE must be an absolute path"
+ << std::endl);
+ return false;
+ }
+
+ this->ResourceSpecSetupTest = test.first;
+ this->ResourceSpecSetupFixture = *test.second->FixturesSetup.begin();
+ }
+ }
+
+ if (!this->ResourceSpecSetupFixture.empty()) {
+ for (auto& test : this->Properties) {
+ if (!test.second->ResourceGroups.empty() &&
+ !test.second->FixturesRequired.count(
+ this->ResourceSpecSetupFixture)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "All tests that have RESOURCE_GROUPS must include the "
+ "resource spec generator fixture in their FIXTURES_REQUIRED"
+ << std::endl);
+ return false;
+ }
+ }
+ }
+
+ if (!this->ResourceSpecFile.empty()) {
+ if (this->ResourceSpecSetupTest) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "GENERATED_RESOURCE_SPEC_FILE test property cannot be used "
+ "in conjunction with ResourceSpecFile option"
+ << std::endl);
+ return false;
+ }
+ std::string error;
+ if (!this->InitResourceAllocator(error)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, error << std::endl);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool cmCTestMultiProcessHandler::InitResourceAllocator(std::string& error)
+{
+ if (!this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile)) {
+ error = cmStrCat("Could not read/parse resource spec file ",
+ this->ResourceSpecFile, ": ",
+ this->ResourceSpec.parseState.GetErrorMessage());
+ return false;
+ }
+ this->UseResourceSpec = true;
+ this->ResourceAllocator.InitializeFromResourceSpec(this->ResourceSpec);
+ return true;
+}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 2f5ad40..3b4e9c5 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -11,15 +11,17 @@
#include <string>
#include <vector>
+#include <cm/optional>
+
#include <cm3p/uv.h>
#include "cmCTest.h"
#include "cmCTestResourceAllocator.h"
+#include "cmCTestResourceSpec.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
struct cmCTestBinPackerAllocation;
-class cmCTestResourceSpec;
class cmCTestRunTest;
/** \class cmCTestMultiProcessHandler
@@ -90,13 +92,13 @@ public:
this->RepeatCount = count;
}
- void SetQuiet(bool b) { this->Quiet = b; }
-
- void InitResourceAllocator(const cmCTestResourceSpec& spec)
+ void SetResourceSpecFile(const std::string& resourceSpecFile)
{
- this->ResourceAllocator.InitializeFromResourceSpec(spec);
+ this->ResourceSpecFile = resourceSpecFile;
}
+ void SetQuiet(bool b) { this->Quiet = b; }
+
void CheckResourcesAvailable();
protected:
@@ -158,6 +160,15 @@ protected:
std::map<std::string, ResourceAllocationError>* errors = nullptr);
void DeallocateResources(int index);
bool AllResourcesAvailable();
+ bool InitResourceAllocator(std::string& error);
+ bool CheckGeneratedResourceSpec();
+
+ bool UseResourceSpec = false;
+ cmCTestResourceSpec ResourceSpec;
+ std::string ResourceSpecFile;
+ std::string ResourceSpecSetupFixture;
+ cm::optional<std::size_t> ResourceSpecSetupTest;
+ bool HasInvalidGeneratedResourceSpec;
// map from test number to set of depend tests
TestMap Tests;
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index e22ec4b..5d71b84 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -14,7 +14,6 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmList.h"
-#include "cmProcessTools.h"
#include "cmRange.h"
#include "cmSystemTools.h"
@@ -150,17 +149,16 @@ cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
auto it = this->Users.find(username);
if (it == this->Users.end()) {
- std::vector<char const*> p4_users;
+ std::vector<std::string> p4_users;
this->SetP4Options(p4_users);
p4_users.push_back("users");
p4_users.push_back("-m");
p4_users.push_back("1");
- p4_users.push_back(username.c_str());
- p4_users.push_back(nullptr);
+ p4_users.push_back(username);
UserParser out(this, "users-out> ");
OutputLogger err(this->Log, "users-err> ");
- this->RunChild(p4_users.data(), &out, &err);
+ this->RunChild(p4_users, &out, &err);
// The user should now be added to the map. Search again.
it = this->Users.find(username);
@@ -304,10 +302,10 @@ private:
}
};
-void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
+void cmCTestP4::SetP4Options(std::vector<std::string>& CommandOptions)
{
if (this->P4Options.empty()) {
- const char* p4 = this->CommandLineTool.c_str();
+ std::string p4 = this->CommandLineTool;
this->P4Options.emplace_back(p4);
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing
@@ -329,15 +327,12 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
cm::append(this->P4Options, cmSystemTools::ParseArguments(opts));
}
- CommandOptions.clear();
- for (std::string const& o : this->P4Options) {
- CommandOptions.push_back(o.c_str());
- }
+ CommandOptions = this->P4Options;
}
std::string cmCTestP4::GetWorkingRevision()
{
- std::vector<char const*> p4_identify;
+ std::vector<std::string> p4_identify;
this->SetP4Options(p4_identify);
p4_identify.push_back("changes");
@@ -346,14 +341,13 @@ std::string cmCTestP4::GetWorkingRevision()
p4_identify.push_back("-t");
std::string source = this->SourceDirectory + "/...#have";
- p4_identify.push_back(source.c_str());
- p4_identify.push_back(nullptr);
+ p4_identify.push_back(source);
std::string rev;
IdentifyParser out(this, "p4_changes-out> ", rev);
OutputLogger err(this->Log, "p4_changes-err> ");
- bool result = this->RunChild(p4_identify.data(), &out, &err);
+ bool result = this->RunChild(p4_identify, &out, &err);
// If there was a problem contacting the server return "<unknown>"
if (!result) {
@@ -389,7 +383,7 @@ bool cmCTestP4::NoteNewRevision()
bool cmCTestP4::LoadRevisions()
{
- std::vector<char const*> p4_changes;
+ std::vector<std::string> p4_changes;
this->SetP4Options(p4_changes);
// Use 'p4 changes ...@old,new' to get a list of changelists
@@ -410,38 +404,36 @@ bool cmCTestP4::LoadRevisions()
.append(this->NewRevision);
p4_changes.push_back("changes");
- p4_changes.push_back(range.c_str());
- p4_changes.push_back(nullptr);
+ p4_changes.push_back(range);
ChangesParser out(this, "p4_changes-out> ");
OutputLogger err(this->Log, "p4_changes-err> ");
this->ChangeLists.clear();
- this->RunChild(p4_changes.data(), &out, &err);
+ this->RunChild(p4_changes, &out, &err);
if (this->ChangeLists.empty()) {
return true;
}
// p4 describe -s ...@1111111,2222222
- std::vector<char const*> p4_describe;
+ std::vector<std::string> p4_describe;
for (std::string const& i : cmReverseRange(this->ChangeLists)) {
this->SetP4Options(p4_describe);
p4_describe.push_back("describe");
p4_describe.push_back("-s");
- p4_describe.push_back(i.c_str());
- p4_describe.push_back(nullptr);
+ p4_describe.push_back(i);
DescribeParser outDescribe(this, "p4_describe-out> ");
OutputLogger errDescribe(this->Log, "p4_describe-err> ");
- this->RunChild(p4_describe.data(), &outDescribe, &errDescribe);
+ this->RunChild(p4_describe, &outDescribe, &errDescribe);
}
return true;
}
bool cmCTestP4::LoadModifications()
{
- std::vector<char const*> p4_diff;
+ std::vector<std::string> p4_diff;
this->SetP4Options(p4_diff);
p4_diff.push_back("diff");
@@ -449,12 +441,11 @@ bool cmCTestP4::LoadModifications()
// Ideally we would use -Od but not all clients support it
p4_diff.push_back("-dn");
std::string source = this->SourceDirectory + "/...";
- p4_diff.push_back(source.c_str());
- p4_diff.push_back(nullptr);
+ p4_diff.push_back(source);
DiffParser out(this, "p4_diff-out> ");
OutputLogger err(this->Log, "p4_diff-err> ");
- this->RunChild(p4_diff.data(), &out, &err);
+ this->RunChild(p4_diff, &out, &err);
return true;
}
@@ -462,17 +453,14 @@ bool cmCTestP4::UpdateCustom(const std::string& custom)
{
cmList p4_custom_command{ custom, cmList::EmptyElements::Yes };
- std::vector<char const*> p4_custom;
- p4_custom.reserve(p4_custom_command.size() + 1);
- for (std::string const& i : p4_custom_command) {
- p4_custom.push_back(i.c_str());
- }
- p4_custom.push_back(nullptr);
+ std::vector<std::string> p4_custom;
+ p4_custom.reserve(p4_custom_command.size());
+ cm::append(p4_custom, p4_custom_command);
OutputLogger custom_out(this->Log, "p4_customsync-out> ");
OutputLogger custom_err(this->Log, "p4_customsync-err> ");
- return this->RunUpdateCommand(p4_custom.data(), &custom_out, &custom_err);
+ return this->RunUpdateCommand(p4_custom, &custom_out, &custom_err);
}
bool cmCTestP4::UpdateImpl()
@@ -489,7 +477,7 @@ bool cmCTestP4::UpdateImpl()
return false;
}
- std::vector<char const*> p4_sync;
+ std::vector<std::string> p4_sync;
this->SetP4Options(p4_sync);
p4_sync.push_back("sync");
@@ -500,9 +488,7 @@ bool cmCTestP4::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("P4UpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- for (std::string const& arg : args) {
- p4_sync.push_back(arg.c_str());
- }
+ cm::append(p4_sync, args);
std::string source = this->SourceDirectory + "/...";
@@ -516,11 +502,10 @@ bool cmCTestP4::UpdateImpl()
source.append("@\"").append(date).append("\"");
}
- p4_sync.push_back(source.c_str());
- p4_sync.push_back(nullptr);
+ p4_sync.push_back(source);
OutputLogger out(this->Log, "p4_sync-out> ");
OutputLogger err(this->Log, "p4_sync-err> ");
- return this->RunUpdateCommand(p4_sync.data(), &out, &err);
+ return this->RunUpdateCommand(p4_sync, &out, &err);
}
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
index 1889520..827caa1 100644
--- a/Source/CTest/cmCTestP4.h
+++ b/Source/CTest/cmCTestP4.h
@@ -39,7 +39,7 @@ private:
std::vector<std::string> P4Options;
User GetUserData(const std::string& username);
- void SetP4Options(std::vector<char const*>& options);
+ void SetP4Options(std::vector<std::string>& options);
std::string GetWorkingRevision();
bool NoteOldRevision() override;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 563439a..4c57cf6 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -152,6 +152,18 @@ cmCTestRunTest::EndTestResult cmCTestRunTest::EndTest(size_t completed,
}
}
}
+ std::string resourceSpecParseError;
+ if (!this->TestProperties->GeneratedResourceSpecFile.empty()) {
+ this->MultiTestHandler.ResourceSpecFile =
+ this->TestProperties->GeneratedResourceSpecFile;
+ if (!this->MultiTestHandler.InitResourceAllocator(
+ resourceSpecParseError)) {
+ reason = "Invalid resource spec file";
+ forceFail = true;
+ } else {
+ this->MultiTestHandler.CheckResourcesAvailable();
+ }
+ }
std::ostringstream outputStream;
if (res == cmProcess::State::Exited) {
bool success = !forceFail &&
@@ -260,6 +272,16 @@ cmCTestRunTest::EndTestResult cmCTestRunTest::EndTest(size_t completed,
cmCTestLog(this->CTest, HANDLER_OUTPUT, this->ProcessOutput << std::endl);
}
+ if (!resourceSpecParseError.empty()) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ resourceSpecParseError << std::endl);
+ } else if (!this->TestProperties->GeneratedResourceSpecFile.empty()) {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Using generated resource spec file "
+ << this->TestProperties->GeneratedResourceSpecFile
+ << std::endl);
+ }
+
if (this->TestHandler->LogFile) {
*this->TestHandler->LogFile << "Test time = " << buf << std::endl;
}
@@ -372,7 +394,8 @@ bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner,
// change to tests directory
cmWorkingDirectory workdir(testRun->TestProperties->Directory);
if (workdir.Failed()) {
- testRun->StartFailure("Failed to change working directory to " +
+ testRun->StartFailure(testRun->TotalNumberOfTests,
+ "Failed to change working directory to " +
testRun->TestProperties->Directory + " : " +
std::strerror(workdir.GetLastResult()),
"Failed to change working directory");
@@ -437,25 +460,25 @@ void cmCTestRunTest::MemCheckPostProcess()
}
void cmCTestRunTest::StartFailure(std::unique_ptr<cmCTestRunTest> runner,
- std::string const& output,
+ size_t total, std::string const& output,
std::string const& detail)
{
auto* testRun = runner.get();
testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
- testRun->StartFailure(output, detail);
+ testRun->StartFailure(total, output, detail);
testRun->FinalizeTest(false);
}
-void cmCTestRunTest::StartFailure(std::string const& output,
+void cmCTestRunTest::StartFailure(size_t total, std::string const& output,
std::string const& detail)
{
// Still need to log the Start message so the test summary records our
// attempt to start this test
if (!this->CTest->GetTestProgressOutput()) {
cmCTestLog(this->CTest, HANDLER_OUTPUT,
- std::setw(2 * getNumWidth(this->TotalNumberOfTests) + 8)
+ std::setw(2 * getNumWidth(total) + 8)
<< "Start "
<< std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
<< this->TestProperties->Index << ": "
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index fed7296..34f23c4 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -68,7 +68,7 @@ public:
size_t completed);
static void StartFailure(std::unique_ptr<cmCTestRunTest> runner,
- std::string const& output,
+ size_t total, std::string const& output,
std::string const& detail);
struct EndTestResult
@@ -86,7 +86,8 @@ public:
void ComputeWeightedCost();
- void StartFailure(std::string const& output, std::string const& detail);
+ void StartFailure(size_t total, std::string const& output,
+ std::string const& detail);
cmCTest* GetCTest() const { return this->CTest; }
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 4c98fdf..14bc510 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -13,7 +13,6 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
-#include "cmProcessTools.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -34,7 +33,7 @@ cmCTestSVN::~cmCTestSVN() = default;
void cmCTestSVN::CleanupImpl()
{
- std::vector<const char*> svn_cleanup;
+ std::vector<std::string> svn_cleanup;
svn_cleanup.push_back("cleanup");
OutputLogger out(this->Log, "cleanup-out> ");
OutputLogger err(this->Log, "cleanup-err> ");
@@ -89,9 +88,9 @@ static bool cmCTestSVNPathStarts(std::string const& p1, std::string const& p2)
std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo)
{
// Run "svn info" to get the repository info from the work tree.
- std::vector<const char*> svn_info;
+ std::vector<std::string> svn_info;
svn_info.push_back("info");
- svn_info.push_back(svninfo.LocalPath.c_str());
+ svn_info.push_back(svninfo.LocalPath);
std::string rev;
InfoParser out(this, "info-out> ", rev, svninfo);
OutputLogger err(this->Log, "info-err> ");
@@ -252,26 +251,24 @@ bool cmCTestSVN::UpdateImpl()
args.push_back("-r{" + this->GetNightlyTime() + " +0000}");
}
- std::vector<char const*> svn_update;
+ std::vector<std::string> svn_update;
svn_update.push_back("update");
- for (std::string const& arg : args) {
- svn_update.push_back(arg.c_str());
- }
+ cm::append(svn_update, args);
UpdateParser out(this, "up-out> ");
OutputLogger err(this->Log, "up-err> ");
return this->RunSVNCommand(svn_update, &out, &err);
}
-bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
+bool cmCTestSVN::RunSVNCommand(std::vector<std::string> const& parameters,
OutputParser* out, OutputParser* err)
{
if (parameters.empty()) {
return false;
}
- std::vector<char const*> args;
- args.push_back(this->CommandLineTool.c_str());
+ std::vector<std::string> args;
+ args.push_back(this->CommandLineTool);
cm::append(args, parameters);
args.push_back("--non-interactive");
@@ -279,16 +276,12 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
std::vector<std::string> parsedUserOptions =
cmSystemTools::ParseArguments(userOptions);
- for (std::string const& opt : parsedUserOptions) {
- args.push_back(opt.c_str());
- }
-
- args.push_back(nullptr);
+ cm::append(args, parsedUserOptions);
- if (strcmp(parameters[0], "update") == 0) {
- return this->RunUpdateCommand(args.data(), out, err);
+ if (parameters[0] == "update") {
+ return this->RunUpdateCommand(args, out, err);
}
- return this->RunChild(args.data(), out, err);
+ return this->RunChild(args, out, err);
}
class cmCTestSVN::LogParser
@@ -394,7 +387,7 @@ bool cmCTestSVN::LoadRevisions(SVNInfo& svninfo)
}
// Run "svn log" to get all global revisions of interest.
- std::vector<const char*> svn_log;
+ std::vector<std::string> svn_log;
svn_log.push_back("log");
svn_log.push_back("--xml");
svn_log.push_back("-v");
@@ -473,7 +466,7 @@ private:
bool cmCTestSVN::LoadModifications()
{
// Run "svn status" which reports local modifications.
- std::vector<const char*> svn_status;
+ std::vector<std::string> svn_status;
svn_status.push_back("status");
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
@@ -535,7 +528,7 @@ bool cmCTestSVN::LoadRepositories()
this->RootInfo = &(this->Repositories.back());
// Run "svn status" to get the list of external repositories
- std::vector<const char*> svn_status;
+ std::vector<std::string> svn_status;
svn_status.push_back("status");
ExternalParser out(this, "external-out> ");
OutputLogger err(this->Log, "external-err> ");
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 370d176..1485dc0 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -33,7 +33,7 @@ private:
bool NoteNewRevision() override;
bool UpdateImpl() override;
- bool RunSVNCommand(std::vector<char const*> const& parameters,
+ bool RunSVNCommand(std::vector<std::string> const& parameters,
OutputParser* out, OutputParser* err);
// Information about an SVN repository (root repository or external)
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 461ad1a..48f8f6d 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -11,8 +11,9 @@
#include <cm/memory>
+#include <cm3p/uv.h>
+
#include "cmsys/Directory.hxx"
-#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestBuildCommand.h"
@@ -40,6 +41,8 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
#include "cmValue.h"
#include "cmake.h"
@@ -148,66 +151,65 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
// now pass through all the other arguments
std::vector<std::string>& initArgs =
this->CTest->GetInitialCommandLineArguments();
- //*** need to make sure this does not have the current script ***
- for (size_t i = 1; i < initArgs.size(); ++i) {
- argv.push_back(initArgs[i].c_str());
- }
- argv.push_back(nullptr);
// Now create process object
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, argv.data());
- // cmsysProcess_SetWorkingDirectory(cp, dir);
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
- // cmsysProcess_SetTimeout(cp, timeout);
- cmsysProcess_Execute(cp);
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(initArgs)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+ auto process = builder.Start();
+ cm::uv_pipe_ptr outPipe;
+ outPipe.init(process.GetLoop(), 0);
+ uv_pipe_open(outPipe, process.OutputStream());
+ cm::uv_pipe_ptr errPipe;
+ errPipe.init(process.GetLoop(), 0);
+ uv_pipe_open(errPipe, process.ErrorStream());
std::vector<char> out;
std::vector<char> err;
std::string line;
- int pipe =
- cmSystemTools::WaitForLine(cp, line, std::chrono::seconds(100), out, err);
- while (pipe != cmsysProcess_Pipe_None) {
+ auto pipe =
+ cmSystemTools::WaitForLine(&process.GetLoop(), outPipe, errPipe, line,
+ std::chrono::seconds(100), out, err);
+ while (pipe != cmSystemTools::WaitForLineResult::None) {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Output: " << line << "\n");
- if (pipe == cmsysProcess_Pipe_STDERR) {
+ if (pipe == cmSystemTools::WaitForLineResult::STDERR) {
cmCTestLog(this->CTest, ERROR_MESSAGE, line << "\n");
- } else if (pipe == cmsysProcess_Pipe_STDOUT) {
+ } else if (pipe == cmSystemTools::WaitForLineResult::STDOUT) {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, line << "\n");
}
- pipe = cmSystemTools::WaitForLine(cp, line, std::chrono::seconds(100), out,
- err);
+ pipe =
+ cmSystemTools::WaitForLine(&process.GetLoop(), outPipe, errPipe, line,
+ std::chrono::seconds(100), out, err);
}
// Properly handle output of the build command
- cmsysProcess_WaitForExit(cp, nullptr);
- int result = cmsysProcess_GetState(cp);
+ process.Wait();
+ auto const& status = process.GetStatus(0);
+ auto result = status.GetException();
int retVal = 0;
bool failed = false;
- if (result == cmsysProcess_State_Exited) {
- retVal = cmsysProcess_GetExitValue(cp);
- } else if (result == cmsysProcess_State_Exception) {
- retVal = cmsysProcess_GetExitException(cp);
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "\tThere was an exception: "
- << cmsysProcess_GetExceptionString(cp) << " " << retVal
- << std::endl);
- failed = true;
- } else if (result == cmsysProcess_State_Expired) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "\tThere was a timeout" << std::endl);
- failed = true;
- } else if (result == cmsysProcess_State_Error) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "\tError executing ctest: " << cmsysProcess_GetErrorString(cp)
- << std::endl);
- failed = true;
+ switch (result.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ retVal = static_cast<int>(status.ExitStatus);
+ break;
+ case cmUVProcessChain::ExceptionCode::Spawn:
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "\tError executing ctest: " << result.second << std::endl);
+ failed = true;
+ break;
+ default:
+ retVal = status.TermSignal;
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "\tThere was an exception: " << result.second << " " << retVal
+ << std::endl);
+ failed = true;
}
- cmsysProcess_Delete(cp);
if (failed) {
std::ostringstream message;
message << "Error running command: [";
- message << result << "] ";
+ message << static_cast<int>(result.first) << "] ";
for (const char* arg : argv) {
if (arg) {
message << arg << " ";
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index c04f23a..77af889 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -285,8 +285,8 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
if (cmIsOn(this->GetOption("InternalTest"))) {
upload_as += "ffffffffffffffffffffffffffffffff";
} else {
- upload_as +=
- cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5);
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ upload_as += hasher.HashFile(local_file);
}
if (!cmSystemTools::FileExists(local_file)) {
@@ -552,8 +552,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
}
}
- std::string md5sum =
- cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5);
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ std::string md5sum = hasher.HashFile(file);
// 1. request the buildid and check to see if the file
// has already been uploaded
// TODO I added support for subproject. You would need to add
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 5488388..c717868 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -4,6 +4,7 @@
#include <chrono>
#include <cstdlib>
+#include <ratio>
#include <sstream>
#include <cmext/string_view>
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 6b02a5e..e4b9239 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -13,6 +13,7 @@
#include <functional>
#include <iomanip>
#include <iterator>
+#include <ratio>
#include <set>
#include <sstream>
#include <utility>
@@ -41,7 +42,6 @@
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
-#include "cmJSONState.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -283,7 +283,6 @@ cmCTestTestHandler::cmCTestTestHandler()
this->UseIncludeRegExpFlag = false;
this->UseExcludeRegExpFlag = false;
this->UseExcludeRegExpFirst = false;
- this->UseResourceSpec = false;
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
@@ -890,8 +889,7 @@ bool cmCTestTestHandler::ComputeTestList()
}
if (this->RerunFailed) {
- this->ComputeTestListForRerunFailed();
- return true;
+ return this->ComputeTestListForRerunFailed();
}
cmCTestTestHandler::ListOfTests::size_type tmsize = this->TestList.size();
@@ -950,7 +948,7 @@ bool cmCTestTestHandler::ComputeTestList()
return true;
}
-void cmCTestTestHandler::ComputeTestListForRerunFailed()
+bool cmCTestTestHandler::ComputeTestListForRerunFailed()
{
this->ExpandTestsToRunInformationForRerunFailed();
@@ -977,6 +975,8 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
this->TestList = finalList;
this->UpdateMaxTestNameWidth();
+
+ return true;
}
void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
@@ -1350,18 +1350,6 @@ bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->SetTestLoad(this->CTest->GetTestLoad());
}
- if (!this->ResourceSpecFile.empty()) {
- this->UseResourceSpec = true;
- if (!this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Could not read/parse resource spec file "
- << this->ResourceSpecFile << ": "
- << this->ResourceSpec.parseState.GetErrorMessage()
- << std::endl);
- return false;
- }
- parallel->InitResourceAllocator(this->ResourceSpec);
- }
*this->LogFile
<< "Start testing: " << this->CTest->CurrentTime() << std::endl
@@ -1396,6 +1384,7 @@ bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
tests[p.Index] = depends;
properties[p.Index] = &p;
}
+ parallel->SetResourceSpecFile(this->ResourceSpecFile);
parallel->SetTests(tests, properties);
parallel->SetPassFailVectors(&passed, &failed);
this->TestResults.clear();
@@ -2335,6 +2324,8 @@ bool cmCTestTestHandler::SetTestsProperties(
if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
return false;
}
+ } else if (key == "GENERATED_RESOURCE_SPEC_FILE"_s) {
+ rt.GeneratedResourceSpecFile = val;
} else if (key == "SKIP_RETURN_CODE"_s) {
rt.SkipReturnCode = atoi(val.c_str());
if (rt.SkipReturnCode < 0 || rt.SkipReturnCode > 255) {
@@ -2617,6 +2608,21 @@ bool cmCTestTestHandler::WriteJUnitXML()
xml.EndElement(); // </failure>
}
+ xml.StartElement("properties");
+ if ((result.Properties) && (!result.Properties->Labels.empty())) {
+ xml.StartElement("property");
+ xml.Attribute("name", "cmake_labels");
+ // Pass the property as a cmake-formatted list, consumers will know
+ // anyway that this information is coming from cmake, so it should
+ // be ok to put it here as a cmake-list.
+ xml.Attribute("value", cmList::to_string(result.Properties->Labels));
+ // if we export more properties, this should be done the same way,
+ // i.e. prefix the property name with "cmake_", and it it can be
+ // a list, write it cmake-formatted.
+ xml.EndElement(); // </property>
+ }
+ xml.EndElement(); // </properties>
+
// Note: compressed test output is unconditionally disabled when
// --output-junit is specified.
xml.Element("system-out", result.Output);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 315a5b7..23f0a76 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -21,8 +21,7 @@
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
-#include "cmCTestResourceSpec.h"
-#include "cmCTestTypes.h"
+#include "cmCTestTypes.h" // IWYU pragma: keep
#include "cmDuration.h"
#include "cmListFileCache.h"
#include "cmValue.h"
@@ -172,6 +171,7 @@ public:
std::set<std::string> FixturesRequired;
std::set<std::string> RequireSuccessDepends;
std::vector<std::vector<cmCTestTestResourceRequirement>> ResourceGroups;
+ std::string GeneratedResourceSpecFile;
// Private test generator properties used to track backtraces
cmListFileBacktrace Backtrace;
};
@@ -319,7 +319,7 @@ private:
// compute the lists of tests that will actually run
// based on LastTestFailed.log
- void ComputeTestListForRerunFailed();
+ bool ComputeTestListForRerunFailed();
// add required setup/cleanup tests not already in the
// list of tests to be run and update dependencies between
@@ -360,8 +360,6 @@ private:
cmsys::RegularExpression IncludeTestsRegularExpression;
cmsys::RegularExpression ExcludeTestsRegularExpression;
- bool UseResourceSpec;
- cmCTestResourceSpec ResourceSpec;
std::string ResourceSpecFile;
void RecordCustomTestMeasurements(cmXMLWriter& xml, std::string content);
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 609ccba..cbbb5a5 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -7,10 +7,9 @@
#include <sstream>
#include <vector>
-#include "cmsys/Process.h"
-
#include "cmCTest.h"
#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
#include "cmValue.h"
#include "cmXMLWriter.h"
@@ -55,18 +54,12 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
// Construct the initial checkout command line.
std::vector<std::string> args = cmSystemTools::ParseArguments(command);
- std::vector<char const*> vc_co;
- vc_co.reserve(args.size() + 1);
- for (std::string const& arg : args) {
- vc_co.push_back(arg.c_str());
- }
- vc_co.push_back(nullptr);
// Run the initial checkout command and log its output.
this->Log << "--- Begin Initial Checkout ---\n";
OutputLogger out(this->Log, "co-out> ");
OutputLogger err(this->Log, "co-err> ");
- bool result = this->RunChild(vc_co.data(), &out, &err, parent.c_str());
+ bool result = this->RunChild(args, &out, &err, parent);
this->Log << "--- End Initial Checkout ---\n";
if (!result) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -75,35 +68,35 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
return result;
}
-bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out,
- OutputParser* err, const char* workDir,
- Encoding encoding)
+bool cmCTestVC::RunChild(const std::vector<std::string>& cmd,
+ OutputParser* out, OutputParser* err,
+ std::string workDir, Encoding encoding)
{
this->Log << cmCTestVC::ComputeCommandLine(cmd) << "\n";
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, cmd);
- workDir = workDir ? workDir : this->SourceDirectory.c_str();
- cmsysProcess_SetWorkingDirectory(cp, workDir);
- cmCTestVC::RunProcess(cp, out, err, encoding);
- int result = cmsysProcess_GetExitValue(cp);
- cmsysProcess_Delete(cp);
- return result == 0;
+ cmUVProcessChainBuilder builder;
+ if (workDir.empty()) {
+ workDir = this->SourceDirectory;
+ }
+ builder.AddCommand(cmd).SetWorkingDirectory(workDir);
+ auto status = cmCTestVC::RunProcess(builder, out, err, encoding);
+ return status.front().SpawnResult == 0 && status.front().ExitStatus == 0;
}
-std::string cmCTestVC::ComputeCommandLine(char const* const* cmd)
+std::string cmCTestVC::ComputeCommandLine(const std::vector<std::string>& cmd)
{
std::ostringstream line;
const char* sep = "";
- for (const char* const* arg = cmd; *arg; ++arg) {
- line << sep << "\"" << *arg << "\"";
+ for (auto const& arg : cmd) {
+ line << sep << "\"" << arg << "\"";
sep = " ";
}
return line.str();
}
-bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out,
- OutputParser* err, Encoding encoding)
+bool cmCTestVC::RunUpdateCommand(const std::vector<std::string>& cmd,
+ OutputParser* out, OutputParser* err,
+ Encoding encoding)
{
// Report the command line.
this->UpdateCommandLine = this->ComputeCommandLine(cmd);
@@ -113,7 +106,7 @@ bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out,
}
// Run the command.
- return this->RunChild(cmd, out, err, nullptr, encoding);
+ return this->RunChild(cmd, out, err, "", encoding);
}
std::string cmCTestVC::GetNightlyTime()
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 7b03d10..dd5456d 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -6,6 +6,7 @@
#include <iosfwd>
#include <string>
+#include <vector>
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
@@ -108,15 +109,15 @@ protected:
};
/** Convert a list of arguments to a human-readable command line. */
- static std::string ComputeCommandLine(char const* const* cmd);
+ static std::string ComputeCommandLine(const std::vector<std::string>& cmd);
/** Run a command line and send output to given parsers. */
- bool RunChild(char const* const* cmd, OutputParser* out, OutputParser* err,
- const char* workDir = nullptr,
+ bool RunChild(const std::vector<std::string>& cmd, OutputParser* out,
+ OutputParser* err, std::string workDir = {},
Encoding encoding = cmProcessOutput::Auto);
/** Run VC update command line and send output to given parsers. */
- bool RunUpdateCommand(char const* const* cmd, OutputParser* out,
+ bool RunUpdateCommand(const std::vector<std::string>& cmd, OutputParser* out,
OutputParser* err = nullptr,
Encoding encoding = cmProcessOutput::Auto);
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 14417cc..c63b496 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -2,7 +2,6 @@
#include <cstdio>
#include <cstdlib>
-#include <map>
#include <vector>
#include "cmsys/Directory.hxx"
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 269b92c..2c809b6 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -4,6 +4,7 @@
#include <csignal>
#include <iostream>
+#include <ratio>
#include <string>
#include <utility>
diff --git a/Source/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt
index 0fee7ac..bc6b906 100644
--- a/Source/Checks/Curses/CMakeLists.txt
+++ b/Source/Checks/Curses/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.13...3.24 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
project(CheckCurses C)
set(CURSES_NEED_NCURSES TRUE)
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index fc5450e..0b104ea 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -4,6 +4,7 @@
#include <cassert>
#include <utility>
+#include <vector>
#include <cm/memory>
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index a1b2149..77a0048 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -458,6 +458,14 @@ void cmCursesMainForm::UpdateProgress(const std::string& msg, float prog)
}
}
+void cmCursesMainForm::Write()
+{
+ this->FillCacheManagerFromUI();
+ this->CMakeInstance->SaveCache(
+ this->CMakeInstance->GetHomeOutputDirectory());
+ this->LoadCache(nullptr);
+}
+
int cmCursesMainForm::Configure(int noconfigure)
{
this->ResetOutputs();
@@ -471,10 +479,7 @@ int cmCursesMainForm::Configure(int noconfigure)
}
// always save the current gui values to disk
- this->FillCacheManagerFromUI();
- this->CMakeInstance->SaveCache(
- this->CMakeInstance->GetHomeOutputDirectory());
- this->LoadCache(nullptr);
+ this->Write();
// run the generate process
this->OkToGenerate = true;
@@ -794,6 +799,21 @@ void cmCursesMainForm::HandleInput()
else if (key == KEY_PPAGE || key == ctrl('u')) {
form_driver(this->Form, REQ_PREV_PAGE);
}
+ // first entry
+ else if (key == KEY_HOME) {
+ form_driver(this->Form, REQ_FIRST_PAGE);
+ form_driver(this->Form, REQ_FIRST_FIELD);
+ }
+ // last entry
+ else if (key == KEY_END) {
+ form_driver(this->Form, REQ_LAST_PAGE);
+ form_driver(this->Form, REQ_LAST_FIELD);
+ }
+ // write and quit
+ else if (key == 'w') {
+ this->Write();
+ break;
+ }
// configure
else if (key == 'c') {
this->Configure();
@@ -854,6 +874,10 @@ void cmCursesMainForm::HandleInput()
if (!this->OldSearchString.empty()) {
this->JumpToCacheEntry(this->OldSearchString.c_str());
}
+ } else if (key == 'N') {
+ if (!this->OldSearchString.empty()) {
+ this->JumpToCacheEntry(this->OldSearchString.c_str(), true);
+ }
}
// switch advanced on/off
else if (key == 't') {
@@ -945,6 +969,11 @@ int cmCursesMainForm::LoadCache(const char* /*unused*/)
void cmCursesMainForm::JumpToCacheEntry(const char* astr)
{
+ this->JumpToCacheEntry(astr, false);
+}
+
+void cmCursesMainForm::JumpToCacheEntry(const char* astr, bool reverse)
+{
std::string str;
if (astr) {
str = cmSystemTools::LowerCase(astr);
@@ -973,12 +1002,21 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr)
}
}
}
- if (static_cast<size_t>(findex) >= 3 * this->NumberOfVisibleEntries - 1) {
- set_current_field(this->Form, this->Fields[2]);
- } else if (new_page(this->Fields[findex + 1])) {
- form_driver(this->Form, REQ_NEXT_PAGE);
+ if (!reverse &&
+ static_cast<size_t>(findex) >= 3 * this->NumberOfVisibleEntries - 1) {
+ form_driver(this->Form, REQ_FIRST_PAGE);
+ form_driver(this->Form, REQ_FIRST_FIELD);
+ } else if (reverse && static_cast<size_t>(findex) < 3) {
+ form_driver(this->Form, REQ_LAST_PAGE);
+ form_driver(this->Form, REQ_LAST_FIELD);
+ } else if (this->Fields[findex + (reverse ? -3 : 1)]->page !=
+ this->Fields[findex]->page) {
+ form_driver(this->Form, reverse ? REQ_PREV_PAGE : REQ_NEXT_PAGE);
+ if (reverse) {
+ form_driver(this->Form, REQ_LAST_FIELD);
+ }
} else {
- form_driver(this->Form, REQ_NEXT_FIELD);
+ form_driver(this->Form, reverse ? REQ_PREV_FIELD : REQ_NEXT_FIELD);
}
cur = current_field(this->Form);
findex = field_index(cur);
@@ -1040,15 +1078,21 @@ const char* cmCursesMainForm::s_ConstHelpMessage =
"hit 'g' to have CMake generate all the build files (i.e. makefiles or "
"project files) and exit. "
"At any point during the process, you can exit ccmake with 'q'. However, "
- "this will not generate/change any build files.\n\n"
+ "this will not generate/change any build files. Additionally, you can exit "
+ "ccmake with 'w' to write changes to the cache file without generating or "
+ "changing the build files.\n\n"
"ccmake KEYS:\n\n"
"Navigation: "
"You can use the arrow keys and page up, down to navigate the options. "
- "Alternatively, you can use the following keys: \n"
+ "Additionally, you can use the following keys: \n"
" C-n or j : next option\n"
" C-p or k : previous options\n"
" C-d : down one page\n"
- " C-u : up one page\n\n"
+ " C-u : up one page\n"
+ " Home : jump to first option\n"
+ " End : jump to last option\n"
+ " n : next search result\n"
+ " N : previous search result\n\n"
"Editing options: "
"To change an option press enter or return. If the current options is a "
"boolean, this will toggle its value. "
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index 112b7e8..1ce75e7 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -87,6 +87,11 @@ public:
void AddError(const std::string& message, const char* title) override;
/**
+ * Write files to cache file without reconfiguring.
+ */
+ void Write();
+
+ /**
* Used to do a configure. If argument is specified, it does only the check
* and not configure.
*/
@@ -123,6 +128,7 @@ protected:
// Jump to the cache entry whose name matches the string.
void JumpToCacheEntry(const char* str);
+ void JumpToCacheEntry(const char* str, bool reverse);
// Clear and reset the output log and state
void ResetOutputs();
diff --git a/Source/LexerParser/cmCTestResourceGroupsLexer.cxx b/Source/LexerParser/cmCTestResourceGroupsLexer.cxx
index 85b379b..f1d351a 100644
--- a/Source/LexerParser/cmCTestResourceGroupsLexer.cxx
+++ b/Source/LexerParser/cmCTestResourceGroupsLexer.cxx
@@ -667,6 +667,10 @@ Modify cmCTestResourceGroupsLexer.cxx:
#include <cstddef>
+#ifndef _WIN32
+# include <termios.h>
+#endif
+
/*--------------------------------------------------------------------------*/
#define INITIAL 0
diff --git a/Source/LexerParser/cmCTestResourceGroupsLexer.in.l b/Source/LexerParser/cmCTestResourceGroupsLexer.in.l
index 2befa85..ac9cbaf 100644
--- a/Source/LexerParser/cmCTestResourceGroupsLexer.in.l
+++ b/Source/LexerParser/cmCTestResourceGroupsLexer.in.l
@@ -26,6 +26,10 @@ Modify cmCTestResourceGroupsLexer.cxx:
#include <cstddef>
+#ifndef _WIN32
+# include <termios.h>
+#endif
+
/*--------------------------------------------------------------------------*/
%}
diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx
index 4c49e0f..7ea0b15 100644
--- a/Source/LexerParser/cmCommandArgumentParser.cxx
+++ b/Source/LexerParser/cmCommandArgumentParser.cxx
@@ -97,7 +97,6 @@ Run bison like this:
# include <malloc.h>
#endif
-#include <stdint.h>
/* Make sure the parser uses standard memory allocation. The default
generated parser malloc/free declarations do not work on all
platforms. */
@@ -137,7 +136,7 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# endif
#endif
-#line 141 "cmCommandArgumentParser.cxx"
+#line 140 "cmCommandArgumentParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -576,9 +575,9 @@ static const yytype_int8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 102, 102, 108, 111, 116, 119, 124, 127, 132,
- 135, 138, 141, 144, 147, 152, 155, 158, 161, 166,
- 169, 174, 177, 182, 185
+ 0, 101, 101, 107, 110, 115, 118, 123, 126, 131,
+ 134, 137, 140, 143, 146, 151, 154, 157, 160, 165,
+ 168, 173, 176, 181, 184
};
#endif
@@ -1437,192 +1436,192 @@ yyreduce:
switch (yyn)
{
case 2: /* Start: GoalWithOptionalBackSlash */
-#line 102 "cmCommandArgumentParser.y"
+#line 101 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
yyGetParser->SetResult((yyvsp[0].str));
}
-#line 1446 "cmCommandArgumentParser.cxx"
+#line 1445 "cmCommandArgumentParser.cxx"
break;
case 3: /* GoalWithOptionalBackSlash: Goal */
-#line 108 "cmCommandArgumentParser.y"
+#line 107 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1454 "cmCommandArgumentParser.cxx"
+#line 1453 "cmCommandArgumentParser.cxx"
break;
case 4: /* GoalWithOptionalBackSlash: Goal "\\" */
-#line 111 "cmCommandArgumentParser.y"
+#line 110 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1462 "cmCommandArgumentParser.cxx"
+#line 1461 "cmCommandArgumentParser.cxx"
break;
case 5: /* Goal: %empty */
-#line 116 "cmCommandArgumentParser.y"
+#line 115 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1470 "cmCommandArgumentParser.cxx"
+#line 1469 "cmCommandArgumentParser.cxx"
break;
case 6: /* Goal: String Goal */
-#line 119 "cmCommandArgumentParser.y"
+#line 118 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1478 "cmCommandArgumentParser.cxx"
+#line 1477 "cmCommandArgumentParser.cxx"
break;
case 7: /* String: OuterText */
-#line 124 "cmCommandArgumentParser.y"
+#line 123 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1486 "cmCommandArgumentParser.cxx"
+#line 1485 "cmCommandArgumentParser.cxx"
break;
case 8: /* String: Variable */
-#line 127 "cmCommandArgumentParser.y"
+#line 126 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1494 "cmCommandArgumentParser.cxx"
+#line 1493 "cmCommandArgumentParser.cxx"
break;
case 9: /* OuterText: cal_NAME */
-#line 132 "cmCommandArgumentParser.y"
+#line 131 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1502 "cmCommandArgumentParser.cxx"
+#line 1501 "cmCommandArgumentParser.cxx"
break;
case 10: /* OuterText: "@" */
-#line 135 "cmCommandArgumentParser.y"
+#line 134 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1510 "cmCommandArgumentParser.cxx"
+#line 1509 "cmCommandArgumentParser.cxx"
break;
case 11: /* OuterText: "$" */
-#line 138 "cmCommandArgumentParser.y"
+#line 137 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1518 "cmCommandArgumentParser.cxx"
+#line 1517 "cmCommandArgumentParser.cxx"
break;
case 12: /* OuterText: "{" */
-#line 141 "cmCommandArgumentParser.y"
+#line 140 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1526 "cmCommandArgumentParser.cxx"
+#line 1525 "cmCommandArgumentParser.cxx"
break;
case 13: /* OuterText: "}" */
-#line 144 "cmCommandArgumentParser.y"
+#line 143 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1534 "cmCommandArgumentParser.cxx"
+#line 1533 "cmCommandArgumentParser.cxx"
break;
case 14: /* OuterText: cal_SYMBOL */
-#line 147 "cmCommandArgumentParser.y"
+#line 146 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1542 "cmCommandArgumentParser.cxx"
+#line 1541 "cmCommandArgumentParser.cxx"
break;
case 15: /* Variable: cal_ENVCURLY EnvVarName "}" */
-#line 152 "cmCommandArgumentParser.y"
+#line 151 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1550 "cmCommandArgumentParser.cxx"
+#line 1549 "cmCommandArgumentParser.cxx"
break;
case 16: /* Variable: cal_NCURLY MultipleIds "}" */
-#line 155 "cmCommandArgumentParser.y"
+#line 154 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1558 "cmCommandArgumentParser.cxx"
+#line 1557 "cmCommandArgumentParser.cxx"
break;
case 17: /* Variable: cal_DCURLY MultipleIds "}" */
-#line 158 "cmCommandArgumentParser.y"
+#line 157 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
}
-#line 1566 "cmCommandArgumentParser.cxx"
+#line 1565 "cmCommandArgumentParser.cxx"
break;
case 18: /* Variable: cal_ATNAME */
-#line 161 "cmCommandArgumentParser.y"
+#line 160 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
}
-#line 1574 "cmCommandArgumentParser.cxx"
+#line 1573 "cmCommandArgumentParser.cxx"
break;
case 19: /* EnvVarName: MultipleIds */
-#line 166 "cmCommandArgumentParser.y"
+#line 165 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1582 "cmCommandArgumentParser.cxx"
+#line 1581 "cmCommandArgumentParser.cxx"
break;
case 20: /* EnvVarName: cal_SYMBOL EnvVarName */
-#line 169 "cmCommandArgumentParser.y"
+#line 168 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[-1].str);
}
-#line 1590 "cmCommandArgumentParser.cxx"
+#line 1589 "cmCommandArgumentParser.cxx"
break;
case 21: /* MultipleIds: %empty */
-#line 174 "cmCommandArgumentParser.y"
+#line 173 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1598 "cmCommandArgumentParser.cxx"
+#line 1597 "cmCommandArgumentParser.cxx"
break;
case 22: /* MultipleIds: ID MultipleIds */
-#line 177 "cmCommandArgumentParser.y"
+#line 176 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1606 "cmCommandArgumentParser.cxx"
+#line 1605 "cmCommandArgumentParser.cxx"
break;
case 23: /* ID: cal_NAME */
-#line 182 "cmCommandArgumentParser.y"
+#line 181 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1614 "cmCommandArgumentParser.cxx"
+#line 1613 "cmCommandArgumentParser.cxx"
break;
case 24: /* ID: Variable */
-#line 185 "cmCommandArgumentParser.y"
+#line 184 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1622 "cmCommandArgumentParser.cxx"
+#line 1621 "cmCommandArgumentParser.cxx"
break;
-#line 1626 "cmCommandArgumentParser.cxx"
+#line 1625 "cmCommandArgumentParser.cxx"
default: break;
}
@@ -1846,7 +1845,7 @@ yyreturnlab:
return yyresult;
}
-#line 190 "cmCommandArgumentParser.y"
+#line 189 "cmCommandArgumentParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmCommandArgumentParser.y b/Source/LexerParser/cmCommandArgumentParser.y
index 602e1c3..59f4b32 100644
--- a/Source/LexerParser/cmCommandArgumentParser.y
+++ b/Source/LexerParser/cmCommandArgumentParser.y
@@ -22,7 +22,6 @@ Run bison like this:
# include <malloc.h>
#endif
-#include <stdint.h>
/* Make sure the parser uses standard memory allocation. The default
generated parser malloc/free declarations do not work on all
platforms. */
diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx
index 59cf1be..6755c70 100644
--- a/Source/LexerParser/cmDependsJavaParser.cxx
+++ b/Source/LexerParser/cmDependsJavaParser.cxx
@@ -88,7 +88,6 @@ Run bison like this:
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <string>
@@ -126,7 +125,7 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# endif
#endif
-#line 130 "cmDependsJavaParser.cxx"
+#line 129 "cmDependsJavaParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -814,42 +813,42 @@ static const yytype_int8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_int16 yyrline[] =
{
- 0, 185, 185, 194, 202, 210, 218, 226, 234, 243,
- 251, 260, 268, 277, 282, 287, 292, 297, 302, 307,
- 312, 318, 326, 335, 345, 354, 363, 371, 381, 387,
- 394, 401, 407, 414, 423, 433, 443, 452, 460, 469,
- 478, 484, 493, 499, 508, 514, 523, 535, 543, 552,
- 564, 577, 585, 593, 602, 610, 619, 619, 619, 620,
- 621, 621, 621, 621, 621, 621, 622, 625, 635, 644,
- 653, 662, 672, 678, 687, 696, 705, 713, 722, 731,
- 737, 746, 754, 762, 770, 779, 787, 796, 802, 810,
- 819, 827, 836, 845, 854, 862, 871, 879, 887, 896,
- 905, 915, 922, 932, 942, 949, 956, 959, 965, 975,
- 985, 995, 1001, 1011, 1021, 1031, 1040, 1050, 1061, 1071,
- 1078, 1088, 1097, 1107, 1116, 1126, 1132, 1142, 1151, 1161,
- 1171, 1178, 1187, 1196, 1205, 1214, 1222, 1231, 1240, 1250,
- 1260, 1269, 1279, 1289, 1296, 1305, 1315, 1324, 1334, 1343,
- 1350, 1360, 1369, 1379, 1388, 1397, 1407, 1417, 1426, 1436,
- 1445, 1454, 1463, 1472, 1481, 1491, 1500, 1509, 1518, 1527,
- 1537, 1546, 1555, 1564, 1573, 1582, 1591, 1600, 1609, 1618,
- 1627, 1636, 1646, 1656, 1667, 1677, 1687, 1696, 1705, 1714,
- 1723, 1732, 1741, 1751, 1761, 1771, 1781, 1788, 1795, 1802,
- 1812, 1819, 1829, 1839, 1848, 1858, 1867, 1877, 1884, 1891,
- 1898, 1906, 1913, 1923, 1930, 1940, 1950, 1957, 1967, 1976,
- 1986, 1996, 2005, 2015, 2024, 2034, 2045, 2052, 2059, 2070,
- 2080, 2090, 2100, 2109, 2119, 2126, 2136, 2145, 2155, 2162,
- 2172, 2181, 2191, 2200, 2206, 2215, 2224, 2233, 2242, 2252,
- 2262, 2269, 2279, 2286, 2296, 2305, 2315, 2324, 2333, 2342,
- 2352, 2359, 2369, 2378, 2388, 2398, 2404, 2411, 2421, 2431,
- 2441, 2452, 2462, 2473, 2483, 2494, 2504, 2514, 2523, 2532,
- 2541, 2550, 2560, 2570, 2580, 2589, 2598, 2607, 2616, 2626,
- 2636, 2646, 2655, 2664, 2673, 2683, 2692, 2701, 2708, 2717,
- 2726, 2735, 2745, 2754, 2763, 2773, 2782, 2791, 2800, 2810,
- 2819, 2828, 2837, 2846, 2855, 2865, 2874, 2883, 2893, 2902,
- 2912, 2921, 2931, 2940, 2950, 2959, 2969, 2978, 2988, 2997,
- 3007, 3016, 3026, 3036, 3046, 3055, 3065, 3074, 3083, 3092,
- 3101, 3110, 3119, 3128, 3137, 3146, 3155, 3164, 3174, 3184,
- 3194, 3203
+ 0, 184, 184, 193, 201, 209, 217, 225, 233, 242,
+ 250, 259, 267, 276, 281, 286, 291, 296, 301, 306,
+ 311, 317, 325, 334, 344, 353, 362, 370, 380, 386,
+ 393, 400, 406, 413, 422, 432, 442, 451, 459, 468,
+ 477, 483, 492, 498, 507, 513, 522, 534, 542, 551,
+ 563, 576, 584, 592, 601, 609, 618, 618, 618, 619,
+ 620, 620, 620, 620, 620, 620, 621, 624, 634, 643,
+ 652, 661, 671, 677, 686, 695, 704, 712, 721, 730,
+ 736, 745, 753, 761, 769, 778, 786, 795, 801, 809,
+ 818, 826, 835, 844, 853, 861, 870, 878, 886, 895,
+ 904, 914, 921, 931, 941, 948, 955, 958, 964, 974,
+ 984, 994, 1000, 1010, 1020, 1030, 1039, 1049, 1060, 1070,
+ 1077, 1087, 1096, 1106, 1115, 1125, 1131, 1141, 1150, 1160,
+ 1170, 1177, 1186, 1195, 1204, 1213, 1221, 1230, 1239, 1249,
+ 1259, 1268, 1278, 1288, 1295, 1304, 1314, 1323, 1333, 1342,
+ 1349, 1359, 1368, 1378, 1387, 1396, 1406, 1416, 1425, 1435,
+ 1444, 1453, 1462, 1471, 1480, 1490, 1499, 1508, 1517, 1526,
+ 1536, 1545, 1554, 1563, 1572, 1581, 1590, 1599, 1608, 1617,
+ 1626, 1635, 1645, 1655, 1666, 1676, 1686, 1695, 1704, 1713,
+ 1722, 1731, 1740, 1750, 1760, 1770, 1780, 1787, 1794, 1801,
+ 1811, 1818, 1828, 1838, 1847, 1857, 1866, 1876, 1883, 1890,
+ 1897, 1905, 1912, 1922, 1929, 1939, 1949, 1956, 1966, 1975,
+ 1985, 1995, 2004, 2014, 2023, 2033, 2044, 2051, 2058, 2069,
+ 2079, 2089, 2099, 2108, 2118, 2125, 2135, 2144, 2154, 2161,
+ 2171, 2180, 2190, 2199, 2205, 2214, 2223, 2232, 2241, 2251,
+ 2261, 2268, 2278, 2285, 2295, 2304, 2314, 2323, 2332, 2341,
+ 2351, 2358, 2368, 2377, 2387, 2397, 2403, 2410, 2420, 2430,
+ 2440, 2451, 2461, 2472, 2482, 2493, 2503, 2513, 2522, 2531,
+ 2540, 2549, 2559, 2569, 2579, 2588, 2597, 2606, 2615, 2625,
+ 2635, 2645, 2654, 2663, 2672, 2682, 2691, 2700, 2707, 2716,
+ 2725, 2734, 2744, 2753, 2762, 2772, 2781, 2790, 2799, 2809,
+ 2818, 2827, 2836, 2845, 2854, 2864, 2873, 2882, 2892, 2901,
+ 2911, 2920, 2930, 2939, 2949, 2958, 2968, 2977, 2987, 2996,
+ 3006, 3015, 3025, 3035, 3045, 3054, 3064, 3073, 3082, 3091,
+ 3100, 3109, 3118, 3127, 3136, 3145, 3154, 3163, 3173, 3183,
+ 3193, 3202
};
#endif
@@ -2470,214 +2469,214 @@ yyreduce:
switch (yyn)
{
case 2: /* Goal: CompilationUnit */
-#line 186 "cmDependsJavaParser.y"
+#line 185 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2481 "cmDependsJavaParser.cxx"
+#line 2480 "cmDependsJavaParser.cxx"
break;
case 3: /* Literal: IntegerLiteral */
-#line 195 "cmDependsJavaParser.y"
+#line 194 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2492 "cmDependsJavaParser.cxx"
+#line 2491 "cmDependsJavaParser.cxx"
break;
case 4: /* Literal: jp_FLOATINGPOINTLITERAL */
-#line 203 "cmDependsJavaParser.y"
+#line 202 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2503 "cmDependsJavaParser.cxx"
+#line 2502 "cmDependsJavaParser.cxx"
break;
case 5: /* Literal: jp_BOOLEANLITERAL */
-#line 211 "cmDependsJavaParser.y"
+#line 210 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2514 "cmDependsJavaParser.cxx"
+#line 2513 "cmDependsJavaParser.cxx"
break;
case 6: /* Literal: jp_CHARACTERLITERAL */
-#line 219 "cmDependsJavaParser.y"
+#line 218 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2525 "cmDependsJavaParser.cxx"
+#line 2524 "cmDependsJavaParser.cxx"
break;
case 7: /* Literal: jp_STRINGLITERAL */
-#line 227 "cmDependsJavaParser.y"
+#line 226 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2536 "cmDependsJavaParser.cxx"
+#line 2535 "cmDependsJavaParser.cxx"
break;
case 8: /* Literal: jp_NULLLITERAL */
-#line 235 "cmDependsJavaParser.y"
+#line 234 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2547 "cmDependsJavaParser.cxx"
+#line 2546 "cmDependsJavaParser.cxx"
break;
case 9: /* IntegerLiteral: jp_DECIMALINTEGERLITERAL */
-#line 244 "cmDependsJavaParser.y"
+#line 243 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2558 "cmDependsJavaParser.cxx"
+#line 2557 "cmDependsJavaParser.cxx"
break;
case 10: /* IntegerLiteral: jp_HEXINTEGERLITERAL */
-#line 252 "cmDependsJavaParser.y"
+#line 251 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2569 "cmDependsJavaParser.cxx"
+#line 2568 "cmDependsJavaParser.cxx"
break;
case 11: /* Type: PrimitiveType */
-#line 261 "cmDependsJavaParser.y"
+#line 260 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2580 "cmDependsJavaParser.cxx"
+#line 2579 "cmDependsJavaParser.cxx"
break;
case 12: /* Type: ReferenceType */
-#line 269 "cmDependsJavaParser.y"
+#line 268 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2591 "cmDependsJavaParser.cxx"
+#line 2590 "cmDependsJavaParser.cxx"
break;
case 13: /* PrimitiveType: jp_BYTE_TYPE */
-#line 278 "cmDependsJavaParser.y"
+#line 277 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2599 "cmDependsJavaParser.cxx"
+#line 2598 "cmDependsJavaParser.cxx"
break;
case 14: /* PrimitiveType: jp_SHORT_TYPE */
-#line 283 "cmDependsJavaParser.y"
+#line 282 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2607 "cmDependsJavaParser.cxx"
+#line 2606 "cmDependsJavaParser.cxx"
break;
case 15: /* PrimitiveType: jp_INT_TYPE */
-#line 288 "cmDependsJavaParser.y"
+#line 287 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2615 "cmDependsJavaParser.cxx"
+#line 2614 "cmDependsJavaParser.cxx"
break;
case 16: /* PrimitiveType: jp_LONG_TYPE */
-#line 293 "cmDependsJavaParser.y"
+#line 292 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2623 "cmDependsJavaParser.cxx"
+#line 2622 "cmDependsJavaParser.cxx"
break;
case 17: /* PrimitiveType: jp_CHAR_TYPE */
-#line 298 "cmDependsJavaParser.y"
+#line 297 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2631 "cmDependsJavaParser.cxx"
+#line 2630 "cmDependsJavaParser.cxx"
break;
case 18: /* PrimitiveType: jp_FLOAT_TYPE */
-#line 303 "cmDependsJavaParser.y"
+#line 302 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2639 "cmDependsJavaParser.cxx"
+#line 2638 "cmDependsJavaParser.cxx"
break;
case 19: /* PrimitiveType: jp_DOUBLE_TYPE */
-#line 308 "cmDependsJavaParser.y"
+#line 307 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2647 "cmDependsJavaParser.cxx"
+#line 2646 "cmDependsJavaParser.cxx"
break;
case 20: /* PrimitiveType: jp_BOOLEAN_TYPE */
-#line 313 "cmDependsJavaParser.y"
+#line 312 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2655 "cmDependsJavaParser.cxx"
+#line 2654 "cmDependsJavaParser.cxx"
break;
case 21: /* ReferenceType: ClassOrInterfaceType */
-#line 319 "cmDependsJavaParser.y"
+#line 318 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2666 "cmDependsJavaParser.cxx"
+#line 2665 "cmDependsJavaParser.cxx"
break;
case 22: /* ReferenceType: ArrayType */
-#line 327 "cmDependsJavaParser.y"
+#line 326 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2677 "cmDependsJavaParser.cxx"
+#line 2676 "cmDependsJavaParser.cxx"
break;
case 23: /* ClassOrInterfaceType: Name */
-#line 336 "cmDependsJavaParser.y"
+#line 335 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpStoreClass((yyvsp[0].str));
@@ -2685,44 +2684,44 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2689 "cmDependsJavaParser.cxx"
+#line 2688 "cmDependsJavaParser.cxx"
break;
case 24: /* ClassType: ClassOrInterfaceType */
-#line 346 "cmDependsJavaParser.y"
+#line 345 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2700 "cmDependsJavaParser.cxx"
+#line 2699 "cmDependsJavaParser.cxx"
break;
case 25: /* InterfaceType: ClassOrInterfaceType */
-#line 355 "cmDependsJavaParser.y"
+#line 354 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2711 "cmDependsJavaParser.cxx"
+#line 2710 "cmDependsJavaParser.cxx"
break;
case 26: /* ArrayType: PrimitiveType Dims */
-#line 364 "cmDependsJavaParser.y"
+#line 363 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2722 "cmDependsJavaParser.cxx"
+#line 2721 "cmDependsJavaParser.cxx"
break;
case 27: /* ArrayType: Name Dims */
-#line 372 "cmDependsJavaParser.y"
+#line 371 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpStoreClass((yyvsp[-1].str));
@@ -2730,56 +2729,56 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2734 "cmDependsJavaParser.cxx"
+#line 2733 "cmDependsJavaParser.cxx"
break;
case 28: /* Name: SimpleName */
-#line 382 "cmDependsJavaParser.y"
+#line 381 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2743 "cmDependsJavaParser.cxx"
+#line 2742 "cmDependsJavaParser.cxx"
break;
case 29: /* Name: QualifiedName */
-#line 388 "cmDependsJavaParser.y"
+#line 387 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2752 "cmDependsJavaParser.cxx"
+#line 2751 "cmDependsJavaParser.cxx"
break;
case 30: /* SimpleName: Identifier */
-#line 395 "cmDependsJavaParser.y"
+#line 394 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2761 "cmDependsJavaParser.cxx"
+#line 2760 "cmDependsJavaParser.cxx"
break;
case 31: /* Identifier: jp_NAME */
-#line 402 "cmDependsJavaParser.y"
+#line 401 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2770 "cmDependsJavaParser.cxx"
+#line 2769 "cmDependsJavaParser.cxx"
break;
case 32: /* Identifier: jp_DOLLAR jp_NAME */
-#line 408 "cmDependsJavaParser.y"
+#line 407 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = (yyvsp[0].str);
}
-#line 2779 "cmDependsJavaParser.cxx"
+#line 2778 "cmDependsJavaParser.cxx"
break;
case 33: /* QualifiedName: Name jp_DOT Identifier */
-#line 415 "cmDependsJavaParser.y"
+#line 414 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddClassFound((yyvsp[-2].str));
@@ -2787,11 +2786,11 @@ yyreduce:
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
(yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine());
}
-#line 2791 "cmDependsJavaParser.cxx"
+#line 2790 "cmDependsJavaParser.cxx"
break;
case 34: /* QualifiedName: Name jp_DOT jp_CLASS */
-#line 424 "cmDependsJavaParser.y"
+#line 423 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2800,11 +2799,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2804 "cmDependsJavaParser.cxx"
+#line 2803 "cmDependsJavaParser.cxx"
break;
case 35: /* QualifiedName: Name jp_DOT jp_THIS */
-#line 434 "cmDependsJavaParser.y"
+#line 433 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2813,118 +2812,118 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2817 "cmDependsJavaParser.cxx"
+#line 2816 "cmDependsJavaParser.cxx"
break;
case 36: /* QualifiedName: SimpleType jp_DOT jp_CLASS */
-#line 444 "cmDependsJavaParser.y"
+#line 443 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2828 "cmDependsJavaParser.cxx"
+#line 2827 "cmDependsJavaParser.cxx"
break;
case 37: /* SimpleType: PrimitiveType */
-#line 453 "cmDependsJavaParser.y"
+#line 452 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2839 "cmDependsJavaParser.cxx"
+#line 2838 "cmDependsJavaParser.cxx"
break;
case 38: /* SimpleType: jp_VOID */
-#line 461 "cmDependsJavaParser.y"
+#line 460 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2850 "cmDependsJavaParser.cxx"
+#line 2849 "cmDependsJavaParser.cxx"
break;
case 39: /* CompilationUnit: PackageDeclarationopt ImportDeclarations TypeDeclarations */
-#line 470 "cmDependsJavaParser.y"
+#line 469 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2861 "cmDependsJavaParser.cxx"
+#line 2860 "cmDependsJavaParser.cxx"
break;
case 40: /* PackageDeclarationopt: %empty */
-#line 478 "cmDependsJavaParser.y"
+#line 477 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2871 "cmDependsJavaParser.cxx"
+#line 2870 "cmDependsJavaParser.cxx"
break;
case 41: /* PackageDeclarationopt: PackageDeclaration */
-#line 485 "cmDependsJavaParser.y"
+#line 484 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2882 "cmDependsJavaParser.cxx"
+#line 2881 "cmDependsJavaParser.cxx"
break;
case 42: /* ImportDeclarations: %empty */
-#line 493 "cmDependsJavaParser.y"
+#line 492 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2892 "cmDependsJavaParser.cxx"
+#line 2891 "cmDependsJavaParser.cxx"
break;
case 43: /* ImportDeclarations: ImportDeclarations ImportDeclaration */
-#line 500 "cmDependsJavaParser.y"
+#line 499 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2903 "cmDependsJavaParser.cxx"
+#line 2902 "cmDependsJavaParser.cxx"
break;
case 44: /* TypeDeclarations: %empty */
-#line 508 "cmDependsJavaParser.y"
+#line 507 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2913 "cmDependsJavaParser.cxx"
+#line 2912 "cmDependsJavaParser.cxx"
break;
case 45: /* TypeDeclarations: TypeDeclarations TypeDeclaration */
-#line 515 "cmDependsJavaParser.y"
+#line 514 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2924 "cmDependsJavaParser.cxx"
+#line 2923 "cmDependsJavaParser.cxx"
break;
case 46: /* PackageDeclaration: jp_PACKAGE Name jp_SEMICOL */
-#line 524 "cmDependsJavaParser.y"
+#line 523 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->SetCurrentPackage((yyvsp[-1].str));
@@ -2934,33 +2933,33 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2938 "cmDependsJavaParser.cxx"
+#line 2937 "cmDependsJavaParser.cxx"
break;
case 47: /* ImportDeclaration: SingleTypeImportDeclaration */
-#line 536 "cmDependsJavaParser.y"
+#line 535 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2949 "cmDependsJavaParser.cxx"
+#line 2948 "cmDependsJavaParser.cxx"
break;
case 48: /* ImportDeclaration: TypeImportOnDemandDeclaration */
-#line 544 "cmDependsJavaParser.y"
+#line 543 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2960 "cmDependsJavaParser.cxx"
+#line 2959 "cmDependsJavaParser.cxx"
break;
case 49: /* SingleTypeImportDeclaration: jp_IMPORT Name jp_SEMICOL */
-#line 553 "cmDependsJavaParser.y"
+#line 552 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddPackagesImport((yyvsp[-1].str));
@@ -2970,11 +2969,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2974 "cmDependsJavaParser.cxx"
+#line 2973 "cmDependsJavaParser.cxx"
break;
case 50: /* TypeImportOnDemandDeclaration: jp_IMPORT Name jp_DOT jp_TIMES jp_SEMICOL */
-#line 565 "cmDependsJavaParser.y"
+#line 564 "cmDependsJavaParser.y"
{
jpElementStart(5);
std::string str = (yyvsp[-3].str);
@@ -2985,77 +2984,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2989 "cmDependsJavaParser.cxx"
+#line 2988 "cmDependsJavaParser.cxx"
break;
case 51: /* TypeDeclaration: ClassDeclaration */
-#line 578 "cmDependsJavaParser.y"
+#line 577 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3000 "cmDependsJavaParser.cxx"
+#line 2999 "cmDependsJavaParser.cxx"
break;
case 52: /* TypeDeclaration: InterfaceDeclaration */
-#line 586 "cmDependsJavaParser.y"
+#line 585 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3011 "cmDependsJavaParser.cxx"
+#line 3010 "cmDependsJavaParser.cxx"
break;
case 53: /* TypeDeclaration: jp_SEMICOL */
-#line 594 "cmDependsJavaParser.y"
+#line 593 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3022 "cmDependsJavaParser.cxx"
+#line 3021 "cmDependsJavaParser.cxx"
break;
case 54: /* Modifiers: Modifier */
-#line 603 "cmDependsJavaParser.y"
+#line 602 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3033 "cmDependsJavaParser.cxx"
+#line 3032 "cmDependsJavaParser.cxx"
break;
case 55: /* Modifiers: Modifiers Modifier */
-#line 611 "cmDependsJavaParser.y"
+#line 610 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3044 "cmDependsJavaParser.cxx"
+#line 3043 "cmDependsJavaParser.cxx"
break;
case 67: /* ClassHeader: Modifiersopt jp_CLASS Identifier */
-#line 626 "cmDependsJavaParser.y"
+#line 625 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3055 "cmDependsJavaParser.cxx"
+#line 3054 "cmDependsJavaParser.cxx"
break;
case 68: /* ClassDeclaration: ClassHeader ClassBody */
-#line 636 "cmDependsJavaParser.y"
+#line 635 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3063,11 +3062,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3067 "cmDependsJavaParser.cxx"
+#line 3066 "cmDependsJavaParser.cxx"
break;
case 69: /* ClassDeclaration: ClassHeader Interfaces ClassBody */
-#line 645 "cmDependsJavaParser.y"
+#line 644 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(2);
@@ -3075,11 +3074,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3079 "cmDependsJavaParser.cxx"
+#line 3078 "cmDependsJavaParser.cxx"
break;
case 70: /* ClassDeclaration: ClassHeader Super ClassBody */
-#line 654 "cmDependsJavaParser.y"
+#line 653 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3087,11 +3086,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3091 "cmDependsJavaParser.cxx"
+#line 3090 "cmDependsJavaParser.cxx"
break;
case 71: /* ClassDeclaration: ClassHeader Super Interfaces ClassBody */
-#line 663 "cmDependsJavaParser.y"
+#line 662 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3099,226 +3098,226 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3103 "cmDependsJavaParser.cxx"
+#line 3102 "cmDependsJavaParser.cxx"
break;
case 72: /* Modifiersopt: %empty */
-#line 672 "cmDependsJavaParser.y"
+#line 671 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3113 "cmDependsJavaParser.cxx"
+#line 3112 "cmDependsJavaParser.cxx"
break;
case 73: /* Modifiersopt: Modifiers */
-#line 679 "cmDependsJavaParser.y"
+#line 678 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3124 "cmDependsJavaParser.cxx"
+#line 3123 "cmDependsJavaParser.cxx"
break;
case 74: /* Super: jp_EXTENDS ClassType */
-#line 688 "cmDependsJavaParser.y"
+#line 687 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3135 "cmDependsJavaParser.cxx"
+#line 3134 "cmDependsJavaParser.cxx"
break;
case 75: /* Interfaces: jp_IMPLEMENTS InterfaceTypeList */
-#line 697 "cmDependsJavaParser.y"
+#line 696 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3146 "cmDependsJavaParser.cxx"
+#line 3145 "cmDependsJavaParser.cxx"
break;
case 76: /* InterfaceTypeList: InterfaceType */
-#line 706 "cmDependsJavaParser.y"
+#line 705 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3157 "cmDependsJavaParser.cxx"
+#line 3156 "cmDependsJavaParser.cxx"
break;
case 77: /* InterfaceTypeList: InterfaceTypeList jp_COMMA InterfaceType */
-#line 714 "cmDependsJavaParser.y"
+#line 713 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3168 "cmDependsJavaParser.cxx"
+#line 3167 "cmDependsJavaParser.cxx"
break;
case 78: /* ClassBody: jp_CURLYSTART ClassBodyDeclarations jp_CURLYEND */
-#line 723 "cmDependsJavaParser.y"
+#line 722 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3179 "cmDependsJavaParser.cxx"
+#line 3178 "cmDependsJavaParser.cxx"
break;
case 79: /* ClassBodyDeclarations: %empty */
-#line 731 "cmDependsJavaParser.y"
+#line 730 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3189 "cmDependsJavaParser.cxx"
+#line 3188 "cmDependsJavaParser.cxx"
break;
case 80: /* ClassBodyDeclarations: ClassBodyDeclarations ClassBodyDeclaration */
-#line 738 "cmDependsJavaParser.y"
+#line 737 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3200 "cmDependsJavaParser.cxx"
+#line 3199 "cmDependsJavaParser.cxx"
break;
case 81: /* ClassBodyDeclaration: ClassMemberDeclaration */
-#line 747 "cmDependsJavaParser.y"
+#line 746 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3211 "cmDependsJavaParser.cxx"
+#line 3210 "cmDependsJavaParser.cxx"
break;
case 82: /* ClassBodyDeclaration: StaticInitializer */
-#line 755 "cmDependsJavaParser.y"
+#line 754 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3222 "cmDependsJavaParser.cxx"
+#line 3221 "cmDependsJavaParser.cxx"
break;
case 83: /* ClassBodyDeclaration: ConstructorDeclaration */
-#line 763 "cmDependsJavaParser.y"
+#line 762 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3233 "cmDependsJavaParser.cxx"
+#line 3232 "cmDependsJavaParser.cxx"
break;
case 84: /* ClassBodyDeclaration: TypeDeclaration */
-#line 771 "cmDependsJavaParser.y"
+#line 770 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3244 "cmDependsJavaParser.cxx"
+#line 3243 "cmDependsJavaParser.cxx"
break;
case 85: /* ClassMemberDeclaration: FieldDeclaration */
-#line 780 "cmDependsJavaParser.y"
+#line 779 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3255 "cmDependsJavaParser.cxx"
+#line 3254 "cmDependsJavaParser.cxx"
break;
case 86: /* ClassMemberDeclaration: MethodDeclaration */
-#line 788 "cmDependsJavaParser.y"
+#line 787 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3266 "cmDependsJavaParser.cxx"
+#line 3265 "cmDependsJavaParser.cxx"
break;
case 87: /* FieldDeclaration: Modifiersopt Type VariableDeclarators jp_SEMICOL */
-#line 797 "cmDependsJavaParser.y"
+#line 796 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 3274 "cmDependsJavaParser.cxx"
+#line 3273 "cmDependsJavaParser.cxx"
break;
case 88: /* VariableDeclarators: VariableDeclarator */
-#line 803 "cmDependsJavaParser.y"
+#line 802 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3285 "cmDependsJavaParser.cxx"
+#line 3284 "cmDependsJavaParser.cxx"
break;
case 89: /* VariableDeclarators: VariableDeclarators jp_COMMA VariableDeclarator */
-#line 811 "cmDependsJavaParser.y"
+#line 810 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3296 "cmDependsJavaParser.cxx"
+#line 3295 "cmDependsJavaParser.cxx"
break;
case 90: /* VariableDeclarator: VariableDeclaratorId */
-#line 820 "cmDependsJavaParser.y"
+#line 819 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3307 "cmDependsJavaParser.cxx"
+#line 3306 "cmDependsJavaParser.cxx"
break;
case 91: /* VariableDeclarator: VariableDeclaratorId jp_EQUALS VariableInitializer */
-#line 828 "cmDependsJavaParser.y"
+#line 827 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3318 "cmDependsJavaParser.cxx"
+#line 3317 "cmDependsJavaParser.cxx"
break;
case 92: /* VariableDeclaratorId: Identifier */
-#line 837 "cmDependsJavaParser.y"
+#line 836 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -3326,77 +3325,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3330 "cmDependsJavaParser.cxx"
+#line 3329 "cmDependsJavaParser.cxx"
break;
case 93: /* VariableDeclaratorId: VariableDeclaratorId jp_BRACKETSTART jp_BRACKETEND */
-#line 846 "cmDependsJavaParser.y"
+#line 845 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3341 "cmDependsJavaParser.cxx"
+#line 3340 "cmDependsJavaParser.cxx"
break;
case 94: /* VariableInitializer: Expression */
-#line 855 "cmDependsJavaParser.y"
+#line 854 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3352 "cmDependsJavaParser.cxx"
+#line 3351 "cmDependsJavaParser.cxx"
break;
case 95: /* VariableInitializer: ArrayInitializer */
-#line 863 "cmDependsJavaParser.y"
+#line 862 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3363 "cmDependsJavaParser.cxx"
+#line 3362 "cmDependsJavaParser.cxx"
break;
case 96: /* MethodDeclaration: MethodHeader jp_SEMICOL */
-#line 872 "cmDependsJavaParser.y"
+#line 871 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3374 "cmDependsJavaParser.cxx"
+#line 3373 "cmDependsJavaParser.cxx"
break;
case 97: /* MethodDeclaration: MethodHeader MethodBody */
-#line 880 "cmDependsJavaParser.y"
+#line 879 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3385 "cmDependsJavaParser.cxx"
+#line 3384 "cmDependsJavaParser.cxx"
break;
case 98: /* MethodDeclaration: MethodHeader MethodBody jp_SEMICOL */
-#line 888 "cmDependsJavaParser.y"
+#line 887 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3396 "cmDependsJavaParser.cxx"
+#line 3395 "cmDependsJavaParser.cxx"
break;
case 99: /* MethodHeader: Modifiersopt Type MethodDeclarator Throwsopt */
-#line 897 "cmDependsJavaParser.y"
+#line 896 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3404,11 +3403,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3408 "cmDependsJavaParser.cxx"
+#line 3407 "cmDependsJavaParser.cxx"
break;
case 100: /* MethodHeader: Modifiersopt jp_VOID MethodDeclarator Throwsopt */
-#line 906 "cmDependsJavaParser.y"
+#line 905 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3416,22 +3415,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3420 "cmDependsJavaParser.cxx"
+#line 3419 "cmDependsJavaParser.cxx"
break;
case 101: /* Throwsopt: %empty */
-#line 915 "cmDependsJavaParser.y"
+#line 914 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3431 "cmDependsJavaParser.cxx"
+#line 3430 "cmDependsJavaParser.cxx"
break;
case 102: /* Throwsopt: Throws */
-#line 923 "cmDependsJavaParser.y"
+#line 922 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3439,11 +3438,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3443 "cmDependsJavaParser.cxx"
+#line 3442 "cmDependsJavaParser.cxx"
break;
case 103: /* MethodDeclarator: Identifier jp_PARESTART FormalParameterListopt jp_PAREEND */
-#line 933 "cmDependsJavaParser.y"
+#line 932 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3452,40 +3451,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3456 "cmDependsJavaParser.cxx"
+#line 3455 "cmDependsJavaParser.cxx"
break;
case 104: /* MethodDeclarator: MethodDeclarator jp_BRACKETSTART jp_BRACKETEND */
-#line 943 "cmDependsJavaParser.y"
+#line 942 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 3465 "cmDependsJavaParser.cxx"
+#line 3464 "cmDependsJavaParser.cxx"
break;
case 105: /* FormalParameterListopt: %empty */
-#line 949 "cmDependsJavaParser.y"
+#line 948 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3476 "cmDependsJavaParser.cxx"
+#line 3475 "cmDependsJavaParser.cxx"
break;
case 107: /* FormalParameterList: FormalParameter */
-#line 960 "cmDependsJavaParser.y"
+#line 959 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3485 "cmDependsJavaParser.cxx"
+#line 3484 "cmDependsJavaParser.cxx"
break;
case 108: /* FormalParameterList: FormalParameterList jp_COMMA FormalParameter */
-#line 966 "cmDependsJavaParser.y"
+#line 965 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3493,11 +3492,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3497 "cmDependsJavaParser.cxx"
+#line 3496 "cmDependsJavaParser.cxx"
break;
case 109: /* FormalParameter: Modifiersopt Type VariableDeclaratorId */
-#line 976 "cmDependsJavaParser.y"
+#line 975 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3505,11 +3504,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3509 "cmDependsJavaParser.cxx"
+#line 3508 "cmDependsJavaParser.cxx"
break;
case 110: /* Throws: jp_THROWS ClassTypeList */
-#line 986 "cmDependsJavaParser.y"
+#line 985 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3517,20 +3516,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3521 "cmDependsJavaParser.cxx"
+#line 3520 "cmDependsJavaParser.cxx"
break;
case 111: /* ClassTypeList: ClassType */
-#line 996 "cmDependsJavaParser.y"
+#line 995 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3530 "cmDependsJavaParser.cxx"
+#line 3529 "cmDependsJavaParser.cxx"
break;
case 112: /* ClassTypeList: ClassTypeList jp_COMMA ClassType */
-#line 1002 "cmDependsJavaParser.y"
+#line 1001 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3538,11 +3537,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3542 "cmDependsJavaParser.cxx"
+#line 3541 "cmDependsJavaParser.cxx"
break;
case 113: /* MethodBody: Block */
-#line 1012 "cmDependsJavaParser.y"
+#line 1011 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3550,11 +3549,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3554 "cmDependsJavaParser.cxx"
+#line 3553 "cmDependsJavaParser.cxx"
break;
case 114: /* StaticInitializer: jp_STATIC Block */
-#line 1022 "cmDependsJavaParser.y"
+#line 1021 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3562,11 +3561,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3566 "cmDependsJavaParser.cxx"
+#line 3565 "cmDependsJavaParser.cxx"
break;
case 115: /* ConstructorDeclaration: Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody */
-#line 1032 "cmDependsJavaParser.y"
+#line 1031 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3574,11 +3573,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3578 "cmDependsJavaParser.cxx"
+#line 3577 "cmDependsJavaParser.cxx"
break;
case 116: /* ConstructorDeclaration: Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody jp_SEMICOL */
-#line 1041 "cmDependsJavaParser.y"
+#line 1040 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3586,11 +3585,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3590 "cmDependsJavaParser.cxx"
+#line 3589 "cmDependsJavaParser.cxx"
break;
case 117: /* ConstructorDeclarator: SimpleName jp_PARESTART FormalParameterListopt jp_PAREEND */
-#line 1051 "cmDependsJavaParser.y"
+#line 1050 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3599,11 +3598,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3603 "cmDependsJavaParser.cxx"
+#line 3602 "cmDependsJavaParser.cxx"
break;
case 118: /* ConstructorBody: jp_CURLYSTART ExplicitConstructorInvocationopt BlockStatementsopt jp_CURLYEND */
-#line 1062 "cmDependsJavaParser.y"
+#line 1061 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3611,22 +3610,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3615 "cmDependsJavaParser.cxx"
+#line 3614 "cmDependsJavaParser.cxx"
break;
case 119: /* ExplicitConstructorInvocationopt: %empty */
-#line 1071 "cmDependsJavaParser.y"
+#line 1070 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3626 "cmDependsJavaParser.cxx"
+#line 3625 "cmDependsJavaParser.cxx"
break;
case 120: /* ExplicitConstructorInvocationopt: ExplicitConstructorInvocationopt ExplicitConstructorInvocation */
-#line 1079 "cmDependsJavaParser.y"
+#line 1078 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3634,11 +3633,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3638 "cmDependsJavaParser.cxx"
+#line 3637 "cmDependsJavaParser.cxx"
break;
case 121: /* ExplicitConstructorInvocation: jp_THIS jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL */
-#line 1089 "cmDependsJavaParser.y"
+#line 1088 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3646,11 +3645,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3650 "cmDependsJavaParser.cxx"
+#line 3649 "cmDependsJavaParser.cxx"
break;
case 122: /* ExplicitConstructorInvocation: jp_SUPER jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL */
-#line 1098 "cmDependsJavaParser.y"
+#line 1097 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3658,22 +3657,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3662 "cmDependsJavaParser.cxx"
+#line 3661 "cmDependsJavaParser.cxx"
break;
case 123: /* InterfaceHeader: Modifiersopt jp_INTERFACE Identifier */
-#line 1108 "cmDependsJavaParser.y"
+#line 1107 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3673 "cmDependsJavaParser.cxx"
+#line 3672 "cmDependsJavaParser.cxx"
break;
case 124: /* InterfaceDeclaration: InterfaceHeader ExtendsInterfacesopt InterfaceBody */
-#line 1117 "cmDependsJavaParser.y"
+#line 1116 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3681,21 +3680,21 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3685 "cmDependsJavaParser.cxx"
+#line 3684 "cmDependsJavaParser.cxx"
break;
case 125: /* ExtendsInterfacesopt: %empty */
-#line 1126 "cmDependsJavaParser.y"
+#line 1125 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3695 "cmDependsJavaParser.cxx"
+#line 3694 "cmDependsJavaParser.cxx"
break;
case 126: /* ExtendsInterfacesopt: ExtendsInterfaces */
-#line 1133 "cmDependsJavaParser.y"
+#line 1132 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3703,11 +3702,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3707 "cmDependsJavaParser.cxx"
+#line 3706 "cmDependsJavaParser.cxx"
break;
case 127: /* ExtendsInterfaces: jp_EXTENDS InterfaceType */
-#line 1143 "cmDependsJavaParser.y"
+#line 1142 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3715,11 +3714,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3719 "cmDependsJavaParser.cxx"
+#line 3718 "cmDependsJavaParser.cxx"
break;
case 128: /* ExtendsInterfaces: ExtendsInterfaces jp_COMMA InterfaceType */
-#line 1152 "cmDependsJavaParser.y"
+#line 1151 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3727,11 +3726,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3731 "cmDependsJavaParser.cxx"
+#line 3730 "cmDependsJavaParser.cxx"
break;
case 129: /* InterfaceBody: jp_CURLYSTART InterfaceMemberDeclarations jp_CURLYEND */
-#line 1162 "cmDependsJavaParser.y"
+#line 1161 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3739,33 +3738,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3743 "cmDependsJavaParser.cxx"
+#line 3742 "cmDependsJavaParser.cxx"
break;
case 130: /* InterfaceMemberDeclarations: %empty */
-#line 1171 "cmDependsJavaParser.y"
+#line 1170 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3754 "cmDependsJavaParser.cxx"
+#line 3753 "cmDependsJavaParser.cxx"
break;
case 131: /* InterfaceMemberDeclarations: InterfaceMemberDeclarations InterfaceMemberDeclaration */
-#line 1179 "cmDependsJavaParser.y"
+#line 1178 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3765 "cmDependsJavaParser.cxx"
+#line 3764 "cmDependsJavaParser.cxx"
break;
case 132: /* InterfaceMemberDeclaration: ConstantDeclaration */
-#line 1188 "cmDependsJavaParser.y"
+#line 1187 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3773,11 +3772,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3777 "cmDependsJavaParser.cxx"
+#line 3776 "cmDependsJavaParser.cxx"
break;
case 133: /* InterfaceMemberDeclaration: AbstractMethodDeclaration */
-#line 1197 "cmDependsJavaParser.y"
+#line 1196 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3785,11 +3784,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3789 "cmDependsJavaParser.cxx"
+#line 3788 "cmDependsJavaParser.cxx"
break;
case 134: /* InterfaceMemberDeclaration: ClassDeclaration */
-#line 1206 "cmDependsJavaParser.y"
+#line 1205 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3797,22 +3796,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3801 "cmDependsJavaParser.cxx"
+#line 3800 "cmDependsJavaParser.cxx"
break;
case 135: /* InterfaceMemberDeclaration: ClassDeclaration jp_SEMICOL */
-#line 1215 "cmDependsJavaParser.y"
+#line 1214 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3812 "cmDependsJavaParser.cxx"
+#line 3811 "cmDependsJavaParser.cxx"
break;
case 136: /* InterfaceMemberDeclaration: InterfaceDeclaration */
-#line 1223 "cmDependsJavaParser.y"
+#line 1222 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3820,22 +3819,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3824 "cmDependsJavaParser.cxx"
+#line 3823 "cmDependsJavaParser.cxx"
break;
case 137: /* InterfaceMemberDeclaration: InterfaceDeclaration jp_SEMICOL */
-#line 1232 "cmDependsJavaParser.y"
+#line 1231 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3835 "cmDependsJavaParser.cxx"
+#line 3834 "cmDependsJavaParser.cxx"
break;
case 138: /* ConstantDeclaration: FieldDeclaration */
-#line 1241 "cmDependsJavaParser.y"
+#line 1240 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3843,11 +3842,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3847 "cmDependsJavaParser.cxx"
+#line 3846 "cmDependsJavaParser.cxx"
break;
case 139: /* AbstractMethodDeclaration: MethodHeader Semicols */
-#line 1251 "cmDependsJavaParser.y"
+#line 1250 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3855,11 +3854,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3859 "cmDependsJavaParser.cxx"
+#line 3858 "cmDependsJavaParser.cxx"
break;
case 140: /* Semicols: jp_SEMICOL */
-#line 1261 "cmDependsJavaParser.y"
+#line 1260 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3867,11 +3866,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3871 "cmDependsJavaParser.cxx"
+#line 3870 "cmDependsJavaParser.cxx"
break;
case 141: /* Semicols: Semicols jp_SEMICOL */
-#line 1270 "cmDependsJavaParser.y"
+#line 1269 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3879,11 +3878,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3883 "cmDependsJavaParser.cxx"
+#line 3882 "cmDependsJavaParser.cxx"
break;
case 142: /* ArrayInitializer: jp_CURLYSTART VariableInitializersOptional jp_CURLYEND */
-#line 1280 "cmDependsJavaParser.y"
+#line 1279 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3891,22 +3890,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3895 "cmDependsJavaParser.cxx"
+#line 3894 "cmDependsJavaParser.cxx"
break;
case 143: /* VariableInitializersOptional: %empty */
-#line 1289 "cmDependsJavaParser.y"
+#line 1288 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3906 "cmDependsJavaParser.cxx"
+#line 3905 "cmDependsJavaParser.cxx"
break;
case 144: /* VariableInitializersOptional: VariableInitializers */
-#line 1297 "cmDependsJavaParser.y"
+#line 1296 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3914,11 +3913,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3918 "cmDependsJavaParser.cxx"
+#line 3917 "cmDependsJavaParser.cxx"
break;
case 145: /* VariableInitializersOptional: VariableInitializers jp_COMMA */
-#line 1306 "cmDependsJavaParser.y"
+#line 1305 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3926,11 +3925,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3930 "cmDependsJavaParser.cxx"
+#line 3929 "cmDependsJavaParser.cxx"
break;
case 146: /* VariableInitializers: VariableInitializer */
-#line 1316 "cmDependsJavaParser.y"
+#line 1315 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3938,11 +3937,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3942 "cmDependsJavaParser.cxx"
+#line 3941 "cmDependsJavaParser.cxx"
break;
case 147: /* VariableInitializers: VariableInitializers jp_COMMA VariableInitializer */
-#line 1325 "cmDependsJavaParser.y"
+#line 1324 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3950,33 +3949,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3954 "cmDependsJavaParser.cxx"
+#line 3953 "cmDependsJavaParser.cxx"
break;
case 148: /* Block: jp_CURLYSTART BlockStatementsopt jp_CURLYEND */
-#line 1335 "cmDependsJavaParser.y"
+#line 1334 "cmDependsJavaParser.y"
{
jpElementStart(4);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3965 "cmDependsJavaParser.cxx"
+#line 3964 "cmDependsJavaParser.cxx"
break;
case 149: /* BlockStatementsopt: %empty */
-#line 1343 "cmDependsJavaParser.y"
+#line 1342 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3976 "cmDependsJavaParser.cxx"
+#line 3975 "cmDependsJavaParser.cxx"
break;
case 150: /* BlockStatementsopt: BlockStatements */
-#line 1351 "cmDependsJavaParser.y"
+#line 1350 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3984,11 +3983,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3988 "cmDependsJavaParser.cxx"
+#line 3987 "cmDependsJavaParser.cxx"
break;
case 151: /* BlockStatements: BlockStatement */
-#line 1361 "cmDependsJavaParser.y"
+#line 1360 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3996,11 +3995,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4000 "cmDependsJavaParser.cxx"
+#line 3999 "cmDependsJavaParser.cxx"
break;
case 152: /* BlockStatements: BlockStatements BlockStatement */
-#line 1370 "cmDependsJavaParser.y"
+#line 1369 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -4008,11 +4007,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4012 "cmDependsJavaParser.cxx"
+#line 4011 "cmDependsJavaParser.cxx"
break;
case 153: /* BlockStatement: LocalVariableDeclarationStatement */
-#line 1380 "cmDependsJavaParser.y"
+#line 1379 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4020,11 +4019,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4024 "cmDependsJavaParser.cxx"
+#line 4023 "cmDependsJavaParser.cxx"
break;
case 154: /* BlockStatement: Statement */
-#line 1389 "cmDependsJavaParser.y"
+#line 1388 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4032,11 +4031,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4036 "cmDependsJavaParser.cxx"
+#line 4035 "cmDependsJavaParser.cxx"
break;
case 155: /* BlockStatement: ClassDeclaration */
-#line 1398 "cmDependsJavaParser.y"
+#line 1397 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4044,11 +4043,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4048 "cmDependsJavaParser.cxx"
+#line 4047 "cmDependsJavaParser.cxx"
break;
case 156: /* LocalVariableDeclarationStatement: LocalVariableDeclaration jp_SEMICOL */
-#line 1408 "cmDependsJavaParser.y"
+#line 1407 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -4056,11 +4055,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4060 "cmDependsJavaParser.cxx"
+#line 4059 "cmDependsJavaParser.cxx"
break;
case 157: /* LocalVariableDeclaration: Modifiers Type VariableDeclarators */
-#line 1418 "cmDependsJavaParser.y"
+#line 1417 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(3);
@@ -4068,11 +4067,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4072 "cmDependsJavaParser.cxx"
+#line 4071 "cmDependsJavaParser.cxx"
break;
case 158: /* LocalVariableDeclaration: Type VariableDeclarators */
-#line 1427 "cmDependsJavaParser.y"
+#line 1426 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -4080,11 +4079,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4084 "cmDependsJavaParser.cxx"
+#line 4083 "cmDependsJavaParser.cxx"
break;
case 159: /* Statement: StatementWithoutTrailingSubstatement */
-#line 1437 "cmDependsJavaParser.y"
+#line 1436 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4092,11 +4091,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4096 "cmDependsJavaParser.cxx"
+#line 4095 "cmDependsJavaParser.cxx"
break;
case 160: /* Statement: LabeledStatement */
-#line 1446 "cmDependsJavaParser.y"
+#line 1445 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4104,11 +4103,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4108 "cmDependsJavaParser.cxx"
+#line 4107 "cmDependsJavaParser.cxx"
break;
case 161: /* Statement: IfThenStatement */
-#line 1455 "cmDependsJavaParser.y"
+#line 1454 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4116,11 +4115,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4120 "cmDependsJavaParser.cxx"
+#line 4119 "cmDependsJavaParser.cxx"
break;
case 162: /* Statement: IfThenElseStatement */
-#line 1464 "cmDependsJavaParser.y"
+#line 1463 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4128,11 +4127,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4132 "cmDependsJavaParser.cxx"
+#line 4131 "cmDependsJavaParser.cxx"
break;
case 163: /* Statement: WhileStatement */
-#line 1473 "cmDependsJavaParser.y"
+#line 1472 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4140,11 +4139,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4144 "cmDependsJavaParser.cxx"
+#line 4143 "cmDependsJavaParser.cxx"
break;
case 164: /* Statement: ForStatement */
-#line 1482 "cmDependsJavaParser.y"
+#line 1481 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4152,11 +4151,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4156 "cmDependsJavaParser.cxx"
+#line 4155 "cmDependsJavaParser.cxx"
break;
case 165: /* StatementNoShortIf: StatementWithoutTrailingSubstatement */
-#line 1492 "cmDependsJavaParser.y"
+#line 1491 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4164,11 +4163,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4168 "cmDependsJavaParser.cxx"
+#line 4167 "cmDependsJavaParser.cxx"
break;
case 166: /* StatementNoShortIf: LabeledStatementNoShortIf */
-#line 1501 "cmDependsJavaParser.y"
+#line 1500 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4176,11 +4175,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4180 "cmDependsJavaParser.cxx"
+#line 4179 "cmDependsJavaParser.cxx"
break;
case 167: /* StatementNoShortIf: IfThenElseStatementNoShortIf */
-#line 1510 "cmDependsJavaParser.y"
+#line 1509 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4188,11 +4187,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4192 "cmDependsJavaParser.cxx"
+#line 4191 "cmDependsJavaParser.cxx"
break;
case 168: /* StatementNoShortIf: WhileStatementNoShortIf */
-#line 1519 "cmDependsJavaParser.y"
+#line 1518 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4200,11 +4199,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4204 "cmDependsJavaParser.cxx"
+#line 4203 "cmDependsJavaParser.cxx"
break;
case 169: /* StatementNoShortIf: ForStatementNoShortIf */
-#line 1528 "cmDependsJavaParser.y"
+#line 1527 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4212,11 +4211,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4216 "cmDependsJavaParser.cxx"
+#line 4215 "cmDependsJavaParser.cxx"
break;
case 170: /* StatementWithoutTrailingSubstatement: Block */
-#line 1538 "cmDependsJavaParser.y"
+#line 1537 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4224,11 +4223,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4228 "cmDependsJavaParser.cxx"
+#line 4227 "cmDependsJavaParser.cxx"
break;
case 171: /* StatementWithoutTrailingSubstatement: EmptyStatement */
-#line 1547 "cmDependsJavaParser.y"
+#line 1546 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4236,11 +4235,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4240 "cmDependsJavaParser.cxx"
+#line 4239 "cmDependsJavaParser.cxx"
break;
case 172: /* StatementWithoutTrailingSubstatement: ExpressionStatement */
-#line 1556 "cmDependsJavaParser.y"
+#line 1555 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4248,11 +4247,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4252 "cmDependsJavaParser.cxx"
+#line 4251 "cmDependsJavaParser.cxx"
break;
case 173: /* StatementWithoutTrailingSubstatement: SwitchStatement */
-#line 1565 "cmDependsJavaParser.y"
+#line 1564 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4260,11 +4259,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4264 "cmDependsJavaParser.cxx"
+#line 4263 "cmDependsJavaParser.cxx"
break;
case 174: /* StatementWithoutTrailingSubstatement: DoStatement */
-#line 1574 "cmDependsJavaParser.y"
+#line 1573 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4272,11 +4271,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4276 "cmDependsJavaParser.cxx"
+#line 4275 "cmDependsJavaParser.cxx"
break;
case 175: /* StatementWithoutTrailingSubstatement: BreakStatement */
-#line 1583 "cmDependsJavaParser.y"
+#line 1582 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4284,11 +4283,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4288 "cmDependsJavaParser.cxx"
+#line 4287 "cmDependsJavaParser.cxx"
break;
case 176: /* StatementWithoutTrailingSubstatement: ContinueStatement */
-#line 1592 "cmDependsJavaParser.y"
+#line 1591 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4296,11 +4295,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4300 "cmDependsJavaParser.cxx"
+#line 4299 "cmDependsJavaParser.cxx"
break;
case 177: /* StatementWithoutTrailingSubstatement: ReturnStatement */
-#line 1601 "cmDependsJavaParser.y"
+#line 1600 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4308,11 +4307,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4312 "cmDependsJavaParser.cxx"
+#line 4311 "cmDependsJavaParser.cxx"
break;
case 178: /* StatementWithoutTrailingSubstatement: SynchronizedStatement */
-#line 1610 "cmDependsJavaParser.y"
+#line 1609 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4320,11 +4319,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4324 "cmDependsJavaParser.cxx"
+#line 4323 "cmDependsJavaParser.cxx"
break;
case 179: /* StatementWithoutTrailingSubstatement: ThrowStatement */
-#line 1619 "cmDependsJavaParser.y"
+#line 1618 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4332,11 +4331,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4336 "cmDependsJavaParser.cxx"
+#line 4335 "cmDependsJavaParser.cxx"
break;
case 180: /* StatementWithoutTrailingSubstatement: TryStatement */
-#line 1628 "cmDependsJavaParser.y"
+#line 1627 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4344,11 +4343,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4348 "cmDependsJavaParser.cxx"
+#line 4347 "cmDependsJavaParser.cxx"
break;
case 181: /* StatementWithoutTrailingSubstatement: AssertStatement */
-#line 1637 "cmDependsJavaParser.y"
+#line 1636 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4356,11 +4355,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4360 "cmDependsJavaParser.cxx"
+#line 4359 "cmDependsJavaParser.cxx"
break;
case 182: /* EmptyStatement: jp_SEMICOL */
-#line 1647 "cmDependsJavaParser.y"
+#line 1646 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4368,11 +4367,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4372 "cmDependsJavaParser.cxx"
+#line 4371 "cmDependsJavaParser.cxx"
break;
case 183: /* LabeledStatement: Identifier jp_COLON Statement */
-#line 1657 "cmDependsJavaParser.y"
+#line 1656 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
@@ -4381,11 +4380,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4385 "cmDependsJavaParser.cxx"
+#line 4384 "cmDependsJavaParser.cxx"
break;
case 184: /* LabeledStatementNoShortIf: Identifier jp_COLON StatementNoShortIf */
-#line 1668 "cmDependsJavaParser.y"
+#line 1667 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4393,11 +4392,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4397 "cmDependsJavaParser.cxx"
+#line 4396 "cmDependsJavaParser.cxx"
break;
case 185: /* ExpressionStatement: StatementExpression jp_SEMICOL */
-#line 1678 "cmDependsJavaParser.y"
+#line 1677 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4405,11 +4404,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4409 "cmDependsJavaParser.cxx"
+#line 4408 "cmDependsJavaParser.cxx"
break;
case 186: /* StatementExpression: Assignment */
-#line 1688 "cmDependsJavaParser.y"
+#line 1687 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4417,11 +4416,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4421 "cmDependsJavaParser.cxx"
+#line 4420 "cmDependsJavaParser.cxx"
break;
case 187: /* StatementExpression: PreIncrementExpression */
-#line 1697 "cmDependsJavaParser.y"
+#line 1696 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4429,11 +4428,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4433 "cmDependsJavaParser.cxx"
+#line 4432 "cmDependsJavaParser.cxx"
break;
case 188: /* StatementExpression: PreDecrementExpression */
-#line 1706 "cmDependsJavaParser.y"
+#line 1705 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4441,11 +4440,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4445 "cmDependsJavaParser.cxx"
+#line 4444 "cmDependsJavaParser.cxx"
break;
case 189: /* StatementExpression: PostIncrementExpression */
-#line 1715 "cmDependsJavaParser.y"
+#line 1714 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4453,11 +4452,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4457 "cmDependsJavaParser.cxx"
+#line 4456 "cmDependsJavaParser.cxx"
break;
case 190: /* StatementExpression: PostDecrementExpression */
-#line 1724 "cmDependsJavaParser.y"
+#line 1723 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4465,11 +4464,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4469 "cmDependsJavaParser.cxx"
+#line 4468 "cmDependsJavaParser.cxx"
break;
case 191: /* StatementExpression: MethodInvocation */
-#line 1733 "cmDependsJavaParser.y"
+#line 1732 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4477,11 +4476,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4481 "cmDependsJavaParser.cxx"
+#line 4480 "cmDependsJavaParser.cxx"
break;
case 192: /* StatementExpression: ClassInstanceCreationExpression */
-#line 1742 "cmDependsJavaParser.y"
+#line 1741 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4489,11 +4488,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4493 "cmDependsJavaParser.cxx"
+#line 4492 "cmDependsJavaParser.cxx"
break;
case 193: /* IfThenStatement: jp_IF jp_PARESTART Expression jp_PAREEND Statement */
-#line 1752 "cmDependsJavaParser.y"
+#line 1751 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4501,11 +4500,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4505 "cmDependsJavaParser.cxx"
+#line 4504 "cmDependsJavaParser.cxx"
break;
case 194: /* IfThenElseStatement: jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE Statement */
-#line 1762 "cmDependsJavaParser.y"
+#line 1761 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4513,11 +4512,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4517 "cmDependsJavaParser.cxx"
+#line 4516 "cmDependsJavaParser.cxx"
break;
case 195: /* IfThenElseStatementNoShortIf: jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE StatementNoShortIf */
-#line 1772 "cmDependsJavaParser.y"
+#line 1771 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4525,40 +4524,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4529 "cmDependsJavaParser.cxx"
+#line 4528 "cmDependsJavaParser.cxx"
break;
case 196: /* SwitchStatement: jp_SWITCH jp_PARESTART Expression jp_PAREEND SwitchBlock */
-#line 1782 "cmDependsJavaParser.y"
+#line 1781 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4538 "cmDependsJavaParser.cxx"
+#line 4537 "cmDependsJavaParser.cxx"
break;
case 197: /* SwitchBlock: jp_CURLYSTART SwitchBlockStatementGroups SwitchLabelsopt jp_CURLYEND */
-#line 1789 "cmDependsJavaParser.y"
+#line 1788 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 4547 "cmDependsJavaParser.cxx"
+#line 4546 "cmDependsJavaParser.cxx"
break;
case 198: /* SwitchLabelsopt: %empty */
-#line 1795 "cmDependsJavaParser.y"
+#line 1794 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4558 "cmDependsJavaParser.cxx"
+#line 4557 "cmDependsJavaParser.cxx"
break;
case 199: /* SwitchLabelsopt: SwitchLabels */
-#line 1803 "cmDependsJavaParser.y"
+#line 1802 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4566,22 +4565,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4570 "cmDependsJavaParser.cxx"
+#line 4569 "cmDependsJavaParser.cxx"
break;
case 200: /* SwitchBlockStatementGroups: %empty */
-#line 1812 "cmDependsJavaParser.y"
+#line 1811 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4581 "cmDependsJavaParser.cxx"
+#line 4580 "cmDependsJavaParser.cxx"
break;
case 201: /* SwitchBlockStatementGroups: SwitchBlockStatementGroups SwitchBlockStatementGroup */
-#line 1820 "cmDependsJavaParser.y"
+#line 1819 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4589,11 +4588,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4593 "cmDependsJavaParser.cxx"
+#line 4592 "cmDependsJavaParser.cxx"
break;
case 202: /* SwitchBlockStatementGroup: SwitchLabels BlockStatements */
-#line 1830 "cmDependsJavaParser.y"
+#line 1829 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4601,11 +4600,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4605 "cmDependsJavaParser.cxx"
+#line 4604 "cmDependsJavaParser.cxx"
break;
case 203: /* SwitchLabels: SwitchLabel */
-#line 1840 "cmDependsJavaParser.y"
+#line 1839 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4613,11 +4612,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4617 "cmDependsJavaParser.cxx"
+#line 4616 "cmDependsJavaParser.cxx"
break;
case 204: /* SwitchLabels: SwitchLabels SwitchLabel */
-#line 1849 "cmDependsJavaParser.y"
+#line 1848 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4625,11 +4624,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4629 "cmDependsJavaParser.cxx"
+#line 4628 "cmDependsJavaParser.cxx"
break;
case 205: /* SwitchLabel: jp_CASE ConstantExpression jp_COLON */
-#line 1859 "cmDependsJavaParser.y"
+#line 1858 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4637,11 +4636,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4641 "cmDependsJavaParser.cxx"
+#line 4640 "cmDependsJavaParser.cxx"
break;
case 206: /* SwitchLabel: jp_DEFAULT jp_COLON */
-#line 1868 "cmDependsJavaParser.y"
+#line 1867 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4649,58 +4648,58 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4653 "cmDependsJavaParser.cxx"
+#line 4652 "cmDependsJavaParser.cxx"
break;
case 207: /* WhileStatement: jp_WHILE jp_PARESTART Expression jp_PAREEND Statement */
-#line 1878 "cmDependsJavaParser.y"
+#line 1877 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4662 "cmDependsJavaParser.cxx"
+#line 4661 "cmDependsJavaParser.cxx"
break;
case 208: /* WhileStatementNoShortIf: jp_WHILE jp_PARESTART Expression jp_PAREEND StatementNoShortIf */
-#line 1885 "cmDependsJavaParser.y"
+#line 1884 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4671 "cmDependsJavaParser.cxx"
+#line 4670 "cmDependsJavaParser.cxx"
break;
case 209: /* DoStatement: jp_DO Statement jp_WHILE jp_PARESTART Expression jp_PAREEND jp_SEMICOL */
-#line 1892 "cmDependsJavaParser.y"
+#line 1891 "cmDependsJavaParser.y"
{
jpElementStart(7);
}
-#line 4680 "cmDependsJavaParser.cxx"
+#line 4679 "cmDependsJavaParser.cxx"
break;
case 210: /* ForStatement: jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND Statement */
-#line 1900 "cmDependsJavaParser.y"
+#line 1899 "cmDependsJavaParser.y"
{
jpElementStart(9);
}
-#line 4689 "cmDependsJavaParser.cxx"
+#line 4688 "cmDependsJavaParser.cxx"
break;
case 211: /* ForUpdateopt: %empty */
-#line 1906 "cmDependsJavaParser.y"
+#line 1905 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4700 "cmDependsJavaParser.cxx"
+#line 4699 "cmDependsJavaParser.cxx"
break;
case 212: /* ForUpdateopt: ForUpdate */
-#line 1914 "cmDependsJavaParser.y"
+#line 1913 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4708,22 +4707,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4712 "cmDependsJavaParser.cxx"
+#line 4711 "cmDependsJavaParser.cxx"
break;
case 213: /* ForInitopt: %empty */
-#line 1923 "cmDependsJavaParser.y"
+#line 1922 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4723 "cmDependsJavaParser.cxx"
+#line 4722 "cmDependsJavaParser.cxx"
break;
case 214: /* ForInitopt: ForInit */
-#line 1931 "cmDependsJavaParser.y"
+#line 1930 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4731,33 +4730,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4735 "cmDependsJavaParser.cxx"
+#line 4734 "cmDependsJavaParser.cxx"
break;
case 215: /* ForStatementNoShortIf: jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND StatementNoShortIf */
-#line 1942 "cmDependsJavaParser.y"
+#line 1941 "cmDependsJavaParser.y"
{
jpElementStart(9);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4746 "cmDependsJavaParser.cxx"
+#line 4745 "cmDependsJavaParser.cxx"
break;
case 216: /* Expressionopt: %empty */
-#line 1950 "cmDependsJavaParser.y"
+#line 1949 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4757 "cmDependsJavaParser.cxx"
+#line 4756 "cmDependsJavaParser.cxx"
break;
case 217: /* Expressionopt: Expression */
-#line 1958 "cmDependsJavaParser.y"
+#line 1957 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4765,11 +4764,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4769 "cmDependsJavaParser.cxx"
+#line 4768 "cmDependsJavaParser.cxx"
break;
case 218: /* ForInit: StatementExpressionList */
-#line 1968 "cmDependsJavaParser.y"
+#line 1967 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4777,11 +4776,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4781 "cmDependsJavaParser.cxx"
+#line 4780 "cmDependsJavaParser.cxx"
break;
case 219: /* ForInit: LocalVariableDeclaration */
-#line 1977 "cmDependsJavaParser.y"
+#line 1976 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4789,11 +4788,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4793 "cmDependsJavaParser.cxx"
+#line 4792 "cmDependsJavaParser.cxx"
break;
case 220: /* ForUpdate: StatementExpressionList */
-#line 1987 "cmDependsJavaParser.y"
+#line 1986 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4801,11 +4800,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4805 "cmDependsJavaParser.cxx"
+#line 4804 "cmDependsJavaParser.cxx"
break;
case 221: /* StatementExpressionList: StatementExpression */
-#line 1997 "cmDependsJavaParser.y"
+#line 1996 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4813,11 +4812,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4817 "cmDependsJavaParser.cxx"
+#line 4816 "cmDependsJavaParser.cxx"
break;
case 222: /* StatementExpressionList: StatementExpressionList jp_COMMA StatementExpression */
-#line 2006 "cmDependsJavaParser.y"
+#line 2005 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4825,11 +4824,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4829 "cmDependsJavaParser.cxx"
+#line 4828 "cmDependsJavaParser.cxx"
break;
case 223: /* AssertStatement: jp_ASSERT Expression jp_SEMICOL */
-#line 2016 "cmDependsJavaParser.y"
+#line 2015 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4837,11 +4836,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4841 "cmDependsJavaParser.cxx"
+#line 4840 "cmDependsJavaParser.cxx"
break;
case 224: /* AssertStatement: jp_ASSERT Expression jp_COLON Expression jp_SEMICOL */
-#line 2025 "cmDependsJavaParser.y"
+#line 2024 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4849,11 +4848,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4853 "cmDependsJavaParser.cxx"
+#line 4852 "cmDependsJavaParser.cxx"
break;
case 225: /* BreakStatement: jp_BREAK Identifieropt jp_SEMICOL */
-#line 2035 "cmDependsJavaParser.y"
+#line 2034 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4862,31 +4861,31 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4866 "cmDependsJavaParser.cxx"
+#line 4865 "cmDependsJavaParser.cxx"
break;
case 226: /* Identifieropt: %empty */
-#line 2045 "cmDependsJavaParser.y"
+#line 2044 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4877 "cmDependsJavaParser.cxx"
+#line 4876 "cmDependsJavaParser.cxx"
break;
case 227: /* Identifieropt: Identifier */
-#line 2053 "cmDependsJavaParser.y"
+#line 2052 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 4886 "cmDependsJavaParser.cxx"
+#line 4885 "cmDependsJavaParser.cxx"
break;
case 228: /* ContinueStatement: jp_CONTINUE Identifieropt jp_SEMICOL */
-#line 2060 "cmDependsJavaParser.y"
+#line 2059 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4895,11 +4894,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4899 "cmDependsJavaParser.cxx"
+#line 4898 "cmDependsJavaParser.cxx"
break;
case 229: /* ReturnStatement: jp_RETURN Expressionopt jp_SEMICOL */
-#line 2071 "cmDependsJavaParser.y"
+#line 2070 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4907,11 +4906,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4911 "cmDependsJavaParser.cxx"
+#line 4910 "cmDependsJavaParser.cxx"
break;
case 230: /* ThrowStatement: jp_THROW Expression jp_SEMICOL */
-#line 2081 "cmDependsJavaParser.y"
+#line 2080 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4919,11 +4918,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4923 "cmDependsJavaParser.cxx"
+#line 4922 "cmDependsJavaParser.cxx"
break;
case 231: /* SynchronizedStatement: jp_SYNCHRONIZED jp_PARESTART Expression jp_PAREEND Block */
-#line 2091 "cmDependsJavaParser.y"
+#line 2090 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4931,11 +4930,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4935 "cmDependsJavaParser.cxx"
+#line 4934 "cmDependsJavaParser.cxx"
break;
case 232: /* TryStatement: jp_TRY Block Catches */
-#line 2101 "cmDependsJavaParser.y"
+#line 2100 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4943,11 +4942,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4947 "cmDependsJavaParser.cxx"
+#line 4946 "cmDependsJavaParser.cxx"
break;
case 233: /* TryStatement: jp_TRY Block Catchesopt Finally */
-#line 2110 "cmDependsJavaParser.y"
+#line 2109 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -4955,22 +4954,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4959 "cmDependsJavaParser.cxx"
+#line 4958 "cmDependsJavaParser.cxx"
break;
case 234: /* Catchesopt: %empty */
-#line 2119 "cmDependsJavaParser.y"
+#line 2118 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4970 "cmDependsJavaParser.cxx"
+#line 4969 "cmDependsJavaParser.cxx"
break;
case 235: /* Catchesopt: Catches */
-#line 2127 "cmDependsJavaParser.y"
+#line 2126 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4978,11 +4977,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4982 "cmDependsJavaParser.cxx"
+#line 4981 "cmDependsJavaParser.cxx"
break;
case 236: /* Catches: CatchClause */
-#line 2137 "cmDependsJavaParser.y"
+#line 2136 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4990,11 +4989,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4994 "cmDependsJavaParser.cxx"
+#line 4993 "cmDependsJavaParser.cxx"
break;
case 237: /* Catches: Catches CatchClause */
-#line 2146 "cmDependsJavaParser.y"
+#line 2145 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5002,20 +5001,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5006 "cmDependsJavaParser.cxx"
+#line 5005 "cmDependsJavaParser.cxx"
break;
case 238: /* CatchClause: jp_CATCH jp_PARESTART FormalParameter jp_PAREEND Block */
-#line 2156 "cmDependsJavaParser.y"
+#line 2155 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 5015 "cmDependsJavaParser.cxx"
+#line 5014 "cmDependsJavaParser.cxx"
break;
case 239: /* Finally: jp_FINALLY Block */
-#line 2163 "cmDependsJavaParser.y"
+#line 2162 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5023,11 +5022,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5027 "cmDependsJavaParser.cxx"
+#line 5026 "cmDependsJavaParser.cxx"
break;
case 240: /* Primary: PrimaryNoNewArray */
-#line 2173 "cmDependsJavaParser.y"
+#line 2172 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5035,11 +5034,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5039 "cmDependsJavaParser.cxx"
+#line 5038 "cmDependsJavaParser.cxx"
break;
case 241: /* Primary: ArrayCreationExpression */
-#line 2182 "cmDependsJavaParser.y"
+#line 2181 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5047,11 +5046,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5051 "cmDependsJavaParser.cxx"
+#line 5050 "cmDependsJavaParser.cxx"
break;
case 242: /* PrimaryNoNewArray: Literal */
-#line 2192 "cmDependsJavaParser.y"
+#line 2191 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5059,20 +5058,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5063 "cmDependsJavaParser.cxx"
+#line 5062 "cmDependsJavaParser.cxx"
break;
case 243: /* PrimaryNoNewArray: jp_THIS */
-#line 2201 "cmDependsJavaParser.y"
+#line 2200 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 5072 "cmDependsJavaParser.cxx"
+#line 5071 "cmDependsJavaParser.cxx"
break;
case 244: /* PrimaryNoNewArray: jp_PARESTART Expression jp_PAREEND */
-#line 2207 "cmDependsJavaParser.y"
+#line 2206 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5080,11 +5079,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5084 "cmDependsJavaParser.cxx"
+#line 5083 "cmDependsJavaParser.cxx"
break;
case 245: /* PrimaryNoNewArray: ClassInstanceCreationExpression */
-#line 2216 "cmDependsJavaParser.y"
+#line 2215 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5092,11 +5091,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5096 "cmDependsJavaParser.cxx"
+#line 5095 "cmDependsJavaParser.cxx"
break;
case 246: /* PrimaryNoNewArray: FieldAccess */
-#line 2225 "cmDependsJavaParser.y"
+#line 2224 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5104,11 +5103,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5108 "cmDependsJavaParser.cxx"
+#line 5107 "cmDependsJavaParser.cxx"
break;
case 247: /* PrimaryNoNewArray: MethodInvocation */
-#line 2234 "cmDependsJavaParser.y"
+#line 2233 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5116,11 +5115,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5120 "cmDependsJavaParser.cxx"
+#line 5119 "cmDependsJavaParser.cxx"
break;
case 248: /* PrimaryNoNewArray: ArrayAccess */
-#line 2243 "cmDependsJavaParser.y"
+#line 2242 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5128,11 +5127,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5132 "cmDependsJavaParser.cxx"
+#line 5131 "cmDependsJavaParser.cxx"
break;
case 249: /* ClassInstanceCreationExpression: New ClassType jp_PARESTART ArgumentListopt jp_PAREEND ClassBodyOpt */
-#line 2253 "cmDependsJavaParser.y"
+#line 2252 "cmDependsJavaParser.y"
{
jpElementStart(6);
jpCheckEmpty(6);
@@ -5140,22 +5139,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5144 "cmDependsJavaParser.cxx"
+#line 5143 "cmDependsJavaParser.cxx"
break;
case 250: /* ClassBodyOpt: %empty */
-#line 2262 "cmDependsJavaParser.y"
+#line 2261 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5155 "cmDependsJavaParser.cxx"
+#line 5154 "cmDependsJavaParser.cxx"
break;
case 251: /* ClassBodyOpt: ClassBody */
-#line 2270 "cmDependsJavaParser.y"
+#line 2269 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5163,22 +5162,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5167 "cmDependsJavaParser.cxx"
+#line 5166 "cmDependsJavaParser.cxx"
break;
case 252: /* ArgumentListopt: %empty */
-#line 2279 "cmDependsJavaParser.y"
+#line 2278 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5178 "cmDependsJavaParser.cxx"
+#line 5177 "cmDependsJavaParser.cxx"
break;
case 253: /* ArgumentListopt: ArgumentList */
-#line 2287 "cmDependsJavaParser.y"
+#line 2286 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5186,11 +5185,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5190 "cmDependsJavaParser.cxx"
+#line 5189 "cmDependsJavaParser.cxx"
break;
case 254: /* ArgumentList: Expression */
-#line 2297 "cmDependsJavaParser.y"
+#line 2296 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5198,11 +5197,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5202 "cmDependsJavaParser.cxx"
+#line 5201 "cmDependsJavaParser.cxx"
break;
case 255: /* ArgumentList: ArgumentList jp_COMMA Expression */
-#line 2306 "cmDependsJavaParser.y"
+#line 2305 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5210,11 +5209,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5214 "cmDependsJavaParser.cxx"
+#line 5213 "cmDependsJavaParser.cxx"
break;
case 256: /* ArrayCreationExpression: New PrimitiveType DimExprs Dimsopt */
-#line 2316 "cmDependsJavaParser.y"
+#line 2315 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5222,11 +5221,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5226 "cmDependsJavaParser.cxx"
+#line 5225 "cmDependsJavaParser.cxx"
break;
case 257: /* ArrayCreationExpression: New ClassOrInterfaceType DimExprs Dimsopt */
-#line 2325 "cmDependsJavaParser.y"
+#line 2324 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5234,11 +5233,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5238 "cmDependsJavaParser.cxx"
+#line 5237 "cmDependsJavaParser.cxx"
break;
case 258: /* ArrayCreationExpression: New PrimitiveType Dims ArrayInitializer */
-#line 2334 "cmDependsJavaParser.y"
+#line 2333 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5246,11 +5245,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5250 "cmDependsJavaParser.cxx"
+#line 5249 "cmDependsJavaParser.cxx"
break;
case 259: /* ArrayCreationExpression: New ClassOrInterfaceType Dims ArrayInitializer */
-#line 2343 "cmDependsJavaParser.y"
+#line 2342 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5258,22 +5257,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5262 "cmDependsJavaParser.cxx"
+#line 5261 "cmDependsJavaParser.cxx"
break;
case 260: /* Dimsopt: %empty */
-#line 2352 "cmDependsJavaParser.y"
+#line 2351 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5273 "cmDependsJavaParser.cxx"
+#line 5272 "cmDependsJavaParser.cxx"
break;
case 261: /* Dimsopt: Dims */
-#line 2360 "cmDependsJavaParser.y"
+#line 2359 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5281,11 +5280,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5285 "cmDependsJavaParser.cxx"
+#line 5284 "cmDependsJavaParser.cxx"
break;
case 262: /* DimExprs: DimExpr */
-#line 2370 "cmDependsJavaParser.y"
+#line 2369 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5293,11 +5292,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5297 "cmDependsJavaParser.cxx"
+#line 5296 "cmDependsJavaParser.cxx"
break;
case 263: /* DimExprs: DimExprs DimExpr */
-#line 2379 "cmDependsJavaParser.y"
+#line 2378 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5305,11 +5304,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5309 "cmDependsJavaParser.cxx"
+#line 5308 "cmDependsJavaParser.cxx"
break;
case 264: /* DimExpr: jp_BRACKETSTART Expression jp_BRACKETEND */
-#line 2389 "cmDependsJavaParser.y"
+#line 2388 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5317,29 +5316,29 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5321 "cmDependsJavaParser.cxx"
+#line 5320 "cmDependsJavaParser.cxx"
break;
case 265: /* Dims: jp_BRACKETSTART jp_BRACKETEND */
-#line 2399 "cmDependsJavaParser.y"
+#line 2398 "cmDependsJavaParser.y"
{
jpElementStart(2);
}
-#line 5330 "cmDependsJavaParser.cxx"
+#line 5329 "cmDependsJavaParser.cxx"
break;
case 266: /* Dims: Dims jp_BRACKETSTART jp_BRACKETEND */
-#line 2405 "cmDependsJavaParser.y"
+#line 2404 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 5339 "cmDependsJavaParser.cxx"
+#line 5338 "cmDependsJavaParser.cxx"
break;
case 267: /* FieldAccess: Primary jp_DOT Identifier */
-#line 2412 "cmDependsJavaParser.y"
+#line 2411 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5348,11 +5347,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5352 "cmDependsJavaParser.cxx"
+#line 5351 "cmDependsJavaParser.cxx"
break;
case 268: /* FieldAccess: jp_SUPER jp_DOT Identifier */
-#line 2422 "cmDependsJavaParser.y"
+#line 2421 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5361,11 +5360,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5365 "cmDependsJavaParser.cxx"
+#line 5364 "cmDependsJavaParser.cxx"
break;
case 269: /* FieldAccess: jp_THIS jp_DOT Identifier */
-#line 2432 "cmDependsJavaParser.y"
+#line 2431 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5374,11 +5373,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5378 "cmDependsJavaParser.cxx"
+#line 5377 "cmDependsJavaParser.cxx"
break;
case 270: /* FieldAccess: Primary jp_DOT jp_THIS */
-#line 2442 "cmDependsJavaParser.y"
+#line 2441 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5387,11 +5386,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5391 "cmDependsJavaParser.cxx"
+#line 5390 "cmDependsJavaParser.cxx"
break;
case 271: /* MethodInvocation: Name jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2453 "cmDependsJavaParser.y"
+#line 2452 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5400,11 +5399,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5404 "cmDependsJavaParser.cxx"
+#line 5403 "cmDependsJavaParser.cxx"
break;
case 272: /* MethodInvocation: Primary jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2463 "cmDependsJavaParser.y"
+#line 2462 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-5].str)));
@@ -5414,11 +5413,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5418 "cmDependsJavaParser.cxx"
+#line 5417 "cmDependsJavaParser.cxx"
break;
case 273: /* MethodInvocation: jp_SUPER jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2474 "cmDependsJavaParser.y"
+#line 2473 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5427,11 +5426,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5431 "cmDependsJavaParser.cxx"
+#line 5430 "cmDependsJavaParser.cxx"
break;
case 274: /* MethodInvocation: jp_THIS jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2484 "cmDependsJavaParser.y"
+#line 2483 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5440,11 +5439,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5444 "cmDependsJavaParser.cxx"
+#line 5443 "cmDependsJavaParser.cxx"
break;
case 275: /* ArrayAccess: Name jp_BRACKETSTART Expression jp_BRACKETEND */
-#line 2495 "cmDependsJavaParser.y"
+#line 2494 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5453,11 +5452,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5457 "cmDependsJavaParser.cxx"
+#line 5456 "cmDependsJavaParser.cxx"
break;
case 276: /* ArrayAccess: PrimaryNoNewArray jp_BRACKETSTART Expression jp_BRACKETEND */
-#line 2505 "cmDependsJavaParser.y"
+#line 2504 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5465,11 +5464,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5469 "cmDependsJavaParser.cxx"
+#line 5468 "cmDependsJavaParser.cxx"
break;
case 277: /* PostfixExpression: Primary */
-#line 2515 "cmDependsJavaParser.y"
+#line 2514 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5477,11 +5476,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5481 "cmDependsJavaParser.cxx"
+#line 5480 "cmDependsJavaParser.cxx"
break;
case 278: /* PostfixExpression: Name */
-#line 2524 "cmDependsJavaParser.y"
+#line 2523 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5489,11 +5488,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5493 "cmDependsJavaParser.cxx"
+#line 5492 "cmDependsJavaParser.cxx"
break;
case 279: /* PostfixExpression: ArrayType jp_DOT jp_CLASS */
-#line 2533 "cmDependsJavaParser.y"
+#line 2532 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5501,11 +5500,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5505 "cmDependsJavaParser.cxx"
+#line 5504 "cmDependsJavaParser.cxx"
break;
case 280: /* PostfixExpression: PostIncrementExpression */
-#line 2542 "cmDependsJavaParser.y"
+#line 2541 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5513,11 +5512,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5517 "cmDependsJavaParser.cxx"
+#line 5516 "cmDependsJavaParser.cxx"
break;
case 281: /* PostfixExpression: PostDecrementExpression */
-#line 2551 "cmDependsJavaParser.y"
+#line 2550 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5525,11 +5524,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5529 "cmDependsJavaParser.cxx"
+#line 5528 "cmDependsJavaParser.cxx"
break;
case 282: /* PostIncrementExpression: PostfixExpression jp_PLUSPLUS */
-#line 2561 "cmDependsJavaParser.y"
+#line 2560 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5537,11 +5536,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5541 "cmDependsJavaParser.cxx"
+#line 5540 "cmDependsJavaParser.cxx"
break;
case 283: /* PostDecrementExpression: PostfixExpression jp_MINUSMINUS */
-#line 2571 "cmDependsJavaParser.y"
+#line 2570 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5549,11 +5548,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5553 "cmDependsJavaParser.cxx"
+#line 5552 "cmDependsJavaParser.cxx"
break;
case 284: /* UnaryExpression: PreIncrementExpression */
-#line 2581 "cmDependsJavaParser.y"
+#line 2580 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5561,11 +5560,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5565 "cmDependsJavaParser.cxx"
+#line 5564 "cmDependsJavaParser.cxx"
break;
case 285: /* UnaryExpression: PreDecrementExpression */
-#line 2590 "cmDependsJavaParser.y"
+#line 2589 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5573,11 +5572,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5577 "cmDependsJavaParser.cxx"
+#line 5576 "cmDependsJavaParser.cxx"
break;
case 286: /* UnaryExpression: jp_PLUS UnaryExpression */
-#line 2599 "cmDependsJavaParser.y"
+#line 2598 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5585,11 +5584,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5589 "cmDependsJavaParser.cxx"
+#line 5588 "cmDependsJavaParser.cxx"
break;
case 287: /* UnaryExpression: jp_MINUS UnaryExpression */
-#line 2608 "cmDependsJavaParser.y"
+#line 2607 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5597,11 +5596,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5601 "cmDependsJavaParser.cxx"
+#line 5600 "cmDependsJavaParser.cxx"
break;
case 288: /* UnaryExpression: UnaryExpressionNotPlusMinus */
-#line 2617 "cmDependsJavaParser.y"
+#line 2616 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5609,11 +5608,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5613 "cmDependsJavaParser.cxx"
+#line 5612 "cmDependsJavaParser.cxx"
break;
case 289: /* PreIncrementExpression: jp_PLUSPLUS UnaryExpression */
-#line 2627 "cmDependsJavaParser.y"
+#line 2626 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5621,11 +5620,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5625 "cmDependsJavaParser.cxx"
+#line 5624 "cmDependsJavaParser.cxx"
break;
case 290: /* PreDecrementExpression: jp_MINUSMINUS UnaryExpression */
-#line 2637 "cmDependsJavaParser.y"
+#line 2636 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5633,11 +5632,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5637 "cmDependsJavaParser.cxx"
+#line 5636 "cmDependsJavaParser.cxx"
break;
case 291: /* UnaryExpressionNotPlusMinus: PostfixExpression */
-#line 2647 "cmDependsJavaParser.y"
+#line 2646 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5645,11 +5644,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5649 "cmDependsJavaParser.cxx"
+#line 5648 "cmDependsJavaParser.cxx"
break;
case 292: /* UnaryExpressionNotPlusMinus: jp_TILDE UnaryExpression */
-#line 2656 "cmDependsJavaParser.y"
+#line 2655 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5657,11 +5656,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5661 "cmDependsJavaParser.cxx"
+#line 5660 "cmDependsJavaParser.cxx"
break;
case 293: /* UnaryExpressionNotPlusMinus: jp_EXCLAMATION UnaryExpression */
-#line 2665 "cmDependsJavaParser.y"
+#line 2664 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5669,11 +5668,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5673 "cmDependsJavaParser.cxx"
+#line 5672 "cmDependsJavaParser.cxx"
break;
case 294: /* UnaryExpressionNotPlusMinus: CastExpression */
-#line 2674 "cmDependsJavaParser.y"
+#line 2673 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5681,11 +5680,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5685 "cmDependsJavaParser.cxx"
+#line 5684 "cmDependsJavaParser.cxx"
break;
case 295: /* CastExpression: jp_PARESTART PrimitiveType Dimsopt jp_PAREEND UnaryExpression */
-#line 2684 "cmDependsJavaParser.y"
+#line 2683 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5693,11 +5692,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5697 "cmDependsJavaParser.cxx"
+#line 5696 "cmDependsJavaParser.cxx"
break;
case 296: /* CastExpression: jp_PARESTART Expression jp_PAREEND UnaryExpressionNotPlusMinus */
-#line 2693 "cmDependsJavaParser.y"
+#line 2692 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5705,20 +5704,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5709 "cmDependsJavaParser.cxx"
+#line 5708 "cmDependsJavaParser.cxx"
break;
case 297: /* CastExpression: jp_PARESTART Name Dims jp_PAREEND UnaryExpressionNotPlusMinus */
-#line 2702 "cmDependsJavaParser.y"
+#line 2701 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 5718 "cmDependsJavaParser.cxx"
+#line 5717 "cmDependsJavaParser.cxx"
break;
case 298: /* MultiplicativeExpression: UnaryExpression */
-#line 2709 "cmDependsJavaParser.y"
+#line 2708 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5726,11 +5725,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5730 "cmDependsJavaParser.cxx"
+#line 5729 "cmDependsJavaParser.cxx"
break;
case 299: /* MultiplicativeExpression: MultiplicativeExpression jp_TIMES UnaryExpression */
-#line 2718 "cmDependsJavaParser.y"
+#line 2717 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5738,11 +5737,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5742 "cmDependsJavaParser.cxx"
+#line 5741 "cmDependsJavaParser.cxx"
break;
case 300: /* MultiplicativeExpression: MultiplicativeExpression jp_DIVIDE UnaryExpression */
-#line 2727 "cmDependsJavaParser.y"
+#line 2726 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5750,11 +5749,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5754 "cmDependsJavaParser.cxx"
+#line 5753 "cmDependsJavaParser.cxx"
break;
case 301: /* MultiplicativeExpression: MultiplicativeExpression jp_PERCENT UnaryExpression */
-#line 2736 "cmDependsJavaParser.y"
+#line 2735 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5762,11 +5761,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5766 "cmDependsJavaParser.cxx"
+#line 5765 "cmDependsJavaParser.cxx"
break;
case 302: /* AdditiveExpression: MultiplicativeExpression */
-#line 2746 "cmDependsJavaParser.y"
+#line 2745 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5774,11 +5773,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5778 "cmDependsJavaParser.cxx"
+#line 5777 "cmDependsJavaParser.cxx"
break;
case 303: /* AdditiveExpression: AdditiveExpression jp_PLUS MultiplicativeExpression */
-#line 2755 "cmDependsJavaParser.y"
+#line 2754 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5786,11 +5785,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5790 "cmDependsJavaParser.cxx"
+#line 5789 "cmDependsJavaParser.cxx"
break;
case 304: /* AdditiveExpression: AdditiveExpression jp_MINUS MultiplicativeExpression */
-#line 2764 "cmDependsJavaParser.y"
+#line 2763 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5798,11 +5797,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5802 "cmDependsJavaParser.cxx"
+#line 5801 "cmDependsJavaParser.cxx"
break;
case 305: /* ShiftExpression: AdditiveExpression */
-#line 2774 "cmDependsJavaParser.y"
+#line 2773 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5810,11 +5809,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5814 "cmDependsJavaParser.cxx"
+#line 5813 "cmDependsJavaParser.cxx"
break;
case 306: /* ShiftExpression: ShiftExpression jp_LTLT AdditiveExpression */
-#line 2783 "cmDependsJavaParser.y"
+#line 2782 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5822,11 +5821,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5826 "cmDependsJavaParser.cxx"
+#line 5825 "cmDependsJavaParser.cxx"
break;
case 307: /* ShiftExpression: ShiftExpression jp_GTGT AdditiveExpression */
-#line 2792 "cmDependsJavaParser.y"
+#line 2791 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5834,11 +5833,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5838 "cmDependsJavaParser.cxx"
+#line 5837 "cmDependsJavaParser.cxx"
break;
case 308: /* ShiftExpression: ShiftExpression jp_GTGTGT AdditiveExpression */
-#line 2801 "cmDependsJavaParser.y"
+#line 2800 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5846,11 +5845,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5850 "cmDependsJavaParser.cxx"
+#line 5849 "cmDependsJavaParser.cxx"
break;
case 309: /* RelationalExpression: ShiftExpression */
-#line 2811 "cmDependsJavaParser.y"
+#line 2810 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5858,11 +5857,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5862 "cmDependsJavaParser.cxx"
+#line 5861 "cmDependsJavaParser.cxx"
break;
case 310: /* RelationalExpression: RelationalExpression jp_LESSTHAN ShiftExpression */
-#line 2820 "cmDependsJavaParser.y"
+#line 2819 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5870,11 +5869,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5874 "cmDependsJavaParser.cxx"
+#line 5873 "cmDependsJavaParser.cxx"
break;
case 311: /* RelationalExpression: RelationalExpression jp_GREATER ShiftExpression */
-#line 2829 "cmDependsJavaParser.y"
+#line 2828 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5882,11 +5881,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5886 "cmDependsJavaParser.cxx"
+#line 5885 "cmDependsJavaParser.cxx"
break;
case 312: /* RelationalExpression: RelationalExpression jp_LTEQUALS ShiftExpression */
-#line 2838 "cmDependsJavaParser.y"
+#line 2837 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5894,11 +5893,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5898 "cmDependsJavaParser.cxx"
+#line 5897 "cmDependsJavaParser.cxx"
break;
case 313: /* RelationalExpression: RelationalExpression jp_GTEQUALS ShiftExpression */
-#line 2847 "cmDependsJavaParser.y"
+#line 2846 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5906,11 +5905,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5910 "cmDependsJavaParser.cxx"
+#line 5909 "cmDependsJavaParser.cxx"
break;
case 314: /* RelationalExpression: RelationalExpression jp_INSTANCEOF ReferenceType */
-#line 2856 "cmDependsJavaParser.y"
+#line 2855 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5918,11 +5917,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5922 "cmDependsJavaParser.cxx"
+#line 5921 "cmDependsJavaParser.cxx"
break;
case 315: /* EqualityExpression: RelationalExpression */
-#line 2866 "cmDependsJavaParser.y"
+#line 2865 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5930,11 +5929,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5934 "cmDependsJavaParser.cxx"
+#line 5933 "cmDependsJavaParser.cxx"
break;
case 316: /* EqualityExpression: EqualityExpression jp_EQUALSEQUALS RelationalExpression */
-#line 2875 "cmDependsJavaParser.y"
+#line 2874 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5942,11 +5941,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5946 "cmDependsJavaParser.cxx"
+#line 5945 "cmDependsJavaParser.cxx"
break;
case 317: /* EqualityExpression: EqualityExpression jp_EXCLAMATIONEQUALS RelationalExpression */
-#line 2884 "cmDependsJavaParser.y"
+#line 2883 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5954,11 +5953,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5958 "cmDependsJavaParser.cxx"
+#line 5957 "cmDependsJavaParser.cxx"
break;
case 318: /* AndExpression: EqualityExpression */
-#line 2894 "cmDependsJavaParser.y"
+#line 2893 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5966,11 +5965,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5970 "cmDependsJavaParser.cxx"
+#line 5969 "cmDependsJavaParser.cxx"
break;
case 319: /* AndExpression: AndExpression jp_AND EqualityExpression */
-#line 2903 "cmDependsJavaParser.y"
+#line 2902 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5978,11 +5977,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5982 "cmDependsJavaParser.cxx"
+#line 5981 "cmDependsJavaParser.cxx"
break;
case 320: /* ExclusiveOrExpression: AndExpression */
-#line 2913 "cmDependsJavaParser.y"
+#line 2912 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5990,11 +5989,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5994 "cmDependsJavaParser.cxx"
+#line 5993 "cmDependsJavaParser.cxx"
break;
case 321: /* ExclusiveOrExpression: ExclusiveOrExpression jp_CARROT AndExpression */
-#line 2922 "cmDependsJavaParser.y"
+#line 2921 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6002,11 +6001,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6006 "cmDependsJavaParser.cxx"
+#line 6005 "cmDependsJavaParser.cxx"
break;
case 322: /* InclusiveOrExpression: ExclusiveOrExpression */
-#line 2932 "cmDependsJavaParser.y"
+#line 2931 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6014,11 +6013,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6018 "cmDependsJavaParser.cxx"
+#line 6017 "cmDependsJavaParser.cxx"
break;
case 323: /* InclusiveOrExpression: InclusiveOrExpression jp_PIPE ExclusiveOrExpression */
-#line 2941 "cmDependsJavaParser.y"
+#line 2940 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6026,11 +6025,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6030 "cmDependsJavaParser.cxx"
+#line 6029 "cmDependsJavaParser.cxx"
break;
case 324: /* ConditionalAndExpression: InclusiveOrExpression */
-#line 2951 "cmDependsJavaParser.y"
+#line 2950 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6038,11 +6037,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6042 "cmDependsJavaParser.cxx"
+#line 6041 "cmDependsJavaParser.cxx"
break;
case 325: /* ConditionalAndExpression: ConditionalAndExpression jp_ANDAND InclusiveOrExpression */
-#line 2960 "cmDependsJavaParser.y"
+#line 2959 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6050,11 +6049,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6054 "cmDependsJavaParser.cxx"
+#line 6053 "cmDependsJavaParser.cxx"
break;
case 326: /* ConditionalOrExpression: ConditionalAndExpression */
-#line 2970 "cmDependsJavaParser.y"
+#line 2969 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6062,11 +6061,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6066 "cmDependsJavaParser.cxx"
+#line 6065 "cmDependsJavaParser.cxx"
break;
case 327: /* ConditionalOrExpression: ConditionalOrExpression jp_PIPEPIPE ConditionalAndExpression */
-#line 2979 "cmDependsJavaParser.y"
+#line 2978 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6074,11 +6073,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6078 "cmDependsJavaParser.cxx"
+#line 6077 "cmDependsJavaParser.cxx"
break;
case 328: /* ConditionalExpression: ConditionalOrExpression */
-#line 2989 "cmDependsJavaParser.y"
+#line 2988 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6086,11 +6085,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6090 "cmDependsJavaParser.cxx"
+#line 6089 "cmDependsJavaParser.cxx"
break;
case 329: /* ConditionalExpression: ConditionalOrExpression jp_QUESTION Expression jp_COLON ConditionalExpression */
-#line 2998 "cmDependsJavaParser.y"
+#line 2997 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -6098,11 +6097,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6102 "cmDependsJavaParser.cxx"
+#line 6101 "cmDependsJavaParser.cxx"
break;
case 330: /* AssignmentExpression: ConditionalExpression */
-#line 3008 "cmDependsJavaParser.y"
+#line 3007 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6110,11 +6109,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6114 "cmDependsJavaParser.cxx"
+#line 6113 "cmDependsJavaParser.cxx"
break;
case 331: /* AssignmentExpression: Assignment */
-#line 3017 "cmDependsJavaParser.y"
+#line 3016 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6122,11 +6121,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6126 "cmDependsJavaParser.cxx"
+#line 6125 "cmDependsJavaParser.cxx"
break;
case 332: /* Assignment: LeftHandSide AssignmentOperator AssignmentExpression */
-#line 3027 "cmDependsJavaParser.y"
+#line 3026 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6134,11 +6133,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6138 "cmDependsJavaParser.cxx"
+#line 6137 "cmDependsJavaParser.cxx"
break;
case 333: /* LeftHandSide: Name */
-#line 3037 "cmDependsJavaParser.y"
+#line 3036 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -6147,11 +6146,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6151 "cmDependsJavaParser.cxx"
+#line 6150 "cmDependsJavaParser.cxx"
break;
case 334: /* LeftHandSide: FieldAccess */
-#line 3047 "cmDependsJavaParser.y"
+#line 3046 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6159,11 +6158,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6163 "cmDependsJavaParser.cxx"
+#line 6162 "cmDependsJavaParser.cxx"
break;
case 335: /* LeftHandSide: ArrayAccess */
-#line 3056 "cmDependsJavaParser.y"
+#line 3055 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6171,11 +6170,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6175 "cmDependsJavaParser.cxx"
+#line 6174 "cmDependsJavaParser.cxx"
break;
case 336: /* AssignmentOperator: jp_EQUALS */
-#line 3066 "cmDependsJavaParser.y"
+#line 3065 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6183,11 +6182,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6187 "cmDependsJavaParser.cxx"
+#line 6186 "cmDependsJavaParser.cxx"
break;
case 337: /* AssignmentOperator: jp_TIMESEQUALS */
-#line 3075 "cmDependsJavaParser.y"
+#line 3074 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6195,11 +6194,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6199 "cmDependsJavaParser.cxx"
+#line 6198 "cmDependsJavaParser.cxx"
break;
case 338: /* AssignmentOperator: jp_DIVIDEEQUALS */
-#line 3084 "cmDependsJavaParser.y"
+#line 3083 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6207,11 +6206,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6211 "cmDependsJavaParser.cxx"
+#line 6210 "cmDependsJavaParser.cxx"
break;
case 339: /* AssignmentOperator: jp_PERCENTEQUALS */
-#line 3093 "cmDependsJavaParser.y"
+#line 3092 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6219,11 +6218,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6223 "cmDependsJavaParser.cxx"
+#line 6222 "cmDependsJavaParser.cxx"
break;
case 340: /* AssignmentOperator: jp_PLUSEQUALS */
-#line 3102 "cmDependsJavaParser.y"
+#line 3101 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6231,11 +6230,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6235 "cmDependsJavaParser.cxx"
+#line 6234 "cmDependsJavaParser.cxx"
break;
case 341: /* AssignmentOperator: jp_MINUSEQUALS */
-#line 3111 "cmDependsJavaParser.y"
+#line 3110 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6243,11 +6242,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6247 "cmDependsJavaParser.cxx"
+#line 6246 "cmDependsJavaParser.cxx"
break;
case 342: /* AssignmentOperator: jp_LESLESEQUALS */
-#line 3120 "cmDependsJavaParser.y"
+#line 3119 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6255,11 +6254,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6259 "cmDependsJavaParser.cxx"
+#line 6258 "cmDependsJavaParser.cxx"
break;
case 343: /* AssignmentOperator: jp_GTGTEQUALS */
-#line 3129 "cmDependsJavaParser.y"
+#line 3128 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6267,11 +6266,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6271 "cmDependsJavaParser.cxx"
+#line 6270 "cmDependsJavaParser.cxx"
break;
case 344: /* AssignmentOperator: jp_GTGTGTEQUALS */
-#line 3138 "cmDependsJavaParser.y"
+#line 3137 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6279,11 +6278,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6283 "cmDependsJavaParser.cxx"
+#line 6282 "cmDependsJavaParser.cxx"
break;
case 345: /* AssignmentOperator: jp_ANDEQUALS */
-#line 3147 "cmDependsJavaParser.y"
+#line 3146 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6291,11 +6290,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6295 "cmDependsJavaParser.cxx"
+#line 6294 "cmDependsJavaParser.cxx"
break;
case 346: /* AssignmentOperator: jp_CARROTEQUALS */
-#line 3156 "cmDependsJavaParser.y"
+#line 3155 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6303,11 +6302,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6307 "cmDependsJavaParser.cxx"
+#line 6306 "cmDependsJavaParser.cxx"
break;
case 347: /* AssignmentOperator: jp_PIPEEQUALS */
-#line 3165 "cmDependsJavaParser.y"
+#line 3164 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6315,11 +6314,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6319 "cmDependsJavaParser.cxx"
+#line 6318 "cmDependsJavaParser.cxx"
break;
case 348: /* Expression: AssignmentExpression */
-#line 3175 "cmDependsJavaParser.y"
+#line 3174 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6327,11 +6326,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6331 "cmDependsJavaParser.cxx"
+#line 6330 "cmDependsJavaParser.cxx"
break;
case 349: /* ConstantExpression: Expression */
-#line 3185 "cmDependsJavaParser.y"
+#line 3184 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6339,11 +6338,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6343 "cmDependsJavaParser.cxx"
+#line 6342 "cmDependsJavaParser.cxx"
break;
case 350: /* New: jp_NEW */
-#line 3195 "cmDependsJavaParser.y"
+#line 3194 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6351,11 +6350,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6355 "cmDependsJavaParser.cxx"
+#line 6354 "cmDependsJavaParser.cxx"
break;
case 351: /* New: Name jp_DOT jp_NEW */
-#line 3204 "cmDependsJavaParser.y"
+#line 3203 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -6364,11 +6363,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6368 "cmDependsJavaParser.cxx"
+#line 6367 "cmDependsJavaParser.cxx"
break;
-#line 6372 "cmDependsJavaParser.cxx"
+#line 6371 "cmDependsJavaParser.cxx"
default: break;
}
@@ -6592,7 +6591,7 @@ yyreturnlab:
return yyresult;
}
-#line 3213 "cmDependsJavaParser.y"
+#line 3212 "cmDependsJavaParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmDependsJavaParser.y b/Source/LexerParser/cmDependsJavaParser.y
index ff37af2..d64043a 100644
--- a/Source/LexerParser/cmDependsJavaParser.y
+++ b/Source/LexerParser/cmDependsJavaParser.y
@@ -13,7 +13,6 @@ Run bison like this:
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <string>
diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx
index cb5e498..80c0abd 100644
--- a/Source/LexerParser/cmExprParser.cxx
+++ b/Source/LexerParser/cmExprParser.cxx
@@ -88,7 +88,6 @@ Run bison like this:
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdexcept>
@@ -127,7 +126,7 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma diag_suppress 550 /* variable set but never used */
#endif
-#line 131 "cmExprParser.cxx"
+#line 130 "cmExprParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -569,9 +568,9 @@ static const yytype_int8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 88, 88, 93, 96, 101, 104, 109, 112, 117,
- 120, 123, 128, 131, 134, 139, 142, 145, 151, 156,
- 159, 162, 165, 170, 173
+ 0, 87, 87, 92, 95, 100, 103, 108, 111, 116,
+ 119, 122, 127, 130, 133, 138, 141, 144, 150, 155,
+ 158, 161, 164, 169, 172
};
#endif
@@ -1432,194 +1431,194 @@ yyreduce:
switch (yyn)
{
case 2: /* start: exp */
-#line 88 "cmExprParser.y"
+#line 87 "cmExprParser.y"
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
-#line 1440 "cmExprParser.cxx"
+#line 1439 "cmExprParser.cxx"
break;
case 3: /* exp: bitwiseor */
-#line 93 "cmExprParser.y"
+#line 92 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1448 "cmExprParser.cxx"
+#line 1447 "cmExprParser.cxx"
break;
case 4: /* exp: exp exp_OR bitwiseor */
-#line 96 "cmExprParser.y"
+#line 95 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
-#line 1456 "cmExprParser.cxx"
+#line 1455 "cmExprParser.cxx"
break;
case 5: /* bitwiseor: bitwisexor */
-#line 101 "cmExprParser.y"
+#line 100 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1464 "cmExprParser.cxx"
+#line 1463 "cmExprParser.cxx"
break;
case 6: /* bitwiseor: bitwiseor exp_XOR bitwisexor */
-#line 104 "cmExprParser.y"
+#line 103 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
-#line 1472 "cmExprParser.cxx"
+#line 1471 "cmExprParser.cxx"
break;
case 7: /* bitwisexor: bitwiseand */
-#line 109 "cmExprParser.y"
+#line 108 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1480 "cmExprParser.cxx"
+#line 1479 "cmExprParser.cxx"
break;
case 8: /* bitwisexor: bitwisexor exp_AND bitwiseand */
-#line 112 "cmExprParser.y"
+#line 111 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
-#line 1488 "cmExprParser.cxx"
+#line 1487 "cmExprParser.cxx"
break;
case 9: /* bitwiseand: shift */
-#line 117 "cmExprParser.y"
+#line 116 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1496 "cmExprParser.cxx"
+#line 1495 "cmExprParser.cxx"
break;
case 10: /* bitwiseand: bitwiseand exp_SHIFTLEFT shift */
-#line 120 "cmExprParser.y"
+#line 119 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
-#line 1504 "cmExprParser.cxx"
+#line 1503 "cmExprParser.cxx"
break;
case 11: /* bitwiseand: bitwiseand exp_SHIFTRIGHT shift */
-#line 123 "cmExprParser.y"
+#line 122 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
-#line 1512 "cmExprParser.cxx"
+#line 1511 "cmExprParser.cxx"
break;
case 12: /* shift: term */
-#line 128 "cmExprParser.y"
+#line 127 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1520 "cmExprParser.cxx"
+#line 1519 "cmExprParser.cxx"
break;
case 13: /* shift: shift exp_PLUS term */
-#line 131 "cmExprParser.y"
+#line 130 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
-#line 1528 "cmExprParser.cxx"
+#line 1527 "cmExprParser.cxx"
break;
case 14: /* shift: shift exp_MINUS term */
-#line 134 "cmExprParser.y"
+#line 133 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
-#line 1536 "cmExprParser.cxx"
+#line 1535 "cmExprParser.cxx"
break;
case 15: /* term: unary */
-#line 139 "cmExprParser.y"
+#line 138 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1544 "cmExprParser.cxx"
+#line 1543 "cmExprParser.cxx"
break;
case 16: /* term: term exp_TIMES unary */
-#line 142 "cmExprParser.y"
+#line 141 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
-#line 1552 "cmExprParser.cxx"
+#line 1551 "cmExprParser.cxx"
break;
case 17: /* term: term exp_DIVIDE unary */
-#line 145 "cmExprParser.y"
+#line 144 "cmExprParser.y"
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
-#line 1563 "cmExprParser.cxx"
+#line 1562 "cmExprParser.cxx"
break;
case 18: /* term: term exp_MOD unary */
-#line 151 "cmExprParser.y"
+#line 150 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
-#line 1571 "cmExprParser.cxx"
+#line 1570 "cmExprParser.cxx"
break;
case 19: /* unary: factor */
-#line 156 "cmExprParser.y"
+#line 155 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1579 "cmExprParser.cxx"
+#line 1578 "cmExprParser.cxx"
break;
case 20: /* unary: exp_PLUS unary */
-#line 159 "cmExprParser.y"
+#line 158 "cmExprParser.y"
{
(yyval.Number) = + (yyvsp[0].Number);
}
-#line 1587 "cmExprParser.cxx"
+#line 1586 "cmExprParser.cxx"
break;
case 21: /* unary: exp_MINUS unary */
-#line 162 "cmExprParser.y"
+#line 161 "cmExprParser.y"
{
(yyval.Number) = - (yyvsp[0].Number);
}
-#line 1595 "cmExprParser.cxx"
+#line 1594 "cmExprParser.cxx"
break;
case 22: /* unary: exp_NOT unary */
-#line 165 "cmExprParser.y"
+#line 164 "cmExprParser.y"
{
(yyval.Number) = ~ (yyvsp[0].Number);
}
-#line 1603 "cmExprParser.cxx"
+#line 1602 "cmExprParser.cxx"
break;
case 23: /* factor: exp_NUMBER */
-#line 170 "cmExprParser.y"
+#line 169 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1611 "cmExprParser.cxx"
+#line 1610 "cmExprParser.cxx"
break;
case 24: /* factor: exp_OPENPARENT exp exp_CLOSEPARENT */
-#line 173 "cmExprParser.y"
+#line 172 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-1].Number);
}
-#line 1619 "cmExprParser.cxx"
+#line 1618 "cmExprParser.cxx"
break;
-#line 1623 "cmExprParser.cxx"
+#line 1622 "cmExprParser.cxx"
default: break;
}
@@ -1843,7 +1842,7 @@ yyreturnlab:
return yyresult;
}
-#line 178 "cmExprParser.y"
+#line 177 "cmExprParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmExprParser.y b/Source/LexerParser/cmExprParser.y
index 1c959f6..51df56e 100644
--- a/Source/LexerParser/cmExprParser.y
+++ b/Source/LexerParser/cmExprParser.y
@@ -13,7 +13,6 @@ Run bison like this:
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdexcept>
diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx
index e588853..ca5577e 100644
--- a/Source/LexerParser/cmGccDepfileLexer.cxx
+++ b/Source/LexerParser/cmGccDepfileLexer.cxx
@@ -256,7 +256,6 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -421,7 +420,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -498,7 +497,7 @@ static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
void *yyalloc ( yy_size_t , yyscan_t yyscanner );
void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
@@ -545,7 +544,7 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (yy_size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
@@ -674,8 +673,8 @@ struct yyguts_t
size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
- yy_size_t yy_n_chars;
- yy_size_t yyleng_r;
+ int yy_n_chars;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -722,7 +721,7 @@ FILE *yyget_out ( yyscan_t yyscanner );
void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
- yy_size_t yyget_leng ( yyscan_t yyscanner );
+ int yyget_leng ( yyscan_t yyscanner );
char *yyget_text ( yyscan_t yyscanner );
@@ -795,7 +794,7 @@ static int input ( yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- yy_size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -1241,7 +1240,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1255,7 +1254,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -1313,7 +1312,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
@@ -1406,7 +1405,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- yy_size_t number_to_move = yyg->yy_n_chars + 2;
+ int number_to_move = yyg->yy_n_chars + 2;
char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
char *source =
@@ -1458,7 +1457,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1836,12 +1835,12 @@ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = (yy_size_t) (_yybytes_len + 2);
@@ -1885,7 +1884,7 @@ static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
do \
{ \
/* Undo effects of setting up yytext. */ \
- yy_size_t yyless_macro_arg = (n); \
+ int yyless_macro_arg = (n); \
YY_LESS_LINENO(yyless_macro_arg);\
yytext[yyleng] = yyg->yy_hold_char; \
yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
@@ -1953,7 +1952,7 @@ FILE *yyget_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t yyget_leng (yyscan_t yyscanner)
+int yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
diff --git a/Source/LexerParser/cmGccDepfileLexer.h b/Source/LexerParser/cmGccDepfileLexer.h
index ab73ebc..7d34060 100644
--- a/Source/LexerParser/cmGccDepfileLexer.h
+++ b/Source/LexerParser/cmGccDepfileLexer.h
@@ -258,7 +258,6 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -372,7 +371,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -416,7 +415,7 @@ void yypop_buffer_state ( yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
void *yyalloc ( yy_size_t , yyscan_t yyscanner );
void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
@@ -463,7 +462,7 @@ FILE *yyget_out ( yyscan_t yyscanner );
void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
- yy_size_t yyget_leng ( yyscan_t yyscanner );
+ int yyget_leng ( yyscan_t yyscanner );
char *yyget_text ( yyscan_t yyscanner );
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index b1398db..b1589ff 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -19,6 +19,7 @@
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmValue.h"
bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -39,6 +40,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
std::string working;
std::string depfile;
std::string job_pool;
+ std::string job_server_aware;
std::string comment_buffer;
const char* comment = nullptr;
std::vector<std::string> depends;
@@ -78,6 +80,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
doing_working_directory,
doing_depfile,
doing_job_pool,
+ doing_job_server_aware,
doing_nothing
};
@@ -95,6 +98,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
MAKE_STATIC_KEYWORD(DEPFILE);
MAKE_STATIC_KEYWORD(IMPLICIT_DEPENDS);
MAKE_STATIC_KEYWORD(JOB_POOL);
+ MAKE_STATIC_KEYWORD(JOB_SERVER_AWARE);
MAKE_STATIC_KEYWORD(MAIN_DEPENDENCY);
MAKE_STATIC_KEYWORD(OUTPUT);
MAKE_STATIC_KEYWORD(OUTPUTS);
@@ -126,6 +130,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
keyPRE_BUILD,
keyPRE_LINK,
keySOURCE,
+ keyJOB_SERVER_AWARE,
keyTARGET,
keyUSES_TERMINAL,
keyVERBATIM,
@@ -190,6 +195,8 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
}
} else if (copy == keyJOB_POOL) {
doing = doing_job_pool;
+ } else if (copy == keyJOB_SERVER_AWARE) {
+ doing = doing_job_server_aware;
}
} else {
std::string filename;
@@ -226,6 +233,9 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
case doing_job_pool:
job_pool = copy;
break;
+ case doing_job_server_aware:
+ job_server_aware = copy;
+ break;
case doing_working_directory:
working = copy;
break;
@@ -334,6 +344,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
cc->SetUsesTerminal(uses_terminal);
cc->SetDepfile(depfile);
cc->SetJobPool(job_pool);
+ cc->SetJobserverAware(cmIsOn(job_server_aware));
cc->SetCommandExpandLists(command_expand_lists);
cc->SetDependsExplicitOnly(depends_explicit_only);
if (source.empty() && output.empty()) {
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index a246d06..711eaa5 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -17,6 +17,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmValue.h"
bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -54,6 +55,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
const char* comment = nullptr;
std::vector<std::string> sources;
std::string job_pool;
+ std::string job_server_aware;
// Keep track of parser state.
enum tdoing
@@ -65,6 +67,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
doing_comment,
doing_source,
doing_job_pool,
+ doing_job_server_aware,
doing_nothing
};
tdoing doing = doing_command;
@@ -102,6 +105,8 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
doing = doing_comment;
} else if (copy == "JOB_POOL") {
doing = doing_job_pool;
+ } else if (copy == "JOB_SERVER_AWARE") {
+ doing = doing_job_server_aware;
} else if (copy == "COMMAND") {
doing = doing_command;
@@ -148,6 +153,9 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
case doing_job_pool:
job_pool = copy;
break;
+ case doing_job_server_aware:
+ job_server_aware = copy;
+ break;
default:
status.SetError("Wrong syntax. Unknown type of argument.");
return false;
@@ -223,6 +231,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
cc->SetUsesTerminal(uses_terminal);
cc->SetCommandExpandLists(command_expand_lists);
cc->SetJobPool(job_pool);
+ cc->SetJobserverAware(cmIsOn(job_server_aware));
cmTarget* target =
mf.AddUtilityCommand(targetName, excludeFromAll, std::move(cc));
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index fdf54fb..b35d7f3 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -7,6 +7,7 @@
#include <cassert>
#include <cstddef>
#include <functional>
+#include <iterator>
#include <map>
#include <string>
#include <utility>
@@ -176,6 +177,17 @@ public:
void Bind(MaybeEmpty<std::vector<std::string>>& val);
void Bind(NonEmpty<std::vector<std::string>>& val);
void Bind(std::vector<std::vector<std::string>>& val);
+ template <typename U>
+ void Bind(NonEmpty<std::vector<std::pair<std::string, U>>>& val,
+ U const& context)
+ {
+ this->Bind(
+ [&val, &context](cm::string_view arg) -> Continue {
+ val.emplace_back(std::string(arg), context);
+ return Continue::Yes;
+ },
+ ExpectAtLeast{ 1 });
+ }
// cm::optional<> records the presence the keyword to which it binds.
template <typename T>
@@ -187,6 +199,15 @@ public:
this->Bind(*optVal);
}
+ template <typename T, typename U>
+ void Bind(cm::optional<T>& optVal, U const& context)
+ {
+ if (!optVal) {
+ optVal.emplace();
+ }
+ this->Bind(*optVal, context);
+ }
+
template <typename Range>
void Parse(Range const& args, std::size_t pos = 0)
{
@@ -232,6 +253,17 @@ public:
return *this;
}
+ template <typename T, typename U>
+ cmArgumentParser& BindWithContext(cm::static_string_view name,
+ T Result::*member, U Result::*context)
+ {
+ this->Base::Bind(name, [member, context](Instance& instance) {
+ auto* result = static_cast<Result*>(instance.Result);
+ instance.Bind(result->*member, result->*context);
+ });
+ return *this;
+ }
+
cmArgumentParser& Bind(cm::static_string_view name,
Continue (Result::*member)(cm::string_view),
ExpectAtLeast expect = { 1 })
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 35f4c88..b2e3cad 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -11,6 +11,7 @@
#include "cmsys/Directory.hxx"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
@@ -67,7 +68,7 @@ bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
if (!sourceListValue.empty()) {
sourceListValue += ";";
}
- sourceListValue += cmJoin(files, ";");
+ sourceListValue += cmList::to_string(files);
mf.AddDefinition(args[1], sourceListValue);
return true;
}
diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
index 566e4a4..8043f82 100644
--- a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
@@ -10,6 +10,7 @@
#include "cmRuntimeDependencyArchive.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::
cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool(
@@ -35,7 +36,7 @@ bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
builder.AddCommand(command);
auto process = builder.Start();
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
std::ostringstream e;
e << "Failed to start objdump process for:\n " << file;
this->SetError(e.str());
@@ -46,7 +47,8 @@ bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
static const cmsys::RegularExpression neededRegex("^ *NEEDED *([^\n]*)$");
static const cmsys::RegularExpression rpathRegex("^ *RPATH *([^\n]*)$");
static const cmsys::RegularExpression runpathRegex("^ *RUNPATH *([^\n]*)$");
- while (std::getline(*process.OutputStream(), line)) {
+ cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
+ while (std::getline(output, line)) {
cmsys::RegularExpressionMatch match;
if (neededRegex.find(line.c_str(), match)) {
needed.push_back(match.match(1));
@@ -73,8 +75,7 @@ bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
this->SetError(e.str());
return false;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
+ if (process.GetStatus(0).ExitStatus != 0) {
std::ostringstream e;
e << "Failed to run objdump on:\n " << file;
this->SetError(e.str());
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index c064377..90e0891 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -5,7 +5,6 @@
#include <sstream>
#include <string>
-#include <type_traits>
#include <utility>
#include <vector>
diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
index 6d97720..4c35841 100644
--- a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
@@ -9,6 +9,7 @@
#include "cmRuntimeDependencyArchive.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::
cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool(
@@ -34,7 +35,7 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
.AddCommand(command);
auto process = builder.Start();
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
std::ostringstream e;
e << "Failed to start otool process for:\n " << file;
this->SetError(e.str());
@@ -49,11 +50,12 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
"^ *path (.*) \\(offset [0-9]+\\)$");
static const cmsys::RegularExpression nameRegex(
"^ *name (.*) \\(offset [0-9]+\\)$");
- while (std::getline(*process.OutputStream(), line)) {
+ cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
+ while (std::getline(output, line)) {
cmsys::RegularExpressionMatch cmdMatch;
if (rpathRegex.find(line.c_str(), cmdMatch)) {
- if (!std::getline(*process.OutputStream(), line) ||
- !std::getline(*process.OutputStream(), line)) {
+ // NOLINTNEXTLINE(misc-redundant-expression)
+ if (!std::getline(output, line) || !std::getline(output, line)) {
this->SetError("Invalid output from otool");
return false;
}
@@ -66,8 +68,8 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
return false;
}
} else if (loadDylibRegex.find(line.c_str(), cmdMatch)) {
- if (!std::getline(*process.OutputStream(), line) ||
- !std::getline(*process.OutputStream(), line)) {
+ // NOLINTNEXTLINE(misc-redundant-expression)
+ if (!std::getline(output, line) || !std::getline(output, line)) {
this->SetError("Invalid output from otool");
return false;
}
@@ -88,8 +90,7 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
this->SetError(e.str());
return false;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
+ if (process.GetStatus(0).ExitStatus != 0) {
std::ostringstream e;
e << "Failed to run otool on:\n " << file;
this->SetError(e.str());
diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
index f342884..cd21140 100644
--- a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
@@ -9,6 +9,7 @@
#include "cmRuntimeDependencyArchive.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::
cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool(
@@ -33,7 +34,7 @@ bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo(
builder.AddCommand(command);
auto process = builder.Start();
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
std::ostringstream e;
e << "Failed to start dumpbin process for:\n " << file;
this->SetError(e.str());
@@ -43,7 +44,8 @@ bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo(
std::string line;
static const cmsys::RegularExpression regex(
"^ ([^\n]*\\.[Dd][Ll][Ll])\r$");
- while (std::getline(*process.OutputStream(), line)) {
+ cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
+ while (std::getline(output, line)) {
cmsys::RegularExpressionMatch match;
if (regex.find(line.c_str(), match)) {
needed.push_back(match.match(1));
@@ -56,8 +58,7 @@ bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo(
this->SetError(e.str());
return false;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
+ if (process.GetStatus(0).ExitStatus != 0) {
std::ostringstream e;
e << "Failed to run dumpbin on:\n " << file;
this->SetError(e.str());
diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
index f14de55..d95da95 100644
--- a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
@@ -10,6 +10,7 @@
#include "cmRuntimeDependencyArchive.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool(
@@ -34,7 +35,7 @@ bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo(
builder.AddCommand(command);
auto process = builder.Start();
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
std::ostringstream e;
e << "Failed to start objdump process for:\n " << file;
this->SetError(e.str());
@@ -44,7 +45,8 @@ bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo(
std::string line;
static const cmsys::RegularExpression regex(
"^\t*DLL Name: ([^\n]*\\.[Dd][Ll][Ll])$");
- while (cmSystemTools::GetLineFromStream(*process.OutputStream(), line)) {
+ cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
+ while (cmSystemTools::GetLineFromStream(output, line)) {
cmsys::RegularExpressionMatch match;
if (regex.find(line.c_str(), match)) {
needed.push_back(match.match(1));
@@ -57,8 +59,7 @@ bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo(
this->SetError(e.str());
return false;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
+ if (process.GetStatus(0).ExitStatus != 0) {
std::ostringstream e;
e << "Failed to run objdump on:\n " << file;
this->SetError(e.str());
diff --git a/Source/cmBlockCommand.cxx b/Source/cmBlockCommand.cxx
index ec79149..42f1ad3 100644
--- a/Source/cmBlockCommand.cxx
+++ b/Source/cmBlockCommand.cxx
@@ -3,7 +3,8 @@
#include "cmBlockCommand.h"
-#include <cstdint> // IWYU pragma: keep
+#include <cstdint>
+#include <initializer_list>
#include <utility>
#include <cm/memory>
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 1c00f15..0efb9a4 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -5,6 +5,7 @@
#include <algorithm>
#include <cassert>
#include <cctype>
+#include <cstddef>
#include <initializer_list>
#include <map>
#include <string>
@@ -34,7 +35,6 @@
# include "cmGlobalVisualStudio10Generator.h"
# include "cmGlobalVisualStudioVersionedGenerator.h"
# include "cmVSSetupHelper.h"
-# define HAVE_VS_SETUP_HELPER
#endif
namespace {
@@ -377,9 +377,9 @@ std::map<std::string, std::string> GetOSReleaseVariables(
return data;
}
-cm::optional<std::string> GetValue(cmExecutionStatus& status,
- std::string const& key,
- std::string const& variable)
+cm::optional<std::string> GetDistribValue(cmExecutionStatus& status,
+ std::string const& key,
+ std::string const& variable)
{
const auto prefix = "DISTRIB_"_s;
if (!cmHasPrefix(key, prefix)) {
@@ -413,9 +413,89 @@ cm::optional<std::string> GetValue(cmExecutionStatus& status,
return std::string{};
}
-#ifdef HAVE_VS_SETUP_HELPER
-cm::optional<std::string> GetValue(cmExecutionStatus& status,
- std::string const& key)
+#ifdef _WIN32
+std::string FindMSYSTEM_PREFIX(std::vector<std::string> prefixes)
+{
+ for (std::string const& prefix : prefixes) {
+ std::string out;
+ std::string err;
+ int ret;
+ // In a modern MSYSTEM environment we expect cygpath to be in PATH.
+ std::vector<std::string> cygpath_cmd{ "cygpath", "-w", prefix };
+ if (cmSystemTools::RunSingleCommand(cygpath_cmd, &out, &err, &ret, nullptr,
+ cmSystemTools::OUTPUT_NONE)) {
+ if (ret == 0) {
+ out = cmTrimWhitespace(out);
+ cmSystemTools::ConvertToUnixSlashes(out);
+ if (cmSystemTools::FileIsDirectory(out)) {
+ return out;
+ }
+ }
+ } else {
+ // In a legacy MSYSTEM environment (MinGW/MSYS 1.0) there is no
+ // cygpath but we expect 'sh' to be in PATH.
+ std::vector<std::string> sh_cmd{
+ "sh", "-c", cmStrCat("cd \"", prefix, "\" && cmd //c cd")
+ };
+ if (cmSystemTools::RunSingleCommand(sh_cmd, &out, &err, &ret, nullptr,
+ cmSystemTools::OUTPUT_NONE)) {
+ if (ret == 0) {
+ out = cmTrimWhitespace(out);
+ cmSystemTools::ConvertToUnixSlashes(out);
+ if (cmSystemTools::FileIsDirectory(out)) {
+ return out;
+ }
+ }
+ }
+ }
+ }
+ return {};
+}
+
+std::string FallbackMSYSTEM_PREFIX(cm::string_view msystem)
+{
+ // These layouts are used by distributions such as
+ // * MSYS2: https://www.msys2.org/docs/environments/
+ // * MinGW/MSYS 1.0: http://mingw.osdn.io/
+ if (msystem == "MSYS"_s) {
+ static std::string const msystem_msys = FindMSYSTEM_PREFIX({ "/usr" });
+ return msystem_msys;
+ }
+ if (msystem == "MINGW32"_s) {
+ static std::string const msystem_mingw32 =
+ FindMSYSTEM_PREFIX({ "/mingw32", "/mingw" });
+ return msystem_mingw32;
+ }
+ if (msystem == "MINGW64"_s) {
+ static std::string const msystem_mingw64 =
+ FindMSYSTEM_PREFIX({ "/mingw64" });
+ return msystem_mingw64;
+ }
+ if (msystem == "UCRT64"_s) {
+ static std::string const msystem_ucrt64 =
+ FindMSYSTEM_PREFIX({ "/ucrt64" });
+ return msystem_ucrt64;
+ }
+ if (msystem == "CLANG32"_s) {
+ static std::string const msystem_clang32 =
+ FindMSYSTEM_PREFIX({ "/clang32" });
+ return msystem_clang32;
+ }
+ if (msystem == "CLANG64"_s) {
+ static std::string const msystem_clang64 =
+ FindMSYSTEM_PREFIX({ "/clang64" });
+ return msystem_clang64;
+ }
+ if (msystem == "CLANGARM64"_s) {
+ static std::string const msystem_clangarm64 =
+ FindMSYSTEM_PREFIX({ "/clangarm64" });
+ return msystem_clangarm64;
+ }
+ return {};
+}
+
+cm::optional<std::string> GetWindowsValue(cmExecutionStatus& status,
+ std::string const& key)
{
auto* const gg = status.GetMakefile().GetGlobalGenerator();
for (auto vs : { 15, 16, 17 }) {
@@ -446,6 +526,23 @@ cm::optional<std::string> GetValue(cmExecutionStatus& status,
return vs10gen->FindMSBuildCommandEarly(&status.GetMakefile());
}
+ if (key == "MSYSTEM_PREFIX") {
+ // MSYSTEM_PREFIX is meaningful only under a MSYSTEM environment.
+ cm::optional<std::string> ms = cmSystemTools::GetEnvVar("MSYSTEM");
+ if (!ms || ms->empty()) {
+ return std::string();
+ }
+ // Prefer the MSYSTEM_PREFIX environment variable.
+ if (cm::optional<std::string> msp =
+ cmSystemTools::GetEnvVar("MSYSTEM_PREFIX")) {
+ cmSystemTools::ConvertToUnixSlashes(*msp);
+ if (cmSystemTools::FileIsDirectory(*msp)) {
+ return msp;
+ }
+ }
+ // Fall back to known distribution layouts.
+ return FallbackMSYSTEM_PREFIX(*ms);
+ }
return {};
}
#endif
@@ -529,12 +626,12 @@ bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
if (arguments.ValueNames) {
auto result = registry.GetValueNames(key, view);
if (result) {
- makefile.AddDefinition(variable, cmJoin(*result, ";"_s));
+ makefile.AddDefinition(variable, cmList::to_string(*result));
}
} else if (arguments.SubKeys) {
auto result = registry.GetSubKeys(key, view);
if (result) {
- makefile.AddDefinition(variable, cmJoin(*result, ";"_s));
+ makefile.AddDefinition(variable, cmList::to_string(*result));
}
} else {
auto result =
@@ -597,9 +694,9 @@ bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
auto value =
GetValueChained(
[&]() { return GetValue(info, key); }
- , [&]() { return GetValue(status, key, variable); }
-#ifdef HAVE_VS_SETUP_HELPER
- , [&]() { return GetValue(status, key); }
+ , [&]() { return GetDistribValue(status, key, variable); }
+#ifdef _WIN32
+ , [&]() { return GetWindowsValue(status, key); }
#endif
);
// clang-format on
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index c7e9209..329427c 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <array>
#include <cstddef>
-#include <memory>
#include <string>
#include <utility>
@@ -17,10 +16,11 @@
#include "cmArgumentParserTypes.h"
#include "cmDependencyProvider.h"
#include "cmExecutionStatus.h"
+#include "cmExperimental.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -328,6 +328,46 @@ bool cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(
makefile.AddDefinition(outputVariable, outputValue);
return true;
}
+
+bool cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED(
+ std::vector<cmListFileArgument> const& args, cmExecutionStatus& status)
+{
+ cmMakefile& makefile = status.GetMakefile();
+ std::vector<std::string> expandedArgs;
+ makefile.ExpandArguments(args, expandedArgs);
+
+ if (expandedArgs.size() != 3) {
+ return FatalError(status,
+ "sub-command GET_EXPERIMENTAL_FEATURE_ENABLED expects "
+ "exactly two arguments");
+ }
+
+ auto const& featureName = expandedArgs[1];
+ auto const& variableName = expandedArgs[2];
+
+ auto feature = cmExperimental::Feature::Sentinel;
+ for (std::size_t i = 0;
+ i < static_cast<std::size_t>(cmExperimental::Feature::Sentinel); i++) {
+ if (cmExperimental::DataForFeature(static_cast<cmExperimental::Feature>(i))
+ .Name == featureName) {
+ feature = static_cast<cmExperimental::Feature>(i);
+ break;
+ }
+ }
+ if (feature == cmExperimental::Feature::Sentinel) {
+ return FatalError(status,
+ cmStrCat("Experimental feature name \"", featureName,
+ "\" does not exist."));
+ }
+
+ if (cmExperimental::HasSupportEnabled(makefile, feature)) {
+ makefile.AddDefinition(variableName, "TRUE");
+ } else {
+ makefile.AddDefinition(variableName, "FALSE");
+ }
+
+ return true;
+}
}
bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
@@ -480,5 +520,10 @@ bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
return cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(args, status);
}
+ if (expArgs[expArg] == "GET_EXPERIMENTAL_FEATURE_ENABLED") {
+ return cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED(args,
+ status);
+ }
+
return FatalError(status, "called with unknown meta-operation");
}
diff --git a/Source/cmCMakePath.cxx b/Source/cmCMakePath.cxx
index 73321c6..5080f58 100644
--- a/Source/cmCMakePath.cxx
+++ b/Source/cmCMakePath.cxx
@@ -15,6 +15,8 @@
#include <cm/string_view>
#if defined(_WIN32)
+# include <cmext/string_view>
+
# include "cmStringAlgorithms.h"
#endif
diff --git a/Source/cmCMakePath.h b/Source/cmCMakePath.h
index 15aa30c..a42ac98 100644
--- a/Source/cmCMakePath.h
+++ b/Source/cmCMakePath.h
@@ -12,7 +12,10 @@
#include <cm/filesystem>
#include <cm/string_view>
#include <cm/type_traits>
-#include <cmext/string_view>
+
+namespace cm {
+class static_string_view;
+}
namespace detail {
#if defined(__SUNPRO_CC) && defined(__sparc)
@@ -123,11 +126,29 @@ public:
: Path(FormatPath(source, fmt))
{
}
+ cmCMakePath(const char* source, format fmt = generic_format) noexcept
+ : Path(FormatPath(cm::string_view{ source }, fmt))
+ {
+ }
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath(const std::string& source, format fmt = generic_format)
+ : Path(FormatPath(source, fmt))
+ {
+ }
+ cmCMakePath(std::string&& source, format fmt = generic_format)
+ : Path(FormatPath(std::move(source), fmt))
+ {
+ }
+#else
template <typename Source, typename = enable_if_move_pathable<Source>>
cmCMakePath(Source source, format fmt = generic_format)
: Path(FormatPath(std::move(source), fmt))
{
}
+#endif
template <typename Source, typename = enable_if_move_pathable<Source>>
cmCMakePath& Assign(Source&& source)
@@ -156,6 +177,41 @@ public:
}
return *this;
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath& operator=(cm::filesystem::path&& source)
+ {
+ this->Assign(std::forward<cm::filesystem::path>(source));
+ return *this;
+ }
+ cmCMakePath& operator=(std::string&& source)
+ {
+ this->Assign(std::forward<std::string>(source));
+ return *this;
+ }
+ cmCMakePath& operator=(const cm::filesystem::path& source)
+ {
+ this->Assign(source);
+ return *this;
+ }
+ cmCMakePath& operator=(const std::string& source)
+ {
+ this->Assign(source);
+ return *this;
+ }
+ cmCMakePath& operator=(const cm::string_view source)
+ {
+ this->Assign(source);
+ return *this;
+ }
+ cmCMakePath& operator=(const char* source)
+ {
+ this->Assign(cm::string_view{ source });
+ return *this;
+ }
+#else
template <typename Source, typename = enable_if_move_pathable<Source>>
cmCMakePath& operator=(Source&& source)
{
@@ -168,6 +224,7 @@ public:
this->Assign(source);
return *this;
}
+#endif
// Concatenation
cmCMakePath& Append(const cmCMakePath& path)
@@ -182,12 +239,29 @@ public:
this->Path = this->Path.generic_string();
return *this;
}
-
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath& Append(const std::string& source)
+ {
+ return this->Append(cm::filesystem::path(source));
+ }
+ cmCMakePath& Append(cm::string_view source)
+ {
+ return this->Append(cm::filesystem::path(source));
+ }
+ cmCMakePath& Append(const char* source)
+ {
+ return this->Append(cm::filesystem::path(cm::string_view{ source }));
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath& Append(const Source& source)
{
return this->Append(cm::filesystem::path(source));
}
+#endif
cmCMakePath& operator/=(const cmCMakePath& path)
{
@@ -204,17 +278,38 @@ public:
this->Path += path.Path;
return *this;
}
- cmCMakePath& Concat(cm::static_string_view source)
+ cmCMakePath& Concat(cm::string_view source)
{
- this->Path.concat(std::string(source));
+ this->Path.operator+=(std::string(source));
return *this;
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath& Concat(const cm::filesystem::path& source)
+ {
+ this->Path.operator+=(source);
+ return *this;
+ }
+ cmCMakePath& Concat(const std::string& source)
+ {
+ this->Path.operator+=(source);
+ return *this;
+ }
+ cmCMakePath& Concat(const char* source)
+ {
+ this->Path.operator+=(source);
+ return *this;
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath& Concat(const Source& source)
{
- this->Path.concat(source);
+ this->Path.operator+=(source);
return *this;
}
+#endif
cmCMakePath& operator+=(const cmCMakePath& path)
{
@@ -242,6 +337,32 @@ public:
}
return *this;
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath& ReplaceFileName(const cm::filesystem::path& filename)
+ {
+ if (this->Path.has_filename()) {
+ this->Path.replace_filename(filename);
+ }
+ return *this;
+ }
+ cmCMakePath& ReplaceFileName(const std::string& filename)
+ {
+ if (this->Path.has_filename()) {
+ this->Path.replace_filename(filename);
+ }
+ return *this;
+ }
+ cmCMakePath& ReplaceFileName(cm::string_view filename)
+ {
+ if (this->Path.has_filename()) {
+ this->Path.replace_filename(filename);
+ }
+ return *this;
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath& ReplaceFileName(const Source& filename)
{
@@ -250,18 +371,40 @@ public:
}
return *this;
}
+#endif
cmCMakePath& ReplaceExtension(const cmCMakePath& extension = cmCMakePath())
{
this->Path.replace_extension(extension.Path);
return *this;
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath& ReplaceExtension(const cm::filesystem::path& extension)
+ {
+ this->Path.replace_extension(extension);
+ return *this;
+ }
+ cmCMakePath& ReplaceExtension(const std::string& extension)
+ {
+ this->Path.replace_extension(extension);
+ return *this;
+ }
+ cmCMakePath& ReplaceExtension(const cm::string_view extension)
+ {
+ this->Path.replace_extension(extension);
+ return *this;
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath& ReplaceExtension(const Source& extension)
{
this->Path.replace_extension(extension);
return *this;
}
+#endif
cmCMakePath& ReplaceWideExtension(
const cmCMakePath& extension = cmCMakePath())
@@ -269,11 +412,26 @@ public:
return this->ReplaceWideExtension(
static_cast<cm::string_view>(extension.Path.string()));
}
+ cmCMakePath& ReplaceWideExtension(const cm::filesystem::path& extension)
+ {
+ return this->ReplaceWideExtension(
+ static_cast<cm::string_view>(extension.string()));
+ }
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath& ReplaceWideExtension(const std::string& extension)
+ {
+ return this->ReplaceWideExtension(cm::string_view{ extension });
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath& ReplaceWideExtension(const Source& extension)
{
- return this->ReplaceWideExtension(cm::string_view(extension));
+ return this->ReplaceWideExtension(extension);
}
+#endif
cmCMakePath& ReplaceWideExtension(cm::string_view extension);
cmCMakePath& RemoveExtension()
@@ -355,12 +513,25 @@ public:
// Windows) so convert back to '/'
return path.generic_string();
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath Relative(const std::string& base) const
+ {
+ return this->Relative(cm::filesystem::path(base));
+ }
+ cmCMakePath Relative(cm::string_view base) const
+ {
+ return this->Relative(cm::filesystem::path(base));
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath Relative(const Source& base) const
{
return this->Relative(cm::filesystem::path(base));
}
-
+#endif
cmCMakePath Proximate(const cmCMakePath& base) const
{
return this->Proximate(base.Path);
@@ -372,21 +543,49 @@ public:
// Windows) so convert back to '/'
return path.generic_string();
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath Proximate(const std::string& base) const
+ {
+ return this->Proximate(cm::filesystem::path(base));
+ }
+ cmCMakePath Proximate(cm::string_view base) const
+ {
+ return this->Proximate(cm::filesystem::path(base));
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath Proximate(const Source& base) const
{
return this->Proximate(cm::filesystem::path(base));
}
+#endif
cmCMakePath Absolute(const cmCMakePath& base) const
{
return this->Absolute(base.Path);
}
+#if defined(__SUNPRO_CC) && defined(__sparc)
+ // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when
+ // standard methods and templates use the same name. The template is selected
+ // rather than the standard one regardless the arguments of the method.
+ cmCMakePath Absolute(const std::string& base) const
+ {
+ return this->Absolute(cm::filesystem::path(base));
+ }
+ cmCMakePath Absolute(cm::string_view base) const
+ {
+ return this->Absolute(cm::filesystem::path(base));
+ }
+#else
template <typename Source, typename = enable_if_pathable<Source>>
cmCMakePath Absolute(const Source& base) const
{
return this->Absolute(cm::filesystem::path(base));
}
+#endif
cmCMakePath Absolute(const cm::filesystem::path& base) const;
// Comparison
diff --git a/Source/cmCMakePresetErrors.h b/Source/cmCMakePresetErrors.h
deleted file mode 100644
index 0db391e..0000000
--- a/Source/cmCMakePresetErrors.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <cm3p/json/value.h>
-
-#include "cmJSONHelpers.h"
-#include "cmJSONState.h"
-#include "cmStringAlgorithms.h"
-
-namespace cmCMakePresetErrors {
-const auto getPreset = [](cmJSONState* state) -> const Json::Value* {
- if (state->parseStack.size() < 2) {
- return nullptr;
- }
- std::string firstKey = state->parseStack[0].first;
- if (firstKey == "configurePresets" || firstKey == "packagePresets" ||
- firstKey == "buildPresets" || firstKey == "testPresets") {
- return state->parseStack[1].second;
- }
- return nullptr;
-};
-const auto getPresetName = [](cmJSONState* state) -> std::string {
-#if !defined(CMAKE_BOOTSTRAP)
- const Json::Value* preset = getPreset(state);
- if (preset != nullptr && preset->isMember("name")) {
- return preset->operator[]("name").asString();
- }
-#endif
- return "";
-};
-const auto getVariableName = [](cmJSONState* state) -> std::string {
- std::string var = state->key_after("cacheVariables");
- std::string errMsg = cmStrCat("variable \"", var, "\"");
- errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), "\"");
- return errMsg;
-};
-const auto FILE_NOT_FOUND = [](const std::string& filename,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("File not found: ", filename));
-};
-const auto INVALID_ROOT = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("Invalid root object", value);
-};
-const auto NO_VERSION = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("No \"version\" field", value);
-};
-const auto INVALID_VERSION = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("Invalid \"version\" field", value);
-};
-const auto UNRECOGNIZED_VERSION = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("Unrecognized \"version\" field", value);
-};
-const auto INVALID_PRESETS = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("Invalid \"configurePresets\" field", value);
-};
-const auto INVALID_PRESET = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("Invalid preset", value);
-};
-const auto INVALID_PRESET_NAMED = [](const std::string& presetName,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("Invalid preset: \"", presetName, "\""));
-};
-const auto INVALID_VARIABLE = [](const Json::Value* value,
- cmJSONState* state) -> void {
- std::string var = cmCMakePresetErrors::getVariableName(state);
- state->AddErrorAtValue(cmStrCat("Invalid CMake ", var), value);
-};
-const auto DUPLICATE_PRESETS = [](const std::string& presetName,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("Duplicate preset: \"", presetName, "\""));
-};
-const auto CYCLIC_PRESET_INHERITANCE = [](const std::string& presetName,
- cmJSONState* state) -> void {
- state->AddError(
- cmStrCat("Cyclic preset inheritance for preset \"", presetName, "\""));
-};
-const auto INHERITED_PRESET_UNREACHABLE_FROM_FILE =
- [](const std::string& presetName, cmJSONState* state) -> void {
- state->AddError(cmStrCat("Inherited preset \"", presetName,
- "\" is unreachable from preset's file"));
-};
-const auto CONFIGURE_PRESET_UNREACHABLE_FROM_FILE =
- [](const std::string& presetName, cmJSONState* state) -> void {
- state->AddError(cmStrCat("Configure preset \"", presetName,
- "\" is unreachable from preset's file"));
-};
-const auto INVALID_MACRO_EXPANSION = [](const std::string& presetName,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, "\""));
-};
-const auto BUILD_TEST_PRESETS_UNSUPPORTED = [](const Json::Value*,
- cmJSONState* state) -> void {
- state->AddError("File version must be 2 or higher for build and test preset "
- "support");
-};
-const auto PACKAGE_PRESETS_UNSUPPORTED = [](const Json::Value*,
- cmJSONState* state) -> void {
- state->AddError(
- "File version must be 6 or higher for package preset support");
-};
-const auto WORKFLOW_PRESETS_UNSUPPORTED = [](const Json::Value*,
- cmJSONState* state) -> void {
- state->AddError(
- "File version must be 6 or higher for workflow preset support");
-};
-const auto INCLUDE_UNSUPPORTED = [](const Json::Value*,
- cmJSONState* state) -> void {
- state->AddError("File version must be 4 or higher for include support");
-};
-const auto INVALID_INCLUDE = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue("Invalid \"include\" field", value);
-};
-const auto INVALID_CONFIGURE_PRESET = [](const std::string& presetName,
- cmJSONState* state) -> void {
- state->AddError(
- cmStrCat(R"(Invalid "configurePreset": ")", presetName, "\""));
-};
-const auto INSTALL_PREFIX_UNSUPPORTED = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue(
- "File version must be 3 or higher for installDir preset "
- "support",
- value);
-};
-const auto CONDITION_UNSUPPORTED = [](cmJSONState* state) -> void {
- state->AddError("File version must be 3 or higher for condition support");
-};
-const auto TOOLCHAIN_FILE_UNSUPPORTED = [](cmJSONState* state) -> void {
- state->AddError("File version must be 3 or higher for toolchainFile preset "
- "support");
-};
-const auto CYCLIC_INCLUDE = [](const std::string& file,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("Cyclic include among preset files: ", file));
-};
-const auto TEST_OUTPUT_TRUNCATION_UNSUPPORTED =
- [](cmJSONState* state) -> void {
- state->AddError("File version must be 5 or higher for testOutputTruncation "
- "preset support");
-};
-const auto INVALID_WORKFLOW_STEPS = [](const std::string& workflowStep,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, "\""));
-};
-const auto NO_WORKFLOW_STEPS = [](const std::string& presetName,
- cmJSONState* state) -> void {
- state->AddError(
- cmStrCat("No workflow steps specified for \"", presetName, "\""));
-};
-const auto FIRST_WORKFLOW_STEP_NOT_CONFIGURE = [](const std::string& stepName,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("First workflow step \"", stepName,
- "\" must be a configure step"));
-};
-const auto CONFIGURE_WORKFLOW_STEP_NOT_FIRST = [](const std::string& stepName,
- cmJSONState* state) -> void {
- state->AddError(cmStrCat("Configure workflow step \"", stepName,
- "\" must be the first step"));
-};
-const auto WORKFLOW_STEP_UNREACHABLE_FROM_FILE =
- [](const std::string& workflowStep, cmJSONState* state) -> void {
- state->AddError(cmStrCat("Workflow step \"", workflowStep,
- "\" is unreachable from preset's file"));
-};
-const auto CTEST_JUNIT_UNSUPPORTED = [](cmJSONState* state) -> void {
- state->AddError(
- "File version must be 6 or higher for CTest JUnit output support");
-};
-const auto TRACE_UNSUPPORTED = [](cmJSONState* state) -> void {
- state->AddError("File version must be 7 or higher for trace preset support");
-};
-const auto UNRECOGNIZED_CMAKE_VERSION = [](const std::string& version,
- int current, int required) {
- return [version, current, required](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue(cmStrCat("\"cmakeMinimumRequired\" ", version,
- " version ", required,
- " must be less than ", current),
- value);
- };
-};
-const auto INVALID_PRESET_NAME = [](const Json::Value* value,
- cmJSONState* state) -> void {
- std::string errMsg = "Invalid Preset Name";
- if (value && value->isConvertibleTo(Json::ValueType::stringValue) &&
- !value->asString().empty()) {
- errMsg = cmStrCat(errMsg, ": ", value->asString());
- }
- state->AddErrorAtValue(errMsg, value);
-};
-const auto INVALID_CONDITION = [](const Json::Value* value,
- cmJSONState* state) -> void {
- state->AddErrorAtValue(
- cmStrCat("Invalid condition for preset \"", getPresetName(state), "\""),
- value);
-};
-const auto INVALID_CONDITION_OBJECT =
- [](JsonErrors::ObjectError errorType,
- const Json::Value::Members& extraFields) {
- return JsonErrors::INVALID_NAMED_OBJECT(
- [](const Json::Value*, cmJSONState* state) -> std::string {
- return cmStrCat(" condition for preset \"", getPresetName(state),
- "\"");
- })(errorType, extraFields);
- };
-const auto INVALID_VARIABLE_OBJECT =
- [](JsonErrors::ObjectError errorType,
- const Json::Value::Members& extraFields) {
- return JsonErrors::INVALID_NAMED_OBJECT(
- [](const Json::Value*, cmJSONState* state) -> std::string {
- return getVariableName(state);
- })(errorType, extraFields);
- };
-const auto INVALID_PRESET_OBJECT =
- [](JsonErrors::ObjectError errorType,
- const Json::Value::Members& extraFields) {
- return JsonErrors::INVALID_NAMED_OBJECT(
- [](const Json::Value*, cmJSONState*) -> std::string {
- return "Preset";
- })(errorType, extraFields);
- };
-const auto INVALID_ROOT_OBJECT = [](JsonErrors::ObjectError errorType,
- const Json::Value::Members& extraFields) {
- return JsonErrors::INVALID_NAMED_OBJECT(
- [](const Json::Value*, cmJSONState*) -> std::string {
- return "root object";
- })(errorType, extraFields);
-};
-const auto PRESET_MISSING_FIELD = [](const std::string& presetName,
- const std::string& missingField,
- cmJSONState* state) {
- state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
- missingField, "\""));
-};
-}
diff --git a/Source/cmCMakePresetsErrors.cxx b/Source/cmCMakePresetsErrors.cxx
new file mode 100644
index 0000000..e0ff0c6
--- /dev/null
+++ b/Source/cmCMakePresetsErrors.cxx
@@ -0,0 +1,305 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmCMakePresetsErrors.h"
+
+#include <functional>
+#include <utility>
+#include <vector>
+
+#include <cm3p/json/value.h>
+
+#include "cmJSONHelpers.h"
+#include "cmJSONState.h"
+#include "cmStringAlgorithms.h"
+
+namespace cmCMakePresetsErrors {
+const Json::Value* getPreset(cmJSONState* state)
+{
+ if (state->parseStack.size() < 2) {
+ return nullptr;
+ }
+ std::string firstKey = state->parseStack[0].first;
+ if (firstKey == "configurePresets" || firstKey == "packagePresets" ||
+ firstKey == "buildPresets" || firstKey == "testPresets") {
+ return state->parseStack[1].second;
+ }
+ return nullptr;
+}
+
+std::string getPresetName(cmJSONState* state)
+{
+ const Json::Value* preset = getPreset(state);
+ if (preset != nullptr && preset->isMember("name")) {
+ return preset->operator[]("name").asString();
+ }
+ return "";
+}
+
+std::string getVariableName(cmJSONState* state)
+{
+ std::string var = state->key_after("cacheVariables");
+ std::string errMsg = cmStrCat("variable \"", var, "\"");
+ errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), "\"");
+ return errMsg;
+}
+
+void FILE_NOT_FOUND(const std::string& filename, cmJSONState* state)
+{
+ state->AddError(cmStrCat("File not found: ", filename));
+}
+
+void INVALID_ROOT(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("Invalid root object", value);
+}
+
+void NO_VERSION(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("No \"version\" field", value);
+}
+
+void INVALID_VERSION(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("Invalid \"version\" field", value);
+}
+
+void UNRECOGNIZED_VERSION(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("Unrecognized \"version\" field", value);
+}
+
+void INVALID_PRESETS(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("Invalid \"configurePresets\" field", value);
+}
+
+void INVALID_PRESET(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("Invalid preset", value);
+}
+
+void INVALID_PRESET_NAMED(const std::string& presetName, cmJSONState* state)
+{
+ state->AddError(cmStrCat("Invalid preset: \"", presetName, "\""));
+}
+
+void INVALID_VARIABLE(const Json::Value* value, cmJSONState* state)
+{
+ std::string var = cmCMakePresetsErrors::getVariableName(state);
+ state->AddErrorAtValue(cmStrCat("Invalid CMake ", var), value);
+}
+
+void DUPLICATE_PRESETS(const std::string& presetName, cmJSONState* state)
+{
+ state->AddError(cmStrCat("Duplicate preset: \"", presetName, "\""));
+}
+
+void CYCLIC_PRESET_INHERITANCE(const std::string& presetName,
+ cmJSONState* state)
+
+{
+ state->AddError(
+ cmStrCat("Cyclic preset inheritance for preset \"", presetName, "\""));
+}
+
+void INHERITED_PRESET_UNREACHABLE_FROM_FILE(const std::string& presetName,
+ cmJSONState* state)
+{
+ state->AddError(cmStrCat("Inherited preset \"", presetName,
+ "\" is unreachable from preset's file"));
+}
+
+void CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(const std::string& presetName,
+ cmJSONState* state)
+{
+ state->AddError(cmStrCat("Configure preset \"", presetName,
+ "\" is unreachable from preset's file"));
+}
+
+void INVALID_MACRO_EXPANSION(const std::string& presetName, cmJSONState* state)
+{
+ state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, "\""));
+}
+
+void BUILD_TEST_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state)
+{
+ state->AddError("File version must be 2 or higher for build and test preset "
+ "support");
+}
+
+void PACKAGE_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state)
+{
+ state->AddError(
+ "File version must be 6 or higher for package preset support");
+}
+
+void WORKFLOW_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state)
+{
+ state->AddError(
+ "File version must be 6 or higher for workflow preset support");
+}
+
+void INCLUDE_UNSUPPORTED(const Json::Value*, cmJSONState* state)
+{
+ state->AddError("File version must be 4 or higher for include support");
+}
+
+void INVALID_INCLUDE(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue("Invalid \"include\" field", value);
+}
+
+void INVALID_CONFIGURE_PRESET(const std::string& presetName,
+ cmJSONState* state)
+{
+ state->AddError(
+ cmStrCat(R"(Invalid "configurePreset": ")", presetName, "\""));
+}
+
+void INSTALL_PREFIX_UNSUPPORTED(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue(
+ "File version must be 3 or higher for installDir preset "
+ "support",
+ value);
+}
+
+void CONDITION_UNSUPPORTED(cmJSONState* state)
+{
+ state->AddError("File version must be 3 or higher for condition support");
+}
+
+void TOOLCHAIN_FILE_UNSUPPORTED(cmJSONState* state)
+{
+ state->AddError("File version must be 3 or higher for toolchainFile preset "
+ "support");
+}
+
+void CYCLIC_INCLUDE(const std::string& file, cmJSONState* state)
+{
+ state->AddError(cmStrCat("Cyclic include among preset files: ", file));
+}
+
+void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state)
+{
+ state->AddError("File version must be 5 or higher for testOutputTruncation "
+ "preset support");
+}
+
+void INVALID_WORKFLOW_STEPS(const std::string& workflowStep,
+ cmJSONState* state)
+{
+ state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, "\""));
+}
+
+void NO_WORKFLOW_STEPS(const std::string& presetName, cmJSONState* state)
+{
+ state->AddError(
+ cmStrCat("No workflow steps specified for \"", presetName, "\""));
+}
+
+void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(const std::string& stepName,
+ cmJSONState* state)
+{
+ state->AddError(cmStrCat("First workflow step \"", stepName,
+ "\" must be a configure step"));
+}
+
+void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(const std::string& stepName,
+ cmJSONState* state)
+{
+ state->AddError(cmStrCat("Configure workflow step \"", stepName,
+ "\" must be the first step"));
+}
+
+void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(const std::string& workflowStep,
+ cmJSONState* state)
+{
+ state->AddError(cmStrCat("Workflow step \"", workflowStep,
+ "\" is unreachable from preset's file"));
+}
+
+void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state)
+{
+ state->AddError(
+ "File version must be 6 or higher for CTest JUnit output support");
+}
+
+void TRACE_UNSUPPORTED(cmJSONState* state)
+{
+ state->AddError("File version must be 7 or higher for trace preset support");
+}
+
+JsonErrors::ErrorGenerator UNRECOGNIZED_CMAKE_VERSION(
+ const std::string& version, int current, int required)
+{
+ return [version, current, required](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue(cmStrCat("\"cmakeMinimumRequired\" ", version,
+ " version ", required,
+ " must be less than ", current),
+ value);
+ };
+}
+
+void INVALID_PRESET_NAME(const Json::Value* value, cmJSONState* state)
+{
+ std::string errMsg = "Invalid Preset Name";
+ if (value && value->isConvertibleTo(Json::ValueType::stringValue) &&
+ !value->asString().empty()) {
+ errMsg = cmStrCat(errMsg, ": ", value->asString());
+ }
+ state->AddErrorAtValue(errMsg, value);
+}
+
+void INVALID_CONDITION(const Json::Value* value, cmJSONState* state)
+{
+ state->AddErrorAtValue(
+ cmStrCat("Invalid condition for preset \"", getPresetName(state), "\""),
+ value);
+}
+
+JsonErrors::ErrorGenerator INVALID_CONDITION_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
+{
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState* state) -> std::string {
+ return cmStrCat(" condition for preset \"", getPresetName(state), "\"");
+ })(errorType, extraFields);
+}
+
+JsonErrors::ErrorGenerator INVALID_VARIABLE_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
+{
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState* state) -> std::string {
+ return getVariableName(state);
+ })(errorType, extraFields);
+}
+
+JsonErrors::ErrorGenerator INVALID_PRESET_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
+{
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState*) -> std::string { return "Preset"; })(
+ errorType, extraFields);
+}
+
+JsonErrors::ErrorGenerator INVALID_ROOT_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
+{
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState*) -> std::string {
+ return "root object";
+ })(errorType, extraFields);
+}
+
+void PRESET_MISSING_FIELD(const std::string& presetName,
+ const std::string& missingField, cmJSONState* state)
+{
+ state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
+ missingField, "\""));
+}
+}
diff --git a/Source/cmCMakePresetsErrors.h b/Source/cmCMakePresetsErrors.h
new file mode 100644
index 0000000..14aaed7
--- /dev/null
+++ b/Source/cmCMakePresetsErrors.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 "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+#include <cm3p/json/value.h>
+
+#include "cmJSONHelpers.h"
+
+class cmJSONState;
+
+namespace cmCMakePresetsErrors {
+const Json::Value* getPreset(cmJSONState* state);
+
+std::string getPresetName(cmJSONState* state);
+
+std::string getVariableName(cmJSONState* state);
+
+void FILE_NOT_FOUND(const std::string& filename, cmJSONState* state);
+
+void INVALID_ROOT(const Json::Value* value, cmJSONState* state);
+
+void NO_VERSION(const Json::Value* value, cmJSONState* state);
+
+void INVALID_VERSION(const Json::Value* value, cmJSONState* state);
+
+void UNRECOGNIZED_VERSION(const Json::Value* value, cmJSONState* state);
+
+void INVALID_PRESETS(const Json::Value* value, cmJSONState* state);
+
+void INVALID_PRESET(const Json::Value* value, cmJSONState* state);
+
+void INVALID_PRESET_NAMED(const std::string& presetName, cmJSONState* state);
+
+void INVALID_VARIABLE(const Json::Value* value, cmJSONState* state);
+
+void DUPLICATE_PRESETS(const std::string& presetName, cmJSONState* state);
+
+void CYCLIC_PRESET_INHERITANCE(const std::string& presetName,
+ cmJSONState* state);
+
+void INHERITED_PRESET_UNREACHABLE_FROM_FILE(const std::string& presetName,
+ cmJSONState* state);
+
+void CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(const std::string& presetName,
+ cmJSONState* state);
+
+void INVALID_MACRO_EXPANSION(const std::string& presetName,
+ cmJSONState* state);
+
+void BUILD_TEST_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state);
+
+void PACKAGE_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state);
+
+void WORKFLOW_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state);
+
+void INCLUDE_UNSUPPORTED(const Json::Value*, cmJSONState* state);
+
+void INVALID_INCLUDE(const Json::Value* value, cmJSONState* state);
+
+void INVALID_CONFIGURE_PRESET(const std::string& presetName,
+ cmJSONState* state);
+
+void INSTALL_PREFIX_UNSUPPORTED(const Json::Value* value, cmJSONState* state);
+
+void CONDITION_UNSUPPORTED(cmJSONState* state);
+
+void TOOLCHAIN_FILE_UNSUPPORTED(cmJSONState* state);
+
+void CYCLIC_INCLUDE(const std::string& file, cmJSONState* state);
+
+void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state);
+
+void INVALID_WORKFLOW_STEPS(const std::string& workflowStep,
+ cmJSONState* state);
+
+void NO_WORKFLOW_STEPS(const std::string& presetName, cmJSONState* state);
+
+void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(const std::string& stepName,
+ cmJSONState* state);
+
+void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(const std::string& stepName,
+ cmJSONState* state);
+
+void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(const std::string& workflowStep,
+ cmJSONState* state);
+
+void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state);
+
+void TRACE_UNSUPPORTED(cmJSONState* state);
+
+JsonErrors::ErrorGenerator UNRECOGNIZED_CMAKE_VERSION(
+ const std::string& version, int current, int required);
+
+void INVALID_PRESET_NAME(const Json::Value* value, cmJSONState* state);
+
+void INVALID_CONDITION(const Json::Value* value, cmJSONState* state);
+
+JsonErrors::ErrorGenerator INVALID_CONDITION_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields);
+
+JsonErrors::ErrorGenerator INVALID_VARIABLE_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields);
+
+JsonErrors::ErrorGenerator INVALID_PRESET_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields);
+
+JsonErrors::ErrorGenerator INVALID_ROOT_OBJECT(
+ JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields);
+
+void PRESET_MISSING_FIELD(const std::string& presetName,
+ const std::string& missingField, cmJSONState* state);
+}
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index 13eddbe..d37c8a4 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
@@ -13,7 +14,7 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -88,8 +89,8 @@ bool VisitPreset(
{
switch (cycleStatus[preset.Name]) {
case CycleStatus::InProgress:
- cmCMakePresetErrors::CYCLIC_PRESET_INHERITANCE(preset.Name,
- &graph.parseState);
+ cmCMakePresetsErrors::CYCLIC_PRESET_INHERITANCE(preset.Name,
+ &graph.parseState);
return false;
case CycleStatus::Verified:
return true;
@@ -100,27 +101,27 @@ bool VisitPreset(
cycleStatus[preset.Name] = CycleStatus::InProgress;
if (preset.Environment.count("") != 0) {
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
return false;
}
bool result = preset.VisitPresetBeforeInherit();
if (!result) {
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
return false;
}
for (auto const& i : preset.Inherits) {
auto parent = presets.find(i);
if (parent == presets.end()) {
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
- &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
return false;
}
auto& parentPreset = parent->second.Unexpanded;
if (!preset.OriginFile->ReachableFiles.count(parentPreset.OriginFile)) {
- cmCMakePresetErrors::INHERITED_PRESET_UNREACHABLE_FROM_FILE(
+ cmCMakePresetsErrors::INHERITED_PRESET_UNREACHABLE_FROM_FILE(
preset.Name, &graph.parseState);
return false;
}
@@ -131,8 +132,8 @@ bool VisitPreset(
result = preset.VisitPresetInherit(parentPreset);
if (!result) {
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
- &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
return false;
}
@@ -152,7 +153,7 @@ bool VisitPreset(
result = preset.VisitPresetAfterInherit(graph.GetVersion(preset),
&graph.parseState);
if (!result) {
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
return false;
}
@@ -458,8 +459,8 @@ bool ExpandMacros(cmCMakePresetsGraph& graph, const T& preset,
switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders,
graph.GetVersion(preset))) {
case ExpandMacroResult::Error:
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
- &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
return false;
case ExpandMacroResult::Ignore:
out.reset();
@@ -474,8 +475,8 @@ bool ExpandMacros(cmCMakePresetsGraph& graph, const T& preset,
cm::optional<bool> result;
if (!preset.ConditionEvaluator->Evaluate(
macroExpanders, graph.GetVersion(preset), result)) {
- cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
- &graph.parseState);
+ cmCMakePresetsErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
return false;
}
if (!result) {
@@ -614,7 +615,7 @@ bool SetupWorkflowConfigurePreset(const T& preset,
cmJSONState* state)
{
if (preset.ConfigurePreset != configurePreset->Name) {
- cmCMakePresetErrors::INVALID_WORKFLOW_STEPS(configurePreset->Name, state);
+ cmCMakePresetsErrors::INVALID_WORKFLOW_STEPS(configurePreset->Name, state);
return false;
}
return true;
@@ -637,12 +638,12 @@ bool TryReachPresetFromWorkflow(
{
auto it = presets.find(name);
if (it == presets.end()) {
- cmCMakePresetErrors::INVALID_WORKFLOW_STEPS(name, state);
+ cmCMakePresetsErrors::INVALID_WORKFLOW_STEPS(name, state);
return false;
}
if (!origin.OriginFile->ReachableFiles.count(
it->second.Unexpanded.OriginFile)) {
- cmCMakePresetErrors::WORKFLOW_STEP_UNREACHABLE_FROM_FILE(name, state);
+ cmCMakePresetsErrors::WORKFLOW_STEP_UNREACHABLE_FROM_FILE(name, state);
return false;
}
return SetupWorkflowConfigurePreset<T>(it->second.Unexpanded,
@@ -792,13 +793,13 @@ bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetAfterInherit(
if (!preset.Hidden) {
if (version < 3) {
if (preset.Generator.empty()) {
- cmCMakePresetErrors::PRESET_MISSING_FIELD(preset.Name, "generator",
- state);
+ cmCMakePresetsErrors::PRESET_MISSING_FIELD(preset.Name, "generator",
+ state);
return false;
}
if (preset.BinaryDir.empty()) {
- cmCMakePresetErrors::PRESET_MISSING_FIELD(preset.Name, "binaryDir",
- state);
+ cmCMakePresetsErrors::PRESET_MISSING_FIELD(preset.Name, "binaryDir",
+ state);
return false;
}
}
@@ -1063,7 +1064,7 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
if (allowNoFiles) {
return true;
}
- cmCMakePresetErrors::FILE_NOT_FOUND(filename, &this->parseState);
+ cmCMakePresetsErrors::FILE_NOT_FOUND(filename, &this->parseState);
return false;
}
@@ -1079,8 +1080,8 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
for (auto& it : this->ConfigurePresets) {
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
return false;
}
}
@@ -1090,13 +1091,13 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const auto configurePreset =
this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
if (configurePreset == this->ConfigurePresets.end()) {
- cmCMakePresetErrors::INVALID_CONFIGURE_PRESET(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_CONFIGURE_PRESET(it.first,
+ &this->parseState);
return false;
}
if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
configurePreset->second.Unexpanded.OriginFile)) {
- cmCMakePresetErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
+ cmCMakePresetsErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
it.first, &this->parseState);
return false;
}
@@ -1109,8 +1110,8 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
return false;
}
}
@@ -1120,13 +1121,13 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const auto configurePreset =
this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
if (configurePreset == this->ConfigurePresets.end()) {
- cmCMakePresetErrors::INVALID_CONFIGURE_PRESET(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_CONFIGURE_PRESET(it.first,
+ &this->parseState);
return false;
}
if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
configurePreset->second.Unexpanded.OriginFile)) {
- cmCMakePresetErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
+ cmCMakePresetsErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
it.first, &this->parseState);
return false;
}
@@ -1139,8 +1140,8 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
return false;
}
}
@@ -1150,13 +1151,13 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const auto configurePreset =
this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
if (configurePreset == this->ConfigurePresets.end()) {
- cmCMakePresetErrors::INVALID_CONFIGURE_PRESET(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_CONFIGURE_PRESET(it.first,
+ &this->parseState);
return false;
}
if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
configurePreset->second.Unexpanded.OriginFile)) {
- cmCMakePresetErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
+ cmCMakePresetsErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
it.first, &this->parseState);
return false;
}
@@ -1169,8 +1170,8 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
return false;
}
}
@@ -1181,12 +1182,12 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const ConfigurePreset* configurePreset = nullptr;
for (auto const& step : it.second.Unexpanded.Steps) {
if (configurePreset == nullptr && step.PresetType != Type::Configure) {
- cmCMakePresetErrors::FIRST_WORKFLOW_STEP_NOT_CONFIGURE(
+ cmCMakePresetsErrors::FIRST_WORKFLOW_STEP_NOT_CONFIGURE(
step.PresetName, &this->parseState);
return false;
}
if (configurePreset != nullptr && step.PresetType == Type::Configure) {
- cmCMakePresetErrors::CONFIGURE_WORKFLOW_STEP_NOT_FIRST(
+ cmCMakePresetsErrors::CONFIGURE_WORKFLOW_STEP_NOT_FIRST(
step.PresetName, &this->parseState);
return false;
}
@@ -1219,13 +1220,13 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (configurePreset == nullptr) {
- cmCMakePresetErrors::NO_WORKFLOW_STEPS(it.first, &this->parseState);
+ cmCMakePresetsErrors::NO_WORKFLOW_STEPS(it.first, &this->parseState);
return false;
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
- &this->parseState);
+ cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
return false;
}
}
diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h
index 7844624..a000e7d 100644
--- a/Source/cmCMakePresetsGraph.h
+++ b/Source/cmCMakePresetsGraph.h
@@ -15,9 +15,9 @@
#include <cm/optional>
#include "cmJSONState.h"
-#include "cmStateTypes.h"
+#include "cmStateTypes.h" // IWYU pragma: keep
-#include "CTest/cmCTestTypes.h"
+#include "CTest/cmCTestTypes.h" // IWYU pragma: keep
enum class PackageResolveMode;
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index 54fea40..8d63441 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -15,7 +15,7 @@
#include <cm3p/json/value.h>
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
@@ -71,18 +71,18 @@ auto const ConditionStringHelper = JSONHelperBuilder::String();
auto const ConditionBoolHelper = JSONHelperBuilder::Bool();
auto const ConditionStringListHelper = JSONHelperBuilder::Vector<std::string>(
- cmCMakePresetErrors::INVALID_CONDITION, ConditionStringHelper);
+ cmCMakePresetsErrors::INVALID_CONDITION, ConditionStringHelper);
auto const ConstConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::ConstCondition>(
- cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value,
ConditionBoolHelper, true);
auto const EqualsConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::EqualsCondition>(
- cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs,
ConditionStringHelper, true)
@@ -91,7 +91,7 @@ auto const EqualsConditionHelper =
auto const InListConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::InListCondition>(
- cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String,
ConditionStringHelper, true)
@@ -100,7 +100,7 @@ auto const InListConditionHelper =
auto const MatchesConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::MatchesCondition>(
- cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String,
ConditionStringHelper, true)
@@ -112,10 +112,10 @@ bool SubConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
auto const ListConditionVectorHelper =
JSONHelperBuilder::Vector<std::unique_ptr<cmCMakePresetsGraph::Condition>>(
- cmCMakePresetErrors::INVALID_CONDITION, SubConditionHelper);
+ cmCMakePresetsErrors::INVALID_CONDITION, SubConditionHelper);
auto const AnyAllOfConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::AnyAllOfCondition>(
- cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("conditions"_s,
&cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions,
@@ -123,7 +123,7 @@ auto const AnyAllOfConditionHelper =
auto const NotConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::NotCondition>(
- cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("condition"_s,
&cmCMakePresetsGraphInternal::NotCondition::SubCondition,
@@ -151,12 +151,12 @@ bool ConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
if (value->isObject()) {
if (!value->isMember("type")) {
- cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ cmCMakePresetsErrors::INVALID_CONDITION(value, state);
return false;
}
if (!(*value)["type"].isString()) {
- cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ cmCMakePresetsErrors::INVALID_CONDITION(value, state);
return false;
}
auto type = (*value)["type"].asString();
@@ -216,7 +216,7 @@ bool ConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
}
}
- cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ cmCMakePresetsErrors::INVALID_CONDITION(value, state);
return false;
}
@@ -226,7 +226,7 @@ bool SubConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
auto result = ConditionHelper(ptr, value, state);
if (ptr && ptr->IsNull()) {
- cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ cmCMakePresetsErrors::INVALID_CONDITION(value, state);
return false;
}
out = std::move(ptr);
@@ -244,22 +244,22 @@ bool EnvironmentHelper(cm::optional<std::string>& out,
out = value->asString();
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
auto const VersionIntHelper =
- JSONHelperBuilder::Int(cmCMakePresetErrors::INVALID_VERSION);
+ JSONHelperBuilder::Int(cmCMakePresetsErrors::INVALID_VERSION);
auto const VersionHelper = JSONHelperBuilder::Required<int>(
- cmCMakePresetErrors::NO_VERSION, VersionIntHelper);
+ cmCMakePresetsErrors::NO_VERSION, VersionIntHelper);
auto const RootVersionHelper =
- JSONHelperBuilder::Object<int>(cmCMakePresetErrors::INVALID_ROOT_OBJECT)
+ JSONHelperBuilder::Object<int>(cmCMakePresetsErrors::INVALID_ROOT_OBJECT)
.Bind("version"_s, VersionHelper, false);
auto const CMakeVersionUIntHelper =
- JSONHelperBuilder::UInt(cmCMakePresetErrors::INVALID_VERSION);
+ JSONHelperBuilder::UInt(cmCMakePresetsErrors::INVALID_VERSION);
auto const CMakeVersionHelper =
JSONHelperBuilder::Object<CMakeVersion>(JsonErrors::INVALID_NAMED_OBJECT_KEY,
@@ -269,14 +269,14 @@ auto const CMakeVersionHelper =
.Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false);
auto const IncludeHelper =
- JSONHelperBuilder::String(cmCMakePresetErrors::INVALID_INCLUDE);
+ JSONHelperBuilder::String(cmCMakePresetsErrors::INVALID_INCLUDE);
auto const IncludeVectorHelper = JSONHelperBuilder::Vector<std::string>(
- cmCMakePresetErrors::INVALID_INCLUDE, IncludeHelper);
+ cmCMakePresetsErrors::INVALID_INCLUDE, IncludeHelper);
auto const RootPresetsHelper =
JSONHelperBuilder::Object<RootPresets>(
- cmCMakePresetErrors::INVALID_ROOT_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_ROOT_OBJECT, false)
.Bind<int>("version"_s, nullptr, VersionHelper)
.Bind("configurePresets"_s, &RootPresets::ConfigurePresets,
cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false)
@@ -293,7 +293,7 @@ auto const RootPresetsHelper =
.Bind("include"_s, &RootPresets::Include, IncludeVectorHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- cmCMakePresetErrors::INVALID_ROOT),
+ cmCMakePresetsErrors::INVALID_ROOT),
false);
}
@@ -309,7 +309,7 @@ bool PresetNameHelper(std::string& out, const Json::Value* value,
cmJSONState* state)
{
if (!value || !value->isString() || value->asString().empty()) {
- cmCMakePresetErrors::INVALID_PRESET_NAME(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET_NAME(value, state);
return false;
}
out = value->asString();
@@ -320,7 +320,7 @@ bool PresetVectorStringHelper(std::vector<std::string>& out,
const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<std::string>(
- cmCMakePresetErrors::INVALID_PRESET,
+ cmCMakePresetsErrors::INVALID_PRESET,
cmCMakePresetsGraphInternal::PresetStringHelper);
return helper(out, value, state);
}
@@ -356,7 +356,7 @@ bool PresetVectorIntHelper(std::vector<int>& out, const Json::Value* value,
cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<int>(
- cmCMakePresetErrors::INVALID_PRESET, PresetIntHelper);
+ cmCMakePresetsErrors::INVALID_PRESET, PresetIntHelper);
return helper(out, value, state);
}
@@ -409,7 +409,7 @@ bool EnvironmentMapHelper(
const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Map<cm::optional<std::string>>(
- cmCMakePresetErrors::INVALID_PRESET, EnvironmentHelper);
+ cmCMakePresetsErrors::INVALID_PRESET, EnvironmentHelper);
return helper(out, value, state);
}
@@ -429,7 +429,7 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
auto fileIt =
std::find(inProgressFiles.begin(), inProgressFiles.end(), file);
if (fileIt != inProgressFiles.end()) {
- cmCMakePresetErrors::CYCLIC_INCLUDE(filename, &this->parseState);
+ cmCMakePresetsErrors::CYCLIC_INCLUDE(filename, &this->parseState);
return false;
}
@@ -448,43 +448,43 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
return result;
}
if (v < MIN_VERSION || v > MAX_VERSION) {
- cmCMakePresetErrors::UNRECOGNIZED_VERSION(&root["version"],
- &this->parseState);
+ cmCMakePresetsErrors::UNRECOGNIZED_VERSION(&root["version"],
+ &this->parseState);
return false;
}
// Support for build and test presets added in version 2.
if (v < 2) {
if (root.isMember("buildPresets")) {
- cmCMakePresetErrors::BUILD_TEST_PRESETS_UNSUPPORTED(
+ cmCMakePresetsErrors::BUILD_TEST_PRESETS_UNSUPPORTED(
&root["buildPresets"], &this->parseState);
return false;
}
if (root.isMember("testPresets")) {
- cmCMakePresetErrors::BUILD_TEST_PRESETS_UNSUPPORTED(&root["testPresets"],
- &this->parseState);
+ cmCMakePresetsErrors::BUILD_TEST_PRESETS_UNSUPPORTED(
+ &root["testPresets"], &this->parseState);
return false;
}
}
// Support for package presets added in version 6.
if (v < 6 && root.isMember("packagePresets")) {
- cmCMakePresetErrors::PACKAGE_PRESETS_UNSUPPORTED(&root["packagePresets"],
- &this->parseState);
+ cmCMakePresetsErrors::PACKAGE_PRESETS_UNSUPPORTED(&root["packagePresets"],
+ &this->parseState);
return false;
}
// Support for workflow presets added in version 6.
if (v < 6 && root.isMember("workflowPresets")) {
- cmCMakePresetErrors::WORKFLOW_PRESETS_UNSUPPORTED(&root["workflowPresets"],
- &this->parseState);
+ cmCMakePresetsErrors::WORKFLOW_PRESETS_UNSUPPORTED(
+ &root["workflowPresets"], &this->parseState);
return false;
}
// Support for include added in version 4.
if (v < 4 && root.isMember("include")) {
- cmCMakePresetErrors::INCLUDE_UNSUPPORTED(&root["include"],
- &this->parseState);
+ cmCMakePresetsErrors::INCLUDE_UNSUPPORTED(&root["include"],
+ &this->parseState);
return false;
}
@@ -498,20 +498,20 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
unsigned int currentPatch = cmVersion::GetPatchVersion();
auto const& required = presets.CMakeMinimumRequired;
if (required.Major > currentMajor) {
- ErrorGenerator error = cmCMakePresetErrors::UNRECOGNIZED_CMAKE_VERSION(
+ ErrorGenerator error = cmCMakePresetsErrors::UNRECOGNIZED_CMAKE_VERSION(
"major", currentMajor, required.Major);
error(&root["cmakeMinimumRequired"]["major"], &this->parseState);
return false;
}
if (required.Major == currentMajor) {
if (required.Minor > currentMinor) {
- ErrorGenerator error = cmCMakePresetErrors::UNRECOGNIZED_CMAKE_VERSION(
+ ErrorGenerator error = cmCMakePresetsErrors::UNRECOGNIZED_CMAKE_VERSION(
"minor", currentMinor, required.Minor);
error(&root["cmakeMinimumRequired"]["minor"], &this->parseState);
return false;
}
if (required.Minor == currentMinor && required.Patch > currentPatch) {
- ErrorGenerator error = cmCMakePresetErrors::UNRECOGNIZED_CMAKE_VERSION(
+ ErrorGenerator error = cmCMakePresetsErrors::UNRECOGNIZED_CMAKE_VERSION(
"patch", currentPatch, required.Patch);
error(&root["cmakeMinimumRequired"]["patch"], &this->parseState);
return false;
@@ -537,26 +537,26 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->ConfigurePresets.emplace(preset.Name, presetPair).second) {
- cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ cmCMakePresetsErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
return false;
}
// Support for installDir presets added in version 3.
if (v < 3 && !preset.InstallDir.empty()) {
- cmCMakePresetErrors::INSTALL_PREFIX_UNSUPPORTED(&root["installDir"],
- &this->parseState);
+ cmCMakePresetsErrors::INSTALL_PREFIX_UNSUPPORTED(&root["installDir"],
+ &this->parseState);
return false;
}
// Support for conditions added in version 3.
if (v < 3 && preset.ConditionEvaluator) {
- cmCMakePresetErrors::CONDITION_UNSUPPORTED(&this->parseState);
+ cmCMakePresetsErrors::CONDITION_UNSUPPORTED(&this->parseState);
return false;
}
// Support for toolchainFile presets added in version 3.
if (v < 3 && !preset.ToolchainFile.empty()) {
- cmCMakePresetErrors::TOOLCHAIN_FILE_UNSUPPORTED(&this->parseState);
+ cmCMakePresetsErrors::TOOLCHAIN_FILE_UNSUPPORTED(&this->parseState);
return false;
}
@@ -564,7 +564,7 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
if (v < 7 &&
(preset.TraceMode.has_value() || preset.TraceFormat.has_value() ||
!preset.TraceRedirect.empty() || !preset.TraceSource.empty())) {
- cmCMakePresetErrors::TRACE_UNSUPPORTED(&this->parseState);
+ cmCMakePresetsErrors::TRACE_UNSUPPORTED(&this->parseState);
return false;
}
@@ -582,13 +582,13 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->BuildPresets.emplace(preset.Name, presetPair).second) {
- cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ cmCMakePresetsErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
return false;
}
// Support for conditions added in version 3.
if (v < 3 && preset.ConditionEvaluator) {
- cmCMakePresetErrors::CONDITION_UNSUPPORTED(&this->parseState);
+ cmCMakePresetsErrors::CONDITION_UNSUPPORTED(&this->parseState);
return false;
}
@@ -606,26 +606,26 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->TestPresets.emplace(preset.Name, presetPair).second) {
- cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ cmCMakePresetsErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
return false;
}
// Support for conditions added in version 3.
if (v < 3 && preset.ConditionEvaluator) {
- cmCMakePresetErrors::CONDITION_UNSUPPORTED(&this->parseState);
+ cmCMakePresetsErrors::CONDITION_UNSUPPORTED(&this->parseState);
return false;
}
// Support for TestOutputTruncation added in version 5.
if (v < 5 && preset.Output && preset.Output->TestOutputTruncation) {
- cmCMakePresetErrors::TEST_OUTPUT_TRUNCATION_UNSUPPORTED(
+ cmCMakePresetsErrors::TEST_OUTPUT_TRUNCATION_UNSUPPORTED(
&this->parseState);
return false;
}
// Support for outputJUnitFile added in version 6.
if (v < 6 && preset.Output && !preset.Output->OutputJUnitFile.empty()) {
- cmCMakePresetErrors::CTEST_JUNIT_UNSUPPORTED(&this->parseState);
+ cmCMakePresetsErrors::CTEST_JUNIT_UNSUPPORTED(&this->parseState);
return false;
}
@@ -643,7 +643,7 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->PackagePresets.emplace(preset.Name, presetPair).second) {
- cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ cmCMakePresetsErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
return false;
}
@@ -664,7 +664,7 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->WorkflowPresets.emplace(preset.Name, presetPair).second) {
- cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ cmCMakePresetsErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
return false;
}
@@ -718,8 +718,8 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
// 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);
+ cmCMakePresetsErrors::INVALID_INCLUDE(&root["include"][i],
+ &this->parseState);
return false;
}
}
diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
index 07f2bc3..c743ac1 100644
--- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
@@ -13,7 +13,7 @@
#include <cm3p/json/value.h>
#include "cmBuildOptions.h"
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
@@ -32,7 +32,7 @@ bool PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -43,7 +43,7 @@ bool PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
} else if (value->asString() == "only") {
out = PackageResolveMode::OnlyResolve;
} else {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -59,7 +59,7 @@ std::function<bool(BuildPreset&, const Json::Value*, cmJSONState*)> const
auto const BuildPresetHelper =
JSONHelperBuilder::Object<BuildPreset>(
- cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &BuildPreset::Name,
cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &BuildPreset::Inherits,
@@ -69,7 +69,7 @@ auto const BuildPresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- cmCMakePresetErrors::INVALID_PRESET),
+ cmCMakePresetsErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &BuildPreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -105,7 +105,7 @@ bool BuildPresetsHelper(std::vector<BuildPreset>& out,
const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<BuildPreset>(
- cmCMakePresetErrors::INVALID_PRESETS, BuildPresetHelper);
+ cmCMakePresetsErrors::INVALID_PRESETS, BuildPresetHelper);
return helper(out, value, state);
}
diff --git a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
index 66ec6a4..c52a187 100644
--- a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
@@ -12,13 +12,14 @@
#include <cm3p/json/value.h>
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
-#include "cmJSONState.h"
#include "cmStateTypes.h"
+class cmJSONState;
+
namespace {
using CacheVariable = cmCMakePresetsGraph::CacheVariable;
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
@@ -36,7 +37,7 @@ bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out,
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -50,7 +51,7 @@ bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out,
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -84,7 +85,7 @@ ArchToolsetHelper(
return objectHelper(out, value, state);
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
};
}
@@ -103,7 +104,7 @@ bool TraceEnableModeHelper(cm::optional<TraceEnableMode>& out,
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -114,7 +115,7 @@ bool TraceEnableModeHelper(cm::optional<TraceEnableMode>& out,
} else if (value->asString() == "expand") {
out = TraceEnableMode::Expand;
} else {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -130,7 +131,7 @@ bool TraceOutputFormatHelper(cm::optional<TraceOutputFormat>& out,
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -139,7 +140,7 @@ bool TraceOutputFormatHelper(cm::optional<TraceOutputFormat>& out,
} else if (value->asString() == "json-v1") {
out = TraceOutputFormat::JSONv1;
} else {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -166,7 +167,7 @@ bool VariableValueHelper(std::string& out, const Json::Value* value,
auto const VariableObjectHelper =
JSONHelperBuilder::Object<CacheVariable>(
- cmCMakePresetErrors::INVALID_VARIABLE_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_VARIABLE_OBJECT, false)
.Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
.Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
@@ -195,13 +196,13 @@ bool VariableHelper(cm::optional<CacheVariable>& out, const Json::Value* value,
out = cm::nullopt;
return true;
}
- cmCMakePresetErrors::INVALID_VARIABLE(value, state);
+ cmCMakePresetsErrors::INVALID_VARIABLE(value, state);
return false;
}
auto const VariablesHelper =
JSONHelperBuilder::Map<cm::optional<CacheVariable>>(
- cmCMakePresetErrors::INVALID_PRESET, VariableHelper);
+ cmCMakePresetsErrors::INVALID_PRESET, VariableHelper);
auto const PresetWarningsHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
@@ -237,7 +238,7 @@ auto const PresetDebugHelper =
auto const PresetTraceHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
- cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
.Bind("mode"_s, &ConfigurePreset::TraceMode, TraceEnableModeHelper, false)
.Bind("format"_s, &ConfigurePreset::TraceFormat, TraceOutputFormatHelper,
false)
@@ -249,7 +250,7 @@ auto const PresetTraceHelper =
auto const ConfigurePresetHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
- cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &ConfigurePreset::Name,
cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &ConfigurePreset::Inherits,
@@ -259,7 +260,7 @@ auto const ConfigurePresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- cmCMakePresetErrors::INVALID_PRESET),
+ cmCMakePresetsErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &ConfigurePreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -294,7 +295,7 @@ bool ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>(
- cmCMakePresetErrors::INVALID_PRESETS, ConfigurePresetHelper);
+ cmCMakePresetsErrors::INVALID_PRESETS, ConfigurePresetHelper);
return helper(out, value, state);
}
diff --git a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
index 7290d4d..ac49c62 100644
--- a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
@@ -1,7 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include <cstddef>
-#include <functional>
#include <map>
#include <memory>
#include <string>
@@ -12,7 +11,7 @@
#include <cm3p/json/value.h>
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
@@ -30,14 +29,14 @@ auto const OutputHelper =
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
auto const VariableHelper =
- cmJSONHelperBuilder::String(cmCMakePresetErrors::INVALID_VARIABLE);
+ cmJSONHelperBuilder::String(cmCMakePresetsErrors::INVALID_VARIABLE);
auto const VariablesHelper = cmJSONHelperBuilder::Map<std::string>(
- cmCMakePresetErrors::INVALID_VARIABLE, VariableHelper);
+ cmCMakePresetsErrors::INVALID_VARIABLE, VariableHelper);
auto const PackagePresetHelper =
cmJSONHelperBuilder::Object<PackagePreset>(
- cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &PackagePreset::Name,
cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &PackagePreset::Inherits,
@@ -47,7 +46,7 @@ auto const PackagePresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- cmCMakePresetErrors::INVALID_PRESET),
+ cmCMakePresetsErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &PackagePreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -85,7 +84,7 @@ bool PackagePresetsHelper(std::vector<cmCMakePresetsGraph::PackagePreset>& out,
const Json::Value* value, cmJSONState* state)
{
static auto const helper = cmJSONHelperBuilder::Vector<PackagePreset>(
- cmCMakePresetErrors::INVALID_PRESETS, PackagePresetHelper);
+ cmCMakePresetsErrors::INVALID_PRESETS, PackagePresetHelper);
return helper(out, value, state);
}
diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
index 791be04..f9e0753 100644
--- a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
@@ -1,7 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include <cstddef>
-#include <functional>
#include <map>
#include <memory>
#include <string>
@@ -12,7 +11,7 @@
#include <cm3p/json/value.h>
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
@@ -35,7 +34,7 @@ bool TestPresetOutputVerbosityHelper(
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -54,7 +53,7 @@ bool TestPresetOutputVerbosityHelper(
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -72,7 +71,7 @@ bool TestPresetOutputTruncationHelper(
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -91,7 +90,7 @@ bool TestPresetOutputTruncationHelper(
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -202,7 +201,7 @@ bool TestPresetExecutionShowOnlyHelper(
cmJSONState* state)
{
if (!value || !value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -216,7 +215,7 @@ bool TestPresetExecutionShowOnlyHelper(
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -233,7 +232,7 @@ bool TestPresetExecutionModeHelper(
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -252,7 +251,7 @@ bool TestPresetExecutionModeHelper(
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -274,7 +273,7 @@ bool TestPresetExecutionNoTestsActionHelper(
}
if (!value->isString()) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -293,7 +292,7 @@ bool TestPresetExecutionNoTestsActionHelper(
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -339,7 +338,7 @@ auto const TestPresetFilterHelper =
auto const TestPresetHelper =
JSONHelperBuilder::Object<TestPreset>(
- cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &TestPreset::Name,
cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &TestPreset::Inherits,
@@ -349,7 +348,7 @@ auto const TestPresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- cmCMakePresetErrors::INVALID_PRESET),
+ cmCMakePresetsErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &TestPreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -381,7 +380,7 @@ bool TestPresetsHelper(std::vector<cmCMakePresetsGraph::TestPreset>& out,
const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<TestPreset>(
- cmCMakePresetErrors::INVALID_PRESETS, TestPresetHelper);
+ cmCMakePresetsErrors::INVALID_PRESETS, TestPresetHelper);
return helper(out, value, state);
}
diff --git a/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx b/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
index 7224e17..e152871 100644
--- a/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
@@ -1,7 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include <cstddef>
-#include <functional>
#include <string>
#include <vector>
@@ -9,7 +8,7 @@
#include <cm3p/json/value.h>
-#include "cmCMakePresetErrors.h"
+#include "cmCMakePresetsErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
@@ -23,7 +22,7 @@ bool WorkflowStepTypeHelper(WorkflowPreset::WorkflowStep::Type& out,
const Json::Value* value, cmJSONState* state)
{
if (!value) {
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -51,7 +50,7 @@ bool WorkflowStepTypeHelper(WorkflowPreset::WorkflowStep::Type& out,
return true;
}
- cmCMakePresetErrors::INVALID_PRESET(value, state);
+ cmCMakePresetsErrors::INVALID_PRESET(value, state);
return false;
}
@@ -65,16 +64,16 @@ auto const WorkflowStepHelper =
auto const WorkflowStepsHelper =
cmJSONHelperBuilder::Vector<WorkflowPreset::WorkflowStep>(
- cmCMakePresetErrors::INVALID_PRESET, WorkflowStepHelper);
+ cmCMakePresetsErrors::INVALID_PRESET, WorkflowStepHelper);
auto const WorkflowPresetHelper =
cmJSONHelperBuilder::Object<WorkflowPreset>(
- cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
+ cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &WorkflowPreset::Name,
cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- cmCMakePresetErrors::INVALID_PRESET),
+ cmCMakePresetsErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &WorkflowPreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -89,7 +88,7 @@ bool WorkflowPresetsHelper(
const Json::Value* value, cmJSONState* state)
{
static auto const helper = cmJSONHelperBuilder::Vector<WorkflowPreset>(
- cmCMakePresetErrors::INVALID_PRESETS, WorkflowPresetHelper);
+ cmCMakePresetsErrors::INVALID_PRESETS, WorkflowPresetHelper);
return helper(out, value, state);
}
diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx
index cc9ad01..fbf7d73 100644
--- a/Source/cmCPackPropertiesGenerator.cxx
+++ b/Source/cmCPackPropertiesGenerator.cxx
@@ -1,6 +1,7 @@
#include "cmCPackPropertiesGenerator.h"
#include <map>
+#include <memory>
#include <ostream>
#include "cmGeneratorExpression.h"
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 13ccf4f..655f4bc 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -628,8 +628,8 @@ static void CCONV cmSourceFileSetProperty(void* arg, const char* prop,
{
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if (cmSourceFile* rsf = sf->RealSourceFile) {
- if (value == nullptr) {
- rsf->SetProperty(prop, nullptr);
+ if (!value) {
+ rsf->RemoveProperty(prop);
} else {
rsf->SetProperty(prop, value);
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index a311041..36fd3a8 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -5,12 +5,14 @@
#include <algorithm>
#include <cctype>
#include <chrono>
+#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
+#include <ratio>
#include <sstream>
#include <string>
#include <utility>
@@ -23,13 +25,13 @@
#include <cmext/string_view>
#include <cm3p/curl/curl.h>
+#include <cm3p/uv.h>
#include <cm3p/zlib.h>
#include "cmsys/Base64.h"
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
-#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/SystemInformation.hxx"
#if defined(_WIN32)
@@ -63,6 +65,9 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
#include "cmValue.h"
#include "cmVersion.h"
#include "cmVersionConfig.h"
@@ -1073,9 +1078,9 @@ int cmCTest::GetTestModelFromString(const std::string& str)
// ######################################################################
// ######################################################################
-int cmCTest::RunMakeCommand(const std::string& command, std::string& output,
- int* retVal, const char* dir, cmDuration timeout,
- std::ostream& ofs, Encoding encoding)
+bool cmCTest::RunMakeCommand(const std::string& command, std::string& output,
+ int* retVal, const char* dir, cmDuration timeout,
+ std::ostream& ofs, Encoding encoding)
{
// First generate the command and arguments
std::vector<std::string> args = cmSystemTools::ParseArguments(command);
@@ -1084,107 +1089,107 @@ int cmCTest::RunMakeCommand(const std::string& command, std::string& output,
return false;
}
- std::vector<const char*> argv;
- argv.reserve(args.size() + 1);
- for (std::string const& a : args) {
- argv.push_back(a.c_str());
- }
- argv.push_back(nullptr);
-
output.clear();
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Run command:");
- for (char const* arg : argv) {
- if (!arg) {
- break;
- }
+ for (auto const& arg : args) {
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, " \"" << arg << "\"");
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, std::endl);
// Now create process object
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, argv.data());
- cmsysProcess_SetWorkingDirectory(cp, dir);
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
- cmsysProcess_SetTimeout(cp, timeout.count());
- cmsysProcess_Execute(cp);
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(args).SetMergedBuiltinStreams();
+ if (dir) {
+ builder.SetWorkingDirectory(dir);
+ }
+ auto chain = builder.Start();
+ cm::uv_pipe_ptr outputStream;
+ outputStream.init(chain.GetLoop(), 0);
+ uv_pipe_open(outputStream, chain.OutputStream());
// Initialize tick's
std::string::size_type tick = 0;
std::string::size_type tick_len = 1024;
std::string::size_type tick_line_len = 50;
- char* data;
- int length;
cmProcessOutput processOutput(encoding);
- std::string strdata;
cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
" Each . represents " << tick_len
<< " bytes of output\n"
" "
<< std::flush);
- while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
- processOutput.DecodeText(data, length, strdata);
- for (char& cc : strdata) {
- if (cc == 0) {
- cc = '\n';
+ auto outputHandle = cmUVStreamRead(
+ outputStream,
+ [this, &processOutput, &output, &tick, &tick_len, &tick_line_len,
+ &ofs](std::vector<char> data) {
+ std::string strdata;
+ processOutput.DecodeText(data.data(), data.size(), strdata);
+ for (char& cc : strdata) {
+ if (cc == 0) {
+ cc = '\n';
+ }
}
- }
- output.append(strdata);
- while (output.size() > (tick * tick_len)) {
- tick++;
- cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush);
- if (tick % tick_line_len == 0 && tick > 0) {
- cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
- " Size: " << int((double(output.size()) / 1024.0) + 1)
- << "K\n " << std::flush);
+ output.append(strdata);
+ while (output.size() > (tick * tick_len)) {
+ tick++;
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush);
+ if (tick % tick_line_len == 0 && tick > 0) {
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
+ " Size: " << int((double(output.size()) / 1024.0) + 1)
+ << "K\n " << std::flush);
+ }
}
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- cmCTestLogWrite(strdata.c_str(), strdata.size()));
- if (ofs) {
- ofs << cmCTestLogWrite(strdata.c_str(), strdata.size());
- }
- }
- processOutput.DecodeText(std::string(), strdata);
- if (!strdata.empty()) {
- output.append(strdata);
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- cmCTestLogWrite(strdata.c_str(), strdata.size()));
- if (ofs) {
- ofs << cmCTestLogWrite(strdata.c_str(), strdata.size());
- }
- }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(strdata.c_str(), strdata.size()));
+ if (ofs) {
+ ofs << cmCTestLogWrite(strdata.c_str(), strdata.size());
+ }
+ },
+ [this, &processOutput, &output, &ofs]() {
+ std::string strdata;
+ processOutput.DecodeText(std::string(), strdata);
+ if (!strdata.empty()) {
+ output.append(strdata);
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(strdata.c_str(), strdata.size()));
+ if (ofs) {
+ ofs << cmCTestLogWrite(strdata.c_str(), strdata.size());
+ }
+ }
+ });
+
+ bool finished = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0));
cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
" Size of output: " << int(double(output.size()) / 1024.0) << "K"
<< std::endl);
- cmsysProcess_WaitForExit(cp, nullptr);
-
- int result = cmsysProcess_GetState(cp);
-
- if (result == cmsysProcess_State_Exited) {
- *retVal = cmsysProcess_GetExitValue(cp);
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- "Command exited with the value: " << *retVal << std::endl);
- } else if (result == cmsysProcess_State_Exception) {
- *retVal = cmsysProcess_GetExitException(cp);
- cmCTestLog(this, WARNING,
- "There was an exception: " << *retVal << std::endl);
- } else if (result == cmsysProcess_State_Expired) {
+ if (finished) {
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ *retVal = static_cast<int>(status.ExitStatus);
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ "Command exited with the value: " << *retVal << std::endl);
+ break;
+ case cmUVProcessChain::ExceptionCode::Spawn:
+ output += "\n*** ERROR executing: ";
+ output += exception.second;
+ output += "\n***The build process failed.";
+ cmCTestLog(this, ERROR_MESSAGE,
+ "There was an error: " << exception.second << std::endl);
+ break;
+ default:
+ *retVal = static_cast<int>(exception.first);
+ cmCTestLog(this, WARNING,
+ "There was an exception: " << *retVal << std::endl);
+ break;
+ }
+ } else {
cmCTestLog(this, WARNING, "There was a timeout" << std::endl);
- } else if (result == cmsysProcess_State_Error) {
- output += "\n*** ERROR executing: ";
- output += cmsysProcess_GetErrorString(cp);
- output += "\n***The build process failed.";
- cmCTestLog(this, ERROR_MESSAGE,
- "There was an error: " << cmsysProcess_GetErrorString(cp)
- << std::endl);
}
- cmsysProcess_Delete(cp);
-
- return result;
+ return true;
}
// ######################################################################
@@ -1192,9 +1197,10 @@ int cmCTest::RunMakeCommand(const std::string& command, std::string& output,
// ######################################################################
// ######################################################################
-int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
- int* retVal, std::ostream* log, cmDuration testTimeOut,
- std::vector<std::string>* environment, Encoding encoding)
+bool cmCTest::RunTest(const std::vector<std::string>& argv,
+ std::string* output, int* retVal, std::ostream* log,
+ cmDuration testTimeOut,
+ std::vector<std::string>* environment, Encoding encoding)
{
bool modifyEnv = (environment && !environment->empty());
@@ -1233,19 +1239,16 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
inst.SetStreams(&oss, &oss);
std::vector<std::string> args;
- for (char const* i : argv) {
- if (i) {
- // make sure we pass the timeout in for any build and test
- // invocations. Since --build-generator is required this is a
- // good place to check for it, and to add the arguments in
- if (strcmp(i, "--build-generator") == 0 &&
- timeout != cmCTest::MaxDuration() &&
- timeout > cmDuration::zero()) {
- args.emplace_back("--test-timeout");
- args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout)));
- }
- args.emplace_back(i);
+ for (auto const& i : argv) {
+ // make sure we pass the timeout in for any build and test
+ // invocations. Since --build-generator is required this is a
+ // good place to check for it, and to add the arguments in
+ if (i == "--build-generator" && timeout != cmCTest::MaxDuration() &&
+ timeout > cmDuration::zero()) {
+ args.emplace_back("--test-timeout");
+ args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout)));
}
+ args.emplace_back(i);
}
if (log) {
*log << "* Run internal CTest" << std::endl;
@@ -1271,7 +1274,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
<< std::endl);
}
- return cmsysProcess_State_Exited;
+ return true;
}
std::vector<char> tempOutput;
if (output) {
@@ -1284,41 +1287,43 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
cmSystemTools::AppendEnv(*environment);
}
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, argv.data());
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(argv).SetMergedBuiltinStreams();
cmCTestLog(this, DEBUG, "Command is: " << argv[0] << std::endl);
- if (cmSystemTools::GetRunCommandHideConsole()) {
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
- }
+ auto chain = builder.Start();
- cmsysProcess_SetTimeout(cp, timeout.count());
- cmsysProcess_Execute(cp);
-
- char* data;
- int length;
cmProcessOutput processOutput(encoding);
- std::string strdata;
- while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
- processOutput.DecodeText(data, length, strdata);
- if (output) {
- cm::append(tempOutput, data, data + length);
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- cmCTestLogWrite(strdata.c_str(), strdata.size()));
- if (log) {
- log->write(strdata.c_str(), strdata.size());
- }
- }
- processOutput.DecodeText(std::string(), strdata);
- if (!strdata.empty()) {
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- cmCTestLogWrite(strdata.c_str(), strdata.size()));
- if (log) {
- log->write(strdata.c_str(), strdata.size());
- }
- }
+ cm::uv_pipe_ptr outputStream;
+ outputStream.init(chain.GetLoop(), 0);
+ uv_pipe_open(outputStream, chain.OutputStream());
+ auto outputHandle = cmUVStreamRead(
+ outputStream,
+ [this, &processOutput, &output, &tempOutput,
+ &log](std::vector<char> data) {
+ std::string strdata;
+ processOutput.DecodeText(data.data(), data.size(), strdata);
+ if (output) {
+ cm::append(tempOutput, data.data(), data.data() + data.size());
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(strdata.c_str(), strdata.size()));
+ if (log) {
+ log->write(strdata.c_str(), strdata.size());
+ }
+ },
+ [this, &processOutput, &log]() {
+ std::string strdata;
+ processOutput.DecodeText(std::string(), strdata);
+ if (!strdata.empty()) {
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(strdata.c_str(), strdata.size()));
+ if (log) {
+ log->write(strdata.c_str(), strdata.size());
+ }
+ }
+ });
- cmsysProcess_WaitForExit(cp, nullptr);
+ bool complete = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0));
processOutput.DecodeText(tempOutput, tempOutput);
if (output && tempOutput.begin() != tempOutput.end()) {
output->append(tempOutput.data(), tempOutput.size());
@@ -1326,33 +1331,41 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
"-- Process completed" << std::endl);
- int result = cmsysProcess_GetState(cp);
+ bool result = false;
- if (result == cmsysProcess_State_Exited) {
- *retVal = cmsysProcess_GetExitValue(cp);
- if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) {
- this->OutputTestErrors(tempOutput);
- }
- } else if (result == cmsysProcess_State_Exception) {
- if (this->Impl->OutputTestOutputOnTestFailure) {
- this->OutputTestErrors(tempOutput);
- }
- *retVal = cmsysProcess_GetExitException(cp);
- std::string outerr = cmStrCat("\n*** Exception executing: ",
- cmsysProcess_GetExceptionString(cp));
- if (output) {
- *output += outerr;
- }
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
- } else if (result == cmsysProcess_State_Error) {
- std::string outerr =
- cmStrCat("\n*** ERROR executing: ", cmsysProcess_GetErrorString(cp));
- if (output) {
- *output += outerr;
+ if (complete) {
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ *retVal = static_cast<int>(status.ExitStatus);
+ if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) {
+ this->OutputTestErrors(tempOutput);
+ }
+ result = true;
+ break;
+ case cmUVProcessChain::ExceptionCode::Spawn: {
+ std::string outerr =
+ cmStrCat("\n*** ERROR executing: ", exception.second);
+ if (output) {
+ *output += outerr;
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
+ } break;
+ default: {
+ if (this->Impl->OutputTestOutputOnTestFailure) {
+ this->OutputTestErrors(tempOutput);
+ }
+ *retVal = status.TermSignal;
+ std::string outerr =
+ cmStrCat("\n*** Exception executing: ", exception.second);
+ if (output) {
+ *output += outerr;
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
+ } break;
}
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
}
- cmsysProcess_Delete(cp);
return result;
}
@@ -3470,49 +3483,70 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
stdOut->clear();
stdErr->clear();
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, argv.data());
- cmsysProcess_SetWorkingDirectory(cp, dir);
- if (cmSystemTools::GetRunCommandHideConsole()) {
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(args)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+ if (dir) {
+ builder.SetWorkingDirectory(dir);
+ }
+ auto chain = builder.Start();
+
+ cm::uv_timer_ptr timer;
+ bool timedOut = false;
+ if (timeout.count()) {
+ timer.init(chain.GetLoop(), &timedOut);
+ timer.start(
+ [](uv_timer_t* t) {
+ auto* timedOutPtr = static_cast<bool*>(t->data);
+ *timedOutPtr = true;
+ },
+ static_cast<uint64_t>(timeout.count() * 1000.0), 0);
}
- cmsysProcess_SetTimeout(cp, timeout.count());
- cmsysProcess_Execute(cp);
std::vector<char> tempOutput;
+ bool outFinished = false;
+ cm::uv_pipe_ptr outStream;
std::vector<char> tempError;
- char* data;
- int length;
+ bool errFinished = false;
+ cm::uv_pipe_ptr errStream;
cmProcessOutput processOutput(encoding);
- std::string strdata;
- int res;
- bool done = false;
- while (!done) {
- res = cmsysProcess_WaitForData(cp, &data, &length, nullptr);
- switch (res) {
- case cmsysProcess_Pipe_STDOUT:
- cm::append(tempOutput, data, data + length);
- break;
- case cmsysProcess_Pipe_STDERR:
- cm::append(tempError, data, data + length);
- break;
- default:
- done = true;
- }
- if ((res == cmsysProcess_Pipe_STDOUT || res == cmsysProcess_Pipe_STDERR) &&
- this->Impl->ExtraVerbose) {
- processOutput.DecodeText(data, length, strdata);
- cmSystemTools::Stdout(strdata);
- }
+ auto startRead = [this, &chain, &processOutput](
+ cm::uv_pipe_ptr& pipe, int stream,
+ std::vector<char>& temp,
+ bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
+ pipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(pipe, stream);
+ return cmUVStreamRead(
+ pipe,
+ [this, &temp, &processOutput](std::vector<char> data) {
+ cm::append(temp, data);
+ if (this->Impl->ExtraVerbose) {
+ std::string strdata;
+ processOutput.DecodeText(data.data(), data.size(), strdata);
+ cmSystemTools::Stdout(strdata);
+ }
+ },
+ [&finished]() { finished = true; });
+ };
+ auto outputHandle =
+ startRead(outStream, chain.OutputStream(), tempOutput, outFinished);
+ auto errorHandle =
+ startRead(errStream, chain.ErrorStream(), tempError, errFinished);
+ while (!timedOut && !(outFinished && errFinished)) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
}
if (this->Impl->ExtraVerbose) {
+ std::string strdata;
processOutput.DecodeText(std::string(), strdata);
if (!strdata.empty()) {
cmSystemTools::Stdout(strdata);
}
}
- cmsysProcess_WaitForExit(cp, nullptr);
+ while (!timedOut && !chain.Finished()) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
+ }
if (!tempOutput.empty()) {
processOutput.DecodeText(tempOutput, tempOutput);
stdOut->append(tempOutput.data(), tempOutput.size());
@@ -3523,32 +3557,32 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
}
bool result = true;
- if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
- if (retVal) {
- *retVal = cmsysProcess_GetExitValue(cp);
- } else {
- if (cmsysProcess_GetExitValue(cp) != 0) {
- result = false;
- }
- }
- } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exception) {
- const char* exception_str = cmsysProcess_GetExceptionString(cp);
- cmCTestLog(this, ERROR_MESSAGE, exception_str << std::endl);
- stdErr->append(exception_str, strlen(exception_str));
- result = false;
- } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Error) {
- const char* error_str = cmsysProcess_GetErrorString(cp);
- cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
- stdErr->append(error_str, strlen(error_str));
- result = false;
- } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Expired) {
+ if (timedOut) {
const char* error_str = "Process terminated due to timeout\n";
cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
stdErr->append(error_str, strlen(error_str));
result = false;
+ } else {
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ if (retVal) {
+ *retVal = static_cast<int>(status.ExitStatus);
+ } else {
+ if (status.ExitStatus != 0) {
+ result = false;
+ }
+ }
+ break;
+ default: {
+ cmCTestLog(this, ERROR_MESSAGE, exception.second << std::endl);
+ stdErr->append(exception.second);
+ result = false;
+ } break;
+ }
}
- cmsysProcess_Delete(cp);
return result;
}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 9a8d5a6..1644d84 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -254,10 +254,10 @@ public:
* Run command specialized for make and configure. Returns process status
* and retVal is return value or exception.
*/
- int RunMakeCommand(const std::string& command, std::string& output,
- int* retVal, const char* dir, cmDuration timeout,
- std::ostream& ofs,
- Encoding encoding = cmProcessOutput::Auto);
+ bool RunMakeCommand(const std::string& command, std::string& output,
+ int* retVal, const char* dir, cmDuration timeout,
+ std::ostream& ofs,
+ Encoding encoding = cmProcessOutput::Auto);
/** Return the current tag */
std::string GetCurrentTag();
@@ -303,10 +303,10 @@ public:
* environment variables prior to running the test. After running the test,
* environment variables are restored to their previous values.
*/
- int RunTest(std::vector<const char*> args, std::string* output, int* retVal,
- std::ostream* logfile, cmDuration testTimeOut,
- std::vector<std::string>* environment,
- Encoding encoding = cmProcessOutput::Auto);
+ bool RunTest(const std::vector<std::string>& args, std::string* output,
+ int* retVal, std::ostream* logfile, cmDuration testTimeOut,
+ std::vector<std::string>* environment,
+ Encoding encoding = cmProcessOutput::Auto);
/**
* Get the handler object
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 0c6b225..5c25cb9 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -597,15 +597,14 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& p, bool v)
this->SetProperty(p, v ? std::string{ "ON" } : std::string{ "OFF" });
}
-void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
- std::nullptr_t)
+void cmCacheManager::CacheEntry::RemoveProperty(const std::string& prop)
{
if (prop == "TYPE") {
this->Type = cmState::StringToCacheEntryType("STRING");
} else if (prop == "VALUE") {
- this->Value = "";
+ this->Value.clear();
} else {
- this->Properties.SetProperty(prop, cmValue{ nullptr });
+ this->Properties.RemoveProperty(prop);
}
}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index 5268248..ae32759 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -41,7 +41,7 @@ class cmCacheManager
bool GetPropertyAsBool(const std::string& property) const;
void SetProperty(const std::string& property, const std::string& value);
void SetProperty(const std::string& property, bool value);
- void SetProperty(const std::string& property, std::nullptr_t);
+ void RemoveProperty(const std::string& property);
void AppendProperty(const std::string& property, const std::string& value,
bool asString = false);
@@ -144,7 +144,7 @@ public:
std::string const& propName)
{
if (auto* entry = this->GetCacheEntry(key)) {
- entry->SetProperty(propName, nullptr);
+ entry->RemoveProperty(propName);
}
}
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index 94b6e18..292b9a3 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -4,6 +4,8 @@
#include <sstream>
+#include <cmext/string_view>
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -305,7 +307,7 @@ HRESULT GetRunningInstances(std::map<std::string, IUnknownPtr>& mrot)
//! we perhaps looking for any and all solutions?
bool FilesSameSolution(const std::string& slnFile, const std::string& slnName)
{
- if (slnFile == "ALL" || slnName == "ALL") {
+ if (slnFile == "ALL"_s || slnName == "ALL"_s) {
return true;
}
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index ae83b2e..2ee4f47 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -135,7 +135,6 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("cmake_path", cmCMakePathCommand);
state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand);
state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
- state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand);
state->AddBuiltinCommand("file", cmFileCommand);
state->AddBuiltinCommand("find_file", cmFindFile);
@@ -220,6 +219,9 @@ void GetScriptingCommands(cmState* state)
state->AddDisallowedCommand(
"use_mangled_mesa", cmUseMangledMesaCommand, cmPolicies::CMP0030,
"The use_mangled_mesa command should not be called; see CMP0030.");
+ state->AddDisallowedCommand(
+ "exec_program", cmExecProgramCommand, cmPolicies::CMP0153,
+ "The exec_program command should not be called; see CMP0153.");
#endif
}
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 1924235..2d6ce98 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <sstream>
+#include <type_traits>
#include <utility>
#include <cm/string_view>
@@ -172,13 +173,7 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
this->GeneratorTarget->GetLinkInformation(config)) {
std::vector<cmGeneratorTarget const*> targets;
for (auto const& item : cli->GetItems()) {
- targets.push_back(item.Target);
- }
- for (auto const* target : cli->GetObjectLibrariesLinked()) {
- targets.push_back(target);
- }
-
- for (auto const* linkee : targets) {
+ auto const* linkee = item.Target;
if (linkee &&
!linkee->IsImported()
// Skip targets that build after this one in a static lib cycle.
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index f51a1c8..7394d86 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -8,6 +8,7 @@
#include <cstdio>
#include <iterator>
#include <sstream>
+#include <type_traits>
#include <unordered_map>
#include <utility>
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 4804565..91395e2 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -29,6 +29,7 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
+#include "cmXcFramework.h"
#include "cmake.h"
// #define CM_COMPUTE_LINK_INFO_DEBUG
@@ -373,6 +374,10 @@ cmComputeLinkInformation::cmComputeLinkInformation(
this->LibraryFeatureDescriptors.emplace(
"__CMAKE_LINK_FRAMEWORK",
LibraryFeatureDescriptor{ "__CMAKE_LINK_FRAMEWORK", "<LIBRARY>" });
+ // To link xcframework using a full path
+ this->LibraryFeatureDescriptors.emplace(
+ "__CMAKE_LINK_XCFRAMEWORK",
+ LibraryFeatureDescriptor{ "__CMAKE_LINK_XCFRAMEWORK", "<LIBRARY>" });
// Check the platform policy for missing soname case.
this->NoSONameUsesPath =
@@ -519,16 +524,16 @@ cmComputeLinkInformation::GetFrameworkPathsEmitted() const
return this->FrameworkPathsEmitted;
}
-const std::set<const cmGeneratorTarget*>&
-cmComputeLinkInformation::GetSharedLibrariesLinked() const
+std::vector<std::string> const&
+cmComputeLinkInformation::GetXcFrameworkHeaderPaths() const
{
- return this->SharedLibrariesLinked;
+ return this->XcFrameworkHeaderPaths;
}
-const std::vector<const cmGeneratorTarget*>&
-cmComputeLinkInformation::GetObjectLibrariesLinked() const
+const std::set<const cmGeneratorTarget*>&
+cmComputeLinkInformation::GetSharedLibrariesLinked() const
{
- return this->ObjectLibrariesLinked;
+ return this->SharedLibrariesLinked;
}
bool cmComputeLinkInformation::Compute()
@@ -1156,12 +1161,14 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
this->AddItem(BT<std::string>(libName, item.Backtrace));
}
} else if (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- if (!tgt->HaveCxx20ModuleSources() && !tgt->HaveFortranSources(config)) {
- // Ignore object library!
- // Its object-files should already have been extracted for linking.
- } else {
- this->ObjectLibrariesLinked.push_back(entry.Target);
- }
+ this->Items.emplace_back(entry.Item, ItemIsPath::No, entry.Target);
+ } else if (this->GlobalGenerator->IsXcode() &&
+ !tgt->GetImportedXcFrameworkPath(config).empty()) {
+ this->Items.emplace_back(
+ tgt->GetImportedXcFrameworkPath(config), ItemIsPath::Yes, tgt,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "__CMAKE_LINK_XCFRAMEWORK"
+ : entry.Feature));
} else {
// Decide whether to use an import library.
cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
@@ -1201,6 +1208,25 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
this->AddRuntimeDLL(tgt);
}
}
+
+ auto xcFrameworkPath = tgt->GetImportedXcFrameworkPath(config);
+ if (!xcFrameworkPath.empty()) {
+ auto plist = cmParseXcFrameworkPlist(xcFrameworkPath, *this->Makefile,
+ item.Backtrace);
+ if (!plist) {
+ return;
+ }
+ if (auto const* library =
+ plist->SelectSuitableLibrary(*this->Makefile, item.Backtrace)) {
+ if (!library->HeadersPath.empty()) {
+ this->AddXcFrameworkHeaderPath(cmStrCat(xcFrameworkPath, '/',
+ library->LibraryIdentifier,
+ '/', library->HeadersPath));
+ }
+ } else {
+ return;
+ }
+ }
} else {
// This is not a CMake target. Use the name given.
if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s) ||
@@ -1209,6 +1235,12 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
this->Target->IsApple())) {
// This is a framework.
this->AddFrameworkItem(entry);
+ } else if (cmHasSuffix(entry.Feature, "XCFRAMEWORK"_s) ||
+ (entry.Feature == DEFAULT &&
+ cmSystemTools::IsPathToXcFramework(item.Value) &&
+ this->Target->IsApple())) {
+ // This is a framework.
+ this->AddXcFrameworkItem(entry);
} else if (cmSystemTools::FileIsFullPath(item.Value)) {
if (cmSystemTools::FileIsDirectory(item.Value)) {
// This is a directory.
@@ -1592,7 +1624,9 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
this->OldLinkDirItems.push_back(item.Value);
}
- if (target->IsFrameworkOnApple()) {
+ const bool isImportedFrameworkFolderOnApple =
+ target->IsImportedFrameworkFolderOnApple(this->Config);
+ if (target->IsFrameworkOnApple() || isImportedFrameworkFolderOnApple) {
// Add the framework directory and the framework item itself
auto fwDescriptor = this->GlobalGenerator->SplitFrameworkPath(
item.Value, cmGlobalGenerator::FrameworkFormat::Extended);
@@ -1610,16 +1644,33 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
}
if (this->GlobalGenerator->IsXcode()) {
- this->Items.emplace_back(
- item, ItemIsPath::Yes, target,
- this->FindLibraryFeature(entry.Feature == DEFAULT
- ? "__CMAKE_LINK_FRAMEWORK"
- : entry.Feature));
+ if (isImportedFrameworkFolderOnApple) {
+ if (entry.Feature == DEFAULT) {
+ this->AddLibraryFeature("FRAMEWORK");
+ this->Items.emplace_back(item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature("FRAMEWORK"));
+ } else {
+ this->Items.emplace_back(item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(entry.Feature));
+ }
+ } else {
+ this->Items.emplace_back(
+ item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "__CMAKE_LINK_FRAMEWORK"
+ : entry.Feature));
+ }
} else {
if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes,
target,
this->FindLibraryFeature(entry.Feature));
+ } else if (entry.Feature == DEFAULT &&
+ isImportedFrameworkFolderOnApple) {
+ this->AddLibraryFeature("FRAMEWORK");
+ this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes,
+ target,
+ this->FindLibraryFeature("FRAMEWORK"));
} else {
this->Items.emplace_back(
item, ItemIsPath::Yes, target,
@@ -1929,6 +1980,46 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry)
}
}
+void cmComputeLinkInformation::AddXcFrameworkItem(LinkEntry const& entry)
+{
+ auto plist = cmParseXcFrameworkPlist(entry.Item.Value, *this->Makefile,
+ entry.Item.Backtrace);
+ if (!plist) {
+ return;
+ }
+
+ if (auto const* lib =
+ plist->SelectSuitableLibrary(*this->Makefile, entry.Item.Backtrace)) {
+ if (this->GlobalGenerator->IsXcode()) {
+ this->Items.emplace_back(
+ entry.Item.Value, ItemIsPath::Yes, nullptr,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "__CMAKE_LINK_XCFRAMEWORK"
+ : entry.Feature));
+ } else {
+ auto libraryPath = cmStrCat(
+ entry.Item.Value, '/', lib->LibraryIdentifier, '/', lib->LibraryPath);
+ LinkEntry libraryEntry(
+ BT<std::string>(libraryPath, entry.Item.Backtrace), entry.Target);
+
+ if (cmSystemTools::IsPathToFramework(libraryPath) &&
+ this->Target->IsApple()) {
+ // This is a framework.
+ this->AddFrameworkItem(libraryEntry);
+ } else {
+ this->Depends.push_back(libraryPath);
+ this->AddFullItem(libraryEntry);
+ this->AddLibraryRuntimeInfo(libraryPath);
+ if (!lib->HeadersPath.empty()) {
+ this->AddXcFrameworkHeaderPath(cmStrCat(entry.Item.Value, '/',
+ lib->LibraryIdentifier, '/',
+ lib->HeadersPath));
+ }
+ }
+ }
+ }
+}
+
void cmComputeLinkInformation::DropDirectoryItem(BT<std::string> const& item)
{
// A full path to a directory was found as a link item. Warn the
@@ -1966,6 +2057,11 @@ void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
}
}
+void cmComputeLinkInformation::AddXcFrameworkHeaderPath(std::string const& p)
+{
+ this->XcFrameworkHeaderPaths.push_back(p);
+}
+
bool cmComputeLinkInformation::CheckSharedLibNoSOName(LinkEntry const& entry)
{
// This platform will use the path to a library as its soname if the
@@ -2235,16 +2331,20 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo(
if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
return;
}
+ auto const* info = target->GetImportInfo(this->Config);
// Try to get the soname of the library. Only files with this name
// could possibly conflict.
- std::string soName = target->GetSOName(this->Config);
- const char* soname = soName.empty() ? nullptr : soName.c_str();
-
- // Include this library in the runtime path ordering.
- this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
- if (this->LinkWithRuntimePath) {
- this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
+ const char* soname =
+ (!info || info->SOName.empty()) ? nullptr : info->SOName.c_str();
+
+ // If this shared library has a known runtime artifact (IMPORTED_LOCATION),
+ // include its location in the runtime path ordering.
+ if (!info || !info->Location.empty()) {
+ this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
+ if (this->LinkWithRuntimePath) {
+ this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
+ }
}
}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 8393a29..a988307 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -88,6 +88,7 @@ public:
std::vector<std::string> const& GetDepends() const;
std::vector<std::string> const& GetFrameworkPaths() const;
std::set<std::string> const& GetFrameworkPathsEmitted() const;
+ std::vector<std::string> const& GetXcFrameworkHeaderPaths() const;
std::string GetLinkLanguage() const { return this->LinkLanguage; }
std::vector<std::string> const& GetRuntimeSearchPath() const;
std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
@@ -96,8 +97,6 @@ public:
std::string GetRPathString(bool for_install) const;
std::string GetChrpathString() const;
std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
- std::vector<cmGeneratorTarget const*> const& GetObjectLibrariesLinked()
- const;
std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
{
return this->RuntimeDLLs;
@@ -132,9 +131,9 @@ private:
std::vector<std::string> Directories;
std::vector<std::string> Depends;
std::vector<std::string> FrameworkPaths;
+ std::vector<std::string> XcFrameworkHeaderPaths;
std::vector<std::string> RuntimeSearchPath;
std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
- std::vector<cmGeneratorTarget const*> ObjectLibrariesLinked;
std::vector<cmGeneratorTarget const*> RuntimeDLLs;
// Context information.
@@ -204,6 +203,7 @@ private:
bool CheckImplicitDirItem(LinkEntry const& entry);
void AddUserItem(LinkEntry const& entry, bool pathNotKnown);
void AddFrameworkItem(LinkEntry const& entry);
+ void AddXcFrameworkItem(LinkEntry const& entry);
void DropDirectoryItem(BT<std::string> const& item);
bool CheckSharedLibNoSOName(LinkEntry const& entry);
void AddSharedLibNoSOName(LinkEntry const& entry);
@@ -214,6 +214,8 @@ private:
void AddFrameworkPath(std::string const& p);
std::set<std::string> FrameworkPathsEmitted;
+ void AddXcFrameworkHeaderPath(std::string const& p);
+
// Linker search path computation.
std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
bool FinishLinkerSearchDirectories();
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
index 9486b16..4f42206 100644
--- a/Source/cmConditionEvaluator.h
+++ b/Source/cmConditionEvaluator.h
@@ -10,7 +10,7 @@
#include <cmext/string_view>
#include "cmListFileCache.h"
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
#include "cmPolicies.h"
#include "cmValue.h"
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 7d4ab50..2ec62d9 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -7,7 +7,6 @@
#include <cstring>
#include <set>
#include <sstream>
-#include <type_traits>
#include <utility>
#include <cm/string_view>
@@ -18,6 +17,7 @@
#include "cmArgumentParser.h"
#include "cmConfigureLog.h"
+#include "cmExperimental.h"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
@@ -167,7 +167,9 @@ auto const TryCompileBaseArgParser =
auto const TryCompileBaseSourcesArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
- .Bind("SOURCES"_s, &Arguments::Sources)
+ .Bind("SOURCES_TYPE"_s, &Arguments::SetSourceType)
+ .BindWithContext("SOURCES"_s, &Arguments::Sources,
+ &Arguments::SourceTypeContext)
.Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs,
ArgumentParser::ExpectAtLeast{ 0 })
.Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries)
@@ -184,9 +186,12 @@ auto const TryCompileBaseSourcesArgParser =
auto const TryCompileBaseNewSourcesArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseSourcesArgParser }
- .Bind("SOURCE_FROM_CONTENT"_s, &Arguments::SourceFromContent)
- .Bind("SOURCE_FROM_VAR"_s, &Arguments::SourceFromVar)
- .Bind("SOURCE_FROM_FILE"_s, &Arguments::SourceFromFile)
+ .BindWithContext("SOURCE_FROM_CONTENT"_s, &Arguments::SourceFromContent,
+ &Arguments::SourceTypeContext)
+ .BindWithContext("SOURCE_FROM_VAR"_s, &Arguments::SourceFromVar,
+ &Arguments::SourceTypeContext)
+ .BindWithContext("SOURCE_FROM_FILE"_s, &Arguments::SourceFromFile,
+ &Arguments::SourceTypeContext)
/* keep semicolon on own line */;
auto const TryCompileBaseProjectArgParser =
@@ -221,17 +226,49 @@ auto const TryRunOldArgParser = makeTryRunParser(TryCompileOldArgParser);
std::string const TryCompileDefaultConfig = "DEBUG";
}
+ArgumentParser::Continue cmCoreTryCompile::Arguments::SetSourceType(
+ cm::string_view sourceType)
+{
+ bool matched = false;
+ if (sourceType == "NORMAL"_s) {
+ this->SourceTypeContext = SourceType::Normal;
+ matched = true;
+ } else if (sourceType == "CXX_MODULE"_s) {
+ bool const supportCxxModuleSources = cmExperimental::HasSupportEnabled(
+ *this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+ if (supportCxxModuleSources) {
+ this->SourceTypeContext = SourceType::CxxModule;
+ matched = true;
+ }
+ }
+
+ if (!matched && this->SourceTypeError.empty()) {
+ bool const supportCxxModuleSources = cmExperimental::HasSupportEnabled(
+ *this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+ auto const* message = "'SOURCE'";
+ if (supportCxxModuleSources) {
+ message = "one of 'SOURCE' or 'CXX_MODULE'";
+ }
+ // Only remember one error at a time; all other errors related to argument
+ // parsing are "indicate one error and return" anyways.
+ this->SourceTypeError =
+ cmStrCat("Invalid 'SOURCE_TYPE' '", sourceType, "'; must be ", message);
+ }
+ return ArgumentParser::Continue::Yes;
+}
+
Arguments cmCoreTryCompile::ParseArgs(
const cmRange<std::vector<std::string>::const_iterator>& args,
const cmArgumentParser<Arguments>& parser,
std::vector<std::string>& unparsedArguments)
{
- auto arguments = parser.Parse(args, &unparsedArguments, 0);
+ Arguments arguments{ this->Makefile };
+ parser.Parse(arguments, args, &unparsedArguments, 0);
if (!arguments.MaybeReportError(*(this->Makefile)) &&
!unparsedArguments.empty()) {
std::string m = "Unknown arguments:";
for (const auto& i : unparsedArguments) {
- m = cmStrCat(m, "\n \"", i, "\"");
+ m = cmStrCat(m, "\n \"", i, '"');
}
this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
}
@@ -345,7 +382,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("<bindir> is not an absolute path:\n '",
- *arguments.BinaryDirectory, "'"));
+ *arguments.BinaryDirectory, '\''));
return cm::nullopt;
}
this->BinaryDirectory = *arguments.BinaryDirectory;
@@ -377,7 +414,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
cmStrCat("Only libraries may be used as try_compile or try_run "
"IMPORTED LINK_LIBRARIES. Got ",
tgt->GetName(), " of type ",
- cmState::GetTargetTypeName(tgt->GetType()), "."));
+ cmState::GetTargetTypeName(tgt->GetType()), '.'));
return cm::nullopt;
}
if (tgt->IsImported()) {
@@ -434,6 +471,11 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
"SOURCE_FROM_FILE requires exactly two arguments");
return cm::nullopt;
}
+ if (!arguments.SourceTypeError.empty()) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ arguments.SourceTypeError);
+ return cm::nullopt;
+ }
} else {
// only valid for srcfile signatures
if (!arguments.LangProps.empty()) {
@@ -478,59 +520,62 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
std::map<std::string, std::string> cmakeVariables;
- std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
+ std::string outFileName = cmStrCat(this->BinaryDirectory, "/CMakeLists.txt");
// which signature are we using? If we are using var srcfile bindir
if (this->SrcFileSignature) {
// remove any CMakeCache.txt files so we will have a clean test
- std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt";
+ std::string ccFile = cmStrCat(this->BinaryDirectory, "/CMakeCache.txt");
cmSystemTools::RemoveFile(ccFile);
// Choose sources.
- std::vector<std::string> sources;
+ std::vector<std::pair<std::string, Arguments::SourceType>> sources;
if (arguments.Sources) {
sources = std::move(*arguments.Sources);
} else if (arguments.SourceDirectoryOrFile) {
- sources.emplace_back(*arguments.SourceDirectoryOrFile);
+ sources.emplace_back(*arguments.SourceDirectoryOrFile,
+ Arguments::SourceType::Directory);
}
if (arguments.SourceFromContent) {
auto const k = arguments.SourceFromContent->size();
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
- const auto& name = (*arguments.SourceFromContent)[i + 0];
- const auto& content = (*arguments.SourceFromContent)[i + 1];
+ const auto& name = (*arguments.SourceFromContent)[i + 0].first;
+ const auto& content = (*arguments.SourceFromContent)[i + 1].first;
auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT");
if (out.empty()) {
return cm::nullopt;
}
- sources.emplace_back(std::move(out));
+ sources.emplace_back(std::move(out),
+ (*arguments.SourceFromContent)[i + 0].second);
}
}
if (arguments.SourceFromVar) {
auto const k = arguments.SourceFromVar->size();
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
- const auto& name = (*arguments.SourceFromVar)[i + 0];
- const auto& var = (*arguments.SourceFromVar)[i + 1];
+ const auto& name = (*arguments.SourceFromVar)[i + 0].first;
+ const auto& var = (*arguments.SourceFromVar)[i + 1].first;
const auto& content = this->Makefile->GetDefinition(var);
auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR");
if (out.empty()) {
return cm::nullopt;
}
- sources.emplace_back(std::move(out));
+ sources.emplace_back(std::move(out),
+ (*arguments.SourceFromVar)[i + 0].second);
}
}
if (arguments.SourceFromFile) {
auto const k = arguments.SourceFromFile->size();
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
- const auto& dst = (*arguments.SourceFromFile)[i + 0];
- const auto& src = (*arguments.SourceFromFile)[i + 1];
+ const auto& dst = (*arguments.SourceFromFile)[i + 0].first;
+ const auto& src = (*arguments.SourceFromFile)[i + 1].first;
if (!cmSystemTools::GetFilenamePath(dst).empty()) {
const auto& msg =
- cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\"");
+ cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, '"');
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
return cm::nullopt;
}
- auto dstPath = cmStrCat(this->BinaryDirectory, "/", dst);
+ auto dstPath = cmStrCat(this->BinaryDirectory, '/', dst);
auto const result = cmSystemTools::CopyFileAlways(src, dstPath);
if (!result.IsSuccess()) {
const auto& msg = cmStrCat("SOURCE_FROM_FILE failed to copy \"", src,
@@ -539,7 +584,8 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
return cm::nullopt;
}
- sources.emplace_back(std::move(dstPath));
+ sources.emplace_back(std::move(dstPath),
+ (*arguments.SourceFromFile)[i + 0].second);
}
}
// TODO: ensure sources is not empty
@@ -547,17 +593,21 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
// Detect languages to enable.
cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
std::set<std::string> testLangs;
- for (std::string const& si : sources) {
+ for (auto const& source : sources) {
+ auto const& si = source.first;
std::string ext = cmSystemTools::GetFilenameLastExtension(si);
std::string lang = gg->GetLanguageFromExtension(ext.c_str());
if (!lang.empty()) {
testLangs.insert(lang);
} else {
std::ostringstream err;
- err << "Unknown extension \"" << ext << "\" for file\n"
- << " " << si << "\n"
- << "try_compile() works only for enabled languages. "
- << "Currently these are:\n ";
+ err << "Unknown extension \"" << ext
+ << "\" for file\n"
+ " "
+ << si
+ << "\n"
+ "try_compile() works only for enabled languages. "
+ "Currently these are:\n ";
std::vector<std::string> langs;
gg->GetEnabledLanguages(langs);
err << cmJoin(langs, " ");
@@ -586,7 +636,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
std::ostringstream e;
/* clang-format off */
e << "Failed to open\n"
- << " " << outFileName << "\n"
+ " " << outFileName << "\n"
<< cmSystemTools::GetLastSystemError();
/* clang-format on */
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -654,9 +704,9 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
std::string projectLangs;
for (std::string const& li : testLangs) {
- projectLangs += " " + li;
+ projectLangs += cmStrCat(' ', li);
std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE";
- std::string rulesOverrideLang = cmStrCat(rulesOverrideBase, "_", li);
+ std::string rulesOverrideLang = cmStrCat(rulesOverrideBase, '_', li);
if (cmValue rulesOverridePath =
this->Makefile->GetDefinition(rulesOverrideLang)) {
fprintf(fout, "set(%s \"%s\")\n", rulesOverrideLang.c_str(),
@@ -689,7 +739,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
}
fprintf(fout, "set(CMAKE_VERBOSE_MAKEFILE 1)\n");
for (std::string const& li : testLangs) {
- std::string langFlags = "CMAKE_" + li + "_FLAGS";
+ std::string langFlags = cmStrCat("CMAKE_", li, "_FLAGS");
cmValue flags = this->Makefile->GetDefinition(langFlags);
fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li.c_str(),
cmOutputConverter::EscapeForCMake(*flags).c_str());
@@ -793,10 +843,10 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
}
if (!targets.empty()) {
- std::string fname = "/" + std::string(targetName) + "Targets.cmake";
+ std::string fname = cmStrCat('/', targetName, "Targets.cmake");
cmExportTryCompileFileGenerator tcfg(gg, targets, this->Makefile,
testLangs);
- tcfg.SetExportFile((this->BinaryDirectory + fname).c_str());
+ tcfg.SetExportFile(cmStrCat(this->BinaryDirectory, fname).c_str());
tcfg.SetConfig(tcConfig);
if (!tcfg.GenerateImportFile()) {
@@ -834,17 +884,43 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
this->BinaryDirectory.c_str());
/* Create the actual executable. */
- fprintf(fout, "add_executable(%s", targetName.c_str());
+ fprintf(fout, "add_executable(%s)\n", targetName.c_str());
} else // if (targetType == cmStateEnums::STATIC_LIBRARY)
{
/* Put the static library at a known location (for COPY_FILE). */
fprintf(fout, "set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"%s\")\n",
this->BinaryDirectory.c_str());
/* Create the actual static library. */
- fprintf(fout, "add_library(%s STATIC", targetName.c_str());
+ fprintf(fout, "add_library(%s STATIC)\n", targetName.c_str());
}
- for (std::string const& si : sources) {
- fprintf(fout, " \"%s\"", si.c_str());
+ fprintf(fout, "target_sources(%s PRIVATE\n", targetName.c_str());
+ std::string file_set_name;
+ bool in_file_set = false;
+ for (auto const& source : sources) {
+ auto const& si = source.first;
+ switch (source.second) {
+ case Arguments::SourceType::Normal: {
+ if (in_file_set) {
+ fprintf(fout, " PRIVATE\n");
+ in_file_set = false;
+ }
+ } break;
+ case Arguments::SourceType::CxxModule: {
+ if (!in_file_set) {
+ file_set_name += 'a';
+ fprintf(fout,
+ " PRIVATE FILE_SET %s TYPE CXX_MODULES BASE_DIRS \"%s\" "
+ "FILES\n",
+ file_set_name.c_str(),
+ this->Makefile->GetCurrentSourceDirectory().c_str());
+ in_file_set = true;
+ }
+ } break;
+ case Arguments::SourceType::Directory:
+ /* Handled elsewhere. */
+ break;
+ }
+ fprintf(fout, " \"%s\"\n", si.c_str());
// Add dependencies on any non-temporary sources.
if (!IsTemporary(si)) {
@@ -964,7 +1040,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
if (arguments.LinkLibraries) {
std::string libsToLink = " ";
for (std::string const& i : *arguments.LinkLibraries) {
- libsToLink += "\"" + cmTrimWhitespace(i) + "\" ";
+ libsToLink += cmStrCat('"', cmTrimWhitespace(i), "\" ");
}
fprintf(fout, "target_link_libraries(%s %s)\n", targetName.c_str(),
libsToLink.c_str());
@@ -1022,6 +1098,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
vars.emplace("CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"_s);
+ vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
if (cmValue varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
@@ -1063,14 +1140,33 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
if (cmValue tcArchs = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES)) {
vars.erase(kCMAKE_OSX_ARCHITECTURES);
- std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + *tcArchs;
+ std::string flag = cmStrCat("-DCMAKE_OSX_ARCHITECTURES=", *tcArchs);
arguments.CMakeFlags.emplace_back(std::move(flag));
cmakeVariables.emplace("CMAKE_OSX_ARCHITECTURES", *tcArchs);
}
+ // Pass down CMAKE_EXPERIMENTAL_* feature flags
+ for (std::size_t i = 0;
+ i < static_cast<std::size_t>(cmExperimental::Feature::Sentinel);
+ i++) {
+ auto const& data = cmExperimental::DataForFeature(
+ static_cast<cmExperimental::Feature>(i));
+ if (data.ForwardThroughTryCompile ==
+ cmExperimental::TryCompileCondition::Always ||
+ (data.ForwardThroughTryCompile ==
+ cmExperimental::TryCompileCondition::SkipCompilerChecks &&
+ arguments.CMakeInternal != "ABI"_s &&
+ arguments.CMakeInternal != "FEATURE_TESTING"_s)) {
+ vars.insert(data.Variable);
+ for (auto const& var : data.TryCompileVariables) {
+ vars.insert(var);
+ }
+ }
+ }
+
for (std::string const& var : vars) {
if (cmValue val = this->Makefile->GetDefinition(var)) {
- std::string flag = "-D" + var + "=" + *val;
+ std::string flag = cmStrCat("-D", var, '=', *val);
arguments.CMakeFlags.emplace_back(std::move(flag));
cmakeVariables.emplace(var, *val);
}
@@ -1081,7 +1177,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
// Forward the GHS variables to the inner project cache.
for (std::string const& var : ghs_platform_vars) {
if (cmValue val = this->Makefile->GetDefinition(var)) {
- std::string flag = "-D" + var + "=" + "'" + *val + "'";
+ std::string flag = cmStrCat("-D", var, "=\'", *val, '\'');
arguments.CMakeFlags.emplace_back(std::move(flag));
cmakeVariables.emplace(var, *val);
}
@@ -1143,11 +1239,11 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
}
/* clang-format off */
err = cmStrCat(
- "Cannot copy output executable\n",
- " '", this->OutputFile, "'\n",
- "to destination specified by COPY_FILE:\n",
- " '", copyFile, "'\n",
- "because:\n",
+ "Cannot copy output executable\n"
+ " '", this->OutputFile, "'\n"
+ "to destination specified by COPY_FILE:\n"
+ " '", copyFile, "'\n"
+ "because:\n"
" ", err, "\n",
this->FindErrorMessage);
/* clang-format on */
@@ -1192,10 +1288,10 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
}
if (!IsTemporary(binDir)) {
- cmSystemTools::Error(
+ cmSystemTools::Error(cmStrCat(
"TRY_COMPILE attempt to remove -rf directory that does not contain "
- "CMakeTmp or CMakeScratch: \"" +
- binDir + "\"");
+ "CMakeTmp or CMakeScratch: \"",
+ binDir, '"'));
return;
}
@@ -1208,8 +1304,7 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
// Do not delete NFS temporary files.
!cmHasPrefix(fileName, ".nfs")) {
if (deletedFiles.insert(fileName).second) {
- std::string const fullPath =
- std::string(binDir).append("/").append(fileName);
+ std::string const fullPath = cmStrCat(binDir, '/', fileName);
if (cmSystemTools::FileIsSymlink(fullPath)) {
cmSystemTools::RemoveFile(fullPath);
} else if (cmSystemTools::FileIsDirectory(fullPath)) {
@@ -1293,12 +1388,12 @@ std::string cmCoreTryCompile::WriteSource(std::string const& filename,
{
if (!cmSystemTools::GetFilenamePath(filename).empty()) {
const auto& msg =
- cmStrCat(command, " given invalid filename \"", filename, "\"");
+ cmStrCat(command, " given invalid filename \"", filename, '"');
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
return {};
}
- auto filepath = cmStrCat(this->BinaryDirectory, "/", filename);
+ auto filepath = cmStrCat(this->BinaryDirectory, '/', filename);
cmsys::ofstream file{ filepath.c_str(), std::ios::out };
if (!file) {
const auto& msg =
@@ -1309,7 +1404,7 @@ std::string cmCoreTryCompile::WriteSource(std::string const& filename,
file << content;
if (!file) {
- const auto& msg = cmStrCat(command, " failed to write \"", filename, "\"");
+ const auto& msg = cmStrCat(command, " failed to write \"", filename, '"');
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
return {};
}
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index c185c68..3217a1b 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -6,9 +6,11 @@
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include <cm/optional>
+#include <cm/string_view>
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
@@ -51,17 +53,36 @@ public:
struct Arguments : public ArgumentParser::ParseResult
{
+ Arguments(cmMakefile const* mf)
+ : Makefile(mf)
+ {
+ }
+
+ cmMakefile const* Makefile;
+
+ enum class SourceType
+ {
+ Normal,
+ CxxModule,
+ Directory,
+ };
+
cm::optional<std::string> CompileResultVariable;
cm::optional<std::string> BinaryDirectory;
cm::optional<std::string> SourceDirectoryOrFile;
cm::optional<std::string> ProjectName;
cm::optional<std::string> TargetName;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> Sources;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
+ Sources;
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
SourceFromContent;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
SourceFromVar;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
SourceFromFile;
ArgumentParser::MaybeEmpty<std::vector<std::string>> CMakeFlags{
1, "CMAKE_FLAGS"
@@ -79,6 +100,10 @@ public:
bool NoCache = false;
bool NoLog = false;
+ ArgumentParser::Continue SetSourceType(cm::string_view sourceType);
+ SourceType SourceTypeContext = SourceType::Normal;
+ std::string SourceTypeError;
+
// Argument for try_run only.
// Keep in sync with warnings in cmCoreTryCompile::ParseArgs.
cm::optional<std::string> CompileOutputVariable;
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index e12cf70..9958e4d 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -194,6 +194,16 @@ void cmCustomCommand::SetJobPool(const std::string& job_pool)
this->JobPool = job_pool;
}
+bool cmCustomCommand::GetJobserverAware() const
+{
+ return this->JobserverAware;
+}
+
+void cmCustomCommand::SetJobserverAware(bool b)
+{
+ this->JobserverAware = b;
+}
+
#define DEFINE_CC_POLICY_ACCESSOR(P) \
cmPolicies::PolicyStatus cmCustomCommand::Get##P##Status() const \
{ \
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 1e68dbf..167e601 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -115,6 +115,11 @@ public:
const std::string& GetJobPool() const;
void SetJobPool(const std::string& job_pool);
+ /** Set/Get whether this custom command should be given access to the
+ jobserver (if possible). */
+ bool GetJobserverAware() const;
+ void SetJobserverAware(bool b);
+
#define DECLARE_CC_POLICY_ACCESSOR(P) \
cmPolicies::PolicyStatus Get##P##Status() const;
CM_FOR_EACH_CUSTOM_COMMAND_POLICY(DECLARE_CC_POLICY_ACCESSOR)
@@ -139,6 +144,7 @@ private:
std::string WorkingDirectory;
std::string Depfile;
std::string JobPool;
+ bool JobserverAware = false;
bool HaveComment = false;
bool EscapeAllowMakeVars = false;
bool EscapeOldStyle = true;
diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx
index e836a2a..e6c10c6 100644
--- a/Source/cmCxxModuleMapper.cxx
+++ b/Source/cmCxxModuleMapper.cxx
@@ -74,8 +74,62 @@ CxxBmiLocation CxxModuleLocations::BmiGeneratorPathForModule(
namespace {
+struct TransitiveUsage
+{
+ TransitiveUsage(std::string name, std::string location, LookupMethod method)
+ : LogicalName(std::move(name))
+ , Location(std::move(location))
+ , Method(method)
+ {
+ }
+
+ std::string LogicalName;
+ std::string Location;
+ LookupMethod Method;
+};
+
+std::vector<TransitiveUsage> GetTransitiveUsages(
+ CxxModuleLocations const& loc, std::vector<cmSourceReqInfo> const& required,
+ CxxModuleUsage const& usages)
+{
+ std::set<std::string> transitive_usage_directs;
+ std::set<std::string> transitive_usage_names;
+
+ std::vector<TransitiveUsage> all_usages;
+
+ for (auto const& r : required) {
+ auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
+ if (bmi_loc.IsKnown()) {
+ all_usages.emplace_back(r.LogicalName, bmi_loc.Location(), r.Method);
+ transitive_usage_directs.insert(r.LogicalName);
+
+ // Insert transitive usages.
+ auto transitive_usages = usages.Usage.find(r.LogicalName);
+ if (transitive_usages != usages.Usage.end()) {
+ transitive_usage_names.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ }
+ }
+ }
+
+ for (auto const& transitive_name : transitive_usage_names) {
+ if (transitive_usage_directs.count(transitive_name)) {
+ continue;
+ }
+
+ auto module_ref = usages.Reference.find(transitive_name);
+ if (module_ref != usages.Reference.end()) {
+ all_usages.emplace_back(transitive_name, module_ref->second.Path,
+ module_ref->second.Method);
+ }
+ }
+
+ return all_usages;
+}
+
std::string CxxModuleMapContentClang(CxxModuleLocations const& loc,
- cmScanDepInfo const& obj)
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages)
{
std::stringstream mm;
@@ -98,12 +152,11 @@ std::string CxxModuleMapContentClang(CxxModuleLocations const& loc,
break;
}
}
- for (auto const& r : obj.Requires) {
- auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
- if (bmi_loc.IsKnown()) {
- mm << "-fmodule-file=" << r.LogicalName << "=" << bmi_loc.Location()
- << '\n';
- }
+
+ auto all_usages = GetTransitiveUsages(loc, obj.Requires, usages);
+ for (auto const& usage : all_usages) {
+ mm << "-fmodule-file=" << usage.LogicalName << '=' << usage.Location
+ << '\n';
}
return mm.str();
@@ -122,7 +175,7 @@ std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
// generate any).
// Write the root directory to use for module paths.
- mm << "$root " << loc.RootDirectory << "\n";
+ mm << "$root " << loc.RootDirectory << '\n';
for (auto const& p : obj.Provides) {
auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName);
@@ -180,37 +233,11 @@ std::string CxxModuleMapContentMsvc(CxxModuleLocations const& loc,
}
}
- std::set<std::string> transitive_usage_directs;
- std::set<std::string> transitive_usage_names;
-
- for (auto const& r : obj.Requires) {
- auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
- if (bmi_loc.IsKnown()) {
- auto flag = flag_for_method(r.Method);
-
- mm << flag << ' ' << r.LogicalName << '=' << bmi_loc.Location() << "\n";
- transitive_usage_directs.insert(r.LogicalName);
-
- // Insert transitive usages.
- auto transitive_usages = usages.Usage.find(r.LogicalName);
- if (transitive_usages != usages.Usage.end()) {
- transitive_usage_names.insert(transitive_usages->second.begin(),
- transitive_usages->second.end());
- }
- }
- }
-
- for (auto const& transitive_name : transitive_usage_names) {
- if (transitive_usage_directs.count(transitive_name)) {
- continue;
- }
+ auto all_usages = GetTransitiveUsages(loc, obj.Requires, usages);
+ for (auto const& usage : all_usages) {
+ auto flag = flag_for_method(usage.Method);
- auto module_ref = usages.Reference.find(transitive_name);
- if (module_ref != usages.Reference.end()) {
- auto flag = flag_for_method(module_ref->second.Method);
- mm << flag << ' ' << transitive_name << '=' << module_ref->second.Path
- << "\n";
- }
+ mm << flag << ' ' << usage.LogicalName << '=' << usage.Location << '\n';
}
return mm.str();
@@ -393,7 +420,7 @@ std::string CxxModuleMapContent(CxxModuleMapFormat format,
{
switch (format) {
case CxxModuleMapFormat::Clang:
- return CxxModuleMapContentClang(loc, obj);
+ return CxxModuleMapContentClang(loc, obj, usages);
case CxxModuleMapFormat::Gcc:
return CxxModuleMapContentGcc(loc, obj);
case CxxModuleMapFormat::Msvc:
diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h
index ef01e48..34111f7 100644
--- a/Source/cmCxxModuleMapper.h
+++ b/Source/cmCxxModuleMapper.h
@@ -13,7 +13,8 @@
#include <cm/optional>
#include <cmext/string_view>
-#include "cmScanDepFormat.h"
+enum class LookupMethod;
+struct cmScanDepInfo;
enum class CxxModuleMapFormat
{
diff --git a/Source/cmCxxModuleUsageEffects.cxx b/Source/cmCxxModuleUsageEffects.cxx
new file mode 100644
index 0000000..eea5245
--- /dev/null
+++ b/Source/cmCxxModuleUsageEffects.cxx
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCxxModuleUsageEffects.h"
+
+cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(
+ cmGeneratorTarget const* /*gt*/)
+ : Hash("0000000000000000000000000000000000000000")
+{
+ // TODO: collect information from the generator target as to what might
+ // affect module consumption.
+}
+
+void cmCxxModuleUsageEffects::ApplyToTarget(cmTarget* /*tgt*/)
+{
+ // TODO: apply the information collected in the constructor
+}
+
+std::string const& cmCxxModuleUsageEffects::GetHash() const
+{
+ return this->Hash;
+}
diff --git a/Source/cmCxxModuleUsageEffects.h b/Source/cmCxxModuleUsageEffects.h
new file mode 100644
index 0000000..a63919c
--- /dev/null
+++ b/Source/cmCxxModuleUsageEffects.h
@@ -0,0 +1,22 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+class cmGeneratorTarget;
+class cmTarget;
+
+class cmCxxModuleUsageEffects
+{
+public:
+ cmCxxModuleUsageEffects(cmGeneratorTarget const* gt);
+
+ void ApplyToTarget(cmTarget* tgt);
+ std::string const& GetHash() const;
+
+private:
+ std::string Hash;
+};
diff --git a/Source/cmDebuggerAdapter.h b/Source/cmDebuggerAdapter.h
index f261d88..3403b36 100644
--- a/Source/cmDebuggerAdapter.h
+++ b/Source/cmDebuggerAdapter.h
@@ -16,7 +16,7 @@
#include <cm3p/cppdap/io.h> // IWYU pragma: keep
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
class cmListFileFunction;
class cmMakefile;
diff --git a/Source/cmDebuggerBreakpointManager.cxx b/Source/cmDebuggerBreakpointManager.cxx
index 4ae6728..db18c6e 100644
--- a/Source/cmDebuggerBreakpointManager.cxx
+++ b/Source/cmDebuggerBreakpointManager.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
-#include <memory>
#include <utility>
#include <cm3p/cppdap/optional.h>
diff --git a/Source/cmDebuggerBreakpointManager.h b/Source/cmDebuggerBreakpointManager.h
index 747722f..815262a 100644
--- a/Source/cmDebuggerBreakpointManager.h
+++ b/Source/cmDebuggerBreakpointManager.h
@@ -14,11 +14,9 @@
#include <cm3p/cppdap/protocol.h>
-class cmListFileFunction;
+#include "cmDebuggerSourceBreakpoint.h"
-namespace cmDebugger {
-class cmDebuggerSourceBreakpoint;
-}
+class cmListFileFunction;
namespace dap {
class Session;
diff --git a/Source/cmDebuggerExceptionManager.h b/Source/cmDebuggerExceptionManager.h
index b819128..4c044d7 100644
--- a/Source/cmDebuggerExceptionManager.h
+++ b/Source/cmDebuggerExceptionManager.h
@@ -5,7 +5,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <cstddef>
-#include <functional>
#include <mutex>
#include <string>
#include <unordered_map>
@@ -14,7 +13,7 @@
#include <cm3p/cppdap/protocol.h>
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
namespace dap {
class Session;
diff --git a/Source/cmDebuggerPipeConnection.cxx b/Source/cmDebuggerPipeConnection.cxx
deleted file mode 100644
index 1b54346..0000000
--- a/Source/cmDebuggerPipeConnection.cxx
+++ /dev/null
@@ -1,293 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmDebuggerPipeConnection.h"
-
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-#include <stdexcept>
-#include <utility>
-
-namespace cmDebugger {
-
-struct write_req_t
-{
- uv_write_t req;
- uv_buf_t buf;
-};
-
-cmDebuggerPipeBase::cmDebuggerPipeBase(std::string name)
- : PipeName(std::move(name))
-{
- Loop.init();
- LoopExit.init(
- *Loop, [](uv_async_t* handle) { uv_stop((uv_loop_t*)handle->data); },
- Loop);
- WriteEvent.init(
- *Loop,
- [](uv_async_t* handle) {
- auto* conn = static_cast<cmDebuggerPipeBase*>(handle->data);
- conn->WriteInternal();
- },
- this);
- PipeClose.init(
- *Loop,
- [](uv_async_t* handle) {
- auto* conn = static_cast<cmDebuggerPipeBase*>(handle->data);
- if (conn->Pipe.get()) {
- conn->Pipe->data = nullptr;
- conn->Pipe.reset();
- }
- },
- this);
-}
-
-void cmDebuggerPipeBase::WaitForConnection()
-{
- std::unique_lock<std::mutex> lock(Mutex);
- Connected.wait(lock, [this] { return isOpen() || FailedToOpen; });
- if (FailedToOpen) {
- throw std::runtime_error("Failed to open debugger connection.");
- }
-}
-
-void cmDebuggerPipeBase::close()
-{
- std::unique_lock<std::mutex> lock(Mutex);
-
- CloseConnection();
- PipeClose.send();
- lock.unlock();
- ReadReady.notify_all();
-}
-
-size_t cmDebuggerPipeBase::read(void* buffer, size_t n)
-{
- std::unique_lock<std::mutex> lock(Mutex);
- ReadReady.wait(lock, [this] { return !isOpen() || !ReadBuffer.empty(); });
-
- if (!isOpen() && ReadBuffer.empty()) {
- return 0;
- }
-
- auto size = std::min(n, ReadBuffer.size());
- memcpy(buffer, ReadBuffer.data(), size);
- ReadBuffer.erase(0, size);
- return size;
-}
-
-bool cmDebuggerPipeBase::write(const void* buffer, size_t n)
-{
- std::unique_lock<std::mutex> lock(Mutex);
- WriteBuffer.append(static_cast<const char*>(buffer), n);
- lock.unlock();
- WriteEvent.send();
-
- lock.lock();
- WriteComplete.wait(lock, [this] { return WriteBuffer.empty(); });
- return true;
-}
-
-void cmDebuggerPipeBase::StopLoop()
-{
- LoopExit.send();
-
- if (LoopThread.joinable()) {
- LoopThread.join();
- }
-}
-
-void cmDebuggerPipeBase::BufferData(const std::string& data)
-{
- std::unique_lock<std::mutex> lock(Mutex);
- ReadBuffer += data;
- lock.unlock();
- ReadReady.notify_all();
-}
-
-void cmDebuggerPipeBase::WriteInternal()
-{
- std::unique_lock<std::mutex> lock(Mutex);
- auto n = WriteBuffer.length();
- assert(this->Pipe.get());
- write_req_t* req = new write_req_t;
- req->req.data = &WriteComplete;
- char* rawBuffer = new char[n];
- req->buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(n));
- memcpy(req->buf.base, WriteBuffer.data(), n);
- WriteBuffer.clear();
- lock.unlock();
-
- uv_write(
- reinterpret_cast<uv_write_t*>(req), this->Pipe, &req->buf, 1,
- [](uv_write_t* cb_req, int status) {
- (void)status; // We need to free memory even if the write failed.
- write_req_t* wr = reinterpret_cast<write_req_t*>(cb_req);
- reinterpret_cast<std::condition_variable*>(wr->req.data)->notify_all();
- delete[] (wr->buf.base);
- delete wr;
- });
-
-#ifdef __clang_analyzer__
- // Tell clang-analyzer that 'rawBuffer' does not leak.
- // We pass ownership to the closure.
- delete[] rawBuffer;
-#endif
-}
-
-cmDebuggerPipeConnection::cmDebuggerPipeConnection(std::string name)
- : cmDebuggerPipeBase(std::move(name))
-{
- ServerPipeClose.init(
- *Loop,
- [](uv_async_t* handle) {
- auto* conn = static_cast<cmDebuggerPipeConnection*>(handle->data);
- if (conn->ServerPipe.get()) {
- conn->ServerPipe->data = nullptr;
- conn->ServerPipe.reset();
- }
- },
- this);
-}
-
-cmDebuggerPipeConnection::~cmDebuggerPipeConnection()
-{
- StopLoop();
-}
-
-bool cmDebuggerPipeConnection::StartListening(std::string& errorMessage)
-{
- this->ServerPipe.init(*Loop, 0,
- static_cast<cmDebuggerPipeConnection*>(this));
-
- int r;
- if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
- errorMessage =
- "Internal Error with " + this->PipeName + ": " + uv_err_name(r);
- return false;
- }
-
- r = uv_listen(this->ServerPipe, 1, [](uv_stream_t* stream, int status) {
- if (status >= 0) {
- auto* conn = static_cast<cmDebuggerPipeConnection*>(stream->data);
- if (conn) {
- conn->Connect(stream);
- }
- }
- });
-
- if (r != 0) {
- errorMessage =
- "Internal Error listening on " + this->PipeName + ": " + uv_err_name(r);
- return false;
- }
-
- // Start the libuv event loop thread so that a client can connect.
- LoopThread = std::thread([this] { uv_run(Loop, UV_RUN_DEFAULT); });
-
- StartedListening.set_value();
-
- return true;
-}
-
-std::shared_ptr<dap::Reader> cmDebuggerPipeConnection::GetReader()
-{
- return std::static_pointer_cast<dap::Reader>(shared_from_this());
-}
-
-std::shared_ptr<dap::Writer> cmDebuggerPipeConnection::GetWriter()
-{
- return std::static_pointer_cast<dap::Writer>(shared_from_this());
-}
-
-bool cmDebuggerPipeConnection::isOpen()
-{
- return this->Pipe.get() != nullptr;
-}
-
-void cmDebuggerPipeConnection::CloseConnection()
-{
- ServerPipeClose.send();
-}
-
-void cmDebuggerPipeConnection::Connect(uv_stream_t* server)
-{
- if (this->Pipe.get()) {
- // Accept and close all pipes but the first:
- cm::uv_pipe_ptr rejectPipe;
-
- rejectPipe.init(*Loop, 0);
- uv_accept(server, rejectPipe);
-
- return;
- }
-
- cm::uv_pipe_ptr ClientPipe;
- ClientPipe.init(*Loop, 0, static_cast<cmDebuggerPipeConnection*>(this));
-
- if (uv_accept(server, ClientPipe) != 0) {
- return;
- }
-
- StartReading<cmDebuggerPipeConnection>(ClientPipe);
-
- std::unique_lock<std::mutex> lock(Mutex);
- Pipe = std::move(ClientPipe);
- lock.unlock();
- Connected.notify_all();
-}
-
-cmDebuggerPipeClient::~cmDebuggerPipeClient()
-{
- StopLoop();
-}
-
-void cmDebuggerPipeClient::Start()
-{
- this->Pipe.init(*Loop, 0, static_cast<cmDebuggerPipeClient*>(this));
-
- uv_connect_t* connect = new uv_connect_t;
- connect->data = this;
- uv_pipe_connect(
- connect, Pipe, PipeName.c_str(), [](uv_connect_t* cb_connect, int status) {
- auto* conn = static_cast<cmDebuggerPipeClient*>(cb_connect->data);
- if (status >= 0) {
- conn->Connect();
- } else {
- conn->FailConnection();
- }
- delete cb_connect;
- });
-
- // Start the libuv event loop so that the pipe can connect.
- LoopThread = std::thread([this] { uv_run(Loop, UV_RUN_DEFAULT); });
-}
-
-bool cmDebuggerPipeClient::isOpen()
-{
- return IsConnected;
-}
-
-void cmDebuggerPipeClient::CloseConnection()
-{
- IsConnected = false;
-}
-
-void cmDebuggerPipeClient::Connect()
-{
- StartReading<cmDebuggerPipeClient>(Pipe);
- std::unique_lock<std::mutex> lock(Mutex);
- IsConnected = true;
- lock.unlock();
- Connected.notify_all();
-}
-
-void cmDebuggerPipeClient::FailConnection()
-{
- std::unique_lock<std::mutex> lock(Mutex);
- FailedToOpen = true;
- lock.unlock();
- Connected.notify_all();
-}
-
-} // namespace cmDebugger
diff --git a/Source/cmDebuggerPipeConnection.h b/Source/cmDebuggerPipeConnection.h
deleted file mode 100644
index 0991ff7..0000000
--- a/Source/cmDebuggerPipeConnection.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <condition_variable>
-#include <cstddef>
-#include <future>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <thread>
-
-#include <cm3p/cppdap/io.h>
-#include <cm3p/uv.h>
-
-#include "cmDebuggerAdapter.h"
-#include "cmUVHandlePtr.h"
-
-namespace cmDebugger {
-
-class cmDebuggerPipeBase : public dap::ReaderWriter
-{
-public:
- cmDebuggerPipeBase(std::string name);
-
- void WaitForConnection();
-
- // dap::ReaderWriter implementation
-
- void close() final;
- size_t read(void* buffer, size_t n) final;
- bool write(const void* buffer, size_t n) final;
-
-protected:
- virtual void CloseConnection(){};
- template <typename T>
- void StartReading(uv_stream_t* stream)
- {
- uv_read_start(
- stream,
- // alloc_cb
- [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
- (void)handle;
- char* rawBuffer = new char[suggested_size];
- *buf =
- uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
- },
- // read_cb
- [](uv_stream_t* readStream, ssize_t nread, const uv_buf_t* buf) {
- auto conn = static_cast<T*>(readStream->data);
- if (conn) {
- if (nread >= 0) {
- conn->BufferData(std::string(buf->base, buf->base + nread));
- } else {
- conn->close();
- }
- }
- delete[] (buf->base);
- });
- }
- void StopLoop();
-
- const std::string PipeName;
- std::thread LoopThread;
- cm::uv_loop_ptr Loop;
- cm::uv_pipe_ptr Pipe;
- std::mutex Mutex;
- std::condition_variable Connected;
- bool FailedToOpen = false;
-
-private:
- void BufferData(const std::string& data);
- void WriteInternal();
-
- cm::uv_async_ptr LoopExit;
- cm::uv_async_ptr WriteEvent;
- cm::uv_async_ptr PipeClose;
- std::string WriteBuffer;
- std::string ReadBuffer;
- std::condition_variable ReadReady;
- std::condition_variable WriteComplete;
-};
-
-class cmDebuggerPipeConnection
- : public cmDebuggerPipeBase
- , public cmDebuggerConnection
- , public std::enable_shared_from_this<cmDebuggerPipeConnection>
-{
-public:
- cmDebuggerPipeConnection(std::string name);
- ~cmDebuggerPipeConnection() override;
-
- void WaitForConnection() override
- {
- cmDebuggerPipeBase::WaitForConnection();
- }
-
- bool StartListening(std::string& errorMessage) override;
- std::shared_ptr<dap::Reader> GetReader() override;
- std::shared_ptr<dap::Writer> GetWriter() override;
-
- // dap::ReaderWriter implementation
-
- bool isOpen() override;
-
- // Used for unit test synchronization
- std::promise<void> StartedListening;
-
-private:
- void CloseConnection() override;
- void Connect(uv_stream_t* server);
-
- cm::uv_pipe_ptr ServerPipe;
- cm::uv_async_ptr ServerPipeClose;
-};
-
-class cmDebuggerPipeClient : public cmDebuggerPipeBase
-{
-public:
- using cmDebuggerPipeBase::cmDebuggerPipeBase;
- ~cmDebuggerPipeClient() override;
-
- void Start();
-
- // dap::ReaderWriter implementation
-
- bool isOpen() override;
-
-private:
- void CloseConnection() override;
- void Connect();
- void FailConnection();
-
- bool IsConnected = false;
-};
-
-} // namespace cmDebugger
diff --git a/Source/cmDebuggerPosixPipeConnection.cxx b/Source/cmDebuggerPosixPipeConnection.cxx
new file mode 100644
index 0000000..0587450
--- /dev/null
+++ b/Source/cmDebuggerPosixPipeConnection.cxx
@@ -0,0 +1,205 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmDebuggerPosixPipeConnection.h"
+
+#include <cerrno>
+#include <cstring>
+#include <stdexcept>
+#include <utility>
+
+#include <unistd.h>
+
+#include <sys/socket.h>
+
+namespace cmDebugger {
+
+#ifndef _WIN32
+
+cmDebuggerPipeConnection_POSIX::cmDebuggerPipeConnection_POSIX(
+ std::string name)
+ : PipeName(std::move(name))
+{
+ addr.sun_path[0] = '\0';
+}
+
+cmDebuggerPipeConnection_POSIX::~cmDebuggerPipeConnection_POSIX()
+{
+ if (isOpen()) {
+ close();
+ }
+}
+
+bool cmDebuggerPipeConnection_POSIX::StartListening(std::string& errorMessage)
+{
+ listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (listen_fd < 0) {
+ errorMessage = "Failed to create socket: ";
+ errorMessage += strerror(errno);
+ return false;
+ }
+
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
+ if (bind(listen_fd, (sockaddr*)&addr, sizeof(addr)) == -1) {
+ errorMessage = "Failed to bind name '";
+ errorMessage += addr.sun_path;
+ errorMessage += "' to socket: ";
+ errorMessage += strerror(errno);
+ close_listen();
+ return false;
+ }
+
+ if (listen(listen_fd, 1) == -1) {
+ errorMessage = "Failed to listen on socket: ";
+ errorMessage += strerror(errno);
+ close_listen();
+ return false;
+ }
+
+ StartedListening.set_value();
+ return true;
+}
+
+std::shared_ptr<dap::Reader> cmDebuggerPipeConnection_POSIX::GetReader()
+{
+ return std::static_pointer_cast<dap::Reader>(shared_from_this());
+}
+
+std::shared_ptr<dap::Writer> cmDebuggerPipeConnection_POSIX::GetWriter()
+{
+ return std::static_pointer_cast<dap::Writer>(shared_from_this());
+}
+
+bool cmDebuggerPipeConnection_POSIX::isOpen()
+{
+ return rw_pipe >= 0;
+}
+
+void cmDebuggerPipeConnection_POSIX::close()
+{
+ close_listen();
+ ::close(rw_pipe);
+ rw_pipe = -1;
+}
+
+void cmDebuggerPipeConnection_POSIX::close_listen()
+{
+ if (strlen(addr.sun_path) > 0) {
+ unlink(addr.sun_path);
+ addr.sun_path[0] = '\0';
+ }
+ ::close(listen_fd);
+ listen_fd = -1;
+}
+
+void cmDebuggerPipeConnection_POSIX::WaitForConnection()
+{
+ sockaddr_un laddr;
+ socklen_t len = sizeof(laddr);
+ rw_pipe = accept(listen_fd, (sockaddr*)&laddr, &len);
+ if (rw_pipe < 0) {
+ close();
+ return;
+ }
+
+ close_listen(); // no longer need the listen resources
+}
+
+size_t cmDebuggerPipeConnection_POSIX::read(void* buffer, size_t n)
+{
+ size_t result = 0;
+ if (rw_pipe >= 0) {
+ result = ::read(rw_pipe, buffer, n);
+ if (result == 0) {
+ close();
+ }
+ }
+
+ return result;
+}
+
+bool cmDebuggerPipeConnection_POSIX::write(void const* buffer, size_t n)
+{
+ bool result = false;
+ if (rw_pipe >= 0) {
+ result = ::write(rw_pipe, buffer, n) >= 0;
+ if (!result) {
+ close();
+ }
+ }
+
+ return result;
+}
+
+cmDebuggerPipeClient_POSIX::cmDebuggerPipeClient_POSIX(std::string name)
+ : PipeName(std::move(name))
+{
+}
+
+cmDebuggerPipeClient_POSIX::~cmDebuggerPipeClient_POSIX()
+{
+ close();
+}
+
+void cmDebuggerPipeClient_POSIX::WaitForConnection()
+{
+ rw_pipe = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (rw_pipe < 0) {
+ throw std::runtime_error(std::string("Failed to create socket: ") +
+ strerror(errno));
+ }
+
+ sockaddr_un addr;
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
+ if (connect(rw_pipe, (sockaddr*)&addr, sizeof(addr)) == -1) {
+ close();
+ throw std::runtime_error(
+ std::string("Failed to connect path to socket: ") + strerror(errno));
+ }
+}
+
+bool cmDebuggerPipeClient_POSIX::isOpen()
+{
+ return rw_pipe >= 0;
+}
+
+void cmDebuggerPipeClient_POSIX::close()
+{
+ if (isOpen()) {
+ ::close(rw_pipe);
+ rw_pipe = -1;
+ }
+}
+
+size_t cmDebuggerPipeClient_POSIX::read(void* buffer, size_t n)
+{
+ int count = 0;
+ if (isOpen()) {
+ count = static_cast<int>(::read(rw_pipe, buffer, n));
+ if (count == 0) {
+ close();
+ }
+ }
+
+ return count;
+}
+
+bool cmDebuggerPipeClient_POSIX::write(void const* buffer, size_t n)
+{
+ int count = 0;
+ if (isOpen()) {
+ count = static_cast<int>(::write(rw_pipe, buffer, n));
+ if (count < 0) {
+ close();
+ }
+ }
+
+ return count > 0;
+}
+
+#endif // !_WIN32
+
+} // namespace cmDebugger
diff --git a/Source/cmDebuggerPosixPipeConnection.h b/Source/cmDebuggerPosixPipeConnection.h
new file mode 100644
index 0000000..42642fa
--- /dev/null
+++ b/Source/cmDebuggerPosixPipeConnection.h
@@ -0,0 +1,81 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cstddef>
+#include <future>
+#include <memory>
+#include <string>
+
+#include <cm3p/cppdap/io.h>
+
+#include <sys/un.h>
+
+#include "cmDebuggerAdapter.h"
+
+namespace cmDebugger {
+
+#ifndef _WIN32
+
+class cmDebuggerPipeConnection_POSIX
+ : public dap::ReaderWriter
+ , public cmDebuggerConnection
+ , public std::enable_shared_from_this<cmDebuggerPipeConnection_POSIX>
+{
+public:
+ cmDebuggerPipeConnection_POSIX(std::string name);
+ ~cmDebuggerPipeConnection_POSIX() override;
+
+ void WaitForConnection() override;
+
+ bool StartListening(std::string& errorMessage) override;
+ std::shared_ptr<dap::Reader> GetReader() override;
+ std::shared_ptr<dap::Writer> GetWriter() override;
+
+ // dap::ReaderWriter implementation
+
+ bool isOpen() override;
+ void close() override;
+ size_t read(void* buffer, size_t n) override;
+ bool write(void const* buffer, size_t n) override;
+
+ // Used for unit test synchronization
+ std::promise<void> StartedListening;
+
+private:
+ void close_listen(); // release listen resources
+
+ std::string const PipeName;
+ sockaddr_un addr;
+ int listen_fd = -1; // listen fd
+ int rw_pipe = -1; // rw fd
+};
+
+using cmDebuggerPipeConnection = cmDebuggerPipeConnection_POSIX;
+
+class cmDebuggerPipeClient_POSIX
+ : public dap::ReaderWriter
+ , public std::enable_shared_from_this<cmDebuggerPipeClient_POSIX>
+{
+public:
+ cmDebuggerPipeClient_POSIX(std::string name);
+ ~cmDebuggerPipeClient_POSIX() override;
+ void WaitForConnection();
+
+ bool isOpen() override;
+ void close() override;
+ size_t read(void* buffer, size_t n) override;
+ bool write(void const* buffer, size_t n) override;
+
+private:
+ std::string const PipeName;
+ int rw_pipe = -1;
+};
+
+using cmDebuggerPipeClient = cmDebuggerPipeClient_POSIX;
+
+#endif // !_WIN32
+
+} // namespace cmDebugger
diff --git a/Source/cmDebuggerProtocol.h b/Source/cmDebuggerProtocol.h
index 4334aed..d4b1a96 100644
--- a/Source/cmDebuggerProtocol.h
+++ b/Source/cmDebuggerProtocol.h
@@ -4,7 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <vector>
+#include <string>
#include <cm3p/cppdap/protocol.h>
diff --git a/Source/cmDebuggerVariablesHelper.cxx b/Source/cmDebuggerVariablesHelper.cxx
index 1322b20..73f9111 100644
--- a/Source/cmDebuggerVariablesHelper.cxx
+++ b/Source/cmDebuggerVariablesHelper.cxx
@@ -7,10 +7,11 @@
#include <cstddef>
#include <functional>
#include <iomanip>
+#include <iterator>
#include <map>
#include <sstream>
-#include "cm_codecvt.hxx"
+#include "cm_codecvt_Encoding.hxx"
#include "cmDebuggerStackFrame.h"
#include "cmDebuggerVariables.h"
@@ -578,17 +579,17 @@ std::shared_ptr<cmDebuggerVariables> cmDebuggerVariablesHelper::CreateIfAny(
return {};
}
- auto makeFileEncodingString = [](codecvt::Encoding encoding) {
+ auto makeFileEncodingString = [](codecvt_Encoding encoding) {
switch (encoding) {
- case codecvt::Encoding::None:
+ case codecvt_Encoding::None:
return "None";
- case codecvt::Encoding::UTF8:
+ case codecvt_Encoding::UTF8:
return "UTF8";
- case codecvt::Encoding::UTF8_WITH_BOM:
+ case codecvt_Encoding::UTF8_WITH_BOM:
return "UTF8_WITH_BOM";
- case codecvt::Encoding::ANSI:
+ case codecvt_Encoding::ANSI:
return "ANSI";
- case codecvt::Encoding::ConsoleOutput:
+ case codecvt_Encoding::ConsoleOutput:
return "ConsoleOutput";
default:
return "Unknown";
diff --git a/Source/cmDebuggerVariablesManager.h b/Source/cmDebuggerVariablesManager.h
index c219164..9a64f10 100644
--- a/Source/cmDebuggerVariablesManager.h
+++ b/Source/cmDebuggerVariablesManager.h
@@ -7,14 +7,9 @@
#include <cstdint>
#include <functional>
#include <unordered_map>
-#include <vector>
-#include <cm3p/cppdap/types.h> // IWYU pragma: keep
-
-namespace dap {
-struct Variable;
-struct VariablesRequest;
-}
+#include <cm3p/cppdap/protocol.h>
+#include <cm3p/cppdap/types.h>
namespace cmDebugger {
diff --git a/Source/cmDebuggerWindowsPipeConnection.cxx b/Source/cmDebuggerWindowsPipeConnection.cxx
new file mode 100644
index 0000000..5f6f848
--- /dev/null
+++ b/Source/cmDebuggerWindowsPipeConnection.cxx
@@ -0,0 +1,287 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmDebuggerWindowsPipeConnection.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <stdexcept>
+#include <utility>
+
+namespace cmDebugger {
+
+#ifdef _WIN32
+
+DuplexPipe_WIN32::DuplexPipe_WIN32(HANDLE pipe)
+ : hPipe(pipe)
+{
+ readOp.Offset = readOp.OffsetHigh = 0;
+ readOp.hEvent = CreateEvent(NULL, true, false, NULL);
+ writeOp.Offset = readOp.OffsetHigh = 0;
+ writeOp.hEvent = CreateEvent(NULL, true, false, NULL);
+}
+
+DuplexPipe_WIN32::~DuplexPipe_WIN32()
+{
+ close();
+}
+
+size_t DuplexPipe_WIN32::read(void* buffer, size_t n)
+{
+ if (hPipe != INVALID_HANDLE_VALUE) {
+ readOp.Offset = readOp.OffsetHigh = 0;
+ ResetEvent(readOp.hEvent);
+ auto r = ReadFile(hPipe, buffer, n, NULL, &readOp);
+ auto err = GetLastError();
+ if (r || err == ERROR_IO_PENDING) {
+ DWORD nRead = 0;
+ if (GetOverlappedResult(hPipe, &readOp, &nRead, true)) {
+ return nRead;
+ }
+ }
+ }
+
+ return 0;
+}
+
+bool DuplexPipe_WIN32::write(void const* buffer, size_t n)
+{
+ if (hPipe != INVALID_HANDLE_VALUE) {
+ writeOp.Offset = writeOp.OffsetHigh = 0;
+ ResetEvent(writeOp.hEvent);
+ auto w = WriteFile(hPipe, buffer, n, NULL, &writeOp);
+ auto err = GetLastError();
+ if (w || err == ERROR_IO_PENDING) {
+ DWORD nWrite = 0;
+ if (GetOverlappedResult(hPipe, &writeOp, &nWrite, true)) {
+ return n == nWrite;
+ }
+ }
+ }
+
+ return false;
+}
+
+void DuplexPipe_WIN32::close()
+{
+ CloseHandle(hPipe);
+ hPipe = INVALID_HANDLE_VALUE;
+ CloseHandle(readOp.hEvent);
+ CloseHandle(writeOp.hEvent);
+ readOp.hEvent = writeOp.hEvent = INVALID_HANDLE_VALUE;
+}
+
+bool DuplexPipe_WIN32::WaitForConnection()
+{
+ auto connect = ConnectNamedPipe(hPipe, &readOp);
+ auto err = GetLastError();
+ if (!connect && err == ERROR_IO_PENDING) {
+ DWORD ignored;
+ if (GetOverlappedResult(hPipe, &readOp, &ignored, true)) {
+ return true;
+ }
+ }
+
+ return connect || err == ERROR_PIPE_CONNECTED;
+}
+
+cmDebuggerPipeConnection_WIN32::cmDebuggerPipeConnection_WIN32(
+ std::string name)
+ : PipeName(std::move(name))
+ , pipes(nullptr)
+{
+}
+
+cmDebuggerPipeConnection_WIN32::~cmDebuggerPipeConnection_WIN32()
+{
+ if (isOpen()) {
+ pipes = nullptr;
+ }
+}
+
+bool cmDebuggerPipeConnection_WIN32::StartListening(std::string& errorMessage)
+{
+ bool result = true;
+
+ auto hPipe = CreateNamedPipeA(
+ PipeName.c_str(),
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_REJECT_REMOTE_CLIENTS, 1,
+ 1024 * 16, 1024 * 16, NMPWAIT_USE_DEFAULT_WAIT, NULL);
+
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ auto err = GetLastError();
+ errorMessage = GetErrorMessage(err);
+ result = false;
+ }
+
+ if (result) {
+ pipes = std::make_unique<DuplexPipe_WIN32>(hPipe);
+ }
+
+ StartedListening.set_value();
+ return result;
+}
+
+std::string cmDebuggerPipeConnection_WIN32::GetErrorMessage(DWORD errorCode)
+{
+ LPSTR message = nullptr;
+ DWORD size = FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&message, 0, nullptr);
+ std::string errorMessage = "Internal Error with " + this->PipeName + ": " +
+ std::string(message, size);
+ LocalFree(message);
+ return errorMessage;
+}
+
+std::shared_ptr<dap::Reader> cmDebuggerPipeConnection_WIN32::GetReader()
+{
+ return std::static_pointer_cast<dap::Reader>(shared_from_this());
+}
+
+std::shared_ptr<dap::Writer> cmDebuggerPipeConnection_WIN32::GetWriter()
+{
+ return std::static_pointer_cast<dap::Writer>(shared_from_this());
+}
+
+bool cmDebuggerPipeConnection_WIN32::isOpen()
+{
+ return pipes != nullptr;
+}
+
+void cmDebuggerPipeConnection_WIN32::close()
+{
+ CloseConnection();
+}
+
+void cmDebuggerPipeConnection_WIN32::CloseConnection()
+{
+ if (isOpen()) {
+ pipes->close();
+ pipes = nullptr;
+ }
+}
+
+void cmDebuggerPipeConnection_WIN32::WaitForConnection()
+{
+ if (!isOpen()) {
+ return;
+ }
+
+ if (pipes->WaitForConnection()) {
+ return;
+ }
+
+ CloseConnection();
+}
+
+size_t cmDebuggerPipeConnection_WIN32::read(void* buffer, size_t n)
+{
+ size_t result = 0;
+ if (isOpen()) {
+ result = pipes->read(buffer, n);
+ if (result == 0) {
+ CloseConnection();
+ }
+ }
+
+ return result;
+}
+
+bool cmDebuggerPipeConnection_WIN32::write(void const* buffer, size_t n)
+{
+ bool result = false;
+ if (isOpen()) {
+ result = pipes->write(buffer, n);
+ if (!result) {
+ CloseConnection();
+ }
+ }
+
+ return result;
+}
+
+cmDebuggerPipeClient_WIN32::cmDebuggerPipeClient_WIN32(std::string name)
+ : PipeName(std::move(name))
+{
+}
+
+cmDebuggerPipeClient_WIN32::~cmDebuggerPipeClient_WIN32()
+{
+ close();
+}
+
+void cmDebuggerPipeClient_WIN32::WaitForConnection()
+{
+ if (!isOpen()) {
+ auto hPipe = CreateFileA(PipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
+ NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ auto err = GetLastError();
+ throw std::runtime_error(std::string("CreateFile failed for pipe ") +
+ GetErrorMessage(err));
+ }
+
+ pipes = std::make_unique<DuplexPipe_WIN32>(hPipe);
+ }
+}
+
+std::string cmDebuggerPipeClient_WIN32::GetErrorMessage(DWORD errorCode)
+{
+ LPSTR message = nullptr;
+ DWORD size = FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&message, 0, nullptr);
+ std::string errorMessage =
+ this->PipeName + ": " + std::string(message, size);
+ LocalFree(message);
+ return errorMessage;
+}
+
+bool cmDebuggerPipeClient_WIN32::isOpen()
+{
+ return pipes != nullptr;
+}
+
+void cmDebuggerPipeClient_WIN32::close()
+{
+ if (isOpen()) {
+ pipes->close();
+ pipes = nullptr;
+ }
+}
+
+size_t cmDebuggerPipeClient_WIN32::read(void* buffer, size_t n)
+{
+ size_t result = 0;
+ if (isOpen()) {
+ result = pipes->read(buffer, n);
+ if (result == 0) {
+ close();
+ }
+ }
+
+ return result;
+}
+
+bool cmDebuggerPipeClient_WIN32::write(void const* buffer, size_t n)
+{
+ bool result = false;
+ if (isOpen()) {
+ result = pipes->write(buffer, n);
+ if (!result) {
+ close();
+ }
+ }
+
+ return result;
+}
+
+#endif // _WIN32
+
+} // namespace cmDebugger
diff --git a/Source/cmDebuggerWindowsPipeConnection.h b/Source/cmDebuggerWindowsPipeConnection.h
new file mode 100644
index 0000000..6a57435
--- /dev/null
+++ b/Source/cmDebuggerWindowsPipeConnection.h
@@ -0,0 +1,103 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <condition_variable>
+#include <cstddef>
+#include <future>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include <windows.h>
+
+#include <cm3p/cppdap/io.h>
+
+#include "cmDebuggerAdapter.h"
+
+namespace cmDebugger {
+
+#ifdef _WIN32
+
+class DuplexPipe_WIN32
+{
+public:
+ DuplexPipe_WIN32(HANDLE read);
+ ~DuplexPipe_WIN32();
+
+ void close();
+ size_t read(void* buffer, size_t n);
+ bool write(void const* buffer, size_t n);
+
+ bool WaitForConnection();
+
+private:
+ HANDLE hPipe;
+ OVERLAPPED readOp;
+ OVERLAPPED writeOp;
+};
+
+class cmDebuggerPipeConnection_WIN32
+ : public dap::ReaderWriter
+ , public cmDebuggerConnection
+ , public std::enable_shared_from_this<cmDebuggerPipeConnection_WIN32>
+{
+public:
+ cmDebuggerPipeConnection_WIN32(std::string name);
+ ~cmDebuggerPipeConnection_WIN32() override;
+
+ void WaitForConnection() override;
+
+ bool StartListening(std::string& errorMessage) override;
+ std::shared_ptr<dap::Reader> GetReader() override;
+ std::shared_ptr<dap::Writer> GetWriter() override;
+
+ // dap::ReaderWriter implementation
+
+ bool isOpen() override;
+ void close() override;
+ size_t read(void* buffer, size_t n) override;
+ bool write(void const* buffer, size_t n) override;
+
+ // Used for unit test synchronization
+ std::promise<void> StartedListening;
+
+private:
+ void CloseConnection();
+ std::string GetErrorMessage(DWORD errorCode);
+
+ std::string const PipeName;
+ std::unique_ptr<DuplexPipe_WIN32> pipes;
+};
+
+using cmDebuggerPipeConnection = cmDebuggerPipeConnection_WIN32;
+
+class cmDebuggerPipeClient_WIN32
+ : public dap::ReaderWriter
+ , public std::enable_shared_from_this<cmDebuggerPipeClient_WIN32>
+{
+public:
+ cmDebuggerPipeClient_WIN32(std::string name);
+ ~cmDebuggerPipeClient_WIN32();
+ void WaitForConnection();
+
+ bool isOpen() override;
+ void close() override;
+ size_t read(void* buffer, size_t n) override;
+ bool write(void const* buffer, size_t n) override;
+
+private:
+ std::string GetErrorMessage(DWORD errorCode);
+
+ std::string const PipeName;
+ std::unique_ptr<DuplexPipe_WIN32> pipes;
+};
+
+using cmDebuggerPipeClient = cmDebuggerPipeClient_WIN32;
+
+#endif // _WIN32
+
+} // namespace cmDebugger
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index a5f8aab..453c0d1 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -3,7 +3,6 @@
#include "cmDefinitions.h"
#include <cassert>
-#include <functional>
#include <unordered_set>
#include <utility>
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 22fef80..11d8947 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -4,7 +4,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index c8061c3..27f328d 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -6,7 +6,6 @@
#include <algorithm>
#include <iterator>
#include <map>
-#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index d038db7..2a50565 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -6,6 +6,7 @@
#include <cstdlib>
#include <iostream>
#include <map>
+#include <type_traits>
#include <utility>
#include "cmsys/FStream.hxx"
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index 70ba1fc..b85b2f5 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDocumentationFormatter.h"
-#include <algorithm>
+#include <algorithm> // IWYU pragma: keep
#include <cassert>
#include <iomanip>
#include <ostream>
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
index e269f6a..9d35e0a 100644
--- a/Source/cmDocumentationFormatter.h
+++ b/Source/cmDocumentationFormatter.h
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <iosfwd>
#include <string>
diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx
index 80e1357..dfab975 100644
--- a/Source/cmDyndepCollation.cxx
+++ b/Source/cmDyndepCollation.cxx
@@ -73,20 +73,36 @@ Json::Value CollationInformationCxxModules(
gt->LocalGenerator, config, gt);
}
- std::map<std::string, cmSourceFile const*> sf_map;
+ enum class CompileType
{
- std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources, config);
- for (auto const* sf : objectSources) {
+ ObjectAndBmi,
+ BmiOnly,
+ };
+ std::map<std::string, std::pair<cmSourceFile const*, CompileType>> sf_map;
+ {
+ auto fill_sf_map = [gt, tgt, &sf_map](cmSourceFile const* sf,
+ CompileType type) {
auto full_path = sf->GetFullPath();
if (full_path.empty()) {
gt->Makefile->IssueMessage(
MessageType::INTERNAL_ERROR,
cmStrCat("Target \"", tgt->GetName(),
"\" has a full path-less source file."));
- continue;
+ return;
}
- sf_map[full_path] = sf;
+ sf_map[full_path] = std::make_pair(sf, type);
+ };
+
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources, config);
+ for (auto const* sf : objectSources) {
+ fill_sf_map(sf, CompileType::ObjectAndBmi);
+ }
+
+ std::vector<cmSourceFile const*> cxxModuleSources;
+ gt->GetCxxModuleSources(cxxModuleSources, config);
+ for (auto const* sf : cxxModuleSources) {
+ fill_sf_map(sf, CompileType::BmiOnly);
}
}
@@ -113,7 +129,8 @@ Json::Value CollationInformationCxxModules(
continue;
}
- auto const* sf = lookup->second;
+ auto const* sf = lookup->second.first;
+ CompileType const ct = lookup->second.second;
if (!sf) {
gt->Makefile->IssueMessage(
@@ -123,11 +140,14 @@ Json::Value CollationInformationCxxModules(
continue;
}
- auto obj_path = cb.ObjectFilePath(sf, config);
+ auto obj_path = ct == CompileType::ObjectAndBmi
+ ? cb.ObjectFilePath(sf, config)
+ : cb.BmiFilePath(sf, config);
Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] =
Json::objectValue;
tdi_module_info["source"] = file;
+ tdi_module_info["bmi-only"] = ct == CompileType::BmiOnly;
tdi_module_info["relative-directory"] = files_per_dir.first;
tdi_module_info["name"] = file_set->GetName();
tdi_module_info["type"] = file_set->GetType();
@@ -269,10 +289,11 @@ void cmDyndepCollation::AddCollationInformation(
struct CxxModuleFileSet
{
std::string Name;
+ bool BmiOnly = false;
std::string RelativeDirectory;
std::string SourcePath;
std::string Type;
- cmFileSetVisibility Visibility;
+ cmFileSetVisibility Visibility = cmFileSetVisibility::Private;
cm::optional<std::string> Destination;
};
@@ -356,6 +377,7 @@ cmDyndepCollation::ParseExportInfo(Json::Value const& tdi)
CxxModuleFileSet& fsi = export_info->ObjectToFileSet[i.key().asString()];
auto const& tdi_cxx_module_info = *i;
fsi.Name = tdi_cxx_module_info["name"].asString();
+ fsi.BmiOnly = tdi_cxx_module_info["bmi-only"].asBool();
fsi.RelativeDirectory =
tdi_cxx_module_info["relative-directory"].asString();
if (!fsi.RelativeDirectory.empty() &&
@@ -644,3 +666,16 @@ bool cmDyndepCollation::IsObjectPrivate(
auto const& file_set = fileset_info_itr->second;
return !cmFileSetVisibilityIsForInterface(file_set.Visibility);
}
+
+bool cmDyndepCollation::IsBmiOnly(cmCxxModuleExportInfo const& exportInfo,
+ std::string const& object)
+{
+#ifdef _WIN32
+ auto object_path = object;
+ cmSystemTools::ConvertToUnixSlashes(object_path);
+#else
+ auto const& object_path = object;
+#endif
+ auto fs = exportInfo.ObjectToFileSet.find(object_path);
+ return (fs != exportInfo.ObjectToFileSet.end()) && fs->second.BmiOnly;
+}
diff --git a/Source/cmDyndepCollation.h b/Source/cmDyndepCollation.h
index 48afe2b..b193467 100644
--- a/Source/cmDyndepCollation.h
+++ b/Source/cmDyndepCollation.h
@@ -23,6 +23,8 @@ struct cmDyndepGeneratorCallbacks
{
std::function<std::string(cmSourceFile const* sf, std::string const& config)>
ObjectFilePath;
+ std::function<std::string(cmSourceFile const* sf, std::string const& config)>
+ BmiFilePath;
};
struct cmDyndepMetadataCallbacks
@@ -51,4 +53,7 @@ struct cmDyndepCollation
cmDyndepMetadataCallbacks const& cb);
static bool IsObjectPrivate(std::string const& object,
cmCxxModuleExportInfo const& export_info);
+
+ static bool IsBmiOnly(cmCxxModuleExportInfo const& exportInfo,
+ std::string const& object);
};
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 7fbd826..9b5f2b4 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -2,8 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExecuteProcessCommand.h"
-#include <algorithm>
#include <cctype> /* isspace */
+#include <cstdint>
#include <cstdio>
#include <iostream>
#include <map>
@@ -16,15 +16,21 @@
#include <cmext/algorithm>
#include <cmext/string_view>
-#include "cmsys/Process.h"
+#include <cm3p/uv.h>
+
+#include "cm_fileno.hxx"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
namespace {
bool cmExecuteProcessCommandIsWhitespace(char c)
@@ -35,7 +41,7 @@ bool cmExecuteProcessCommandIsWhitespace(char c)
void cmExecuteProcessCommandFixText(std::vector<char>& output,
bool strip_trailing_whitespace);
void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
- int length);
+ std::size_t length);
}
// cmExecuteProcessCommand
@@ -142,57 +148,61 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
}
}
// Create a process instance.
- std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp_ptr(
- cmsysProcess_New(), cmsysProcess_Delete);
- cmsysProcess* cp = cp_ptr.get();
+ cmUVProcessChainBuilder builder;
// Set the command sequence.
for (std::vector<std::string> const& cmd : arguments.Commands) {
- std::vector<const char*> argv(cmd.size() + 1);
- std::transform(cmd.begin(), cmd.end(), argv.begin(),
- [](std::string const& s) { return s.c_str(); });
- argv.back() = nullptr;
- cmsysProcess_AddCommand(cp, argv.data());
+ builder.AddCommand(cmd);
}
// Set the process working directory.
if (!arguments.WorkingDirectory.empty()) {
- cmsysProcess_SetWorkingDirectory(cp, arguments.WorkingDirectory.c_str());
+ builder.SetWorkingDirectory(arguments.WorkingDirectory);
}
- // Always hide the process window.
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
-
// Check the output variables.
- bool merge_output = false;
+ std::unique_ptr<FILE, int (*)(FILE*)> inputFile(nullptr, fclose);
if (!arguments.InputFile.empty()) {
- cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDIN,
- arguments.InputFile.c_str());
+ inputFile.reset(cmsys::SystemTools::Fopen(arguments.InputFile, "rb"));
+ builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
+ cm_fileno(inputFile.get()));
+ } else {
+ builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
+ cm_fileno(stdin));
}
+
+ std::unique_ptr<FILE, int (*)(FILE*)> outputFile(nullptr, fclose);
if (!arguments.OutputFile.empty()) {
- cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDOUT,
- arguments.OutputFile.c_str());
+ outputFile.reset(cmsys::SystemTools::Fopen(arguments.OutputFile, "wb"));
+ builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ cm_fileno(outputFile.get()));
+ } else {
+ if (arguments.OutputVariable == arguments.ErrorVariable &&
+ !arguments.ErrorVariable.empty()) {
+ builder.SetMergedBuiltinStreams();
+ } else {
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+ }
}
+
+ std::unique_ptr<FILE, int (*)(FILE*)> errorFile(nullptr, fclose);
if (!arguments.ErrorFile.empty()) {
if (arguments.ErrorFile == arguments.OutputFile) {
- merge_output = true;
+ builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(outputFile.get()));
} else {
- cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
- arguments.ErrorFile.c_str());
+ errorFile.reset(cmsys::SystemTools::Fopen(arguments.ErrorFile, "wb"));
+ builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(errorFile.get()));
}
- }
- if (!arguments.OutputVariable.empty() &&
- arguments.OutputVariable == arguments.ErrorVariable) {
- merge_output = true;
- }
- if (merge_output) {
- cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
+ } else if (arguments.ErrorVariable.empty() ||
+ (!arguments.ErrorVariable.empty() &&
+ arguments.OutputVariable != arguments.ErrorVariable)) {
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
}
// Set the timeout if any.
- if (timeout >= 0) {
- cmsysProcess_SetTimeout(cp, timeout);
- }
+ int64_t timeoutMillis = static_cast<int64_t>(timeout * 1000.0);
bool echo_stdout = false;
bool echo_stderr = false;
@@ -240,36 +250,86 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
}
}
// Start the process.
- cmsysProcess_Execute(cp);
+ auto chain = builder.Start();
+
+ bool timedOut = false;
+ cm::uv_timer_ptr timer;
+
+ if (timeoutMillis >= 0) {
+ timer.init(chain.GetLoop(), &timedOut);
+ timer.start(
+ [](uv_timer_t* handle) {
+ auto* timeoutPtr = static_cast<bool*>(handle->data);
+ *timeoutPtr = true;
+ },
+ timeoutMillis, 0);
+ }
// Read the process output.
- std::vector<char> tempOutput;
- std::vector<char> tempError;
- int length;
- char* data;
- int p;
+ struct ReadData
+ {
+ bool Finished = false;
+ std::vector<char> Output;
+ cm::uv_pipe_ptr Stream;
+ };
+ ReadData outputData;
+ ReadData errorData;
cmProcessOutput processOutput(
cmProcessOutput::FindEncoding(arguments.Encoding));
std::string strdata;
- while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
- // Put the output in the right place.
- if (p == cmsysProcess_Pipe_STDOUT && !arguments.OutputQuiet) {
- if (arguments.OutputVariable.empty() || arguments.EchoOutputVariable) {
- processOutput.DecodeText(data, length, strdata, 1);
- cmSystemTools::Stdout(strdata);
- }
- if (!arguments.OutputVariable.empty()) {
- cmExecuteProcessCommandAppend(tempOutput, data, length);
- }
- } else if (p == cmsysProcess_Pipe_STDERR && !arguments.ErrorQuiet) {
- if (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable) {
- processOutput.DecodeText(data, length, strdata, 2);
- cmSystemTools::Stderr(strdata);
- }
- if (!arguments.ErrorVariable.empty()) {
- cmExecuteProcessCommandAppend(tempError, data, length);
- }
- }
+
+ std::unique_ptr<cmUVStreamReadHandle> outputHandle;
+ if (chain.OutputStream() >= 0) {
+ outputData.Stream.init(chain.GetLoop(), 0);
+ uv_pipe_open(outputData.Stream, chain.OutputStream());
+ outputHandle = cmUVStreamRead(
+ outputData.Stream,
+ [&arguments, &processOutput, &outputData,
+ &strdata](std::vector<char> data) {
+ if (!arguments.OutputQuiet) {
+ if (arguments.OutputVariable.empty() ||
+ arguments.EchoOutputVariable) {
+ processOutput.DecodeText(data.data(), data.size(), strdata, 1);
+ cmSystemTools::Stdout(strdata);
+ }
+ if (!arguments.OutputVariable.empty()) {
+ cmExecuteProcessCommandAppend(outputData.Output, data.data(),
+ data.size());
+ }
+ }
+ },
+ [&outputData]() { outputData.Finished = true; });
+ } else {
+ outputData.Finished = true;
+ }
+ std::unique_ptr<cmUVStreamReadHandle> errorHandle;
+ if (chain.ErrorStream() >= 0 &&
+ chain.ErrorStream() != chain.OutputStream()) {
+ errorData.Stream.init(chain.GetLoop(), 0);
+ uv_pipe_open(errorData.Stream, chain.ErrorStream());
+ errorHandle = cmUVStreamRead(
+ errorData.Stream,
+ [&arguments, &processOutput, &errorData,
+ &strdata](std::vector<char> data) {
+ if (!arguments.ErrorQuiet) {
+ if (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable) {
+ processOutput.DecodeText(data.data(), data.size(), strdata, 2);
+ cmSystemTools::Stderr(strdata);
+ }
+ if (!arguments.ErrorVariable.empty()) {
+ cmExecuteProcessCommandAppend(errorData.Output, data.data(),
+ data.size());
+ }
+ }
+ },
+ [&errorData]() { errorData.Finished = true; });
+ } else {
+ errorData.Finished = true;
+ }
+
+ while (chain.Valid() && !timedOut &&
+ !(chain.Finished() && outputData.Finished && errorData.Finished)) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
}
if (!arguments.OutputQuiet &&
(arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
@@ -286,151 +346,102 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
}
}
- // All output has been read. Wait for the process to exit.
- cmsysProcess_WaitForExit(cp, nullptr);
- processOutput.DecodeText(tempOutput, tempOutput);
- processOutput.DecodeText(tempError, tempError);
+ // All output has been read.
+ processOutput.DecodeText(outputData.Output, outputData.Output);
+ processOutput.DecodeText(errorData.Output, errorData.Output);
// Fix the text in the output strings.
- cmExecuteProcessCommandFixText(tempOutput,
+ cmExecuteProcessCommandFixText(outputData.Output,
arguments.OutputStripTrailingWhitespace);
- cmExecuteProcessCommandFixText(tempError,
+ cmExecuteProcessCommandFixText(errorData.Output,
arguments.ErrorStripTrailingWhitespace);
// Store the output obtained.
- if (!arguments.OutputVariable.empty() && !tempOutput.empty()) {
+ if (!arguments.OutputVariable.empty() && !outputData.Output.empty()) {
status.GetMakefile().AddDefinition(arguments.OutputVariable,
- tempOutput.data());
+ outputData.Output.data());
}
- if (!merge_output && !arguments.ErrorVariable.empty() &&
- !tempError.empty()) {
+ if (arguments.ErrorVariable != arguments.OutputVariable &&
+ !arguments.ErrorVariable.empty() && !errorData.Output.empty()) {
status.GetMakefile().AddDefinition(arguments.ErrorVariable,
- tempError.data());
+ errorData.Output.data());
}
// Store the result of running the process.
if (!arguments.ResultVariable.empty()) {
- switch (cmsysProcess_GetState(cp)) {
- case cmsysProcess_State_Exited: {
- int v = cmsysProcess_GetExitValue(cp);
- char buf[16];
- snprintf(buf, sizeof(buf), "%d", v);
- status.GetMakefile().AddDefinition(arguments.ResultVariable, buf);
- } break;
- case cmsysProcess_State_Exception:
+ if (timedOut) {
+ status.GetMakefile().AddDefinition(arguments.ResultVariable,
+ "Process terminated due to timeout");
+ } else {
+ auto const* lastStatus = chain.GetStatus().back();
+ auto exception = lastStatus->GetException();
+ if (exception.first == cmUVProcessChain::ExceptionCode::None) {
status.GetMakefile().AddDefinition(
- arguments.ResultVariable, cmsysProcess_GetExceptionString(cp));
- break;
- case cmsysProcess_State_Error:
+ arguments.ResultVariable,
+ std::to_string(static_cast<int>(lastStatus->ExitStatus)));
+ } else {
status.GetMakefile().AddDefinition(arguments.ResultVariable,
- cmsysProcess_GetErrorString(cp));
- break;
- case cmsysProcess_State_Expired:
- status.GetMakefile().AddDefinition(
- arguments.ResultVariable, "Process terminated due to timeout");
- break;
+ exception.second);
+ }
}
}
// Store the result of running the processes.
if (!arguments.ResultsVariable.empty()) {
- switch (cmsysProcess_GetState(cp)) {
- case cmsysProcess_State_Exited: {
- std::vector<std::string> res;
- for (size_t i = 0; i < arguments.Commands.size(); ++i) {
- switch (cmsysProcess_GetStateByIndex(cp, static_cast<int>(i))) {
- case kwsysProcess_StateByIndex_Exited: {
- int exitCode =
- cmsysProcess_GetExitValueByIndex(cp, static_cast<int>(i));
- char buf[16];
- snprintf(buf, sizeof(buf), "%d", exitCode);
- res.emplace_back(buf);
- } break;
- case kwsysProcess_StateByIndex_Exception:
- res.emplace_back(cmsysProcess_GetExceptionStringByIndex(
- cp, static_cast<int>(i)));
- break;
- case kwsysProcess_StateByIndex_Error:
- default:
- res.emplace_back("Error getting the child return code");
- break;
- }
+ if (timedOut) {
+ status.GetMakefile().AddDefinition(arguments.ResultsVariable,
+ "Process terminated due to timeout");
+ } else {
+ std::vector<std::string> res;
+ for (auto const* processStatus : chain.GetStatus()) {
+ auto exception = processStatus->GetException();
+ if (exception.first == cmUVProcessChain::ExceptionCode::None) {
+ res.emplace_back(
+ std::to_string(static_cast<int>(processStatus->ExitStatus)));
+ } else {
+ res.emplace_back(exception.second);
}
- status.GetMakefile().AddDefinition(arguments.ResultsVariable,
- cmJoin(res, ";"));
- } break;
- case cmsysProcess_State_Exception:
- status.GetMakefile().AddDefinition(
- arguments.ResultsVariable, cmsysProcess_GetExceptionString(cp));
- break;
- case cmsysProcess_State_Error:
- status.GetMakefile().AddDefinition(arguments.ResultsVariable,
- cmsysProcess_GetErrorString(cp));
- break;
- case cmsysProcess_State_Expired:
- status.GetMakefile().AddDefinition(
- arguments.ResultsVariable, "Process terminated due to timeout");
- break;
+ }
+ status.GetMakefile().AddDefinition(arguments.ResultsVariable,
+ cmList::to_string(res));
}
}
- auto queryProcessStatusByIndex = [&cp](int index) -> std::string {
- std::string processStatus;
- switch (cmsysProcess_GetStateByIndex(cp, static_cast<int>(index))) {
- case kwsysProcess_StateByIndex_Exited: {
- int exitCode = cmsysProcess_GetExitValueByIndex(cp, index);
- if (exitCode) {
- processStatus = "Child return code: " + std::to_string(exitCode);
- }
- } break;
- case kwsysProcess_StateByIndex_Exception: {
- processStatus = cmStrCat(
- "Abnormal exit with child return code: ",
- cmsysProcess_GetExceptionStringByIndex(cp, static_cast<int>(index)));
- break;
+ auto queryProcessStatusByIndex = [&chain](std::size_t index) -> std::string {
+ auto const& processStatus = chain.GetStatus(index);
+ auto exception = processStatus.GetException();
+ if (exception.first == cmUVProcessChain::ExceptionCode::None) {
+ if (processStatus.ExitStatus) {
+ return cmStrCat("Child return code: ", processStatus.ExitStatus);
}
- case kwsysProcess_StateByIndex_Error:
- default:
- processStatus = "Error getting the child return code";
- break;
+ return "";
}
- return processStatus;
+ return cmStrCat("Abnormal exit with child return code: ",
+ exception.second);
};
if (arguments.CommandErrorIsFatal == "ANY"_s) {
bool ret = true;
- switch (cmsysProcess_GetState(cp)) {
- case cmsysProcess_State_Exited: {
- std::map<int, std::string> failureIndices;
- for (int i = 0; i < static_cast<int>(arguments.Commands.size()); ++i) {
- std::string processStatus = queryProcessStatusByIndex(i);
- if (!processStatus.empty()) {
- failureIndices[i] = processStatus;
- }
- if (!failureIndices.empty()) {
- std::ostringstream oss;
- oss << "failed command indexes:\n";
- for (auto const& e : failureIndices) {
- oss << " " << e.first + 1 << ": \"" << e.second << "\"\n";
- }
- status.SetError(oss.str());
- ret = false;
- }
+ if (timedOut) {
+ status.SetError("Process terminated due to timeout");
+ ret = false;
+ } else {
+ std::map<std::size_t, std::string> failureIndices;
+ auto statuses = chain.GetStatus();
+ for (std::size_t i = 0; i < statuses.size(); ++i) {
+ std::string processStatus = queryProcessStatusByIndex(i);
+ if (!processStatus.empty()) {
+ failureIndices[i] = processStatus;
}
- } break;
- case cmsysProcess_State_Exception:
- status.SetError(
- cmStrCat("abnormal exit: ", cmsysProcess_GetExceptionString(cp)));
- ret = false;
- break;
- case cmsysProcess_State_Error:
- status.SetError(cmStrCat("error getting child return code: ",
- cmsysProcess_GetErrorString(cp)));
- ret = false;
- break;
- case cmsysProcess_State_Expired:
- status.SetError("Process terminated due to timeout");
+ }
+ if (!failureIndices.empty()) {
+ std::ostringstream oss;
+ oss << "failed command indexes:\n";
+ for (auto const& e : failureIndices) {
+ oss << " " << e.first + 1 << ": \"" << e.second << "\"\n";
+ }
+ status.SetError(oss.str());
ret = false;
- break;
+ }
}
if (!ret) {
@@ -441,29 +452,23 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
if (arguments.CommandErrorIsFatal == "LAST"_s) {
bool ret = true;
- switch (cmsysProcess_GetState(cp)) {
- case cmsysProcess_State_Exited: {
+ if (timedOut) {
+ status.SetError("Process terminated due to timeout");
+ ret = false;
+ } else {
+ auto const& lastStatus = chain.GetStatus(arguments.Commands.size() - 1);
+ auto exception = lastStatus.GetException();
+ if (exception.first != cmUVProcessChain::ExceptionCode::None) {
+ status.SetError(cmStrCat("Abnormal exit: ", exception.second));
+ ret = false;
+ } else {
int lastIndex = static_cast<int>(arguments.Commands.size() - 1);
const std::string processStatus = queryProcessStatusByIndex(lastIndex);
if (!processStatus.empty()) {
status.SetError("last command failed");
ret = false;
}
- } break;
- case cmsysProcess_State_Exception:
- status.SetError(
- cmStrCat("Abnormal exit: ", cmsysProcess_GetExceptionString(cp)));
- ret = false;
- break;
- case cmsysProcess_State_Error:
- status.SetError(cmStrCat("Error getting child return code: ",
- cmsysProcess_GetErrorString(cp)));
- ret = false;
- break;
- case cmsysProcess_State_Expired:
- status.SetError("Process terminated due to timeout");
- ret = false;
- break;
+ }
}
if (!ret) {
cmSystemTools::SetFatalErrorOccurred();
@@ -506,7 +511,7 @@ void cmExecuteProcessCommandFixText(std::vector<char>& output,
}
void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
- int length)
+ std::size_t length)
{
#if defined(__APPLE__)
// HACK on Apple to work around bug with inserting at the
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
index 2f26627..104ab81 100644
--- a/Source/cmExperimental.cxx
+++ b/Source/cmExperimental.cxx
@@ -18,36 +18,48 @@ namespace {
* Search for other instances to keep the documentation and test suite
* up-to-date.
*/
-
-struct FeatureData
-{
- std::string const Uuid;
- std::string const Variable;
- std::string const Description;
- bool Warned;
-} LookupTable[] = {
+cmExperimental::FeatureData LookupTable[] = {
// CxxModuleCMakeApi
- { "aa1f7df0-828a-4fcd-9afc-2dc80491aca7",
+ { "CxxModuleCMakeApi",
+ "ac01f462-0f5f-432a-86aa-acef252918a6",
"CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
"CMake's C++ module support is experimental. It is meant only for "
"experimentation and feedback to CMake developers.",
+ { "CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE",
+ "CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT",
+ "CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG" },
+ cmExperimental::TryCompileCondition::SkipCompilerChecks,
+ false },
+ // WindowsKernelModeDriver
+ { "WindowsKernelModeDriver",
+ "5c2d848d-4efa-4529-a768-efd57171bf68",
+ "CMAKE_EXPERIMENTAL_WINDOWS_KERNEL_MODE_DRIVER",
+ "CMake's Windows kernel-mode driver support is experimental. It is meant "
+ "only for experimentation and feedback to CMake developers.",
+ {},
+ cmExperimental::TryCompileCondition::Always,
false },
};
static_assert(sizeof(LookupTable) / sizeof(LookupTable[0]) ==
static_cast<size_t>(cmExperimental::Feature::Sentinel),
"Experimental feature lookup table mismatch");
-FeatureData& DataForFeature(cmExperimental::Feature f)
+cmExperimental::FeatureData& DataForFeature(cmExperimental::Feature f)
{
assert(f != cmExperimental::Feature::Sentinel);
return LookupTable[static_cast<size_t>(f)];
}
}
+const cmExperimental::FeatureData& cmExperimental::DataForFeature(Feature f)
+{
+ return ::DataForFeature(f);
+}
+
bool cmExperimental::HasSupportEnabled(cmMakefile const& mf, Feature f)
{
bool enabled = false;
- auto& data = DataForFeature(f);
+ auto& data = ::DataForFeature(f);
auto value = mf.GetDefinition(data.Variable);
if (value == data.Uuid) {
diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h
index 26e0d17..c958ab6 100644
--- a/Source/cmExperimental.h
+++ b/Source/cmExperimental.h
@@ -5,6 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+#include <vector>
+
class cmMakefile;
class cmExperimental
@@ -13,9 +16,29 @@ public:
enum class Feature
{
CxxModuleCMakeApi,
+ WindowsKernelModeDriver,
Sentinel,
};
+ enum class TryCompileCondition
+ {
+ Always,
+ SkipCompilerChecks,
+ Never,
+ };
+
+ struct FeatureData
+ {
+ std::string const Name;
+ std::string const Uuid;
+ std::string const Variable;
+ std::string const Description;
+ std::vector<std::string> const TryCompileVariables;
+ TryCompileCondition const ForwardThroughTryCompile;
+ bool Warned;
+ };
+
+ static const FeatureData& DataForFeature(Feature f);
static bool HasSupportEnabled(cmMakefile const& mf, Feature f);
};
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 5e7008b..c54e6ac 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildAndroidMKGenerator.h"
+#include <map>
#include <sstream>
#include <utility>
#include <vector>
diff --git a/Source/cmExportBuildAndroidMKGenerator.h b/Source/cmExportBuildAndroidMKGenerator.h
index 1a9a626..7067488 100644
--- a/Source/cmExportBuildAndroidMKGenerator.h
+++ b/Source/cmExportBuildAndroidMKGenerator.h
@@ -8,7 +8,6 @@
#include <string>
#include "cmExportBuildFileGenerator.h"
-#include "cmExportFileGenerator.h"
#include "cmStateTypes.h"
class cmGeneratorTarget;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index df26bad..69572f4 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -125,6 +126,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
properties);
std::string errorMessage;
+ if (!this->PopulateCxxModuleExportProperties(
+ gte, properties, cmGeneratorExpression::BuildInterface,
+ errorMessage)) {
+ this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR, errorMessage,
+ this->LG->GetMakefile()->GetBacktrace());
+ return false;
+ }
+
if (!this->PopulateExportProperties(gte, properties, errorMessage)) {
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR, errorMessage,
@@ -237,7 +247,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
}
// Store the property.
- properties[prop] = cmJoin(objects, ";");
+ properties[prop] = cmList::to_string(objects);
} else {
// Add the main target file.
{
@@ -418,7 +428,7 @@ std::string cmExportBuildFileGenerator::GetFileSetDirectories(
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
} else {
- resultVector.push_back(cmStrCat('"', dest, '"'));
+ resultVector.emplace_back(cmStrCat('"', dest, '"'));
break;
}
}
@@ -477,7 +487,7 @@ std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
} else {
- resultVector.push_back(cmStrCat('"', escapedFile, '"'));
+ resultVector.emplace_back(cmStrCat('"', escapedFile, '"'));
}
}
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index a58f2b7..273296d 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -14,6 +14,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
+#include "cmCryptoHash.h"
#include "cmExecutionStatus.h"
#include "cmExperimental.h"
#include "cmExportBuildAndroidMKGenerator.h"
@@ -310,7 +311,8 @@ static bool HandlePackage(std::vector<std::string> const& args,
// named by a hash of its own content. This is deterministic and is
// unique with high probability.
const std::string& outDir = mf.GetCurrentBinaryDirectory();
- std::string hash = cmSystemTools::ComputeStringMD5(outDir);
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ std::string hash = hasher.HashString(outDir);
StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str());
return true;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 22276ae..5a12297 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -9,6 +9,7 @@
#include <utility>
#include <cm/memory>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
@@ -383,7 +384,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmGeneratorExpression ge(*target->Makefile->GetCMakeInstance());
std::string dirs = cmGeneratorExpression::Preprocess(
- cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(te), ";"),
+ cmList::to_string(target->Target->GetInstallIncludeDirectoriesEntries(te)),
preprocessRule, true);
this->ReplaceInstallPrefix(dirs);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs);
@@ -536,7 +537,7 @@ static void getCompatibleInterfaceProperties(
const cmComputeLinkInformation::ItemVector& deps = info->GetItems();
for (auto const& dep : deps) {
- if (!dep.Target) {
+ if (!dep.Target || dep.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
continue;
}
getPropertyContents(dep.Target, "COMPATIBLE_INTERFACE_BOOL",
@@ -955,13 +956,13 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
// Isolate the file policy level.
// Support CMake versions as far back as 2.6 but also support using NEW
- // policy settings for up to CMake 3.25 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.26 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.8.3...3.25)\n";
+ << "cmake_policy(VERSION 2.8.3...3.26)\n";
/* clang-format on */
}
@@ -1255,6 +1256,77 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
os << ")\n\n";
}
+bool cmExportFileGenerator::PopulateCxxModuleExportProperties(
+ cmGeneratorTarget const* gte, ImportPropertyMap& properties,
+ cmGeneratorExpression::PreprocessContext ctx, std::string& errorMessage)
+{
+ if (!gte->HaveCxx20ModuleSources(&errorMessage)) {
+ return true;
+ }
+
+ const cm::static_string_view exportedDirectModuleProperties[] = {
+ "CXX_EXTENSIONS"_s,
+ };
+ for (auto const& propName : exportedDirectModuleProperties) {
+ auto const propNameStr = std::string(propName);
+ cmValue prop = gte->Target->GetComputedProperty(
+ propNameStr, *gte->Target->GetMakefile());
+ if (!prop) {
+ prop = gte->Target->GetProperty(propNameStr);
+ }
+ if (prop) {
+ properties[propNameStr] = cmGeneratorExpression::Preprocess(*prop, ctx);
+ }
+ }
+
+ const cm::static_string_view exportedModuleProperties[] = {
+ "INCLUDE_DIRECTORIES"_s,
+ "COMPILE_DEFINITIONS"_s,
+ "COMPILE_OPTIONS"_s,
+ "COMPILE_FEATURES"_s,
+ };
+ for (auto const& propName : exportedModuleProperties) {
+ auto const propNameStr = std::string(propName);
+ cmValue prop = gte->Target->GetComputedProperty(
+ propNameStr, *gte->Target->GetMakefile());
+ if (!prop) {
+ prop = gte->Target->GetProperty(propNameStr);
+ }
+ if (prop) {
+ auto const exportedPropName =
+ cmStrCat("IMPORTED_CXX_MODULES_", propName);
+ properties[exportedPropName] =
+ cmGeneratorExpression::Preprocess(*prop, ctx);
+ }
+ }
+
+ const cm::static_string_view exportedLinkModuleProperties[] = {
+ "LINK_LIBRARIES"_s,
+ };
+ for (auto const& propName : exportedLinkModuleProperties) {
+ auto const propNameStr = std::string(propName);
+ cmValue prop = gte->Target->GetComputedProperty(
+ propNameStr, *gte->Target->GetMakefile());
+ if (!prop) {
+ prop = gte->Target->GetProperty(propNameStr);
+ }
+ if (prop) {
+ auto const exportedPropName =
+ cmStrCat("IMPORTED_CXX_MODULES_", propName);
+ auto value = cmGeneratorExpression::Preprocess(*prop, ctx);
+ this->ResolveTargetsInGeneratorExpressions(
+ value, gte, cmExportFileGenerator::ReplaceFreeTargets);
+ std::vector<std::string> wrappedValues;
+ for (auto& item : cmList{ value }) {
+ wrappedValues.push_back(cmStrCat("$<COMPILE_ONLY:", item, '>'));
+ }
+ properties[exportedPropName] = cmJoin(wrappedValues, ";");
+ }
+ }
+
+ return true;
+}
+
bool cmExportFileGenerator::PopulateExportProperties(
cmGeneratorTarget const* gte, ImportPropertyMap& properties,
std::string& errorMessage)
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index fdda878..6fa19ee 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -175,6 +175,9 @@ protected:
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
const char* versionString);
+ bool PopulateCxxModuleExportProperties(
+ cmGeneratorTarget const* gte, ImportPropertyMap& properties,
+ cmGeneratorExpression::PreprocessContext ctx, std::string& errorMessage);
bool PopulateExportProperties(cmGeneratorTarget const* gte,
ImportPropertyMap& properties,
std::string& errorMessage);
diff --git a/Source/cmExportInstallAndroidMKGenerator.h b/Source/cmExportInstallAndroidMKGenerator.h
index c05751a..061358d 100644
--- a/Source/cmExportInstallAndroidMKGenerator.h
+++ b/Source/cmExportInstallAndroidMKGenerator.h
@@ -8,7 +8,6 @@
#include <set>
#include <string>
-#include "cmExportFileGenerator.h"
#include "cmExportInstallFileGenerator.h"
#include "cmStateTypes.h"
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 538c883..908bb31 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
#include "cmInstallTargetGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -125,6 +126,13 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
gt, cmGeneratorExpression::InstallInterface, properties);
std::string errorMessage;
+ if (!this->PopulateCxxModuleExportProperties(
+ gt, properties, cmGeneratorExpression::InstallInterface,
+ errorMessage)) {
+ cmSystemTools::Error(errorMessage);
+ return false;
+ }
+
if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
cmSystemTools::Error(errorMessage);
return false;
@@ -430,7 +438,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
}
// Store the property.
- properties[prop] = cmJoin(objects, ";");
+ properties[prop] = cmList::to_string(objects);
importedLocations.insert(prop);
} else {
if (target->IsFrameworkOnApple() && target->HasImportLibrary(config)) {
@@ -590,10 +598,12 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
auto cge = ge.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
for (auto const& config : configs) {
- auto dest = cmStrCat("${_IMPORT_PREFIX}/",
- cmOutputConverter::EscapeForCMake(
- cge->Evaluate(gte->LocalGenerator, config, gte),
- cmOutputConverter::WrapQuotes::NoWrap));
+ auto unescapedDest = cge->Evaluate(gte->LocalGenerator, config, gte);
+ auto dest = cmOutputConverter::EscapeForCMake(
+ unescapedDest, cmOutputConverter::WrapQuotes::NoWrap);
+ if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
+ dest = cmStrCat("${_IMPORT_PREFIX}/", dest);
+ }
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
@@ -613,7 +623,7 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
} else {
- resultVector.push_back(cmStrCat('"', dest, '"'));
+ resultVector.emplace_back(cmStrCat('"', dest, '"'));
break;
}
}
@@ -645,11 +655,14 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
fileSet->EvaluateFileEntry(directories, files, entry,
gte->LocalGenerator, config, gte);
}
- auto dest = cmStrCat("${_IMPORT_PREFIX}/",
- cmOutputConverter::EscapeForCMake(
- destCge->Evaluate(gte->LocalGenerator, config, gte),
- cmOutputConverter::WrapQuotes::NoWrap),
- '/');
+ auto unescapedDest = destCge->Evaluate(gte->LocalGenerator, config, gte);
+ auto dest =
+ cmStrCat(cmOutputConverter::EscapeForCMake(
+ unescapedDest, cmOutputConverter::WrapQuotes::NoWrap),
+ '/');
+ if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
+ dest = cmStrCat("${_IMPORT_PREFIX}/", dest);
+ }
bool const contextSensitive = destCge->GetHadContextSensitiveCondition() ||
std::any_of(directoryEntries.begin(), directoryEntries.end(),
@@ -684,7 +697,7 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
} else {
- resultVector.push_back(cmStrCat('"', escapedFile, '"'));
+ resultVector.emplace_back(cmStrCat('"', escapedFile, '"'));
}
}
}
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 8aec12b..02d0444 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -3,6 +3,7 @@
#include "cmExportLibraryDependenciesCommand.h"
#include <map>
+#include <unordered_map>
#include <utility>
#include <cm/memory>
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index f30c3c3..00c9173 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportTryCompileFileGenerator.h"
-#include <map>
#include <utility>
#include <cm/memory>
@@ -13,7 +12,6 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
-#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -156,12 +154,12 @@ std::string cmExportTryCompileFileGenerator::GetFileSetDirectories(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
{
return cmOutputConverter::EscapeForCMake(
- cmJoin(fileSet->GetDirectoryEntries(), ";"));
+ cmList::to_string(fileSet->GetDirectoryEntries()));
}
std::string cmExportTryCompileFileGenerator::GetFileSetFiles(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
{
return cmOutputConverter::EscapeForCMake(
- cmJoin(fileSet->GetFileEntries(), ";"));
+ cmList::to_string(fileSet->GetFileEntries()));
}
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index 8abb5a8..8b0f309 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
#include <chrono>
-#include <cstddef>
#include <ctime>
#include <iomanip>
#include <sstream>
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 280ebb0..3c1bc14 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
#include <cstddef>
-#include <functional>
#include <limits>
#include <map>
#include <memory>
@@ -1679,6 +1678,7 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
}
switch (sk.Kind) {
+ case cmGeneratorTarget::SourceKindCxxModuleSource:
case cmGeneratorTarget::SourceKindObjectSource: {
source["compileGroupIndex"] =
this->AddSourceCompileGroup(sk.Source.Value, si);
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 8f2ebf5..49a0e89 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -30,6 +30,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
+#include "cmCMakePath.h"
#include "cmCryptoHash.h"
#include "cmELF.h"
#include "cmExecutionStatus.h"
@@ -42,6 +43,7 @@
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmHexFileConverter.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -805,7 +807,7 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
std::sort(files.begin(), files.end());
files.erase(std::unique(files.begin(), files.end()), files.end());
- status.GetMakefile().AddDefinition(variable, cmJoin(files, ";"));
+ status.GetMakefile().AddDefinition(variable, cmList::to_string(files));
return true;
}
@@ -1012,7 +1014,8 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args,
if (success) {
if (changed) {
std::string message =
- cmStrCat("Set runtime path of \"", file, "\" to \"", *newRPath, '"');
+ cmStrCat("Set non-toolchain portion of runtime path of \"", file,
+ "\" to \"", *newRPath, '"');
status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
@@ -1066,7 +1069,8 @@ bool HandleRPathSetCommand(std::vector<std::string> const& args,
if (success) {
if (changed) {
std::string message =
- cmStrCat("Set runtime path of \"", file, "\" to \"", *newRPath, '"');
+ cmStrCat("Set non-toolchain portion of runtime path of \"", file,
+ "\" to \"", *newRPath, '"');
status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
@@ -1277,9 +1281,58 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
}
}
- auto realPath =
- cmSystemTools::CollapseFullPath(input, *arguments.BaseDirectory);
- realPath = cmSystemTools::GetRealPath(realPath);
+ bool warnAbout152 = false;
+ bool use152New = true;
+ cmPolicies::PolicyStatus policyStatus =
+ status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0152);
+ switch (policyStatus) {
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ break;
+ case cmPolicies::WARN:
+ use152New = false;
+ warnAbout152 = true;
+ break;
+ case cmPolicies::OLD:
+ use152New = false;
+ warnAbout152 = false;
+ break;
+ }
+
+ auto computeNewPath = [=](std::string const& in, std::string& result) {
+ auto path = cmCMakePath{ in };
+ if (path.IsRelative()) {
+ auto basePath = cmCMakePath{ *arguments.BaseDirectory };
+ path = basePath.Append(path);
+ }
+ result = cmSystemTools::GetActualCaseForPath(
+ cmSystemTools::GetRealPath(path.String()));
+ };
+
+ std::string realPath;
+ if (use152New) {
+ computeNewPath(input, realPath);
+ } else {
+ std::string oldPolicyPath =
+ cmSystemTools::CollapseFullPath(input, *arguments.BaseDirectory);
+ oldPolicyPath = cmSystemTools::GetRealPath(oldPolicyPath);
+ if (warnAbout152) {
+ computeNewPath(input, realPath);
+ if (oldPolicyPath != realPath) {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0152), '\n',
+ "From input path:\n ", input,
+ "\nthe policy OLD behavior produces path:\n ", oldPolicyPath,
+ "\nbut the policy NEW behavior produces path:\n ", realPath,
+ "\nSince the policy is not set, CMake is using the OLD "
+ "behavior for compatibility."));
+ }
+ }
+ realPath = oldPolicyPath;
+ }
status.GetMakefile().AddDefinition(args[2], realPath);
@@ -1556,7 +1609,7 @@ bool HandlePathCommand(std::vector<std::string> const& args,
#endif
std::vector<std::string> path = cmSystemTools::SplitString(args[1], pathSep);
- std::string value = cmJoin(cmMakeRange(path).transform(convert), ";");
+ std::string value = cmList::to_string(cmMakeRange(path).transform(convert));
status.GetMakefile().AddDefinition(args[2], value);
return true;
}
@@ -3158,7 +3211,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
if (!parsedArgs.RPathPrefix.empty()) {
status.GetMakefile().AddDefinition(
parsedArgs.RPathPrefix + "_" + firstPath,
- cmJoin(archive.GetRPaths().at(firstPath), ";"));
+ cmList::to_string(archive.GetRPaths().at(firstPath)));
}
} else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
conflictingDeps.push_back(val.first);
@@ -3166,7 +3219,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
paths.insert(paths.begin(), val.second.begin(), val.second.end());
std::string varName =
parsedArgs.ConflictingDependenciesPrefix + "_" + val.first;
- std::string pathsStr = cmJoin(paths, ";");
+ std::string pathsStr = cmList::to_string(paths);
status.GetMakefile().AddDefinition(varName, pathsStr);
} else {
std::ostringstream e;
@@ -3197,17 +3250,17 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
}
if (!parsedArgs.ResolvedDependenciesVar.empty()) {
- std::string val = cmJoin(deps, ";");
+ std::string val = cmList::to_string(deps);
status.GetMakefile().AddDefinition(parsedArgs.ResolvedDependenciesVar,
val);
}
if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
- std::string val = cmJoin(unresolvedDeps, ";");
+ std::string val = cmList::to_string(unresolvedDeps);
status.GetMakefile().AddDefinition(parsedArgs.UnresolvedDependenciesVar,
val);
}
if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
- std::string val = cmJoin(conflictingDeps, ";");
+ std::string val = cmList::to_string(conflictingDeps);
status.GetMakefile().AddDefinition(
parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val);
}
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
index 5d197d2..548e327 100644
--- a/Source/cmFileLock.cxx
+++ b/Source/cmFileLock.cxx
@@ -12,11 +12,7 @@
cmFileLock::cmFileLock(cmFileLock&& other) noexcept
{
this->File = other.File;
-#if defined(_WIN32)
- other.File = INVALID_HANDLE_VALUE;
-#else
- other.File = -1;
-#endif
+ other.File = (decltype(other.File))-1;
this->Filename = std::move(other.Filename);
}
@@ -32,11 +28,7 @@ cmFileLock::~cmFileLock()
cmFileLock& cmFileLock::operator=(cmFileLock&& other) noexcept
{
this->File = other.File;
-#if defined(_WIN32)
- other.File = INVALID_HANDLE_VALUE;
-#else
- other.File = -1;
-#endif
+ other.File = (decltype(other.File))-1;
this->Filename = std::move(other.Filename);
return *this;
diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h
index 94baea1..0f2e7d9 100644
--- a/Source/cmFileLock.h
+++ b/Source/cmFileLock.h
@@ -7,7 +7,7 @@
#include <string>
#if defined(_WIN32)
-# include <windows.h> // HANDLE
+using HANDLE = void*;
#endif
class cmFileLockResult;
@@ -53,8 +53,8 @@ private:
cmFileLockResult LockWithTimeout(unsigned long timeoutSec);
#if defined(_WIN32)
- HANDLE File = INVALID_HANDLE_VALUE;
- BOOL LockFile(DWORD flags);
+ HANDLE File = (HANDLE)-1;
+ int LockFile(int flags);
#else
int File = -1;
int LockFile(int cmd, int type) const;
diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx
index b7f7f38..632c0e9 100644
--- a/Source/cmFileLockResult.cxx
+++ b/Source/cmFileLockResult.cxx
@@ -5,6 +5,10 @@
#include <cerrno>
#include <cstring>
+#ifdef _WIN32
+# include <Windows.h>
+#endif
+
cmFileLockResult cmFileLockResult::MakeOk()
{
return { OK, 0 };
diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h
index 8a58d1f..e252de7 100644
--- a/Source/cmFileLockResult.h
+++ b/Source/cmFileLockResult.h
@@ -6,10 +6,6 @@
#include <string>
-#if defined(_WIN32)
-# include <windows.h> // DWORD
-#endif
-
/**
* @brief Result of the locking/unlocking file.
* @note See @c cmFileLock
@@ -17,11 +13,7 @@
class cmFileLockResult
{
public:
-#if defined(_WIN32)
- using Error = DWORD;
-#else
using Error = int;
-#endif
/**
* @brief Successful lock/unlock.
diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx
index 7bee5f2..244ade2 100644
--- a/Source/cmFileLockWin32.cxx
+++ b/Source/cmFileLockWin32.cxx
@@ -78,7 +78,7 @@ cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
}
}
-BOOL cmFileLock::LockFile(DWORD flags)
+int cmFileLock::LockFile(int flags)
{
const DWORD reserved = 0;
const unsigned long len = static_cast<unsigned long>(-1);
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index 48a2570..bcf7fba 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -88,6 +89,12 @@ cmFileSet::cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
{
}
+void cmFileSet::CopyEntries(cmFileSet const* fs)
+{
+ cm::append(this->DirectoryEntries, fs->DirectoryEntries);
+ cm::append(this->FileEntries, fs->FileEntries);
+}
+
void cmFileSet::ClearDirectoryEntries()
{
this->DirectoryEntries.clear();
diff --git a/Source/cmFileSet.h b/Source/cmFileSet.h
index 54d430c..c508e2b 100644
--- a/Source/cmFileSet.h
+++ b/Source/cmFileSet.h
@@ -41,6 +41,8 @@ public:
const std::string& GetType() const { return this->Type; }
cmFileSetVisibility GetVisibility() const { return this->Visibility; }
+ void CopyEntries(cmFileSet const* fs);
+
void ClearDirectoryEntries();
void AddDirectoryEntry(BT<std::string> directories);
const std::vector<BT<std::string>>& GetDirectoryEntries() const
diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx
index 0606baf..3d103d3 100644
--- a/Source/cmFileTime.cxx
+++ b/Source/cmFileTime.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileTime.h"
-#include <ctime>
#include <string>
// Use a platform-specific API to get file times efficiently.
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 5e92dd0..9f78418 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -6,6 +6,7 @@
#include <cstddef>
#include <deque>
#include <functional>
+#include <iterator>
#include <map>
#include <utility>
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 9eb0603..df77ad0 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -251,8 +251,14 @@ struct cmFindLibraryHelper
void DebugLibraryFailed(std::string const& name, std::string const& path)
{
if (this->DebugMode) {
- auto regexName =
- cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr);
+ // To improve readability of the debug output, if there is only one
+ // prefix/suffix, use the plain prefix/suffix instead of the regex.
+ const auto& prefix = (this->Prefixes.size() == 1) ? this->Prefixes[0]
+ : this->PrefixRegexStr;
+ const auto& suffix = (this->Suffixes.size() == 1) ? this->Suffixes[0]
+ : this->SuffixRegexStr;
+
+ auto regexName = cmStrCat(prefix, name, suffix);
this->DebugSearches.FailedAt(path, regexName);
}
}
@@ -552,6 +558,14 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
// Search for all names in each search path.
for (std::string const& d : this->SearchPaths) {
for (std::string const& n : this->Names) {
+ fwPath = cmStrCat(d, n, ".xcframework");
+ if (cmSystemTools::FileIsDirectory(fwPath)) {
+ auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ if (this->Validate(finalPath)) {
+ return finalPath;
+ }
+ }
+
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
@@ -572,6 +586,14 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
// Search for each name in all search paths.
for (std::string const& n : this->Names) {
for (std::string const& d : this->SearchPaths) {
+ fwPath = cmStrCat(d, n, ".xcframework");
+ if (cmSystemTools::FileIsDirectory(fwPath)) {
+ auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ if (this->Validate(finalPath)) {
+ return finalPath;
+ }
+ }
+
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index f863a51..30458cd 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -11,7 +11,6 @@
#include <sstream>
#include <utility>
-#include <cm/memory>
#include <cm/optional>
#include <cmext/string_view>
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index f4768b6..8d2d972 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -11,6 +11,7 @@
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
@@ -89,9 +90,9 @@ bool cmFunctionHelperCommand::operator()(
}
// define ARGV and ARGN
- auto const argvDef = cmJoin(expandedArgs, ";");
+ auto const argvDef = cmList::to_string(expandedArgs);
auto const eit = expandedArgs.begin() + (this->Args.size() - 1);
- auto const argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
+ auto const argnDef = cmList::to_string(cmMakeRange(eit, expandedArgs.end()));
makefile.AddDefinition(ARGV, argvDef);
makefile.MarkVariableAsUsed(ARGV);
makefile.AddDefinition(ARGN, argnDef);
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 87377de..a375904 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cstdio>
-#include <memory>
#include <string>
#include <vector>
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 133bf5f..37a2be4 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -3,6 +3,7 @@
#include "cmGeneratedFileStream.h"
#include <cstdio>
+#include <locale>
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -16,7 +17,7 @@
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
{
#ifndef CMAKE_BOOTSTRAP
- if (encoding != codecvt::None) {
+ if (encoding != codecvt_Encoding::None) {
this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
}
#else
@@ -35,13 +36,13 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
cmSystemTools::ReportLastSystemError("");
}
#ifndef CMAKE_BOOTSTRAP
- if (encoding != codecvt::None) {
+ if (encoding != codecvt_Encoding::None) {
this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
}
#else
static_cast<void>(encoding);
#endif
- if (encoding == codecvt::UTF8_WITH_BOM) {
+ if (encoding == codecvt_Encoding::UTF8_WITH_BOM) {
// Write the BOM encoding header into the file
char magic[] = { static_cast<char>(0xEF), static_cast<char>(0xBB),
static_cast<char>(0xBF) };
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index bfc121f..a26616d 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -8,7 +8,7 @@
#include "cmsys/FStream.hxx"
-#include "cm_codecvt.hxx"
+#include "cm_codecvt_Encoding.hxx"
// This is the first base class of cmGeneratedFileStream. It will be
// created before and destroyed after the ofstream portion and can
@@ -77,13 +77,13 @@ class cmGeneratedFileStream
{
public:
using Stream = cmsys::ofstream;
- using Encoding = codecvt::Encoding;
+ using Encoding = codecvt_Encoding;
/**
* This constructor prepares a default stream. The open method must
* be used before writing to the stream.
*/
- cmGeneratedFileStream(Encoding encoding = codecvt::None);
+ cmGeneratedFileStream(codecvt_Encoding encoding = codecvt_Encoding::None);
/**
* This constructor takes the name of the file to be generated. It
@@ -92,7 +92,7 @@ public:
* second argument is set to true.
*/
cmGeneratedFileStream(std::string const& name, bool quiet = false,
- Encoding encoding = codecvt::None);
+ codecvt_Encoding encoding = codecvt_Encoding::None);
/**
* The destructor checks the stream status to be sure the temporary
@@ -151,5 +151,5 @@ public:
* Write a specific string using an alternate encoding.
* Afterward, the original encoding is restored.
*/
- void WriteAltEncoding(std::string const& data, Encoding encoding);
+ void WriteAltEncoding(std::string const& data, codecvt_Encoding encoding);
};
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 4c80d4b..745a749 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2542,7 +2542,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
list.front() = LL_BEGIN;
list.push_back(LL_END);
- return cmJoin(list, ";"_s);
+ return list.to_string();
}
} linkLibraryNode;
@@ -2611,7 +2611,7 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
list.front() = LG_BEGIN;
list.push_back(LG_END);
- return cmJoin(list, ";"_s);
+ return list.to_string();
}
} linkGroupNode;
@@ -2636,7 +2636,7 @@ static const struct HostLinkNode : public cmGeneratorExpressionNode
}
return context->HeadTarget->IsDeviceLink() ? std::string()
- : cmJoin(parameters, ";");
+ : cmList::to_string(parameters);
}
} hostLinkNode;
@@ -2671,7 +2671,7 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
list.insert(list.begin(), static_cast<std::string>(DL_BEGIN));
list.push_back(static_cast<std::string>(DL_END));
- return cmJoin(list, ";");
+ return list.to_string();
}
return std::string();
@@ -3108,7 +3108,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
mf->AddTargetObject(tgtName, o);
}
- return cmJoin(objects, ";");
+ return objects.to_string();
}
} targetObjectsNode;
@@ -3168,7 +3168,7 @@ static const struct TargetRuntimeDllsNode : public TargetRuntimeDllsBaseNode
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
std::vector<std::string> dlls = CollectDlls(parameters, context, content);
- return cmJoin(dlls, ";");
+ return cmList::to_string(dlls);
}
} targetRuntimeDllsNode;
@@ -3191,7 +3191,7 @@ static const struct TargetRuntimeDllDirsNode : public TargetRuntimeDllsBaseNode
dllDirs.push_back(directory);
}
}
- return cmJoin(dllDirs, ";");
+ return cmList::to_string(dllDirs);
}
} targetRuntimeDllDirsNode;
diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h
index 63273e4..490de0a 100644
--- a/Source/cmGeneratorExpressionParser.h
+++ b/Source/cmGeneratorExpressionParser.h
@@ -7,10 +7,9 @@
#include <memory>
#include <vector>
+#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
-struct cmGeneratorExpressionEvaluator;
-
struct cmGeneratorExpressionParser
{
cmGeneratorExpressionParser(std::vector<cmGeneratorExpressionToken> tokens);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7d1fcf3..764618e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -13,6 +13,7 @@
#include <iterator>
#include <queue>
#include <sstream>
+#include <type_traits>
#include <unordered_set>
#include <utility>
@@ -26,7 +27,9 @@
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
+#include "cmCryptoHash.h"
#include "cmCustomCommandGenerator.h"
+#include "cmCxxModuleUsageEffects.h"
#include "cmEvaluatedTargetProperty.h"
#include "cmExperimental.h"
#include "cmFileSet.h"
@@ -51,6 +54,7 @@
#include "cmStandardLevelResolver.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
+#include "cmSyntheticTargetCache.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
@@ -190,7 +194,7 @@ public:
}
static std::string filesStr;
- filesStr = cmJoin(files, ";");
+ filesStr = cmList::to_string(files);
return filesStr;
}
@@ -322,8 +326,7 @@ cmValue cmGeneratorTarget::GetSourcesProperty() const
values.push_back(se->GetInput());
}
static std::string value;
- value.clear();
- value = cmJoin(values, ";");
+ value = cmList::to_string(values);
return cmValue(value);
}
@@ -794,10 +797,10 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
*dirs, lg, config, headTarget, dagChecker, depTgt, language));
}
- if (depTgt->Target->IsFrameworkOnApple()) {
+ if (depTgt->Target->IsFrameworkOnApple() ||
+ depTgt->IsImportedFrameworkFolderOnApple(config)) {
if (auto fwDescriptor = depTgt->GetGlobalGenerator()->SplitFrameworkPath(
- depTgt->GetLocation(config),
- cmGlobalGenerator::FrameworkFormat::Strict)) {
+ depTgt->GetLocation(config))) {
result.push_back(fwDescriptor->Directory);
result.push_back(fwDescriptor->GetFrameworkPath());
}
@@ -1071,6 +1074,12 @@ void cmGeneratorTarget::GetHeaderSources(
IMPLEMENT_VISIT(SourceKindHeader);
}
+void cmGeneratorTarget::GetCxxModuleSources(
+ std::vector<cmSourceFile const*>& data, const std::string& config) const
+{
+ IMPLEMENT_VISIT(SourceKindCxxModuleSource);
+}
+
void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile const*>& data,
const std::string& config) const
{
@@ -1224,6 +1233,11 @@ bool cmGeneratorTarget::IsNormal() const
return this->Target->IsNormal();
}
+bool cmGeneratorTarget::IsRuntimeBinary() const
+{
+ return this->Target->IsRuntimeBinary();
+}
+
bool cmGeneratorTarget::IsSynthetic() const
{
return this->Target->IsSynthetic();
@@ -1493,9 +1507,9 @@ std::string AddLangSpecificInterfaceIncludeDirectories(
}
std::string directories;
- if (const auto* interface = target->GetLinkInterfaceLibraries(
+ if (const auto* link_interface = target->GetLinkInterfaceLibraries(
config, root, LinkInterfaceFor::Usage)) {
- for (const cmLinkItem& library : interface->Libraries) {
+ for (const cmLinkItem& library : link_interface->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
auto* lg = dependency->GetLocalGenerator();
@@ -1948,8 +1962,12 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
// Compute the kind (classification) of this source file.
SourceKind kind;
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ cmFileSet const* fs = this->GetFileSetForSource(config, sf);
if (sf->GetCustomCommand()) {
kind = SourceKindCustomCommand;
+ } else if (!this->Target->IsNormal() && !this->Target->IsImported() &&
+ fs && (fs->GetType() == "CXX_MODULES"_s)) {
+ kind = SourceKindCxxModuleSource;
} else if (this->Target->GetType() == cmStateEnums::UTILITY ||
this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
@@ -3828,7 +3846,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
if (lib.Target == nullptr) {
libDir = cmSystemTools::CollapseFullPath(
lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
- } else if (lib.Target->Target->IsFrameworkOnApple()) {
+ } else if (lib.Target->Target->IsFrameworkOnApple() ||
+ this->IsImportedFrameworkFolderOnApple(config)) {
libDir = lib.Target->GetLocation(config);
} else {
continue;
@@ -5857,7 +5876,7 @@ void cmGeneratorTarget::CheckPropertyCompatibility(
static const std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
for (auto const& dep : deps) {
- if (!dep.Target) {
+ if (!dep.Target || dep.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
continue;
}
@@ -8214,6 +8233,96 @@ void ComputeLinkImplTransitive(cmGeneratorTarget const* self,
}
}
+bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
+ std::string const& config)
+{
+ cmOptionalLinkImplementation impl;
+ this->ComputeLinkImplementationLibraries(config, impl, this,
+ LinkInterfaceFor::Link);
+
+ cmCxxModuleUsageEffects usage(this);
+
+ auto& SyntheticDeps = this->Configs[config].SyntheticDeps;
+
+ for (auto const& entry : impl.Libraries) {
+ auto const* gt = entry.Target;
+ if (!gt || !gt->IsImported()) {
+ continue;
+ }
+
+ if (gt->HaveCxx20ModuleSources()) {
+ auto hasher = cmCryptoHash::New("SHA3_512");
+ constexpr size_t HASH_TRUNCATION = 12;
+ auto dirhash = hasher->HashString(
+ gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
+ std::string safeName = gt->GetName();
+ cmSystemTools::ReplaceString(safeName, ":", "_");
+ auto targetIdent =
+ hasher->HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
+ std::string targetName =
+ cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
+
+ // Check the cache to see if this instance of the imported target has
+ // already been created.
+ auto cached = cache.CxxModuleTargets.find(targetName);
+ cmGeneratorTarget const* synthDep = nullptr;
+ if (cached == cache.CxxModuleTargets.end()) {
+ auto const* model = gt->Target;
+ auto* mf = gt->Makefile;
+ auto* lg = gt->GetLocalGenerator();
+ auto* tgt = mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY,
+ targetName);
+
+ // Copy relevant information from the existing IMPORTED target.
+
+ // Copy policies to the target.
+ tgt->CopyPolicyStatuses(model);
+
+ // Copy file sets.
+ {
+ auto fsNames = model->GetAllFileSetNames();
+ for (auto const& fsName : fsNames) {
+ auto const* fs = model->GetFileSet(fsName);
+ if (!fs) {
+ mf->IssueMessage(MessageType::INTERNAL_ERROR,
+ cmStrCat("Failed to find file set named '",
+ fsName, "' on target '",
+ tgt->GetName(), '\''));
+ continue;
+ }
+ auto* newFs = tgt
+ ->GetOrCreateFileSet(fs->GetName(), fs->GetType(),
+ fs->GetVisibility())
+ .first;
+ newFs->CopyEntries(fs);
+ }
+ }
+
+ // Copy imported C++ module properties.
+ tgt->CopyImportedCxxModulesEntries(model);
+
+ // Copy other properties which may affect the C++ module BMI
+ // generation.
+ tgt->CopyImportedCxxModulesProperties(model);
+
+ // Apply usage requirements to the target.
+ usage.ApplyToTarget(tgt);
+
+ // Create the generator target and attach it to the local generator.
+ auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+ synthDep = gtp.get();
+ lg->AddGeneratorTarget(std::move(gtp));
+ } else {
+ synthDep = cached->second;
+ }
+
+ SyntheticDeps[gt].push_back(synthDep);
+ }
+ }
+
+ return true;
+}
+
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
const std::string& config, cmOptionalLinkImplementation& impl,
cmGeneratorTarget const* head, LinkInterfaceFor implFor) const
@@ -8221,6 +8330,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmLocalGenerator const* lg = this->LocalGenerator;
cmMakefile const* mf = lg->GetMakefile();
cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries();
+ auto const& synthTargetsForConfig = this->Configs[config].SyntheticDeps;
// Collect libraries directly linked in this configuration.
for (auto const& entry : entryRange) {
// Keep this logic in sync with ExpandLinkItems.
@@ -8310,7 +8420,15 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
// The entry is meant for this configuration.
cmLinkItem item =
this->ResolveLinkItem(BT<std::string>(name, entry.Backtrace), lg);
- if (!item.Target) {
+ if (item.Target) {
+ auto depsForTarget = synthTargetsForConfig.find(item.Target);
+ if (depsForTarget != synthTargetsForConfig.end()) {
+ for (auto const* depForTarget : depsForTarget->second) {
+ cmLinkItem synthItem(depForTarget, item.Cross, item.Backtrace);
+ impl.Libraries.emplace_back(std::move(synthItem), false);
+ }
+ }
+ } else {
// Report explicitly linked object files separately.
std::string const& maybeObj = item.AsStr();
if (cmSystemTools::FileIsFullPath(maybeObj)) {
@@ -8572,6 +8690,16 @@ bool cmGeneratorTarget::IsFrameworkOnApple() const
return this->Target->IsFrameworkOnApple();
}
+bool cmGeneratorTarget::IsImportedFrameworkFolderOnApple(
+ const std::string& config) const
+{
+ return this->IsApple() && this->IsImported() &&
+ (this->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->GetType() == cmStateEnums::UNKNOWN_LIBRARY) &&
+ cmSystemTools::IsPathToFramework(this->GetLocation(config));
+}
+
bool cmGeneratorTarget::IsAppBundleOnApple() const
{
return this->Target->IsAppBundleOnApple();
@@ -8864,6 +8992,47 @@ std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile(
return filename;
}
+std::string cmGeneratorTarget::GetImportedXcFrameworkPath(
+ const std::string& config) const
+{
+ if (!(this->IsApple() && this->IsImported() &&
+ (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ this->GetType() == cmStateEnums::UNKNOWN_LIBRARY))) {
+ return {};
+ }
+
+ std::string desiredConfig = config;
+ if (config.empty()) {
+ desiredConfig = "NOCONFIG";
+ }
+
+ std::string result;
+
+ cmValue loc = nullptr;
+ cmValue imp = nullptr;
+ std::string suffix;
+
+ if (this->Target->GetMappedConfig(desiredConfig, loc, imp, suffix)) {
+ if (loc) {
+ result = *loc;
+ } else {
+ std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
+ if (cmValue configLocation = this->GetProperty(impProp)) {
+ result = *configLocation;
+ } else if (cmValue location = this->GetProperty("IMPORTED_LOCATION")) {
+ result = *location;
+ }
+ }
+
+ if (cmSystemTools::IsPathToXcFramework(result)) {
+ return result;
+ }
+ }
+
+ return {};
+}
+
bool cmGeneratorTarget::HaveFortranSources(std::string const& config) const
{
auto sources = cmGeneratorTarget::GetSourceFiles(config);
@@ -8882,24 +9051,28 @@ bool cmGeneratorTarget::HaveFortranSources() const
});
}
-bool cmGeneratorTarget::HaveCxx20ModuleSources() const
+bool cmGeneratorTarget::HaveCxx20ModuleSources(std::string* errorMessage) const
{
auto const& fs_names = this->Target->GetAllFileSetNames();
- return std::any_of(fs_names.begin(), fs_names.end(),
- [this](std::string const& name) -> bool {
- auto const* file_set = this->Target->GetFileSet(name);
- if (!file_set) {
- this->Makefile->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", this->Target->GetName(),
- "\" is tracked to have file set \"", name,
- "\", but it was not found."));
- return false;
- }
-
- auto const& fs_type = file_set->GetType();
- return fs_type == "CXX_MODULES"_s;
- });
+ return std::any_of(
+ fs_names.begin(), fs_names.end(),
+ [this, errorMessage](std::string const& name) -> bool {
+ auto const* file_set = this->Target->GetFileSet(name);
+ if (!file_set) {
+ auto message = cmStrCat("Target \"", this->Target->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found.");
+ if (errorMessage) {
+ *errorMessage = std::move(message);
+ } else {
+ this->Makefile->IssueMessage(MessageType::INTERNAL_ERROR, message);
+ }
+ return false;
+ }
+
+ auto const& fs_type = file_set->GetType();
+ return fs_type == "CXX_MODULES"_s;
+ });
}
cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
@@ -8936,25 +9109,34 @@ void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("The \"", this->GetName(),
- "\" target has C++ module sources but the \"CXX\" language "
- "has not been enabled"));
+ cmStrCat("The target named \"", this->GetName(),
+ "\" has C++ sources that export modules but the \"CXX\" "
+ "language has not been enabled"));
break;
case cmGeneratorTarget::Cxx20SupportLevel::MissingExperimentalFlag:
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("The \"", this->GetName(),
- "\" target has C++ module sources but its experimental "
- "support has not been requested"));
+ cmStrCat("The target named \"", this->GetName(),
+ "\" has C++ sources that export modules but its "
+ "experimental support has not been requested"));
break;
- case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20:
+ case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20: {
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ auto effStandard =
+ standardResolver.GetEffectiveStandard(this, "CXX", config);
+ if (effStandard.empty()) {
+ effStandard = "; no C++ standard found";
+ } else {
+ effStandard = cmStrCat("; found \"cxx_std_", effStandard, '"');
+ }
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
- "The \"", this->GetName(),
- "\" target has C++ module sources but is not using at least "
- "\"cxx_std_20\""));
- break;
+ "The target named \"", this->GetName(),
+ "\" has C++ sources that export modules but does not include "
+ "\"cxx_std_20\" (or newer) among its `target_compile_features`",
+ effStandard));
+ } break;
case cmGeneratorTarget::Cxx20SupportLevel::Supported:
// All is well.
break;
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index dca69fd..7673bef 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -17,6 +17,7 @@
#include <cm/optional>
#include "cmAlgorithms.h"
+#include "cmComputeLinkInformation.h"
#include "cmLinkItem.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
@@ -24,13 +25,13 @@
#include "cmValue.h"
enum class cmBuildStep;
-class cmComputeLinkInformation;
class cmCustomCommand;
class cmFileSet;
class cmGlobalGenerator;
class cmLocalGenerator;
class cmMakefile;
class cmSourceFile;
+struct cmSyntheticTargetCache;
class cmTarget;
struct cmGeneratorExpressionContext;
@@ -51,6 +52,7 @@ public:
bool IsInBuildSystem() const;
bool IsNormal() const;
+ bool IsRuntimeBinary() const;
bool IsSynthetic() const;
bool IsImported() const;
bool IsImportedGloballyVisible() const;
@@ -115,6 +117,7 @@ public:
SourceKindCertificate,
SourceKindCustomCommand,
SourceKindExternalObject,
+ SourceKindCxxModuleSource,
SourceKindExtra,
SourceKindHeader,
SourceKindIDL,
@@ -185,6 +188,8 @@ public:
const std::string& config) const;
void GetHeaderSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
+ void GetCxxModuleSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
void GetExtraSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
void GetCustomCommands(std::vector<cmSourceFile const*>&,
@@ -812,6 +817,10 @@ public:
Apple. */
bool IsFrameworkOnApple() const;
+ /** Return whether this target is an IMPORTED library target on Apple
+ with a .framework folder as its location. */
+ bool IsImportedFrameworkFolderOnApple(const std::string& config) const;
+
/** Return whether this target is an executable Bundle on Apple. */
bool IsAppBundleOnApple() const;
@@ -922,6 +931,11 @@ public:
cmSourceFile& source, const std::string& dir,
cm::optional<std::set<std::string>>& languages) const;
+ std::string GetImportedXcFrameworkPath(const std::string& config) const;
+
+ bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
+ std::string const& config);
+
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -1072,6 +1086,7 @@ private:
std::string SharedDeps;
};
+ friend cmComputeLinkInformation;
using ImportInfoMapType = std::map<std::string, ImportInfo>;
mutable ImportInfoMapType ImportInfoMap;
void ComputeImportInfo(std::string const& desired_config,
@@ -1257,8 +1272,11 @@ public:
*
* This will inspect the target itself to see if C++20 module
* support is expected to work based on its sources.
+ *
+ * If `errorMessage` is given a non-`nullptr`, any error message will be
+ * stored in it, otherwise the error will be reported directly.
*/
- bool HaveCxx20ModuleSources() const;
+ bool HaveCxx20ModuleSources(std::string* errorMessage = nullptr) const;
enum class Cxx20SupportLevel
{
@@ -1294,6 +1312,8 @@ private:
{
bool BuiltFileSetCache = false;
std::map<std::string, cmFileSet const*> FileSetCache;
+ std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>
+ SyntheticDeps;
};
mutable std::map<std::string, InfoByConfig> Configs;
};
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index 42bd206..d2c4fd6 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -6,9 +6,9 @@
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
-#include "cmStringAlgorithms.h"
#include "cmValue.h"
// cmGetCMakePropertyCommand
@@ -35,7 +35,7 @@ bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
} else if (args[1] == "COMPONENTS") {
const std::set<std::string>* components =
status.GetMakefile().GetGlobalGenerator()->GetInstallComponents();
- output = cmJoin(*components, ";");
+ output = cmList::to_string(*components);
} else {
cmValue prop = nullptr;
if (!args[1].empty()) {
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 943ce1d..880756d 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -49,7 +49,8 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
bool source_file_paths_should_be_absolute);
bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
- const std::string& propertyName);
+ const std::string& propertyName,
+ cmMakefile& directory_makefile);
bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
const std::string& propertyName);
@@ -81,6 +82,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
bool source_file_directory_option_enabled = false;
bool source_file_target_option_enabled = false;
+ std::string test_directory;
+ bool test_directory_option_enabled = false;
+
// Get the scope from which to get the property.
cmProperty::ScopeType scope;
if (args[1] == "GLOBAL") {
@@ -116,7 +120,8 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
DoingProperty,
DoingType,
DoingSourceDirectory,
- DoingSourceTargetDirectory
+ DoingSourceTargetDirectory,
+ DoingTestDirectory,
};
Doing doing = DoingName;
for (unsigned int i = 2; i < args.size(); ++i) {
@@ -145,12 +150,19 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
args[i] == "TARGET_DIRECTORY") {
doing = DoingSourceTargetDirectory;
source_file_target_option_enabled = true;
+ } else if (doing == DoingNone && scope == cmProperty::TEST &&
+ args[i] == "DIRECTORY") {
+ doing = DoingTestDirectory;
+ test_directory_option_enabled = true;
} else if (doing == DoingSourceDirectory) {
source_file_directories.push_back(args[i]);
doing = DoingNone;
} else if (doing == DoingSourceTargetDirectory) {
source_file_target_directories.push_back(args[i]);
doing = DoingNone;
+ } else if (doing == DoingTestDirectory) {
+ test_directory = args[i];
+ doing = DoingNone;
} else if (doing == DoingProperty) {
doing = DoingNone;
propertyName = args[i];
@@ -167,12 +179,17 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
}
std::vector<cmMakefile*> source_file_directory_makefiles;
- bool file_scopes_handled =
+ bool source_file_scopes_handled =
SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
- if (!file_scopes_handled) {
+ cmMakefile* test_directory_makefile;
+ bool test_scopes_handled =
+ SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
+ status, test_directory_option_enabled, test_directory,
+ test_directory_makefile);
+ if (!(source_file_scopes_handled && test_scopes_handled)) {
return false;
}
@@ -231,7 +248,8 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
directory_scope_mf,
source_file_paths_should_be_absolute);
case cmProperty::TEST:
- return HandleTestMode(status, name, infoType, variable, propertyName);
+ return HandleTestMode(status, name, infoType, variable, propertyName,
+ *test_directory_makefile);
case cmProperty::VARIABLE:
return HandleVariableMode(status, name, infoType, variable,
propertyName);
@@ -404,7 +422,7 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
- const std::string& propertyName)
+ const std::string& propertyName, cmMakefile& test_makefile)
{
if (name.empty()) {
status.SetError("not given name for TEST scope.");
@@ -412,7 +430,7 @@ bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
}
// Loop over all tests looking for matching names.
- if (cmTest* test = status.GetMakefile().GetTest(name)) {
+ if (cmTest* test = test_makefile.GetTest(name)) {
return StoreResult(infoType, status.GetMakefile(), variable,
test->GetProperty(propertyName));
}
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
index 36446c9..103471b 100644
--- a/Source/cmGetTestPropertyCommand.cxx
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -4,21 +4,42 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
#include "cmTest.h"
#include "cmValue.h"
bool cmGetTestPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- if (args.size() < 3) {
+ std::vector<std::string>::size_type args_size = args.size();
+ if (args_size != 3 && args_size != 5) {
status.SetError("called with incorrect number of arguments");
return false;
}
+ std::string test_directory;
+ bool test_directory_option_enabled = false;
+
+ int var_arg_index = 2;
+ if (args[2] == "DIRECTORY" && args_size == 5) {
+ var_arg_index = 4;
+ test_directory_option_enabled = true;
+ test_directory = args[3];
+ }
+
+ cmMakefile* test_directory_makefile = &status.GetMakefile();
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
+ status, test_directory_option_enabled, test_directory,
+ test_directory_makefile);
+ if (!file_scopes_handled) {
+ return false;
+ }
+
std::string const& testName = args[0];
- std::string const& var = args[2];
+ std::string const& var = args[var_arg_index];
cmMakefile& mf = status.GetMakefile();
- cmTest* test = mf.GetTest(testName);
+ cmTest* test = test_directory_makefile->GetTest(testName);
if (test) {
cmValue prop;
if (!args[1].empty()) {
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 2d35b8f..95e2187 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -6,6 +6,7 @@
#include <memory>
#include <ostream>
#include <set>
+#include <type_traits>
#include <utility>
#include <vector>
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 049d6ba..a2adbd0 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -54,6 +54,8 @@ public:
bool AllowDeleteOnError() const override { return false; }
bool CanEscapeOctothorpe() const override { return true; }
+ bool IsGNUMakeJobServerAware() const override { return false; }
+
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 5175aae..d5099ee 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -13,6 +13,7 @@
#include <iomanip>
#include <iterator>
#include <sstream>
+#include <type_traits>
#include <utility>
#include <cm/memory>
@@ -24,13 +25,12 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <windows.h>
-#endif
+#include "cm_codecvt_Encoding.hxx"
#include "cmAlgorithms.h"
#include "cmCPackPropertiesGenerator.h"
#include "cmComputeTargetDepends.h"
+#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
@@ -55,6 +55,7 @@
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
+#include "cmSyntheticTargetCache.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmVersion.h"
@@ -65,7 +66,6 @@
# include <cm3p/json/value.h>
# include <cm3p/json/writer.h>
-# include "cmCryptoHash.h"
# include "cmQtAutoGenGlobalInitializer.h"
#endif
@@ -142,6 +142,10 @@ cmGlobalGenerator::~cmGlobalGenerator()
{
this->ClearGeneratorMembers();
}
+codecvt_Encoding cmGlobalGenerator::GetMakefileEncoding() const
+{
+ return codecvt_Encoding::None;
+}
#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmGlobalGenerator::GetJson() const
@@ -239,7 +243,8 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
if (!mf->GetDefinition(langComp)) {
if (!optional) {
- cmSystemTools::Error(langComp + " not set, after EnableLanguage");
+ cmSystemTools::Error(
+ cmStrCat(langComp, " not set, after EnableLanguage"));
}
return;
}
@@ -636,11 +641,10 @@ void cmGlobalGenerator::EnableLanguage(
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemTools::WindowsVersion windowsVersion =
cmSystemTools::GetWindowsVersion();
- std::ostringstream windowsVersionString;
- windowsVersionString << windowsVersion.dwMajorVersion << "."
- << windowsVersion.dwMinorVersion << "."
- << windowsVersion.dwBuildNumber;
- mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str());
+ auto windowsVersionString = cmStrCat(windowsVersion.dwMajorVersion, '.',
+ windowsVersion.dwMinorVersion, '.',
+ windowsVersion.dwBuildNumber);
+ mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString);
#endif
// Read the DetermineSystem file
std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
@@ -695,22 +699,22 @@ void cmGlobalGenerator::EnableLanguage(
setupFile, mf->GetCurrentSourceDirectory());
if (!cmSystemTools::FileExists(absSetupFile)) {
cmSystemTools::Error(
- "CMAKE_PROJECT_TOP_LEVEL_INCLUDES file does not exist: " +
- setupFile);
+ cmStrCat("CMAKE_PROJECT_TOP_LEVEL_INCLUDES file does not exist: ",
+ setupFile));
mf->GetState()->SetInTopLevelIncludes(false);
return;
}
if (cmSystemTools::FileIsDirectory(absSetupFile)) {
cmSystemTools::Error(
- "CMAKE_PROJECT_TOP_LEVEL_INCLUDES file is a directory: " +
- setupFile);
+ cmStrCat("CMAKE_PROJECT_TOP_LEVEL_INCLUDES file is a directory: ",
+ setupFile));
mf->GetState()->SetInTopLevelIncludes(false);
return;
}
if (!mf->ReadListFile(absSetupFile)) {
cmSystemTools::Error(
- "Failed reading CMAKE_PROJECT_TOP_LEVEL_INCLUDES file: " +
- setupFile);
+ cmStrCat("Failed reading CMAKE_PROJECT_TOP_LEVEL_INCLUDES file: ",
+ setupFile));
mf->GetState()->SetInTopLevelIncludes(false);
return;
}
@@ -754,7 +758,8 @@ void cmGlobalGenerator::EnableLanguage(
// to avoid duplicate compiler tests.
if (cmSystemTools::FileExists(fpath)) {
if (!mf->ReadListFile(fpath)) {
- cmSystemTools::Error("Could not find cmake module file: " + fpath);
+ cmSystemTools::Error(
+ cmStrCat("Could not find cmake module file: ", fpath));
}
// if this file was found then the language was already determined
// to be working
@@ -778,8 +783,8 @@ void cmGlobalGenerator::EnableLanguage(
cmStrCat("CMakeDetermine", lang, "Compiler.cmake");
std::string determineFile = mf->GetModulesFile(determineCompiler);
if (!mf->ReadListFile(determineFile)) {
- cmSystemTools::Error("Could not find cmake module file: " +
- determineCompiler);
+ cmSystemTools::Error(
+ cmStrCat("Could not find cmake module file: ", determineCompiler));
}
if (cmSystemTools::GetFatalErrorOccurred()) {
return;
@@ -807,7 +812,8 @@ void cmGlobalGenerator::EnableLanguage(
// configures CMake(LANG)Compiler.cmake
fpath = cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake");
if (!mf->ReadListFile(fpath)) {
- cmSystemTools::Error("Could not find cmake module file: " + fpath);
+ cmSystemTools::Error(
+ cmStrCat("Could not find cmake module file: ", fpath));
}
this->SetLanguageEnabledFlag(lang, mf);
needSetLanguageEnabledMaps[lang] = true;
@@ -890,10 +896,11 @@ void cmGlobalGenerator::EnableLanguage(
fpath = cmStrCat("CMake", lang, "Information.cmake");
std::string informationFile = mf->GetModulesFile(fpath);
if (informationFile.empty()) {
- cmSystemTools::Error("Could not find cmake module file: " + fpath);
+ cmSystemTools::Error(
+ cmStrCat("Could not find cmake module file: ", fpath));
} else if (!mf->ReadListFile(informationFile)) {
- cmSystemTools::Error("Could not process cmake module file: " +
- informationFile);
+ cmSystemTools::Error(
+ cmStrCat("Could not process cmake module file: ", informationFile));
}
}
if (needSetLanguageEnabledMaps[lang]) {
@@ -911,8 +918,8 @@ void cmGlobalGenerator::EnableLanguage(
std::string testLang = cmStrCat("CMakeTest", lang, "Compiler.cmake");
std::string ifpath = mf->GetModulesFile(testLang);
if (!mf->ReadListFile(ifpath)) {
- cmSystemTools::Error("Could not find cmake module file: " +
- testLang);
+ cmSystemTools::Error(
+ cmStrCat("Could not find cmake module file: ", testLang));
}
std::string compilerWorks =
cmStrCat("CMAKE_", lang, "_COMPILER_WORKS");
@@ -977,7 +984,7 @@ void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os,
void cmGlobalGenerator::CheckCompilerIdCompatibility(
cmMakefile* mf, std::string const& lang) const
{
- std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID";
+ std::string compilerIdVar = cmStrCat("CMAKE_", lang, "_COMPILER_ID");
std::string const compilerId = mf->GetSafeDefinition(compilerIdVar);
if (compilerId == "AppleClang") {
@@ -1105,9 +1112,9 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(
}
{
// Fix compiler versions.
- std::string version = "CMAKE_" + lang + "_COMPILER_VERSION";
- std::string emulated = "CMAKE_" + lang + "_SIMULATE_VERSION";
- std::string emulatedId = "CMAKE_" + lang + "_SIMULATE_ID";
+ std::string version = cmStrCat("CMAKE_", lang, "_COMPILER_VERSION");
+ std::string emulated = cmStrCat("CMAKE_", lang, "_SIMULATE_VERSION");
+ std::string emulatedId = cmStrCat("CMAKE_", lang, "_SIMULATE_ID");
std::string const& actual = mf->GetRequiredDefinition(emulated);
mf->AddDefinition(version, actual);
mf->RemoveDefinition(emulatedId);
@@ -1208,7 +1215,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
return;
}
- std::string linkerPrefVar = "CMAKE_" + l + "_LINKER_PREFERENCE";
+ std::string linkerPrefVar = cmStrCat("CMAKE_", l, "_LINKER_PREFERENCE");
cmValue linkerPref = mf->GetDefinition(linkerPrefVar);
int preference = 0;
if (cmNonempty(linkerPref)) {
@@ -1234,7 +1241,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
this->LanguageToLinkerPreference[l] = preference;
- std::string outputExtensionVar = "CMAKE_" + l + "_OUTPUT_EXTENSION";
+ std::string outputExtensionVar = cmStrCat("CMAKE_", l, "_OUTPUT_EXTENSION");
if (cmValue p = mf->GetDefinition(outputExtensionVar)) {
std::string outputExtension = *p;
this->LanguageToOutputExtension[l] = outputExtension;
@@ -1251,7 +1258,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
this->FillExtensionToLanguageMap(l, mf);
std::string ignoreExtensionsVar =
- std::string("CMAKE_") + std::string(l) + std::string("_IGNORE_EXTENSIONS");
+ cmStrCat("CMAKE_", l, "_IGNORE_EXTENSIONS");
std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar);
cmList extensionList{ ignoreExts };
for (std::string const& i : extensionList) {
@@ -1262,8 +1269,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
cmMakefile* mf)
{
- std::string extensionsVar = std::string("CMAKE_") + std::string(l) +
- std::string("_SOURCE_FILE_EXTENSIONS");
+ std::string extensionsVar = cmStrCat("CMAKE_", l, "_SOURCE_FILE_EXTENSIONS");
const std::string& exts = mf->GetSafeDefinition(extensionsVar);
cmList extensionList{ exts };
for (std::string const& i : extensionList) {
@@ -1555,6 +1561,17 @@ bool cmGlobalGenerator::Compute()
}
#endif
+ // Iterate through all targets and set up C++20 module targets.
+ // Create target templates for each imported target with C++20 modules.
+ // INTERFACE library with BMI-generating rules and a collation step?
+ // Maybe INTERFACE libraries with modules files should just do BMI-only?
+ // Make `add_dependencies(imported_target
+ // $<$<TARGET_NAME_IF_EXISTS:uses_imported>:synth1>
+ // $<$<TARGET_NAME_IF_EXISTS:other_uses_imported>:synth2>)`
+ if (!this->DiscoverSyntheticTargets()) {
+ return false;
+ }
+
// Add generator specific helper commands
for (const auto& localGen : this->LocalGenerators) {
localGen->AddHelperCommands();
@@ -1779,6 +1796,34 @@ void cmGlobalGenerator::ComputeTargetOrder(cmGeneratorTarget const* gt,
entry->second = index++;
}
+bool cmGlobalGenerator::DiscoverSyntheticTargets()
+{
+ cmSyntheticTargetCache cache;
+
+ for (auto const& gen : this->LocalGenerators) {
+ // Because DiscoverSyntheticTargets() adds generator targets, we need to
+ // cache the existing list of generator targets before starting.
+ std::vector<cmGeneratorTarget*> genTargets;
+ genTargets.reserve(gen->GetGeneratorTargets().size());
+ for (auto const& tgt : gen->GetGeneratorTargets()) {
+ genTargets.push_back(tgt.get());
+ }
+
+ for (auto* tgt : genTargets) {
+ std::vector<std::string> const& configs =
+ tgt->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
+ for (auto const& config : configs) {
+ if (!tgt->DiscoverSyntheticTargets(cache, config)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
bool cmGlobalGenerator::AddHeaderSetVerification()
{
for (auto const& gen : this->LocalGenerators) {
@@ -1886,7 +1931,7 @@ void cmGlobalGenerator::FinalizeTargetConfiguration()
std::set<std::string> standardIncludesSet;
for (std::string const& li : langs) {
std::string const standardIncludesVar =
- "CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES";
+ cmStrCat("CMAKE_", li, "_STANDARD_INCLUDE_DIRECTORIES");
std::string const& standardIncludesStr =
mf->GetSafeDefinition(standardIncludesVar);
cmList standardIncludesList{ standardIncludesStr };
@@ -2017,13 +2062,14 @@ void cmGlobalGenerator::CheckTargetProperties()
for (auto const& notFound : notFoundMap) {
notFoundVars += notFound.first;
notFoundVars += notFound.second;
- notFoundVars += "\n";
+ notFoundVars += '\n';
}
- cmSystemTools::Error("The following variables are used in this project, "
- "but they are set to NOTFOUND.\n"
- "Please set them or make sure they are set and "
- "tested correctly in the CMake files:\n" +
- notFoundVars);
+ cmSystemTools::Error(
+ cmStrCat("The following variables are used in this project, "
+ "but they are set to NOTFOUND.\n"
+ "Please set them or make sure they are set and "
+ "tested correctly in the CMake files:\n",
+ notFoundVars));
}
}
@@ -2181,8 +2227,8 @@ int cmGlobalGenerator::Build(
outputflag, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error(
- "Generator: execution of make failed. Make command was: " +
- makeCommandStr);
+ cmStrCat("Generator: execution of make failed. Make command was: ",
+ makeCommandStr));
ostr << *outputPtr
<< "\nGenerator: execution of make failed. Make command was: "
<< outputMakeCommandStr << std::endl;
@@ -3216,7 +3262,6 @@ std::set<std::string> const& cmGlobalGenerator::GetDirectoryContent(
void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
std::string const& content)
{
-#if !defined(CMAKE_BOOTSTRAP)
// Ignore if there are no outputs.
if (outputs.empty()) {
return;
@@ -3236,20 +3281,14 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
// Associate the hash with this output.
this->RuleHashes[fname] = hash;
-#else
- (void)outputs;
- (void)content;
-#endif
}
void cmGlobalGenerator::CheckRuleHashes()
{
-#if !defined(CMAKE_BOOTSTRAP)
std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory();
std::string pfile = cmStrCat(home, "/CMakeFiles/CMakeRuleHashes.txt");
this->CheckRuleHashes(pfile, home);
this->WriteRuleHashes(pfile);
-#endif
}
void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile,
@@ -3342,7 +3381,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
// Place the labels file in a per-target support directory.
std::string dir = target->GetSupportDirectory();
std::string file = cmStrCat(dir, "/Labels.txt");
- std::string json_file = dir + "/Labels.json";
+ std::string json_file = cmStrCat(dir, "/Labels.json");
#ifndef CMAKE_BOOTSTRAP
// Check whether labels are enabled for this target.
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 9aefaff..6d29dc1 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -19,18 +19,16 @@
#include <cmext/algorithm>
#include <cmext/string_view>
-#include "cm_codecvt.hxx"
-
#include "cmBuildOptions.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmExportSet.h"
+#include "cmLocalGenerator.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
-#include "cmTransformDepfile.h"
#include "cmValue.h"
#if !defined(CMAKE_BOOTSTRAP)
@@ -41,13 +39,15 @@
#define CMAKE_DIRECTORY_ID_SEP "::@"
+enum class cmDepfileFormat;
+enum class codecvt_Encoding;
+
class cmDirectoryId;
class cmExportBuildFileGenerator;
class cmExternalMakefileProjectGenerator;
class cmGeneratorTarget;
class cmInstallRuntimeDependencySet;
class cmLinkLineComputer;
-class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
class cmQtAutoGenGlobalInitializer;
@@ -120,10 +120,7 @@ public:
}
/** Get encoding used by generator for makefile files */
- virtual codecvt::Encoding GetMakefileEncoding() const
- {
- return codecvt::None;
- }
+ virtual codecvt_Encoding GetMakefileEncoding() const;
#if !defined(CMAKE_BOOTSTRAP)
/** Get a JSON object describing the generator. */
@@ -161,6 +158,8 @@ public:
virtual bool CheckCxxModuleSupport() { return false; }
+ virtual bool IsGNUMakeJobServerAware() const { return false; }
+
bool Compute();
virtual void AddExtraIDETargets() {}
@@ -640,6 +639,8 @@ public:
};
StripCommandStyle GetStripCommandStyle(std::string const& strip);
+ virtual std::string& EncodeLiteral(std::string& lit) { return lit; }
+
protected:
// for a project collect all its targets by following depend
// information, and also collect all the targets
@@ -661,6 +662,8 @@ protected:
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
+ bool DiscoverSyntheticTargets();
+
bool AddHeaderSetVerification();
bool AddAutomaticSources();
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 2453bfc..4ba53ec 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -670,7 +670,7 @@ bool cmGlobalGhsMultiGenerator::AddCheckTarget()
}
// Add the cache file.
- listFiles.push_back(cmStrCat(
+ listFiles.emplace_back(cmStrCat(
this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeCache.txt"));
// Print not implemented warning.
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index f1d4d09..44980d6 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -5,6 +5,7 @@
#include <ostream>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -45,7 +46,7 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
std::string const& lang,
cmValue envVar) const
{
- if (lang == "CXX" || lang == "C") {
+ if (lang == "CXX"_s || lang == "C"_s) {
/* clang-format off */
os <<
"To use the JOM generator with Visual C++, cmake must be run from a "
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 5e74875..cd3ed33 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -47,6 +47,8 @@ public:
void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
bool optional) override;
+ bool IsGNUMakeJobServerAware() const override { return false; }
+
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index e543aea..26b30fd 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalMSYSMakefileGenerator.h"
+#include <cmext/string_view>
+
#include "cmsys/FStream.hxx"
#include "cmMakefile.h"
@@ -31,7 +33,7 @@ std::string cmGlobalMSYSMakefileGenerator::FindMinGW(
while (fin) {
fin >> path;
fin >> mount;
- if (mount == "/mingw") {
+ if (mount == "/mingw"_s) {
mingwBin = cmStrCat(path, "/bin");
}
}
@@ -45,7 +47,7 @@ void cmGlobalMSYSMakefileGenerator::EnableLanguage(
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
if (!mf->IsSet("CMAKE_AR") && !this->CMakeInstance->GetIsInTryCompile() &&
- !(1 == l.size() && l[0] == "NONE")) {
+ !(1 == l.size() && l[0] == "NONE"_s)) {
cmSystemTools::Error(
"CMAKE_AR was not found, please set to archive program. " +
mf->GetSafeDefinition("CMAKE_AR"));
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index cb53850..424c4bd 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -5,6 +5,7 @@
#include <ostream>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -88,7 +89,7 @@ cmDocumentationEntry cmGlobalNMakeMakefileGenerator::GetDocumentation()
void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(
std::ostream& os, std::string const& lang, cmValue envVar) const
{
- if (lang == "CXX" || lang == "C") {
+ if (lang == "CXX"_s || lang == "C"_s) {
/* clang-format off */
os <<
"To use the NMake generator with Visual C++, cmake must be run from a "
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 436ebca..eafab83 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -7,7 +7,7 @@
#include <string>
#include <vector>
-#include "cm_codecvt.hxx"
+#include "cm_codecvt_Encoding.hxx"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -38,9 +38,10 @@ public:
static std::string GetActualName() { return "NMake Makefiles"; }
/** Get encoding used by generator for makefile files */
- codecvt::Encoding GetMakefileEncoding() const override
+ codecvt_Encoding GetMakefileEncoding() const override
{
- return this->NMakeSupportsUTF8 ? codecvt::UTF8_WITH_BOM : codecvt::ANSI;
+ return this->NMakeSupportsUTF8 ? codecvt_Encoding::UTF8_WITH_BOM
+ : codecvt_Encoding::ANSI;
}
/** Get the documentation entry for this generator. */
@@ -53,6 +54,8 @@ public:
void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
bool optional) override;
+ bool IsGNUMakeJobServerAware() const override { return false; }
+
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 97c9b70..30305a1 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -8,6 +8,7 @@
#include <cstdio>
#include <functional>
#include <sstream>
+#include <type_traits>
#include <utility>
#include <cm/iterator>
@@ -181,14 +182,13 @@ std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
return encoded;
}
-std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit)
+std::string cmGlobalNinjaGenerator::GetEncodedLiteral(const std::string& lit)
{
std::string result = lit;
- EncodeLiteralInplace(result);
- return result;
+ return this->EncodeLiteral(result);
}
-void cmGlobalNinjaGenerator::EncodeLiteralInplace(std::string& lit)
+std::string& cmGlobalNinjaGenerator::EncodeLiteral(std::string& lit)
{
cmSystemTools::ReplaceString(lit, "$", "$$");
cmSystemTools::ReplaceString(lit, "\n", "$\n");
@@ -196,6 +196,7 @@ void cmGlobalNinjaGenerator::EncodeLiteralInplace(std::string& lit)
cmSystemTools::ReplaceString(lit, cmStrCat('$', this->GetCMakeCFGIntDir()),
this->GetCMakeCFGIntDir());
}
+ return lit;
}
std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path)
@@ -207,7 +208,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path)
else
std::replace(result.begin(), result.end(), '/', '\\');
#endif
- this->EncodeLiteralInplace(result);
+ this->EncodeLiteral(result);
cmSystemTools::ReplaceString(result, " ", "$ ");
cmSystemTools::ReplaceString(result, ":", "$:");
return result;
@@ -394,7 +395,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
#endif
vars["COMMAND"] = std::move(cmd);
}
- vars["DESC"] = this->EncodeLiteral(description);
+ vars["DESC"] = this->GetEncodedLiteral(description);
if (restat) {
vars["restat"] = "1";
}
@@ -553,6 +554,15 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
{
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
+
+ // Attempt to use full path to COMSPEC, default "cmd.exe"
+ std::string comspec;
+ if (cmSystemTools::GetEnv("COMSPEC", comspec) &&
+ cmSystemTools::FileIsFullPath(comspec)) {
+ this->Comspec = comspec;
+ } else {
+ this->Comspec = "cmd.exe";
+ }
#endif
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
}
@@ -566,7 +576,7 @@ std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator(
cm::make_unique<cmLocalNinjaGenerator>(this, mf));
}
-codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
+codecvt_Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
{
return this->NinjaExpectedEncoding;
}
@@ -799,7 +809,7 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
if (this->NinjaSupportsCodePage) {
this->CheckNinjaCodePage();
} else {
- this->NinjaExpectedEncoding = codecvt::ANSI;
+ this->NinjaExpectedEncoding = codecvt_Encoding::ANSI;
}
#endif
}
@@ -830,9 +840,9 @@ void cmGlobalNinjaGenerator::CheckNinjaCodePage()
lineView.substr(cmStrLen("Build file encoding: "));
if (encoding == "UTF-8") {
// Ninja expects UTF-8. We use that internally. No conversion needed.
- this->NinjaExpectedEncoding = codecvt::None;
+ this->NinjaExpectedEncoding = codecvt_Encoding::None;
} else {
- this->NinjaExpectedEncoding = codecvt::ANSI;
+ this->NinjaExpectedEncoding = codecvt_Encoding::ANSI;
}
found = true;
break;
@@ -842,10 +852,10 @@ void cmGlobalNinjaGenerator::CheckNinjaCodePage()
this->GetCMakeInstance()->IssueMessage(
MessageType::WARNING,
"Could not determine Ninja's code page, defaulting to UTF-8");
- this->NinjaExpectedEncoding = codecvt::None;
+ this->NinjaExpectedEncoding = codecvt_Encoding::None;
}
} else {
- this->NinjaExpectedEncoding = codecvt::ANSI;
+ this->NinjaExpectedEncoding = codecvt_Encoding::ANSI;
}
}
@@ -2642,7 +2652,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
for (cmScanDepInfo const& object : objects) {
for (auto const& p : object.Provides) {
std::string mod;
- if (!p.CompiledModulePath.empty()) {
+ if (cmDyndepCollation::IsBmiOnly(export_info, object.PrimaryOutput)) {
+ mod = object.PrimaryOutput;
+ } else if (!p.CompiledModulePath.empty()) {
// The scanner provided the path to the module file.
mod = p.CompiledModulePath;
if (!cmSystemTools::FileIsFullPath(mod)) {
@@ -2713,8 +2725,12 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput);
build.ImplicitOuts.clear();
for (auto const& p : object.Provides) {
- build.ImplicitOuts.push_back(
- this->ConvertToNinjaPath(mod_files[p.LogicalName].BmiPath));
+ auto const implicitOut =
+ this->ConvertToNinjaPath(mod_files[p.LogicalName].BmiPath);
+ // Ignore the `provides` when the BMI is the output.
+ if (implicitOut != build.Outputs[0]) {
+ build.ImplicitOuts.emplace_back(implicitOut);
+ }
}
build.ImplicitDeps.clear();
for (auto const& r : object.Requires) {
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index bfbe57f..c43e27c 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -16,7 +16,7 @@
#include <cm/optional>
-#include "cm_codecvt.hxx"
+#include "cm_codecvt_Encoding.hxx"
#include "cmBuildOptions.h"
#include "cmGeneratedFileStream.h"
@@ -77,8 +77,8 @@ public:
static void WriteDivider(std::ostream& os);
static std::string EncodeRuleName(std::string const& name);
- std::string EncodeLiteral(const std::string& lit);
- void EncodeLiteralInplace(std::string& lit);
+ std::string& EncodeLiteral(std::string& lit) override;
+ std::string GetEncodedLiteral(const std::string& lit);
std::string EncodePath(const std::string& path);
std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
@@ -192,7 +192,7 @@ public:
bool IsNinja() const override { return true; }
/** Get encoding used by generator for ninja files */
- codecvt::Encoding GetMakefileEncoding() const override;
+ codecvt_Encoding GetMakefileEncoding() const override;
static cmDocumentationEntry GetDocumentation();
@@ -282,6 +282,10 @@ public:
};
MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
+#ifdef _WIN32
+ std::string const& GetComspec() const { return this->Comspec; }
+#endif
+
// -- Additional clean files
void AddAdditionalCleanFile(std::string fileName, const std::string& config);
const char* GetAdditionalCleanTargetName() const
@@ -590,7 +594,12 @@ private:
bool NinjaSupportsMetadataOnRegeneration = false;
bool NinjaSupportsCodePage = false;
- codecvt::Encoding NinjaExpectedEncoding = codecvt::None;
+ codecvt_Encoding NinjaExpectedEncoding = codecvt_Encoding::None;
+
+#ifdef _WIN32
+ // Windows Command shell.
+ std::string Comspec;
+#endif
bool DiagnosedCxxModuleNinjaSupport = false;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 760679a..ee78351 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -120,6 +120,8 @@ public:
void Configure() override;
+ bool IsGNUMakeJobServerAware() const override { return true; }
+
/**
* Generate the all required files for building this project/tree. This
* basically creates a series of LocalGenerators for each directory and
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 35227db..541db63 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -9,6 +9,7 @@
#include <utility>
#include <cm/memory>
+#include <cmext/string_view>
#include <cm3p/json/reader.h>
#include <cm3p/json/value.h>
@@ -17,6 +18,7 @@
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cmCryptoHash.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -83,10 +85,10 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
{
if (this->SystemIsWindowsCE && ts.empty() &&
this->DefaultPlatformToolset.empty()) {
- std::ostringstream e;
- e << this->GetName() << " Windows CE version '" << this->SystemVersion
- << "' requires CMAKE_GENERATOR_TOOLSET to be set.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->GetName(), " Windows CE version '", this->SystemVersion,
+ "' requires CMAKE_GENERATOR_TOOLSET to be set."));
return false;
}
@@ -105,16 +107,17 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (!this->CustomFlagTableDir.empty() &&
!(cmSystemTools::FileIsFullPath(this->CustomFlagTableDir) &&
cmSystemTools::FileIsDirectory(this->CustomFlagTableDir))) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset\n"
- " customFlagTableDir=" << this->CustomFlagTableDir << "\n"
- "that is not an absolute path to an existing directory.";
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset\n"
+ " customFlagTableDir=",
+ this->CustomFlagTableDir,
+ "\n"
+ "that is not an absolute path to an existing directory."));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -125,7 +128,8 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
// differing from the "false" and "true" values used in older toolsets.
// A VS 2015 update changed it back. Parse the "link.xml" file to
// discover which one we need.
- std::string const link_xml = this->VCTargetsPath + "/1033/link.xml";
+ std::string const link_xml =
+ cmStrCat(this->VCTargetsPath, "/1033/link.xml");
cmsys::ifstream fin(link_xml.c_str());
std::string line;
while (fin && cmSystemTools::GetLineFromStream(fin, line)) {
@@ -140,24 +144,24 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
this->SupportsUnityBuilds =
this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 ||
(this->Version == cmGlobalVisualStudioGenerator::VSVersion::VS15 &&
- cmSystemTools::PathExists(this->VCTargetsPath +
- "/Microsoft.Cpp.Unity.targets"));
+ cmSystemTools::PathExists(
+ cmStrCat(this->VCTargetsPath, "/Microsoft.Cpp.Unity.targets")));
if (this->GeneratorToolsetCuda.empty()) {
// Find the highest available version of the CUDA tools.
std::vector<std::string> cudaTools;
std::string bcDir;
if (this->GeneratorToolsetCudaCustomDir.empty()) {
- bcDir = this->VCTargetsPath + "/BuildCustomizations";
+ bcDir = cmStrCat(this->VCTargetsPath, "/BuildCustomizations");
} else {
- bcDir = this->GetPlatformToolsetCudaCustomDirString() +
- this->GetPlatformToolsetCudaVSIntegrationSubdirString() +
- "extras\\visual_studio_integration\\MSBuildExtensions";
+ bcDir = cmStrCat(this->GetPlatformToolsetCudaCustomDirString(),
+ this->GetPlatformToolsetCudaVSIntegrationSubdirString(),
+ "extras\\visual_studio_integration\\MSBuildExtensions");
cmSystemTools::ConvertToUnixSlashes(bcDir);
}
cmsys::Glob gl;
gl.SetRelative(bcDir.c_str());
- if (gl.FindFiles(bcDir + "/CUDA *.props")) {
+ if (gl.FindFiles(cmStrCat(bcDir, "/CUDA *.props"))) {
cudaTools = gl.GetFiles();
}
if (!cudaTools.empty()) {
@@ -168,18 +172,19 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
} else if (!this->GeneratorToolsetCudaCustomDir.empty()) {
// Generate an error if Visual Studio integration files are not found
// inside of custom cuda toolset.
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset\n"
- " cuda=" << this->GeneratorToolsetCudaCustomDir << "\n"
- "cannot detect Visual Studio integration files in path\n"
- " " << bcDir;
-
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset\n"
+ " cuda=",
+ this->GeneratorToolsetCudaCustomDir,
+ "\n"
+ "cannot detect Visual Studio integration files in path\n"
+ " ",
+ bcDir));
// Clear the configured tool-set
this->GeneratorToolsetCuda.clear();
@@ -187,35 +192,40 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
}
if (!this->GeneratorToolsetVersion.empty() &&
- this->GeneratorToolsetVersion != "Test Toolset Version") {
- // If a specific minor version of the toolset was requested, verify that it
- // is compatible to the major version and that is exists on disk.
- // If not clear the value.
- std::string versionToolset = this->GeneratorToolsetVersion;
- cmsys::RegularExpression regex("[0-9][0-9]\\.[0-9][0-9]");
- if (regex.find(versionToolset)) {
- versionToolset = "v" + versionToolset.erase(2, 1);
- } else {
- // Version not recognized. Clear it.
- versionToolset.clear();
- }
+ this->GeneratorToolsetVersion != "Test Toolset Version"_s) {
+ // If a specific minor version of the MSVC toolset is requested, verify
+ // that it is compatible with the PlatformToolset version. The ability to
+ // choose a minor version of MSVC has been available since v141.
+ std::string const& platformToolset = this->GetPlatformToolsetString();
+ cmsys::RegularExpression vcPlatformToolsetRegex("^v[0-9][0-9][0-9]$");
+ if (vcPlatformToolsetRegex.find(platformToolset) ||
+ platformToolset == "Test Toolset"_s) {
+ std::string versionToolset = this->GeneratorToolsetVersion;
+ cmsys::RegularExpression versionToolsetRegex("^[0-9][0-9]\\.[0-9][0-9]");
+ if (versionToolsetRegex.find(versionToolset)) {
+ versionToolset = cmStrCat('v', versionToolset.erase(2, 1));
+ } else {
+ // Version not recognized. Clear it.
+ versionToolset.clear();
+ }
- if (!cmHasPrefix(versionToolset, this->GetPlatformToolsetString())) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset and version specification\n"
- " " << this->GetPlatformToolsetString() << ",version=" <<
- this->GeneratorToolsetVersion << "\n"
- "contains an invalid version specification."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ if (!cmHasPrefix(versionToolset, platformToolset)) {
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset and version specification\n"
+ " ",
+ this->GetPlatformToolsetString(),
+ ",version=", this->GeneratorToolsetVersion,
+ "\n"
+ "contains an invalid version specification."));
- // Clear the configured tool-set
- this->GeneratorToolsetVersion.clear();
+ // Clear the configured tool-set
+ this->GeneratorToolsetVersion.clear();
+ }
}
std::string auxProps;
@@ -232,40 +242,40 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
this->GeneratorToolsetVersionProps = std::move(auxProps);
break;
case AuxToolset::PropsMissing: {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset and version specification\n"
- " " << this->GetPlatformToolsetString() << ",version=" <<
- this->GeneratorToolsetVersion << "\n"
- "does not seem to be installed at\n" <<
- " " << auxProps;
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset and version specification\n"
+ " ",
+ this->GetPlatformToolsetString(),
+ ",version=", this->GeneratorToolsetVersion,
+ "\n"
+ "does not seem to be installed at\n"
+ " ",
+ auxProps));
// Clear the configured tool-set
this->GeneratorToolsetVersion.clear();
this->GeneratorToolsetVersionProps = {};
} break;
case AuxToolset::PropsIndeterminate: {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset and version specification\n"
- " " << this->GetPlatformToolsetString() << ",version=" <<
- this->GeneratorToolsetVersion << "\n"
- "has multiple matches installed at\n" <<
- " " << auxProps << "\n" <<
- "The toolset and version specification must resolve \n" <<
- "to a single installed toolset";
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset and version specification\n"
+ " ",
+ this->GetPlatformToolsetString(),
+ ",version=", this->GeneratorToolsetVersion,
+ "\n"
+ "has multiple matches installed at\n",
+ " ", auxProps, "\n",
+ "The toolset and version specification must resolve \n"
+ "to a single installed toolset"));
// Clear the configured tool-set
this->GeneratorToolsetVersion.clear();
@@ -319,47 +329,47 @@ bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
for (; fi != fields.end(); ++fi) {
std::string::size_type pos = fi->find('=');
if (pos == fi->npos) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset specification\n"
- " " << ts << "\n"
- "that contains a field after the first ',' with no '='."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset specification\n"
+ " ",
+ ts,
+ "\n"
+ "that contains a field after the first ',' with no '='."));
return false;
}
std::string const key = fi->substr(0, pos);
std::string const value = fi->substr(pos + 1);
if (!handled.insert(key).second) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset specification\n"
- " " << ts << "\n"
- "that contains duplicate field key '" << key << "'."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset specification\n"
+ " ",
+ ts,
+ "\n"
+ "that contains duplicate field key '",
+ key, "'."));
return false;
}
if (!this->ProcessGeneratorToolsetField(key, value)) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given toolset specification\n"
- " " << ts << "\n"
- "that contains invalid field '" << *fi << "'."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given toolset specification\n"
+ " ",
+ ts,
+ "\n"
+ "that contains invalid field '",
+ *fi, "'."));
return false;
}
}
@@ -370,7 +380,7 @@ bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
std::string const& key, std::string const& value)
{
- if (key == "cuda") {
+ if (key == "cuda"_s) {
/* test if cuda toolset is path to custom dir or cuda version */
auto pos = value.find_first_not_of("0123456789.");
if (pos != std::string::npos) {
@@ -395,16 +405,16 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
}
return true;
}
- if (key == "customFlagTableDir") {
+ if (key == "customFlagTableDir"_s) {
this->CustomFlagTableDir = value;
cmSystemTools::ConvertToUnixSlashes(this->CustomFlagTableDir);
return true;
}
- if (key == "version") {
+ if (key == "version"_s) {
this->GeneratorToolsetVersion = value;
return true;
}
- if (key == "VCTargetsPath") {
+ if (key == "VCTargetsPath"_s) {
this->CustomVCTargetsPath = value;
ConvertToWindowsSlashes(this->CustomVCTargetsPath);
return true;
@@ -414,34 +424,35 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
{
- if (this->SystemName == "Windows") {
+ if (this->SystemName == "Windows"_s) {
if (!this->InitializeWindows(mf)) {
return false;
}
- } else if (this->SystemName == "WindowsCE") {
+ } else if (this->SystemName == "WindowsCE"_s) {
this->SystemIsWindowsCE = true;
if (!this->InitializeWindowsCE(mf)) {
return false;
}
- } else if (this->SystemName == "WindowsPhone") {
+ } else if (this->SystemName == "WindowsPhone"_s) {
this->SystemIsWindowsPhone = true;
if (!this->InitializeWindowsPhone(mf)) {
return false;
}
- } else if (this->SystemName == "WindowsStore") {
+ } else if (this->SystemName == "WindowsStore"_s) {
this->SystemIsWindowsStore = true;
if (!this->InitializeWindowsStore(mf)) {
return false;
}
- } else if (this->SystemName == "Android") {
+ } else if (this->SystemName == "Android"_s) {
if (this->PlatformInGeneratorName) {
- std::ostringstream e;
- e << "CMAKE_SYSTEM_NAME is 'Android' but CMAKE_GENERATOR "
- << "specifies a platform too: '" << this->GetName() << "'";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("CMAKE_SYSTEM_NAME is 'Android' but CMAKE_GENERATOR ",
+ "specifies a platform too: '", this->GetName(), '\''));
return false;
}
- if (mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM") == "Tegra-Android") {
+ if (mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM") ==
+ "Tegra-Android"_s) {
if (!this->InitializeTegraAndroid(mf)) {
return false;
}
@@ -464,10 +475,10 @@ bool cmGlobalVisualStudio10Generator::InitializeWindows(cmMakefile*)
bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf)
{
if (this->PlatformInGeneratorName) {
- std::ostringstream e;
- e << "CMAKE_SYSTEM_NAME is 'WindowsCE' but CMAKE_GENERATOR "
- << "specifies a platform too: '" << this->GetName() << "'";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("CMAKE_SYSTEM_NAME is 'WindowsCE' but CMAKE_GENERATOR ",
+ "specifies a platform too: '", this->GetName(), '\''));
return false;
}
@@ -485,17 +496,17 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf)
bool cmGlobalVisualStudio10Generator::InitializeWindowsPhone(cmMakefile* mf)
{
- std::ostringstream e;
- e << this->GetName() << " does not support Windows Phone.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->GetName(), " does not support Windows Phone."));
return false;
}
bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf)
{
- std::ostringstream e;
- e << this->GetName() << " does not support Windows Store.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->GetName(), " does not support Windows Store."));
return false;
}
@@ -519,15 +530,15 @@ bool cmGlobalVisualStudio10Generator::InitializeTegraAndroid(cmMakefile* mf)
bool cmGlobalVisualStudio10Generator::InitializeAndroid(cmMakefile* mf)
{
- std::ostringstream e;
- e << this->GetName() << " does not support Android.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat(this->GetName(), " does not support Android."));
return false;
}
bool cmGlobalVisualStudio10Generator::InitializePlatform(cmMakefile* mf)
{
- if (this->SystemName == "Windows" || this->SystemName == "WindowsStore") {
+ if (this->SystemName == "Windows"_s ||
+ this->SystemName == "WindowsStore"_s) {
if (!this->InitializePlatformWindows(mf)) {
return false;
}
@@ -565,7 +576,7 @@ bool cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(
std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
{
- if (this->SystemVersion == "8.0") {
+ if (this->SystemVersion == "8.0"_s) {
return "CE800";
}
return "";
@@ -607,29 +618,30 @@ void cmGlobalVisualStudio10Generator::Generate()
}
if (this->LongestSource.Length > 0) {
cmLocalGenerator* lg = this->LongestSource.Target->GetLocalGenerator();
- std::ostringstream e;
- /* clang-format off */
- e <<
- "The binary and/or source directory paths may be too long to generate "
- "Visual Studio 10 files for this project. "
- "Consider choosing shorter directory names to build this project with "
- "Visual Studio 10. "
- "A more detailed explanation follows."
- "\n"
- "There is a bug in the VS 10 IDE that renders property dialog fields "
- "blank for files referenced by full path in the project file. "
- "However, CMake must reference at least one file by full path:\n"
- " " << this->LongestSource.SourceFile->GetFullPath() << "\n"
- "This is because some Visual Studio tools would append the relative "
- "path to the end of the referencing directory path, as in:\n"
- " " << lg->GetCurrentBinaryDirectory() << "/"
- << this->LongestSource.SourceRel << "\n"
- "and then incorrectly complain that the file does not exist because "
- "the path length is too long for some internal buffer or API. "
- "To avoid this problem CMake must use a full path for this file "
- "which then triggers the VS 10 property dialog bug.";
- /* clang-format on */
- lg->IssueMessage(MessageType::WARNING, e.str());
+ lg->IssueMessage(
+ MessageType::WARNING,
+ cmStrCat(
+ "The binary and/or source directory paths may be too long to generate "
+ "Visual Studio 10 files for this project. "
+ "Consider choosing shorter directory names to build this project with "
+ "Visual Studio 10. "
+ "A more detailed explanation follows."
+ "\n"
+ "There is a bug in the VS 10 IDE that renders property dialog fields "
+ "blank for files referenced by full path in the project file. "
+ "However, CMake must reference at least one file by full path:\n"
+ " ",
+ this->LongestSource.SourceFile->GetFullPath(),
+ "\n"
+ "This is because some Visual Studio tools would append the relative "
+ "path to the end of the referencing directory path, as in:\n"
+ " ",
+ lg->GetCurrentBinaryDirectory(), '/', this->LongestSource.SourceRel,
+ "\n"
+ "and then incorrectly complain that the file does not exist because "
+ "the path length is too long for some internal buffer or API. "
+ "To avoid this problem CMake must use a full path for this file "
+ "which then triggers the VS 10 property dialog bug."));
}
if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue(
"CMAKE_VS_NUGET_PACKAGE_RESTORE")) {
@@ -641,10 +653,10 @@ void cmGlobalVisualStudio10Generator::EnableLanguage(
std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
{
for (std::string const& it : lang) {
- if (it == "ASM_NASM") {
+ if (it == "ASM_NASM"_s) {
this->NasmEnabled = true;
}
- if (it == "CUDA") {
+ if (it == "CUDA"_s) {
this->CudaEnabled = true;
}
}
@@ -830,8 +842,8 @@ std::string cmGlobalVisualStudio10Generator::FindDevEnvCommand()
bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
{
// Skip this in special cases within our own test suite.
- if (this->GetPlatformName() == "Test Platform" ||
- this->GetPlatformToolsetString() == "Test Toolset") {
+ if (this->GetPlatformName() == "Test Platform"_s ||
+ this->GetPlatformToolsetString() == "Test Toolset"_s) {
return true;
}
@@ -843,11 +855,11 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
wd = cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
"/CMakeFiles");
}
- wd += "/";
+ wd += '/';
wd += cmVersion::GetCMakeVersion();
// We record the result persistently in a file.
- std::string const txt = wd + "/VCTargetsPath.txt";
+ std::string const txt = cmStrCat(wd, "/VCTargetsPath.txt");
// If we have a recorded result, use it.
{
@@ -861,8 +873,8 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
// Prepare the work directory.
if (!cmSystemTools::MakeDirectory(wd)) {
- std::string e = "Failed to make directory:\n " + wd;
- mf->IssueMessage(MessageType::FATAL_ERROR, e);
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Failed to make directory:\n ", wd));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
@@ -870,7 +882,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
// Generate a project file for MSBuild to tell us the VCTargetsPath value.
std::string const vcxproj = "VCTargetsPath.vcxproj";
{
- std::string const vcxprojAbs = wd + "/" + vcxproj;
+ std::string const vcxprojAbs = cmStrCat(wd, '/', vcxproj);
cmsys::ofstream fout(vcxprojAbs.c_str());
cmXMLWriter xw(fout);
@@ -889,7 +901,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
cmXMLElement eig(eprj, "ItemGroup");
eig.Attribute("Label", "ProjectConfigurations");
cmXMLElement epc(eig, "ProjectConfiguration");
- epc.Attribute("Include", "Debug|" + this->GetPlatformName());
+ epc.Attribute("Include", cmStrCat("Debug|", this->GetPlatformName()));
cmXMLElement(epc, "Configuration").Content("Debug");
cmXMLElement(epc, "Platform").Content(this->GetPlatformName());
}
@@ -899,19 +911,19 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
cmXMLElement(epg, "ProjectGuid")
.Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
cmXMLElement(epg, "Keyword")
- .Content(mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"
+ .Content(mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"_s
? "Android"
: "Win32Proj");
cmXMLElement(epg, "Platform").Content(this->GetPlatformName());
- if (this->GetSystemName() == "WindowsPhone") {
+ if (this->GetSystemName() == "WindowsPhone"_s) {
cmXMLElement(epg, "ApplicationType").Content("Windows Phone");
cmXMLElement(epg, "ApplicationTypeRevision")
.Content(this->GetApplicationTypeRevision());
- } else if (this->GetSystemName() == "WindowsStore") {
+ } else if (this->GetSystemName() == "WindowsStore"_s) {
cmXMLElement(epg, "ApplicationType").Content("Windows Store");
cmXMLElement(epg, "ApplicationTypeRevision")
.Content(this->GetApplicationTypeRevision());
- } else if (this->GetSystemName() == "Android") {
+ } else if (this->GetSystemName() == "Android"_s) {
cmXMLElement(epg, "ApplicationType").Content("Android");
cmXMLElement(epg, "ApplicationTypeRevision")
.Content(this->GetApplicationTypeRevision());
@@ -920,10 +932,10 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
cmXMLElement(epg, "WindowsTargetPlatformVersion")
.Content(this->WindowsTargetPlatformVersion);
}
- if (this->GetSystemName() != "Android") {
- if (this->GetPlatformName() == "ARM64") {
+ if (this->GetSystemName() != "Android"_s) {
+ if (this->GetPlatformName() == "ARM64"_s) {
cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
- } else if (this->GetPlatformName() == "ARM") {
+ } else if (this->GetPlatformName() == "ARM"_s) {
cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
}
}
@@ -970,10 +982,9 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
std::vector<std::string> cmd;
cmd.push_back(this->GetMSBuildCommand());
cmd.push_back(vcxproj);
- cmd.push_back("/p:Configuration=Debug");
- cmd.push_back(cmStrCat("/p:Platform=", this->GetPlatformName()));
- cmd.push_back(std::string("/p:VisualStudioVersion=") +
- this->GetIDEVersion());
+ cmd.emplace_back("/p:Configuration=Debug");
+ cmd.emplace_back(cmStrCat("/p:Platform=", this->GetPlatformName()));
+ cmd.emplace_back(cmStrCat("/p:VisualStudioVersion=", this->GetIDEVersion()));
std::string out;
int ret = 0;
cmsys::RegularExpression regex("\n *VCTargetsPath=([^%\r\n]+)[\r\n]");
@@ -1049,7 +1060,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
break;
}
std::string proj = project.GetRelativePath();
- if (proj.size() > 7 && proj.substr(proj.size() - 7) == ".vfproj") {
+ if (proj.size() > 7 && proj.substr(proj.size() - 7) == ".vfproj"_s) {
useDevEnv = true;
}
}
@@ -1080,7 +1091,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
makeCommand.Add(makeProgramSelected);
cm::optional<cmSlnProjectEntry> proj = cm::nullopt;
- if (tname == "clean") {
+ if (tname == "clean"_s) {
makeCommand.Add(cmStrCat(projectName, ".sln"));
makeCommand.Add("/t:Clean");
} else {
@@ -1104,7 +1115,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
requiresRestore = false;
} else if (cmValue cached =
this->CMakeInstance->GetState()->GetCacheEntryValue(
- tname + "_REQUIRES_VS_PACKAGE_RESTORE")) {
+ cmStrCat(tname, "_REQUIRES_VS_PACKAGE_RESTORE"))) {
requiresRestore = cached.IsOn();
} else {
// There are no package references defined.
@@ -1164,7 +1175,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
std::string extension =
cmSystemTools::GetFilenameLastExtension(proj->GetRelativePath());
extension = cmSystemTools::LowerCase(extension);
- if (extension == ".csproj") {
+ if (extension == ".csproj"_s) {
// Use correct platform name
platform =
slnData.GetConfigurationTarget(tname, plainConfig, platform);
@@ -1198,9 +1209,10 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile(
{
// The VS 10 generator needs to create the .rule files on disk.
// Hide them away under the CMakeFiles directory.
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
std::string ruleDir = cmStrCat(
this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/",
- cmSystemTools::ComputeStringMD5(cmSystemTools::GetFilenamePath(output)));
+ hasher.HashString(cmSystemTools::GetFilenamePath(output)));
std::string ruleFile =
cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule");
return ruleFile;
@@ -1230,7 +1242,6 @@ const char* cmGlobalVisualStudio10Generator::GetToolsVersion() const
{
switch (this->Version) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
return "4.0";
// in Visual Studio 2013 they detached the MSBuild tools version
@@ -1272,7 +1283,7 @@ std::string cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion()
std::string cmGlobalVisualStudio10Generator::GetApplicationTypeRevision() const
{
- if (this->GetSystemName() == "Android") {
+ if (this->GetSystemName() == "Android"_s) {
return this->GetAndroidApplicationTypeRevision();
}
@@ -1303,23 +1314,23 @@ static unsigned int cmLoadFlagTableSpecial(Json::Value entry,
if (specials.isArray()) {
for (auto const& special : specials) {
std::string s = special.asString();
- if (s == "UserValue") {
+ if (s == "UserValue"_s) {
value |= cmIDEFlagTable::UserValue;
- } else if (s == "UserIgnored") {
+ } else if (s == "UserIgnored"_s) {
value |= cmIDEFlagTable::UserIgnored;
- } else if (s == "UserRequired") {
+ } else if (s == "UserRequired"_s) {
value |= cmIDEFlagTable::UserRequired;
- } else if (s == "Continue") {
+ } else if (s == "Continue"_s) {
value |= cmIDEFlagTable::Continue;
- } else if (s == "SemicolonAppendable") {
+ } else if (s == "SemicolonAppendable"_s) {
value |= cmIDEFlagTable::SemicolonAppendable;
- } else if (s == "UserFollowing") {
+ } else if (s == "UserFollowing"_s) {
value |= cmIDEFlagTable::UserFollowing;
- } else if (s == "CaseInsensitive") {
+ } else if (s == "CaseInsensitive"_s) {
value |= cmIDEFlagTable::CaseInsensitive;
- } else if (s == "SpaceAppendable") {
+ } else if (s == "SpaceAppendable"_s) {
value |= cmIDEFlagTable::SpaceAppendable;
- } else if (s == "CommaAppendable") {
+ } else if (s == "CommaAppendable"_s) {
value |= cmIDEFlagTable::CommaAppendable;
}
}
@@ -1538,22 +1549,22 @@ std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const
std::string const& toolset = this->GetPlatformToolsetString();
std::string const useToolset = this->CanonicalToolsetName(toolset);
- if (toolset == "v142") {
+ if (toolset == "v142"_s) {
return "v142";
}
- if (toolset == "v141") {
+ if (toolset == "v141"_s) {
return "v141";
}
- if (useToolset == "v140") {
+ if (useToolset == "v140"_s) {
return "v140";
}
- if (useToolset == "v120") {
+ if (useToolset == "v120"_s) {
return "v12";
}
- if (useToolset == "v110") {
+ if (useToolset == "v110"_s) {
return "v11";
}
- if (useToolset == "v100") {
+ if (useToolset == "v100"_s) {
return "v10";
}
return "";
@@ -1564,22 +1575,22 @@ std::string cmGlobalVisualStudio10Generator::GetCSharpFlagTableName() const
std::string const& toolset = this->GetPlatformToolsetString();
std::string const useToolset = this->CanonicalToolsetName(toolset);
- if (useToolset == "v142") {
+ if (useToolset == "v142"_s) {
return "v142";
}
- if (useToolset == "v141") {
+ if (useToolset == "v141"_s) {
return "v141";
}
- if (useToolset == "v140") {
+ if (useToolset == "v140"_s) {
return "v140";
}
- if (useToolset == "v120") {
+ if (useToolset == "v120"_s) {
return "v12";
}
- if (useToolset == "v110") {
+ if (useToolset == "v110"_s) {
return "v11";
}
- if (useToolset == "v100") {
+ if (useToolset == "v100"_s) {
return "v10";
}
return "";
@@ -1590,17 +1601,17 @@ std::string cmGlobalVisualStudio10Generator::GetRcFlagTableName() const
std::string const& toolset = this->GetPlatformToolsetString();
std::string const useToolset = this->CanonicalToolsetName(toolset);
- if ((useToolset == "v140") || (useToolset == "v141") ||
- (useToolset == "v142")) {
+ if ((useToolset == "v140"_s) || (useToolset == "v141"_s) ||
+ (useToolset == "v142"_s)) {
return "v14";
}
- if (useToolset == "v120") {
+ if (useToolset == "v120"_s) {
return "v12";
}
- if (useToolset == "v110") {
+ if (useToolset == "v110"_s) {
return "v11";
}
- if (useToolset == "v100") {
+ if (useToolset == "v100"_s) {
return "v10";
}
return "";
@@ -1611,17 +1622,17 @@ std::string cmGlobalVisualStudio10Generator::GetLibFlagTableName() const
std::string const& toolset = this->GetPlatformToolsetString();
std::string const useToolset = this->CanonicalToolsetName(toolset);
- if ((useToolset == "v140") || (useToolset == "v141") ||
- (useToolset == "v142")) {
+ if ((useToolset == "v140"_s) || (useToolset == "v141"_s) ||
+ (useToolset == "v142"_s)) {
return "v14";
}
- if (useToolset == "v120") {
+ if (useToolset == "v120"_s) {
return "v12";
}
- if (useToolset == "v110") {
+ if (useToolset == "v110"_s) {
return "v11";
}
- if (useToolset == "v100") {
+ if (useToolset == "v100"_s) {
return "v10";
}
return "";
@@ -1632,22 +1643,22 @@ std::string cmGlobalVisualStudio10Generator::GetLinkFlagTableName() const
std::string const& toolset = this->GetPlatformToolsetString();
std::string const useToolset = this->CanonicalToolsetName(toolset);
- if (useToolset == "v142") {
+ if (useToolset == "v142"_s) {
return "v142";
}
- if (useToolset == "v141") {
+ if (useToolset == "v141"_s) {
return "v141";
}
- if (useToolset == "v140") {
+ if (useToolset == "v140"_s) {
return "v140";
}
- if (useToolset == "v120") {
+ if (useToolset == "v120"_s) {
return "v12";
}
- if (useToolset == "v110") {
+ if (useToolset == "v110"_s) {
return "v11";
}
- if (useToolset == "v100") {
+ if (useToolset == "v100"_s) {
return "v10";
}
return "";
@@ -1658,17 +1669,17 @@ std::string cmGlobalVisualStudio10Generator::GetMasmFlagTableName() const
std::string const& toolset = this->GetPlatformToolsetString();
std::string const useToolset = this->CanonicalToolsetName(toolset);
- if ((useToolset == "v140") || (useToolset == "v141") ||
- (useToolset == "v142")) {
+ if ((useToolset == "v140"_s) || (useToolset == "v141"_s) ||
+ (useToolset == "v142"_s)) {
return "v14";
}
- if (useToolset == "v120") {
+ if (useToolset == "v120"_s) {
return "v12";
}
- if (useToolset == "v110") {
+ if (useToolset == "v110"_s) {
return "v11";
}
- if (useToolset == "v100") {
+ if (useToolset == "v100"_s) {
return "v10";
}
return "";
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 3ad10eb..0ec5e8b 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -3,168 +3,30 @@
#include "cmGlobalVisualStudio11Generator.h"
#include <cstring>
-#include <sstream>
#include <utility>
#include <vector>
+#include <cmext/string_view>
+
#include "cmGlobalGenerator.h"
-#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-static const char vs11generatorName[] = "Visual Studio 11 2012";
-
-// Map generator name without year to name with year.
-static const char* cmVS11GenName(const std::string& name, std::string& genName)
-{
- if (strncmp(name.c_str(), vs11generatorName,
- sizeof(vs11generatorName) - 6) != 0) {
- return nullptr;
- }
- const char* p = name.c_str() + sizeof(vs11generatorName) - 6;
- if (cmHasLiteralPrefix(p, " 2012")) {
- p += 5;
- }
- genName = std::string(vs11generatorName) + p;
- return p;
-}
-
-class cmGlobalVisualStudio11Generator::Factory
- : public cmGlobalGeneratorFactory
-{
-public:
- std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
- const std::string& name, bool allowArch, cmake* cm) const override
- {
- std::string genName;
- const char* p = cmVS11GenName(name, genName);
- if (!p) {
- return std::unique_ptr<cmGlobalGenerator>();
- }
- if (!*p) {
- return std::unique_ptr<cmGlobalGenerator>(
- new cmGlobalVisualStudio11Generator(cm, genName, ""));
- }
- if (!allowArch || *p++ != ' ') {
- return std::unique_ptr<cmGlobalGenerator>();
- }
- if (strcmp(p, "Win64") == 0) {
- return std::unique_ptr<cmGlobalGenerator>(
- new cmGlobalVisualStudio11Generator(cm, genName, "x64"));
- }
- if (strcmp(p, "ARM") == 0) {
- return std::unique_ptr<cmGlobalGenerator>(
- new cmGlobalVisualStudio11Generator(cm, genName, "ARM"));
- }
-
- std::set<std::string> installedSDKs =
- cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
-
- if (installedSDKs.find(p) == installedSDKs.end()) {
- return std::unique_ptr<cmGlobalGenerator>();
- }
-
- auto ret = std::unique_ptr<cmGlobalVisualStudio11Generator>(
- new cmGlobalVisualStudio11Generator(cm, name, p));
- ret->WindowsCEVersion = "8.00";
- return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
- }
-
- cmDocumentationEntry GetDocumentation() const override
- {
- return { std::string(vs11generatorName) + " [arch]",
- "Deprecated. Generates Visual Studio 2012 project files. "
- "Optional [arch] can be \"Win64\" or \"ARM\"." };
- }
-
- std::vector<std::string> GetGeneratorNames() const override
- {
- std::vector<std::string> names;
- names.push_back(vs11generatorName);
- return names;
- }
-
- std::vector<std::string> GetGeneratorNamesWithPlatform() const override
- {
- std::vector<std::string> names;
- names.push_back(vs11generatorName + std::string(" ARM"));
- names.push_back(vs11generatorName + std::string(" Win64"));
-
- std::set<std::string> installedSDKs =
- cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
- for (std::string const& i : installedSDKs) {
- names.push_back(std::string(vs11generatorName) + " " + i);
- }
-
- return names;
- }
-
- bool SupportsToolset() const override { return true; }
- bool SupportsPlatform() const override { return true; }
-
- std::vector<std::string> GetKnownPlatforms() const override
- {
- std::vector<std::string> platforms;
- platforms.emplace_back("x64");
- platforms.emplace_back("Win32");
- platforms.emplace_back("ARM");
-
- std::set<std::string> installedSDKs =
- cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
- for (std::string const& i : installedSDKs) {
- platforms.emplace_back(i);
- }
-
- return platforms;
- }
-
- std::string GetDefaultPlatformName() const override { return "Win32"; }
-};
-
-std::unique_ptr<cmGlobalGeneratorFactory>
-cmGlobalVisualStudio11Generator::NewFactory()
-{
- return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
-}
-
cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
cmake* cm, const std::string& name,
std::string const& platformInGeneratorName)
: cmGlobalVisualStudio10Generator(cm, name, platformInGeneratorName)
{
- std::string vc11Express;
- this->ExpressEdition = cmSystemTools::ReadRegistryValue(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;"
- "ProductDir",
- vc11Express, cmSystemTools::KeyWOW64_32);
- this->DefaultPlatformToolset = "v110";
- this->DefaultCLFlagTableName = "v11";
- this->DefaultCSharpFlagTableName = "v11";
- this->DefaultLibFlagTableName = "v11";
- this->DefaultLinkFlagTableName = "v11";
- this->DefaultMasmFlagTableName = "v11";
- this->DefaultRCFlagTableName = "v11";
- this->Version = VSVersion::VS11;
-}
-
-bool cmGlobalVisualStudio11Generator::MatchesGeneratorName(
- const std::string& name) const
-{
- std::string genName;
- if (cmVS11GenName(name, genName)) {
- return genName == this->GetName();
- }
- return false;
}
void cmGlobalVisualStudio11Generator::EnableLanguage(
std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
{
for (std::string const& it : lang) {
- if (it == "ASM_MARMASM") {
+ if (it == "ASM_MARMASM"_s) {
this->MarmasmEnabled = true;
}
}
@@ -175,16 +37,18 @@ void cmGlobalVisualStudio11Generator::EnableLanguage(
bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
{
if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
- std::ostringstream e;
+ std::string e;
if (this->DefaultPlatformToolset.empty()) {
- e << this->GetName() << " supports Windows Phone '8.0', but not '"
- << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ e = cmStrCat(this->GetName(), " supports Windows Phone '8.0', but not '",
+ this->SystemVersion, "'. Check CMAKE_SYSTEM_VERSION.");
} else {
- e << "A Windows Phone component with CMake requires both the Windows "
- << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
- << "' SDK. Please make sure that you have both installed";
+ e = cmStrCat(
+ "A Windows Phone component with CMake requires both the Windows "
+ "Desktop SDK as well as the Windows Phone '",
+ this->SystemVersion,
+ "' SDK. Please make sure that you have both installed");
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
return true;
@@ -193,16 +57,18 @@ bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
{
if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
- std::ostringstream e;
+ std::string e;
if (this->DefaultPlatformToolset.empty()) {
- e << this->GetName() << " supports Windows Store '8.0', but not '"
- << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ e = cmStrCat(this->GetName(), " supports Windows Store '8.0', but not '",
+ this->SystemVersion, "'. Check CMAKE_SYSTEM_VERSION.");
} else {
- e << "A Windows Store component with CMake requires both the Windows "
- << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
- << "' SDK. Please make sure that you have both installed";
+ e = cmStrCat(
+ "A Windows Store component with CMake requires both the Windows "
+ "Desktop SDK as well as the Windows Store '",
+ this->SystemVersion,
+ "' SDK. Please make sure that you have both installed");
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
return true;
@@ -211,7 +77,7 @@ bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
bool cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
std::string& toolset) const
{
- if (this->SystemVersion == "8.0") {
+ if (this->SystemVersion == "8.0"_s) {
if (this->IsWindowsPhoneToolsetInstalled() &&
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v110_wp80";
@@ -226,7 +92,7 @@ bool cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
bool cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
std::string& toolset) const
{
- if (this->SystemVersion == "8.0") {
+ if (this->SystemVersion == "8.0"_s) {
if (this->IsWindowsStoreToolsetInstalled() &&
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v110";
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index fd25984..ad12c1f 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -13,7 +13,6 @@
#include "cmGlobalVisualStudio10Generator.h"
#include "cmTransformDepfile.h"
-class cmGlobalGeneratorFactory;
class cmMakefile;
class cmake;
@@ -21,10 +20,6 @@ class cmake;
class cmGlobalVisualStudio11Generator : public cmGlobalVisualStudio10Generator
{
public:
- static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
-
- bool MatchesGeneratorName(const std::string& name) const override;
-
void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
bool optional) override;
@@ -58,8 +53,4 @@ protected:
/** Return true if target system supports debugging deployment. */
bool TargetSystemSupportsDeployment() const override;
-
-private:
- class Factory;
- friend class Factory;
};
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index d417f9e..1f1a2c3 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -6,6 +6,8 @@
#include <sstream>
#include <vector>
+#include <cmext/string_view>
+
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -63,8 +65,8 @@ public:
cmDocumentationEntry GetDocumentation() const override
{
- return { std::string(vs12generatorName) + " [arch]",
- "Generates Visual Studio 2013 project files. "
+ return { cmStrCat(vs12generatorName, " [arch]"),
+ "Deprecated. Generates Visual Studio 2013 project files. "
"Optional [arch] can be \"Win64\" or \"ARM\"." };
}
@@ -78,8 +80,8 @@ public:
std::vector<std::string> GetGeneratorNamesWithPlatform() const override
{
std::vector<std::string> names;
- names.push_back(vs12generatorName + std::string(" ARM"));
- names.push_back(vs12generatorName + std::string(" Win64"));
+ names.emplace_back(cmStrCat(vs12generatorName, " ARM"));
+ names.emplace_back(cmStrCat(vs12generatorName, " Win64"));
return names;
}
@@ -137,8 +139,8 @@ bool cmGlobalVisualStudio12Generator::MatchesGeneratorName(
bool cmGlobalVisualStudio12Generator::ProcessGeneratorToolsetField(
std::string const& key, std::string const& value)
{
- if (key == "host" &&
- (value == "x64" || value == "x86" || value == "ARM64")) {
+ if (key == "host"_s &&
+ (value == "x64"_s || value == "x86"_s || value == "ARM64"_s)) {
this->GeneratorToolsetHostArchitecture = value;
return true;
}
@@ -149,18 +151,20 @@ bool cmGlobalVisualStudio12Generator::ProcessGeneratorToolsetField(
bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
{
if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
- std::ostringstream e;
+ std::string e;
if (this->DefaultPlatformToolset.empty()) {
- e << this->GetName()
- << " supports Windows Phone '8.0' and '8.1', but "
- "not '"
- << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ e = cmStrCat(this->GetName(),
+ " supports Windows Phone '8.0' and '8.1', but "
+ "not '",
+ this->SystemVersion, "'. Check CMAKE_SYSTEM_VERSION.");
} else {
- e << "A Windows Phone component with CMake requires both the Windows "
- << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
- << "' SDK. Please make sure that you have both installed";
+ e = cmStrCat(
+ "A Windows Phone component with CMake requires both the Windows "
+ "Desktop SDK as well as the Windows Phone '",
+ this->SystemVersion,
+ "' SDK. Please make sure that you have both installed");
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
return true;
@@ -169,18 +173,20 @@ bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf)
{
if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
- std::ostringstream e;
+ std::string e;
if (this->DefaultPlatformToolset.empty()) {
- e << this->GetName()
- << " supports Windows Store '8.0' and '8.1', but "
- "not '"
- << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ e = cmStrCat(this->GetName(),
+ " supports Windows Store '8.0' and '8.1', but "
+ "not '",
+ this->SystemVersion, "'. Check CMAKE_SYSTEM_VERSION.");
} else {
- e << "A Windows Store component with CMake requires both the Windows "
- << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
- << "' SDK. Please make sure that you have both installed";
+ e = cmStrCat(
+ "A Windows Store component with CMake requires both the Windows "
+ "Desktop SDK as well as the Windows Store '",
+ this->SystemVersion,
+ "' SDK. Please make sure that you have both installed");
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
return true;
@@ -189,7 +195,7 @@ bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf)
bool cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset(
std::string& toolset) const
{
- if (this->SystemVersion == "8.1") {
+ if (this->SystemVersion == "8.1"_s) {
if (this->IsWindowsPhoneToolsetInstalled() &&
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v120_wp81";
@@ -204,7 +210,7 @@ bool cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset(
bool cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(
std::string& toolset) const
{
- if (this->SystemVersion == "8.1") {
+ if (this->SystemVersion == "8.1"_s) {
if (this->IsWindowsStoreToolsetInstalled() &&
this->IsWindowsDesktopToolsetInstalled()) {
toolset = "v120";
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 01294dd..68b4d1a 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -67,7 +67,7 @@ public:
cmDocumentationEntry GetDocumentation() const override
{
- return { std::string(vs14generatorName) + " [arch]",
+ return { cmStrCat(vs14generatorName, " [arch]"),
"Generates Visual Studio 2015 project files. "
"Optional [arch] can be \"Win64\" or \"ARM\"." };
}
@@ -82,8 +82,8 @@ public:
std::vector<std::string> GetGeneratorNamesWithPlatform() const override
{
std::vector<std::string> names;
- names.push_back(vs14generatorName + std::string(" ARM"));
- names.push_back(vs14generatorName + std::string(" Win64"));
+ names.emplace_back(cmStrCat(vs14generatorName, " ARM"));
+ names.emplace_back(cmStrCat(vs14generatorName, " Win64"));
return names;
}
@@ -250,7 +250,7 @@ bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion(
"given platform specification containing a\n"
" version=" << *this->GeneratorPlatformVersion << "\n"
"field. The version field is not supported when targeting\n"
- " " << this->SystemName << " " << this->SystemVersion << "\n"
+ " " << this->SystemName << ' ' << this->SystemVersion << '\n'
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -259,19 +259,21 @@ bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion(
bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
{
- std::ostringstream e;
if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
+ std::string e;
if (this->DefaultPlatformToolset.empty()) {
- e << this->GetName()
- << " supports Windows Store '8.0', '8.1' and "
- "'10.0', but not '"
- << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ e = cmStrCat(this->GetName(),
+ " supports Windows Store '8.0', '8.1' and "
+ "'10.0', but not '",
+ this->SystemVersion, "'. Check CMAKE_SYSTEM_VERSION.");
} else {
- e << "A Windows Store component with CMake requires both the Windows "
- << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
- << "' SDK. Please make sure that you have both installed";
+ e = cmStrCat(
+ "A Windows Store component with CMake requires both the Windows "
+ "Desktop SDK as well as the Windows Store '",
+ this->SystemVersion,
+ "' SDK. Please make sure that you have both installed");
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
return true;
@@ -285,7 +287,7 @@ bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*)
bool cmGlobalVisualStudio14Generator::ProcessGeneratorPlatformField(
std::string const& key, std::string const& value)
{
- if (key == "version") {
+ if (key == "version"_s) {
this->GeneratorPlatformVersion = value;
return true;
}
@@ -308,7 +310,7 @@ bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf)
return false;
}
- if (this->SystemName == "WindowsStore") {
+ if (this->SystemName == "WindowsStore"_s) {
mf->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find an appropriate version of the Windows 10 SDK"
@@ -328,10 +330,11 @@ void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion(
if (!this->WindowsTargetPlatformVersion.empty() &&
!cmSystemTools::VersionCompareEqual(this->WindowsTargetPlatformVersion,
this->SystemVersion)) {
- std::ostringstream e;
- e << "Selecting Windows SDK version " << this->WindowsTargetPlatformVersion
- << " to target Windows " << this->SystemVersion << ".";
- mf->DisplayStatus(e.str(), -1);
+ mf->DisplayStatus(cmStrCat("Selecting Windows SDK version ",
+ this->WindowsTargetPlatformVersion,
+ " to target Windows ", this->SystemVersion,
+ '.'),
+ -1);
}
mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
this->WindowsTargetPlatformVersion);
@@ -416,7 +419,7 @@ struct NoWindowsH
{
bool operator()(std::string const& p)
{
- return !cmSystemTools::FileExists(p + "/um/windows.h", true);
+ return !cmSystemTools::FileExists(cmStrCat(p, "/um/windows.h"), true);
}
};
class WindowsSDKTooRecent
@@ -473,7 +476,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion(
std::vector<std::string> sdks;
// Grab the paths of the different SDKs that are installed
for (std::string const& i : win10Roots) {
- std::string path = i + "/Include/*";
+ std::string path = cmStrCat(i, "/Include/*");
cmSystemTools::GlobDirs(path, sdks);
}
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index bcb26cc..8375b72 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -86,7 +86,7 @@ void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations(
{
fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
for (std::string const& i : configs) {
- fout << "\t\t" << i << " = " << i << "\n";
+ fout << "\t\t" << i << " = " << i << '\n';
}
fout << "\tEndGlobalSection\n";
}
@@ -136,9 +136,9 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
<< uname << ".vcproj" << "\", \"{"
<< this->GetGUID(uname) << "}\"\n"
<< "\tProjectSection(ProjectDependencies) = postProject\n"
- << "\t\t{" << guid << "} = {" << guid << "}\n"
- << "\tEndProjectSection\n"
- << "EndProject\n";
+ "\t\t{" << guid << "} = {" << guid << "}\n"
+ "\tEndProjectSection\n"
+ "EndProject\n";
/* clang-format on */
}
}
@@ -209,19 +209,19 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
cmList mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
- if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(i))) {
+ if (cmValue m = target.GetProperty(
+ cmStrCat("MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(i)))) {
mapConfig.assign(*m);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
}
}
- fout << "\t\t{" << guid << "}." << i << ".ActiveCfg = " << dstConfig << "|"
+ fout << "\t\t{" << guid << "}." << i << ".ActiveCfg = " << dstConfig << '|'
<< platformName << std::endl;
auto ci = configsPartOfDefaultBuild.find(i);
if (!(ci == configsPartOfDefaultBuild.end())) {
- fout << "\t\t{" << guid << "}." << i << ".Build.0 = " << dstConfig << "|"
+ fout << "\t\t{" << guid << "}." << i << ".Build.0 = " << dstConfig << '|'
<< platformName << std::endl;
}
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index b254777..6953ec6 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -158,7 +158,7 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
std::string vskey;
// Search in standard location.
- vskey = this->GetRegistryBase() + ";InstallDir";
+ vskey = cmStrCat(this->GetRegistryBase(), ";InstallDir");
if (cmSystemTools::ReadRegistryValue(vskey, vscmd,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(vscmd);
@@ -189,25 +189,25 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
const std::string& location)
{
std::string extension = cmSystemTools::GetFilenameLastExtension(location);
- if (extension == ".vbproj") {
+ if (extension == ".vbproj"_s) {
return "F184B08F-C81C-45F6-A57F-5ABD9991F28F";
}
- if (extension == ".csproj") {
+ if (extension == ".csproj"_s) {
return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC";
}
- if (extension == ".fsproj") {
+ if (extension == ".fsproj"_s) {
return "F2A71F9B-5D33-465A-A702-920D77279786";
}
- if (extension == ".vdproj") {
+ if (extension == ".vdproj"_s) {
return "54435603-DBB4-11D2-8724-00A0C9A8B90C";
}
- if (extension == ".dbproj") {
+ if (extension == ".dbproj"_s) {
return "C8D11400-126E-41CD-887F-60BD40844F9E";
}
- if (extension == ".wixproj") {
+ if (extension == ".wixproj"_s) {
return "930C7802-8A8C-48F9-8165-68863BCCD9DD";
}
- if (extension == ".pyproj") {
+ if (extension == ".pyproj"_s) {
return "888888A0-9F3D-457C-B088-3A5042F75D52";
}
return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
@@ -252,14 +252,14 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
continue;
}
bool clean = false;
- if (realTarget == "clean") {
+ if (realTarget == "clean"_s) {
clean = true;
realTarget = "ALL_BUILD";
}
GeneratedMakeCommand makeCommand;
makeCommand.RequiresOutputForward = requiresOutputForward;
makeCommand.Add(makeProgramSelected);
- makeCommand.Add(projectName + ".sln");
+ makeCommand.Add(cmStrCat(projectName, ".sln"));
makeCommand.Add((clean ? "/clean" : "/build"));
makeCommand.Add((config.empty() ? "Debug" : config));
makeCommand.Add("/project");
@@ -330,23 +330,23 @@ void cmGlobalVisualStudio7Generator::Generate()
}
}
- if (this->Version == VSVersion::VS11 &&
+ if (this->Version == VSVersion::VS12 &&
!this->CMakeInstance->GetIsInTryCompile()) {
- std::string cmakeWarnVS11;
+ std::string cmakeWarnVS12;
if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue(
- "CMAKE_WARN_VS11")) {
- this->CMakeInstance->MarkCliAsUsed("CMAKE_WARN_VS11");
- cmakeWarnVS11 = *cached;
+ "CMAKE_WARN_VS12")) {
+ this->CMakeInstance->MarkCliAsUsed("CMAKE_WARN_VS12");
+ cmakeWarnVS12 = *cached;
} else {
- cmSystemTools::GetEnv("CMAKE_WARN_VS11", cmakeWarnVS11);
+ cmSystemTools::GetEnv("CMAKE_WARN_VS12", cmakeWarnVS12);
}
- if (cmakeWarnVS11.empty() || !cmIsOff(cmakeWarnVS11)) {
+ if (cmakeWarnVS12.empty() || !cmIsOff(cmakeWarnVS12)) {
this->CMakeInstance->IssueMessage(
MessageType::WARNING,
- "The \"Visual Studio 11 2012\" generator is deprecated "
+ "The \"Visual Studio 12 2013\" generator is deprecated "
"and will be removed in a future version of CMake."
"\n"
- "Add CMAKE_WARN_VS11=OFF to the cache to disable this warning.");
+ "Add CMAKE_WARN_VS12=OFF to the cache to disable this warning.");
}
}
}
@@ -438,8 +438,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
if (target->HaveCxx20ModuleSources() && !this->SupportsCxxModuleDyndep()) {
root->GetMakefile()->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("The \"", target->GetName(),
- "\" target contains C++ module sources which are not "
+ cmStrCat("The target named \"", target->GetName(),
+ "\" contains C++ sources that export modules which is not "
"supported by the generator"));
}
@@ -459,7 +459,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
dir = root->MaybeRelativeToCurBinDir(dir);
- if (dir == ".") {
+ if (dir == "."_s) {
dir.clear(); // msbuild cannot handle ".\" prefix
}
this->WriteProject(fout, *vcprojName, dir, target);
@@ -483,12 +483,12 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
}
if (cumulativePath.empty()) {
- cumulativePath = "CMAKE_FOLDER_GUID_" + iter;
+ cumulativePath = cmStrCat("CMAKE_FOLDER_GUID_", iter);
} else {
- VisualStudioFolders[cumulativePath].insert(cumulativePath + "/" +
- iter);
+ VisualStudioFolders[cumulativePath].insert(
+ cmStrCat(cumulativePath, '/', iter));
- cumulativePath = cumulativePath + "/" + iter;
+ cumulativePath = cmStrCat(cumulativePath, '/', iter);
}
}
@@ -552,7 +552,8 @@ std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath(
void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
std::ostream& fout, cmLocalGenerator* root)
{
- std::string const guid = this->GetGUID(root->GetProjectName() + ".sln");
+ std::string const guid =
+ this->GetGUID(cmStrCat(root->GetProjectName(), ".sln"));
bool extensibilityGlobalsOverridden = false;
bool extensibilityAddInsOverridden = false;
const std::vector<std::string> propKeys =
@@ -572,14 +573,15 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
}
if (!name.empty()) {
bool addGuid = false;
- if (name == "ExtensibilityGlobals" && sectionType == "postSolution") {
+ if (name == "ExtensibilityGlobals"_s &&
+ sectionType == "postSolution"_s) {
addGuid = true;
extensibilityGlobalsOverridden = true;
- } else if (name == "ExtensibilityAddIns" &&
- sectionType == "postSolution") {
+ } else if (name == "ExtensibilityAddIns"_s &&
+ sectionType == "postSolution"_s) {
extensibilityAddInsOverridden = true;
}
- fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
+ fout << "\tGlobalSection(" << name << ") = " << sectionType << '\n';
cmValue p = root->GetMakefile()->GetProperty(it);
cmList keyValuePairs{ *p };
for (std::string const& itPair : keyValuePairs) {
@@ -589,8 +591,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
cmTrimWhitespace(itPair.substr(0, posEqual));
const std::string value =
cmTrimWhitespace(itPair.substr(posEqual + 1));
- fout << "\t\t" << key << " = " << value << "\n";
- if (key == "SolutionGuid") {
+ fout << "\t\t" << key << " = " << value << '\n';
+ if (key == "SolutionGuid"_s) {
addGuid = false;
}
}
@@ -679,7 +681,7 @@ std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(
std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
{
- std::string const& guidStoreName = name + "_GUID_CMAKE";
+ std::string const& guidStoreName = cmStrCat(name, "_GUID_CMAKE");
if (cmValue storedGUID =
this->CMakeInstance->GetCacheDefinition(guidStoreName)) {
return *storedGUID;
@@ -704,9 +706,7 @@ void cmGlobalVisualStudio7Generator::AppendDirectoryForConfig(
const std::string& suffix, std::string& dir)
{
if (!config.empty()) {
- dir += prefix;
- dir += config;
- dir += suffix;
+ dir += cmStrCat(prefix, config, suffix);
}
}
@@ -727,7 +727,7 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
// check if target <t> is part of default build
if (target->GetName() == t) {
const std::string propertyName =
- "CMAKE_VS_INCLUDE_" + t + "_TO_DEFAULT_BUILD";
+ cmStrCat("CMAKE_VS_INCLUDE_", t, "_TO_DEFAULT_BUILD");
// inspect CMAKE_VS_INCLUDE_<t>_TO_DEFAULT_BUILD properties
for (std::string const& i : configs) {
cmValue propertyValue =
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 3125eb5..0d357ad 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -288,7 +288,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
for (const auto& gi : generators) {
stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(),
"/CMakeFiles/generate.stamp");
- fout << stampFile << "\n";
+ fout << stampFile << '\n';
stamps.push_back(stampFile);
}
}
@@ -325,7 +325,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
std::string const sln =
- lg.GetBinaryDirectory() + "/" + lg.GetProjectName() + ".sln";
+ cmStrCat(lg.GetBinaryDirectory(), '/', lg.GetProjectName(), ".sln");
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list",
stampList, "--vs-solution-file", sln });
@@ -348,7 +348,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
lg.AddCustomCommandToOutput(std::move(cc), true)) {
gt->AddSource(file->ResolveFullPath());
} else {
- cmSystemTools::Error("Error adding rule for " + stamps[0]);
+ cmSystemTools::Error(cmStrCat("Error adding rule for ", stamps[0]));
}
}
@@ -376,8 +376,8 @@ void cmGlobalVisualStudio8Generator::WriteSolutionConfigurations(
{
fout << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n";
for (std::string const& i : configs) {
- fout << "\t\t" << i << "|" << this->GetPlatformName() << " = " << i << "|"
- << this->GetPlatformName() << "\n";
+ fout << "\t\t" << i << '|' << this->GetPlatformName() << " = " << i << '|'
+ << this->GetPlatformName() << '\n';
}
fout << "\tEndGlobalSection\n";
}
@@ -393,33 +393,33 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
cmList mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
- if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(i))) {
+ if (cmValue m = target.GetProperty(
+ cmStrCat("MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(i)))) {
mapConfig.assign(*m);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
}
}
- fout << "\t\t{" << guid << "}." << i << "|" << this->GetPlatformName()
- << ".ActiveCfg = " << dstConfig << "|"
+ fout << "\t\t{" << guid << "}." << i << '|' << this->GetPlatformName()
+ << ".ActiveCfg = " << dstConfig << '|'
<< (!platformMapping.empty() ? platformMapping
: this->GetPlatformName())
- << "\n";
+ << '\n';
auto ci = configsPartOfDefaultBuild.find(i);
if (!(ci == configsPartOfDefaultBuild.end())) {
- fout << "\t\t{" << guid << "}." << i << "|" << this->GetPlatformName()
- << ".Build.0 = " << dstConfig << "|"
+ fout << "\t\t{" << guid << "}." << i << '|' << this->GetPlatformName()
+ << ".Build.0 = " << dstConfig << '|'
<< (!platformMapping.empty() ? platformMapping
: this->GetPlatformName())
- << "\n";
+ << '\n';
}
if (this->NeedsDeploy(target, dstConfig)) {
- fout << "\t\t{" << guid << "}." << i << "|" << this->GetPlatformName()
- << ".Deploy.0 = " << dstConfig << "|"
+ fout << "\t\t{" << guid << "}." << i << '|' << this->GetPlatformName()
+ << ".Deploy.0 = " << dstConfig << '|'
<< (!platformMapping.empty() ? platformMapping
: this->GetPlatformName())
- << "\n";
+ << '\n';
}
}
}
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index e396405..de2153d 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -9,6 +9,7 @@
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVisualStudioWCEPlatformParser.h"
@@ -63,7 +64,7 @@ public:
cmDocumentationEntry GetDocumentation() const override
{
- return { std::string(vs9generatorName) + " [arch]",
+ return { cmStrCat(vs9generatorName, " [arch]"),
"Deprecated. Generates Visual Studio 2008 project files. "
"Optional [arch] can be \"Win64\" or \"IA64\"." };
}
@@ -71,21 +72,21 @@ public:
std::vector<std::string> GetGeneratorNames() const override
{
std::vector<std::string> names;
- names.push_back(vs9generatorName);
+ names.emplace_back(vs9generatorName);
return names;
}
std::vector<std::string> GetGeneratorNamesWithPlatform() const override
{
std::vector<std::string> names;
- names.push_back(vs9generatorName + std::string(" Win64"));
- names.push_back(vs9generatorName + std::string(" IA64"));
+ names.emplace_back(cmStrCat(vs9generatorName, " Win64"));
+ names.emplace_back(cmStrCat(vs9generatorName, " IA64"));
cmVisualStudioWCEPlatformParser parser;
parser.ParseVersion("9.0");
const std::vector<std::string>& availablePlatforms =
parser.GetAvailablePlatforms();
for (std::string const& i : availablePlatforms) {
- names.push_back("Visual Studio 9 2008 " + i);
+ names.emplace_back(cmStrCat("Visual Studio 9 2008 ", i));
}
return names;
}
@@ -144,7 +145,7 @@ std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory()
cmSystemTools::ConvertToUnixSlashes(base);
// 9.0 macros folder:
- path = base + "/VSMacros80";
+ path = cmStrCat(base, "/VSMacros80");
// *NOT* a typo; right now in Visual Studio 2008 beta the macros
// folder is VSMacros80... They may change it to 90 before final
// release of 2008 or they may not... we'll have to keep our eyes
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 6b024db..5305fec 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -12,6 +12,7 @@
#include <cm/iterator>
#include <cm/memory>
+#include <cmext/string_view>
#include <windows.h>
@@ -78,9 +79,9 @@ bool cmGlobalVisualStudioGenerator::SetGeneratorPlatform(std::string const& p,
if (!this->InitializePlatform(mf)) {
return false;
}
- if (this->GetPlatformName() == "x64") {
+ if (this->GetPlatformName() == "x64"_s) {
mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
- } else if (this->GetPlatformName() == "Itanium") {
+ } else if (this->GetPlatformName() == "Itanium"_s) {
mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
}
mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName());
@@ -105,8 +106,6 @@ const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const
switch (this->Version) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return "9.0";
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
- return "11.0";
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "12.0";
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
@@ -132,14 +131,6 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n";
fout << "# Visual Studio 2008\n";
break;
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
- fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
- if (this->ExpressEdition) {
- fout << "# Visual Studio Express 2012 for Windows Desktop\n";
- } else {
- fout << "# Visual Studio 2012\n";
- }
- break;
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
@@ -194,8 +185,8 @@ std::string cmGlobalVisualStudioGenerator::GetRegistryBase()
std::string cmGlobalVisualStudioGenerator::GetRegistryBase(const char* version)
{
- std::string key = R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\)";
- return key + version;
+ return cmStrCat(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\)",
+ version);
}
void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
@@ -252,12 +243,12 @@ void cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory(
std::string tgtDir = gt->LocalGenerator->GetTargetDirectory(gt);
if (!tgtDir.empty()) {
dir += tgtDir;
- dir += "/";
+ dir += '/';
}
const char* cd = this->GetCMakeCFGIntDir();
if (cd && *cd) {
dir += cd;
- dir += "/";
+ dir += '/';
}
gt->ObjectDirectory = dir;
}
@@ -284,7 +275,7 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
std::string src = cmStrCat(cmSystemTools::GetCMakeRoot(),
"/Templates/" CMAKE_VSMACROS_FILENAME);
- std::string dst = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
+ std::string dst = cmStrCat(dir, "/CMakeMacros/" CMAKE_VSMACROS_FILENAME);
// Copy the macros file to the user directory only if the
// destination does not exist or the source location is newer.
@@ -295,8 +286,8 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
if (!cmSystemTools::FileTimeCompare(src, dst, &res) || res > 0) {
if (!cmSystemTools::CopyFileAlways(src, dst)) {
std::ostringstream oss;
- oss << "Could not copy from: " << src << std::endl;
- oss << " to: " << dst << std::endl;
+ oss << "Could not copy from: " << src << std::endl
+ << " to: " << dst << std::endl;
cmSystemTools::Message(oss.str(), "Warning");
}
}
@@ -319,7 +310,8 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
// - there were .sln/.vcproj files changed during generation
//
if (!dir.empty()) {
- std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
+ std::string macrosFile =
+ cmStrCat(dir, "/CMakeMacros/" CMAKE_VSMACROS_FILENAME);
std::string nextSubkeyName;
if (cmSystemTools::FileExists(macrosFile) &&
IsVisualStudioMacrosFileRegistered(
@@ -528,9 +520,9 @@ std::string cmGlobalVisualStudioGenerator::GetStartupProjectName(
}
root->GetMakefile()->IssueMessage(
MessageType::AUTHOR_WARNING,
- "Directory property VS_STARTUP_PROJECT specifies target "
- "'" +
- startup + "' that does not exist. Ignoring.");
+ cmStrCat("Directory property VS_STARTUP_PROJECT specifies target "
+ "'",
+ startup, "' that does not exist. Ignoring."));
}
// default, if not specified
@@ -556,7 +548,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
LONG result = ERROR_SUCCESS;
DWORD index = 0;
- keyname = regKeyBase + "\\OtherProjects7";
+ keyname = cmStrCat(regKeyBase, "\\OtherProjects7");
hkey = nullptr;
result =
RegOpenKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(keyname).c_str(),
@@ -648,7 +640,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
// as the name of the next subkey.
nextAvailableSubKeyName = std::to_string(index);
- keyname = regKeyBase + "\\RecordingProject7";
+ keyname = cmStrCat(regKeyBase, "\\RecordingProject7");
hkey = nullptr;
result =
RegOpenKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(keyname).c_str(),
@@ -694,7 +686,7 @@ void WriteVSMacrosFileRegistryEntry(const std::string& nextAvailableSubKeyName,
const std::string& macrosFile,
const std::string& regKeyBase)
{
- std::string keyname = regKeyBase + "\\OtherProjects7";
+ std::string keyname = cmStrCat(regKeyBase, "\\OtherProjects7");
HKEY hkey = nullptr;
LONG result =
RegOpenKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(keyname).c_str(),
@@ -829,7 +821,7 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
// Intel Fortran .vfproj files do support the resource compiler.
languages.erase("RC");
- return languages.size() == 1 && *languages.begin() == "Fortran";
+ return languages.size() == 1 && *languages.begin() == "Fortran"_s;
}
bool cmGlobalVisualStudioGenerator::IsInSolution(
@@ -915,10 +907,10 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmSystemTools::ReplaceString(obj_dir_expanded, this->GetCMakeCFGIntDir(),
configName.c_str());
cmSystemTools::MakeDirectory(obj_dir_expanded);
- std::string const objs_file = obj_dir_expanded + "/objects.txt";
+ std::string const objs_file = cmStrCat(obj_dir_expanded, "/objects.txt");
cmGeneratedFileStream fout(objs_file.c_str());
if (!fout) {
- cmSystemTools::Error("could not open " + objs_file);
+ cmSystemTools::Error(cmStrCat("could not open ", objs_file));
return;
}
@@ -929,7 +921,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
// It must exist because we populated the mapping just above.
const auto& v = mapping[it];
assert(!v.empty());
- std::string objFile = obj_dir + v;
+ std::string objFile = cmStrCat(obj_dir, v);
objs.push_back(objFile);
}
std::vector<cmSourceFile const*> externalObjectSources;
@@ -985,7 +977,7 @@ bool cmGlobalVisualStudioGenerator::Open(const std::string& bindir,
const std::string& projectName,
bool dryRun)
{
- std::string sln = bindir + "/" + projectName + ".sln";
+ std::string sln = cmStrCat(bindir, '/', projectName, ".sln");
if (dryRun) {
return cmSystemTools::FileExists(sln, true);
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 52db98d..76713fa 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -10,7 +10,7 @@
#include <string>
#include <vector>
-#include "cm_codecvt.hxx"
+#include "cm_codecvt_Encoding.hxx"
#include "cmGlobalGenerator.h"
#include "cmTargetDepend.h"
@@ -35,7 +35,6 @@ public:
enum class VSVersion : uint16_t
{
VS9 = 90,
- VS11 = 110,
VS12 = 120,
/* VS13 = 130 was skipped */
VS14 = 140,
@@ -120,9 +119,9 @@ public:
/** Get encoding used by generator for generated source files
*/
- codecvt::Encoding GetMakefileEncoding() const override
+ codecvt_Encoding GetMakefileEncoding() const override
{
- return codecvt::ANSI;
+ return codecvt_Encoding::ANSI;
}
class TargetSet : public std::set<cmGeneratorTarget const*>
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 14c7d0f..d816d7b 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -127,8 +127,6 @@ static unsigned int VSVersionToMajor(
switch (v) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return 9;
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
- return 11;
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return 12;
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
@@ -149,8 +147,6 @@ static const char* VSVersionToToolset(
switch (v) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return "v90";
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
- return "v110";
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "v120";
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
@@ -171,8 +167,6 @@ static std::string VSVersionToMajorString(
switch (v) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return "9";
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
- return "11";
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "12";
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
@@ -192,7 +186,6 @@ static const char* VSVersionToAndroidToolset(
{
switch (v) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "";
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
@@ -218,7 +211,7 @@ static const char* cmVS15GenName(const std::string& name, std::string& genName)
if (cmHasLiteralPrefix(p, " 2017")) {
p += 5;
}
- genName = std::string(vs15generatorName) + p;
+ genName = cmStrCat(vs15generatorName, p);
return p;
}
@@ -257,7 +250,7 @@ public:
cmDocumentationEntry GetDocumentation() const override
{
- return { std::string(vs15generatorName) + " [arch]",
+ return { cmStrCat(vs15generatorName, " [arch]"),
"Generates Visual Studio 2017 project files. "
"Optional [arch] can be \"Win64\" or \"ARM\"." };
}
@@ -272,8 +265,8 @@ public:
std::vector<std::string> GetGeneratorNamesWithPlatform() const override
{
std::vector<std::string> names;
- names.push_back(vs15generatorName + std::string(" ARM"));
- names.push_back(vs15generatorName + std::string(" Win64"));
+ names.emplace_back(cmStrCat(vs15generatorName, " ARM"));
+ names.emplace_back(cmStrCat(vs15generatorName, " Win64"));
return names;
}
@@ -313,7 +306,7 @@ static const char* cmVS16GenName(const std::string& name, std::string& genName)
if (cmHasLiteralPrefix(p, " 2019")) {
p += 5;
}
- genName = std::string(vs16generatorName) + p;
+ genName = cmStrCat(vs16generatorName, p);
return p;
}
@@ -327,7 +320,7 @@ static const char* cmVS17GenName(const std::string& name, std::string& genName)
if (cmHasLiteralPrefix(p, " 2022")) {
p += 5;
}
- genName = std::string(vs17generatorName) + p;
+ genName = cmStrCat(vs17generatorName, p);
return p;
}
@@ -493,7 +486,6 @@ bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName(
std::string genName;
switch (this->Version) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
break;
@@ -532,20 +524,21 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
if (!this->GeneratorInstanceVersion.empty()) {
std::string const majorStr = VSVersionToMajorString(this->Version);
cmsys::RegularExpression versionRegex(
- cmStrCat("^", majorStr, R"(\.[0-9]+\.[0-9]+\.[0-9]+$)"));
+ cmStrCat('^', majorStr, R"(\.[0-9]+\.[0-9]+\.[0-9]+$)"));
if (!versionRegex.find(this->GeneratorInstanceVersion)) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given instance specification\n"
- " " << i << "\n"
- "but the version field is not 4 integer components"
- " starting in " << majorStr << "."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given instance specification\n"
+ " ",
+ i,
+ "\n"
+ "but the version field is not 4 integer components"
+ " starting in ",
+ majorStr, '.'));
return false;
}
}
@@ -574,14 +567,13 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
return false;
}
} else if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "could not find any instance of Visual Studio.\n";
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "could not find any instance of Visual Studio.\n"));
return false;
}
@@ -627,47 +619,47 @@ bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
for (; fi != fields.end(); ++fi) {
std::string::size_type pos = fi->find('=');
if (pos == fi->npos) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given instance specification\n"
- " " << is << "\n"
- "that contains a field after the first ',' with no '='."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given instance specification\n"
+ " ",
+ is,
+ "\n"
+ "that contains a field after the first ',' with no '='."));
return false;
}
std::string const key = fi->substr(0, pos);
std::string const value = fi->substr(pos + 1);
if (!handled.insert(key).second) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given instance specification\n"
- " " << is << "\n"
- "that contains duplicate field key '" << key << "'."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given instance specification\n"
+ " ",
+ is,
+ "\n"
+ "that contains duplicate field key '",
+ key, "'."));
return false;
}
if (!this->ProcessGeneratorInstanceField(key, value)) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "given instance specification\n"
- " " << is << "\n"
- "that contains invalid field '" << *fi << "'."
- ;
- /* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Generator\n"
+ " ",
+ this->GetName(),
+ "\n"
+ "given instance specification\n"
+ " ",
+ is,
+ "\n"
+ "that contains invalid field '",
+ *fi, "'."));
return false;
}
}
@@ -685,7 +677,7 @@ void cmGlobalVisualStudioVersionedGenerator::SetVSVersionVar(cmMakefile* mf)
bool cmGlobalVisualStudioVersionedGenerator::ProcessGeneratorInstanceField(
std::string const& key, std::string const& value)
{
- if (key == "version") {
+ if (key == "version"_s) {
this->GeneratorInstanceVersion = value;
return true;
}
@@ -761,7 +753,6 @@ cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
{
switch (this->Version) {
case cmGlobalVisualStudioGenerator::VSVersion::VS9:
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "";
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
@@ -877,13 +868,13 @@ cmGlobalVisualStudioVersionedGenerator::FindAuxToolset(
// Accept known SxS props file names using four version components
// in VS versions later than the current.
- if (version == "14.28.16.9" && vcToolsetVersion == "14.28.29910") {
+ if (version == "14.28.16.9"_s && vcToolsetVersion == "14.28.29910"_s) {
return AuxToolset::Default;
}
- if (version == "14.29.16.10" && vcToolsetVersion == "14.29.30037") {
+ if (version == "14.29.16.10"_s && vcToolsetVersion == "14.29.30037"_s) {
return AuxToolset::Default;
}
- if (version == "14.29.16.11" && vcToolsetVersion == "14.29.30133") {
+ if (version == "14.29.16.11"_s && vcToolsetVersion == "14.29.30133"_s) {
return AuxToolset::Default;
}
@@ -945,8 +936,8 @@ bool cmGlobalVisualStudioVersionedGenerator::IsWin81SDKInstalled() const
"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\"
"Windows Kits\\Installed Roots;KitsRoot81",
win81Root, cmSystemTools::KeyWOW64_32)) {
- return cmSystemTools::FileExists(win81Root + "/include/um/windows.h",
- true);
+ return cmSystemTools::FileExists(
+ cmStrCat(win81Root, "/include/um/windows.h"), true);
}
return false;
}
@@ -979,29 +970,29 @@ std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand()
if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
if (VSIsArm64Host()) {
if (VSHasDotNETFrameworkArm64()) {
- msbuild = vs + "/MSBuild/Current/Bin/arm64/MSBuild.exe";
+ msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/arm64/MSBuild.exe");
if (cmSystemTools::FileExists(msbuild)) {
return msbuild;
}
}
if (VSIsWindows11OrGreater()) {
- msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe";
+ msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/amd64/MSBuild.exe");
if (cmSystemTools::FileExists(msbuild)) {
return msbuild;
}
}
} else {
- msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe";
+ msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/amd64/MSBuild.exe");
if (cmSystemTools::FileExists(msbuild)) {
return msbuild;
}
}
}
- msbuild = vs + "/MSBuild/Current/Bin/MSBuild.exe";
+ msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/MSBuild.exe");
if (cmSystemTools::FileExists(msbuild)) {
return msbuild;
}
- msbuild = vs + "/MSBuild/15.0/Bin/MSBuild.exe";
+ msbuild = cmStrCat(vs, "/MSBuild/15.0/Bin/MSBuild.exe");
if (cmSystemTools::FileExists(msbuild)) {
return msbuild;
}
@@ -1018,7 +1009,7 @@ std::string cmGlobalVisualStudioVersionedGenerator::FindDevEnvCommand()
// Ask Visual Studio Installer tool.
std::string vs;
if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
- devenv = vs + "/Common7/IDE/devenv.com";
+ devenv = cmStrCat(vs, "/Common7/IDE/devenv.com");
if (cmSystemTools::FileExists(devenv)) {
return devenv;
}
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index ed44e6b..ca7a1b9 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -4,6 +4,9 @@
#include <ostream>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -46,7 +49,7 @@ void cmGlobalWatcomWMakeGenerator::EnableLanguage(
bool cmGlobalWatcomWMakeGenerator::SetSystemName(std::string const& s,
cmMakefile* mf)
{
- if (mf->GetSafeDefinition("CMAKE_SYSTEM_PROCESSOR") == "I86") {
+ if (mf->GetSafeDefinition("CMAKE_SYSTEM_PROCESSOR") == "I86"_s) {
mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl");
}
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index 5579120..8b24679 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -53,6 +53,8 @@ public:
bool AllowNotParallel() const override { return false; }
bool AllowDeleteOnError() const override { return false; }
+ bool IsGNUMakeJobServerAware() const override { return false; }
+
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index fd58f75..90b8839 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -53,6 +53,7 @@
#include "cmXCodeObject.h"
#include "cmXCodeScheme.h"
#include "cmXMLWriter.h"
+#include "cmXcFramework.h"
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP) && defined(__APPLE__)
@@ -81,10 +82,10 @@ public:
}
void EndElement(const std::string& name) override
{
- if (name == "key") {
+ if (name == "key"_s) {
this->Key = this->Data;
- } else if (name == "string") {
- if (this->Key == "CFBundleShortVersionString") {
+ } else if (name == "string"_s) {
+ if (this->Key == "CFBundleShortVersionString"_s) {
this->Version = this->Data;
}
}
@@ -104,15 +105,13 @@ public:
class cmGlobalXCodeGenerator::BuildObjectListOrString
{
cmGlobalXCodeGenerator* Generator;
- cmXCodeObject* Group;
- bool Empty;
+ cmXCodeObject* Group = nullptr;
+ bool Empty = true;
std::string String;
public:
BuildObjectListOrString(cmGlobalXCodeGenerator* gen, bool buildObjectList)
: Generator(gen)
- , Group(nullptr)
- , Empty(true)
{
if (buildObjectList) {
this->Group = this->Generator->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -227,7 +226,8 @@ cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(const std::string& name,
if (commandResult) {
std::string::size_type pos = out.find(".app/");
if (pos != std::string::npos) {
- versionFile = out.substr(0, pos + 5) + "Contents/version.plist";
+ versionFile =
+ cmStrCat(out.substr(0, pos + 5), "Contents/version.plist");
}
}
}
@@ -249,7 +249,7 @@ cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(const std::string& name,
if (version_number < 50) {
cm->IssueMessage(MessageType::FATAL_ERROR,
- "Xcode " + version_string + " not supported.");
+ cmStrCat("Xcode ", version_string, " not supported."));
return std::unique_ptr<cmGlobalGenerator>();
}
@@ -389,7 +389,7 @@ bool cmGlobalXCodeGenerator::ParseGeneratorToolset(std::string const& ts,
bool cmGlobalXCodeGenerator::ProcessGeneratorToolsetField(
std::string const& key, std::string const& value, cmMakefile* mf)
{
- if (key == "buildsystem") {
+ if (key == "buildsystem"_s) {
if (value == "1"_s) {
this->XcodeBuildSystem = BuildSystem::One;
} else if (value == "12"_s) {
@@ -407,8 +407,10 @@ bool cmGlobalXCodeGenerator::ProcessGeneratorToolsetField(
mf->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
- if (this->XcodeBuildSystem == BuildSystem::Twelve &&
- this->XcodeVersion < 120) {
+ if ((this->XcodeBuildSystem == BuildSystem::Twelve &&
+ this->XcodeVersion < 120) ||
+ (this->XcodeBuildSystem == BuildSystem::One &&
+ this->XcodeVersion >= 140)) {
/* clang-format off */
std::string const& e = cmStrCat(
"Generator\n"
@@ -451,7 +453,7 @@ bool cmGlobalXCodeGenerator::Open(const std::string& bindir,
bool ret = false;
#ifdef HAVE_APPLICATION_SERVICES
- std::string url = bindir + "/" + projectName + ".xcodeproj";
+ std::string url = cmStrCat(bindir, '/', projectName, ".xcodeproj");
if (dryRun) {
return cmSystemTools::FileExists(url, false);
@@ -702,7 +704,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
cmLocalGenerator* root, std::vector<cmLocalGenerator*> const& gens)
{
std::vector<std::string> lfiles;
- for (auto gen : gens) {
+ for (auto* gen : gens) {
cm::append(lfiles, gen->GetMakefile()->GetListFiles());
}
@@ -721,29 +723,30 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
cmGeneratedFileStream makefileStream(this->CurrentReRunCMakeMakefile);
makefileStream.SetCopyIfDifferent(true);
- makefileStream << "# Generated by CMake, DO NOT EDIT\n\n";
+ makefileStream << "# Generated by CMake, DO NOT EDIT\n\n"
- makefileStream << "TARGETS:= \n";
- makefileStream << "empty:= \n";
- makefileStream << "space:= $(empty) $(empty)\n";
- makefileStream << "spaceplus:= $(empty)\\ $(empty)\n\n";
+ "TARGETS:= \n"
+ "empty:= \n"
+ "space:= $(empty) $(empty)\n"
+ "spaceplus:= $(empty)\\ $(empty)\n\n";
for (const auto& lfile : lfiles) {
makefileStream << "TARGETS += $(subst $(space),$(spaceplus),$(wildcard "
<< this->ConvertToRelativeForMake(lfile) << "))\n";
}
- makefileStream << "\n";
+ makefileStream << '\n';
std::string checkCache =
cmStrCat(root->GetBinaryDirectory(), "/CMakeFiles/cmake.check_cache");
if (cm->DoWriteGlobVerifyTarget()) {
- makefileStream << ".NOTPARALLEL:\n\n";
- makefileStream << ".PHONY: all VERIFY_GLOBS\n\n";
- makefileStream << "all: VERIFY_GLOBS "
- << this->ConvertToRelativeForMake(checkCache) << "\n\n";
- makefileStream << "VERIFY_GLOBS:\n";
- makefileStream << "\t"
+ makefileStream << ".NOTPARALLEL:\n\n"
+ ".PHONY: all VERIFY_GLOBS\n\n"
+ "all: VERIFY_GLOBS "
+ << this->ConvertToRelativeForMake(checkCache)
+ << "\n\n"
+ "VERIFY_GLOBS:\n"
+ "\t"
<< this->ConvertToRelativeForMake(
cmSystemTools::GetCMakeCommand())
<< " -P "
@@ -754,11 +757,11 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
makefileStream << this->ConvertToRelativeForMake(checkCache)
<< ": $(TARGETS)\n";
makefileStream
- << "\t" << this->ConvertToRelativeForMake(cmSystemTools::GetCMakeCommand())
+ << '\t' << this->ConvertToRelativeForMake(cmSystemTools::GetCMakeCommand())
<< " -S" << this->ConvertToRelativeForMake(root->GetSourceDirectory())
<< " -B" << this->ConvertToRelativeForMake(root->GetBinaryDirectory())
<< (cm->GetIgnoreWarningAsError() ? " --compile-no-warning-as-error" : "")
- << "\n";
+ << '\n';
}
static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l,
@@ -813,7 +816,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(
{
auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT,
this->GetObjectId(ptype, key));
- auto ptr = obj.get();
+ auto* ptr = obj.get();
this->addObject(std::move(obj));
return ptr;
}
@@ -823,7 +826,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
auto obj = cm::make_unique<cmXCodeObject>(
cmXCodeObject::None, type,
"Temporary cmake object, should not be referred to in Xcode file");
- auto ptr = obj.get();
+ auto* ptr = obj.get();
this->addObject(std::move(obj));
return ptr;
}
@@ -853,10 +856,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateFlatClone(cmXCodeObject* orig)
static std::string GetGroupMapKeyFromPath(cmGeneratorTarget* target,
const std::string& fullpath)
{
- std::string key(target->GetName());
- key += "-";
- key += fullpath;
- return key;
+ return cmStrCat(target->GetName(), '-', fullpath);
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeBuildFileFromPath(
@@ -920,7 +920,7 @@ public:
"Xcode does not support per-config per-source " << property << ":\n"
" " << expression << "\n"
"specified for source:\n"
- " " << this->SourceFile->ResolveFullPath() << "\n";
+ " " << this->SourceFile->ResolveFullPath() << '\n';
/* clang-format on */
this->LocalGenerator->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
@@ -944,10 +944,10 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
std::string const& srcfmt = sf->GetSafeProperty("Fortran_FORMAT");
switch (cmOutputConverter::GetFortranFormat(srcfmt)) {
case cmOutputConverter::FortranFormatFixed:
- flags = "-fixed " + flags;
+ flags = cmStrCat("-fixed ", flags);
break;
case cmOutputConverter::FortranFormatFree:
- flags = "-free " + flags;
+ flags = cmStrCat("-free ", flags);
break;
default:
break;
@@ -1061,25 +1061,30 @@ bool IsLinkPhaseLibraryExtension(const std::string& fileExt)
{
// Empty file extension is a special case for paths to framework's
// internal binary which could be MyFw.framework/Versions/*/MyFw
- return (fileExt == ".framework" || fileExt == ".a" || fileExt == ".o" ||
- fileExt == ".dylib" || fileExt == ".tbd" || fileExt.empty());
+ return (fileExt == ".framework"_s || fileExt == ".xcframework"_s ||
+ fileExt == ".a"_s || fileExt == ".o"_s || fileExt == ".dylib"_s ||
+ fileExt == ".tbd"_s || fileExt.empty());
}
bool IsLibraryType(const std::string& fileType)
{
- return (fileType == "wrapper.framework" || fileType == "archive.ar" ||
- fileType == "compiled.mach-o.objfile" ||
- fileType == "compiled.mach-o.dylib" ||
- fileType == "compiled.mach-o.executable" ||
- fileType == "sourcecode.text-based-dylib-definition");
+ return (fileType == "wrapper.framework"_s ||
+ fileType == "wrapper.xcframework"_s || fileType == "archive.ar"_s ||
+ fileType == "compiled.mach-o.objfile"_s ||
+ fileType == "compiled.mach-o.dylib"_s ||
+ fileType == "compiled.mach-o.executable"_s ||
+ fileType == "sourcecode.text-based-dylib-definition"_s);
}
std::string GetDirectoryValueFromFileExtension(const std::string& dirExt)
{
std::string ext = cmSystemTools::LowerCase(dirExt);
- if (ext == "framework") {
+ if (ext == "framework"_s) {
return "wrapper.framework";
}
- if (ext == "xcassets") {
+ if (ext == "xcframework"_s) {
+ return "wrapper.xcframework";
+ }
+ if (ext == "xcassets"_s) {
return "folder.assetcatalog";
}
return "folder";
@@ -1092,66 +1097,68 @@ std::string GetSourcecodeValueFromFileExtension(
std::string ext = cmSystemTools::LowerCase(_ext);
std::string sourcecode = "sourcecode";
- if (ext == "o") {
+ if (ext == "o"_s) {
keepLastKnownFileType = true;
sourcecode = "compiled.mach-o.objfile";
- } else if (ext == "xctest") {
+ } else if (ext == "xctest"_s) {
sourcecode = "wrapper.cfbundle";
- } else if (ext == "xib") {
+ } else if (ext == "xib"_s) {
keepLastKnownFileType = true;
sourcecode = "file.xib";
- } else if (ext == "storyboard") {
+ } else if (ext == "storyboard"_s) {
keepLastKnownFileType = true;
sourcecode = "file.storyboard";
- } else if (ext == "mm" && !cm::contains(enabled_langs, "OBJCXX")) {
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ } else if (ext == "mm"_s && !cm::contains(enabled_langs, "OBJCXX")) {
sourcecode += ".cpp.objcpp";
- } else if (ext == "m" && !cm::contains(enabled_langs, "OBJC")) {
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ } else if (ext == "m"_s && !cm::contains(enabled_langs, "OBJC")) {
sourcecode += ".c.objc";
- } else if (ext == "swift") {
+ } else if (ext == "swift"_s) {
sourcecode += ".swift";
- } else if (ext == "plist") {
+ } else if (ext == "plist"_s) {
sourcecode += ".text.plist";
- } else if (ext == "h") {
+ } else if (ext == "h"_s) {
sourcecode += ".c.h";
- } else if (ext == "hxx" || ext == "hpp" || ext == "txx" || ext == "pch" ||
- ext == "hh" || ext == "inl") {
+ } else if (ext == "hxx"_s || ext == "hpp"_s || ext == "txx"_s ||
+ ext == "pch"_s || ext == "hh"_s || ext == "inl"_s) {
sourcecode += ".cpp.h";
- } else if (ext == "png" || ext == "gif" || ext == "jpg") {
+ } else if (ext == "png"_s || ext == "gif"_s || ext == "jpg"_s) {
keepLastKnownFileType = true;
sourcecode = "image";
- } else if (ext == "txt") {
+ } else if (ext == "txt"_s) {
sourcecode += ".text";
- } else if (lang == "CXX") {
+ } else if (lang == "CXX"_s) {
sourcecode += ".cpp.cpp";
- } else if (lang == "C") {
+ } else if (lang == "C"_s) {
sourcecode += ".c.c";
- } else if (lang == "OBJCXX") {
+ } else if (lang == "OBJCXX"_s) {
sourcecode += ".cpp.objcpp";
- } else if (lang == "OBJC") {
+ } else if (lang == "OBJC"_s) {
sourcecode += ".c.objc";
- } else if (lang == "Fortran") {
+ } else if (lang == "Fortran"_s) {
sourcecode += ".fortran.f90";
- } else if (lang == "ASM") {
+ } else if (lang == "ASM"_s) {
sourcecode += ".asm";
- } else if (ext == "metal") {
+ } else if (ext == "metal"_s) {
sourcecode += ".metal";
- } else if (ext == "mig") {
+ } else if (ext == "mig"_s) {
sourcecode += ".mig";
- } else if (ext == "tbd") {
+ } else if (ext == "tbd"_s) {
sourcecode += ".text-based-dylib-definition";
- } else if (ext == "a") {
+ } else if (ext == "a"_s) {
keepLastKnownFileType = true;
sourcecode = "archive.ar";
- } else if (ext == "dylib") {
+ } else if (ext == "dylib"_s) {
keepLastKnownFileType = true;
sourcecode = "compiled.mach-o.dylib";
- } else if (ext == "framework") {
+ } else if (ext == "framework"_s) {
keepLastKnownFileType = true;
sourcecode = "wrapper.framework";
- } else if (ext == "xcassets") {
+ } else if (ext == "xcassets"_s) {
keepLastKnownFileType = true;
sourcecode = "folder.assetcatalog";
- } else if (ext == "xcconfig") {
+ } else if (ext == "xcconfig"_s) {
keepLastKnownFileType = true;
sourcecode = "text.xcconfig";
}
@@ -1173,11 +1180,11 @@ std::string GetTargetObjectDirArch(T const& target,
cmList archs{ target.GetSafeProperty("OSX_ARCHITECTURES") };
if (archs.size() > 1) {
return "$(CURRENT_ARCH)";
- } else if (archs.size() == 1) {
+ }
+ if (archs.size() == 1) {
return archs.front();
- } else {
- return defaultVal;
}
+ return defaultVal;
}
} // anonymous
@@ -1267,12 +1274,18 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
cmXCodeObject* group = this->GroupMap[key];
- if (!group && IsLibraryType(fileType)) {
- group = this->FrameworkGroup;
- this->GroupMap[key] = group;
+ if (!group) {
+ if (IsLibraryType(fileType)) {
+ group = this->FrameworkGroup;
+ } else if (fileType == "folder") {
+ group = this->ResourcesGroup;
+ }
+ if (group)
+ this->GroupMap[key] = group;
}
+
if (!group) {
- cmSystemTools::Error("Could not find a PBX group for " + key);
+ cmSystemTools::Error(cmStrCat("Could not find a PBX group for ", key));
return nullptr;
}
cmXCodeObject* children = group->GetAttribute("children");
@@ -1293,8 +1306,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReference(
bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
{
- if (tname == "ALL_BUILD" || tname == "install" || tname == "package" ||
- tname == "RUN_TESTS" || tname == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ if (tname == "ALL_BUILD"_s || tname == "install"_s || tname == "package"_s ||
+ tname == "RUN_TESTS"_s || tname == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
if (this->TargetDoneSet.find(tname) != this->TargetDoneSet.end()) {
return true;
}
@@ -1328,10 +1341,10 @@ struct cmCompareTargets
{
std::string const& a = l->GetTarget()->GetName();
std::string const& b = r->GetTarget()->GetName();
- if (a == "ALL_BUILD") {
+ if (a == "ALL_BUILD"_s) {
return true;
}
- if (b == "ALL_BUILD") {
+ if (b == "ALL_BUILD"_s) {
return false;
}
return a < b;
@@ -1344,7 +1357,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
this->SetCurrentLocalGenerator(gen);
std::vector<cmGeneratorTarget*> gts =
this->GetLocalGeneratorTargetsInOrder(gen);
- for (auto gtgt : gts) {
+ for (auto* gtgt : gts) {
if (!this->CreateXCodeTarget(gtgt, targets)) {
return false;
}
@@ -1374,14 +1387,14 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
if (gtgt->HaveCxx20ModuleSources()) {
gtgt->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("The \"", gtgt->GetName(),
- "\" target contains C++ module sources which are not "
+ cmStrCat("The target named \"", gtgt->GetName(),
+ "\" contains C++ sources that export modules which is not "
"supported by the generator"));
}
auto& gtgt_visited = this->CommandsVisited[gtgt];
- auto& deps = this->GetTargetDirectDepends(gtgt);
- for (auto& d : deps) {
+ auto const& deps = this->GetTargetDirectDepends(gtgt);
+ for (auto const& d : deps) {
// Take the union of visited source files of custom commands so far.
// ComputeTargetOrder ensures our dependencies already visited their
// custom commands and updated CommandsVisited.
@@ -1426,7 +1439,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
std::vector<cmXCodeObject*> headerFiles;
std::vector<cmXCodeObject*> resourceFiles;
std::vector<cmXCodeObject*> sourceFiles;
- for (auto sourceFile : commonSourceFiles) {
+ for (auto* sourceFile : commonSourceFiles) {
cmXCodeObject* xsf = this->CreateXCodeSourceFile(
this->CurrentLocalGenerator, sourceFile, gtgt);
cmXCodeObject* fr = xsf->GetAttribute("fileRef");
@@ -1439,7 +1452,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
cmGeneratorTarget::SourceFileFlags tsFlags =
gtgt->GetTargetSourceFileFlags(sourceFile);
- if (filetype && filetype->GetString() == "compiled.mach-o.objfile") {
+ if (filetype && filetype->GetString() == "compiled.mach-o.objfile"_s) {
if (sourceFile->GetObjectLibrary().empty()) {
externalObjFiles.push_back(xsf);
}
@@ -1529,7 +1542,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
using mapOfVectorOfSourceFiles =
std::map<std::string, std::vector<cmSourceFile*>>;
mapOfVectorOfSourceFiles bundleFiles;
- for (auto sourceFile : commonSourceFiles) {
+ for (auto* sourceFile : commonSourceFiles) {
cmGeneratorTarget::SourceFileFlags tsFlags =
gtgt->GetTargetSourceFileFlags(sourceFile);
if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) {
@@ -1548,7 +1561,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
if (gtgt->IsFrameworkOnApple()) {
// dstPath in frameworks is relative to Versions/<version>
ostr << keySources.first;
- } else if (keySources.first != "MacOS") {
+ } else if (keySources.first != "MacOS"_s) {
if (gtgt->Target->GetMakefile()->PlatformIsAppleEmbedded()) {
ostr << keySources.first;
} else {
@@ -1562,7 +1575,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
this->CreateString("0"));
buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
copyFilesBuildPhase->AddAttribute("files", buildFiles);
- for (auto sourceFile : keySources.second) {
+ for (auto* sourceFile : keySources.second) {
cmXCodeObject* xsf = this->CreateXCodeSourceFile(
this->CurrentLocalGenerator, sourceFile, gtgt);
buildFiles->AddObject(xsf);
@@ -1577,7 +1590,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
using mapOfVectorOfSourceFiles =
std::map<std::string, std::vector<cmSourceFile*>>;
mapOfVectorOfSourceFiles bundleFiles;
- for (auto sourceFile : commonSourceFiles) {
+ for (auto* sourceFile : commonSourceFiles) {
cmGeneratorTarget::SourceFileFlags tsFlags =
gtgt->GetTargetSourceFileFlags(sourceFile);
if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
@@ -1598,7 +1611,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
this->CreateString("0"));
buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
copyFilesBuildPhase->AddAttribute("files", buildFiles);
- for (auto sourceFile : keySources.second) {
+ for (auto* sourceFile : keySources.second) {
cmXCodeObject* xsf = this->CreateXCodeSourceFile(
this->CurrentLocalGenerator, sourceFile, gtgt);
buildFiles->AddObject(xsf);
@@ -1674,8 +1687,9 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
if (const char* productType = GetTargetProductType(gtgt)) {
if (strcmp(productType,
"com.apple.product-type.app-extension.messages-sticker-pack") ==
- 0)
+ 0) {
return;
+ }
}
// Add an empty source file to the target that compiles with the
@@ -1687,7 +1701,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
gtgt->GetName(), "-CMakeForceLinker.", cmSystemTools::LowerCase(llang));
{
cmGeneratedFileStream fout(fname);
- fout << "\n";
+ fout << '\n';
}
if (cmSourceFile* sf = mf->GetOrCreateSource(fname)) {
sf->SetProperty("LANGUAGE", llang);
@@ -1797,7 +1811,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
// add all the sources
std::vector<cmCustomCommand> commands;
auto& visited = this->CommandsVisited[gtgt];
- for (auto sourceFile : classes) {
+ for (auto* sourceFile : classes) {
if (sourceFile->GetCustomCommand() &&
visited.insert(sourceFile).second) {
commands.push_back(*sourceFile->GetCustomCommand());
@@ -1836,7 +1850,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
if (resourceBuildPhase) {
buildPhases->AddObject(resourceBuildPhase);
}
- for (auto obj : contentBuildPhases) {
+ for (auto* obj : contentBuildPhases) {
buildPhases->AddObject(obj);
}
if (sourceBuildPhase) {
@@ -1865,7 +1879,7 @@ void cmGlobalXCodeGenerator::CreateRunScriptBuildPhases(
return;
}
auto& visited = this->CommandsVisited[gt];
- for (auto sf : sources) {
+ for (auto* sf : sources) {
this->CreateRunScriptBuildPhases(buildPhases, sf, gt, visited);
}
}
@@ -1900,7 +1914,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
auto depfilesDirectory = cmStrCat(
gt->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/CMakeFiles/d/");
- auto depfilesPrefix = cmStrCat(depfilesDirectory, buildPhase->GetId(), ".");
+ auto depfilesPrefix = cmStrCat(depfilesDirectory, buildPhase->GetId(), '.');
std::string shellScript = "set -e\n";
for (std::string const& configName : this->CurrentConfigurationTypes) {
@@ -2070,7 +2084,7 @@ std::string cmGlobalXCodeGenerator::ConstructScript(
}
wd = lg->ConvertToOutputFormat(wd, cmOutputConverter::SHELL);
ReplaceScriptVars(wd);
- script = cmStrCat(script, " cd ", wd, "\n");
+ script = cmStrCat(script, " cd ", wd, '\n');
for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) {
std::string cmd = ccg.GetCommand(c);
if (cmd.empty()) {
@@ -2195,10 +2209,10 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase(
std::string cdir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
cdir = this->ConvertToRelativeForMake(cdir);
- std::string makecmd =
- cmStrCat("make -C ", cdir, " -f ",
- this->ConvertToRelativeForMake((makefile + "$CONFIGURATION")),
- " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all");
+ std::string makecmd = cmStrCat(
+ "make -C ", cdir, " -f ",
+ this->ConvertToRelativeForMake(cmStrCat(makefile, "$CONFIGURATION")),
+ " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all");
buildphase->AddAttribute("shellScript", this->CreateString(makecmd));
buildphase->AddAttribute("showEnvVarsInLog", this->CreateString("0"));
}
@@ -2213,12 +2227,13 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
return;
}
makefileStream.SetCopyIfDifferent(true);
- makefileStream << "# Generated by CMake, DO NOT EDIT\n";
- makefileStream << "# Custom rules for " << target->GetName() << "\n";
+ makefileStream << "# Generated by CMake, DO NOT EDIT\n"
+ "# Custom rules for "
+ << target->GetName() << '\n';
// disable the implicit rules
makefileStream << ".SUFFIXES: "
- << "\n";
+ "\n";
// have all depend on all outputs
makefileStream << "all: ";
@@ -2236,7 +2251,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
} else {
std::ostringstream str;
str << "_buildpart_" << count++;
- tname[&ccg.GetCC()] = target->GetName() + str.str();
+ tname[&ccg.GetCC()] = cmStrCat(target->GetName(), str.str());
makefileStream << "\\\n\t" << tname[&ccg.GetCC()];
}
}
@@ -2255,7 +2270,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
return cmStrCat(
depfilesDirectory,
this->GetObjectId(cmXCodeObject::PBXShellScriptBuildPhase, file),
- ".", config, ".d");
+ '.', config, ".d");
});
auto depfile = ccg.GetInternalDepfile();
@@ -2279,7 +2294,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
}
if (ccg.GetNumberOfCommands() > 0) {
- makefileStream << "\n";
+ makefileStream << '\n';
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
// There is at least one output, start the rule for it
@@ -2296,14 +2311,14 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
for (auto const& dep : realDepends) {
makefileStream << "\\\n" << this->ConvertToRelativeForMake(dep);
}
- makefileStream << "\n";
+ makefileStream << '\n';
if (cm::optional<std::string> comment = ccg.GetComment()) {
std::string echo_cmd =
cmStrCat("echo ",
(this->CurrentLocalGenerator->EscapeForShell(
*comment, ccg.GetCC().GetEscapeAllowMakeVars())));
- makefileStream << "\t" << echo_cmd << "\n";
+ makefileStream << '\t' << echo_cmd << '\n';
}
// Add each command line to the set of commands.
@@ -2321,7 +2336,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
}
cmd += cmd2;
ccg.AppendArguments(c, cmd);
- makefileStream << "\t" << cmd << "\n";
+ makefileStream << '\t' << cmd << '\n';
}
// Symbolic inputs are not expected to exist, so add dummy rules.
@@ -2400,8 +2415,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string llang = gtgt->GetLinkerLanguage(configName);
if (binary && llang.empty()) {
cmSystemTools::Error(
- "CMake can not determine linker language for target: " +
- gtgt->GetName());
+ cmStrCat("CMake can not determine linker language for target: ",
+ gtgt->GetName()));
return;
}
@@ -2465,7 +2480,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::set<std::string> defines(targetSwiftDefines.begin(),
targetSwiftDefines.end());
this->CurrentLocalGenerator->JoinDefines(defines, defineString, "Swift");
- cflags["Swift"] += " " + defineString;
+ cflags["Swift"] += cmStrCat(' ', defineString);
} else {
BuildObjectListOrString swiftDefs(this, true);
this->AppendDefines(swiftDefs, targetSwiftDefines);
@@ -2552,9 +2567,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string realName = components.base;
std::string soName = components.base;
if (version && soversion) {
- realName += ".";
+ realName += '.';
realName += *version;
- soName += ".";
+ soName += '.';
soName += *soversion;
}
@@ -2639,7 +2654,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string createFlags = this->LookupFlags(
"CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", "-bundle");
if (!createFlags.empty()) {
- extraLinkOptions += " ";
+ extraLinkOptions += ' ';
extraLinkOptions += createFlags;
}
cmValue ext = gtgt->GetProperty("BUNDLE_EXTENSION");
@@ -2665,7 +2680,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string createFlags =
this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
if (!createFlags.empty()) {
- extraLinkOptions += " ";
+ extraLinkOptions += ' ';
extraLinkOptions += createFlags;
}
}
@@ -2695,7 +2710,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string createFlags = this->LookupFlags(
"CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS", "-dynamiclib");
if (!createFlags.empty()) {
- extraLinkOptions += " ";
+ extraLinkOptions += ' ';
extraLinkOptions += createFlags;
}
}
@@ -2715,7 +2730,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string createFlags =
this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
if (!createFlags.empty()) {
- extraLinkOptions += " ";
+ extraLinkOptions += ' ';
extraLinkOptions += createFlags;
}
@@ -2824,7 +2839,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
includes, gtgt, language, configName);
if (!includeFlags.empty()) {
- cflags[language] += " " + includeFlags;
+ cflags[language] += cmStrCat(' ', includeFlags);
}
}
}
@@ -2848,8 +2863,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
gflag = this->ExtractFlag("-g", flags);
// put back gdwarf-2 if used since there is no way
// to represent it in the gui, but we still want debug yes
- if (gflag == "-gdwarf-2") {
- flags += " ";
+ if (gflag == "-gdwarf-2"_s) {
+ flags += ' ';
flags += gflag;
}
if (last_gflag && *last_gflag != gflag) {
@@ -2863,17 +2878,17 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// We can't set the Xcode flag differently depending on the language,
// so put them back in this case.
for (auto const& language : languages) {
- cflags[language] += " ";
+ cflags[language] += ' ';
cflags[language] += gflags[language];
}
debugStr = "NO";
- } else if (last_gflag && (last_gflag->empty() || *last_gflag == "-g0")) {
+ } else if (last_gflag && (last_gflag->empty() || *last_gflag == "-g0"_s)) {
debugStr = "NO";
}
// extract C++ stdlib
for (auto const& language : languages) {
- if (language != "CXX" && language != "OBJCXX") {
+ if (language != "CXX"_s && language != "OBJCXX"_s) {
continue;
}
std::string& flags = cflags[language];
@@ -2882,7 +2897,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->ExtractFlagRegex("(^| )(-stdlib=[^ ]+)( |$)", 2, flags);
if (stdlib.size() > 8) {
const auto cxxLibrary = stdlib.substr(8);
- if (language == "CXX" ||
+ if (language == "CXX"_s ||
!buildSettings->GetAttribute("CLANG_CXX_LIBRARY")) {
buildSettings->AddAttribute("CLANG_CXX_LIBRARY",
this->CreateString(cxxLibrary));
@@ -2902,21 +2917,21 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CreateString("NO"));
for (auto const& language : languages) {
- std::string flags = cflags[language] + " " + defFlags;
- if (language == "CXX" || language == "OBJCXX") {
- if (language == "CXX" ||
+ std::string flags = cmStrCat(cflags[language], ' ', defFlags);
+ if (language == "CXX"_s || language == "OBJCXX"_s) {
+ if (language == "CXX"_s ||
!buildSettings->GetAttribute("OTHER_CPLUSPLUSFLAGS")) {
buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
this->CreateString(flags));
}
- } else if (language == "Fortran") {
+ } else if (language == "Fortran"_s) {
buildSettings->AddAttribute("IFORT_OTHER_FLAGS",
this->CreateString(flags));
- } else if (language == "C" || language == "OBJC") {
- if (language == "C" || !buildSettings->GetAttribute("OTHER_CFLAGS")) {
+ } else if (language == "C"_s || language == "OBJC"_s) {
+ if (language == "C"_s || !buildSettings->GetAttribute("OTHER_CFLAGS")) {
buildSettings->AddAttribute("OTHER_CFLAGS", this->CreateString(flags));
}
- } else if (language == "Swift") {
+ } else if (language == "Swift"_s) {
buildSettings->AddAttribute("OTHER_SWIFT_FLAGS",
this->CreateString(flags));
}
@@ -2955,7 +2970,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Convert to a path for the native build tool.
cmSystemTools::ConvertToUnixSlashes(install_name_dir);
install_name += install_name_dir;
- install_name += "/";
+ install_name += '/';
}
install_name += gtgt->GetSOName(configName);
@@ -2983,7 +2998,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
if (unique_dirs.find(runpath) == unique_dirs.end()) {
unique_dirs.insert(runpath);
if (!search_paths.empty()) {
- search_paths += " ";
+ search_paths += ' ';
}
search_paths += this->XCodeEscapePath(runpath);
}
@@ -3018,7 +3033,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Xcode always wants at least 1.0.0 or nothing
if (!(major == 0 && minor == 0 && patch == 0)) {
- v << major << "." << minor << "." << patch;
+ v << major << '.' << minor << '.' << patch;
}
buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
this->CreateString(v.str()));
@@ -3030,7 +3045,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Xcode always wants at least 1.0.0 or nothing
if (!(major == 0 && minor == 0 && patch == 0)) {
- vso << major << "." << minor << "." << patch;
+ vso << major << '.' << minor << '.' << patch;
}
buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
this->CreateString(vso.str()));
@@ -3111,7 +3126,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
// Add CMakeLists.txt file for user convenience.
this->AddXCodeProjBuildRule(gtgt, sources);
- for (auto sourceFile : sources) {
+ for (auto* sourceFile : sources) {
if (!sourceFile->GetIsGenerated()) {
this->CreateXCodeFileReference(sourceFile, gtgt);
}
@@ -3172,11 +3187,11 @@ void cmGlobalXCodeGenerator::CreateGlobalXCConfigSettings(
return;
}
- auto sf = this->CurrentMakefile->GetSource(xcconfig);
+ auto* sf = this->CurrentMakefile->GetSource(xcconfig);
if (!sf) {
cmSystemTools::Error(
cmStrCat("sources for ALL_BUILD do not contain xcconfig file: '",
- xcconfig, "' (configuration: ", configName, ")"));
+ xcconfig, "' (configuration: ", configName, ')'));
return;
}
@@ -3204,12 +3219,12 @@ void cmGlobalXCodeGenerator::CreateTargetXCConfigSettings(
return;
}
- auto sf = target->Makefile->GetSource(xcconfig);
+ auto* sf = target->Makefile->GetSource(xcconfig);
if (!sf) {
cmSystemTools::Error(cmStrCat("target sources for target ",
target->Target->GetName(),
" do not contain xcconfig file: '", xcconfig,
- "' (configuration: ", configName, ")"));
+ "' (configuration: ", configName, ')'));
return;
}
@@ -3452,8 +3467,8 @@ void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(
{
if (value->GetType() != cmXCodeObject::OBJECT_LIST &&
value->GetType() != cmXCodeObject::STRING) {
- cmSystemTools::Error("Unsupported value type for appending: " +
- std::string(attribute));
+ cmSystemTools::Error(
+ cmStrCat("Unsupported value type for appending: ", attribute));
return;
}
if (attr->GetType() == cmXCodeObject::OBJECT_LIST) {
@@ -3476,8 +3491,8 @@ void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(
attr->SetString(newValue);
}
} else {
- cmSystemTools::Error("Unsupported attribute type for appending: " +
- std::string(attribute));
+ cmSystemTools::Error(
+ cmStrCat("Unsupported attribute type for appending: ", attribute));
}
}
@@ -3491,7 +3506,7 @@ void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(
target->GetAttribute("buildConfigurationList")->GetObject();
cmXCodeObject* buildConfigs =
configurationList->GetAttribute("buildConfigurations");
- for (auto obj : buildConfigs->GetObjectList()) {
+ for (auto* obj : buildConfigs->GetObjectList()) {
if (configName.empty() ||
obj->GetAttribute("name")->GetString() == configName) {
cmXCodeObject* settings = obj->GetAttribute("buildSettings");
@@ -3507,7 +3522,7 @@ void cmGlobalXCodeGenerator::InheritBuildSettingAttribute(
target->GetAttribute("buildConfigurationList")->GetObject();
cmXCodeObject* buildConfigs =
configurationList->GetAttribute("buildConfigurations");
- for (auto obj : buildConfigs->GetObjectList()) {
+ for (auto* obj : buildConfigs->GetObjectList()) {
cmXCodeObject* settings = obj->GetAttribute("buildSettings");
if (cmXCodeObject* attr = settings->GetAttribute(attribute)) {
BuildObjectListOrString inherited(this, true);
@@ -3568,14 +3583,14 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
cmValue prop =
target->GetTarget()->GetProperty("XCODE_LINK_BUILD_PHASE_MODE");
if (prop) {
- if (*prop == "BUILT_ONLY") {
+ if (*prop == "BUILT_ONLY"_s) {
useLinkPhase = true;
- } else if (*prop == "KNOWN_LOCATION") {
+ } else if (*prop == "KNOWN_LOCATION"_s) {
useLinkPhase = true;
forceLinkPhase = true;
- } else if (*prop != "NONE") {
- cmSystemTools::Error("Invalid value for XCODE_LINK_BUILD_PHASE_MODE: " +
- *prop);
+ } else if (*prop != "NONE"_s) {
+ cmSystemTools::Error(
+ cmStrCat("Invalid value for XCODE_LINK_BUILD_PHASE_MODE: ", *prop));
return;
}
}
@@ -3585,6 +3600,13 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
continue;
}
for (auto const& libItem : cli->GetItems()) {
+ // Explicitly ignore OBJECT libraries as Xcode emulates them as static
+ // libraries without an artifact. Avoid exposing this to the rest of
+ // CMake's compilation model.
+ if (libItem.Target &&
+ libItem.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ continue;
+ }
// We want to put only static libraries, dynamic libraries, frameworks
// and bundles that are built from targets that are not imported in "Link
// Binary With Libraries" build phase. Except if the target property
@@ -3607,6 +3629,8 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
bool canUseLinkPhase = !libItem.HasFeature() ||
libItem.GetFeatureName() == "__CMAKE_LINK_FRAMEWORK"_s ||
libItem.GetFeatureName() == "FRAMEWORK"_s ||
+ libItem.GetFeatureName() == "__CMAKE_LINK_XCFRAMEWORK"_s ||
+ libItem.GetFeatureName() == "XCFRAMEWORK"_s ||
libItem.GetFeatureName() == "WEAK_FRAMEWORK"_s ||
libItem.GetFeatureName() == "WEAK_LIBRARY"_s;
if (canUseLinkPhase) {
@@ -3827,7 +3851,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
BuildObjectListOrString libSearchPaths(this, true);
std::vector<cmSourceFile const*> objs;
gt->GetExternalObjects(objs, configName);
- for (auto sourceFile : objs) {
+ for (auto const* sourceFile : objs) {
if (sourceFile->GetObjectLibrary().empty()) {
continue;
}
@@ -3861,12 +3885,12 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
std::string linkDirs;
for (auto const& libDir : cli->GetDirectories()) {
- if (!libDir.empty() && libDir != "/usr/lib") {
+ if (!libDir.empty() && libDir != "/usr/lib"_s) {
cmPolicies::PolicyStatus cmp0142 =
target->GetTarget()->GetPolicyStatusCMP0142();
if (cmp0142 == cmPolicies::OLD || cmp0142 == cmPolicies::WARN) {
- libSearchPaths.Add(this->XCodeEscapePath(
- libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"));
+ libSearchPaths.Add(this->XCodeEscapePath(cmStrCat(
+ libDir, "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)")));
}
libSearchPaths.Add(this->XCodeEscapePath(libDir));
}
@@ -3917,12 +3941,14 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
if (cmSystemTools::FileIsFullPath(cleanPath)) {
cleanPath = cmSystemTools::CollapseFullPath(cleanPath);
}
- bool isFramework =
+ bool isXcFramework =
+ cmHasSuffix(libName.GetFeatureName(), "XCFRAMEWORK"_s);
+ bool isFramework = !isXcFramework &&
cmHasSuffix(libName.GetFeatureName(), "FRAMEWORK"_s);
if (isFramework) {
const auto fwDescriptor = this->SplitFrameworkPath(
cleanPath, cmGlobalGenerator::FrameworkFormat::Extended);
- if (!fwDescriptor->Directory.empty() &&
+ if (isFramework && !fwDescriptor->Directory.empty() &&
emitted.insert(fwDescriptor->Directory).second) {
// This is a search path we had not added before and it isn't
// an implicit search path, so we need it
@@ -3940,13 +3966,54 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
fwDescriptor->GetLinkName()))
.Value);
}
+ } else if (isXcFramework) {
+ auto plist = cmParseXcFrameworkPlist(
+ cleanPath, *this->Makefiles.front(), libName.Value.Backtrace);
+ if (!plist) {
+ return;
+ }
+ if (auto const* library = plist->SelectSuitableLibrary(
+ *this->Makefiles.front(), libName.Value.Backtrace)) {
+ auto libraryPath =
+ cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
+ library->LibraryPath);
+ if (auto const fwDescriptor = this->SplitFrameworkPath(
+ libraryPath,
+ cmGlobalGenerator::FrameworkFormat::Relaxed)) {
+ if (!fwDescriptor->Directory.empty() &&
+ emitted.insert(fwDescriptor->Directory).second) {
+ // This is a search path we had not added before and it
+ // isn't an implicit search path, so we need it
+ fwSearchPaths.Add(
+ this->XCodeEscapePath(fwDescriptor->Directory));
+ }
+ libPaths.Add(cmStrCat(
+ "-framework ",
+ this->XCodeEscapePath(fwDescriptor->GetLinkName())));
+ } else {
+ libPaths.Add(
+ libName.GetFormattedItem(this->XCodeEscapePath(libraryPath))
+ .Value);
+ if (!library->HeadersPath.empty()) {
+ this->AppendBuildSettingAttribute(
+ target, "HEADER_SEARCH_PATHS",
+ this->CreateString(this->XCodeEscapePath(
+ cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
+ library->HeadersPath))),
+ configName);
+ }
+ }
+ } else {
+ return;
+ }
} else {
libPaths.Add(
libName.GetFormattedItem(this->XCodeEscapePath(cleanPath))
.Value);
}
if ((!libName.Target || libName.Target->IsImported()) &&
- (isFramework || IsLinkPhaseLibraryExtension(cleanPath))) {
+ (isFramework || isXcFramework ||
+ IsLinkPhaseLibraryExtension(cleanPath))) {
// Create file reference for embedding
auto it = this->ExternalLibRefs.find(cleanPath);
if (it == this->ExternalLibRefs.end()) {
@@ -4035,16 +4102,16 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
// This is a target - get it's product path reference
auto* xcTarget = this->FindXCodeTarget(genTarget);
if (!xcTarget) {
- cmSystemTools::Error("Can not find a target for " +
- genTarget->GetName());
+ cmSystemTools::Error(
+ cmStrCat("Can not find a target for ", genTarget->GetName()));
continue;
}
// Add the target output file as a build reference for other targets
// to link against
auto* fileRefObject = xcTarget->GetAttribute("productReference");
if (!fileRefObject) {
- cmSystemTools::Error("Target " + genTarget->GetName() +
- " is missing product reference");
+ cmSystemTools::Error(cmStrCat("Target ", genTarget->GetName(),
+ " is missing product reference"));
continue;
}
auto it = this->FileRefToEmbedBuildFileMap.find(fileRefObject);
@@ -4056,7 +4123,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
buildFile = it->second;
}
} else if (cmSystemTools::IsPathToFramework(relFile) ||
- cmSystemTools::IsPathToMacOSSharedLibrary(relFile)) {
+ cmSystemTools::IsPathToMacOSSharedLibrary(relFile) ||
+ cmSystemTools::FileIsDirectory(filePath)) {
// This is a regular string path - create file reference
auto it = this->EmbeddedLibRefs.find(relFile);
if (it == this->EmbeddedLibRefs.end()) {
@@ -4069,7 +4137,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
this->CreateObjectReference(fileRef));
}
if (!buildFile) {
- cmSystemTools::Error("Can't create build file for " + relFile);
+ cmSystemTools::Error(
+ cmStrCat("Can't create build file for ", relFile));
continue;
}
this->EmbeddedLibRefs.emplace(filePath, buildFile);
@@ -4078,7 +4147,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
}
}
if (!buildFile) {
- cmSystemTools::Error("Can't find a build file for " + relFile);
+ cmSystemTools::Error(cmStrCat("Can't find a build file for ", relFile));
continue;
}
// Set build file configuration
@@ -4120,7 +4189,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target)
{
- static const auto dstSubfolderSpec = "10";
+ static auto const* const dstSubfolderSpec = "10";
// Despite the name, by default Xcode uses "Embed Frameworks" build phase
// for both frameworks and dynamic libraries
@@ -4131,7 +4200,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target)
void cmGlobalXCodeGenerator::AddEmbeddedPlugIns(cmXCodeObject* target)
{
- static const auto dstSubfolderSpec = "13";
+ static auto const* const dstSubfolderSpec = "13";
this->AddEmbeddedObjects(target, "Embed PlugIns", "XCODE_EMBED_PLUGINS",
dstSubfolderSpec, NoActionOnCopyByDefault);
@@ -4139,7 +4208,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedPlugIns(cmXCodeObject* target)
void cmGlobalXCodeGenerator::AddEmbeddedAppExtensions(cmXCodeObject* target)
{
- static const auto dstSubfolderSpec = "13";
+ static auto const* const dstSubfolderSpec = "13";
this->AddEmbeddedObjects(target, "Embed App Extensions",
"XCODE_EMBED_APP_EXTENSIONS", dstSubfolderSpec,
@@ -4149,7 +4218,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedAppExtensions(cmXCodeObject* target)
void cmGlobalXCodeGenerator::AddEmbeddedExtensionKitExtensions(
cmXCodeObject* target)
{
- static const auto dstSubfolderSpec = "16";
+ static auto const* const dstSubfolderSpec = "16";
this->AddEmbeddedObjects(target, "Embed App Extensions",
"XCODE_EMBED_EXTENSIONKIT_EXTENSIONS",
@@ -4157,6 +4226,15 @@ void cmGlobalXCodeGenerator::AddEmbeddedExtensionKitExtensions(
"$(EXTENSIONS_FOLDER_PATH)");
}
+void cmGlobalXCodeGenerator::AddEmbeddedResources(cmXCodeObject* target)
+{
+ static const auto dstSubfolderSpec = "7";
+
+ this->AddEmbeddedObjects(target, "Embed Resources",
+ "XCODE_EMBED_RESOURCES_PATH", dstSubfolderSpec,
+ NoActionOnCopyByDefault);
+}
+
bool cmGlobalXCodeGenerator::CreateGroups(
std::vector<cmLocalGenerator*>& generators)
{
@@ -4260,7 +4338,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
for (std::vector<std::string>::size_type i = 0; i < tgt_folders.size();
i++) {
if (i != 0) {
- curr_tgt_folder += "/";
+ curr_tgt_folder += '/';
}
curr_tgt_folder += tgt_folders[i];
it = this->TargetGroup.find(curr_tgt_folder);
@@ -4299,7 +4377,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
} else {
tgroup = i_folder->second;
}
- curr_folder += "\\";
+ curr_folder += '\\';
}
return tgroup;
}
@@ -4358,6 +4436,15 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
this->FrameworkGroup->AddAttribute("children", frameworkGroupChildren);
this->MainGroupChildren->AddObject(this->FrameworkGroup);
+ this->ResourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+ this->ResourcesGroup->AddAttribute("name", this->CreateString("Resources"));
+ this->ResourcesGroup->AddAttribute("sourceTree",
+ this->CreateString("<group>"));
+ cmXCodeObject* ResourcesGroupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ this->ResourcesGroup->AddAttribute("children", ResourcesGroupChildren);
+ this->MainGroupChildren->AddObject(this->ResourcesGroup);
+
this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
this->RootObject->SetComment("Project object");
@@ -4543,12 +4630,13 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
this->CustomCommandRoots.clear();
}
// loop over all targets and add link and depend info
- for (auto t : targets) {
+ for (auto* t : targets) {
this->AddDependAndLinkInformation(t);
this->AddEmbeddedFrameworks(t);
this->AddEmbeddedPlugIns(t);
this->AddEmbeddedAppExtensions(t);
this->AddEmbeddedExtensionKitExtensions(t);
+ this->AddEmbeddedResources(t);
// Inherit project-wide values for any target-specific search paths.
this->InheritBuildSettingAttribute(t, "HEADER_SEARCH_PATHS");
this->InheritBuildSettingAttribute(t, "SYSTEM_HEADER_SEARCH_PATHS");
@@ -4569,7 +4657,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
}
// now add all targets to the root object
cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST);
- for (auto t : targets) {
+ for (auto* t : targets) {
allTargets->AddObject(t);
cmXCodeObject* productRef = t->GetAttribute("productReference");
if (productRef) {
@@ -4637,16 +4725,17 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
{
cmGeneratedFileStream makefileStream(this->CurrentXCodeHackMakefile);
if (!makefileStream) {
- cmSystemTools::Error("Could not create " + this->CurrentXCodeHackMakefile);
+ cmSystemTools::Error(
+ cmStrCat("Could not create ", this->CurrentXCodeHackMakefile));
return;
}
makefileStream.SetCopyIfDifferent(true);
// one more pass for external depend information not handled
// correctly by xcode
/* clang-format off */
- makefileStream << "# DO NOT EDIT\n";
- makefileStream << "# This makefile makes sure all linkable targets are\n";
- makefileStream << "# up-to-date with anything they link to\n"
+ makefileStream << "# DO NOT EDIT\n"
+ "# This makefile makes sure all linkable targets are\n"
+ "# up-to-date with anything they link to\n"
"default:\n"
"\techo \"Do not invoke directly\"\n"
"\n";
@@ -4662,7 +4751,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
"# does not seem to check these dependencies itself.\n";
/* clang-format on */
for (const auto& configName : this->CurrentConfigurationTypes) {
- for (auto target : targets) {
+ for (auto* target : targets) {
cmGeneratorTarget* gt = target->GetTarget();
if (gt->GetType() == cmStateEnums::EXECUTABLE ||
@@ -4687,20 +4776,20 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
if (y != target->GetDependTargets().end()) {
for (auto const& deptgt : y->second) {
makefileStream << this->PostBuildMakeTarget(deptgt, configName)
- << ": " << trel << "\n";
+ << ": " << trel << '\n';
}
}
std::vector<cmGeneratorTarget*> objlibs;
gt->GetObjectLibrariesCMP0026(objlibs);
- for (auto objLib : objlibs) {
+ for (auto* objLib : objlibs) {
makefileStream << this->PostBuildMakeTarget(objLib->GetName(),
configName)
- << ": " << trel << "\n";
+ << ": " << trel << '\n';
}
// Create a rule for this target.
- makefileStream << trel << ":";
+ makefileStream << trel << ':';
// List dependencies if any exist.
auto const x = target->GetDependLibraries().find(configName);
@@ -4712,7 +4801,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
}
}
- for (auto objLib : objlibs) {
+ for (auto* objLib : objlibs) {
const std::string objLibName = objLib->GetName();
std::string d = cmStrCat(this->GetTargetTempDir(gt, configName),
@@ -4724,9 +4813,9 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
}
// Write the action to remove the target if it is out of date.
- makefileStream << "\n";
- makefileStream << "\t/bin/rm -f "
- << this->ConvertToRelativeForMake(tfull) << "\n";
+ makefileStream << "\n"
+ "\t/bin/rm -f "
+ << this->ConvertToRelativeForMake(tfull) << '\n';
// if building for more than one architecture
// then remove those executables as well
if (this->Architectures.size() > 1) {
@@ -4737,7 +4826,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
gt->GetFullName(configName));
makefileStream << "\t/bin/rm -f "
<< this->ConvertToRelativeForMake(universalFile)
- << "\n";
+ << '\n';
}
}
makefileStream << "\n\n";
@@ -4746,8 +4835,8 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile(
}
makefileStream << "\n\n"
- << "# For each target create a dummy rule"
- << "so the target does not have to exist\n";
+ "# For each target create a dummy rule"
+ "so the target does not have to exist\n";
for (auto const& dummyRule : dummyRules) {
makefileStream << dummyRule << ":\n";
}
@@ -4765,7 +4854,7 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
std::string xcodeDir = cmStrCat(root->GetCurrentBinaryDirectory(), '/',
root->GetProjectName(), ".xcodeproj");
cmSystemTools::MakeDirectory(xcodeDir);
- std::string xcodeProjFile = xcodeDir + "/project.pbxproj";
+ std::string xcodeProjFile = cmStrCat(xcodeDir, "/project.pbxproj");
cmGeneratedFileStream fout(xcodeProjFile);
fout.SetCopyIfDifferent(true);
if (!fout) {
@@ -4890,8 +4979,8 @@ void cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
{
SortXCodeObjects();
- fout << "// !$*UTF8*$!\n";
- fout << "{\n";
+ fout << "// !$*UTF8*$!\n"
+ "{\n";
cmXCodeObject::Indent(1, fout);
fout << "archiveVersion = 1;\n";
cmXCodeObject::Indent(1, fout);
@@ -4903,8 +4992,8 @@ void cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
cmXCode21Object::PrintList(this->XCodeObjects, fout);
cmXCodeObject::Indent(1, fout);
fout << "rootObject = " << this->RootObject->GetId()
- << " /* Project object */;\n";
- fout << "}\n";
+ << " /* Project object */;\n"
+ "}\n";
}
const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
@@ -5043,7 +5132,7 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
// Separate from previous flags.
if (!flags.empty()) {
- flags += " ";
+ flags += ' ';
}
// Check if the flag needs quoting.
@@ -5062,7 +5151,7 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
if (quoteFlag) {
// Open single quote.
- flags += "'";
+ flags += '\'';
}
// Flag value with escaped quotes and backslashes.
@@ -5078,7 +5167,7 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
if (quoteFlag) {
// Close single quote.
- flags += "'";
+ flags += '\'';
}
}
@@ -5155,6 +5244,10 @@ std::string cmGlobalXCodeGenerator::GetDeploymentPlatform(const cmMakefile* mf)
case cmMakefile::AppleSDK::WatchSimulator:
return "WATCHOS_DEPLOYMENT_TARGET";
+ case cmMakefile::AppleSDK::XROS:
+ case cmMakefile::AppleSDK::XRSimulator:
+ return "XROS_DEPLOYMENT_TARGET";
+
case cmMakefile::AppleSDK::MacOS:
default:
return "MACOSX_DEPLOYMENT_TARGET";
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 1fdd189..da0a4ea 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -120,7 +120,7 @@ public:
* Used to determine if this generator supports DEPFILE option.
*/
bool SupportsCustomCommandDepfile() const override { return true; }
- virtual cm::optional<cmDepfileFormat> DepfileFormat() const override
+ cm::optional<cmDepfileFormat> DepfileFormat() const override
{
return this->XcodeBuildSystem == BuildSystem::One
? cmDepfileFormat::MakeDepfile
@@ -224,6 +224,7 @@ private:
void AddEmbeddedPlugIns(cmXCodeObject* target);
void AddEmbeddedAppExtensions(cmXCodeObject* target);
void AddEmbeddedExtensionKitExtensions(cmXCodeObject* target);
+ void AddEmbeddedResources(cmXCodeObject* target);
void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target,
cmXCodeObject* buildSettings,
const std::string& configName);
@@ -355,6 +356,7 @@ private:
std::string const& configName);
cmXCodeObject* MainGroupChildren;
cmXCodeObject* FrameworkGroup;
+ cmXCodeObject* ResourcesGroup;
cmMakefile* CurrentMakefile;
cmLocalGenerator* CurrentLocalGenerator;
cmLocalGenerator* CurrentRootGenerator = nullptr;
diff --git a/Source/cmImportedCxxModuleInfo.cxx b/Source/cmImportedCxxModuleInfo.cxx
new file mode 100644
index 0000000..9e3ac9a
--- /dev/null
+++ b/Source/cmImportedCxxModuleInfo.cxx
@@ -0,0 +1,76 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmImportedCxxModuleInfo.h"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cmCryptoHash.h"
+#include "cmList.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+bool ImportedCxxModuleLookup::Initialized() const
+{
+ return this->DoneInit;
+}
+
+void ImportedCxxModuleLookup::Initialize(std::string const& importedModules)
+{
+ for (auto const& entry : cmList{ importedModules }) {
+ auto nameSep = entry.find('=');
+ if (nameSep == std::string::npos) {
+ // Invalid entry; ignore.
+ continue;
+ }
+
+ auto name = entry.substr(0, nameSep);
+
+ auto sourceSep = entry.find(',', nameSep);
+ std::string source;
+ if (sourceSep == std::string::npos) {
+ source = entry.substr(nameSep + 1);
+ } else {
+ source = entry.substr(nameSep + 1, sourceSep - nameSep - 1);
+ }
+
+ std::vector<std::string> bmis;
+ if (sourceSep != std::string::npos) {
+ auto bmiPaths = entry.substr(sourceSep + 1);
+ bmis = cmSystemTools::SplitString(bmiPaths, ',');
+ }
+
+ this->ImportedInfo.emplace(source,
+ ImportedCxxModuleInfo{ name, std::move(bmis) });
+ }
+
+ this->DoneInit = true;
+}
+
+std::string ImportedCxxModuleLookup::BmiNameForSource(std::string const& path)
+{
+ auto genit = this->GeneratorInfo.find(path);
+ if (genit != this->GeneratorInfo.end()) {
+ return genit->second.BmiName;
+ }
+
+ auto importit = this->ImportedInfo.find(path);
+ std::string bmiName;
+ auto hasher = cmCryptoHash::New("SHA3_512");
+ constexpr size_t HASH_TRUNCATION = 12;
+ if (importit != this->ImportedInfo.end()) {
+ auto safename = hasher->HashString(importit->second.Name);
+ bmiName = cmStrCat(safename.substr(0, HASH_TRUNCATION), ".bmi");
+ } else {
+ auto dirhash = hasher->HashString(path);
+ bmiName = cmStrCat(dirhash.substr(0, HASH_TRUNCATION), ".bmi");
+ }
+
+ this->GeneratorInfo.emplace(
+ path, ImportedCxxModuleGeneratorInfo{ &importit->second, bmiName });
+ return bmiName;
+}
diff --git a/Source/cmImportedCxxModuleInfo.h b/Source/cmImportedCxxModuleInfo.h
new file mode 100644
index 0000000..e052283
--- /dev/null
+++ b/Source/cmImportedCxxModuleInfo.h
@@ -0,0 +1,37 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <map>
+#include <string>
+#include <vector>
+
+struct ImportedCxxModuleInfo
+{
+ std::string const Name;
+ std::vector<std::string> const AvailableBmis;
+};
+
+struct ImportedCxxModuleGeneratorInfo
+{
+ ImportedCxxModuleInfo const* ImportedInfo;
+ std::string const BmiName;
+};
+
+struct ImportedCxxModuleLookup
+{
+ ImportedCxxModuleLookup() = default;
+ ~ImportedCxxModuleLookup() = default;
+
+ bool Initialized() const;
+ void Initialize(std::string const& importedModules);
+
+ std::string BmiNameForSource(std::string const& path);
+
+private:
+ bool DoneInit = false;
+ std::map<std::string, ImportedCxxModuleInfo> ImportedInfo;
+ std::map<std::string, ImportedCxxModuleGeneratorInfo> GeneratorInfo;
+};
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx
index e0a6958..2b0e03c 100644
--- a/Source/cmIncludeGuardCommand.cxx
+++ b/Source/cmIncludeGuardCommand.cxx
@@ -2,11 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIncludeGuardCommand.h"
+#include "cmCryptoHash.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include "cmValue.h"
#include "cmake.h"
@@ -21,14 +22,8 @@ enum IncludeGuardScope
std::string GetIncludeGuardVariableName(std::string const& filePath)
{
- std::string result = "__INCGUARD_";
-#ifndef CMAKE_BOOTSTRAP
- result += cmSystemTools::ComputeStringMD5(filePath);
-#else
- result += cmSystemTools::MakeCidentifier(filePath);
-#endif
- result += "__";
- return result;
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ return cmStrCat("__INCGUARD_", hasher.HashString(filePath), "__");
}
bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar)
diff --git a/Source/cmInstallCxxModuleBmiGenerator.cxx b/Source/cmInstallCxxModuleBmiGenerator.cxx
index 1ef1eaa..111691e 100644
--- a/Source/cmInstallCxxModuleBmiGenerator.cxx
+++ b/Source/cmInstallCxxModuleBmiGenerator.cxx
@@ -11,6 +11,7 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmOutputConverter.h"
+#include "cmScriptGenerator.h"
#include "cmStringAlgorithms.h"
cmInstallCxxModuleBmiGenerator::cmInstallCxxModuleBmiGenerator(
diff --git a/Source/cmInstallCxxModuleBmiGenerator.h b/Source/cmInstallCxxModuleBmiGenerator.h
index 21edb2e..23ed02e 100644
--- a/Source/cmInstallCxxModuleBmiGenerator.h
+++ b/Source/cmInstallCxxModuleBmiGenerator.h
@@ -9,7 +9,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmGeneratorTarget;
class cmListFileBacktrace;
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 7deb9ba..96a924f 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -9,7 +9,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmListFileBacktrace;
class cmLocalGenerator;
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 1d81b0b..71d5471 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -8,6 +8,7 @@
#include <cm/memory>
+#include "cmCryptoHash.h"
#ifndef CMAKE_BOOTSTRAP
# include "cmExportInstallAndroidMKGenerator.h"
#endif
@@ -16,6 +17,7 @@
#include "cmInstallType.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
+#include "cmScriptGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -63,11 +65,10 @@ std::string cmInstallExportGenerator::TempDirCalculate() const
return path;
}
-#ifndef CMAKE_BOOTSTRAP
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
path += '/';
// Replace the destination path with a hash to keep it short.
- path += cmSystemTools::ComputeStringMD5(this->Destination);
-#endif
+ path += hasher.HashString(this->Destination);
return path;
}
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 346ca67..f2d4a05 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -10,7 +10,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmExportInstallFileGenerator;
class cmExportSet;
diff --git a/Source/cmInstallFileSetGenerator.h b/Source/cmInstallFileSetGenerator.h
index 56341d4..708cee6 100644
--- a/Source/cmInstallFileSetGenerator.h
+++ b/Source/cmInstallFileSetGenerator.h
@@ -8,7 +8,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmGeneratorTarget;
class cmFileSet;
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 53076b3..874bde1 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -9,7 +9,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmListFileBacktrace;
class cmLocalGenerator;
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
index 3e493bc..3f8a103 100644
--- a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
+#include "cmScriptGenerator.h"
#include "cmStringAlgorithms.h"
namespace {
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.h b/Source/cmInstallGetRuntimeDependenciesGenerator.h
index a2d6593..8e4e8cb 100644
--- a/Source/cmInstallGetRuntimeDependenciesGenerator.h
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.h
@@ -7,7 +7,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmListFileBacktrace;
class cmLocalGenerator;
diff --git a/Source/cmInstallImportedRuntimeArtifactsGenerator.h b/Source/cmInstallImportedRuntimeArtifactsGenerator.h
index 9e045ee..84d3fee 100644
--- a/Source/cmInstallImportedRuntimeArtifactsGenerator.h
+++ b/Source/cmInstallImportedRuntimeArtifactsGenerator.h
@@ -8,7 +8,6 @@
#include "cmInstallGenerator.h"
#include "cmListFileCache.h"
-#include "cmScriptGenerator.h"
class cmGeneratorTarget;
class cmLocalGenerator;
diff --git a/Source/cmInstallRuntimeDependencySetGenerator.h b/Source/cmInstallRuntimeDependencySetGenerator.h
index 680361b..1a3c1e4 100644
--- a/Source/cmInstallRuntimeDependencySetGenerator.h
+++ b/Source/cmInstallRuntimeDependencySetGenerator.h
@@ -7,7 +7,6 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
class cmInstallRuntimeDependencySet;
class cmListFileBacktrace;
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index c3a7058..012a4a3 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -9,7 +9,6 @@
#include "cmInstallGenerator.h"
#include "cmListFileCache.h"
-#include "cmScriptGenerator.h"
class cmLocalGenerator;
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 3ac100d..e7998ea 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -23,6 +23,7 @@
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmScriptGenerator.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 2f41163..11a3264 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -11,7 +11,6 @@
#include "cmInstallGenerator.h"
#include "cmInstallType.h"
#include "cmListFileCache.h"
-#include "cmScriptGenerator.h"
class cmGeneratorTarget;
class cmLocalGenerator;
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index 373c349..e0d7647 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -9,7 +9,8 @@
#include <string>
#include <vector>
-class cmCompiledGeneratorExpression;
+#include "cmGeneratorExpression.h"
+
class cmMakefile;
/** \class cmInstalledFile
diff --git a/Source/cmJSONHelpers.cxx b/Source/cmJSONHelpers.cxx
new file mode 100644
index 0000000..c36b56d
--- /dev/null
+++ b/Source/cmJSONHelpers.cxx
@@ -0,0 +1,113 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmJSONHelpers.h"
+
+#include <functional>
+#include <string>
+#include <vector>
+
+#include <cm3p/json/value.h>
+
+#include "cmJSONState.h"
+
+namespace JsonErrors {
+ErrorGenerator EXPECTED_TYPE(const std::string& type)
+{
+ return [type](const Json::Value* value, cmJSONState* state) -> void {
+ if (state->key().empty()) {
+ state->AddErrorAtValue(cmStrCat("Expected ", type), value);
+ return;
+ }
+ std::string errMsg = cmStrCat("\"", state->key(), "\" expected ", type);
+ if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
+ errMsg = cmStrCat(errMsg, ", got: ", value->asString());
+ }
+ state->AddErrorAtValue(errMsg, value);
+ };
+}
+
+void INVALID_STRING(const Json::Value* value, cmJSONState* state)
+{
+ JsonErrors::EXPECTED_TYPE("a string")(value, state);
+}
+
+void INVALID_BOOL(const Json::Value* value, cmJSONState* state)
+{
+ JsonErrors::EXPECTED_TYPE("a bool")(value, state);
+}
+
+void INVALID_INT(const Json::Value* value, cmJSONState* state)
+{
+ JsonErrors::EXPECTED_TYPE("an integer")(value, state);
+}
+
+void INVALID_UINT(const Json::Value* value, cmJSONState* state)
+{
+ JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
+}
+
+ObjectErrorGenerator INVALID_NAMED_OBJECT(
+ const std::function<std::string(const Json::Value*, cmJSONState*)>&
+ nameGenerator)
+{
+ return [nameGenerator](
+ ObjectError errorType,
+ const Json::Value::Members& extraFields) -> ErrorGenerator {
+ return [nameGenerator, errorType, extraFields](
+ const Json::Value* value, cmJSONState* state) -> void {
+ std::string name = nameGenerator(value, state);
+ switch (errorType) {
+ case ObjectError::RequiredMissing:
+ state->AddErrorAtValue(cmStrCat("Invalid Required ", name), value);
+ break;
+ case ObjectError::InvalidObject:
+ state->AddErrorAtValue(cmStrCat("Invalid ", name), value);
+ break;
+ case ObjectError::ExtraField: {
+ for (auto const& member : extraFields) {
+ if (value) {
+ state->AddErrorAtValue(
+ cmStrCat("Invalid extra field \"", member, "\" in ", name),
+ &(*value)[member]);
+ } else {
+ state->AddError(
+ cmStrCat("Invalid extra field \"", member, "\" in ", name));
+ }
+ }
+ } break;
+ case ObjectError::MissingRequired:
+ state->AddErrorAtValue(cmStrCat("Missing required field \"",
+ state->key(), "\" in ", name),
+ value);
+ break;
+ }
+ };
+ };
+}
+
+ErrorGenerator INVALID_OBJECT(ObjectError errorType,
+ const Json::Value::Members& extraFields)
+{
+ return INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState*) -> std::string { return "Object"; })(
+ errorType, extraFields);
+}
+
+ErrorGenerator INVALID_NAMED_OBJECT_KEY(
+ ObjectError errorType, const Json::Value::Members& extraFields)
+{
+ return INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState* state) -> std::string {
+ for (auto it = state->parseStack.rbegin();
+ it != state->parseStack.rend(); ++it) {
+ if (it->first.rfind("$vector_item_", 0) == 0) {
+ continue;
+ }
+ return cmStrCat("\"", it->first, "\"");
+ }
+ return "root";
+ })(errorType, extraFields);
+}
+}
diff --git a/Source/cmJSONHelpers.h b/Source/cmJSONHelpers.h
index 94641de..24884ed 100644
--- a/Source/cmJSONHelpers.h
+++ b/Source/cmJSONHelpers.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <algorithm>
-#include <cstddef>
#include <functional>
#include <iostream>
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include <cm/optional>
@@ -18,6 +18,7 @@
#include <cm3p/json/value.h>
#include "cmJSONState.h"
+#include "cmStringAlgorithms.h"
template <typename T>
using cmJSONHelper =
@@ -36,98 +37,25 @@ enum ObjectError
using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;
using ObjectErrorGenerator =
std::function<ErrorGenerator(ObjectError, const Json::Value::Members&)>;
-const auto EXPECTED_TYPE = [](const std::string& type) {
- return [type](const Json::Value* value, cmJSONState* state) -> void {
-#if !defined(CMAKE_BOOTSTRAP)
- if (state->key().empty()) {
- state->AddErrorAtValue(cmStrCat("Expected ", type), value);
- return;
- }
- std::string errMsg = cmStrCat("\"", state->key(), "\" expected ", type);
- if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
- errMsg = cmStrCat(errMsg, ", got: ", value->asString());
- }
- state->AddErrorAtValue(errMsg, value);
-#endif
- };
-};
-const auto INVALID_STRING = [](const Json::Value* value,
- cmJSONState* state) -> void {
- JsonErrors::EXPECTED_TYPE("a string")(value, state);
-};
-const auto INVALID_BOOL = [](const Json::Value* value,
- cmJSONState* state) -> void {
- JsonErrors::EXPECTED_TYPE("a bool")(value, state);
-};
-const auto INVALID_INT = [](const Json::Value* value,
- cmJSONState* state) -> void {
- JsonErrors::EXPECTED_TYPE("an integer")(value, state);
-};
-const auto INVALID_UINT = [](const Json::Value* value,
- cmJSONState* state) -> void {
- JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
-};
-const auto INVALID_NAMED_OBJECT =
- [](const std::function<std::string(const Json::Value*, cmJSONState*)>&
- nameGenerator) -> ObjectErrorGenerator {
- return [nameGenerator](
- ObjectError errorType,
- const Json::Value::Members& extraFields) -> ErrorGenerator {
- return [nameGenerator, errorType, extraFields](
- const Json::Value* value, cmJSONState* state) -> void {
-#if !defined(CMAKE_BOOTSTRAP)
- std::string name = nameGenerator(value, state);
- switch (errorType) {
- case ObjectError::RequiredMissing:
- state->AddErrorAtValue(cmStrCat("Invalid Required ", name), value);
- break;
- case ObjectError::InvalidObject:
- state->AddErrorAtValue(cmStrCat("Invalid ", name), value);
- break;
- case ObjectError::ExtraField: {
- for (auto const& member : extraFields) {
- if (value) {
- state->AddErrorAtValue(
- cmStrCat("Invalid extra field \"", member, "\" in ", name),
- &(*value)[member]);
- } else {
- state->AddError(
- cmStrCat("Invalid extra field \"", member, "\" in ", name));
- }
- }
- } break;
- case ObjectError::MissingRequired:
- state->AddErrorAtValue(cmStrCat("Missing required field \"",
- state->key(), "\" in ", name),
- value);
- break;
- }
-#endif
- };
- };
-};
-const auto INVALID_OBJECT =
- [](ObjectError errorType,
- const Json::Value::Members& extraFields) -> ErrorGenerator {
- return INVALID_NAMED_OBJECT(
- [](const Json::Value*, cmJSONState*) -> std::string { return "Object"; })(
- errorType, extraFields);
-};
-const auto INVALID_NAMED_OBJECT_KEY =
- [](ObjectError errorType,
- const Json::Value::Members& extraFields) -> ErrorGenerator {
- return INVALID_NAMED_OBJECT(
- [](const Json::Value*, cmJSONState* state) -> std::string {
- for (auto it = state->parseStack.rbegin();
- it != state->parseStack.rend(); ++it) {
- if (it->first.rfind("$vector_item_", 0) == 0) {
- continue;
- }
- return cmStrCat("\"", it->first, "\"");
- }
- return "root";
- })(errorType, extraFields);
-};
+ErrorGenerator EXPECTED_TYPE(const std::string& type);
+
+void INVALID_STRING(const Json::Value* value, cmJSONState* state);
+
+void INVALID_BOOL(const Json::Value* value, cmJSONState* state);
+
+void INVALID_INT(const Json::Value* value, cmJSONState* state);
+
+void INVALID_UINT(const Json::Value* value, cmJSONState* state);
+
+ObjectErrorGenerator INVALID_NAMED_OBJECT(
+ const std::function<std::string(const Json::Value*, cmJSONState*)>&
+ nameGenerator);
+
+ErrorGenerator INVALID_OBJECT(ObjectError errorType,
+ const Json::Value::Members& extraFields);
+
+ErrorGenerator INVALID_NAMED_OBJECT_KEY(
+ ObjectError errorType, const Json::Value::Members& extraFields);
}
struct cmJSONHelperBuilder
diff --git a/Source/cmJSONState.cxx b/Source/cmJSONState.cxx
index 92bde77..1abdaa6 100644
--- a/Source/cmJSONState.cxx
+++ b/Source/cmJSONState.cxx
@@ -3,10 +3,9 @@
#include "cmJSONState.h"
+#include <iterator>
#include <sstream>
-#include <cm/memory>
-
#include <cm3p/json/reader.h>
#include <cm3p/json/value.h>
diff --git a/Source/cmJSONState.h b/Source/cmJSONState.h
index 4984c81..9071268 100644
--- a/Source/cmJSONState.h
+++ b/Source/cmJSONState.h
@@ -9,7 +9,6 @@
#include <utility>
#include <vector>
-#include "cmJSONState.h"
#include "cmStringAlgorithms.h"
namespace Json {
diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx
index 0752b33..154aa27 100644
--- a/Source/cmLDConfigLDConfigTool.cxx
+++ b/Source/cmLDConfigLDConfigTool.cxx
@@ -14,6 +14,7 @@
#include "cmRuntimeDependencyArchive.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
cmLDConfigLDConfigTool::cmLDConfigLDConfigTool(
cmRuntimeDependencyArchive* archive)
@@ -43,14 +44,15 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
.AddCommand(ldConfigCommand);
auto process = builder.Start();
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
this->Archive->SetError("Failed to start ldconfig process");
return false;
}
std::string line;
static const cmsys::RegularExpression regex("^([^\t:]*):");
- while (std::getline(*process.OutputStream(), line)) {
+ cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
+ while (std::getline(output, line)) {
cmsys::RegularExpressionMatch match;
if (regex.find(line.c_str(), match)) {
paths.push_back(match.match(1));
@@ -61,8 +63,7 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
this->Archive->SetError("Failed to wait on ldconfig process");
return false;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
+ if (process.GetStatus(0).ExitStatus != 0) {
this->Archive->SetError("Failed to run ldconfig");
return false;
}
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index 1ec071b..6775a60 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -6,6 +6,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -39,7 +40,7 @@ bool cmLinkDirectoriesCommand(std::vector<std::string> const& args,
AddLinkDir(mf, *i, directories);
}
- mf.AddLinkDirectory(cmJoin(directories, ";"), before);
+ mf.AddLinkDirectory(cmList::to_string(directories), before);
return true;
}
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index b7ee4fa..1f5005b 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -65,7 +65,8 @@ void cmLinkLineComputer::ComputeLinkLibs(
ItemVector const& items = cli.GetItems();
for (auto const& item : items) {
if (item.Target &&
- item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ (item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+ item.Target->GetType() == cmStateEnums::OBJECT_LIBRARY)) {
continue;
}
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index b06dc3d..ded6466 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -115,6 +115,7 @@ void cmLinkLineDeviceComputer::ComputeLinkLibraries(
switch (item.Target->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::OBJECT_LIBRARY:
case cmStateEnums::INTERFACE_LIBRARY:
skip = true;
break;
diff --git a/Source/cmList.cxx b/Source/cmList.cxx
index 28d4791..939fbb5 100644
--- a/Source/cmList.cxx
+++ b/Source/cmList.cxx
@@ -19,6 +19,7 @@
#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
+#include "cmListFileCache.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
@@ -1004,3 +1005,8 @@ cmList::container_type::iterator cmList::Insert(
}
return container.begin() + delta;
}
+
+std::string const& cmList::ToString(BT<std::string> const& s)
+{
+ return s.Value;
+}
diff --git a/Source/cmList.h b/Source/cmList.h
index df450fd..1b94c2f 100644
--- a/Source/cmList.h
+++ b/Source/cmList.h
@@ -21,6 +21,9 @@
#include "cmValue.h"
+template <typename T>
+class BT;
+
/**
* CMake lists management
* A CMake list is a string where list elements are separated by the ';'
@@ -744,8 +747,10 @@ public:
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
{
- this->insert(this->begin() + this->ComputeInsertIndex(index), first, last,
- expandElements, emptyElements);
+ auto const offset =
+ static_cast<difference_type>(this->ComputeInsertIndex(index));
+ this->insert(this->begin() + offset, first, last, expandElements,
+ emptyElements);
return *this;
}
template <typename InputIterator>
@@ -1121,6 +1126,13 @@ public:
list, cmList::Join(first, last, cmList::element_separator));
}
+ template <typename Range,
+ cm::enable_if_t<cm::is_range<Range>::value, int> = 0>
+ static std::string to_string(Range const& r)
+ {
+ return cmList::Join(r, cmList::element_separator);
+ }
+
// Non-members
// ===========
friend inline bool operator==(const cmList& lhs, const cmList& rhs) noexcept
@@ -1176,13 +1188,13 @@ private:
auto size = container.size();
insertPos = cmList::Insert(container, insertPos, *first,
expandElements, emptyElements);
- insertPos += container.size() - size;
+ insertPos += static_cast<decltype(delta)>(container.size() - size);
}
} else {
for (; first != last; ++first) {
if (!first->empty() || emptyElements == EmptyElements::Yes) {
insertPos = container.insert(insertPos, *first);
- insertPos++;
+ ++insertPos;
}
}
}
@@ -1192,6 +1204,7 @@ private:
static std::string const& ToString(std::string const& s) { return s; }
static std::string ToString(cm::string_view s) { return std::string{ s }; }
+ static std::string const& ToString(BT<std::string> const&);
template <typename Range>
static std::string Join(Range const& r, cm::string_view glue)
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index da95b19..63c8aa8 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -10,6 +10,7 @@
#include <initializer_list>
#include <iterator>
#include <sstream>
+#include <type_traits>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -24,6 +25,7 @@
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
+#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
@@ -40,6 +42,7 @@
#include "cmLinkLineDeviceComputer.h"
#include "cmList.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -57,11 +60,6 @@
#include "cmVersion.h"
#include "cmake.h"
-#if !defined(CMAKE_BOOTSTRAP)
-# define CM_LG_ENCODE_OBJECT_NAMES
-# include "cmCryptoHash.h"
-#endif
-
#if defined(__HAIKU__)
# include <FindDirectory.h>
# include <StorageDefs.h>
@@ -1431,11 +1429,14 @@ void cmLocalGenerator::GetDeviceLinkFlags(
}
this->AddVisibilityPresetFlags(linkFlags, target, "CUDA");
+ this->GetGlobalGenerator()->EncodeLiteral(linkFlags);
std::vector<std::string> linkOpts;
target->GetLinkOptions(linkOpts, config, "CUDA");
+ this->SetLinkScriptShell(this->GetGlobalGenerator()->GetUseLinkScript());
// LINK_OPTIONS are escaped.
this->AppendCompileOptions(linkFlags, linkOpts);
+ this->SetLinkScriptShell(false);
}
void cmLocalGenerator::GetTargetFlags(
@@ -1501,13 +1502,17 @@ void cmLocalGenerator::GetTargetFlags(
}
if (!sharedLibFlags.empty()) {
+ this->GetGlobalGenerator()->EncodeLiteral(sharedLibFlags);
linkFlags.emplace_back(std::move(sharedLibFlags));
}
std::vector<BT<std::string>> linkOpts =
target->GetLinkOptions(config, linkLanguage);
+ this->SetLinkScriptShell(this->GetGlobalGenerator()->GetUseLinkScript());
// LINK_OPTIONS are escaped.
this->AppendCompileOptions(linkFlags, linkOpts);
+ this->SetLinkScriptShell(false);
+
if (pcli) {
this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
@@ -1581,13 +1586,16 @@ void cmLocalGenerator::GetTargetFlags(
}
if (!exeFlags.empty()) {
+ this->GetGlobalGenerator()->EncodeLiteral(exeFlags);
linkFlags.emplace_back(std::move(exeFlags));
}
std::vector<BT<std::string>> linkOpts =
target->GetLinkOptions(config, linkLanguage);
+ this->SetLinkScriptShell(this->GetGlobalGenerator()->GetUseLinkScript());
// LINK_OPTIONS are escaped.
this->AppendCompileOptions(linkFlags, linkOpts);
+ this->SetLinkScriptShell(false);
} break;
default:
break;
@@ -1603,6 +1611,7 @@ void cmLocalGenerator::GetTargetFlags(
config);
if (!extraLinkFlags.empty()) {
+ this->GetGlobalGenerator()->EncodeLiteral(extraLinkFlags);
linkFlags.emplace_back(std::move(extraLinkFlags));
}
}
@@ -1648,6 +1657,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
this->AppendFlags(compileFlags, mf->GetDefineFlags());
this->AppendFlags(compileFlags,
this->GetFrameworkFlags(lang, config, target));
+ this->AppendFlags(compileFlags,
+ this->GetXcFrameworkFlags(lang, config, target));
if (!compileFlags.empty()) {
flags.emplace_back(std::move(compileFlags));
@@ -1713,6 +1724,43 @@ std::string cmLocalGenerator::GetFrameworkFlags(std::string const& lang,
return flags;
}
+std::string cmLocalGenerator::GetXcFrameworkFlags(std::string const& lang,
+ std::string const& config,
+ cmGeneratorTarget* target)
+{
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ cmMakefile* mf = lg->GetMakefile();
+
+ if (!target->IsApple()) {
+ return std::string();
+ }
+
+ cmValue includeSearchFlag =
+ mf->GetDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_", lang));
+ cmValue sysIncludeSearchFlag =
+ mf->GetDefinition(cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang));
+
+ if (!includeSearchFlag && !sysIncludeSearchFlag) {
+ return std::string{};
+ }
+
+ std::string flags;
+ if (cmComputeLinkInformation* cli = target->GetLinkInformation(config)) {
+ std::vector<std::string> const& paths = cli->GetXcFrameworkHeaderPaths();
+ for (std::string const& path : paths) {
+ if (sysIncludeSearchFlag &&
+ target->IsSystemIncludeDirectory(path, config, lang)) {
+ flags += *sysIncludeSearchFlag;
+ } else {
+ flags += *includeSearchFlag;
+ }
+ flags += lg->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
+ flags += " ";
+ }
+ }
+ return flags;
+}
+
void cmLocalGenerator::GetTargetDefines(cmGeneratorTarget const* target,
std::string const& config,
std::string const& lang,
@@ -2722,10 +2770,10 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
if (editAndContinueDebugInfo || msvc2008OrLess) {
- this->CopyPchCompilePdb(config, target, *ReuseFrom,
+ this->CopyPchCompilePdb(config, lang, target, *ReuseFrom,
reuseTarget, { ".pdb", ".idb" });
} else if (programDatabaseDebugInfo) {
- this->CopyPchCompilePdb(config, target, *ReuseFrom,
+ this->CopyPchCompilePdb(config, lang, target, *ReuseFrom,
reuseTarget, { ".pdb" });
}
}
@@ -2782,9 +2830,9 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
void cmLocalGenerator::CopyPchCompilePdb(
- const std::string& config, cmGeneratorTarget* target,
- const std::string& ReuseFrom, cmGeneratorTarget* reuseTarget,
- const std::vector<std::string>& extensions)
+ const std::string& config, const std::string& language,
+ cmGeneratorTarget* target, const std::string& ReuseFrom,
+ cmGeneratorTarget* reuseTarget, const std::vector<std::string>& extensions)
{
const std::string pdb_prefix =
this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, "/") : "";
@@ -2868,6 +2916,7 @@ void cmLocalGenerator::CopyPchCompilePdb(
cc->SetCommandLines(commandLines);
cc->SetComment(no_message);
cc->SetStdPipesUTF8(true);
+ cc->AppendDepends({ reuseTarget->GetPchFile(config, language) });
if (this->GetGlobalGenerator()->IsVisualStudio()) {
cc->SetByproducts(outputs);
@@ -2974,13 +3023,11 @@ void cmLocalGenerator::WriteUnitySourceInclude(
} else {
pathToHash = "ABS_" + sf_full_path;
}
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
unity_file << "/* " << pathToHash << " */\n"
<< "#undef " << *uniqueIdName << "\n"
<< "#define " << *uniqueIdName << " unity_"
-#ifndef CMAKE_BOOTSTRAP
- << cmSystemTools::ComputeStringMD5(pathToHash) << "\n"
-#endif
- ;
+ << hasher.HashString(pathToHash) << "\n";
}
if (beforeInclude) {
@@ -3648,9 +3695,9 @@ void cmLocalGenerator::GenerateTargetInstallRules(
}
}
-#if defined(CM_LG_ENCODE_OBJECT_NAMES)
-static bool cmLocalGeneratorShortenObjectName(std::string& objName,
- std::string::size_type max_len)
+namespace {
+bool cmLocalGeneratorShortenObjectName(std::string& objName,
+ std::string::size_type max_len)
{
// Check if the path can be shortened using an md5 sum replacement for
// a portion of the path.
@@ -3694,7 +3741,7 @@ bool cmLocalGeneratorCheckObjectName(std::string& objName,
// already too deep.
return false;
}
-#endif
+}
std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(
const std::string& sin, std::string const& dir_max)
@@ -3744,7 +3791,6 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(
} while (!done);
}
-#if defined(CM_LG_ENCODE_OBJECT_NAMES)
if (!cmLocalGeneratorCheckObjectName(ssin, dir_max.size(),
this->ObjectPathMax)) {
// Warn if this is the first time the path has been seen.
@@ -3765,9 +3811,6 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(
this->IssueMessage(MessageType::WARNING, m.str());
}
}
-#else
- (void)dir_max;
-#endif
// Insert the newly mapped object file name.
std::map<std::string, std::string>::value_type e(sin, ssin);
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index c811408..a920cfe 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -19,8 +19,9 @@
#include <cm3p/kwiml/int.h>
#include "cmCustomCommandTypes.h"
+#include "cmGeneratorTarget.h"
#include "cmListFileCache.h"
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmStateSnapshot.h"
@@ -31,7 +32,6 @@ class cmComputeLinkInformation;
class cmCustomCommand;
class cmCustomCommandGenerator;
class cmCustomCommandLines;
-class cmGeneratorTarget;
class cmGlobalGenerator;
class cmImplicitDependsList;
class cmLinkLineComputer;
@@ -520,6 +520,9 @@ public:
std::string GetFrameworkFlags(std::string const& l,
std::string const& config,
cmGeneratorTarget* target);
+ std::string GetXcFrameworkFlags(std::string const& l,
+ std::string const& config,
+ cmGeneratorTarget* target);
virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
std::string const& config);
@@ -646,7 +649,9 @@ private:
bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs,
cmValue sysroot);
- void CopyPchCompilePdb(const std::string& config, cmGeneratorTarget* target,
+ void CopyPchCompilePdb(const std::string& config,
+ const std::string& language,
+ cmGeneratorTarget* target,
const std::string& ReuseFrom,
cmGeneratorTarget* reuseTarget,
std::vector<std::string> const& extensions);
@@ -698,12 +703,6 @@ private:
std::string const& filename_base);
};
-#if !defined(CMAKE_BOOTSTRAP)
-bool cmLocalGeneratorCheckObjectName(std::string& objName,
- std::string::size_type dir_len,
- std::string::size_type max_total_len);
-#endif
-
namespace detail {
void AddCustomCommandToTarget(cmLocalGenerator& lg, cmCommandOrigin origin,
cmTarget* target, cmCustomCommandType type,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 4b0604c..bc3da6e 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -14,6 +14,8 @@
#include "cmsys/FStream.hxx"
+#include "cm_codecvt_Encoding.hxx"
+
#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -536,13 +538,14 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
std::ostringstream cmd;
#ifdef _WIN32
+ cmGlobalNinjaGenerator const* gg = this->GetGlobalNinjaGenerator();
bool const needCMD =
cmdLines.size() > 1 || (customStep.empty() && RuleNeedsCMD(cmdLines[0]));
for (auto li = cmdLines.begin(); li != cmdLines.end(); ++li) {
if (li != cmdLines.begin()) {
cmd << " && ";
} else if (needCMD) {
- cmd << "cmd.exe /C \"";
+ cmd << gg->GetComspec() << " /C \"";
}
// Put current cmdLine in brackets if it contains "||" because it has
// higher precedence than "&&" in cmd.exe
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 3c6b303..e26a6ea 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1080,6 +1080,15 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// Setup the proper working directory for the commands.
this->CreateCDCommand(commands1, dir, relative);
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+
+ // Prefix the commands with the jobserver prefix "+"
+ if (ccg.GetCC().GetJobserverAware() && gg->IsGNUMakeJobServerAware()) {
+ std::transform(commands1.begin(), commands1.end(), commands1.begin(),
+ [](std::string const& cmd) { return cmStrCat("+", cmd); });
+ }
+
// push back the custom commands
cm::append(commands, commands1);
}
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 8fe6677..165f0fd 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio10Generator.h"
+#include <cmext/string_view>
+
#include <cm3p/expat.h>
#include "cmGlobalGenerator.h"
@@ -37,7 +39,7 @@ public:
if (!this->GUID.empty()) {
return;
}
- if ("ProjectGUID" == name || "ProjectGuid" == name) {
+ if (name == "ProjectGUID"_s || name == "ProjectGuid"_s) {
this->DoGUID = true;
}
}
@@ -93,7 +95,7 @@ void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
// save the GUID in the cache
this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
- guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL);
+ guidStoreName, parser.GUID, "Stored GUID", cmStateEnums::INTERNAL);
}
const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index af0e118..7b02c56 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -198,7 +198,7 @@ void cmLocalVisualStudio7Generator::GenerateTarget(cmGeneratorTarget* target)
// Intel Fortran always uses VS9 format ".vfproj" files.
cmGlobalVisualStudioGenerator::VSVersion realVersion = gg->GetVersion();
if (this->FortranProject &&
- gg->GetVersion() >= cmGlobalVisualStudioGenerator::VSVersion::VS11) {
+ gg->GetVersion() >= cmGlobalVisualStudioGenerator::VSVersion::VS12) {
gg->SetVersion(cmGlobalVisualStudioGenerator::VSVersion::VS9);
}
@@ -283,7 +283,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
file->ResolveFullPath();
return file;
}
- cmSystemTools::Error("Error adding rule for " + makefileIn);
+ cmSystemTools::Error(cmStrCat("Error adding rule for ", makefileIn));
return nullptr;
}
@@ -673,8 +673,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
: target->GetLinkerLanguage(configName));
if (linkLanguage.empty()) {
cmSystemTools::Error(
- "CMake can not determine linker language for target: " +
- target->GetName());
+ cmStrCat("CMake can not determine linker language for target: ",
+ target->GetName()));
return;
}
langForClCompile = linkLanguage;
@@ -961,7 +961,7 @@ std::string cmLocalVisualStudio7Generator::GetBuildTypeLinkerFlags(
{
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string extraLinkOptionsBuildTypeDef =
- rootLinkerFlags + "_" + configTypeUpper;
+ cmStrCat(rootLinkerFlags, '_', configTypeUpper);
const std::string& extraLinkOptionsBuildType =
this->Makefile->GetRequiredDefinition(extraLinkOptionsBuildTypeDef);
@@ -978,31 +978,31 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
std::string temp;
std::string extraLinkOptions;
if (target->GetType() == cmStateEnums::EXECUTABLE) {
- extraLinkOptions =
- this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS") + " " +
- GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName);
+ extraLinkOptions = cmStrCat(
+ this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS"), ' ',
+ GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName));
}
if (target->GetType() == cmStateEnums::SHARED_LIBRARY) {
- extraLinkOptions =
- this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS") +
- " " + GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName);
+ extraLinkOptions = cmStrCat(
+ this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS"), ' ',
+ GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName));
}
if (target->GetType() == cmStateEnums::MODULE_LIBRARY) {
- extraLinkOptions =
- this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS") +
- " " + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
+ extraLinkOptions = cmStrCat(
+ this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS"), ' ',
+ GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName));
}
cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- extraLinkOptions += " ";
+ extraLinkOptions += ' ';
extraLinkOptions += *targetLinkFlags;
}
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
targetLinkFlags = target->GetProperty(linkFlagsConfig);
if (targetLinkFlags) {
- extraLinkOptions += " ";
+ extraLinkOptions += ' ';
extraLinkOptions += *targetLinkFlags;
}
@@ -1285,7 +1285,8 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
<< "\"/>\n";
if (dir) {
- std::string const exe = *dir + "\\" + target->GetFullName(config);
+ std::string const exe =
+ cmStrCat(*dir, '\\', target->GetFullName(config));
fout << "\t\t\t<DebuggerTool\n"
"\t\t\t\tRemoteExecutable=\""
@@ -1317,7 +1318,8 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
fout << (lib.HasFeature() ? lib.GetFormattedItem(rel).Value : rel)
<< " ";
} else if (!lib.Target ||
- lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ (lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ lib.Target->GetType() != cmStateEnums::OBJECT_LIBRARY)) {
fout << lib.Value.Value << " ";
}
}
@@ -1369,8 +1371,9 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
// First search a configuration-specific subdirectory and then the
// original directory.
fout << comma
- << this->ConvertToXMLOutputPath(dir + "/$(ConfigurationName)") << ","
- << this->ConvertToXMLOutputPath(dir);
+ << this->ConvertToXMLOutputPath(
+ cmStrCat(dir, "/$(ConfigurationName)"))
+ << ',' << this->ConvertToXMLOutputPath(dir);
comma = ",";
}
}
@@ -1550,11 +1553,11 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
switch (cmOutputConverter::GetFortranFormat(
sf.GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:
- fc.CompileFlags = "-fixed " + fc.CompileFlags;
+ fc.CompileFlags = cmStrCat("-fixed ", fc.CompileFlags);
needfc = true;
break;
case cmOutputConverter::FortranFormatFree:
- fc.CompileFlags = "-free " + fc.CompileFlags;
+ fc.CompileFlags = cmStrCat("-free ", fc.CompileFlags);
needfc = true;
break;
default:
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 58d46f1..34b8ae3 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -5,6 +5,7 @@
#include <utility>
#include <cm/memory>
+#include <cmext/string_view>
#include "windows.h"
@@ -204,7 +205,7 @@ std::string cmLocalVisualStudioGenerator::ConstructScript(
std::string suffix;
if (cmd.size() > 4) {
suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4));
- if (suffix == ".bat" || suffix == ".cmd") {
+ if (suffix == ".bat"_s || suffix == ".cmd"_s) {
script += "call ";
}
}
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 759ee7b..9646e66 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -31,7 +31,7 @@ std::string cmLocalXCodeGenerator::GetTargetDirectory(
cmGeneratorTarget const*) const
{
// No per-target directory for this generator (yet).
- return "";
+ return std::string{};
}
void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,
@@ -83,6 +83,12 @@ void cmLocalXCodeGenerator::AddGeneratorSpecificInstallSetup(std::ostream& os)
case cmMakefile::AppleSDK::WatchSimulator:
platformName = "watchsimulator";
break;
+ case cmMakefile::AppleSDK::XROS:
+ platformName = "xros";
+ break;
+ case cmMakefile::AppleSDK::XRSimulator:
+ platformName = "xrsimulator";
+ break;
case cmMakefile::AppleSDK::MacOS:
break;
}
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index 4fcaedf..91a7b84 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -69,7 +69,7 @@ bool read(cmsys::ifstream& fin, std::vector<T>& v)
return true;
}
return static_cast<bool>(
- fin.read(reinterpret_cast<char*>(&v[0]), sizeof(T) * v.size()));
+ fin.read(reinterpret_cast<char*>(v.data()), sizeof(T) * v.size()));
}
}
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 47ad749..3d7cd8b 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -12,6 +12,7 @@
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
@@ -66,8 +67,9 @@ bool cmMacroHelperCommand::operator()(
std::string argcDef = std::to_string(expandedArgs.size());
auto eit = expandedArgs.begin() + (this->Args.size() - 1);
- std::string expandedArgn = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
- std::string expandedArgv = cmJoin(expandedArgs, ";");
+ std::string expandedArgn =
+ cmList::to_string(cmMakeRange(eit, expandedArgs.end()));
+ std::string expandedArgv = cmList::to_string(expandedArgs);
std::vector<std::string> variables;
variables.reserve(this->Args.size() - 1);
for (unsigned int j = 1; j < this->Args.size(); ++j) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 0af0ed0..80f8a77 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -32,6 +32,7 @@
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
+#include "cmCustomCommandTypes.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h" // IWYU pragma: keep
#include "cmExportBuildFileGenerator.h"
@@ -515,7 +516,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
if (!hadNestedError) {
// The command invocation requested that we report an error.
std::string const error =
- std::string(lff.OriginalName()) + " " + status.GetError();
+ cmStrCat(lff.OriginalName(), ' ', status.GetError());
this->IssueMessage(MessageType::FATAL_ERROR, error);
}
result = false;
@@ -1756,7 +1757,7 @@ void cmMakefile::Configure()
bool hasVersion = false;
// search for the right policy command
for (cmListFileFunction const& func : listFile.Functions) {
- if (func.LowerCaseName() == "cmake_minimum_required") {
+ if (func.LowerCaseName() == "cmake_minimum_required"_s) {
hasVersion = true;
break;
}
@@ -1803,7 +1804,7 @@ void cmMakefile::Configure()
bool hasProject = false;
// search for a project command
for (cmListFileFunction const& func : listFile.Functions) {
- if (func.LowerCaseName() == "project") {
+ if (func.LowerCaseName() == "project"_s) {
hasProject = true;
break;
}
@@ -1860,7 +1861,8 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf)
cmSystemTools::Message(msg);
}
- std::string const currentStartFile = currentStart + "/CMakeLists.txt";
+ std::string const currentStartFile =
+ cmStrCat(currentStart, "/CMakeLists.txt");
if (!cmSystemTools::FileExists(currentStartFile, true)) {
// The file is missing. Check policy CMP0014.
std::ostringstream e;
@@ -1980,7 +1982,7 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string>& incs,
return;
}
- std::string entryString = cmJoin(incs, ";");
+ std::string entryString = cmList::to_string(incs);
if (before) {
this->StateSnapshot.GetDirectory().PrependIncludeDirectoriesEntry(
BT<std::string>(entryString, this->Backtrace));
@@ -2149,11 +2151,11 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
std::string libraryName = *j;
cmTargetLinkLibraryType libType = GENERAL_LibraryType;
- if (libraryName == "optimized") {
+ if (libraryName == "optimized"_s) {
libType = OPTIMIZED_LibraryType;
++j;
libraryName = *j;
- } else if (libraryName == "debug") {
+ } else if (libraryName == "debug"_s) {
libType = DEBUG_LibraryType;
++j;
libraryName = *j;
@@ -2520,7 +2522,7 @@ bool cmMakefile::IsSet(const std::string& name) const
bool cmMakefile::PlatformIs32Bit() const
{
if (cmValue plat_abi = this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) {
- if (*plat_abi == "ELF X32") {
+ if (*plat_abi == "ELF X32"_s) {
return false;
}
}
@@ -2541,7 +2543,7 @@ bool cmMakefile::PlatformIs64Bit() const
bool cmMakefile::PlatformIsx32() const
{
if (cmValue plat_abi = this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) {
- if (*plat_abi == "ELF X32") {
+ if (*plat_abi == "ELF X32"_s) {
return true;
}
}
@@ -2565,11 +2567,13 @@ cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const
{ "iphonesimulator", AppleSDK::IPhoneSimulator },
{ "watchos", AppleSDK::WatchOS },
{ "watchsimulator", AppleSDK::WatchSimulator },
+ { "xros", AppleSDK::XROS },
+ { "xrsimulator", AppleSDK::XRSimulator },
};
for (auto const& entry : sdkDatabase) {
if (cmHasPrefix(sdkRoot, entry.name) ||
- sdkRoot.find(std::string("/") + entry.name) != std::string::npos) {
+ sdkRoot.find(cmStrCat('/', entry.name)) != std::string::npos) {
return entry.sdk;
}
}
@@ -2582,6 +2586,17 @@ bool cmMakefile::PlatformIsAppleEmbedded() const
return this->GetAppleSDKType() != AppleSDK::MacOS;
}
+bool cmMakefile::PlatformIsAppleSimulator() const
+{
+ return std::set<AppleSDK>{
+ AppleSDK::AppleTVSimulator,
+ AppleSDK::IPhoneSimulator,
+ AppleSDK::WatchSimulator,
+ AppleSDK::XRSimulator,
+ }
+ .count(this->GetAppleSDKType());
+}
+
bool cmMakefile::PlatformSupportsAppleTextStubs() const
{
return this->IsOn("APPLE") && this->IsSet("CMAKE_TAPI");
@@ -3004,12 +3019,11 @@ cm::optional<std::string> cmMakefile::DeferGetCallIds() const
{
cm::optional<std::string> ids;
if (this->Defer) {
- ids = cmJoin(
+ ids = cmList::to_string(
cmMakeRange(this->Defer->Commands)
.filter([](DeferCommand const& dc) -> bool { return !dc.Id.empty(); })
.transform(
- [](DeferCommand const& dc) -> std::string const& { return dc.Id; }),
- ";");
+ [](DeferCommand const& dc) -> std::string const& { return dc.Id; }));
}
return ids;
}
@@ -3152,15 +3166,15 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
char nextc = *next;
if (nextc == 't') {
result.append(last, in - last);
- result.append("\t");
+ result.push_back('\t');
last = next + 1;
} else if (nextc == 'n') {
result.append(last, in - last);
- result.append("\n");
+ result.push_back('\n');
last = next + 1;
} else if (nextc == 'r') {
result.append(last, in - last);
- result.append("\r");
+ result.push_back('\r');
last = next + 1;
} else if (nextc == ';' && openstack.empty()) {
// Handled in ExpandListArgument; pass the backslash literally.
@@ -3237,9 +3251,9 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
errorstr += "Invalid character (\'";
errorstr += inc;
result.append(last, in - last);
- errorstr += "\') in a variable name: "
- "'" +
- result.substr(openstack.back().loc) + "'";
+ errorstr += cmStrCat("\') in a variable name: "
+ "'",
+ result.substr(openstack.back().loc), '\'');
mtype = MessageType::FATAL_ERROR;
error = true;
}
@@ -3646,13 +3660,13 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const& languages,
}
}
if (!duplicate_languages.empty()) {
- auto quantity = duplicate_languages.size() == 1 ? std::string(" has")
- : std::string("s have");
- this->IssueMessage(MessageType::AUTHOR_WARNING,
- "Languages to be enabled may not be specified more "
- "than once at the same time. The following language" +
- quantity + " been specified multiple times: " +
- cmJoin(duplicate_languages, ", "));
+ auto quantity = duplicate_languages.size() == 1 ? " has"_s : "s have"_s;
+ this->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("Languages to be enabled may not be specified more "
+ "than once at the same time. The following language",
+ quantity, " been specified multiple times: ",
+ cmJoin(duplicate_languages, ", ")));
}
}
@@ -3663,7 +3677,7 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const& languages,
std::vector<std::string> languages_for_RC;
languages_without_RC.reserve(unique_languages.size());
for (std::string const& language : unique_languages) {
- if (language == "RC") {
+ if (language == "RC"_s) {
languages_for_RC.push_back(language);
} else {
languages_without_RC.push_back(language);
@@ -3697,8 +3711,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cmWorkingDirectory workdir(bindir);
if (workdir.Failed()) {
this->IssueMessage(MessageType::FATAL_ERROR,
- "Failed to set working directory to " + bindir + " : " +
- std::strerror(workdir.GetLastResult()));
+ cmStrCat("Failed to set working directory to ", bindir,
+ " : ",
+ std::strerror(workdir.GetLastResult())));
cmSystemTools::SetFatalErrorOccurred();
this->IsSourceFileTryCompile = false;
return 1;
@@ -3926,7 +3941,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
if (!moduleInCMakeModulePath.empty() && !moduleInCMakeRoot.empty()) {
cmValue currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE");
- std::string mods = cmSystemTools::GetCMakeRoot() + "/Modules/";
+ std::string mods = cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/");
if (currentFile && cmSystemTools::IsSubDirectory(*currentFile, mods)) {
switch (this->GetPolicyStatus(cmPolicies::CMP0017)) {
case cmPolicies::WARN: {
@@ -3985,8 +4000,9 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output,
cmValue def = this->GetDefinition(this->cmDefineRegex.match(2));
if (!cmIsOff(def)) {
const std::string indentation = this->cmDefineRegex.match(1);
- cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine",
- "#" + indentation + "define");
+ cmSystemTools::ReplaceString(line,
+ cmStrCat("#", indentation, "cmakedefine"),
+ cmStrCat("#", indentation, "define"));
output += line;
} else {
output += "/* #undef ";
@@ -3996,8 +4012,9 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output,
} else if (this->cmDefine01Regex.find(line)) {
const std::string indentation = this->cmDefine01Regex.match(1);
cmValue def = this->GetDefinition(this->cmDefine01Regex.match(2));
- cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine01",
- "#" + indentation + "define");
+ cmSystemTools::ReplaceString(line,
+ cmStrCat("#", indentation, "cmakedefine01"),
+ cmStrCat("#", indentation, "define"));
output += line;
if (!cmIsOff(def)) {
output += " 1";
@@ -4035,12 +4052,12 @@ int cmMakefile::ConfigureFile(const std::string& infile,
{
int res = 1;
if (!this->CanIWriteThisFile(outfile)) {
- cmSystemTools::Error("Attempt to write file: " + outfile +
- " into a source directory.");
+ cmSystemTools::Error(cmStrCat("Attempt to write file: ", outfile,
+ " into a source directory."));
return 0;
}
if (!cmSystemTools::FileExists(infile)) {
- cmSystemTools::Error("File " + infile + " does not exist.");
+ cmSystemTools::Error(cmStrCat("File ", infile, " does not exist."));
return 0;
}
std::string soutfile = outfile;
@@ -4153,14 +4170,14 @@ cmValue cmMakefile::GetProperty(const std::string& prop) const
{
// Check for computed properties.
static std::string output;
- if (prop == "TESTS") {
+ if (prop == "TESTS"_s) {
std::vector<std::string> keys;
// get list of keys
const auto* t = this;
std::transform(
t->Tests.begin(), t->Tests.end(), std::back_inserter(keys),
[](decltype(t->Tests)::value_type const& pair) { return pair.first; });
- output = cmJoin(keys, ";");
+ output = cmList::to_string(keys);
return cmValue(output);
}
@@ -4613,7 +4630,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
}
// Deprecate old policies.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0114 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0120 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 7005942..24daa72 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -25,9 +25,9 @@
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
-#include "cmCustomCommandTypes.h"
+#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
#include "cmNewLineStyle.h"
#include "cmPolicies.h"
#include "cmSourceFileLocationKind.h"
@@ -43,12 +43,14 @@
# include "cmSourceGroup.h"
#endif
+enum class cmCustomCommandType;
+enum class cmObjectLibraryCommands;
+
class cmCompiledGeneratorExpression;
class cmCustomCommandLines;
class cmExecutionStatus;
class cmExpandedCommandArgument;
class cmExportBuildFileGenerator;
-class cmFunctionBlocker;
class cmGeneratorExpressionEvaluationFile;
class cmGlobalGenerator;
class cmInstallGenerator;
@@ -561,6 +563,8 @@ public:
AppleTVSimulator,
WatchOS,
WatchSimulator,
+ XROS,
+ XRSimulator,
};
/** What SDK type points CMAKE_OSX_SYSROOT to? */
@@ -569,6 +573,9 @@ public:
/** Return whether the target platform is Apple iOS. */
bool PlatformIsAppleEmbedded() const;
+ /** Return whether the target platform is an Apple simulator. */
+ bool PlatformIsAppleSimulator() const;
+
/** Return whether the target platform supports generation of text base stubs
(.tbd file) describing exports (Apple specific). */
bool PlatformSupportsAppleTextStubs() const;
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
index e903ae1..9387582 100644
--- a/Source/cmMakefileProfilingData.cxx
+++ b/Source/cmMakefileProfilingData.cxx
@@ -4,7 +4,6 @@
#include <chrono>
#include <stdexcept>
-#include <type_traits>
#include <utility>
#include <cm3p/json/value.h>
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 5f27856..caa5e67 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -17,7 +17,7 @@
#include <cmext/algorithm>
#include <cmext/string_view>
-#include "cm_codecvt.hxx"
+#include "cm_codecvt_Encoding.hxx"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
@@ -126,8 +126,11 @@ void cmMakefileTargetGenerator::GetDeviceLinkFlags(
std::vector<std::string> linkOpts;
this->GeneratorTarget->GetLinkOptions(linkOpts, this->GetConfigName(),
linkLanguage);
+ this->LocalGenerator->SetLinkScriptShell(
+ this->GlobalGenerator->GetUseLinkScript());
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+ this->LocalGenerator->SetLinkScriptShell(false);
}
void cmMakefileTargetGenerator::GetTargetLinkFlags(
@@ -144,8 +147,11 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
std::vector<std::string> opts;
this->GeneratorTarget->GetLinkOptions(opts, this->GetConfigName(),
linkLanguage);
+ this->LocalGenerator->SetLinkScriptShell(
+ this->GlobalGenerator->GetUseLinkScript());
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(flags, opts);
+ this->LocalGenerator->SetLinkScriptShell(false);
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
@@ -201,9 +207,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("The \"", this->GeneratorTarget->GetName(),
- "\" target contains C++ module sources which are not supported "
- "by the generator"));
+ cmStrCat("The target named \"", this->GeneratorTarget->GetName(),
+ "\" contains C++ sources that export modules which is not "
+ "supported by the generator"));
}
// -- Write the custom commands for this target
@@ -2129,12 +2135,12 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
// FIXME: Find a better way to determine the response file encoding,
// perhaps using tool-specific platform information variables.
// For now, use the makefile encoding as a heuristic.
- codecvt::Encoding responseEncoding =
+ codecvt_Encoding responseEncoding =
this->GlobalGenerator->GetMakefileEncoding();
// Non-MSVC tooling doesn't understand BOM encoded files.
- if (responseEncoding == codecvt::UTF8_WITH_BOM &&
+ if (responseEncoding == codecvt_Encoding::UTF8_WITH_BOM &&
(language == "CUDA" || !this->Makefile->IsOn("MSVC"))) {
- responseEncoding = codecvt::UTF8;
+ responseEncoding = codecvt_Encoding::UTF8;
}
// Create the response file.
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index 4e975d1..b4ea71c 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -4,6 +4,7 @@
#include "cmDocumentationFormatter.h"
#include "cmMessageMetadata.h"
+#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
diff --git a/Source/cmMessenger.h b/Source/cmMessenger.h
index bdefb00..d9462d4 100644
--- a/Source/cmMessenger.h
+++ b/Source/cmMessenger.h
@@ -11,7 +11,7 @@
#include <cm/optional>
#include "cmListFileCache.h"
-#include "cmMessageType.h"
+#include "cmMessageType.h" // IWYU pragma: keep
#ifdef CMake_ENABLE_DEBUGGER
namespace cmDebugger {
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 063ca6b..48c30b6 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
#include <iterator>
-#include <map>
#include <set>
#include <sstream>
#include <unordered_set>
@@ -63,12 +62,15 @@ cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
{
- std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
- if (this->TargetLinkLanguage(config).empty()) {
- cmSystemTools::Error(
- cmStrCat("CMake can not determine linker language for target: ",
- this->GetGeneratorTarget()->GetName()));
- return;
+ if (this->GetGeneratorTarget()->GetType() !=
+ cmStateEnums::INTERFACE_LIBRARY) {
+ std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
+ if (this->TargetLinkLanguage(config).empty()) {
+ cmSystemTools::Error(
+ cmStrCat("CMake can not determine linker language for target: ",
+ this->GetGeneratorTarget()->GetName()));
+ return;
+ }
}
// Write the rules for each language.
@@ -88,6 +90,34 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
this->WriteObjectLibStatement(config);
+ } else if (this->GetGeneratorTarget()->GetType() ==
+ cmStateEnums::INTERFACE_LIBRARY) {
+ bool haveCxxModuleSources = false;
+ if (this->GetGeneratorTarget()->HaveCxx20ModuleSources()) {
+ haveCxxModuleSources = true;
+ }
+
+ if (!haveCxxModuleSources) {
+ cmSystemTools::Error(cmStrCat(
+ "Ninja does not support INTERFACE libraries without C++ module "
+ "sources as a normal target: ",
+ this->GetGeneratorTarget()->GetName()));
+ return;
+ }
+
+ firstForConfig = true;
+ for (auto const& fileConfig : this->GetConfigNames()) {
+ if (!this->GetGlobalGenerator()
+ ->GetCrossConfigs(fileConfig)
+ .count(config)) {
+ continue;
+ }
+ if (haveCxxModuleSources) {
+ this->WriteCxxModuleLibraryStatement(config, fileConfig,
+ firstForConfig);
+ }
+ firstForConfig = false;
+ }
} else {
firstForConfig = true;
for (auto const& fileConfig : this->GetConfigNames()) {
@@ -124,12 +154,26 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
#endif
// Write rules for languages compiled in this target.
- std::set<std::string> languages;
- std::vector<cmSourceFile const*> sourceFiles;
- this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
- if (this->HaveRequiredLanguages(sourceFiles, languages)) {
- for (std::string const& language : languages) {
- this->WriteLanguageRules(language, config);
+ {
+ std::set<std::string> languages;
+ std::vector<cmSourceFile const*> sourceFiles;
+ this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
+ if (this->HaveRequiredLanguages(sourceFiles, languages)) {
+ for (std::string const& language : languages) {
+ this->WriteLanguageRules(language, config);
+ }
+ }
+ }
+
+ // Write rules for languages in BMI-only rules.
+ {
+ std::set<std::string> languages;
+ std::vector<cmSourceFile const*> sourceFiles;
+ this->GetGeneratorTarget()->GetCxxModuleSources(sourceFiles, config);
+ if (this->HaveRequiredLanguages(sourceFiles, languages)) {
+ for (std::string const& language : languages) {
+ this->WriteLanguageRules(language, config);
+ }
}
}
}
@@ -952,8 +996,6 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
- vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
-
vars["MANIFESTS"] = this->GetManifests(config);
vars["LINK_PATH"] = frameworkPath + linkPath;
@@ -1271,8 +1313,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
vars["LINK_FLAGS"], this->GetGeneratorTarget(),
this->TargetLinkLanguage(config));
- vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
-
vars["MANIFESTS"] = this->GetManifests(config);
vars["AIX_EXPORTS"] = this->GetAIXExports(config);
@@ -1474,9 +1514,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
gt, linkBuild.OrderOnlyDeps, config, fileConfig, DependOnTargetArtifact);
// Add order-only dependencies on versioning symlinks of shared libs we link.
- if (!this->GeneratorTarget->IsDLLPlatform()) {
- if (cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(config)) {
+ // If our target is not producing a runtime binary, it doesn't need the
+ // symlinks (anything that links to the target might, but that consumer will
+ // get its own order-only dependency).
+ if (!gt->IsDLLPlatform() && gt->IsRuntimeBinary()) {
+ if (cmComputeLinkInformation* cli = gt->GetLinkInformation(config)) {
for (auto const& item : cli->GetItems()) {
if (item.Target &&
item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
@@ -1640,6 +1682,34 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
this->GetTargetName(), this->GetGeneratorTarget(), config);
}
+void cmNinjaNormalTargetGenerator::WriteCxxModuleLibraryStatement(
+ const std::string& config, const std::string& /*fileConfig*/,
+ bool firstForConfig)
+{
+ // TODO: How to use `fileConfig` properly?
+
+ // Write a phony output that depends on the scanning output.
+ {
+ cmNinjaBuild build("phony");
+ build.Comment =
+ cmStrCat("Imported C++ module library ", this->GetTargetName());
+ this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
+ build.Outputs, config);
+ if (firstForConfig) {
+ this->GetLocalGenerator()->AppendTargetOutputs(
+ this->GetGeneratorTarget(),
+ this->GetGlobalGenerator()->GetByproductsForCleanTarget(config),
+ config);
+ }
+ build.ExplicitDeps.emplace_back(this->GetDyndepFilePath("CXX", config));
+ this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), build);
+ }
+
+ // Add aliases for the target name.
+ this->GetGlobalGenerator()->AddTargetAlias(
+ this->GetTargetName(), this->GetGeneratorTarget(), config);
+}
+
cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames(
const std::string& config) const
{
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 187ea46..3ef0230 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -49,6 +49,9 @@ private:
const std::string& output);
void WriteObjectLibStatement(const std::string& config);
+ void WriteCxxModuleLibraryStatement(const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
std::vector<std::string> ComputeLinkCmd(const std::string& config);
std::vector<std::string> ComputeDeviceLinkCmd();
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index d712d71..09f8495 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -9,7 +9,6 @@
#include <iterator>
#include <map>
#include <ostream>
-#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
@@ -29,6 +28,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmList.h"
#include "cmLocalGenerator.h"
@@ -60,8 +60,13 @@ std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New(
case cmStateEnums::OBJECT_LIBRARY:
return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
- case cmStateEnums::UTILITY:
case cmStateEnums::INTERFACE_LIBRARY:
+ if (target->HaveCxx20ModuleSources()) {
+ return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
+ }
+ CM_FALLTHROUGH;
+
+ case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
@@ -168,7 +173,7 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
// Refactor it.
std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
cmSourceFile const* source, const std::string& language,
- const std::string& config)
+ const std::string& config, const std::string& objectFileName)
{
std::unordered_map<std::string, std::string> pchSources;
std::vector<std::string> architectures =
@@ -248,6 +253,18 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
"\nin a file set of type \"", fs->GetType(),
R"(" but the source is not classified as a "CXX" source.)"));
}
+
+ if (!this->GeneratorTarget->Target->IsNormal()) {
+ auto flag = this->GetMakefile()->GetSafeDefinition(
+ "CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG");
+ cmRulePlaceholderExpander::RuleVariables compileObjectVars;
+ compileObjectVars.Object = objectFileName.c_str();
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
+ rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
+ flag, compileObjectVars);
+ this->LocalGenerator->AppendCompileOptions(flags, flag);
+ }
}
return flags;
@@ -395,6 +412,31 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
return path;
}
+std::string cmNinjaTargetGenerator::GetBmiFilePath(
+ cmSourceFile const* source, const std::string& config) const
+{
+ std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
+ if (!path.empty()) {
+ path += '/';
+ }
+
+ auto& importedConfigInfo = this->Configs.at(config).ImportedCxxModules;
+ if (!importedConfigInfo.Initialized()) {
+ std::string configUpper = cmSystemTools::UpperCase(config);
+ std::string propName = cmStrCat("IMPORTED_CXX_MODULES_", configUpper);
+ auto value = this->GeneratorTarget->GetSafeProperty(propName);
+ importedConfigInfo.Initialize(value);
+ }
+
+ std::string bmiName =
+ importedConfigInfo.BmiNameForSource(source->GetFullPath());
+
+ path += cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', bmiName);
+ return path;
+}
+
std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
std::string const& directory, cmSourceFile const& source,
std::string const& config) const
@@ -1028,6 +1070,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
}
+ {
+ std::vector<cmSourceFile const*> bmiOnlySources;
+ this->GeneratorTarget->GetCxxModuleSources(bmiOnlySources, config);
+
+ for (cmSourceFile const* sf : bmiOnlySources) {
+ this->WriteCxxModuleBmiBuildStatement(sf, config, fileConfig,
+ firstForConfig);
+ }
+ }
+
for (auto const& langScanningFiles : this->Configs[config].ScanningInfo) {
std::string const& language = langScanningFiles.first;
std::vector<ScanningFiles> const& scanningFiles = langScanningFiles.second;
@@ -1052,7 +1104,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
for (std::string const& l :
this->GetLinkedTargetDirectories(language, config)) {
- build.ImplicitDeps.push_back(cmStrCat(l, '/', language, "Modules.json"));
+ build.ImplicitDeps.emplace_back(
+ cmStrCat(l, '/', language, "Modules.json"));
}
this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
@@ -1149,22 +1202,22 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
scanBuild.Variables["OBJ_FILE"] = objectFileName;
// Tell dependency scanner where to store dyndep intermediate results.
- std::string const& ddiFile = cmStrCat(objectFileName, ".ddi");
- scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
+ std::string ddiFileName = cmStrCat(objectFileName, ".ddi");
+ scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFileName;
// Outputs of the scan/preprocessor build statement.
if (compilePP) {
scanBuild.Outputs.push_back(ppFileName);
- scanBuild.ImplicitOuts.push_back(ddiFile);
+ scanBuild.ImplicitOuts.push_back(ddiFileName);
} else {
- scanBuild.Outputs.push_back(ddiFile);
+ scanBuild.Outputs.push_back(ddiFileName);
scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName;
if (!compilationPreprocesses) {
// Compilation does not preprocess and we are not compiling an
// already-preprocessed source. Make compilation depend on the scan
// results to honor implicit dependencies discovered during scanning
// (such as Fortran INCLUDE directives).
- objBuild.ImplicitDeps.emplace_back(ddiFile);
+ objBuild.ImplicitDeps.emplace_back(ddiFileName);
}
}
@@ -1214,7 +1267,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
cmNinjaBuild objBuild(this->LanguageCompilerRule(
language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
cmNinjaVars& vars = objBuild.Variables;
- vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
+ vars["FLAGS"] =
+ this->ComputeFlagsForObject(source, language, config, objectFileName);
vars["DEFINES"] = this->ComputeDefines(source, language, config);
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
@@ -1545,6 +1599,155 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
}
+void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement(
+ cmSourceFile const* source, const std::string& config,
+ const std::string& fileConfig, bool firstForConfig)
+{
+ std::string const language = source->GetLanguage();
+ if (language != "CXX"_s) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Source file '", source->GetFullPath(), "' of target '",
+ this->GetTargetName(), "' is a '", language,
+ "' source but must be 'CXX' in order to have a BMI build "
+ "statement generated."));
+ return;
+ }
+
+ std::string const sourceFilePath = this->GetCompiledSourceNinjaPath(source);
+ std::string const bmiDir = this->ConvertToNinjaPath(
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
+ this->GetGlobalGenerator()->ConfigDirectory(config)));
+ std::string const bmiFileName =
+ this->ConvertToNinjaPath(this->GetBmiFilePath(source, config));
+ std::string const bmiFileDir = cmSystemTools::GetFilenamePath(bmiFileName);
+
+ int const commandLineLengthLimit = this->ForceResponseFile() ? -1 : 0;
+
+ cmNinjaBuild bmiBuild(
+ this->LanguageCompilerRule(language, config, WithScanning::Yes));
+ cmNinjaVars& vars = bmiBuild.Variables;
+ vars["FLAGS"] =
+ this->ComputeFlagsForObject(source, language, config, bmiFileName);
+ vars["DEFINES"] = this->ComputeDefines(source, language, config);
+ vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
+
+ if (this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) {
+ bool replaceExt(false);
+ if (!language.empty()) {
+ std::string repVar =
+ cmStrCat("CMAKE_", language, "_DEPFILE_EXTENSION_REPLACE");
+ replaceExt = this->Makefile->IsOn(repVar);
+ }
+ if (!replaceExt) {
+ // use original code
+ vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmStrCat(bmiFileName, ".d"), cmOutputConverter::SHELL);
+ } else {
+ // Replace the original source file extension with the
+ // depend file extension.
+ std::string dependFileName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(bmiFileName), ".d");
+ vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmStrCat(bmiFileDir, '/', dependFileName), cmOutputConverter::SHELL);
+ }
+ }
+
+ std::string d =
+ this->GeneratorTarget->GetClangTidyExportFixesDirectory(language);
+ if (!d.empty()) {
+ this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d);
+ std::string fixesFile =
+ this->GetClangTidyReplacementsFilePath(d, *source, config);
+ this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
+ cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(fixesFile));
+ fixesFile = this->ConvertToNinjaPath(fixesFile);
+ vars["CLANG_TIDY_EXPORT_FIXES"] = fixesFile;
+ }
+
+ if (firstForConfig) {
+ this->ExportObjectCompileCommand(
+ language, sourceFilePath, bmiDir, bmiFileName, bmiFileDir, vars["FLAGS"],
+ vars["DEFINES"], vars["INCLUDES"], config);
+ }
+
+ bmiBuild.Outputs.push_back(bmiFileName);
+ bmiBuild.ExplicitDeps.push_back(sourceFilePath);
+
+ std::vector<std::string> depList;
+
+ std::vector<std::string> architectures =
+ this->GeneratorTarget->GetAppleArchs(config, language);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ bmiBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config));
+
+ // For some cases we scan to dynamically discover dependencies.
+ std::string modmapFormat;
+ if (true) {
+ std::string const modmapFormatVar =
+ cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
+ modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar);
+ }
+
+ {
+ bool const compilePPWithDefines = this->CompileWithDefines(language);
+
+ std::string scanRuleName = this->LanguageScanRule(language, config);
+ std::string ppFileName = cmStrCat(bmiFileName, ".ddi.i");
+
+ cmNinjaBuild ppBuild = GetScanBuildStatement(
+ scanRuleName, ppFileName, false, compilePPWithDefines, true, bmiBuild,
+ vars, bmiFileName, this->LocalGenerator);
+
+ ScanningFiles scanningFiles;
+
+ if (firstForConfig) {
+ scanningFiles.ScanningOutput = cmStrCat(bmiFileName, ".ddi");
+ }
+
+ this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
+ ppBuild.Variables);
+
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ ppBuild, commandLineLengthLimit);
+
+ std::string const dyndep = this->GetDyndepFilePath(language, config);
+ bmiBuild.OrderOnlyDeps.push_back(dyndep);
+ vars["dyndep"] = dyndep;
+
+ if (!modmapFormat.empty()) {
+ std::string ddModmapFile = cmStrCat(bmiFileName, ".modmap");
+ vars["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile;
+ scanningFiles.ModuleMapFile = std::move(ddModmapFile);
+ }
+
+ if (!scanningFiles.IsEmpty()) {
+ this->Configs[config].ScanningInfo[language].emplace_back(scanningFiles);
+ }
+ }
+
+ this->EnsureParentDirectoryExists(bmiFileName);
+
+ vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ bmiDir, cmOutputConverter::SHELL);
+ vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ bmiFileDir, cmOutputConverter::SHELL);
+
+ this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
+ vars);
+
+ this->SetMsvcTargetPdbVariable(vars, config);
+
+ bmiBuild.RspFile = cmStrCat(bmiFileName, ".rsp");
+
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ bmiBuild, commandLineLengthLimit);
+}
+
void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
const std::string& config)
{
@@ -1605,6 +1808,9 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
return this->GetObjectFilePath(sf, cnf);
};
+ cb.BmiFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
+ return this->GetBmiFilePath(sf, cnf);
+ };
#if !defined(CMAKE_BOOTSTRAP)
cmDyndepCollation::AddCollationInformation(tdi, this->GeneratorTarget,
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 8c38499..49e7018 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -15,6 +15,7 @@
#include "cmCommonTargetGenerator.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmImportedCxxModuleInfo.h"
#include "cmNinjaTypes.h"
#include "cmOSXBundleGenerator.h"
@@ -91,7 +92,8 @@ protected:
*/
std::string ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language,
- const std::string& config);
+ const std::string& config,
+ const std::string& objectFileName);
void AddIncludeFlags(std::string& flags, std::string const& lang,
const std::string& config) override;
@@ -129,6 +131,8 @@ protected:
/// @return the object file path for the given @a source.
std::string GetObjectFilePath(cmSourceFile const* source,
const std::string& config) const;
+ std::string GetBmiFilePath(cmSourceFile const* source,
+ const std::string& config) const;
/// @return the preprocessed source file path for the given @a source.
std::string GetPreprocessedFilePath(cmSourceFile const* source,
@@ -163,6 +167,10 @@ protected:
void WriteObjectBuildStatements(const std::string& config,
const std::string& fileConfig,
bool firstForConfig);
+ void WriteCxxModuleBmiBuildStatement(cmSourceFile const* source,
+ const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
void WriteObjectBuildStatement(cmSourceFile const* source,
const std::string& config,
const std::string& fileConfig,
@@ -239,6 +247,8 @@ private:
cmNinjaDeps Objects;
// Dyndep Support
std::map<std::string, std::vector<ScanningFiles>> ScanningInfo;
+ // Imported C++ module info.
+ mutable ImportedCxxModuleLookup ImportedCxxModules;
// Swift Support
Json::Value SwiftOutputMap;
std::vector<cmCustomCommand const*> CustomCommands;
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 37c4afc..a46c87b 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -6,6 +6,7 @@
#include <cassert>
#include <functional>
#include <sstream>
+#include <type_traits>
#include <vector>
#include <cm/memory>
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 02981ae..9c30d74 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -6,6 +6,7 @@
#include <cassert>
#include <cctype>
#include <set>
+#include <vector>
#ifdef _WIN32
# include <unordered_map>
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index f147ed2..6a9a74c 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -5,6 +5,7 @@
#include <cstdio>
#include <map>
#include <set>
+#include <unordered_map>
#include <utility>
#include <cm/memory>
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index b0462f0..f193ed9 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -20,7 +20,9 @@
#include "cmSystemTools.h"
#include "cmValue.h"
-static std::string EscapeArg(const std::string& arg)
+namespace {
+
+std::string EscapeArg(const std::string& arg)
{
// replace ";" with "\;" so output argument lists will split correctly
std::string escapedArg;
@@ -33,14 +35,12 @@ static std::string EscapeArg(const std::string& arg)
return escapedArg;
}
-static std::string JoinList(std::vector<std::string> const& arg, bool escape)
+std::string JoinList(std::vector<std::string> const& arg, bool escape)
{
- return escape ? cmJoin(cmMakeRange(arg).transform(EscapeArg), ";")
- : cmJoin(cmMakeRange(arg), ";");
+ return escape ? cmList::to_string(cmMakeRange(arg).transform(EscapeArg))
+ : cmList::to_string(cmMakeRange(arg));
}
-namespace {
-
using options_map = std::map<std::string, bool>;
using single_map = std::map<std::string, std::string>;
using multi_map =
@@ -108,8 +108,9 @@ static void PassParsedArguments(
}
if (!keywordsMissingValues.empty()) {
- makefile.AddDefinition(prefix + "KEYWORDS_MISSING_VALUES",
- cmJoin(cmMakeRange(keywordsMissingValues), ";"));
+ makefile.AddDefinition(
+ prefix + "KEYWORDS_MISSING_VALUES",
+ cmList::to_string(cmMakeRange(keywordsMissingValues)));
} else {
makefile.RemoveDefinition(prefix + "KEYWORDS_MISSING_VALUES");
}
diff --git a/Source/cmPlistParser.cxx b/Source/cmPlistParser.cxx
new file mode 100644
index 0000000..ce3c171
--- /dev/null
+++ b/Source/cmPlistParser.cxx
@@ -0,0 +1,33 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmPlistParser.h"
+
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
+
+cm::optional<Json::Value> cmParsePlist(const std::string& filename)
+{
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(
+ { "/usr/bin/plutil", "-convert", "json", "-o", "-", filename });
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+
+ auto chain = builder.Start();
+ chain.Wait();
+
+ auto const& status = chain.GetStatus(0);
+ if (status.ExitStatus != 0) {
+ return cm::nullopt;
+ }
+
+ Json::Reader reader;
+ Json::Value value;
+ cmUVPipeIStream outputStream(chain.GetLoop(), chain.OutputStream());
+ if (!reader.parse(outputStream, value)) {
+ return cm::nullopt;
+ }
+ return cm::optional<Json::Value>(value);
+}
diff --git a/Source/cmPlistParser.h b/Source/cmPlistParser.h
new file mode 100644
index 0000000..2ace254
--- /dev/null
+++ b/Source/cmPlistParser.h
@@ -0,0 +1,13 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <string>
+
+#include <cm/optional>
+
+namespace Json {
+class Value;
+}
+
+cm::optional<Json::Value> cmParsePlist(const std::string& filename);
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index d5e5725..d89c8c8 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -123,23 +123,23 @@ static void DiagnoseAncientPolicies(
{
std::ostringstream e;
e << "The project requests behavior compatible with CMake version \""
- << majorVer << "." << minorVer << "." << patchVer
+ << majorVer << '.' << minorVer << '.' << patchVer
<< "\", which requires the OLD behavior for some policies:\n";
for (cmPolicies::PolicyID i : ancient) {
- e << " " << idToString(i) << ": " << idToShortDescription(i) << "\n";
+ e << " " << idToString(i) << ": " << idToShortDescription(i) << '\n';
}
e << "However, this version of CMake no longer supports the OLD "
- << "behavior for these policies. "
- << "Please either update your CMakeLists.txt files to conform to "
- << "the new behavior or use an older version of CMake that still "
- << "supports the old behavior.";
+ "behavior for these policies. "
+ "Please either update your CMakeLists.txt files to conform to "
+ "the new behavior or use an older version of CMake that still "
+ "supports the old behavior.";
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
static bool GetPolicyDefault(cmMakefile* mf, std::string const& policy,
cmPolicies::PolicyStatus* defaultSetting)
{
- std::string defaultVar = "CMAKE_POLICY_DEFAULT_" + policy;
+ std::string defaultVar = cmStrCat("CMAKE_POLICY_DEFAULT_", policy);
std::string const& defaultValue = mf->GetSafeDefinition(defaultVar);
if (defaultValue == "NEW") {
*defaultSetting = cmPolicies::NEW;
@@ -148,10 +148,10 @@ static bool GetPolicyDefault(cmMakefile* mf, std::string const& policy,
} else if (defaultValue.empty()) {
*defaultSetting = cmPolicies::WARN;
} else {
- std::ostringstream e;
- e << defaultVar << " has value \"" << defaultValue
- << R"(" but must be "OLD", "NEW", or "" (empty).)";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(defaultVar, " has value \"", defaultValue,
+ R"(" but must be "OLD", "NEW", or "" (empty).)"));
return false;
}
@@ -170,10 +170,11 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
unsigned int minTweak = 0;
if (sscanf(version_min.c_str(), "%u.%u.%u.%u", &minMajor, &minMinor,
&minPatch, &minTweak) < 2) {
- std::ostringstream e;
- e << "Invalid policy version value \"" << version_min << "\". "
- << "A numeric major.minor[.patch[.tweak]] must be given.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Invalid policy version value \"", version_min,
+ "\". "
+ "A numeric major.minor[.patch[.tweak]] must be given."));
return false;
}
@@ -199,13 +200,14 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
minMinor == cmVersion::GetMinorVersion() &&
minPatch == cmVersion::GetPatchVersion() &&
minTweak > cmVersion::GetTweakVersion())) {
- std::ostringstream e;
- e << "An attempt was made to set the policy version of CMake to \""
- << version_min << "\" which is greater than this version of CMake. "
- << "This is not allowed because the greater version may have new "
- << "policies not known to this CMake. "
- << "You may need a newer CMake version to build this project.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("An attempt was made to set the policy version of CMake to \"",
+ version_min,
+ "\" which is greater than this version of CMake. ",
+ "This is not allowed because the greater version may have new "
+ "policies not known to this CMake. "
+ "You may need a newer CMake version to build this project."));
return false;
}
@@ -221,10 +223,11 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
unsigned int maxTweak = 0;
if (sscanf(version_max.c_str(), "%u.%u.%u.%u", &maxMajor, &maxMinor,
&maxPatch, &maxTweak) < 2) {
- std::ostringstream e;
- e << "Invalid policy max version value \"" << version_max << "\". "
- << "A numeric major.minor[.patch[.tweak]] must be given.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Invalid policy max version value \"", version_max,
+ "\". "
+ "A numeric major.minor[.patch[.tweak]] must be given."));
return false;
}
@@ -234,11 +237,10 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
minPatch > maxPatch) ||
(minMajor == maxMajor && minMinor == maxMinor &&
minPatch == maxPatch && minTweak > maxTweak)) {
- std::ostringstream e;
- e << "Policy VERSION range \"" << version_min << "..." << version_max
- << "\""
- << " specifies a larger minimum than maximum.";
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Policy VERSION range \"", version_min, "...", version_max,
+ "\" specifies a larger minimum than maximum."));
return false;
}
@@ -328,61 +330,49 @@ bool cmPolicies::GetPolicyID(const char* id, cmPolicies::PolicyID& pid)
//! return a warning string for a given policy
std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id)
{
- std::ostringstream msg;
- msg << "Policy " << idToString(id)
- << " is not set: "
- ""
- << idToShortDescription(id)
- << " "
- "Run \"cmake --help-policy "
- << idToString(id)
- << "\" for "
- "policy details. "
- "Use the cmake_policy command to set the policy "
- "and suppress this warning.";
- return msg.str();
+ return cmStrCat("Policy ", idToString(id),
+ " is not set: ", idToShortDescription(id),
+ " "
+ "Run \"cmake --help-policy ",
+ idToString(id),
+ "\" for "
+ "policy details. "
+ "Use the cmake_policy command to set the policy "
+ "and suppress this warning.");
}
std::string cmPolicies::GetPolicyDeprecatedWarning(cmPolicies::PolicyID id)
{
- std::ostringstream msg;
- /* clang-format off */
- msg <<
- "The OLD behavior for policy " << idToString(id) << " "
+ return cmStrCat(
+ "The OLD behavior for policy ", idToString(id),
+ " "
"will be removed from a future version of CMake.\n"
"The cmake-policies(7) manual explains that the OLD behaviors of all "
"policies are deprecated and that a policy should be set to OLD only "
"under specific short-term circumstances. Projects should be ported "
- "to the NEW behavior and not rely on setting a policy to OLD."
- ;
- /* clang-format on */
- return msg.str();
+ "to the NEW behavior and not rely on setting a policy to OLD.");
}
//! return an error string for when a required policy is unspecified
std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id)
{
- std::ostringstream error;
- error << "Policy " << idToString(id)
- << " is not set to NEW: "
- ""
- << idToShortDescription(id)
- << " "
- "Run \"cmake --help-policy "
- << idToString(id)
- << "\" for "
- "policy details. "
- "CMake now requires this policy to be set to NEW by the project. "
- "The policy may be set explicitly using the code\n"
- " cmake_policy(SET "
- << idToString(id)
- << " NEW)\n"
- "or by upgrading all policies with the code\n"
- " cmake_policy(VERSION "
- << idToVersion(id)
- << ") # or later\n"
- "Run \"cmake --help-command cmake_policy\" for more information.";
- return error.str();
+ return cmStrCat(
+ "Policy ", idToString(id),
+ " is not set to NEW: ", idToShortDescription(id),
+ " "
+ "Run \"cmake --help-policy ",
+ idToString(id),
+ "\" for policy details. "
+ "CMake now requires this policy to be set to NEW by the project. "
+ "The policy may be set explicitly using the code\n"
+ " cmake_policy(SET ",
+ idToString(id),
+ " NEW)\n"
+ "or by upgrading all policies with the code\n"
+ " cmake_policy(VERSION ",
+ idToVersion(id),
+ ") # or later\n"
+ "Run \"cmake --help-command cmake_policy\" for more information.");
}
//! Get the default status for a policy
@@ -395,18 +385,18 @@ cmPolicies::PolicyStatus cmPolicies::GetPolicyStatus(
std::string cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
{
std::string pid = idToString(id);
- std::ostringstream e;
- e << "Policy " << pid << " may not be set to OLD behavior because this "
- << "version of CMake no longer supports it. "
- << "The policy was introduced in "
- << "CMake version " << idToVersion(id)
- << ", and use of NEW behavior is now required."
- << "\n"
- << "Please either update your CMakeLists.txt files to conform to "
- << "the new behavior or use an older version of CMake that still "
- << "supports the old behavior. "
- << "Run cmake --help-policy " << pid << " for more information.";
- return e.str();
+ return cmStrCat(
+ "Policy ", pid,
+ " may not be set to OLD behavior because this "
+ "version of CMake no longer supports it. "
+ "The policy was introduced in CMake version ",
+ idToVersion(id),
+ ", and use of NEW behavior is now required."
+ "\n"
+ "Please either update your CMakeLists.txt files to conform to "
+ "the new behavior or use an older version of CMake that still "
+ "supports the old behavior. Run cmake --help-policy ",
+ pid, " for more information.");
}
cmPolicies::PolicyStatus cmPolicies::PolicyMap::Get(
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a0030d3..26c141d 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -459,7 +459,13 @@ class cmMakefile;
SELECT(POLICY, CMP0151, \
"AUTOMOC include directory is a system include directory by " \
"default.", \
- 3, 27, 0, cmPolicies::WARN)
+ 3, 27, 0, cmPolicies::WARN) \
+ SELECT( \
+ POLICY, CMP0152, \
+ "file(REAL_PATH) resolves symlinks before collapsing ../ components.", 3, \
+ 28, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0153, "The exec_program command should not be called.", \
+ 3, 28, 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/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index 9e7854b..1dd1dce 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -2,48 +2,68 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProcessTools.h"
+#include <algorithm>
+#include <iterator>
#include <ostream>
-#include "cmsys/Process.h"
+#include <cm3p/uv.h>
#include "cmProcessOutput.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVStream.h"
-void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
- OutputParser* err, Encoding encoding)
+std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
+ cmUVProcessChainBuilder& builder, OutputParser* out, OutputParser* err,
+ Encoding encoding)
{
- cmsysProcess_Execute(cp);
- char* data = nullptr;
- int length = 0;
- int p;
cmProcessOutput processOutput(encoding);
+
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+
+ auto chain = builder.Start();
+
std::string strdata;
- while ((out || err) &&
- (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
- if (out && p == cmsysProcess_Pipe_STDOUT) {
- processOutput.DecodeText(data, length, strdata, 1);
- if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
- out = nullptr;
+ cm::uv_pipe_ptr outputPipe;
+ outputPipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(outputPipe, chain.OutputStream());
+ auto outputHandle = cmUVStreamRead(
+ outputPipe,
+ [&out, &processOutput, &strdata](std::vector<char> data) {
+ if (out) {
+ processOutput.DecodeText(data.data(), data.size(), strdata, 1);
+ if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
+ out = nullptr;
+ }
}
- } else if (err && p == cmsysProcess_Pipe_STDERR) {
- processOutput.DecodeText(data, length, strdata, 2);
- if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
- err = nullptr;
+ },
+ [&out]() { out = nullptr; });
+ cm::uv_pipe_ptr errorPipe;
+ errorPipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(errorPipe, chain.ErrorStream());
+ auto errorHandle = cmUVStreamRead(
+ errorPipe,
+ [&err, &processOutput, &strdata](std::vector<char> data) {
+ if (err) {
+ processOutput.DecodeText(data.data(), data.size(), strdata, 2);
+ if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
+ err = nullptr;
+ }
}
- }
+ },
+ [&err]() { err = nullptr; });
+ while (out || err || !chain.Finished()) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
}
- if (out) {
- processOutput.DecodeText(std::string(), strdata, 1);
- if (!strdata.empty()) {
- out->Process(strdata.c_str(), static_cast<int>(strdata.size()));
- }
- }
- if (err) {
- processOutput.DecodeText(std::string(), strdata, 2);
- if (!strdata.empty()) {
- err->Process(strdata.c_str(), static_cast<int>(strdata.size()));
- }
- }
- cmsysProcess_WaitForExit(cp, nullptr);
+
+ std::vector<cmUVProcessChain::Status> result;
+ auto status = chain.GetStatus();
+ std::transform(
+ status.begin(), status.end(), std::back_inserter(result),
+ [](const cmUVProcessChain::Status* s) -> cmUVProcessChain::Status {
+ return *s;
+ });
+ return result;
}
cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR)
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 74ec5e0..2bdabea 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -7,8 +7,10 @@
#include <cstring>
#include <iosfwd>
#include <string>
+#include <vector>
#include "cmProcessOutput.h"
+#include "cmUVProcessChain.h"
/** \class cmProcessTools
* \brief Helper classes for process output parsing
@@ -81,7 +83,7 @@ public:
};
/** Run a process and send output to given parsers. */
- static void RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
- OutputParser* err = nullptr,
- Encoding encoding = cmProcessOutput::Auto);
+ static std::vector<cmUVProcessChain::Status> RunProcess(
+ cmUVProcessChainBuilder& builder, OutputParser* out,
+ OutputParser* err = nullptr, Encoding encoding = cmProcessOutput::Auto);
};
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 4d1ccfe..3aef299 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -3,7 +3,6 @@
#include "cmProjectCommand.h"
#include <array>
-#include <cstddef>
#include <cstdio>
#include <functional>
#include <limits>
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index 568a3d2..5bb769a 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -10,10 +10,6 @@ void cmPropertyMap::Clear()
this->Map_.clear();
}
-void cmPropertyMap::SetProperty(const std::string& name, std::nullptr_t)
-{
- this->Map_.erase(name);
-}
void cmPropertyMap::SetProperty(const std::string& name, cmValue value)
{
if (!value) {
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 23b50a5..3cd90ec 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -4,7 +4,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <string>
#include <unordered_map>
#include <utility>
@@ -26,7 +25,6 @@ public:
// -- Properties
//! Set the property value
- void SetProperty(const std::string& name, std::nullptr_t);
void SetProperty(const std::string& name, cmValue value);
void SetProperty(const std::string& name, const std::string& value)
{
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index e5c7bda..c048312 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenerator.h"
+#include <iterator>
+
#include <cm3p/json/reader.h>
#include "cmsys/FStream.hxx"
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index a101a81..ece657d 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -27,6 +27,7 @@
#include "cmCryptoHash.h"
#include "cmFileTime.h"
#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
@@ -2116,7 +2117,7 @@ void cmQtAutoMocUicT::JobCompileMocT::MaybeWriteMocResponseFile(
cmd.resize(1);
// Specify response file
- cmd.push_back(cmStrCat('@', responseFile));
+ cmd.emplace_back(cmStrCat('@', responseFile));
}
#else
static_cast<void>(outputFile);
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index 414a692..e288645 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -14,7 +14,6 @@
#include "cmFileLockResult.h"
#include "cmFileTime.h"
#include "cmProcessOutput.h"
-#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 17285e7..3576e4f 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -9,6 +9,7 @@
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -159,7 +160,7 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
pos += 2;
}
});
- auto value = cmJoin(values, ";");
+ auto value = cmList::to_string(values);
status.GetMakefile().AddDefinition(var, value);
return true;
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 040eb08..c98745a 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -3,6 +3,7 @@
#include "cmSetCommand.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
@@ -103,7 +104,8 @@ bool cmSetCommand(std::vector<std::string> const& args,
}
// collect any values into a single semi-colon separated value list
- value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";");
+ value =
+ cmList::to_string(cmMakeRange(args).advance(1).retreat(ignoreLastArgs));
if (parentScope) {
status.GetMakefile().RaiseScope(variable, value.c_str());
@@ -113,10 +115,18 @@ bool cmSetCommand(std::vector<std::string> const& args,
// we should be nice and try to catch some simple screwups if the last or
// next to last args are CACHE then they screwed up. If they used FORCE
// without CACHE they screwed up
- if ((args.back() == "CACHE") ||
- (args.size() > 1 && args[args.size() - 2] == "CACHE") ||
- (force && !cache)) {
- status.SetError("given invalid arguments for CACHE mode.");
+ if (args.back() == "CACHE") {
+ status.SetError(
+ "given invalid arguments for CACHE mode: missing type and docstring");
+ return false;
+ }
+ if (args.size() > 1 && args[args.size() - 2] == "CACHE") {
+ status.SetError(
+ "given invalid arguments for CACHE mode: missing type or docstring");
+ return false;
+ }
+ if (force && !cache) {
+ status.SetError("given invalid arguments: FORCE specified without CACHE");
return false;
}
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index de1e3b0..60610a4 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -58,7 +58,8 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
- bool appendMode, bool remove);
+ bool appendMode, bool remove,
+ cmMakefile* test_directory_makefile);
bool HandleTest(cmTest* test, const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove);
@@ -184,6 +185,60 @@ bool HandleAndValidateSourceFileDirectoryScopes(
return scope_options_valid;
}
+bool HandleTestDirectoryScopes(cmExecutionStatus& status,
+ std::string& test_directory,
+ cmMakefile*& directory_makefile)
+{
+ cmMakefile* current_dir_mf = &status.GetMakefile();
+ if (!test_directory.empty()) {
+ const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
+ test_directory, current_dir_mf->GetCurrentSourceDirectory());
+ cmMakefile* dir_mf =
+ status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+ absolute_dir_path);
+ if (!dir_mf) {
+ status.SetError(
+ cmStrCat("given non-existent DIRECTORY ", test_directory));
+ return false;
+ }
+ directory_makefile = dir_mf;
+ } else {
+ directory_makefile = current_dir_mf;
+ }
+ return true;
+}
+
+bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status,
+ bool test_directory_option_enabled,
+ std::string& test_directory)
+{
+ // Validate source file directory scopes.
+ if (test_directory_option_enabled && test_directory.empty()) {
+ std::string errors = "called with incorrect number of arguments "
+ "no value provided to the DIRECTORY option";
+ status.SetError(errors);
+ return false;
+ }
+ return true;
+}
+
+bool HandleAndValidateTestDirectoryScopes(cmExecutionStatus& status,
+ bool test_directory_option_enabled,
+ std::string& test_directory,
+ cmMakefile*& test_directory_makefile)
+{
+ bool scope_options_valid =
+ SetPropertyCommand::HandleTestDirectoryScopeValidation(
+ status, test_directory_option_enabled, test_directory);
+ if (!scope_options_valid) {
+ return false;
+ }
+
+ scope_options_valid = SetPropertyCommand::HandleTestDirectoryScopes(
+ status, test_directory, test_directory_makefile);
+ return scope_options_valid;
+}
+
std::string MakeSourceFilePathAbsoluteIfNeeded(
cmExecutionStatus& status, const std::string& source_file_path,
const bool needed)
@@ -293,7 +348,7 @@ bool HandleAndValidateSourceFilePropertyGENERATED(
sf->AppendProperty("GENERATED", propertyValue, true);
break;
case PropertyOp::Remove:
- sf->SetProperty("GENERATED", nullptr);
+ sf->RemoveProperty("GENERATED");
break;
case PropertyOp::Set:
sf->SetProperty("GENERATED", propertyValue);
@@ -352,6 +407,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
bool source_file_directory_option_enabled = false;
bool source_file_target_option_enabled = false;
+ std::string test_directory;
+ bool test_directory_option_enabled = false;
+
// Parse the rest of the arguments up to the values.
enum Doing
{
@@ -360,7 +418,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
DoingProperty,
DoingValues,
DoingSourceDirectory,
- DoingSourceTargetDirectory
+ DoingSourceTargetDirectory,
+ DoingTestDirectory,
};
Doing doing = DoingNames;
const char* sep = "";
@@ -385,12 +444,19 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
scope == cmProperty::SOURCE_FILE && arg == "TARGET_DIRECTORY") {
doing = DoingSourceTargetDirectory;
source_file_target_option_enabled = true;
+ } else if (doing != DoingProperty && doing != DoingValues &&
+ scope == cmProperty::TEST && arg == "DIRECTORY") {
+ doing = DoingTestDirectory;
+ test_directory_option_enabled = true;
} else if (doing == DoingNames) {
names.insert(arg);
} else if (doing == DoingSourceDirectory) {
source_file_directories.push_back(arg);
} else if (doing == DoingSourceTargetDirectory) {
source_file_target_directories.push_back(arg);
+ } else if (doing == DoingTestDirectory) {
+ test_directory = arg;
+ doing = DoingNone;
} else if (doing == DoingProperty) {
propertyName = arg;
doing = DoingValues;
@@ -412,12 +478,17 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
}
std::vector<cmMakefile*> source_file_directory_makefiles;
- bool file_scopes_handled =
+ bool source_file_scopes_handled =
SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
- if (!file_scopes_handled) {
+ cmMakefile* test_directory_makefile;
+ bool test_scopes_handled =
+ SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
+ status, test_directory_option_enabled, test_directory,
+ test_directory_makefile);
+ if (!(source_file_scopes_handled && test_scopes_handled)) {
return false;
}
bool source_file_paths_should_be_absolute =
@@ -441,7 +512,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
source_file_paths_should_be_absolute);
case cmProperty::TEST:
return HandleTestMode(status, names, propertyName, propertyValue,
- appendAsString, appendMode, remove);
+ appendAsString, appendMode, remove,
+ test_directory_makefile);
case cmProperty::CACHE:
return HandleCacheMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
@@ -631,7 +703,7 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
sf->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
if (remove) {
- sf->SetProperty(propertyName, nullptr);
+ sf->RemoveProperty(propertyName);
} else {
sf->SetProperty(propertyName, propertyValue);
}
@@ -642,14 +714,14 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
- bool appendMode, bool remove)
+ bool appendMode, bool remove, cmMakefile* test_makefile)
{
// Look for tests with all names given.
std::set<std::string>::iterator next;
for (auto ni = names.begin(); ni != names.end(); ni = next) {
next = ni;
++next;
- if (cmTest* test = status.GetMakefile().GetTest(*ni)) {
+ if (cmTest* test = test_makefile->GetTest(*ni)) {
if (HandleTest(test, propertyName, propertyValue, appendAsString,
appendMode, remove)) {
names.erase(ni);
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 05c4873..4d9480d 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -33,6 +33,18 @@ bool HandleAndValidateSourceFileDirectoryScopes(
std::vector<std::string>& source_target_directories,
std::vector<cmMakefile*>& source_file_directory_makefiles);
+bool HandleTestDirectoryScopes(cmExecutionStatus& status,
+ std::string& test_directory,
+ cmMakefile*& directory_makefile);
+
+bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status,
+ bool test_directory_option_enabled,
+ std::string& test_directory);
+
+bool HandleAndValidateTestDirectoryScopes(
+ cmExecutionStatus& status, bool test_directory_option_encountered,
+ std::string& test_directory, cmMakefile*& test_directory_makefile);
+
std::string MakeSourceFilePathAbsoluteIfNeeded(
cmExecutionStatus& status, const std::string& source_file_path, bool needed);
void MakeSourceFilePathsAbsoluteIfNeeded(
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index a17c964..2ac445c 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -5,9 +5,15 @@
#include <algorithm>
#include <iterator>
+#include <cmext/string_view>
+
+#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
+#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmRange.h"
#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
#include "cmTest.h"
bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
@@ -31,9 +37,29 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
return false;
}
+ std::vector<std::string> tests;
+ std::string directory;
+ cmArgumentParser<void> parser;
+ parser.Bind("DIRECTORY"_s, directory);
+ auto result = parser.Parse(cmStringRange{ args.begin(), propsIter }, &tests);
+
+ cmMakefile* mf = &status.GetMakefile();
+ if (result.MaybeReportError(*mf)) {
+ return false;
+ }
+ if (!directory.empty()) {
+ std::string absDirectory = cmSystemTools::CollapseFullPath(
+ directory, mf->GetCurrentSourceDirectory());
+ mf = mf->GetGlobalGenerator()->FindMakefile(absDirectory);
+ if (!mf) {
+ status.SetError(cmStrCat("given non-existent DIRECTORY ", directory));
+ return false;
+ }
+ }
+
// loop over all the tests
- for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
- if (cmTest* test = status.GetMakefile().GetTest(tname)) {
+ for (const std::string& tname : tests) {
+ if (cmTest* test = mf->GetTest(tname)) {
// loop through all the props and set them
for (auto k = propsIter + 1; k != args.end(); k += 2) {
if (!k->empty()) {
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 3403745..1be680a 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -8,6 +8,7 @@
#include <cmext/string_view>
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -390,7 +391,7 @@ cmValue cmSourceFile::GetProperty(const std::string& prop) const
}
static std::string output;
- output = cmJoin(this->IncludeDirectories, ";");
+ output = cmList::to_string(this->IncludeDirectories);
return cmValue(output);
}
@@ -400,7 +401,7 @@ cmValue cmSourceFile::GetProperty(const std::string& prop) const
}
static std::string output;
- output = cmJoin(this->CompileOptions, ";");
+ output = cmList::to_string(this->CompileOptions);
return cmValue(output);
}
@@ -410,7 +411,7 @@ cmValue cmSourceFile::GetProperty(const std::string& prop) const
}
static std::string output;
- output = cmJoin(this->CompileDefinitions, ";");
+ output = cmList::to_string(this->CompileDefinitions);
return cmValue(output);
}
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 3f070a7..be2023f 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -4,7 +4,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <memory>
#include <string>
#include <vector>
@@ -43,7 +42,7 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, cmValue value);
- void SetProperty(const std::string& prop, std::nullptr_t)
+ void RemoveProperty(const std::string& prop)
{
this->SetProperty(prop, cmValue{ nullptr });
}
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index bb75a14..4b1685f 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -4,6 +4,7 @@
#include <cstddef>
#include <map>
+#include <memory>
#include <set>
#include <utility>
@@ -11,6 +12,8 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSourceFileLocation.h"
#include "cmSourceGroup.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -194,7 +197,10 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
// If only two arguments are given, the pre-1.8 version of the
// command is being invoked.
- if (args.size() == 2 && args[1] != "FILES") {
+ bool isShortTreeSyntax =
+ ((args.size() == 2) && (args[0] == kTreeOptionName) &&
+ cmSystemTools::FileIsDirectory(args[1]));
+ if (args.size() == 2 && args[1] != kFilesOptionName && !isShortTreeSyntax) {
cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]);
if (!sg) {
@@ -274,8 +280,19 @@ static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments,
? ""
: parsedArguments[kPrefixOptionName].front();
- const std::vector<std::string> filesVector = prepareFilesPathsForTree(
- parsedArguments[kFilesOptionName], mf.GetCurrentSourceDirectory());
+ std::vector<std::string> files = parsedArguments[kFilesOptionName];
+ if (files.empty()) {
+ const std::vector<std::unique_ptr<cmSourceFile>>& srcFiles =
+ mf.GetSourceFiles();
+ for (const auto& srcFile : srcFiles) {
+ if (!srcFile->GetIsGenerated()) {
+ files.push_back(srcFile->GetLocation().GetFullPath());
+ }
+ }
+ }
+
+ const std::vector<std::string> filesVector =
+ prepareFilesPathsForTree(files, mf.GetCurrentSourceDirectory());
if (!rootIsPrefix(root, filesVector, errorMsg)) {
return false;
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index f6e8bc6..de42bc6 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -13,7 +13,9 @@
#include <vector>
#include <cm/iterator>
+#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -71,6 +73,8 @@ struct StandardLevelComputer
assert(this->Levels.size() == this->LevelsAsStrings.size());
}
+ // Note that the logic here is shadowed in `GetEffectiveStandard`; if one is
+ // changed, the other needs changed as well.
std::string GetCompileOptionDef(cmMakefile* makefile,
cmGeneratorTarget const* target,
std::string const& config) const
@@ -107,7 +111,7 @@ struct StandardLevelComputer
if (cmp0128 == cmPolicies::NEW) {
// Add extension flag if compiler's default doesn't match.
if (ext != defaultExt) {
- return cmStrCat("CMAKE_", this->Language, *defaultStd, "_", type,
+ return cmStrCat("CMAKE_", this->Language, *defaultStd, '_', type,
"_COMPILE_OPTION");
}
} else {
@@ -130,7 +134,7 @@ struct StandardLevelComputer
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0128),
"\nFor compatibility with older versions of CMake, "
"compiler extensions won't be ",
- state, "."));
+ state, '.'));
}
}
@@ -144,7 +148,7 @@ struct StandardLevelComputer
if (target->GetLanguageStandardRequired(this->Language)) {
std::string option_flag = cmStrCat(
- "CMAKE_", this->Language, *standardProp, "_", type, "_COMPILE_OPTION");
+ "CMAKE_", this->Language, *standardProp, '_', type, "_COMPILE_OPTION");
cmValue opt = target->Target->GetMakefile()->GetDefinition(option_flag);
if (!opt) {
@@ -155,8 +159,8 @@ struct StandardLevelComputer
<< this->Language << *standardProp << "\" "
<< (ext ? "(with compiler extensions)" : "")
<< ". But the current compiler \""
- << makefile->GetSafeDefinition("CMAKE_" + this->Language +
- "_COMPILER_ID")
+ << makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", this->Language, "_COMPILER_ID"))
<< "\" does not support this, or "
"CMake does not know the flags to enable it.";
@@ -185,7 +189,7 @@ struct StandardLevelComputer
}
std::string standardStr(*standardProp);
- if (this->Language == "CUDA" && standardStr == "98") {
+ if (this->Language == "CUDA"_s && standardStr == "98"_s) {
standardStr = "03";
}
@@ -194,7 +198,7 @@ struct StandardLevelComputer
if (stdIt == cm::cend(stds)) {
std::string e =
cmStrCat(this->Language, "_STANDARD is set to invalid value '",
- standardStr, "'");
+ standardStr, '\'');
makefile->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
target->GetBacktrace());
return std::string{};
@@ -205,7 +209,7 @@ struct StandardLevelComputer
if (defaultStdIt == cm::cend(stds)) {
std::string e = cmStrCat("CMAKE_", this->Language,
"_STANDARD_DEFAULT is set to invalid value '",
- *defaultStd, "'");
+ *defaultStd, '\'');
makefile->IssueMessage(MessageType::INTERNAL_ERROR, e);
return std::string{};
}
@@ -216,7 +220,7 @@ struct StandardLevelComputer
(cmp0128 == cmPolicies::NEW &&
(stdIt < defaultStdIt || ext != defaultExt))) {
auto offset = std::distance(cm::cbegin(stds), stdIt);
- return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
+ return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], '_', type,
"_COMPILE_OPTION");
}
@@ -226,7 +230,7 @@ struct StandardLevelComputer
for (; defaultStdIt < stdIt; --stdIt) {
auto offset = std::distance(cm::cbegin(stds), stdIt);
std::string option_flag =
- cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
+ cmStrCat("CMAKE_", this->Language, stdsStrings[offset], '_', type,
"_COMPILE_OPTION");
if (target->Target->GetMakefile()->GetDefinition(option_flag)) {
return option_flag;
@@ -236,6 +240,105 @@ struct StandardLevelComputer
return std::string{};
}
+ std::string GetEffectiveStandard(cmMakefile* makefile,
+ cmGeneratorTarget const* target,
+ std::string const& config) const
+ {
+ const auto& stds = this->Levels;
+ const auto& stdsStrings = this->LevelsAsStrings;
+
+ cmValue defaultStd = makefile->GetDefinition(
+ cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+ if (!cmNonempty(defaultStd)) {
+ // this compiler has no notion of language standard levels
+ return std::string{};
+ }
+
+ cmPolicies::PolicyStatus const cmp0128{ makefile->GetPolicyStatus(
+ cmPolicies::CMP0128) };
+ bool const defaultExt{ cmIsOn(*makefile->GetDefinition(
+ cmStrCat("CMAKE_", this->Language, "_EXTENSIONS_DEFAULT"))) };
+ bool ext = true;
+
+ if (cmp0128 == cmPolicies::NEW) {
+ ext = defaultExt;
+ }
+
+ if (cmValue extPropValue = target->GetLanguageExtensions(this->Language)) {
+ ext = cmIsOn(*extPropValue);
+ }
+
+ std::string const type{ ext ? "EXTENSION" : "STANDARD" };
+
+ cmValue standardProp = target->GetLanguageStandard(this->Language, config);
+ if (!standardProp) {
+ if (cmp0128 == cmPolicies::NEW) {
+ // Add extension flag if compiler's default doesn't match.
+ if (ext != defaultExt) {
+ return *defaultStd;
+ }
+ } else {
+ if (ext) {
+ return *defaultStd;
+ }
+ }
+ return std::string{};
+ }
+
+ if (target->GetLanguageStandardRequired(this->Language)) {
+ return *standardProp;
+ }
+
+ // If the request matches the compiler's defaults we don't need to add
+ // anything.
+ if (*standardProp == *defaultStd && ext == defaultExt) {
+ if (cmp0128 == cmPolicies::NEW) {
+ return std::string{};
+ }
+ }
+
+ std::string standardStr(*standardProp);
+ if (this->Language == "CUDA"_s && standardStr == "98"_s) {
+ standardStr = "03";
+ }
+
+ auto stdIt =
+ std::find(cm::cbegin(stds), cm::cend(stds), ParseStd(standardStr));
+ if (stdIt == cm::cend(stds)) {
+ return std::string{};
+ }
+
+ auto defaultStdIt =
+ std::find(cm::cbegin(stds), cm::cend(stds), ParseStd(*defaultStd));
+ if (defaultStdIt == cm::cend(stds)) {
+ return std::string{};
+ }
+
+ // If the standard requested is older than the compiler's default or the
+ // extension mode doesn't match then we need to use a flag.
+ if ((cmp0128 != cmPolicies::NEW && stdIt <= defaultStdIt) ||
+ (cmp0128 == cmPolicies::NEW &&
+ (stdIt < defaultStdIt || ext != defaultExt))) {
+ auto offset = std::distance(cm::cbegin(stds), stdIt);
+ return stdsStrings[offset];
+ }
+
+ // The compiler's default is at least as new as the requested standard,
+ // and the requested standard is not required. Decay to the newest
+ // standard for which a flag is defined.
+ for (; defaultStdIt < stdIt; --stdIt) {
+ auto offset = std::distance(cm::cbegin(stds), stdIt);
+ std::string option_flag =
+ cmStrCat("CMAKE_", this->Language, stdsStrings[offset], '_', type,
+ "_COMPILE_OPTION");
+ if (target->Target->GetMakefile()->GetDefinition(option_flag)) {
+ return stdsStrings[offset];
+ }
+ }
+
+ return std::string{};
+ }
+
bool GetNewRequiredStandard(cmMakefile* makefile,
std::string const& targetName,
const std::string& feature,
@@ -418,6 +521,18 @@ std::string cmStandardLevelResolver::GetCompileOptionDef(
return mapping->second.GetCompileOptionDef(this->Makefile, target, config);
}
+std::string cmStandardLevelResolver::GetEffectiveStandard(
+ cmGeneratorTarget const* target, std::string const& lang,
+ std::string const& config) const
+{
+ const auto& mapping = StandardComputerMapping.find(lang);
+ if (mapping == cm::cend(StandardComputerMapping)) {
+ return std::string{};
+ }
+
+ return mapping->second.GetEffectiveStandard(this->Makefile, target, config);
+}
+
bool cmStandardLevelResolver::AddRequiredTargetFeature(
cmTarget* target, const std::string& feature, std::string* error) const
{
@@ -474,11 +589,12 @@ bool cmStandardLevelResolver::CheckCompileFeaturesAvailable(
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
<< " compiler\n\""
- << this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID")
+ << this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_ID"))
<< "\"\nversion "
- << this->Makefile->GetSafeDefinition("CMAKE_" + lang +
- "_COMPILER_VERSION")
- << ".";
+ << this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_VERSION"))
+ << '.';
if (error) {
*error = e.str();
} else {
@@ -561,8 +677,8 @@ cmValue cmStandardLevelResolver::CompileFeaturesAvailable(
return nullptr;
}
- cmValue featuresKnown =
- this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
+ cmValue featuresKnown = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_FEATURES"));
if (!cmNonempty(featuresKnown)) {
std::ostringstream e;
@@ -572,11 +688,12 @@ cmValue cmStandardLevelResolver::CompileFeaturesAvailable(
e << "No";
}
e << " known features for " << lang << " compiler\n\""
- << this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID")
+ << this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_ID"))
<< "\"\nversion "
- << this->Makefile->GetSafeDefinition("CMAKE_" + lang +
- "_COMPILER_VERSION")
- << ".";
+ << this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_VERSION"))
+ << '.';
if (error) {
*error = e.str();
} else {
diff --git a/Source/cmStandardLevelResolver.h b/Source/cmStandardLevelResolver.h
index 4226456..03adf3f 100644
--- a/Source/cmStandardLevelResolver.h
+++ b/Source/cmStandardLevelResolver.h
@@ -22,6 +22,9 @@ public:
std::string GetCompileOptionDef(cmGeneratorTarget const* target,
std::string const& lang,
std::string const& config) const;
+ std::string GetEffectiveStandard(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config) const;
bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
std::string* error = nullptr) const;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 2596d8c..d41e8e5 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -17,6 +17,7 @@
#include "cmDefinitions.h"
#include "cmExecutionStatus.h"
#include "cmGlobVerificationManager.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -584,10 +585,10 @@ cmValue cmState::GetGlobalProperty(const std::string& prop)
{
if (prop == "CACHE_VARIABLES") {
std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
- this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";"));
+ this->SetGlobalProperty("CACHE_VARIABLES", cmList::to_string(cacheKeys));
} else if (prop == "COMMANDS") {
std::vector<std::string> commands = this->GetCommandNames();
- this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";"));
+ this->SetGlobalProperty("COMMANDS", cmList::to_string(commands));
} else if (prop == "IN_TRY_COMPILE") {
this->SetGlobalProperty(
"IN_TRY_COMPILE",
@@ -596,8 +597,7 @@ cmValue cmState::GetGlobalProperty(const std::string& prop)
this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
this->IsGeneratorMultiConfig ? "1" : "0");
} else if (prop == "ENABLED_LANGUAGES") {
- std::string langs;
- langs = cmJoin(this->EnabledLanguages, ";");
+ auto langs = cmList::to_string(this->EnabledLanguages);
this->SetGlobalProperty("ENABLED_LANGUAGES", langs);
} else if (prop == "CMAKE_ROLE") {
std::string mode = this->GetModeString();
diff --git a/Source/cmState.h b/Source/cmState.h
index 1ebd79a..b79f3e6 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -8,7 +8,6 @@
#include <memory>
#include <set>
#include <string>
-#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 6e6fcbd..39353f3 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -13,6 +13,7 @@
#include <cmext/string_view>
#include "cmAlgorithms.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmProperty.h"
#include "cmPropertyMap.h"
@@ -20,7 +21,6 @@
#include "cmState.h"
#include "cmStatePrivate.h"
#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -381,15 +381,15 @@ cmValue cmStateDirectory::GetProperty(const std::string& prop,
for (cmStateSnapshot const& ci : children) {
child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
}
- output = cmJoin(child_dirs, ";");
+ output = cmList::to_string(child_dirs);
return cmValue(output);
}
if (prop == kBUILDSYSTEM_TARGETS) {
- output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
+ output = cmList::to_string(this->DirectoryState->NormalTargetNames);
return cmValue(output);
}
if (prop == "IMPORTED_TARGETS"_s) {
- output = cmJoin(this->DirectoryState->ImportedTargetNames, ";");
+ output = cmList::to_string(this->DirectoryState->ImportedTargetNames);
return cmValue(output);
}
@@ -401,38 +401,38 @@ cmValue cmStateDirectory::GetProperty(const std::string& prop,
snp = snp.GetCallStackParent();
}
std::reverse(listFiles.begin(), listFiles.end());
- output = cmJoin(listFiles, ";");
+ output = cmList::to_string(listFiles);
return cmValue(output);
}
if (prop == "CACHE_VARIABLES") {
- output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
+ output = cmList::to_string(this->Snapshot_.State->GetCacheEntryKeys());
return cmValue(output);
}
if (prop == "VARIABLES") {
std::vector<std::string> res = this->Snapshot_.ClosureKeys();
cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
- output = cmJoin(res, ";");
+ output = cmList::to_string(res);
return cmValue(output);
}
if (prop == "INCLUDE_DIRECTORIES") {
- output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
+ output = cmList::to_string(this->GetIncludeDirectoriesEntries());
return cmValue(output);
}
if (prop == "COMPILE_OPTIONS") {
- output = cmJoin(this->GetCompileOptionsEntries(), ";");
+ output = cmList::to_string(this->GetCompileOptionsEntries());
return cmValue(output);
}
if (prop == "COMPILE_DEFINITIONS") {
- output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
+ output = cmList::to_string(this->GetCompileDefinitionsEntries());
return cmValue(output);
}
if (prop == "LINK_OPTIONS") {
- output = cmJoin(this->GetLinkOptionsEntries(), ";");
+ output = cmList::to_string(this->GetLinkOptionsEntries());
return cmValue(output);
}
if (prop == "LINK_DIRECTORIES") {
- output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
+ output = cmList::to_string(this->GetLinkDirectoriesEntries());
return cmValue(output);
}
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index e230702..8217a9c 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -10,6 +10,7 @@
#include <cm/iterator>
#include "cmDefinitions.h"
+#include "cmLinkedTree.h"
#include "cmListFileCache.h"
#include "cmPropertyMap.h"
#include "cmState.h"
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index a61ec83..1796d76 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -10,7 +10,6 @@
#include <cm/string_view>
-#include "cmLinkedTree.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmValue.h"
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index f1e462b..1994c2c 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -6,7 +6,6 @@
#include <algorithm>
#include <cstddef>
-#include <functional>
#include <initializer_list>
#include <memory>
#include <ostream>
@@ -494,8 +493,8 @@ public:
char ch)
{
std::string out;
- out.reserve((first - this->view_.begin()) + count2 +
- (this->view_.end() - last));
+ out.reserve(static_cast<size_type>(first - this->view_.begin()) + count2 +
+ static_cast<size_type>(this->view_.end() - last));
out.append(this->view_.begin(), first);
out.append(count2, ch);
out.append(last, this->view_.end());
diff --git a/Source/cmSyntheticTargetCache.h b/Source/cmSyntheticTargetCache.h
new file mode 100644
index 0000000..22d1533
--- /dev/null
+++ b/Source/cmSyntheticTargetCache.h
@@ -0,0 +1,15 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <map>
+#include <string>
+
+class cmGeneratorTarget;
+
+struct cmSyntheticTargetCache
+{
+ std::map<std::string, cmGeneratorTarget const*> CxxModuleTargets;
+};
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 1fb0079..fe421ba 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -25,12 +25,17 @@
#include <cm3p/uv.h>
+#include "cm_fileno.hxx"
+
#include "cmDuration.h"
#include "cmELF.h"
#include "cmMessageMetadata.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
#include "cmValue.h"
#if !defined(CMAKE_BOOTSTRAP)
@@ -47,13 +52,6 @@
# endif
#endif
-#if !defined(CMAKE_BOOTSTRAP)
-# if defined(_WIN32)
-# include <cm/memory>
-# endif
-# include "cmCryptoHash.h"
-#endif
-
#if defined(CMake_USE_MACH_PARSER)
# include "cmMachO.h"
#endif
@@ -66,12 +64,14 @@
#include <cassert>
#include <cctype>
#include <cerrno>
+#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
+#include <memory>
#include <sstream>
#include <utility>
#include <vector>
@@ -529,7 +529,7 @@ bool cmSystemTools::SplitProgramFromArgs(std::string const& command,
return !in_single && !in_escape && !in_double;
}
-size_t cmSystemTools::CalculateCommandLineLengthLimit()
+std::size_t cmSystemTools::CalculateCommandLineLengthLimit()
{
size_t sz =
#ifdef _WIN32
@@ -575,85 +575,113 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
const char* dir, OutputOption outputflag,
cmDuration timeout, Encoding encoding)
{
- std::vector<const char*> argv;
- argv.reserve(command.size() + 1);
- for (std::string const& cmd : command) {
- argv.push_back(cmd.c_str());
- }
- argv.push_back(nullptr);
-
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_SetCommand(cp, argv.data());
- cmsysProcess_SetWorkingDirectory(cp, dir);
- if (cmSystemTools::GetRunCommandHideConsole()) {
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(command);
+ if (dir) {
+ builder.SetWorkingDirectory(dir);
}
if (outputflag == OUTPUT_PASSTHROUGH) {
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
captureStdOut = nullptr;
captureStdErr = nullptr;
+ builder
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ cm_fileno(stdout))
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(stderr));
} else if (outputflag == OUTPUT_MERGE ||
(captureStdErr && captureStdErr == captureStdOut)) {
- cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
+ builder.SetMergedBuiltinStreams();
captureStdErr = nullptr;
+ } else {
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
}
assert(!captureStdErr || captureStdErr != captureStdOut);
- cmsysProcess_SetTimeout(cp, timeout.count());
- cmsysProcess_Execute(cp);
+ auto chain = builder.Start();
+ bool timedOut = false;
+ cm::uv_timer_ptr timer;
+ if (timeout.count()) {
+ timer.init(chain.GetLoop(), &timedOut);
+ timer.start(
+ [](uv_timer_t* t) {
+ auto* timedOutPtr = static_cast<bool*>(t->data);
+ *timedOutPtr = true;
+ },
+ static_cast<uint64_t>(timeout.count() * 1000.0), 0);
+ }
std::vector<char> tempStdOut;
std::vector<char> tempStdErr;
- char* data;
- int length;
- int pipe;
+ cm::uv_pipe_ptr outStream;
+ bool outFinished = true;
+ cm::uv_pipe_ptr errStream;
+ bool errFinished = true;
cmProcessOutput processOutput(encoding);
- std::string strdata;
+ std::unique_ptr<cmUVStreamReadHandle> outputHandle;
+ std::unique_ptr<cmUVStreamReadHandle> errorHandle;
if (outputflag != OUTPUT_PASSTHROUGH &&
(captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) {
- while ((pipe = cmsysProcess_WaitForData(cp, &data, &length, nullptr)) >
- 0) {
- // Translate NULL characters in the output into valid text.
- for (int i = 0; i < length; ++i) {
- if (data[i] == '\0') {
- data[i] = ' ';
- }
- }
+ auto startRead =
+ [&outputflag, &processOutput,
+ &chain](cm::uv_pipe_ptr& pipe, int stream, std::string* captureStd,
+ std::vector<char>& tempStd, int id,
+ void (*outputFunc)(const std::string&),
+ bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
+ if (stream < 0) {
+ return nullptr;
+ }
+
+ pipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(pipe, stream);
+
+ finished = false;
+ return cmUVStreamRead(
+ pipe,
+ [outputflag, &processOutput, captureStd, &tempStd, id,
+ outputFunc](std::vector<char> data) {
+ // Translate NULL characters in the output into valid text.
+ for (auto& c : data) {
+ if (c == '\0') {
+ c = ' ';
+ }
+ }
- if (pipe == cmsysProcess_Pipe_STDOUT) {
- if (outputflag != OUTPUT_NONE) {
- processOutput.DecodeText(data, length, strdata, 1);
- cmSystemTools::Stdout(strdata);
- }
- if (captureStdOut) {
- cm::append(tempStdOut, data, data + length);
- }
- } else if (pipe == cmsysProcess_Pipe_STDERR) {
- if (outputflag != OUTPUT_NONE) {
- processOutput.DecodeText(data, length, strdata, 2);
- cmSystemTools::Stderr(strdata);
- }
- if (captureStdErr) {
- cm::append(tempStdErr, data, data + length);
- }
- }
- }
+ if (outputflag != OUTPUT_NONE) {
+ std::string strdata;
+ processOutput.DecodeText(data.data(), data.size(), strdata, id);
+ outputFunc(strdata);
+ }
+ if (captureStd) {
+ cm::append(tempStd, data.data(), data.data() + data.size());
+ }
+ },
+ [&finished, outputflag, &processOutput, id, outputFunc]() {
+ finished = true;
+ if (outputflag != OUTPUT_NONE) {
+ std::string strdata;
+ processOutput.DecodeText(std::string(), strdata, id);
+ if (!strdata.empty()) {
+ outputFunc(strdata);
+ }
+ }
+ });
+ };
- if (outputflag != OUTPUT_NONE) {
- processOutput.DecodeText(std::string(), strdata, 1);
- if (!strdata.empty()) {
- cmSystemTools::Stdout(strdata);
- }
- processOutput.DecodeText(std::string(), strdata, 2);
- if (!strdata.empty()) {
- cmSystemTools::Stderr(strdata);
- }
+ outputHandle =
+ startRead(outStream, chain.OutputStream(), captureStdOut, tempStdOut, 1,
+ cmSystemTools::Stdout, outFinished);
+ if (chain.OutputStream() != chain.ErrorStream()) {
+ errorHandle =
+ startRead(errStream, chain.ErrorStream(), captureStdErr, tempStdErr, 2,
+ cmSystemTools::Stderr, errFinished);
}
}
- cmsysProcess_WaitForExit(cp, nullptr);
+ while (!timedOut && !(chain.Finished() && outFinished && errFinished)) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
+ }
if (captureStdOut) {
captureStdOut->assign(tempStdOut.begin(), tempStdOut.end());
@@ -665,37 +693,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
}
bool result = true;
- if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
- if (retVal) {
- *retVal = cmsysProcess_GetExitValue(cp);
- } else {
- if (cmsysProcess_GetExitValue(cp) != 0) {
- result = false;
- }
- }
- } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exception) {
- const char* exception_str = cmsysProcess_GetExceptionString(cp);
- if (outputflag != OUTPUT_NONE) {
- std::cerr << exception_str << std::endl;
- }
- if (captureStdErr) {
- captureStdErr->append(exception_str, strlen(exception_str));
- } else if (captureStdOut) {
- captureStdOut->append(exception_str, strlen(exception_str));
- }
- result = false;
- } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Error) {
- const char* error_str = cmsysProcess_GetErrorString(cp);
- if (outputflag != OUTPUT_NONE) {
- std::cerr << error_str << std::endl;
- }
- if (captureStdErr) {
- captureStdErr->append(error_str, strlen(error_str));
- } else if (captureStdOut) {
- captureStdOut->append(error_str, strlen(error_str));
- }
- result = false;
- } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Expired) {
+ if (timedOut) {
const char* error_str = "Process terminated due to timeout\n";
if (outputflag != OUTPUT_NONE) {
std::cerr << error_str << std::endl;
@@ -704,9 +702,34 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
captureStdErr->append(error_str, strlen(error_str));
}
result = false;
+ } else {
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ if (retVal) {
+ *retVal = static_cast<int>(status.ExitStatus);
+ } else {
+ if (status.ExitStatus != 0) {
+ result = false;
+ }
+ }
+ break;
+ default: {
+ if (outputflag != OUTPUT_NONE) {
+ std::cerr << exception.second << std::endl;
+ }
+ if (captureStdErr) {
+ captureStdErr->append(exception.second);
+ } else if (captureStdOut) {
+ captureStdOut->append(exception.second);
+ }
+ result = false;
+ } break;
+ }
}
- cmsysProcess_Delete(cp);
return result;
}
@@ -1308,89 +1331,6 @@ void cmSystemTools::MoveFileIfDifferent(const std::string& source,
RemoveFile(source);
}
-#ifndef CMAKE_BOOTSTRAP
-std::string cmSystemTools::ComputeFileHash(const std::string& source,
- cmCryptoHash::Algo algo)
-{
- cmCryptoHash hash(algo);
- return hash.HashFile(source);
-}
-
-std::string cmSystemTools::ComputeStringMD5(const std::string& input)
-{
- cmCryptoHash md5(cmCryptoHash::AlgoMD5);
- return md5.HashString(input);
-}
-
-# ifdef _WIN32
-std::string cmSystemTools::ComputeCertificateThumbprint(
- const std::string& source)
-{
- std::string thumbprint;
-
- CRYPT_INTEGER_BLOB cryptBlob;
- HCERTSTORE certStore = nullptr;
- PCCERT_CONTEXT certContext = nullptr;
-
- HANDLE certFile = CreateFileW(
- cmsys::Encoding::ToWide(source.c_str()).c_str(), GENERIC_READ,
- FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
-
- if (certFile != INVALID_HANDLE_VALUE && certFile != nullptr) {
- DWORD fileSize = GetFileSize(certFile, nullptr);
- if (fileSize != INVALID_FILE_SIZE) {
- auto certData = cm::make_unique<BYTE[]>(fileSize);
- if (certData != nullptr) {
- DWORD dwRead = 0;
- if (ReadFile(certFile, certData.get(), fileSize, &dwRead, nullptr)) {
- cryptBlob.cbData = fileSize;
- cryptBlob.pbData = certData.get();
-
- // Verify that this is a valid cert
- if (PFXIsPFXBlob(&cryptBlob)) {
- // Open the certificate as a store
- certStore =
- PFXImportCertStore(&cryptBlob, nullptr, CRYPT_EXPORTABLE);
- if (certStore != nullptr) {
- // There should only be 1 cert.
- certContext =
- CertEnumCertificatesInStore(certStore, certContext);
- if (certContext != nullptr) {
- // The hash is 20 bytes
- BYTE hashData[20];
- DWORD hashLength = 20;
-
- // Buffer to print the hash. Each byte takes 2 chars +
- // terminating character
- char hashPrint[41];
- char* pHashPrint = hashPrint;
- // Get the hash property from the certificate
- if (CertGetCertificateContextProperty(
- certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) {
- for (DWORD i = 0; i < hashLength; i++) {
- // Convert each byte to hexadecimal
- snprintf(pHashPrint, 3, "%02X", hashData[i]);
- pHashPrint += 2;
- }
- *pHashPrint = '\0';
- thumbprint = hashPrint;
- }
- CertFreeCertificateContext(certContext);
- }
- CertCloseStore(certStore, 0);
- }
- }
- }
- }
- }
- CloseHandle(certFile);
- }
-
- return thumbprint;
-}
-# endif
-#endif
-
void cmSystemTools::Glob(const std::string& directory,
const std::string& regexp,
std::vector<std::string>& files)
@@ -1900,6 +1840,12 @@ bool cmSystemTools::IsPathToFramework(const std::string& path)
cmHasLiteralSuffix(path, ".framework"));
}
+bool cmSystemTools::IsPathToXcFramework(const std::string& path)
+{
+ return (cmSystemTools::FileIsFullPath(path) &&
+ cmHasLiteralSuffix(path, ".xcframework"));
+}
+
bool cmSystemTools::IsPathToMacOSSharedLibrary(const std::string& path)
{
return (cmSystemTools::FileIsFullPath(path) &&
@@ -2297,9 +2243,10 @@ bool cmSystemTools::ListTar(const std::string& outFileName,
#endif
}
-int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
- cmDuration timeout, std::vector<char>& out,
- std::vector<char>& err)
+cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
+ uv_loop_t* loop, uv_stream_t* outPipe, uv_stream_t* errPipe,
+ std::string& line, cmDuration timeout, std::vector<char>& out,
+ std::vector<char>& err)
{
line.clear();
auto outiter = out.begin();
@@ -2321,7 +2268,7 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
line.append(out.data(), length);
}
out.erase(out.begin(), outiter + 1);
- return cmsysProcess_Pipe_STDOUT;
+ return WaitForLineResult::STDOUT;
}
}
@@ -2339,33 +2286,66 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
line.append(err.data(), length);
}
err.erase(err.begin(), erriter + 1);
- return cmsysProcess_Pipe_STDERR;
+ return WaitForLineResult::STDERR;
}
}
// No newlines found. Wait for more data from the process.
- int length;
- char* data;
- double timeoutAsDbl = timeout.count();
- int pipe =
- cmsysProcess_WaitForData(process, &data, &length, &timeoutAsDbl);
- if (pipe == cmsysProcess_Pipe_Timeout) {
+ struct ReadData
+ {
+ uv_stream_t* Stream;
+ std::vector<char> Buffer;
+ bool Read = false;
+ bool Finished = false;
+ };
+ auto startRead =
+ [](uv_stream_t* stream,
+ ReadData& data) -> std::unique_ptr<cmUVStreamReadHandle> {
+ data.Stream = stream;
+ return cmUVStreamRead(
+ stream,
+ [&data](std::vector<char> buf) {
+ data.Buffer = std::move(buf);
+ data.Read = true;
+ uv_read_stop(data.Stream);
+ },
+ [&data]() { data.Finished = true; });
+ };
+ ReadData outData;
+ auto outHandle = startRead(outPipe, outData);
+ ReadData errData;
+ auto errHandle = startRead(errPipe, errData);
+
+ cm::uv_timer_ptr timer;
+ bool timedOut = false;
+ timer.init(*loop, &timedOut);
+ timer.start(
+ [](uv_timer_t* handle) {
+ auto* timedOutPtr = static_cast<bool*>(handle->data);
+ *timedOutPtr = true;
+ },
+ static_cast<uint64_t>(timeout.count() * 1000.0), 0);
+
+ uv_run(loop, UV_RUN_ONCE);
+ if (timedOut) {
// Timeout has been exceeded.
- return pipe;
+ return WaitForLineResult::Timeout;
}
- if (pipe == cmsysProcess_Pipe_STDOUT) {
- processOutput.DecodeText(data, length, strdata, 1);
+ if (outData.Read) {
+ processOutput.DecodeText(outData.Buffer.data(), outData.Buffer.size(),
+ strdata, 1);
// Append to the stdout buffer.
std::vector<char>::size_type size = out.size();
cm::append(out, strdata);
outiter = out.begin() + size;
- } else if (pipe == cmsysProcess_Pipe_STDERR) {
- processOutput.DecodeText(data, length, strdata, 2);
+ } else if (errData.Read) {
+ processOutput.DecodeText(errData.Buffer.data(), errData.Buffer.size(),
+ strdata, 2);
// Append to the stderr buffer.
std::vector<char>::size_type size = err.size();
cm::append(err, strdata);
erriter = err.begin() + size;
- } else if (pipe == cmsysProcess_Pipe_None) {
+ } else if (outData.Finished && errData.Finished) {
// Both stdout and stderr pipes have broken. Return leftover data.
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
@@ -2382,14 +2362,20 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
if (!out.empty()) {
line.append(out.data(), outiter - out.begin());
out.erase(out.begin(), out.end());
- return cmsysProcess_Pipe_STDOUT;
+ return WaitForLineResult::STDOUT;
}
if (!err.empty()) {
line.append(err.data(), erriter - err.begin());
err.erase(err.begin(), err.end());
- return cmsysProcess_Pipe_STDERR;
+ return WaitForLineResult::STDERR;
}
- return cmsysProcess_Pipe_None;
+ return WaitForLineResult::None;
+ }
+ if (!outData.Finished) {
+ uv_read_stop(outPipe);
+ }
+ if (!errData.Finished) {
+ uv_read_stop(errPipe);
}
}
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 7d55d4b..7e33e58 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -18,11 +18,11 @@
#include <cm/optional>
#include <cm/string_view>
-#include "cmsys/Process.h"
+#include <cm3p/uv.h>
+
#include "cmsys/Status.hxx" // IWYU pragma: export
#include "cmsys/SystemTools.hxx" // IWYU pragma: export
-#include "cmCryptoHash.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
@@ -111,6 +111,9 @@ public:
//! Return true if the path is a framework
static bool IsPathToFramework(const std::string& path);
+ //! Return true if the path is a xcframework
+ static bool IsPathToXcFramework(const std::string& path);
+
//! Return true if the path is a macOS non-framework shared library (aka
//! .dylib)
static bool IsPathToMacOSSharedLibrary(const std::string& path);
@@ -211,20 +214,6 @@ public:
static void MoveFileIfDifferent(const std::string& source,
const std::string& destination);
-#ifndef CMAKE_BOOTSTRAP
- //! Compute the hash of a file
- static std::string ComputeFileHash(const std::string& source,
- cmCryptoHash::Algo algo);
-
- /** Compute the md5sum of a string. */
- static std::string ComputeStringMD5(const std::string& input);
-
-# ifdef _WIN32
- //! Get the SHA thumbprint for a certificate file
- static std::string ComputeCertificateThumbprint(const std::string& source);
-# endif
-#endif
-
/**
* Run a single executable command
*
@@ -302,7 +291,7 @@ public:
std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd);
- static size_t CalculateCommandLineLengthLimit();
+ static std::size_t CalculateCommandLineLengthLimit();
static void DisableRunCommandOutput() { s_DisableRunCommandOutput = true; }
static void EnableRunCommandOutput() { s_DisableRunCommandOutput = false; }
@@ -351,10 +340,20 @@ public:
*/
static void ReportLastSystemError(const char* m);
- /** a general output handler for cmsysProcess */
- static int WaitForLine(cmsysProcess* process, std::string& line,
- cmDuration timeout, std::vector<char>& out,
- std::vector<char>& err);
+ enum class WaitForLineResult
+ {
+ None,
+ STDOUT,
+ STDERR,
+ Timeout,
+ };
+
+ /** a general output handler for libuv */
+ static WaitForLineResult WaitForLine(uv_loop_t* loop, uv_stream_t* outPipe,
+ uv_stream_t* errPipe, std::string& line,
+ cmDuration timeout,
+ std::vector<char>& out,
+ std::vector<char>& err);
static void SetForceUnixPaths(bool v) { s_ForceUnixPaths = v; }
static bool GetForceUnixPaths() { return s_ForceUnixPaths; }
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index b53adf8..ace93e8 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -40,6 +40,7 @@
#include "cmSystemTools.h"
#include "cmTargetPropertyComputer.h"
#include "cmValue.h"
+#include "cmXcFramework.h"
#include "cmake.h"
template <>
@@ -245,9 +246,9 @@ struct UsageRequirementProperty
{
}
- void CopyFromDirectory(cmBTStringRange directoryEntries)
+ void CopyFromEntries(cmBTStringRange entries)
{
- return cm::append(this->Entries, directoryEntries);
+ return cm::append(this->Entries, entries);
}
enum class Action
@@ -672,6 +673,11 @@ public:
UsageRequirementProperty InterfaceLinkLibraries;
UsageRequirementProperty InterfaceLinkLibrariesDirect;
UsageRequirementProperty InterfaceLinkLibrariesDirectExclude;
+ UsageRequirementProperty ImportedCxxModulesIncludeDirectories;
+ UsageRequirementProperty ImportedCxxModulesCompileDefinitions;
+ UsageRequirementProperty ImportedCxxModulesCompileFeatures;
+ UsageRequirementProperty ImportedCxxModulesCompileOptions;
+ UsageRequirementProperty ImportedCxxModulesLinkLibraries;
FileSetType HeadersFileSets;
FileSetType CxxModulesFileSets;
@@ -722,6 +728,14 @@ cmTargetInternals::cmTargetInternals()
, InterfaceLinkLibrariesDirect("INTERFACE_LINK_LIBRARIES_DIRECT"_s)
, InterfaceLinkLibrariesDirectExclude(
"INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s)
+ , ImportedCxxModulesIncludeDirectories(
+ "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES"_s)
+ , ImportedCxxModulesCompileDefinitions(
+ "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS"_s)
+ , ImportedCxxModulesCompileFeatures(
+ "IMPORTED_CXX_MODULES_COMPILE_FEATURES"_s)
+ , ImportedCxxModulesCompileOptions("IMPORTED_CXX_MODULES_COMPILE_OPTIONS"_s)
+ , ImportedCxxModulesLinkLibraries("IMPORTED_CXX_MODULES_LINK_LIBRARIES"_s)
, HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s,
"HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s,
"The default header set"_s, "Header set"_s,
@@ -811,12 +825,12 @@ std::pair<bool, cmValue> FileSetType::ReadProperties(
did_read = true;
} else if (prop == this->SelfEntries.PropertyName) {
static std::string output;
- output = cmJoin(this->SelfEntries.Entries, ";"_s);
+ output = cmList::to_string(this->SelfEntries.Entries);
value = cmValue(output);
did_read = true;
} else if (prop == this->InterfaceEntries.PropertyName) {
static std::string output;
- output = cmJoin(this->InterfaceEntries.Entries, ";"_s);
+ output = cmList::to_string(this->InterfaceEntries.Entries);
value = cmValue(output);
did_read = true;
} else if (cmHasPrefix(prop, this->DirectoryPrefix)) {
@@ -899,7 +913,7 @@ std::pair<bool, cmValue> UsageRequirementProperty::Read(
if (!this->Entries.empty()) {
// Storage to back the returned `cmValue`.
static std::string output;
- output = cmJoin(this->Entries, ";");
+ output = cmList::to_string(this->Entries);
value = cmValue(output);
}
did_read = true;
@@ -950,7 +964,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (this->IsNormal()) {
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
- this->impl->IncludeDirectories.CopyFromDirectory(
+ this->impl->IncludeDirectories.CopyFromEntries(
this->impl->Makefile->GetIncludeDirectoriesEntries());
{
@@ -959,11 +973,11 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
sysInc.end());
}
- this->impl->CompileOptions.CopyFromDirectory(
+ this->impl->CompileOptions.CopyFromEntries(
this->impl->Makefile->GetCompileOptionsEntries());
- this->impl->LinkOptions.CopyFromDirectory(
+ this->impl->LinkOptions.CopyFromEntries(
this->impl->Makefile->GetLinkOptionsEntries());
- this->impl->LinkDirectories.CopyFromDirectory(
+ this->impl->LinkDirectories.CopyFromEntries(
this->impl->Makefile->GetLinkDirectoriesEntries());
}
@@ -1734,6 +1748,186 @@ cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const
return cmMakeRange(this->impl->InterfaceLinkLibrariesDirectExclude.Entries);
}
+void cmTarget::CopyPolicyStatuses(cmTarget const* tgt)
+{
+ // Normal targets cannot be the target of a copy.
+ assert(!this->IsNormal());
+ // Imported targets cannot be the target of a copy.
+ assert(!this->IsImported());
+ // Only imported targets can be the source of a copy.
+ assert(tgt->IsImported());
+
+ this->impl->PolicyMap = tgt->impl->PolicyMap;
+}
+
+void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt)
+{
+ // Normal targets cannot be the target of a copy.
+ assert(!this->IsNormal());
+ // Imported targets cannot be the target of a copy.
+ assert(!this->IsImported());
+ // Only imported targets can be the source of a copy.
+ assert(tgt->IsImported());
+
+ this->impl->IncludeDirectories.Entries.clear();
+ this->impl->IncludeDirectories.CopyFromEntries(
+ cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
+ this->impl->CompileDefinitions.Entries.clear();
+ this->impl->CompileDefinitions.CopyFromEntries(
+ cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
+ this->impl->CompileFeatures.Entries.clear();
+ this->impl->CompileFeatures.CopyFromEntries(
+ cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
+ this->impl->CompileOptions.Entries.clear();
+ this->impl->CompileOptions.CopyFromEntries(
+ cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
+ this->impl->LinkLibraries.Entries.clear();
+ this->impl->LinkLibraries.CopyFromEntries(
+ cmMakeRange(tgt->impl->LinkLibraries.Entries));
+
+ // Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
+ // target's `PRIVATE`.
+ this->impl->CxxModulesFileSets.SelfEntries.Entries.clear();
+ this->impl->CxxModulesFileSets.SelfEntries.Entries =
+ tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries;
+}
+
+void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
+{
+ // Normal targets cannot be the target of a copy.
+ assert(!this->IsNormal());
+ // Imported targets cannot be the target of a copy.
+ assert(!this->IsImported());
+ // Only imported targets can be the source of a copy.
+ assert(tgt->IsImported());
+
+ // The list of properties that are relevant here include:
+ // - compilation-specific properties for any language or platform
+ // - compilation-specific properties for C++
+ // - build graph-specific properties that affect compilation
+ // - IDE metadata properties
+ // - static analysis properties
+
+ static const std::string propertiesToCopy[] = {
+ // Compilation properties
+ "DEFINE_SYMBOL",
+ "DEPRECATION",
+ "NO_SYSTEM_FROM_IMPORTED",
+ "POSITION_INDEPENDENT_CODE",
+ "VISIBILITY_INLINES_HIDDEN",
+ // -- Platforms
+ // ---- Android
+ "ANDROID_API",
+ "ANDROID_API_MIN",
+ "ANDROID_ARCH",
+ "ANDROID_STL_TYPE",
+ // ---- macOS
+ "OSX_ARCHITECTURES",
+ // ---- Windows
+ "MSVC_DEBUG_INFORMATION_FORMAT",
+ "MSVC_RUNTIME_LIBRARY",
+ "VS_PLATFORM_TOOLSET",
+ // ---- OpenWatcom
+ "WATCOM_RUNTIME_LIBRARY",
+ // -- Language
+ // ---- C++
+ "CXX_COMPILER_LAUNCHER",
+ "CXX_STANDARD",
+ "CXX_STANDARD_REQUIRED",
+ "CXX_EXTENSIONS",
+ "CXX_VISIBILITY_PRESET",
+
+ // Static analysis
+ "CXX_CLANG_TIDY",
+ "CXX_CLANG_TIDY_EXPORT_FIXES_DIR",
+ "CXX_CPPLINT",
+ "CXX_CPPCHECK",
+ "CXX_INCLUDE_WHAT_YOU_USE",
+
+ // Build graph properties
+ "EXCLUDE_FROM_ALL",
+ "EXCLUDE_FROM_DEFAULT_BUILD",
+ "OPTIMIZE_DEPENDENCIES",
+ // -- Ninja
+ "JOB_POOL_COMPILE",
+ // -- Visual Studio
+ "VS_NO_COMPILE_BATCHING",
+ "VS_PROJECT_IMPORT",
+
+ // Metadata
+ "EchoString",
+ "EXPORT_COMPILE_COMMANDS",
+ "FOLDER",
+ "LABELS",
+ "PROJECT_LABEL",
+ "SYSTEM",
+ };
+
+ auto copyProperty = [this, tgt](std::string const& prop) -> cmValue {
+ cmValue value = tgt->GetProperty(prop);
+ // Always set the property; it may have been explicitly unset.
+ this->SetProperty(prop, value);
+ return value;
+ };
+
+ for (auto const& prop : propertiesToCopy) {
+ copyProperty(prop);
+ }
+
+ static const cm::static_string_view perConfigPropertiesToCopy[] = {
+ "EXCLUDE_FROM_DEFAULT_BUILD_"_s,
+ "IMPORTED_CXX_MODULES_"_s,
+ "MAP_IMPORTED_CONFIG_"_s,
+ "OSX_ARCHITECTURES_"_s,
+ };
+
+ std::vector<std::string> configNames =
+ this->impl->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
+ for (std::string const& configName : configNames) {
+ std::string configUpper = cmSystemTools::UpperCase(configName);
+ for (auto const& perConfigProp : perConfigPropertiesToCopy) {
+ copyProperty(cmStrCat(perConfigProp, configUpper));
+ }
+ }
+
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ cmValue xcodeGenerateScheme = copyProperty("XCODE_GENERATE_SCHEME");
+
+ // TODO: Make sure these show up on the imported target in the first place
+ // XCODE_ATTRIBUTE_???
+
+ if (xcodeGenerateScheme.IsOn()) {
+#ifdef __APPLE__
+ static const std::string xcodeSchemePropertiesToCopy[] = {
+ // FIXME: Do all of these apply? Do they matter?
+ "XCODE_SCHEME_ADDRESS_SANITIZER",
+ "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN",
+ "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER",
+ "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS",
+ "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE",
+ "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION",
+ "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION",
+ "XCODE_SCHEME_GUARD_MALLOC",
+ "XCODE_SCHEME_LAUNCH_CONFIGURATION",
+ "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP",
+ "XCODE_SCHEME_MALLOC_GUARD_EDGES",
+ "XCODE_SCHEME_MALLOC_SCRIBBLE",
+ "XCODE_SCHEME_MALLOC_STACK",
+ "XCODE_SCHEME_THREAD_SANITIZER",
+ "XCODE_SCHEME_THREAD_SANITIZER_STOP",
+ "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER",
+ "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP",
+ "XCODE_SCHEME_ZOMBIE_OBJECTS",
+ };
+
+ for (auto const& xcodeProperty : xcodeSchemePropertiesToCopy) {
+ copyProperty(xcodeProperty);
+ }
+#endif
+ }
+ }
+}
+
cmBTStringRange cmTarget::GetHeaderSetsEntries() const
{
return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries);
@@ -1776,6 +1970,11 @@ MAKE_PROP(IMPORTED);
MAKE_PROP(IMPORTED_GLOBAL);
MAKE_PROP(INCLUDE_DIRECTORIES);
MAKE_PROP(LINK_OPTIONS);
+MAKE_PROP(IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES);
+MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS);
+MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_FEATURES);
+MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_OPTIONS);
+MAKE_PROP(IMPORTED_CXX_MODULES_LINK_LIBRARIES);
MAKE_PROP(LINK_DIRECTORIES);
MAKE_PROP(LINK_LIBRARIES);
MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES);
@@ -1845,6 +2044,11 @@ void cmTarget::SetProperty(const std::string& prop, cmValue value)
&this->impl->InterfaceLinkLibraries,
&this->impl->InterfaceLinkLibrariesDirect,
&this->impl->InterfaceLinkLibrariesDirectExclude,
+ &this->impl->ImportedCxxModulesIncludeDirectories,
+ &this->impl->ImportedCxxModulesCompileDefinitions,
+ &this->impl->ImportedCxxModulesCompileFeatures,
+ &this->impl->ImportedCxxModulesCompileOptions,
+ &this->impl->ImportedCxxModulesLinkLibraries,
};
for (auto* usageRequirement : usageRequirements) {
@@ -2018,6 +2222,11 @@ void cmTarget::AppendProperty(const std::string& prop,
&this->impl->InterfaceLinkLibraries,
&this->impl->InterfaceLinkLibrariesDirect,
&this->impl->InterfaceLinkLibrariesDirectExclude,
+ &this->impl->ImportedCxxModulesIncludeDirectories,
+ &this->impl->ImportedCxxModulesCompileDefinitions,
+ &this->impl->ImportedCxxModulesCompileFeatures,
+ &this->impl->ImportedCxxModulesCompileOptions,
+ &this->impl->ImportedCxxModulesLinkLibraries,
};
for (auto* usageRequirement : usageRequirements) {
@@ -2130,7 +2339,7 @@ cmValue cmTargetInternals::GetFileSetDirectories(
return nullptr;
}
static std::string output;
- output = cmJoin(fileSet->GetDirectoryEntries(), ";"_s);
+ output = cmList::to_string(fileSet->GetDirectoryEntries());
return cmValue(output);
}
@@ -2150,7 +2359,7 @@ cmValue cmTargetInternals::GetFileSetPaths(cmTarget const* self,
return nullptr;
}
static std::string output;
- output = cmJoin(fileSet->GetFileEntries(), ";"_s);
+ output = cmList::to_string(fileSet->GetFileEntries());
return cmValue(output);
}
@@ -2422,6 +2631,7 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
propC_STANDARD,
propCXX_STANDARD,
propCUDA_STANDARD,
+ propHIP_STANDARD,
propOBJC_STANDARD,
propOBJCXX_STANDARD,
propLINK_LIBRARIES,
@@ -2443,11 +2653,16 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
propINTERFACE_LINK_LIBRARIES,
propINTERFACE_LINK_LIBRARIES_DIRECT,
propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
+ propIMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES,
+ propIMPORTED_CXX_MODULES_COMPILE_DEFINITIONS,
+ propIMPORTED_CXX_MODULES_COMPILE_FEATURES,
+ propIMPORTED_CXX_MODULES_COMPILE_OPTIONS,
+ propIMPORTED_CXX_MODULES_LINK_LIBRARIES,
};
if (specialProps.count(prop)) {
if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
- prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
- prop == propOBJCXX_STANDARD) {
+ prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
+ prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD) {
auto propertyIter = this->impl->LanguageStandardProperties.find(prop);
if (propertyIter == this->impl->LanguageStandardProperties.end()) {
return nullptr;
@@ -2468,6 +2683,11 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
&this->impl->InterfaceLinkLibraries,
&this->impl->InterfaceLinkLibrariesDirect,
&this->impl->InterfaceLinkLibrariesDirectExclude,
+ &this->impl->ImportedCxxModulesIncludeDirectories,
+ &this->impl->ImportedCxxModulesCompileDefinitions,
+ &this->impl->ImportedCxxModulesCompileFeatures,
+ &this->impl->ImportedCxxModulesCompileOptions,
+ &this->impl->ImportedCxxModulesLinkLibraries,
};
for (auto const* usageRequirement : usageRequirements) {
@@ -2495,7 +2715,7 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
[](const BT<std::pair<std::string, bool>>& item) -> std::string {
return item.Value.first;
});
- output = cmJoin(utilities, ";");
+ output = cmList::to_string(utilities);
return cmValue(output);
}
if (prop == propIMPORTED) {
@@ -2650,11 +2870,32 @@ bool cmTarget::IsPerConfig() const
return this->impl->PerConfig;
}
+bool cmTarget::IsRuntimeBinary() const
+{
+ switch (this->GetType()) {
+ case cmStateEnums::EXECUTABLE:
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ return true;
+ case cmStateEnums::OBJECT_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
+ case cmStateEnums::UTILITY:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ case cmStateEnums::GLOBAL_TARGET:
+ case cmStateEnums::UNKNOWN_LIBRARY:
+ break;
+ }
+ return false;
+}
+
bool cmTarget::CanCompileSources() const
{
if (this->IsImported()) {
return false;
}
+ if (this->IsSynthetic()) {
+ return true;
+ }
switch (this->GetType()) {
case cmStateEnums::EXECUTABLE:
case cmStateEnums::STATIC_LIBRARY:
@@ -2779,6 +3020,8 @@ std::string cmTarget::ImportedGetFullPath(
case cmStateEnums::RuntimeBinaryArtifact:
if (loc) {
result = *loc;
+ } else if (imp) {
+ result = *imp;
} else {
std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
if (cmValue config_location = this->GetProperty(impProp)) {
@@ -2787,6 +3030,35 @@ std::string cmTarget::ImportedGetFullPath(
this->GetProperty("IMPORTED_LOCATION")) {
result = *location;
}
+ if (result.empty() &&
+ (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())) {
+ impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
+ if (cmValue config_implib = this->GetProperty(impProp)) {
+ result = *config_implib;
+ } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) {
+ result = *implib;
+ }
+ }
+ }
+ if (this->IsApple() &&
+ (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+ this->impl->TargetType == cmStateEnums::STATIC_LIBRARY ||
+ this->impl->TargetType == cmStateEnums::UNKNOWN_LIBRARY) &&
+ cmSystemTools::IsPathToXcFramework(result)) {
+ auto plist = cmParseXcFrameworkPlist(result, *this->impl->Makefile,
+ this->impl->Backtrace);
+ if (!plist) {
+ return "";
+ }
+ auto const* library = plist->SelectSuitableLibrary(
+ *this->impl->Makefile, this->impl->Backtrace);
+ if (library) {
+ result = cmStrCat(result, '/', library->LibraryIdentifier, '/',
+ library->LibraryPath);
+ } else {
+ return "";
+ }
}
break;
@@ -2812,7 +3084,10 @@ std::string cmTarget::ImportedGetFullPath(
std::string unset;
std::string configuration;
- if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
+ if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
+ artifact == cmStateEnums::RuntimeBinaryArtifact) {
+ unset = "IMPORTED_LOCATION or IMPORTED_IMPLIB";
+ } else if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
unset = "IMPORTED_LOCATION";
} else if (artifact == cmStateEnums::ImportLibraryArtifact) {
unset = "IMPORTED_IMPLIB";
@@ -2985,11 +3260,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
}
// If we needed to find one of the mapped configurations but did not
- // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
- // library or an executable with exports.
- bool allowImp = (this->IsDLLPlatform() &&
- (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->IsExecutableWithExports())) ||
+ // There may be only IMPORTED_IMPLIB for a shared library or an executable
+ // with exports.
+ bool allowImp = (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->IsExecutableWithExports()) ||
(this->IsAIX() && this->IsExecutableWithExports()) ||
(this->GetMakefile()->PlatformSupportsAppleTextStubs() &&
this->IsSharedLibraryWithExports());
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2d12a70..b77ea0c 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -15,7 +15,7 @@
#include <cm/optional>
#include "cmAlgorithms.h"
-#include "cmFileSet.h"
+#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -23,20 +23,16 @@
#include "cmValue.h"
class cmCustomCommand;
+class cmFileSet;
class cmGlobalGenerator;
class cmInstallTargetGenerator;
-class cmListFileBacktrace;
-class cmListFileContext;
class cmMakefile;
class cmPropertyMap;
class cmSourceFile;
class cmTargetExport;
class cmTargetInternals;
-template <typename T>
-class BT;
-template <typename T>
-class BTs;
+enum class cmFileSetVisibility;
/** \class cmTarget
* \brief Represent a library or executable target loaded from a makefile.
@@ -216,6 +212,7 @@ public:
bool IsImported() const;
bool IsImportedGloballyVisible() const;
bool IsPerConfig() const;
+ bool IsRuntimeBinary() const;
bool CanCompileSources() const;
bool GetMappedConfig(std::string const& desired_config, cmValue& loc,
@@ -294,6 +291,10 @@ public:
cmBTStringRange GetLinkInterfaceDirectEntries() const;
cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const;
+ void CopyPolicyStatuses(cmTarget const* tgt);
+ void CopyImportedCxxModulesEntries(cmTarget const* tgt);
+ void CopyImportedCxxModulesProperties(cmTarget const* tgt);
+
cmBTStringRange GetHeaderSetsEntries() const;
cmBTStringRange GetCxxModuleSetsEntries() const;
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index aa1abdd..37c125b 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetCompileFeaturesCommand.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStandardLevelResolver.h"
@@ -43,7 +44,7 @@ private:
std::string Join(const std::vector<std::string>& content) override
{
- return cmJoin(content, ";");
+ return cmList::to_string(content);
}
};
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index 8ca3842..e73a75f 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetCompileOptionsCommand.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -44,7 +45,7 @@ private:
std::string Join(const std::vector<std::string>& content) override
{
- return cmJoin(content, ";");
+ return cmList::to_string(content);
}
};
diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx
index 3ba27a8..dddb348 100644
--- a/Source/cmTargetLinkDirectoriesCommand.cxx
+++ b/Source/cmTargetLinkDirectoriesCommand.cxx
@@ -3,6 +3,7 @@
#include "cmTargetLinkDirectoriesCommand.h"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -58,7 +59,7 @@ std::string TargetLinkDirectoriesImpl::Join(
directories.push_back(unixPath);
}
- return cmJoin(directories, ";");
+ return cmList::to_string(directories);
}
} // namespace
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 03d7c9f..bfd3972 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -3,6 +3,7 @@
#include "cmTargetLinkLibrariesCommand.h"
#include <cassert>
+#include <cstddef>
#include <memory>
#include <sstream>
#include <unordered_set>
diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx
index 3ea2d71..cd93835 100644
--- a/Source/cmTargetLinkOptionsCommand.cxx
+++ b/Source/cmTargetLinkOptionsCommand.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetLinkOptionsCommand.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -36,7 +37,7 @@ private:
std::string Join(const std::vector<std::string>& content) override
{
- return cmJoin(content, ";");
+ return cmList::to_string(content);
}
};
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index 4dd158d..0173a92 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -5,6 +5,7 @@
#include <utility>
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -73,7 +74,7 @@ private:
std::string Join(const std::vector<std::string>& content) override
{
- return cmJoin(content, ";");
+ return cmList::to_string(content);
}
};
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index 12328b1..3d484f5 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -98,7 +98,7 @@ private:
std::string Join(const std::vector<std::string>& content) override
{
- return cmJoin(content, ";");
+ return cmList::to_string(content);
}
enum class IsInterface
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
index 12c121f..914172b 100644
--- a/Source/cmTransformDepfile.cxx
+++ b/Source/cmTransformDepfile.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <functional>
#include <string>
-#include <type_traits>
#include <utility>
#include <vector>
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index e05b2d52..34e6a70 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -11,6 +11,9 @@
namespace cm {
+template <typename T>
+struct uv_handle_deleter;
+
struct uv_loop_deleter
{
void operator()(uv_loop_t* loop) const;
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index ed5f38b..655e52a 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -1,16 +1,11 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmConfigure.h"
-
#include "cmUVProcessChain.h"
#include <array>
-#include <cassert>
#include <csignal>
#include <cstdio>
#include <istream> // IWYU pragma: keep
-#include <iterator>
-#include <type_traits>
#include <utility>
#include <cm/memory>
@@ -19,43 +14,24 @@
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
-#include "cmUVStreambuf.h"
struct cmUVProcessChain::InternalData
{
- struct BasicStreamData
+ struct StreamData
{
- cmUVStreambuf Streambuf;
- cm::uv_pipe_ptr BuiltinStream;
+ int BuiltinStream = -1;
uv_stdio_container_t Stdio;
};
- template <typename IOStream>
- struct StreamData : public BasicStreamData
- {
- StreamData()
- : BuiltinIOStream(&this->Streambuf)
- {
- }
-
- IOStream BuiltinIOStream;
-
- IOStream* GetBuiltinStream()
- {
- if (this->BuiltinStream.get()) {
- return &this->BuiltinIOStream;
- }
- return nullptr;
- }
- };
-
struct ProcessData
{
cmUVProcessChain::InternalData* Data;
cm::uv_process_ptr Process;
+ cm::uv_pipe_ptr InputPipe;
cm::uv_pipe_ptr OutputPipe;
- bool Finished = false;
Status ProcessStatus;
+
+ void Finish();
};
const cmUVProcessChainBuilder* Builder = nullptr;
@@ -64,18 +40,21 @@ struct cmUVProcessChain::InternalData
cm::uv_loop_ptr Loop;
- StreamData<std::istream> OutputStreamData;
- StreamData<std::istream> ErrorStreamData;
+ StreamData InputStreamData;
+ StreamData OutputStreamData;
+ StreamData ErrorStreamData;
+ cm::uv_pipe_ptr TempOutputPipe;
+ cm::uv_pipe_ptr TempErrorPipe;
unsigned int ProcessesCompleted = 0;
std::vector<std::unique_ptr<ProcessData>> Processes;
bool Prepare(const cmUVProcessChainBuilder* builder);
- bool AddCommand(const cmUVProcessChainBuilder::ProcessConfiguration& config,
- bool first, bool last);
- bool Finish();
-
- static const Status* GetStatus(const ProcessData& data);
+ void SpawnProcess(
+ std::size_t index,
+ const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
+ bool last);
+ void Finish();
};
cmUVProcessChainBuilder::cmUVProcessChainBuilder()
@@ -132,9 +111,6 @@ cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream(
{
switch (stdio) {
case Stream_INPUT:
- // FIXME
- break;
-
case Stream_OUTPUT:
case Stream_ERROR: {
auto& streamData = this->Stdio[stdio];
@@ -167,11 +143,9 @@ cmUVProcessChain cmUVProcessChainBuilder::Start() const
return chain;
}
- for (auto it = this->Processes.begin(); it != this->Processes.end(); ++it) {
- if (!chain.Data->AddCommand(*it, it == this->Processes.begin(),
- it == std::prev(this->Processes.end()))) {
- return chain;
- }
+ for (std::size_t i = 0; i < this->Processes.size(); i++) {
+ chain.Data->SpawnProcess(i, this->Processes[i], i == 0,
+ i == this->Processes.size() - 1);
}
chain.Data->Finish();
@@ -179,20 +153,30 @@ cmUVProcessChain cmUVProcessChainBuilder::Start() const
return chain;
}
-const cmUVProcessChain::Status* cmUVProcessChain::InternalData::GetStatus(
- const cmUVProcessChain::InternalData::ProcessData& data)
-{
- if (data.Finished) {
- return &data.ProcessStatus;
- }
- return nullptr;
-}
-
bool cmUVProcessChain::InternalData::Prepare(
const cmUVProcessChainBuilder* builder)
{
this->Builder = builder;
+ auto const& input =
+ this->Builder->Stdio[cmUVProcessChainBuilder::Stream_INPUT];
+ auto& inputData = this->InputStreamData;
+ switch (input.Type) {
+ case cmUVProcessChainBuilder::None:
+ inputData.Stdio.flags = UV_IGNORE;
+ break;
+
+ case cmUVProcessChainBuilder::Builtin: {
+ // FIXME
+ break;
+ }
+
+ case cmUVProcessChainBuilder::External:
+ inputData.Stdio.flags = UV_INHERIT_FD;
+ inputData.Stdio.data.fd = input.FileDescriptor;
+ break;
+ }
+
auto const& error =
this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR];
auto& errorData = this->ErrorStreamData;
@@ -207,12 +191,17 @@ bool cmUVProcessChain::InternalData::Prepare(
return false;
}
- errorData.BuiltinStream.init(*this->Loop, 0);
- if (uv_pipe_open(errorData.BuiltinStream, pipeFd[0]) < 0) {
- return false;
- }
+ errorData.BuiltinStream = pipeFd[0];
errorData.Stdio.flags = UV_INHERIT_FD;
errorData.Stdio.data.fd = pipeFd[1];
+
+ if (this->TempErrorPipe.init(*this->Loop, 0) < 0) {
+ return false;
+ }
+ if (uv_pipe_open(this->TempErrorPipe, errorData.Stdio.data.fd) < 0) {
+ return false;
+ }
+
break;
}
@@ -232,13 +221,25 @@ bool cmUVProcessChain::InternalData::Prepare(
case cmUVProcessChainBuilder::Builtin:
if (this->Builder->MergedBuiltinStreams) {
+ outputData.BuiltinStream = errorData.BuiltinStream;
outputData.Stdio.flags = UV_INHERIT_FD;
outputData.Stdio.data.fd = errorData.Stdio.data.fd;
} else {
- outputData.BuiltinStream.init(*this->Loop, 0);
- outputData.Stdio.flags =
- static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
- outputData.Stdio.data.stream = outputData.BuiltinStream;
+ int pipeFd[2];
+ if (cmGetPipes(pipeFd) < 0) {
+ return false;
+ }
+
+ outputData.BuiltinStream = pipeFd[0];
+ outputData.Stdio.flags = UV_INHERIT_FD;
+ outputData.Stdio.data.fd = pipeFd[1];
+
+ if (this->TempOutputPipe.init(*this->Loop, 0) < 0) {
+ return false;
+ }
+ if (uv_pipe_open(this->TempOutputPipe, outputData.Stdio.data.fd) < 0) {
+ return false;
+ }
}
break;
@@ -248,16 +249,47 @@ bool cmUVProcessChain::InternalData::Prepare(
break;
}
+ bool first = true;
+ for (std::size_t i = 0; i < this->Builder->Processes.size(); i++) {
+ this->Processes.emplace_back(cm::make_unique<ProcessData>());
+ auto& process = *this->Processes.back();
+ process.Data = this;
+ process.ProcessStatus.Finished = false;
+
+ if (!first) {
+ auto& prevProcess = *this->Processes[i - 1];
+
+ int pipeFd[2];
+ if (cmGetPipes(pipeFd) < 0) {
+ return false;
+ }
+
+ if (prevProcess.OutputPipe.init(*this->Loop, 0) < 0) {
+ return false;
+ }
+ if (uv_pipe_open(prevProcess.OutputPipe, pipeFd[1]) < 0) {
+ return false;
+ }
+ if (process.InputPipe.init(*this->Loop, 0) < 0) {
+ return false;
+ }
+ if (uv_pipe_open(process.InputPipe, pipeFd[0]) < 0) {
+ return false;
+ }
+ }
+
+ first = false;
+ }
+
return true;
}
-bool cmUVProcessChain::InternalData::AddCommand(
+void cmUVProcessChain::InternalData::SpawnProcess(
+ std::size_t index,
const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
bool last)
{
- this->Processes.emplace_back(cm::make_unique<ProcessData>());
- auto& process = *this->Processes.back();
- process.Data = this;
+ auto& process = *this->Processes[index];
auto options = uv_process_options_t();
@@ -277,24 +309,18 @@ bool cmUVProcessChain::InternalData::AddCommand(
}
std::array<uv_stdio_container_t, 3> stdio;
- stdio[0] = uv_stdio_container_t();
if (first) {
- stdio[0].flags = UV_IGNORE;
+ stdio[0] = this->InputStreamData.Stdio;
} else {
- assert(this->Processes.size() >= 2);
- auto& prev = *this->Processes[this->Processes.size() - 2];
+ stdio[0] = uv_stdio_container_t();
stdio[0].flags = UV_INHERIT_STREAM;
- stdio[0].data.stream = prev.OutputPipe;
+ stdio[0].data.stream = process.InputPipe;
}
if (last) {
stdio[1] = this->OutputStreamData.Stdio;
} else {
- if (process.OutputPipe.init(*this->Loop, 0) < 0) {
- return false;
- }
stdio[1] = uv_stdio_container_t();
- stdio[1].flags =
- static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
+ stdio[1].flags = UV_INHERIT_STREAM;
stdio[1].data.stream = process.OutputPipe;
}
stdio[2] = this->ErrorStreamData.Stdio;
@@ -304,40 +330,24 @@ bool cmUVProcessChain::InternalData::AddCommand(
options.exit_cb = [](uv_process_t* handle, int64_t exitStatus,
int termSignal) {
auto* processData = static_cast<ProcessData*>(handle->data);
- processData->Finished = true;
processData->ProcessStatus.ExitStatus = exitStatus;
processData->ProcessStatus.TermSignal = termSignal;
- processData->Data->ProcessesCompleted++;
+ processData->Finish();
};
- return process.Process.spawn(*this->Loop, options, &process) >= 0;
+ if ((process.ProcessStatus.SpawnResult =
+ process.Process.spawn(*this->Loop, options, &process)) < 0) {
+ process.Finish();
+ }
+ process.InputPipe.reset();
+ process.OutputPipe.reset();
}
-bool cmUVProcessChain::InternalData::Finish()
+void cmUVProcessChain::InternalData::Finish()
{
- if (this->Builder->Stdio[cmUVProcessChainBuilder::Stream_OUTPUT].Type ==
- cmUVProcessChainBuilder::Builtin &&
- !this->Builder->MergedBuiltinStreams) {
- this->OutputStreamData.Streambuf.open(
- this->OutputStreamData.BuiltinStream);
- }
-
- if (this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR].Type ==
- cmUVProcessChainBuilder::Builtin) {
- cm::uv_pipe_ptr tmpPipe;
- if (tmpPipe.init(*this->Loop, 0) < 0) {
- return false;
- }
- if (uv_pipe_open(tmpPipe, this->ErrorStreamData.Stdio.data.fd) < 0) {
- return false;
- }
- tmpPipe.reset();
-
- this->ErrorStreamData.Streambuf.open(this->ErrorStreamData.BuiltinStream);
- }
-
+ this->TempOutputPipe.reset();
+ this->TempErrorPipe.reset();
this->Valid = true;
- return true;
}
cmUVProcessChain::cmUVProcessChain()
@@ -365,17 +375,14 @@ uv_loop_t& cmUVProcessChain::GetLoop()
return *this->Data->Loop;
}
-std::istream* cmUVProcessChain::OutputStream()
+int cmUVProcessChain::OutputStream()
{
- if (this->Data->Builder->MergedBuiltinStreams) {
- return this->Data->ErrorStreamData.GetBuiltinStream();
- }
- return this->Data->OutputStreamData.GetBuiltinStream();
+ return this->Data->OutputStreamData.BuiltinStream;
}
-std::istream* cmUVProcessChain::ErrorStream()
+int cmUVProcessChain::ErrorStream()
{
- return this->Data->ErrorStreamData.GetBuiltinStream();
+ return this->Data->ErrorStreamData.BuiltinStream;
}
bool cmUVProcessChain::Valid() const
@@ -383,12 +390,12 @@ bool cmUVProcessChain::Valid() const
return this->Data->Valid;
}
-bool cmUVProcessChain::Wait(int64_t milliseconds)
+bool cmUVProcessChain::Wait(uint64_t milliseconds)
{
bool timeout = false;
cm::uv_timer_ptr timer;
- if (milliseconds >= 0) {
+ if (milliseconds > 0) {
timer.init(*this->Data->Loop, &timeout);
timer.start(
[](uv_timer_t* handle) {
@@ -412,19 +419,15 @@ std::vector<const cmUVProcessChain::Status*> cmUVProcessChain::GetStatus()
std::vector<const cmUVProcessChain::Status*> statuses(
this->Data->Processes.size(), nullptr);
for (std::size_t i = 0; i < statuses.size(); i++) {
- statuses[i] = this->GetStatus(i);
+ statuses[i] = &this->GetStatus(i);
}
return statuses;
}
-const cmUVProcessChain::Status* cmUVProcessChain::GetStatus(
+const cmUVProcessChain::Status& cmUVProcessChain::GetStatus(
std::size_t index) const
{
- auto const& process = *this->Data->Processes[index];
- if (process.Finished) {
- return &process.ProcessStatus;
- }
- return nullptr;
+ return this->Data->Processes[index]->ProcessStatus;
}
bool cmUVProcessChain::Finished() const
@@ -435,8 +438,12 @@ bool cmUVProcessChain::Finished() const
std::pair<cmUVProcessChain::ExceptionCode, std::string>
cmUVProcessChain::Status::GetException() const
{
+ if (this->SpawnResult) {
+ return std::make_pair(ExceptionCode::Spawn,
+ uv_strerror(this->SpawnResult));
+ }
#ifdef _WIN32
- if ((this->ExitStatus & 0xF0000000) == 0xC0000000) {
+ if (this->Finished && (this->ExitStatus & 0xF0000000) == 0xC0000000) {
// Child terminated due to exceptional behavior.
switch (this->ExitStatus) {
case STATUS_CONTROL_C_EXIT:
@@ -511,9 +518,8 @@ cmUVProcessChain::Status::GetException() const
}
}
}
- return std::make_pair(ExceptionCode::None, "");
#else
- if (this->TermSignal) {
+ if (this->Finished && this->TermSignal) {
switch (this->TermSignal) {
# ifdef SIGSEGV
case SIGSEGV:
@@ -670,6 +676,12 @@ cmUVProcessChain::Status::GetException() const
}
}
}
- return std::make_pair(ExceptionCode::None, "");
#endif
+ return std::make_pair(ExceptionCode::None, "");
+}
+
+void cmUVProcessChain::InternalData::ProcessData::Finish()
+{
+ this->ProcessStatus.Finished = true;
+ this->Data->ProcessesCompleted++;
}
diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h
index f92742f..0f37e7d 100644
--- a/Source/cmUVProcessChain.h
+++ b/Source/cmUVProcessChain.h
@@ -2,10 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include "cmConfigure.h" // IWYU pragma: keep
+
#include <array>
#include <cstddef> // IWYU pragma: keep
#include <cstdint>
-#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
@@ -74,11 +75,14 @@ public:
Illegal,
Interrupt,
Numerical,
+ Spawn,
Other,
};
struct Status
{
+ int SpawnResult;
+ bool Finished;
int64_t ExitStatus;
int TermSignal;
@@ -96,13 +100,13 @@ public:
uv_loop_t& GetLoop();
// FIXME: Add stdin support
- std::istream* OutputStream();
- std::istream* ErrorStream();
+ int OutputStream();
+ int ErrorStream();
bool Valid() const;
- bool Wait(int64_t milliseconds = -1);
+ bool Wait(uint64_t milliseconds = 0);
std::vector<const Status*> GetStatus() const;
- const Status* GetStatus(std::size_t index) const;
+ const Status& GetStatus(std::size_t index) const;
bool Finished() const;
private:
diff --git a/Source/cmUVStream.h b/Source/cmUVStream.h
new file mode 100644
index 0000000..db051b8
--- /dev/null
+++ b/Source/cmUVStream.h
@@ -0,0 +1,154 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <cassert>
+#include <functional>
+#include <istream>
+
+#include <cm/memory>
+
+#include <cm3p/uv.h>
+
+#include "cmUVHandlePtr.h"
+#include "cmUVStreambuf.h"
+
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+class cmBasicUVIStream : public std::basic_istream<CharT>
+{
+public:
+ cmBasicUVIStream();
+ cmBasicUVIStream(uv_stream_t* stream);
+
+ bool is_open() const;
+
+ void open(uv_stream_t* stream);
+
+ void close();
+
+private:
+ cmBasicUVStreambuf<CharT, Traits> Buffer;
+};
+
+template <typename CharT, typename Traits>
+cmBasicUVIStream<CharT, Traits>::cmBasicUVIStream()
+ : std::basic_istream<CharT, Traits>(&this->Buffer)
+{
+}
+
+template <typename CharT, typename Traits>
+cmBasicUVIStream<CharT, Traits>::cmBasicUVIStream(uv_stream_t* stream)
+ : cmBasicUVIStream()
+{
+ this->open(stream);
+}
+
+template <typename CharT, typename Traits>
+bool cmBasicUVIStream<CharT, Traits>::is_open() const
+{
+ return this->Buffer.is_open();
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVIStream<CharT, Traits>::open(uv_stream_t* stream)
+{
+ this->Buffer.open(stream);
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVIStream<CharT, Traits>::close()
+{
+ this->Buffer.close();
+}
+
+using cmUVIStream = cmBasicUVIStream<char>;
+
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+class cmBasicUVPipeIStream : public cmBasicUVIStream<CharT, Traits>
+{
+public:
+ cmBasicUVPipeIStream();
+ cmBasicUVPipeIStream(uv_loop_t& loop, int fd);
+
+ using cmBasicUVIStream<CharT, Traits>::is_open;
+
+ void open(uv_loop_t& loop, int fd);
+
+ void close();
+
+private:
+ cm::uv_pipe_ptr Pipe;
+};
+
+template <typename CharT, typename Traits>
+cmBasicUVPipeIStream<CharT, Traits>::cmBasicUVPipeIStream() = default;
+
+template <typename CharT, typename Traits>
+cmBasicUVPipeIStream<CharT, Traits>::cmBasicUVPipeIStream(uv_loop_t& loop,
+ int fd)
+{
+ this->open(loop, fd);
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVPipeIStream<CharT, Traits>::open(uv_loop_t& loop, int fd)
+{
+ this->Pipe.init(loop, 0);
+ uv_pipe_open(this->Pipe, fd);
+ this->cmBasicUVIStream<CharT, Traits>::open(this->Pipe);
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVPipeIStream<CharT, Traits>::close()
+{
+ this->cmBasicUVIStream<CharT, Traits>::close();
+ this->Pipe.reset();
+}
+
+using cmUVPipeIStream = cmBasicUVPipeIStream<char>;
+
+class cmUVStreamReadHandle
+{
+private:
+ std::vector<char> Buffer;
+ std::function<void(std::vector<char>)> OnRead;
+ std::function<void()> OnFinish;
+
+ template <typename ReadCallback, typename FinishCallback>
+ friend std::unique_ptr<cmUVStreamReadHandle> cmUVStreamRead(
+ uv_stream_t* stream, ReadCallback onRead, FinishCallback onFinish);
+};
+
+template <typename ReadCallback, typename FinishCallback>
+std::unique_ptr<cmUVStreamReadHandle> cmUVStreamRead(uv_stream_t* stream,
+ ReadCallback onRead,
+ FinishCallback onFinish)
+{
+ auto handle = cm::make_unique<cmUVStreamReadHandle>();
+ handle->OnRead = std::move(onRead);
+ handle->OnFinish = std::move(onFinish);
+
+ stream->data = handle.get();
+ uv_read_start(
+ stream,
+ [](uv_handle_t* s, std::size_t suggestedSize, uv_buf_t* buffer) {
+ auto* data = static_cast<cmUVStreamReadHandle*>(s->data);
+ data->Buffer.resize(suggestedSize);
+ buffer->base = data->Buffer.data();
+ buffer->len = suggestedSize;
+ },
+ [](uv_stream_t* s, ssize_t nread, const uv_buf_t* buffer) {
+ auto* data = static_cast<cmUVStreamReadHandle*>(s->data);
+ if (nread > 0) {
+ (void)buffer;
+ assert(buffer->base == data->Buffer.data());
+ data->Buffer.resize(nread);
+ data->OnRead(std::move(data->Buffer));
+ } else if (nread < 0 /*|| nread == UV_EOF*/) {
+ data->OnFinish();
+ uv_read_stop(s);
+ }
+ });
+
+ return handle;
+}
diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h
index efe45de..4f7b209 100644
--- a/Source/cmUVStreambuf.h
+++ b/Source/cmUVStreambuf.h
@@ -14,7 +14,8 @@
/*
* This file is based on example code from:
*
- * http://www.voidcn.com/article/p-vjnlygmc-gy.html
+ * https://web.archive.org/web/20170515211805/
+ * http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
*
* The example code was distributed under the following license:
*
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 6688668..5f5d3e4 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -104,20 +104,20 @@ std::string cmUuid::BinaryToString(const unsigned char* input) const
size_t bytes = kUuidGroups[i];
for (size_t j = 0; j < bytes; ++j) {
- unsigned char byte = input[inputIndex++];
- output += this->ByteToHex(byte);
+ unsigned char inputByte = input[inputIndex++];
+ output += this->ByteToHex(inputByte);
}
}
return output;
}
-std::string cmUuid::ByteToHex(unsigned char byte) const
+std::string cmUuid::ByteToHex(unsigned char inputByte) const
{
std::string result(" ");
for (int i = 0; i < 2; ++i) {
- unsigned char rest = byte % 16;
- byte /= 16;
+ unsigned char rest = inputByte % 16;
+ inputByte /= 16;
char c = (rest < 0xA) ? static_cast<char>('0' + rest)
: static_cast<char>('a' + (rest - 0xA));
result.at(1 - i) = c;
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index 6702b7b..ccf24a0 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -63,15 +63,16 @@ const WCHAR* ComponentType = L"Component";
bool LoadVSInstanceVCToolsetVersion(VSInstanceInfo& vsInstanceInfo)
{
std::string const vcRoot = vsInstanceInfo.GetInstallLocation();
- std::string vcToolsVersionFile =
- vcRoot + "/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt";
+ std::string vcToolsVersionFile = cmStrCat(
+ vcRoot, "/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt");
std::string vcToolsVersion;
cmsys::ifstream fin(vcToolsVersionFile.c_str());
if (!fin || !cmSystemTools::GetLineFromStream(fin, vcToolsVersion)) {
return false;
}
vcToolsVersion = cmTrimWhitespace(vcToolsVersion);
- std::string const vcToolsDir = vcRoot + "/VC/Tools/MSVC/" + vcToolsVersion;
+ std::string const vcToolsDir =
+ cmStrCat(vcRoot, "/VC/Tools/MSVC/", vcToolsVersion);
if (!cmSystemTools::FileIsDirectory(vcToolsDir)) {
return false;
}
@@ -434,14 +435,14 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
std::string envVSCommonToolsDir;
std::string envVSCommonToolsDirEnvName =
- "VS" + std::to_string(this->Version) + "0COMNTOOLS";
+ cmStrCat("VS", std::to_string(this->Version), "0COMNTOOLS");
if (cmSystemTools::GetEnv(envVSCommonToolsDirEnvName.c_str(),
envVSCommonToolsDir)) {
cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
}
- std::string const wantVersion = std::to_string(this->Version) + '.';
+ std::string const wantVersion = cmStrCat(std::to_string(this->Version), '.');
bool specifiedLocationNotSpecifiedVersion = false;
diff --git a/Source/cmValue.h b/Source/cmValue.h
index f96d2f5..c924dda 100644
--- a/Source/cmValue.h
+++ b/Source/cmValue.h
@@ -4,7 +4,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <iosfwd>
#include <string>
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index b011615..96a01ad 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -14,15 +14,20 @@
#include <cm/string_view>
#include <cm/vector>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "windows.h"
+// include wincrypt.h after windows.h
+#include <wincrypt.h>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmComputeLinkInformation.h"
+#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -100,7 +105,7 @@ struct cmVisualStudio10TargetGenerator::Elem
void SetHasElements()
{
if (!HasElements) {
- this->S << ">";
+ this->S << '>';
HasElements = true;
}
}
@@ -112,13 +117,13 @@ struct cmVisualStudio10TargetGenerator::Elem
}
Elem& Attribute(const char* an, std::string av)
{
- this->S << " " << an << "=\"" << cmVS10EscapeAttr(std::move(av)) << "\"";
+ this->S << ' ' << an << "=\"" << cmVS10EscapeAttr(std::move(av)) << '"';
return *this;
}
void Content(std::string val)
{
if (!this->HasContent) {
- this->S << ">";
+ this->S << '>';
this->HasContent = true;
}
this->S << cmVS10EscapeXML(std::move(val));
@@ -131,9 +136,9 @@ struct cmVisualStudio10TargetGenerator::Elem
}
if (HasElements) {
- this->WriteString("</") << this->Tag << ">";
+ this->WriteString("</") << this->Tag << '>';
} else if (HasContent) {
- this->S << "</" << this->Tag << ">";
+ this->S << "</" << this->Tag << '>';
} else {
this->S << " />";
}
@@ -287,8 +292,8 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->TargetCompileAsWinRT = false;
this->IsMissingFiles = false;
this->DefaultArtifactDir =
- this->LocalGenerator->GetCurrentBinaryDirectory() + "/" +
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget));
this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
this->Makefile->GetCurrentBinaryDirectory());
this->ClassifyAllConfigSources();
@@ -300,16 +305,16 @@ std::string cmVisualStudio10TargetGenerator::CalcCondition(
const std::string& config) const
{
std::ostringstream oss;
- oss << "'$(Configuration)|$(Platform)'=='";
- oss << config << "|" << this->Platform;
- oss << "'";
+ oss << "'$(Configuration)|$(Platform)'=='" << config << '|' << this->Platform
+ << '\'';
// handle special case for 32 bit C# targets
if (this->ProjectType == VsProjectType::csproj &&
- this->Platform == "Win32") {
- oss << " Or ";
- oss << "'$(Configuration)|$(Platform)'=='";
- oss << config << "|x86";
- oss << "'";
+ this->Platform == "Win32"_s) {
+ oss << " Or "
+ "'$(Configuration)|$(Platform)'=='"
+ << config
+ << "|x86"
+ "'";
}
return oss.str();
}
@@ -361,9 +366,9 @@ void cmVisualStudio10TargetGenerator::Generate()
!this->GlobalGenerator->SupportsCxxModuleDyndep()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("The \"", this->GeneratorTarget->GetName(),
- "\" target contains C++ module sources which are not supported "
- "by the generator"));
+ cmStrCat("The target named \"", this->GeneratorTarget->GetName(),
+ "\" contains C++ sources that export modules which is not "
+ "supported by the generator"));
}
this->ProjectType = computeProjectType(this->GeneratorTarget);
@@ -373,10 +378,10 @@ void cmVisualStudio10TargetGenerator::Generate()
if (this->ProjectType == VsProjectType::csproj &&
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
- std::string message = "The C# target \"" +
- this->GeneratorTarget->GetName() +
- "\" is of type STATIC_LIBRARY. This is discouraged (and may be "
- "disabled in future). Make it a SHARED library instead.";
+ std::string message =
+ cmStrCat("The C# target \"", this->GeneratorTarget->GetName(),
+ "\" is of type STATIC_LIBRARY. This is discouraged (and may be "
+ "disabled in future). Make it a SHARED library instead.");
this->Makefile->IssueMessage(MessageType::DEPRECATION_WARNING, message);
}
@@ -506,7 +511,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
// Setting ResolveNugetPackages to false skips this target and the build
// succeeds.
cm::string_view targetName{ this->GeneratorTarget->GetName() };
- if (targetName == "ALL_BUILD" || targetName == "PACKAGE" ||
+ if (targetName == "ALL_BUILD"_s || targetName == "PACKAGE"_s ||
targetName == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
Elem e1(e0, "PropertyGroup");
e1.Element("ResolveNugetPackages", "false");
@@ -620,8 +625,10 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
.empty()) {
e1.Element(
"CudaToolkitCustomDir",
- this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() +
- this->GlobalGenerator->GetPlatformToolsetCudaNvccSubdirString());
+ cmStrCat(
+ this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString(),
+ this->GlobalGenerator
+ ->GetPlatformToolsetCudaNvccSubdirString()));
}
}
@@ -725,15 +732,15 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString();
std::string cudaPath = customDir.empty()
? "$(VCTargetsPath)\\BuildCustomizations\\"
- : customDir +
- this->GlobalGenerator
- ->GetPlatformToolsetCudaVSIntegrationSubdirString() +
- R"(extras\visual_studio_integration\MSBuildExtensions\)";
+ : cmStrCat(customDir,
+ this->GlobalGenerator
+ ->GetPlatformToolsetCudaVSIntegrationSubdirString(),
+ R"(extras\visual_studio_integration\MSBuildExtensions\)");
Elem(e1, "Import")
.Attribute("Project",
- std::move(cudaPath) + "CUDA " +
- this->GlobalGenerator->GetPlatformToolsetCuda() +
- ".props");
+ cmStrCat(std::move(cudaPath), "CUDA ",
+ this->GlobalGenerator->GetPlatformToolsetCuda(),
+ ".props"));
}
if (this->GlobalGenerator->IsMarmasmEnabled()) {
Elem(e1, "Import")
@@ -779,7 +786,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
ConvertToWindowsSlash(props);
Elem(e1, "Import")
.Attribute("Project", props)
- .Attribute("Condition", "exists('" + props + "')")
+ .Attribute("Condition", cmStrCat("exists('", props, "')"))
.Attribute("Label", "LocalAppDataPlatform");
}
@@ -829,15 +836,15 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString();
std::string cudaPath = customDir.empty()
? "$(VCTargetsPath)\\BuildCustomizations\\"
- : customDir +
- this->GlobalGenerator
- ->GetPlatformToolsetCudaVSIntegrationSubdirString() +
- R"(extras\visual_studio_integration\MSBuildExtensions\)";
+ : cmStrCat(customDir,
+ this->GlobalGenerator
+ ->GetPlatformToolsetCudaVSIntegrationSubdirString(),
+ R"(extras\visual_studio_integration\MSBuildExtensions\)");
Elem(e1, "Import")
.Attribute("Project",
- std::move(cudaPath) + "CUDA " +
- this->GlobalGenerator->GetPlatformToolsetCuda() +
- ".targets");
+ cmStrCat(std::move(cudaPath), "CUDA ",
+ this->GlobalGenerator->GetPlatformToolsetCuda(),
+ ".targets"));
}
if (this->GlobalGenerator->IsMarmasmEnabled()) {
Elem(e1, "Import")
@@ -864,7 +871,8 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
if (this->ProjectType == VsProjectType::csproj) {
for (std::string const& c : this->Configurations) {
Elem e1(e0, "PropertyGroup");
- e1.Attribute("Condition", "'$(Configuration)' == '" + c + "'");
+ e1.Attribute("Condition",
+ cmStrCat("'$(Configuration)' == '", c, '\''));
e1.SetHasElements();
this->WriteEvents(e1, c);
}
@@ -877,7 +885,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
oss << " " << i << ";\n";
}
oss << " "
- << "$(BuildDependsOn)\n";
+ "$(BuildDependsOn)\n";
e1.Element("BuildDependsOn", oss.str());
}
}
@@ -889,17 +897,19 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
{
if (this->ProjectType != VsProjectType::csproj ||
!this->GeneratorTarget->IsDotNetSdkTarget()) {
- std::string message = "The target \"" + this->GeneratorTarget->GetName() +
- "\" is not eligible for .Net SDK style project.";
+ std::string message =
+ cmStrCat("The target \"", this->GeneratorTarget->GetName(),
+ "\" is not eligible for .Net SDK style project.");
this->Makefile->IssueMessage(MessageType::INTERNAL_ERROR, message);
return;
}
if (this->HasCustomCommands()) {
- std::string message = "The target \"" + this->GeneratorTarget->GetName() +
+ std::string message = cmStrCat(
+ "The target \"", this->GeneratorTarget->GetName(),
"\" does not currently support add_custom_command as the Visual Studio "
"generators have not yet learned how to generate custom commands in "
- ".Net SDK-style projects.";
+ ".Net SDK-style projects.");
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, message);
return;
}
@@ -982,11 +992,13 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
for (const std::string& config : this->Configurations) {
Elem e1(e0, "PropertyGroup");
- e1.Attribute("Condition", "'$(Configuration)' == '" + config + "'");
+ e1.Attribute("Condition",
+ cmStrCat("'$(Configuration)' == '", config, '\''));
e1.SetHasElements();
this->WriteEvents(e1, config);
- std::string outDir = this->GeneratorTarget->GetDirectory(config) + "/";
+ std::string outDir =
+ cmStrCat(this->GeneratorTarget->GetDirectory(config), '/');
ConvertToWindowsSlash(outDir);
e1.Element("OutputPath", outDir);
@@ -1007,7 +1019,7 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
{
e1.Attribute("Label", "Globals");
- e1.Element("ProjectGuid", "{" + this->GUID + "}");
+ e1.Element("ProjectGuid", cmStrCat('{', this->GUID, '}'));
cmValue vsProjectTypes =
this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
@@ -1045,8 +1057,8 @@ void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
}
cm::string_view globalKey = cm::string_view(keyIt).substr(prefix.length());
// Skip invalid or separately-handled properties.
- if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
- globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
+ if (globalKey.empty() || globalKey == "PROJECT_TYPES"_s ||
+ globalKey == "ROOTNAMESPACE"_s || globalKey == "KEYWORD"_s) {
continue;
}
cmValue value = this->GeneratorTarget->GetProperty(keyIt);
@@ -1103,7 +1115,8 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
if (cmHasPrefix(i.first, vsDnRef)) {
std::string path = i.second;
if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
+ path =
+ cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', path);
}
ConvertToWindowsSlash(path);
this->DotNetHintReferences[""].emplace_back(
@@ -1172,7 +1185,8 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
cmList argsSplit{ *imports };
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
+ path =
+ cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', path);
}
ConvertToWindowsSlash(path);
Elem e1(e0, "Import");
@@ -1187,7 +1201,8 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
static const std::string refpropPrefix = "VS_DOTNET_REFERENCEPROP_";
static const std::string refpropInfix = "_TAG_";
- const std::string refPropFullPrefix = refpropPrefix + ref + refpropInfix;
+ const std::string refPropFullPrefix =
+ cmStrCat(refpropPrefix, ref, refpropInfix);
using CustomTags = std::map<std::string, std::string>;
CustomTags tags;
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
@@ -1239,7 +1254,8 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
e2.Attribute("Include", obj);
if (this->ProjectType != VsProjectType::csproj) {
- std::string hFileName = obj.substr(0, obj.find_last_of('.')) + ".h";
+ std::string hFileName =
+ cmStrCat(obj.substr(0, obj.find_last_of('.')), ".h");
e2.Element("DependentUpon", hFileName);
for (std::string const& c : this->Configurations) {
@@ -1265,10 +1281,10 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
e2.Element("Link", link);
}
// Determine if this is a generated resource from a .Designer.cs file
- std::string designerResource =
- cmSystemTools::GetFilenamePath(oi->GetFullPath()) + "/" +
- cmSystemTools::GetFilenameWithoutLastExtension(oi->GetFullPath()) +
- ".Designer.cs";
+ std::string designerResource = cmStrCat(
+ cmSystemTools::GetFilenamePath(oi->GetFullPath()), '/',
+ cmSystemTools::GetFilenameWithoutLastExtension(oi->GetFullPath()),
+ ".Designer.cs");
if (cmsys::SystemTools::FileExists(designerResource)) {
std::string generator = "PublicResXFileCodeGenerator";
if (cmValue g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
@@ -1333,7 +1349,7 @@ void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences(Elem& e0)
{
if (this->MSTools) {
if (this->GlobalGenerator->TargetsWindowsPhone() &&
- this->GlobalGenerator->GetSystemVersion() == "8.0") {
+ this->GlobalGenerator->GetSystemVersion() == "8.0"_s) {
Elem(e0, "Import")
.Attribute("Project",
"$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v"
@@ -1354,9 +1370,9 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1)
if (j > 0) {
oss << " Or ";
}
- oss << "'$(Configuration)'=='" << tac.Configs[j] << "'";
+ oss << "'$(Configuration)'=='" << tac.Configs[j] << '\'';
}
- oss << ")";
+ oss << ')';
}
Elem(e1, "Import")
@@ -1374,7 +1390,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
- this->GlobalGenerator->GetSystemVersion() == "8.0" &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0"_s &&
references.empty()) {
references.push_back(std::string{ "platform.winmd" });
}
@@ -1396,7 +1412,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations(Elem& e0)
e1.Attribute("Label", "ProjectConfigurations");
for (std::string const& c : this->Configurations) {
Elem e2(e1, "ProjectConfiguration");
- e2.Attribute("Include", c + "|" + this->Platform);
+ e2.Attribute("Include", cmStrCat(c, '|', this->Platform));
e2.Element("Configuration", c);
e2.Element("Platform", this->Platform);
}
@@ -1504,9 +1520,9 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
std::string useOfMfcValue = "false";
if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
- if (mfcFlagValue == "1") {
+ if (mfcFlagValue == "1"_s) {
useOfMfcValue = "Static";
- } else if (mfcFlagValue == "2") {
+ } else if (mfcFlagValue == "2"_s) {
useOfMfcValue = "Dynamic";
}
}
@@ -1572,7 +1588,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
e1.Element("DefineDebug", "true");
}
- std::string outDir = this->GeneratorTarget->GetDirectory(config) + "/";
+ std::string outDir =
+ cmStrCat(this->GeneratorTarget->GetDirectory(config), '/');
ConvertToWindowsSlash(outDir);
e1.Element("OutputPath", outDir);
@@ -1599,7 +1616,7 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
if (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType()) {
e1.Element("StartAction", "Program");
- e1.Element("StartProgram", outDir + assemblyName + ".exe");
+ e1.Element("StartProgram", cmStrCat(outDir, assemblyName, ".exe"));
}
OptionsHelper oh(o, e1);
@@ -1614,10 +1631,10 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
const char* toolset = gg->GetPlatformToolset();
e1.Element("NdkToolchainVersion", toolset ? toolset : "Default");
if (cmValue minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
- e1.Element("AndroidMinAPI", "android-" + *minApi);
+ e1.Element("AndroidMinAPI", cmStrCat("android-", *minApi));
}
if (cmValue api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
- e1.Element("AndroidTargetAPI", "android-" + *api);
+ e1.Element("AndroidTargetAPI", cmStrCat("android-", *api));
}
if (cmValue cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
@@ -1642,7 +1659,7 @@ void cmVisualStudio10TargetGenerator::WriteAndroidConfigurationValues(
}
if (cmValue stlType =
this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
- if (*stlType != "none") {
+ if (*stlType != "none"_s) {
e1.Element("UseOfStl", *stlType);
}
}
@@ -1720,9 +1737,9 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
// preventing dependent rebuilds.
this->ForceOld(sourcePath);
} else {
- std::string error =
- cmStrCat("Could not create file: [", sourcePath, "] ");
- cmSystemTools::Error(error + cmSystemTools::GetLastSystemError());
+ cmSystemTools::Error(cmStrCat("Could not create file: [", sourcePath,
+ "] ",
+ cmSystemTools::GetLastSystemError()));
}
}
}
@@ -1807,8 +1824,9 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
script += lg->FinishConstructScript(this->ProjectType);
if (this->ProjectType == VsProjectType::csproj) {
- std::string name = "CustomCommand_" + c + "_" +
- cmSystemTools::ComputeStringMD5(sourcePath);
+ cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+ std::string name =
+ cmStrCat("CustomCommand_", c, '_', hasher.HashString(sourcePath));
this->WriteCustomRuleCSharp(e0, c, name, script, additional_inputs.str(),
outputs.str(), comment, ccg);
} else {
@@ -1879,7 +1897,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp(
e1.S << "\n Inputs=\"" << cmVS10EscapeAttr(inputs) << "\"";
e1.S << "\n Outputs=\"" << cmVS10EscapeAttr(outputs) << "\"";
if (!comment.empty()) {
- Elem(e1, "Exec").Attribute("Command", "echo " + comment);
+ Elem(e1, "Exec").Attribute("Command", cmStrCat("echo ", comment));
}
Elem(e1, "Exec").Attribute("Command", script);
}
@@ -1961,7 +1979,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
for (std::string const& oi : this->AddedFiles) {
std::string fileName =
cmSystemTools::LowerCase(cmSystemTools::GetFilenameName(oi));
- if (fileName == "wmappmanifest.xml") {
+ if (fileName == "wmappmanifest.xml"_s) {
Elem e2(e1, "XML");
e2.Attribute("Include", oi);
e2.Element("Filter", "Resource Files");
@@ -1970,7 +1988,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
Elem e2(e1, "AppxManifest");
e2.Attribute("Include", oi);
e2.Element("Filter", "Resource Files");
- } else if (cmSystemTools::GetFilenameExtension(fileName) == ".pfx") {
+ } else if (cmSystemTools::GetFilenameExtension(fileName) == ".pfx"_s) {
Elem e2(e1, "None");
e2.Attribute("Include", oi);
e2.Element("Filter", "Resource Files");
@@ -2004,11 +2022,11 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
for (cmSourceGroup const* sg : groupsVec) {
std::string const& name = sg->GetFullName();
if (!name.empty()) {
- std::string guidName = "SG_Filter_" + name;
+ std::string guidName = cmStrCat("SG_Filter_", name);
std::string guid = this->GlobalGenerator->GetGUID(guidName);
Elem e2(e1, "Filter");
e2.Attribute("Include", name);
- e2.Element("UniqueIdentifier", "{" + guid + "}");
+ e2.Element("UniqueIdentifier", cmStrCat('{', guid, '}'));
}
}
@@ -2017,7 +2035,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::string guid = this->GlobalGenerator->GetGUID(guidName);
Elem e2(e1, "Filter");
e2.Attribute("Include", "Resource Files");
- e2.Element("UniqueIdentifier", "{" + guid + "}");
+ e2.Element("UniqueIdentifier", cmStrCat('{', guid, '}'));
e2.Element("Extensions",
"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;"
"gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms");
@@ -2173,7 +2191,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
if (this->ProjectType == VsProjectType::csproj && !this->InSourceBuild) {
toolHasSettings = true;
}
- if (ext == "hlsl") {
+ if (ext == "hlsl"_s) {
tool = "FXCompile";
// Figure out the type of shader compiler to use.
if (cmValue st = sf->GetProperty("VS_SHADER_TYPE")) {
@@ -2251,22 +2269,22 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
toolSettings[config]["ObjectFileOutput"] = *sofn;
}
}
- } else if (ext == "jpg" || ext == "png") {
+ } else if (ext == "jpg"_s || ext == "png"_s) {
tool = "Image";
- } else if (ext == "resw") {
+ } else if (ext == "resw"_s) {
tool = "PRIResource";
- } else if (ext == "xml") {
+ } else if (ext == "xml"_s) {
tool = "XML";
- } else if (ext == "natvis") {
+ } else if (ext == "natvis"_s) {
tool = "Natvis";
- } else if (ext == "settings") {
+ } else if (ext == "settings"_s) {
settingsLastGenOutput =
cmsys::SystemTools::GetFilenameName(sf->GetFullPath());
std::size_t pos = settingsLastGenOutput.find(".settings");
settingsLastGenOutput.replace(pos, 9, ".Designer.cs");
settingsGenerator = "SettingsSingleFileGenerator";
toolHasSettings = true;
- } else if (ext == "vsixmanifest") {
+ } else if (ext == "vsixmanifest"_s) {
subType = "Designer";
}
if (cmValue c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
@@ -2287,13 +2305,13 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
if (this->NsightTegra) {
// Nsight Tegra needs specific file types to check up-to-dateness.
std::string name = cmSystemTools::LowerCase(sf->GetLocation().GetName());
- if (name == "androidmanifest.xml" || name == "build.xml" ||
- name == "proguard.cfg" || name == "proguard-project.txt" ||
- ext == "properties") {
+ if (name == "androidmanifest.xml"_s || name == "build.xml"_s ||
+ name == "proguard.cfg"_s || name == "proguard-project.txt"_s ||
+ ext == "properties"_s) {
tool = "AndroidBuild";
- } else if (ext == "java") {
+ } else if (ext == "java"_s) {
tool = "JCompile";
- } else if (ext == "asm" || ext == "s") {
+ } else if (ext == "asm"_s || ext == "s"_s) {
tool = "ClCompile";
}
}
@@ -2321,7 +2339,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
if (ParsedToolTargetSettings.find(tool) == ParsedToolTargetSettings.end()) {
cmValue toolTargetProperty = this->GeneratorTarget->Target->GetProperty(
- "VS_SOURCE_SETTINGS_" + std::string(tool));
+ cmStrCat("VS_SOURCE_SETTINGS_", tool));
ConfigToSettings toolTargetSettings;
if (toolTargetProperty) {
ParseSettingsProperty(*toolTargetProperty, toolTargetSettings);
@@ -2353,19 +2371,22 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
ge.Parse(deployContent);
// Deployment location cannot be set on a configuration basis
if (!deployLocation.empty()) {
- e2.Element("Link", deployLocation + "\\%(FileName)%(Extension)");
+ e2.Element("Link",
+ cmStrCat(deployLocation, "\\%(FileName)%(Extension)"));
}
for (auto& config : this->Configurations) {
- if (cge->Evaluate(this->LocalGenerator, config) == "1") {
- e2.WritePlatformConfigTag("DeploymentContent",
- "'$(Configuration)|$(Platform)'=='" +
- config + "|" + this->Platform + "'",
- "true");
+ if (cge->Evaluate(this->LocalGenerator, config) == "1"_s) {
+ e2.WritePlatformConfigTag(
+ "DeploymentContent",
+ cmStrCat("'$(Configuration)|$(Platform)'=='", config, '|',
+ this->Platform, '\''),
+ "true");
} else {
- e2.WritePlatformConfigTag("ExcludedFromBuild",
- "'$(Configuration)|$(Platform)'=='" +
- config + "|" + this->Platform + "'",
- "true");
+ e2.WritePlatformConfigTag(
+ "ExcludedFromBuild",
+ cmStrCat("'$(Configuration)|$(Platform)'=='", config, '|',
+ this->Platform, '\''),
+ "true");
}
}
}
@@ -2401,7 +2422,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
// conversion uses full paths when possible to allow deeper trees.
// However, CUDA 8.0 msbuild rules fail on absolute paths so for CUDA
// we must use relative paths.
- bool forceRelative = sf->GetLanguage() == "CUDA";
+ bool forceRelative = sf->GetLanguage() == "CUDA"_s;
std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative);
ConvertToWindowsSlash(sourceFile);
e2.Attribute("Include", sourceFile);
@@ -2480,18 +2501,6 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
break;
case cmGeneratorTarget::SourceKindExternalObject:
tool = "Object";
- if (this->LocalGenerator->GetVersion() <
- cmGlobalVisualStudioGenerator::VSVersion::VS11) {
- // For VS == 10 we cannot use LinkObjects to avoid linking custom
- // command outputs. If an object file is generated in this target,
- // then vs10 will use it in the build, and we have to list it as
- // None instead of Object.
- std::vector<cmSourceFile*> const* d =
- this->GeneratorTarget->GetSourceDepends(si.Source);
- if (d && !d->empty()) {
- tool = "None";
- }
- }
break;
case cmGeneratorTarget::SourceKindExtra:
this->WriteExtraSource(e1, si.Source, toolSettings);
@@ -2508,25 +2517,27 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
case cmGeneratorTarget::SourceKindModuleDefinition:
tool = "None";
break;
+ case cmGeneratorTarget::SourceKindCxxModuleSource:
case cmGeneratorTarget::SourceKindUnityBatched:
case cmGeneratorTarget::SourceKindObjectSource: {
const std::string& lang = si.Source->GetLanguage();
- if (lang == "C" || lang == "CXX") {
+ if (lang == "C"_s || lang == "CXX"_s) {
tool = "ClCompile";
- } else if (lang == "ASM_MARMASM" &&
+ } else if (lang == "ASM_MARMASM"_s &&
this->GlobalGenerator->IsMarmasmEnabled()) {
tool = "MARMASM";
- } else if (lang == "ASM_MASM" &&
+ } else if (lang == "ASM_MASM"_s &&
this->GlobalGenerator->IsMasmEnabled()) {
tool = "MASM";
- } else if (lang == "ASM_NASM" &&
+ } else if (lang == "ASM_NASM"_s &&
this->GlobalGenerator->IsNasmEnabled()) {
tool = "NASM";
- } else if (lang == "RC") {
+ } else if (lang == "RC"_s) {
tool = "ResourceCompile";
- } else if (lang == "CSharp") {
+ } else if (lang == "CSharp"_s) {
tool = "Compile";
- } else if (lang == "CUDA" && this->GlobalGenerator->IsCudaEnabled()) {
+ } else if (lang == "CUDA"_s &&
+ this->GlobalGenerator->IsCudaEnabled()) {
tool = "CudaCompile";
} else {
tool = "None";
@@ -2549,7 +2560,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
std::back_inserter(exclude_configs));
Elem e2(e1, tool);
- bool isCSharp = (si.Source->GetLanguage() == "CSharp");
+ bool isCSharp = (si.Source->GetLanguage() == "CSharp"_s);
if (isCSharp && !exclude_configs.empty()) {
std::stringstream conditions;
bool firstConditionSet{ false };
@@ -2557,8 +2568,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
if (firstConditionSet) {
conditions << " Or ";
}
- conditions << "('$(Configuration)|$(Platform)'=='" +
- this->Configurations[ci] + "|" + this->Platform + "')";
+ conditions << "('$(Configuration)|$(Platform)'=='"
+ << this->Configurations[ci] << '|' << this->Platform
+ << "')";
firstConditionSet = true;
}
e2.Attribute("Condition", conditions.str());
@@ -2638,9 +2650,9 @@ void cmVisualStudio10TargetGenerator::FinishWritingSource(
writtenSettings.push_back(setting.first);
} else {
e2.WritePlatformConfigTag(setting.first,
- "'$(Configuration)|$(Platform)'=='" +
- configSettings.first + "|" +
- this->Platform + "'",
+ cmStrCat("'$(Configuration)|$(Platform)'=='",
+ configSettings.first, '|',
+ this->Platform, '\''),
setting.second);
}
}
@@ -2688,33 +2700,33 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// Force language if the file extension does not match.
// Note that MSVC treats the upper-case '.C' extension as C and not C++.
std::string const ext = sf.GetExtension();
- std::string const extLang = ext == "C"
+ std::string const extLang = ext == "C"_s
? "C"
: this->GlobalGenerator->GetLanguageFromExtension(ext.c_str());
std::string lang = this->LocalGenerator->GetSourceFileLanguage(sf);
const char* compileAs = nullptr;
if (lang != extLang) {
- if (lang == "CXX") {
+ if (lang == "CXX"_s) {
// force a C++ file type
compileAs = "CompileAsCpp";
- } else if (lang == "C") {
+ } else if (lang == "C"_s) {
// force to c
compileAs = "CompileAsC";
}
}
- bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
+ bool noWinRT = this->TargetCompileAsWinRT && lang == "C"_s;
// for the first time we need a new line if there is something
// produced here.
if (!objectName.empty()) {
- if (lang == "CUDA") {
- e2.Element("CompileOut", "$(IntDir)/" + objectName);
+ if (lang == "CUDA"_s) {
+ e2.Element("CompileOut", cmStrCat("$(IntDir)/", objectName));
} else {
- e2.Element("ObjectFileName", "$(IntDir)/" + objectName);
+ e2.Element("ObjectFileName", cmStrCat("$(IntDir)/", objectName));
}
}
- if (lang == "ASM_NASM") {
+ if (lang == "ASM_NASM"_s) {
if (cmValue objectDeps = sf.GetProperty("OBJECT_DEPENDS")) {
cmList depends{ *objectDeps };
for (auto& d : depends) {
@@ -2734,7 +2746,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
if (cmValue ccdefs = sf.GetProperty(defPropName)) {
if (!configDefines.empty()) {
- configDefines += ";";
+ configDefines += ';';
}
configDependentDefines |=
cmGeneratorExpression::Find(*ccdefs) != std::string::npos;
@@ -2799,20 +2811,20 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
- if (srclang == "C" || srclang == "CXX") {
+ if (srclang == "C"_s || srclang == "CXX"_s) {
flagtable = gg->GetClFlagTable();
- } else if (srclang == "ASM_MARMASM" &&
+ } else if (srclang == "ASM_MARMASM"_s &&
this->GlobalGenerator->IsMarmasmEnabled()) {
flagtable = gg->GetMarmasmFlagTable();
- } else if (srclang == "ASM_MASM" &&
+ } else if (srclang == "ASM_MASM"_s &&
this->GlobalGenerator->IsMasmEnabled()) {
flagtable = gg->GetMasmFlagTable();
- } else if (lang == "ASM_NASM" &&
+ } else if (lang == "ASM_NASM"_s &&
this->GlobalGenerator->IsNasmEnabled()) {
flagtable = gg->GetNasmFlagTable();
- } else if (srclang == "RC") {
+ } else if (srclang == "RC"_s) {
flagtable = gg->GetRcFlagTable();
- } else if (srclang == "CSharp") {
+ } else if (srclang == "CSharp"_s) {
flagtable = gg->GetCSharpFlagTable();
}
cmGeneratorExpressionInterpreter genexInterpreter(
@@ -2937,9 +2949,9 @@ void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
{
for (size_t ci : exclude_configs) {
e2.WritePlatformConfigTag("ExcludedFromBuild",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[ci] + "|" +
- this->Platform + "'",
+ cmStrCat("'$(Configuration)|$(Platform)'=='",
+ this->Configurations[ci], '|',
+ this->Platform, '\''),
"true");
}
}
@@ -2973,7 +2985,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
outDir = intermediateDir;
targetNameFull = cmStrCat(this->GeneratorTarget->GetName(), ".lib");
} else {
- outDir = this->GeneratorTarget->GetDirectory(config) + "/";
+ outDir = cmStrCat(this->GeneratorTarget->GetDirectory(config), '/');
targetNameFull = this->GeneratorTarget->GetFullName(config);
}
ConvertToWindowsSlash(intermediateDir);
@@ -3158,7 +3170,7 @@ std::string cmVisualStudio10TargetGenerator::GetTargetOutputName() const
}
const auto& nameComponents =
this->GeneratorTarget->GetFullNameComponents(config);
- return nameComponents.prefix + nameComponents.base;
+ return cmStrCat(nameComponents.prefix, nameComponents.base);
}
bool cmVisualStudio10TargetGenerator::ComputeClOptions()
@@ -3196,8 +3208,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
const std::string& linkLanguage =
this->GeneratorTarget->GetLinkerLanguage(configName);
if (linkLanguage.empty()) {
- cmSystemTools::Error(
- "CMake can not determine linker language for target: " + this->Name);
+ cmSystemTools::Error(cmStrCat(
+ "CMake can not determine linker language for target: ", this->Name));
return false;
}
@@ -3289,11 +3301,11 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
defineFlags.find("/clr") != std::string::npos ||
defineFlags.find("-clr") != std::string::npos) {
if (configName == this->Configurations[0]) {
- std::string message = "For the target \"" +
- this->GeneratorTarget->GetName() +
- "\" the /clr compiler flag was added manually. " +
- "Set usage of C++/CLI by setting COMMON_LANGUAGE_RUNTIME "
- "target property.";
+ std::string message =
+ cmStrCat("For the target \"", this->GeneratorTarget->GetName(),
+ "\" the /clr compiler flag was added manually. ",
+ "Set usage of C++/CLI by setting COMMON_LANGUAGE_RUNTIME "
+ "target property.");
this->Makefile->IssueMessage(MessageType::WARNING, message);
}
}
@@ -3301,9 +3313,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
std::string clrString = *clr;
if (!clrString.empty()) {
- clrString = ":" + clrString;
+ clrString = cmStrCat(':', clrString);
}
- flags += " /clr" + clrString;
+ flags += cmStrCat(" /clr", clrString);
}
}
@@ -3376,7 +3388,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
// Add C-specific flags expressible in a ClCompile meant for C++.
- if (langForClCompile == "CXX") {
+ if (langForClCompile == "CXX"_s) {
std::set<std::string> languages;
this->GeneratorTarget->GetLanguages(languages, configName);
if (languages.count("C")) {
@@ -3431,7 +3443,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string managedType = clOptions.HasFlag("CompileAsManaged")
? clOptions.GetFlag("CompileAsManaged")
: "Mixed";
- if (managedType == "Safe" || managedType == "Pure") {
+ if (managedType == "Safe"_s || managedType == "Pure"_s) {
// force empty calling convention if safe clr is used
clOptions.AddFlag("CallingConvention", "");
}
@@ -3455,7 +3467,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
// Remove any target-wide -TC or -TP flag added by the project.
// Such flags are unnecessary and break our model of language selection.
- if (langForClCompile == "C" || langForClCompile == "CXX") {
+ if (langForClCompile == "C"_s || langForClCompile == "CXX"_s) {
clOptions.RemoveFlag("CompileAs");
}
@@ -3550,9 +3562,10 @@ bool cmVisualStudio10TargetGenerator::ComputeRcOptions(
Options& rcOptions = *pOptions;
std::string CONFIG = cmSystemTools::UpperCase(configName);
- std::string rcConfigFlagsVar = "CMAKE_RC_FLAGS_" + CONFIG;
- std::string flags = this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS") +
- " " + this->Makefile->GetSafeDefinition(rcConfigFlagsVar);
+ std::string rcConfigFlagsVar = cmStrCat("CMAKE_RC_FLAGS_", CONFIG);
+ std::string flags =
+ cmStrCat(this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS"), ' ',
+ this->Makefile->GetSafeDefinition(rcConfigFlagsVar));
rcOptions.Parse(flags);
@@ -3693,7 +3706,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// limitation by creating the directory and passing the flag ourselves.
pdb = this->ConvertPath(pdb, true);
ConvertToWindowsSlash(pdb);
- std::string const clFd = R"(-Xcompiler="-Fd\")" + pdb + R"(\"")";
+ std::string const clFd = cmStrCat(R"(-Xcompiler="-Fd\")", pdb, R"(\"")");
cudaOptions.AppendFlagString("AdditionalOptions", clFd);
}
}
@@ -3701,7 +3714,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// CUDA automatically passes the proper '--machine' flag to nvcc
// for the current architecture, but does not reflect this default
// in the user-visible IDE settings. Set it explicitly.
- if (this->Platform == "x64") {
+ if (this->Platform == "x64"_s) {
cudaOptions.AddFlag("TargetMachinePlatform", "64");
}
@@ -3718,7 +3731,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
cudaOptions.RemoveFlag("AdditionalCompilerOptions");
if (!aco.empty()) {
aco = this->LocalGenerator->EscapeForShell(aco, false);
- cudaOptions.AppendFlagString("AdditionalOptions", "-Xcompiler=" + aco);
+ cudaOptions.AppendFlagString("AdditionalOptions",
+ cmStrCat("-Xcompiler=", aco));
}
}
@@ -3744,11 +3758,11 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// Add runtime library selection flag.
std::string const& cudaRuntime =
this->GeneratorTarget->GetRuntimeLinkLibrary("CUDA", configName);
- if (cudaRuntime == "STATIC") {
+ if (cudaRuntime == "STATIC"_s) {
cudaOptions.AddFlag("CudaRuntime", "Static");
- } else if (cudaRuntime == "SHARED") {
+ } else if (cudaRuntime == "SHARED"_s) {
cudaOptions.AddFlag("CudaRuntime", "Shared");
- } else if (cudaRuntime == "NONE") {
+ } else if (cudaRuntime == "NONE"_s) {
cudaOptions.AddFlag("CudaRuntime", "None");
}
@@ -4095,14 +4109,15 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
e2.Element("AdditionalManifestFiles", oss.str());
}
if (dpiAware) {
- if (*dpiAware == "PerMonitor") {
+ if (*dpiAware == "PerMonitor"_s) {
e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware");
} else if (cmIsOn(*dpiAware)) {
e2.Element("EnableDpiAwareness", "true");
} else if (cmIsOff(*dpiAware)) {
e2.Element("EnableDpiAwareness", "false");
} else {
- cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " + *dpiAware);
+ cmSystemTools::Error(
+ cmStrCat("Bad parameter for VS_DPI_AWARE: ", *dpiAware));
}
}
}
@@ -4190,7 +4205,7 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
}
{
- std::string manifest_xml = rootDir + "/AndroidManifest.xml";
+ std::string manifest_xml = cmStrCat(rootDir, "/AndroidManifest.xml");
ConvertToWindowsSlash(manifest_xml);
e2.Element("AndroidManifestLocation", manifest_xml);
}
@@ -4198,7 +4213,7 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
if (cmValue antAdditionalOptions =
this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) {
e2.Element("AdditionalOptions",
- *antAdditionalOptions + " %(AdditionalOptions)");
+ cmStrCat(*antAdditionalOptions, " %(AdditionalOptions)"));
}
}
@@ -4229,8 +4244,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
const std::string& linkLanguage = linkClosure->LinkerLanguage;
if (linkLanguage.empty()) {
- cmSystemTools::Error(
- "CMake can not determine linker language for target: " + this->Name);
+ cmSystemTools::Error(cmStrCat(
+ "CMake can not determine linker language for target: ", this->Name));
return false;
}
@@ -4245,19 +4260,19 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
}
std::string flags;
std::string linkFlagVarBase = cmStrCat("CMAKE_", linkType, "_LINKER_FLAGS");
- flags += " ";
+ flags += ' ';
flags += this->Makefile->GetRequiredDefinition(linkFlagVarBase);
- std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
- flags += " ";
+ std::string linkFlagVar = cmStrCat(linkFlagVarBase, '_', CONFIG);
+ flags += ' ';
flags += this->Makefile->GetRequiredDefinition(linkFlagVar);
cmValue targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- flags += " ";
+ flags += ' ';
flags += *targetLinkFlags;
}
std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG);
if (cmValue flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) {
- flags += " ";
+ flags += ' ';
flags += *flagsConfig;
}
@@ -4270,8 +4285,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
this->GeneratorTarget->GetLinkInformation(config);
if (!pcli) {
cmSystemTools::Error(
- "CMake can not compute cmComputeLinkInformation for target: " +
- this->Name);
+ cmStrCat("CMake can not compute cmComputeLinkInformation for target: ",
+ this->Name));
return false;
}
cmComputeLinkInformation& cli = *pcli;
@@ -4296,7 +4311,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
// first just full path
linkDirs.push_back(d);
// next path with configuration type Debug, Release, etc
- linkDirs.push_back(d + "/$(Configuration)");
+ linkDirs.emplace_back(cmStrCat(d, "/$(Configuration)"));
}
linkDirs.push_back("%(AdditionalLibraryDirectories)");
linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs);
@@ -4338,7 +4353,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
}
if (cmValue stackVal = this->Makefile->GetDefinition(
- "CMAKE_" + linkLanguage + "_STACK_SIZE")) {
+ cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE"))) {
linkOptions.AddFlag("StackReserveSize", *stackVal);
}
@@ -4370,7 +4385,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
- this->GlobalGenerator->GetSystemVersion() == "8.0") {
+ this->GlobalGenerator->GetSystemVersion() == "8.0"_s) {
// WindowsPhone 8.0 does not have ole32.
linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries", "ole32.lib");
}
@@ -4435,8 +4450,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLibOptions(
this->GeneratorTarget->GetLinkInformation(config);
if (!pcli) {
cmSystemTools::Error(
- "CMake can not compute cmComputeLinkInformation for target: " +
- this->Name);
+ cmStrCat("CMake can not compute cmComputeLinkInformation for target: ",
+ this->Name));
return false;
}
@@ -4542,7 +4557,8 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
: path);
}
} else if (!l.Target ||
- l.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ (l.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ l.Target->GetType() != cmStateEnums::OBJECT_LIBRARY)) {
libVec.push_back(l.Value.Value);
}
}
@@ -4752,7 +4768,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
ConvertToWindowsSlash(path);
Elem e2(e1, "ProjectReference");
e2.Attribute("Include", path);
- e2.Element("Project", "{" + this->GlobalGenerator->GetGUID(name) + "}");
+ e2.Element("Project",
+ cmStrCat('{', this->GlobalGenerator->GetGUID(name), '}'));
e2.Element("Name", name);
this->WriteDotNetReferenceCustomTags(e2, name);
if (dt->IsCSharpOnly() || cmHasLiteralSuffix(path, "csproj")) {
@@ -4791,17 +4808,18 @@ void cmVisualStudio10TargetGenerator::WritePlatformExtensions(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension(
Elem& e1, std::string const& extension, std::string const& version)
{
- const std::string s = "$([Microsoft.Build.Utilities.ToolLocationHelper]"
- "::GetPlatformExtensionSDKLocation(`" +
- extension + ", Version=" + version +
- "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, "
- "$(ExtensionSDKDirectoryRoot), null))"
- "\\DesignTime\\CommonConfiguration\\Neutral\\" +
- extension + ".props";
+ const std::string s =
+ cmStrCat("$([Microsoft.Build.Utilities.ToolLocationHelper]"
+ "::GetPlatformExtensionSDKLocation(`",
+ extension, ", Version=", version,
+ "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, "
+ "$(ExtensionSDKDirectoryRoot), null))"
+ "\\DesignTime\\CommonConfiguration\\Neutral\\",
+ extension, ".props");
Elem e2(e1, "Import");
e2.Attribute("Project", s);
- e2.Attribute("Condition", "exists('" + s + "')");
+ e2.Attribute("Condition", cmStrCat("exists('", s, "')"));
}
void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
@@ -4852,7 +4870,74 @@ void cmVisualStudio10TargetGenerator::WriteSingleSDKReference(
Elem& e1, std::string const& extension, std::string const& version)
{
Elem(e1, "SDKReference")
- .Attribute("Include", extension + ", Version=" + version);
+ .Attribute("Include", cmStrCat(extension, ", Version=", version));
+}
+
+namespace {
+std::string ComputeCertificateThumbprint(const std::string& source)
+{
+ std::string thumbprint;
+
+ CRYPT_INTEGER_BLOB cryptBlob;
+ HCERTSTORE certStore = nullptr;
+ PCCERT_CONTEXT certContext = nullptr;
+
+ HANDLE certFile = CreateFileW(
+ cmsys::Encoding::ToWide(source.c_str()).c_str(), GENERIC_READ,
+ FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+
+ if (certFile != INVALID_HANDLE_VALUE && certFile != nullptr) {
+ DWORD fileSize = GetFileSize(certFile, nullptr);
+ if (fileSize != INVALID_FILE_SIZE) {
+ auto certData = cm::make_unique<BYTE[]>(fileSize);
+ if (certData != nullptr) {
+ DWORD dwRead = 0;
+ if (ReadFile(certFile, certData.get(), fileSize, &dwRead, nullptr)) {
+ cryptBlob.cbData = fileSize;
+ cryptBlob.pbData = certData.get();
+
+ // Verify that this is a valid cert
+ if (PFXIsPFXBlob(&cryptBlob)) {
+ // Open the certificate as a store
+ certStore =
+ PFXImportCertStore(&cryptBlob, nullptr, CRYPT_EXPORTABLE);
+ if (certStore != nullptr) {
+ // There should only be 1 cert.
+ certContext =
+ CertEnumCertificatesInStore(certStore, certContext);
+ if (certContext != nullptr) {
+ // The hash is 20 bytes
+ BYTE hashData[20];
+ DWORD hashLength = 20;
+
+ // Buffer to print the hash. Each byte takes 2 chars +
+ // terminating character
+ char hashPrint[41];
+ char* pHashPrint = hashPrint;
+ // Get the hash property from the certificate
+ if (CertGetCertificateContextProperty(
+ certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) {
+ for (DWORD i = 0; i < hashLength; i++) {
+ // Convert each byte to hexadecimal
+ snprintf(pHashPrint, 3, "%02X", hashData[i]);
+ pHashPrint += 2;
+ }
+ *pHashPrint = '\0';
+ thumbprint = hashPrint;
+ }
+ CertFreeCertificateContext(certContext);
+ }
+ CertCloseStore(certStore, 0);
+ }
+ }
+ }
+ }
+ }
+ CloseHandle(certFile);
+ }
+
+ return thumbprint;
+}
}
void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
@@ -4873,15 +4958,15 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
if (this->IsMissingFiles &&
!(this->GlobalGenerator->TargetsWindowsPhone() &&
- this->GlobalGenerator->GetSystemVersion() == "8.0")) {
+ this->GlobalGenerator->GetSystemVersion() == "8.0"_s)) {
// Move the manifest to a project directory to avoid clashes
std::string artifactDir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
ConvertToWindowsSlash(artifactDir);
Elem e1(e0, "PropertyGroup");
- e1.Element("AppxPackageArtifactsDir", artifactDir + "\\");
+ e1.Element("AppxPackageArtifactsDir", cmStrCat(artifactDir, '\\'));
std::string resourcePriFile =
- this->DefaultArtifactDir + "/resources.pri";
+ cmStrCat(this->DefaultArtifactDir, "/resources.pri");
ConvertToWindowsSlash(resourcePriFile);
e1.Element("ProjectPriFullPath", resourcePriFile);
@@ -4889,24 +4974,26 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
// aren't targeting WP8.0, add a default certificate
if (pfxFile.empty()) {
std::string templateFolder =
- cmSystemTools::GetCMakeRoot() + "/Templates/Windows";
- pfxFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
- cmSystemTools::CopyAFile(templateFolder + "/Windows_TemporaryKey.pfx",
- pfxFile, false);
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Templates/Windows");
+ pfxFile =
+ cmStrCat(this->DefaultArtifactDir, "/Windows_TemporaryKey.pfx");
+ cmSystemTools::CopyAFile(
+ cmStrCat(templateFolder, "/Windows_TemporaryKey.pfx"), pfxFile,
+ false);
ConvertToWindowsSlash(pfxFile);
this->AddedFiles.push_back(pfxFile);
this->AddedDefaultCertificate = true;
}
e1.Element("PackageCertificateKeyFile", pfxFile);
- std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+ std::string thumb = ComputeCertificateThumbprint(pfxFile);
if (!thumb.empty()) {
e1.Element("PackageCertificateThumbprint", thumb);
}
} else if (!pfxFile.empty()) {
Elem e1(e0, "PropertyGroup");
e1.Element("PackageCertificateKeyFile", pfxFile);
- std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+ std::string thumb = ComputeCertificateThumbprint(pfxFile);
if (!thumb.empty()) {
e1.Element("PackageCertificateThumbprint", thumb);
}
@@ -4933,7 +5020,8 @@ void cmVisualStudio10TargetGenerator::ClassifyAllConfigSource(
// where the user supplied the file name and Visual Studio
// appended the suffix.
std::string resx = acs.Source->ResolveFullPath();
- std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
+ std::string hFileName =
+ cmStrCat(resx.substr(0, resx.find_last_of('.')), ".h");
this->ExpectedResxHeaders.insert(hFileName);
} break;
case cmGeneratorTarget::SourceKindXaml: {
@@ -4943,8 +5031,8 @@ void cmVisualStudio10TargetGenerator::ClassifyAllConfigSource(
// where the user supplied the file name and Visual Studio
// appended the suffix.
std::string xaml = acs.Source->ResolveFullPath();
- std::string hFileName = xaml + ".h";
- std::string cppFileName = xaml + ".cpp";
+ std::string hFileName = cmStrCat(xaml, ".h");
+ std::string cppFileName = cmStrCat(xaml, ".cpp");
this->ExpectedXamlHeaders.insert(hFileName);
this->ExpectedXamlSources.insert(cppFileName);
} break;
@@ -4983,7 +5071,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
e1.Element("ApplicationType",
(isWindowsPhone ? "Windows Phone" : "Windows Store"));
e1.Element("DefaultLanguage", "en-US");
- if (rev == "10.0") {
+ if (rev == "10.0"_s) {
e1.Element("ApplicationTypeRevision", rev);
// Visual Studio 14.0 is necessary for building 10.0 apps
e1.Element("MinimumVisualStudioVersion", "14.0");
@@ -4991,7 +5079,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
if (this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) {
isAppContainer = true;
}
- } else if (rev == "8.1") {
+ } else if (rev == "8.1"_s) {
e1.Element("ApplicationTypeRevision", rev);
// Visual Studio 12.0 is necessary for building 8.1 apps
e1.Element("MinimumVisualStudioVersion", "12.0");
@@ -4999,7 +5087,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
if (this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) {
isAppContainer = true;
}
- } else if (rev == "8.0") {
+ } else if (rev == "8.0"_s) {
e1.Element("ApplicationTypeRevision", rev);
// Visual Studio 11.0 is necessary for building 8.0 apps
e1.Element("MinimumVisualStudioVersion", "11.0");
@@ -5012,7 +5100,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
cmStateEnums::EXECUTABLE) {
e1.Element("XapOutputs", "true");
e1.Element("XapFilename",
- this->Name + "_$(Configuration)_$(Platform).xap");
+ cmStrCat(this->Name, "_$(Configuration)_$(Platform).xap"));
}
}
} else if (isAndroid) {
@@ -5023,9 +5111,9 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
if (isAppContainer) {
e1.Element("AppContainerApplication", "true");
} else if (!isAndroid) {
- if (this->Platform == "ARM64") {
+ if (this->Platform == "ARM64"_s) {
e1.Element("WindowsSDKDesktopARM64Support", "true");
- } else if (this->Platform == "ARM") {
+ } else if (this->Platform == "ARM"_s) {
e1.Element("WindowsSDKDesktopARMSupport", "true");
}
}
@@ -5038,7 +5126,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
"VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
if (targetPlatformMinVersion) {
e1.Element("WindowsTargetPlatformMinVersion", *targetPlatformMinVersion);
- } else if (isWindowsStore && rev == "10.0") {
+ } else if (isWindowsStore && rev == "10.0"_s) {
// If the min version is not set, then use the TargetPlatformVersion
if (!targetPlatformVersion.empty()) {
e1.Element("WindowsTargetPlatformMinVersion", targetPlatformVersion);
@@ -5061,7 +5149,7 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
cmGeneratorTarget::SourceKindAppManifest);
std::string const& v = this->GlobalGenerator->GetSystemVersion();
if (this->GlobalGenerator->TargetsWindowsPhone()) {
- if (v == "8.0") {
+ if (v == "8.0"_s) {
// Look through the sources for WMAppManifest.xml
bool foundManifest = false;
for (cmGeneratorTarget::AllConfigSource const& source :
@@ -5077,16 +5165,16 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
if (!foundManifest) {
this->IsMissingFiles = true;
}
- } else if (v == "8.1") {
+ } else if (v == "8.1"_s) {
if (manifestSources.empty()) {
this->IsMissingFiles = true;
}
}
} else if (this->GlobalGenerator->TargetsWindowsStore()) {
if (manifestSources.empty()) {
- if (v == "8.0") {
+ if (v == "8.0"_s) {
this->IsMissingFiles = true;
- } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
+ } else if (v == "8.1"_s || cmHasLiteralPrefix(v, "10.0")) {
this->IsMissingFiles = true;
}
}
@@ -5098,15 +5186,15 @@ void cmVisualStudio10TargetGenerator::WriteMissingFiles(Elem& e1)
{
std::string const& v = this->GlobalGenerator->GetSystemVersion();
if (this->GlobalGenerator->TargetsWindowsPhone()) {
- if (v == "8.0") {
+ if (v == "8.0"_s) {
this->WriteMissingFilesWP80(e1);
- } else if (v == "8.1") {
+ } else if (v == "8.1"_s) {
this->WriteMissingFilesWP81(e1);
}
} else if (this->GlobalGenerator->TargetsWindowsStore()) {
- if (v == "8.0") {
+ if (v == "8.0"_s) {
this->WriteMissingFilesWS80(e1);
- } else if (v == "8.1") {
+ } else if (v == "8.1"_s) {
this->WriteMissingFilesWS81(e1);
} else if (cmHasLiteralPrefix(v, "10.0")) {
this->WriteMissingFilesWS10_0(e1);
@@ -5117,13 +5205,13 @@ void cmVisualStudio10TargetGenerator::WriteMissingFiles(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80(Elem& e1)
{
std::string templateFolder =
- cmSystemTools::GetCMakeRoot() + "/Templates/Windows";
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Templates/Windows");
// For WP80, the manifest needs to be in the same folder as the project
// this can cause an overwrite problem if projects aren't organized in
// folders
- std::string manifestFile =
- this->LocalGenerator->GetCurrentBinaryDirectory() + "/WMAppManifest.xml";
+ std::string manifestFile = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), "/WMAppManifest.xml");
std::string artifactDir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
ConvertToWindowsSlash(artifactDir);
@@ -5180,22 +5268,22 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80(Elem& e1)
}
this->AddedFiles.push_back(sourceFile);
- std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png";
- cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png", smallLogo,
- false);
+ std::string smallLogo = cmStrCat(this->DefaultArtifactDir, "/SmallLogo.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/SmallLogo.png"),
+ smallLogo, false);
ConvertToWindowsSlash(smallLogo);
Elem(e1, "Image").Attribute("Include", smallLogo);
this->AddedFiles.push_back(smallLogo);
- std::string logo = this->DefaultArtifactDir + "/Logo.png";
- cmSystemTools::CopyAFile(templateFolder + "/Logo.png", logo, false);
+ std::string logo = cmStrCat(this->DefaultArtifactDir, "/Logo.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/Logo.png"), logo, false);
ConvertToWindowsSlash(logo);
Elem(e1, "Image").Attribute("Include", logo);
this->AddedFiles.push_back(logo);
std::string applicationIcon =
- this->DefaultArtifactDir + "/ApplicationIcon.png";
- cmSystemTools::CopyAFile(templateFolder + "/ApplicationIcon.png",
+ cmStrCat(this->DefaultArtifactDir, "/ApplicationIcon.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/ApplicationIcon.png"),
applicationIcon, false);
ConvertToWindowsSlash(applicationIcon);
Elem(e1, "Image").Attribute("Include", applicationIcon);
@@ -5205,7 +5293,7 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteMissingFilesWP81(Elem& e1)
{
std::string manifestFile =
- this->DefaultArtifactDir + "/package.appxManifest";
+ cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
std::string artifactDir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
ConvertToWindowsSlash(artifactDir);
@@ -5267,7 +5355,7 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP81(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteMissingFilesWS80(Elem& e1)
{
std::string manifestFile =
- this->DefaultArtifactDir + "/package.appxManifest";
+ cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
std::string artifactDir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
ConvertToWindowsSlash(artifactDir);
@@ -5321,7 +5409,7 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWS80(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81(Elem& e1)
{
std::string manifestFile =
- this->DefaultArtifactDir + "/package.appxManifest";
+ cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
std::string artifactDir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
ConvertToWindowsSlash(artifactDir);
@@ -5380,7 +5468,7 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteMissingFilesWS10_0(Elem& e1)
{
std::string manifestFile =
- this->DefaultArtifactDir + "/package.appxManifest";
+ cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
std::string artifactDir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
ConvertToWindowsSlash(artifactDir);
@@ -5441,7 +5529,7 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
Elem& e1, const std::string& manifestFile)
{
std::string templateFolder =
- cmSystemTools::GetCMakeRoot() + "/Templates/Windows";
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Templates/Windows");
std::string sourceFile = this->ConvertPath(manifestFile, false);
ConvertToWindowsSlash(sourceFile);
@@ -5452,36 +5540,38 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
}
this->AddedFiles.push_back(sourceFile);
- std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png";
- cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png", smallLogo,
- false);
+ std::string smallLogo = cmStrCat(this->DefaultArtifactDir, "/SmallLogo.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/SmallLogo.png"),
+ smallLogo, false);
ConvertToWindowsSlash(smallLogo);
Elem(e1, "Image").Attribute("Include", smallLogo);
this->AddedFiles.push_back(smallLogo);
- std::string smallLogo44 = this->DefaultArtifactDir + "/SmallLogo44x44.png";
- cmSystemTools::CopyAFile(templateFolder + "/SmallLogo44x44.png", smallLogo44,
- false);
+ std::string smallLogo44 =
+ cmStrCat(this->DefaultArtifactDir, "/SmallLogo44x44.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/SmallLogo44x44.png"),
+ smallLogo44, false);
ConvertToWindowsSlash(smallLogo44);
Elem(e1, "Image").Attribute("Include", smallLogo44);
this->AddedFiles.push_back(smallLogo44);
- std::string logo = this->DefaultArtifactDir + "/Logo.png";
- cmSystemTools::CopyAFile(templateFolder + "/Logo.png", logo, false);
+ std::string logo = cmStrCat(this->DefaultArtifactDir, "/Logo.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/Logo.png"), logo, false);
ConvertToWindowsSlash(logo);
Elem(e1, "Image").Attribute("Include", logo);
this->AddedFiles.push_back(logo);
- std::string storeLogo = this->DefaultArtifactDir + "/StoreLogo.png";
- cmSystemTools::CopyAFile(templateFolder + "/StoreLogo.png", storeLogo,
- false);
+ std::string storeLogo = cmStrCat(this->DefaultArtifactDir, "/StoreLogo.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/StoreLogo.png"),
+ storeLogo, false);
ConvertToWindowsSlash(storeLogo);
Elem(e1, "Image").Attribute("Include", storeLogo);
this->AddedFiles.push_back(storeLogo);
- std::string splashScreen = this->DefaultArtifactDir + "/SplashScreen.png";
- cmSystemTools::CopyAFile(templateFolder + "/SplashScreen.png", splashScreen,
- false);
+ std::string splashScreen =
+ cmStrCat(this->DefaultArtifactDir, "/SplashScreen.png");
+ cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/SplashScreen.png"),
+ splashScreen, false);
ConvertToWindowsSlash(splashScreen);
Elem(e1, "Image").Attribute("Include", splashScreen);
this->AddedFiles.push_back(splashScreen);
@@ -5489,7 +5579,7 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
if (this->AddedDefaultCertificate) {
// This file has already been added to the build so don't copy it
std::string keyFile =
- this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
+ cmStrCat(this->DefaultArtifactDir, "/Windows_TemporaryKey.pfx");
ConvertToWindowsSlash(keyFile);
Elem(e1, "None").Attribute("Include", keyFile);
}
@@ -5564,8 +5654,9 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(fullFileName, sourceGroups);
if (sourceGroup && !sourceGroup->GetFullName().empty()) {
- sourceGroupedFile = sourceGroup->GetFullName() + "/" +
- cmsys::SystemTools::GetFilenameName(fullFileName);
+ sourceGroupedFile =
+ cmStrCat(sourceGroup->GetFullName(), '/',
+ cmsys::SystemTools::GetFilenameName(fullFileName));
cmsys::SystemTools::ConvertToUnixSlashes(sourceGroupedFile);
}
@@ -5613,8 +5704,9 @@ void cmVisualStudio10TargetGenerator::UpdateCache()
// Store a cache entry that later determines, if a package restore is
// required.
this->GeneratorTarget->Makefile->AddCacheDefinition(
- this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE", "ON",
- "Value Computed by CMake", cmStateEnums::STATIC);
+ cmStrCat(this->GeneratorTarget->GetName(),
+ "_REQUIRES_VS_PACKAGE_RESTORE"),
+ "ON", "Value Computed by CMake", cmStateEnums::STATIC);
} else {
// If there are any dependencies that require package restore, inherit the
// cache variable.
@@ -5627,7 +5719,8 @@ void cmVisualStudio10TargetGenerator::UpdateCache()
for (cmGeneratorTarget const* dt : depends) {
if (dt->HasPackageReferences()) {
this->GeneratorTarget->Makefile->AddCacheDefinition(
- this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE",
+ cmStrCat(this->GeneratorTarget->GetName(),
+ "_REQUIRES_VS_PACKAGE_RESTORE"),
"ON", "Value Computed by CMake", cmStateEnums::STATIC);
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 6e98874..6188134 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -7,6 +7,7 @@
#include <vector>
#include <cm/iterator>
+#include <cmext/string_view>
#include "cmAlgorithms.h"
#include "cmLocalVisualStudioGenerator.h"
@@ -75,7 +76,6 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
// the flag to disable exception handling. When the user does
// remove the flag we need to override the IDE default of on.
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VSVersion::VS11:
case cmGlobalVisualStudioGenerator::VSVersion::VS12:
case cmGlobalVisualStudioGenerator::VSVersion::VS14:
case cmGlobalVisualStudioGenerator::VSVersion::VS15:
@@ -118,7 +118,7 @@ bool cmVisualStudioGeneratorOptions::IsDebug() const
auto i = this->FlagMap.find("DebugType");
if (i != this->FlagMap.end()) {
if (i->second.size() == 1) {
- return i->second[0] != "none";
+ return i->second[0] != "none"_s;
}
}
return false;
@@ -138,13 +138,13 @@ bool cmVisualStudioGeneratorOptions::UsingUnicode() const
{
// Look for a _UNICODE definition.
return std::any_of(this->Defines.begin(), this->Defines.end(),
- [](std::string const& di) { return di == "_UNICODE"; });
+ [](std::string const& di) { return di == "_UNICODE"_s; });
}
bool cmVisualStudioGeneratorOptions::UsingSBCS() const
{
// Look for a _SBCS definition.
return std::any_of(this->Defines.begin(), this->Defines.end(),
- [](std::string const& di) { return di == "_SBCS"; });
+ [](std::string const& di) { return di == "_SBCS"_s; });
}
void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
@@ -172,7 +172,7 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
return;
}
- if (subOptions.size() == 1 && subOptions[0] == "NO") {
+ if (subOptions.size() == 1 && subOptions[0] == "NO"_s) {
AddFlag(ENABLE_UAC, "false");
return;
}
@@ -199,7 +199,7 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
1, std::max(std::string::size_type(0), keyValue[1].length() - 2));
}
- if (keyValue[0] == "level") {
+ if (keyValue[0] == "level"_s) {
if (uacExecuteLevelMap.find(keyValue[1]) == uacExecuteLevelMap.end()) {
// unknown level value
continue;
@@ -209,8 +209,8 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
continue;
}
- if (keyValue[0] == "uiAccess") {
- if (keyValue[1] != "true" && keyValue[1] != "false") {
+ if (keyValue[0] == "uiAccess"_s) {
+ if (keyValue[1] != "true"_s && keyValue[1] != "false"_s) {
// unknown uiAccess value
continue;
}
@@ -261,11 +261,11 @@ void cmVisualStudioGeneratorOptions::ParseFinish()
auto i = this->FlagMap.find("CudaRuntime");
if (i != this->FlagMap.end() && i->second.size() == 1) {
std::string& cudaRuntime = i->second[0];
- if (cudaRuntime == "static") {
+ if (cudaRuntime == "static"_s) {
cudaRuntime = "Static";
- } else if (cudaRuntime == "shared") {
+ } else if (cudaRuntime == "shared"_s) {
cudaRuntime = "Shared";
- } else if (cudaRuntime == "none") {
+ } else if (cudaRuntime == "none"_s) {
cudaRuntime = "None";
}
}
@@ -280,7 +280,7 @@ void cmVisualStudioGeneratorOptions::PrependInheritedString(
return;
}
std::string& value = i->second[0];
- value = "%(" + key + ") " + value;
+ value = cmStrCat("%(", key, ") ", value);
}
void cmVisualStudioGeneratorOptions::Reparse(std::string const& key)
@@ -299,19 +299,19 @@ void cmVisualStudioGeneratorOptions::StoreUnknownFlag(std::string const& flag)
{
// Look for Intel Fortran flags that do not map well in the flag table.
if (this->CurrentTool == FortranCompiler) {
- if (flag == "/dbglibs" || flag == "-dbglibs") {
+ if (flag == "/dbglibs"_s || flag == "-dbglibs"_s) {
this->FortranRuntimeDebug = true;
return;
}
- if (flag == "/threads" || flag == "-threads") {
+ if (flag == "/threads"_s || flag == "-threads"_s) {
this->FortranRuntimeMT = true;
return;
}
- if (flag == "/libs:dll" || flag == "-libs:dll") {
+ if (flag == "/libs:dll"_s || flag == "-libs:dll"_s) {
this->FortranRuntimeDLL = true;
return;
}
- if (flag == "/libs:static" || flag == "-libs:static") {
+ if (flag == "/libs:static"_s || flag == "-libs:static"_s) {
this->FortranRuntimeDLL = false;
return;
}
@@ -355,13 +355,13 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
return;
}
std::string tag = "PreprocessorDefinitions";
- if (lang == "CUDA") {
+ if (lang == "CUDA"_s) {
tag = "Defines";
}
std::ostringstream oss;
if (this->Version != cmGlobalVisualStudioGenerator::VSVersion::VS9) {
- oss << "%(" << tag << ")";
+ oss << "%(" << tag << ')';
}
auto de = cmRemoveDuplicates(this->Defines);
for (std::string const& di : cmMakeRange(this->Defines.cbegin(), de)) {
@@ -375,7 +375,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
// Escape this flag for the MSBuild.
if (this->Version != cmGlobalVisualStudioGenerator::VSVersion::VS9) {
cmVS10EscapeForMSBuild(define);
- if (lang == "RC") {
+ if (lang == "RC"_s) {
cmSystemTools::ReplaceString(define, "\"", "\\\"");
}
}
@@ -394,9 +394,9 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
}
std::string tag = "AdditionalIncludeDirectories";
- if (lang == "CUDA") {
+ if (lang == "CUDA"_s) {
tag = "Include";
- } else if (lang == "ASM_MASM" || lang == "ASM_NASM") {
+ } else if (lang == "ASM_MASM"_s || lang == "ASM_NASM"_s) {
tag = "IncludePaths";
}
@@ -410,8 +410,8 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
pos++;
}
- if (lang == "ASM_NASM") {
- include += "\\";
+ if (lang == "ASM_NASM"_s) {
+ include += '\\';
}
// Escape this include for the MSBuild.
@@ -421,14 +421,14 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
oss << sep << include;
sep = ";";
- if (lang == "Fortran") {
+ if (lang == "Fortran"_s) {
include += "/$(ConfigurationName)";
oss << sep << include;
}
}
if (this->Version != cmGlobalVisualStudioGenerator::VSVersion::VS9) {
- oss << sep << "%(" << tag << ")";
+ oss << sep << "%(" << tag << ')';
}
this->OutputFlag(fout, indent, tag, oss.str());
diff --git a/Source/cmVisualStudioSlnData.cxx b/Source/cmVisualStudioSlnData.cxx
index 4b6754e..f685158 100644
--- a/Source/cmVisualStudioSlnData.cxx
+++ b/Source/cmVisualStudioSlnData.cxx
@@ -5,6 +5,7 @@
#include <cstddef>
#include <utility>
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
void cmSlnProjectEntry::AddProjectConfiguration(
@@ -72,7 +73,8 @@ std::string cmSlnData::GetConfigurationTarget(
const std::string& projectName, const std::string& solutionConfiguration,
const std::string& platformName)
{
- std::string solutionTarget = solutionConfiguration + "|" + platformName;
+ std::string solutionTarget =
+ cmStrCat(solutionConfiguration, '|', platformName);
cm::optional<cmSlnProjectEntry> project = GetProjectByName(projectName);
if (!project) {
return platformName;
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 71c758e..adfd4c5 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -8,6 +8,8 @@
#include <utility>
#include <vector>
+#include <cmext/string_view>
+
#include "cmsys/FStream.hxx"
#include "cmStringAlgorithms.h"
@@ -81,7 +83,7 @@ bool cmVisualStudioSlnParser::ParsedLine::IsKeyValuePair() const
std::string cmVisualStudioSlnParser::ParsedLine::GetArgVerbatim() const
{
if (this->Arg.second) {
- return Quote + this->Arg.first + Quote;
+ return cmStrCat(Quote, this->Arg.first, Quote);
}
return this->Arg.first;
}
@@ -101,7 +103,7 @@ std::string cmVisualStudioSlnParser::ParsedLine::GetValueVerbatim(
if (idxValue < this->Values.size()) {
const StringData& data = this->Values[idxValue];
if (data.second) {
- return Quote + data.first + Quote;
+ return cmStrCat(Quote, data.first, Quote);
}
return data.first;
}
@@ -169,17 +171,12 @@ LineFormat cmVisualStudioSlnParser::State::NextLineFormat() const
case FileStateTopLevel:
return LineMultiValueTag;
case FileStateProject:
- return LineSingleValueTag;
- case FileStateProjectDependencies:
- return LineKeyValuePair;
case FileStateGlobal:
return LineSingleValueTag;
+ case FileStateProjectDependencies:
case FileStateSolutionConfigurations:
- return LineKeyValuePair;
case FileStateProjectConfigurations:
- return LineKeyValuePair;
case FileStateSolutionFilters:
- return LineKeyValuePair;
case FileStateGlobalSection:
return LineKeyValuePair;
case FileStateIgnore:
@@ -206,7 +203,7 @@ bool cmVisualStudioSlnParser::State::Process(
this->Stack.push(FileStateTopLevel);
break;
case FileStateTopLevel:
- if (line.GetTag() == "Project") {
+ if (line.GetTag() == "Project"_s) {
if (line.GetValueCount() != 3) {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
@@ -221,12 +218,12 @@ bool cmVisualStudioSlnParser::State::Process(
} else {
this->IgnoreUntilTag("EndProject");
}
- } else if (line.GetTag() == "Global") {
+ } else if (line.GetTag() == "Global"_s) {
this->Stack.push(FileStateGlobal);
- } else if (line.GetTag() == "VisualStudioVersion") {
+ } else if (line.GetTag() == "VisualStudioVersion"_s) {
output.SetVisualStudioVersion(line.GetValue(0));
- } else if (line.GetTag() == "MinimumVisualStudioVersion") {
+ } else if (line.GetTag() == "MinimumVisualStudioVersion"_s) {
output.SetMinimumVisualStudioVersion(line.GetValue(0));
} else {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
@@ -234,11 +231,11 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateProject:
- if (line.GetTag() == "EndProject") {
+ if (line.GetTag() == "EndProject"_s) {
this->Stack.pop();
- } else if (line.GetTag() == "ProjectSection") {
- if (line.GetArg() == "ProjectDependencies" &&
- line.GetValue(0) == "postProject") {
+ } else if (line.GetTag() == "ProjectSection"_s) {
+ if (line.GetArg() == "ProjectDependencies"_s &&
+ line.GetValue(0) == "postProject"_s) {
if (this->RequestedData.test(DataGroupProjectDependenciesBit)) {
this->Stack.push(FileStateProjectDependencies);
} else {
@@ -253,7 +250,7 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateProjectDependencies:
- if (line.GetTag() == "EndProjectSection") {
+ if (line.GetTag() == "EndProjectSection"_s) {
this->Stack.pop();
} else if (line.IsKeyValuePair()) {
// implement dependency storing here, once needed
@@ -264,25 +261,25 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateGlobal:
- if (line.GetTag() == "EndGlobal") {
+ if (line.GetTag() == "EndGlobal"_s) {
this->Stack.pop();
- } else if (line.GetTag() == "GlobalSection") {
- if (line.GetArg() == "SolutionConfigurationPlatforms" &&
- line.GetValue(0) == "preSolution") {
+ } else if (line.GetTag() == "GlobalSection"_s) {
+ if (line.GetArg() == "SolutionConfigurationPlatforms"_s &&
+ line.GetValue(0) == "preSolution"_s) {
if (this->RequestedData.test(DataGroupSolutionConfigurationsBit)) {
this->Stack.push(FileStateSolutionConfigurations);
} else {
this->IgnoreUntilTag("EndGlobalSection");
}
- } else if (line.GetArg() == "ProjectConfigurationPlatforms" &&
- line.GetValue(0) == "postSolution") {
+ } else if (line.GetArg() == "ProjectConfigurationPlatforms"_s &&
+ line.GetValue(0) == "postSolution"_s) {
if (this->RequestedData.test(DataGroupProjectConfigurationsBit)) {
this->Stack.push(FileStateProjectConfigurations);
} else {
this->IgnoreUntilTag("EndGlobalSection");
}
- } else if (line.GetArg() == "NestedProjects" &&
- line.GetValue(0) == "preSolution") {
+ } else if (line.GetArg() == "NestedProjects"_s &&
+ line.GetValue(0) == "preSolution"_s) {
if (this->RequestedData.test(DataGroupSolutionFiltersBit)) {
this->Stack.push(FileStateSolutionFilters);
} else {
@@ -300,7 +297,7 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateSolutionConfigurations:
- if (line.GetTag() == "EndGlobalSection") {
+ if (line.GetTag() == "EndGlobalSection"_s) {
this->Stack.pop();
} else if (line.IsKeyValuePair()) {
output.AddConfiguration(line.GetValue(0));
@@ -310,7 +307,7 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateProjectConfigurations:
- if (line.GetTag() == "EndGlobalSection") {
+ if (line.GetTag() == "EndGlobalSection"_s) {
this->Stack.pop();
} else if (line.IsKeyValuePair()) {
std::vector<std::string> tagElements =
@@ -331,7 +328,7 @@ bool cmVisualStudioSlnParser::State::Process(
return false;
}
- if (activeBuild == "ActiveCfg") {
+ if (activeBuild == "ActiveCfg"_s) {
projectEntry->AddProjectConfiguration(solutionConfiguration,
line.GetValue(0));
}
@@ -341,7 +338,7 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateSolutionFilters:
- if (line.GetTag() == "EndGlobalSection") {
+ if (line.GetTag() == "EndGlobalSection"_s) {
this->Stack.pop();
} else if (line.IsKeyValuePair()) {
// implement filter storing here, once needed
@@ -352,7 +349,7 @@ bool cmVisualStudioSlnParser::State::Process(
}
break;
case FileStateGlobalSection:
- if (line.GetTag() == "EndGlobalSection") {
+ if (line.GetTag() == "EndGlobalSection"_s) {
this->Stack.pop();
} else if (line.IsKeyValuePair()) {
// implement section storing here, once needed
@@ -544,7 +541,7 @@ bool cmVisualStudioSlnParser::ParseBOM(std::istream& input, std::string& line,
return false;
}
if (!this->LastResult.HadBOM) {
- line = bom + line; // it wasn't a BOM, prepend it to first line
+ line = cmStrCat(bom, line); // it wasn't a BOM, prepend it to first line
}
return true;
}
diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx
index d8d0da9..8aa5384 100644
--- a/Source/cmVisualStudioWCEPlatformParser.cxx
+++ b/Source/cmVisualStudioWCEPlatformParser.cxx
@@ -7,14 +7,15 @@
#include <utility>
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version)
{
const std::string registryBase =
cmGlobalVisualStudioGenerator::GetRegistryBase(version);
- const std::string vckey = registryBase + "\\Setup\\VC;ProductDir";
- const std::string vskey = registryBase + "\\Setup\\VS;ProductDir";
+ const std::string vckey = cmStrCat(registryBase, "\\Setup\\VC;ProductDir");
+ const std::string vskey = cmStrCat(registryBase, "\\Setup\\VS;ProductDir");
if (!cmSystemTools::ReadRegistryValue(vckey, this->VcInstallDir,
cmSystemTools::KeyWOW64_32) ||
@@ -24,11 +25,10 @@ int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version)
}
cmSystemTools::ConvertToUnixSlashes(this->VcInstallDir);
cmSystemTools::ConvertToUnixSlashes(this->VsInstallDir);
- this->VcInstallDir.append("/");
- this->VsInstallDir.append("/");
+ this->VcInstallDir.append("//");
const std::string configFilename =
- this->VcInstallDir + "vcpackages/WCE.VCPlatform.config";
+ cmStrCat(this->VcInstallDir, "vcpackages/WCE.VCPlatform.config");
return this->ParseFile(configFilename.c_str());
}
@@ -39,7 +39,7 @@ std::string cmVisualStudioWCEPlatformParser::GetOSVersion() const
return OSMajorVersion;
}
- return OSMajorVersion + "." + OSMinorVersion;
+ return cmStrCat(OSMajorVersion, '.', OSMinorVersion);
}
const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const
@@ -61,14 +61,14 @@ void cmVisualStudioWCEPlatformParser::StartElement(const std::string& name,
this->CharacterData.clear();
- if (name == "PlatformData") {
+ if (name == "PlatformData"_s) {
this->PlatformName.clear();
this->OSMajorVersion.clear();
this->OSMinorVersion.clear();
this->Macros.clear();
}
- if (name == "Macro") {
+ if (name == "Macro"_s) {
std::string macroName;
std::string macroValue;
@@ -83,7 +83,7 @@ void cmVisualStudioWCEPlatformParser::StartElement(const std::string& name,
if (!macroName.empty()) {
this->Macros[macroName] = macroValue;
}
- } else if (name == "Directories") {
+ } else if (name == "Directories"_s) {
for (const char** attr = attributes; *attr; attr += 2) {
if (strcmp(attr[0], "Include") == 0) {
this->Include = attr[1];
@@ -99,7 +99,7 @@ void cmVisualStudioWCEPlatformParser::StartElement(const std::string& name,
void cmVisualStudioWCEPlatformParser::EndElement(const std::string& name)
{
if (!this->RequiredName) {
- if (name == "PlatformName") {
+ if (name == "PlatformName"_s) {
this->AvailablePlatforms.push_back(this->CharacterData);
}
return;
@@ -109,13 +109,13 @@ void cmVisualStudioWCEPlatformParser::EndElement(const std::string& name)
return;
}
- if (name == "PlatformName") {
+ if (name == "PlatformName"_s) {
this->PlatformName = this->CharacterData;
- } else if (name == "OSMajorVersion") {
+ } else if (name == "OSMajorVersion"_s) {
this->OSMajorVersion = this->CharacterData;
- } else if (name == "OSMinorVersion") {
+ } else if (name == "OSMinorVersion"_s) {
this->OSMinorVersion = this->CharacterData;
- } else if (name == "Platform") {
+ } else if (name == "Platform"_s) {
if (this->PlatformName == this->RequiredName) {
this->FoundRequiredName = true;
}
diff --git a/Source/cmWindowsRegistry.cxx b/Source/cmWindowsRegistry.cxx
index 6dba863..a4a1ad6 100644
--- a/Source/cmWindowsRegistry.cxx
+++ b/Source/cmWindowsRegistry.cxx
@@ -6,7 +6,6 @@
#include <cctype>
#include <cstddef>
-#include <functional>
#include <type_traits>
#include <unordered_map>
#include <utility>
diff --git a/Source/cmWindowsRegistry.h b/Source/cmWindowsRegistry.h
index f4a0e7b..42179ed 100644
--- a/Source/cmWindowsRegistry.h
+++ b/Source/cmWindowsRegistry.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <cstdint> // IWYU pragma: keep
+#include <initializer_list>
#include <string>
#include <vector>
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index 9b0dc58..7a40eaa 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -26,9 +26,7 @@ void cmXCode21Object::PrintComment(std::ostream& out)
if (this->Comment.empty()) {
return;
}
- out << " /* ";
- out << this->Comment;
- out << " */";
+ out << " /* " << this->Comment << " */";
}
void cmXCode21Object::PrintList(
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index c817980..ddd9669 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -4,6 +4,8 @@
#include <ostream>
+#include <cmext/string_view>
+
#include <CoreFoundation/CoreFoundation.h>
const char* cmXCodeObject::PBXTypeNames[] = {
@@ -91,13 +93,13 @@ void cmXCodeObject::Print(std::ostream& out)
out << this->Id;
this->PrintComment(out);
out << " = {";
- if (separator == "\n") {
+ if (separator == "\n"_s) {
out << separator;
}
cmXCodeObject::Indent(3 * indentFactor, out);
out << "isa = " << PBXTypeNames[this->IsA] << ";" << separator;
for (const auto& keyVal : this->ObjectAttributes) {
- if (keyVal.first == "isa") {
+ if (keyVal.first == "isa"_s) {
continue;
}
@@ -142,7 +144,7 @@ void cmXCodeObject::PrintAttribute(std::ostream& out, int level,
case ATTRIBUTE_GROUP: {
out << name << " = {";
- if (separator == "\n") {
+ if (separator == "\n"_s) {
out << separator;
}
for (const auto& keyVal : object->ObjectAttributes) {
@@ -156,7 +158,7 @@ void cmXCodeObject::PrintAttribute(std::ostream& out, int level,
case OBJECT_REF: {
cmXCodeObject::PrintString(out, name);
out << " = " << object->Object->Id;
- if (object->Object->HasComment() && name != "remoteGlobalIDString") {
+ if (object->Object->HasComment() && name != "remoteGlobalIDString"_s) {
object->Object->PrintComment(out);
}
out << ";" << separator;
@@ -180,7 +182,7 @@ void cmXCodeObject::PrintList(std::vector<cmXCodeObject*> const& objs,
{
cmXCodeObject::Indent(1, out);
out << "objects = {\n";
- for (auto obj : objs) {
+ for (auto* obj : objs) {
if (obj->TypeValue == OBJECT) {
obj->Print(out);
}
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index 389fb62..10a6861 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -129,7 +129,7 @@ public:
// search the attribute list for an object of the specified type
cmXCodeObject* GetObject(cmXCodeObject::PBXType t) const
{
- for (auto o : this->List) {
+ for (auto* o : this->List) {
if (o->IsA == t) {
return o;
}
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index 7f26fd8..80327e4 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -7,6 +7,7 @@
#include <utility>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/String.h"
@@ -121,7 +122,7 @@ void cmXCodeScheme::WriteTestAction(cmXMLWriter& xout,
xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES");
xout.StartElement("Testables");
- for (auto test : this->Tests) {
+ for (auto const* test : this->Tests) {
xout.StartElement("TestableReference");
xout.BreakAttributes();
xout.Attribute("skipped", "NO");
@@ -157,7 +158,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
cmValue launchMode =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_LAUNCH_MODE");
std::string value = "0"; // == 'AUTO'
- if (launchMode && *launchMode == "WAIT") {
+ if (launchMode && *launchMode == "WAIT"_s) {
value = "1";
}
xout.Attribute("launchStyle", value);
@@ -447,7 +448,7 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
std::string const noConfig; // FIXME: What config to use here?
xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName(noConfig));
xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName());
- xout.Attribute("ReferencedContainer", "container:" + container);
+ xout.Attribute("ReferencedContainer", cmStrCat("container:", container));
xout.EndElement();
}
diff --git a/Source/cmXcFramework.cxx b/Source/cmXcFramework.cxx
new file mode 100644
index 0000000..e377fc9
--- /dev/null
+++ b/Source/cmXcFramework.cxx
@@ -0,0 +1,209 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmXcFramework.h"
+
+#include <string>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+
+#include "cmJSONHelpers.h"
+#include "cmJSONState.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPlistParser.h"
+#include "cmStringAlgorithms.h"
+#include "cmake.h"
+
+namespace {
+struct PlistMetadata
+{
+ std::string CFBundlePackageType;
+ std::string XCFrameworkFormatVersion;
+};
+
+auto const PlistMetadataHelper =
+ cmJSONHelperBuilder::Object<PlistMetadata>{}
+ .Bind("CFBundlePackageType"_s, &PlistMetadata::CFBundlePackageType,
+ cmJSONHelperBuilder::String())
+ .Bind("XCFrameworkFormatVersion"_s,
+ &PlistMetadata::XCFrameworkFormatVersion,
+ cmJSONHelperBuilder::String());
+
+bool PlistSupportedPlatformHelper(
+ cmXcFrameworkPlistSupportedPlatform& platform, const Json::Value* value,
+ cmJSONState* /*state*/)
+{
+ if (!value) {
+ return false;
+ }
+
+ if (!value->isString()) {
+ return false;
+ }
+
+ if (value->asString() == "macos"_s) {
+ platform = cmXcFrameworkPlistSupportedPlatform::macOS;
+ return true;
+ }
+ if (value->asString() == "ios"_s) {
+ platform = cmXcFrameworkPlistSupportedPlatform::iOS;
+ return true;
+ }
+ if (value->asString() == "tvos"_s) {
+ platform = cmXcFrameworkPlistSupportedPlatform::tvOS;
+ return true;
+ }
+ if (value->asString() == "watchos"_s) {
+ platform = cmXcFrameworkPlistSupportedPlatform::watchOS;
+ return true;
+ }
+ if (value->asString() == "xros"_s) {
+ platform = cmXcFrameworkPlistSupportedPlatform::visionOS;
+ return true;
+ }
+
+ return false;
+}
+
+bool PlistSupportedPlatformVariantHelper(
+ cmXcFrameworkPlistSupportedPlatformVariant& variant,
+ const Json::Value* value, cmJSONState* /*state*/)
+{
+ if (!value) {
+ return false;
+ }
+
+ if (!value->isString()) {
+ return false;
+ }
+
+ if (value->asString() == "maccatalyst"_s) {
+ variant = cmXcFrameworkPlistSupportedPlatformVariant::maccatalyst;
+ return true;
+ }
+ if (value->asString() == "simulator"_s) {
+ variant = cmXcFrameworkPlistSupportedPlatformVariant::simulator;
+ return true;
+ }
+
+ return false;
+}
+
+auto const PlistLibraryHelper =
+ cmJSONHelperBuilder::Object<cmXcFrameworkPlistLibrary>{}
+ .Bind("LibraryIdentifier"_s, &cmXcFrameworkPlistLibrary::LibraryIdentifier,
+ cmJSONHelperBuilder::String())
+ .Bind("LibraryPath"_s, &cmXcFrameworkPlistLibrary::LibraryPath,
+ cmJSONHelperBuilder::String())
+ .Bind("HeadersPath"_s, &cmXcFrameworkPlistLibrary::HeadersPath,
+ cmJSONHelperBuilder::String(), false)
+ .Bind("SupportedArchitectures"_s,
+ &cmXcFrameworkPlistLibrary::SupportedArchitectures,
+ cmJSONHelperBuilder::Vector<std::string>(
+ JsonErrors::EXPECTED_TYPE("array"), cmJSONHelperBuilder::String()))
+ .Bind("SupportedPlatform"_s, &cmXcFrameworkPlistLibrary::SupportedPlatform,
+ PlistSupportedPlatformHelper)
+ .Bind("SupportedPlatformVariant"_s,
+ &cmXcFrameworkPlistLibrary::SupportedPlatformVariant,
+ cmJSONHelperBuilder::Optional<
+ cmXcFrameworkPlistSupportedPlatformVariant>(
+ PlistSupportedPlatformVariantHelper),
+ false);
+
+auto const PlistHelper =
+ cmJSONHelperBuilder::Object<cmXcFrameworkPlist>{}.Bind(
+ "AvailableLibraries"_s, &cmXcFrameworkPlist::AvailableLibraries,
+ cmJSONHelperBuilder::Vector<cmXcFrameworkPlistLibrary>(
+ JsonErrors::EXPECTED_TYPE("array"), PlistLibraryHelper));
+}
+
+cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
+ const std::string& xcframeworkPath, const cmMakefile& mf,
+ const cmListFileBacktrace& bt)
+{
+ std::string plistPath = cmStrCat(xcframeworkPath, "/Info.plist");
+
+ auto value = cmParsePlist(plistPath);
+ if (!value) {
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Unable to parse plist file:\n ", plistPath), bt);
+ return cm::nullopt;
+ }
+
+ cmJSONState state;
+
+ PlistMetadata metadata;
+ if (!PlistMetadataHelper(metadata, &*value, &state)) {
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Invalid xcframework .plist file:\n ", plistPath), bt);
+ return cm::nullopt;
+ }
+ if (metadata.CFBundlePackageType != "XFWK"_s ||
+ metadata.XCFrameworkFormatVersion != "1.0"_s) {
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Expected:\n ", plistPath,
+ "\nto have CFBundlePackageType \"XFWK\" and "
+ "XCFrameworkFormatVersion \"1.0\""),
+ bt);
+ return cm::nullopt;
+ }
+
+ cmXcFrameworkPlist plist;
+ if (!PlistHelper(plist, &*value, &state)) {
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Invalid xcframework .plist file:\n ", plistPath), bt);
+ return cm::nullopt;
+ }
+ plist.Path = plistPath;
+ return cm::optional<cmXcFrameworkPlist>(plist);
+}
+
+const cmXcFrameworkPlistLibrary* cmXcFrameworkPlist::SelectSuitableLibrary(
+ const cmMakefile& mf, const cmListFileBacktrace& bt) const
+{
+ auto systemName = mf.GetSafeDefinition("CMAKE_SYSTEM_NAME");
+ cm::optional<cmXcFrameworkPlistSupportedPlatformVariant> systemVariant;
+ if (mf.PlatformIsAppleSimulator()) {
+ systemVariant = cmXcFrameworkPlistSupportedPlatformVariant::simulator;
+ }
+
+ for (auto const& lib : this->AvailableLibraries) {
+ std::string supportedSystemName;
+ switch (lib.SupportedPlatform) {
+ case cmXcFrameworkPlistSupportedPlatform::macOS:
+ supportedSystemName = "Darwin";
+ break;
+ case cmXcFrameworkPlistSupportedPlatform::iOS:
+ supportedSystemName = "iOS";
+ break;
+ case cmXcFrameworkPlistSupportedPlatform::tvOS:
+ supportedSystemName = "tvOS";
+ break;
+ case cmXcFrameworkPlistSupportedPlatform::watchOS:
+ supportedSystemName = "watchOS";
+ break;
+ case cmXcFrameworkPlistSupportedPlatform::visionOS:
+ supportedSystemName = "visionOS";
+ break;
+ }
+
+ if (systemName == supportedSystemName &&
+ systemVariant == lib.SupportedPlatformVariant) {
+ return &lib;
+ }
+ }
+
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Unable to find suitable library in:\n ", this->Path,
+ "\nfor system name \"", systemName, '"'),
+ bt);
+ return nullptr;
+}
diff --git a/Source/cmXcFramework.h b/Source/cmXcFramework.h
new file mode 100644
index 0000000..7ca91da
--- /dev/null
+++ b/Source/cmXcFramework.h
@@ -0,0 +1,52 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+
+#include "cmListFileCache.h"
+
+class cmMakefile;
+
+enum class cmXcFrameworkPlistSupportedPlatform
+{
+ macOS,
+ iOS,
+ tvOS,
+ watchOS,
+ visionOS,
+};
+
+enum class cmXcFrameworkPlistSupportedPlatformVariant
+{
+ maccatalyst,
+ simulator,
+};
+
+struct cmXcFrameworkPlistLibrary
+{
+ std::string LibraryIdentifier;
+ std::string LibraryPath;
+ std::string HeadersPath;
+ std::vector<std::string> SupportedArchitectures;
+ cmXcFrameworkPlistSupportedPlatform SupportedPlatform;
+ cm::optional<cmXcFrameworkPlistSupportedPlatformVariant>
+ SupportedPlatformVariant;
+};
+
+struct cmXcFrameworkPlist
+{
+ std::string Path;
+ std::vector<cmXcFrameworkPlistLibrary> AvailableLibraries;
+
+ const cmXcFrameworkPlistLibrary* SelectSuitableLibrary(
+ const cmMakefile& mf,
+ const cmListFileBacktrace& bt = cmListFileBacktrace{}) const;
+};
+
+cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
+ const std::string& xcframeworkPath, const cmMakefile& mf,
+ const cmListFileBacktrace& bt = cmListFileBacktrace{});
diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx
index 12877b8..60faced 100644
--- a/Source/cm_codecvt.cxx
+++ b/Source/cm_codecvt.cxx
@@ -13,19 +13,21 @@
# include "cm_utf8.h"
#endif
-codecvt::codecvt(Encoding e)
+#include "cm_codecvt_Encoding.hxx"
+
+codecvt::codecvt(codecvt_Encoding e)
#if defined(_WIN32)
: m_codepage(0)
#endif
{
switch (e) {
- case codecvt::ConsoleOutput:
+ case codecvt_Encoding::ConsoleOutput:
#if defined(_WIN32)
m_noconv = false;
m_codepage = GetConsoleOutputCP();
break;
#endif
- case codecvt::ANSI:
+ case codecvt_Encoding::ANSI:
#if defined(_WIN32)
m_noconv = false;
m_codepage = CP_ACP;
@@ -33,10 +35,10 @@ codecvt::codecvt(Encoding e)
#endif
// We don't know which ANSI encoding to use for other platforms than
// Windows so we don't do any conversion there
- case codecvt::UTF8:
- case codecvt::UTF8_WITH_BOM:
+ case codecvt_Encoding::UTF8:
+ case codecvt_Encoding::UTF8_WITH_BOM:
// Assume internal encoding is UTF-8
- case codecvt::None:
+ case codecvt_Encoding::None:
// No encoding
default:
this->m_noconv = true;
diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx
index f628de7..c25f9ef 100644
--- a/Source/cm_codecvt.hxx
+++ b/Source/cm_codecvt.hxx
@@ -7,21 +7,14 @@
#include <cwchar>
#include <locale>
+enum class codecvt_Encoding;
+
class codecvt : public std::codecvt<char, char, mbstate_t>
{
public:
- enum Encoding
- {
- None,
- UTF8,
- UTF8_WITH_BOM,
- ANSI,
- ConsoleOutput,
- };
-
#ifndef CMAKE_BOOTSTRAP
- codecvt(Encoding e);
+ codecvt(codecvt_Encoding e);
protected:
~codecvt() override;
diff --git a/Source/cm_codecvt_Encoding.hxx b/Source/cm_codecvt_Encoding.hxx
new file mode 100644
index 0000000..b91ad8f
--- /dev/null
+++ b/Source/cm_codecvt_Encoding.hxx
@@ -0,0 +1,12 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+enum class codecvt_Encoding
+{
+ None,
+ UTF8,
+ UTF8_WITH_BOM,
+ ANSI,
+ ConsoleOutput,
+};
diff --git a/Source/cm_fileno.cxx b/Source/cm_fileno.cxx
new file mode 100644
index 0000000..a40c5ca
--- /dev/null
+++ b/Source/cm_fileno.cxx
@@ -0,0 +1,15 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#if !defined(_POSIX_C_SOURCE) && !defined(_WIN32) && !defined(__sun) && \
+ !defined(__OpenBSD__)
+/* POSIX APIs are needed */
+// NOLINTNEXTLINE(bugprone-reserved-identifier)
+# define _POSIX_C_SOURCE 200809L
+#endif
+
+#include "cm_fileno.hxx"
+
+int cm_fileno(FILE* f)
+{
+ return fileno(f);
+}
diff --git a/Source/cm_fileno.hxx b/Source/cm_fileno.hxx
new file mode 100644
index 0000000..3abcdcf
--- /dev/null
+++ b/Source/cm_fileno.hxx
@@ -0,0 +1,7 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <cstdio>
+
+int cm_fileno(FILE* f);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f30d4d3..1d8a847 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -23,14 +23,11 @@
#include <cmext/algorithm>
#include <cmext/string_view>
-#if !defined(CMAKE_BOOTSTRAP) && !defined(_WIN32)
-# include <unistd.h>
-#endif
-
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cm_fileno.hxx"
#include "cm_sys_stat.h"
#include "cmBuildOptions.h"
@@ -40,7 +37,11 @@
#include "cmCommands.h"
#ifdef CMake_ENABLE_DEBUGGER
# include "cmDebuggerAdapter.h"
-# include "cmDebuggerPipeConnection.h"
+# ifdef _WIN32
+# include "cmDebuggerWindowsPipeConnection.h"
+# else //!_WIN32
+# include "cmDebuggerPosixPipeConnection.h"
+# endif //_WIN32
#endif
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -94,7 +95,6 @@
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalJOMMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
-# include "cmGlobalVisualStudio11Generator.h"
# include "cmGlobalVisualStudio12Generator.h"
# include "cmGlobalVisualStudio14Generator.h"
# include "cmGlobalVisualStudio9Generator.h"
@@ -2507,6 +2507,18 @@ int cmake::ActualConfigure()
"Name of generator toolset.", cmStateEnums::INTERNAL);
}
+ if (!this->State->GetInitializedCacheValue(
+ "CMAKE_CROSSCOMPILING_EMULATOR")) {
+ cm::optional<std::string> emulator =
+ cmSystemTools::GetEnvVar("CMAKE_CROSSCOMPILING_EMULATOR");
+ if (emulator && !emulator->empty()) {
+ std::string message =
+ "Emulator to run executables and tests when cross compiling.";
+ this->AddCacheEntry("CMAKE_CROSSCOMPILING_EMULATOR", *emulator, message,
+ cmStateEnums::STRING);
+ }
+ }
+
// reset any system configuration information, except for when we are
// InTryCompile. With TryCompile the system info is taken from the parent's
// info to save time
@@ -2605,7 +2617,6 @@ std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
static VSVersionedGenerator const vsGenerators[] = {
{ "14.0", "Visual Studio 14 2015" }, //
{ "12.0", "Visual Studio 12 2013" }, //
- { "11.0", "Visual Studio 11 2012" }, //
{ "9.0", "Visual Studio 9 2008" }
};
static const char* const vsEntries[] = {
@@ -2990,7 +3001,6 @@ void cmake::AddDefaultGenerators()
cmGlobalVisualStudioVersionedGenerator::NewFactory15());
this->Generators.push_back(cmGlobalVisualStudio14Generator::NewFactory());
this->Generators.push_back(cmGlobalVisualStudio12Generator::NewFactory());
- this->Generators.push_back(cmGlobalVisualStudio11Generator::NewFactory());
this->Generators.push_back(cmGlobalVisualStudio9Generator::NewFactory());
this->Generators.push_back(cmGlobalBorlandMakefileGenerator::NewFactory());
this->Generators.push_back(cmGlobalNMakeMakefileGenerator::NewFactory());
@@ -3904,19 +3914,15 @@ std::function<int()> cmake::BuildWorkflowStep(
const std::vector<std::string>& args)
{
cmUVProcessChainBuilder builder;
- builder
- .AddCommand(args)
-# ifdef _WIN32
- .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, _fileno(stdout))
- .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, _fileno(stderr));
-# else
- .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, STDOUT_FILENO)
- .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, STDERR_FILENO);
-# endif
+ builder.AddCommand(args)
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ cm_fileno(stdout))
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(stderr));
return [builder]() -> int {
auto chain = builder.Start();
chain.Wait();
- return static_cast<int>(chain.GetStatus().front()->ExitStatus);
+ return static_cast<int>(chain.GetStatus(0).ExitStatus);
};
}
#endif
diff --git a/Source/cmake.h b/Source/cmake.h
index 156d061..58f90c9 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -17,8 +17,9 @@
#include <cm/string_view>
#include <cmext/string_view>
-#include "cmDocumentationEntry.h"
+#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmGlobalGeneratorFactory.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
@@ -48,7 +49,6 @@ class cmExternalMakefileProjectGeneratorFactory;
class cmFileAPI;
class cmFileTimeCache;
class cmGlobalGenerator;
-class cmGlobalGeneratorFactory;
class cmMakefile;
class cmMessenger;
class cmVariableWatch;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 0c8d8db..94f4d38 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -11,8 +11,11 @@
#include <cm3p/uv.h>
#include <fcntl.h>
+#include "cm_fileno.hxx"
+
#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
+#include "cmCryptoHash.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
@@ -28,6 +31,7 @@
#include "cmSystemTools.h"
#include "cmTransformDepfile.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
#include "cmUtils.hxx"
#include "cmValue.h"
#include "cmVersion.h"
@@ -70,7 +74,6 @@
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/Terminal.h"
@@ -293,14 +296,8 @@ int CLCompileAndDependencies(const std::vector<std::string>& args)
}
}
- std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp(
- cmsysProcess_New(), cmsysProcess_Delete);
- std::vector<const char*> argv(command.size() + 1);
- std::transform(command.begin(), command.end(), argv.begin(),
- [](std::string const& s) { return s.c_str(); });
- argv.back() = nullptr;
- cmsysProcess_SetCommand(cp.get(), argv.data());
- cmsysProcess_SetWorkingDirectory(cp.get(), currentBinaryDir.c_str());
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(command).SetWorkingDirectory(currentBinaryDir);
cmsys::ofstream fout(depFile.c_str());
if (!fout) {
@@ -311,22 +308,18 @@ int CLCompileAndDependencies(const std::vector<std::string>& args)
CLOutputLogger errLogger(std::cerr);
// Start the process.
- cmProcessTools::RunProcess(cp.get(), &includeParser, &errLogger);
+ auto result =
+ cmProcessTools::RunProcess(builder, &includeParser, &errLogger);
+ auto const& subStatus = result.front();
int status = 0;
// handle status of process
- switch (cmsysProcess_GetState(cp.get())) {
- case cmsysProcess_State_Exited:
- status = cmsysProcess_GetExitValue(cp.get());
- break;
- case cmsysProcess_State_Exception:
- status = 1;
- break;
- case cmsysProcess_State_Error:
- status = 2;
- break;
- default:
- break;
+ if (subStatus.SpawnResult != 0) {
+ status = 2;
+ } else if (subStatus.TermSignal != 0) {
+ status = 1;
+ } else {
+ status = static_cast<int>(subStatus.ExitStatus);
}
if (status != 0) {
@@ -1114,7 +1107,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
int ret = 0;
auto time_start = std::chrono::steady_clock::now();
- cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret);
+ cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret, nullptr,
+ cmSystemTools::OUTPUT_PASSTHROUGH);
auto time_finish = std::chrono::steady_clock::now();
std::chrono::duration<double> time_elapsed = time_finish - time_start;
@@ -1691,11 +1685,8 @@ int cmcmd::HashSumFile(std::vector<std::string> const& args,
std::cerr << "Error: " << filename << " is a directory" << std::endl;
retval++;
} else {
- std::string value
-#ifndef CMAKE_BOOTSTRAP
- = cmSystemTools::ComputeFileHash(filename, algo)
-#endif
- ;
+ cmCryptoHash hasher(algo);
+ std::string value = hasher.HashFile(filename);
if (value.empty()) {
// To mimic "md5sum/shasum" behavior in a shell:
std::cerr << filename << ": No such file or directory" << std::endl;
@@ -1893,21 +1884,6 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
}
}
- // Allocate a process instance.
- cmsysProcess* cp = cmsysProcess_New();
- if (!cp) {
- std::cerr << "Error allocating process instance in link script."
- << std::endl;
- return 1;
- }
-
- // Children should share stdout and stderr with this process.
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
-
- // Run the command lines verbatim.
- cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
-
// Read command lines from the script.
cmsys::ifstream fin(args[2].c_str());
if (!fin) {
@@ -1925,9 +1901,24 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
continue;
}
+ // Allocate a process instance.
+ cmUVProcessChainBuilder builder;
+
+ // Children should share stdout and stderr with this process.
+ builder
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ cm_fileno(stdout))
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+ cm_fileno(stderr));
+
// Setup this command line.
- const char* cmd[2] = { command.c_str(), nullptr };
- cmsysProcess_SetCommand(cp, cmd);
+ std::vector<std::string> args2;
+#ifdef _WIN32
+ cmSystemTools::ParseWindowsCommandLine(command.c_str(), args2);
+#else
+ cmSystemTools::ParseUnixCommandLine(command.c_str(), args2);
+#endif
+ builder.AddCommand(args2);
// Report the command if verbose output is enabled.
if (verbose) {
@@ -1935,35 +1926,29 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
}
// Run the command and wait for it to exit.
- cmsysProcess_Execute(cp);
- cmsysProcess_WaitForExit(cp, nullptr);
+ auto chain = builder.Start();
+ chain.Wait();
// Report failure if any.
- switch (cmsysProcess_GetState(cp)) {
- case cmsysProcess_State_Exited: {
- int value = cmsysProcess_GetExitValue(cp);
- if (value != 0) {
- result = value;
+ auto const& status = chain.GetStatus(0);
+ auto exception = status.GetException();
+ switch (exception.first) {
+ case cmUVProcessChain::ExceptionCode::None:
+ if (status.ExitStatus != 0) {
+ result = static_cast<int>(status.ExitStatus);
}
- } break;
- case cmsysProcess_State_Exception:
- std::cerr << "Error running link command: "
- << cmsysProcess_GetExceptionString(cp) << std::endl;
- result = 1;
break;
- case cmsysProcess_State_Error:
- std::cerr << "Error running link command: "
- << cmsysProcess_GetErrorString(cp) << std::endl;
+ case cmUVProcessChain::ExceptionCode::Spawn:
+ std::cerr << "Error running link command: " << exception.second;
result = 2;
break;
default:
+ std::cerr << "Error running link command: " << exception.second;
+ result = 1;
break;
}
}
- // Free the process instance.
- cmsysProcess_Delete(cp);
-
// Return the final resulting return value.
return result;
}
@@ -2008,7 +1993,7 @@ int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
.AddCommand(command);
auto process = builder.Start();
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
std::cerr << "Failed to start preprocessor.";
return 1;
}
@@ -2016,12 +2001,9 @@ int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
std::cerr << "Failed to wait for preprocessor";
return 1;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
- auto* errorStream = process.ErrorStream();
- if (errorStream) {
- std::cerr << errorStream->rdbuf();
- }
+ if (process.GetStatus(0).ExitStatus != 0) {
+ cmUVPipeIStream errorStream(process.GetLoop(), process.ErrorStream());
+ std::cerr << errorStream.rdbuf();
return 1;
}
@@ -2130,7 +2112,7 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
.AddCommand(resource_compile);
auto process = builder.Start();
result = 0;
- if (!process.Valid()) {
+ if (!process.Valid() || process.GetStatus(0).SpawnResult != 0) {
std::cerr << "Failed to start resource compiler.";
result = 1;
} else {
@@ -2144,12 +2126,9 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
if (result != 0) {
return result;
}
- auto status = process.GetStatus();
- if (!status[0] || status[0]->ExitStatus != 0) {
- auto* errorStream = process.ErrorStream();
- if (errorStream) {
- std::cerr << errorStream->rdbuf();
- }
+ if (process.GetStatus(0).ExitStatus != 0) {
+ cmUVPipeIStream errorStream(process.GetLoop(), process.ErrorStream());
+ std::cerr << errorStream.rdbuf();
return 1;
}
@@ -2546,14 +2525,17 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
std::vector<std::string> mtCommand;
mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
mtCommand.emplace_back("/nologo");
- mtCommand.emplace_back("/manifest");
// add the linker generated manifest if the file exists.
if (this->LinkGeneratesManifest &&
cmSystemTools::FileExists(this->LinkerManifestFile)) {
+ mtCommand.emplace_back("/manifest");
mtCommand.push_back(this->LinkerManifestFile);
}
- cm::append(mtCommand, this->UserManifests);
+ for (auto const& m : this->UserManifests) {
+ mtCommand.emplace_back("/manifest");
+ mtCommand.push_back(m);
+ }
mtCommand.push_back(out);
if (notify) {
// Add an undocumented option that enables a special return
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 2b8eedd..2b7f2cc 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -634,7 +634,7 @@ set(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
CommandLineArguments FStream SystemInformation ConsoleBuf Status
)
-foreach(cpp ${cppclasses})
+foreach(cpp IN LISTS cppclasses)
if(KWSYS_USE_${cpp})
# Use the corresponding class.
set(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
@@ -647,7 +647,7 @@ foreach(cpp ${cppclasses})
endforeach()
# Add selected C components.
-foreach(c
+foreach(c IN ITEMS
Process Base64 Encoding MD5 Terminal System String
)
if(KWSYS_USE_${c})
@@ -679,7 +679,7 @@ if(KWSYS_USE_Process)
endif()
# Add selected C sources.
-foreach(c Base64 Encoding MD5 Terminal System String)
+foreach(c IN ITEMS Base64 Encoding MD5 Terminal System String)
if(KWSYS_USE_${c})
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
list(APPEND KWSYS_C_SRCS ${c}C.c)
@@ -690,7 +690,7 @@ foreach(c Base64 Encoding MD5 Terminal System String)
endforeach()
# Configure headers of C++ classes and construct the list of sources.
-foreach(c ${KWSYS_CLASSES})
+foreach(c IN LISTS KWSYS_CLASSES)
# Add this source to the list of source files for the library.
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
list(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
@@ -712,7 +712,7 @@ foreach(c ${KWSYS_CLASSES})
endforeach()
# Configure C headers.
-foreach(h ${KWSYS_H_FILES})
+foreach(h IN LISTS KWSYS_H_FILES)
# Configure the header into the given directory.
configure_file(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
@ONLY IMMEDIATE)
@@ -727,7 +727,7 @@ foreach(h ${KWSYS_H_FILES})
endforeach()
# Configure other C++ headers.
-foreach(h ${KWSYS_HXX_FILES})
+foreach(h IN LISTS KWSYS_HXX_FILES)
# Configure the header into the given directory.
configure_file(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
@ONLY IMMEDIATE)
@@ -956,9 +956,11 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
add_executable(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
set_property(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
target_link_libraries(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
- foreach(testfile ${KWSYS_C_TESTS})
+ foreach(testfile IN LISTS KWSYS_C_TESTS)
get_filename_component(test "${testfile}" NAME_WE)
- add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
+ add_test(NAME kwsys.${test}
+ COMMAND ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}}
+ )
set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
endforeach()
@@ -1080,9 +1082,11 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-p
some junk at the end
)
- foreach(testfile ${KWSYS_CXX_TESTS})
+ foreach(testfile IN LISTS KWSYS_CXX_TESTS)
get_filename_component(test "${testfile}" NAME_WE)
- add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
+ add_test(NAME kwsys.${test}
+ COMMAND ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}}
+ )
set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
endforeach()
@@ -1091,10 +1095,12 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
set_property(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
target_link_libraries(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
#set(KWSYS_TEST_PROCESS_7 7) # uncomment to run timing-sensitive test locally
- foreach(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
- add_test(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
+ foreach(n IN ITEMS 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
+ add_test(NAME kwsys.testProcess-${n}
+ COMMAND ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n}
+ )
set_property(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- set_tests_properties(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
+ set_property(TEST kwsys.testProcess-${n} PROPERTY TIMEOUT 120)
endforeach()
set(testProcess_COMPILE_FLAGS "")
@@ -1121,9 +1127,9 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
# Configure some test properties.
if(KWSYS_STANDALONE)
# We expect test to fail
- set_tests_properties(kwsys.testFail PROPERTIES WILL_FAIL ON)
+ set_property(TEST kwsys.testFail PROPERTY WILL_FAIL ON)
get_test_property(kwsys.testFail WILL_FAIL wfv)
- set_tests_properties(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
+ set_property(TEST kwsys.testFail PROPERTY MEASUREMENT "Some Key=Some Value")
message(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
endif()
@@ -1133,7 +1139,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
# Suppress known consistent failures on buggy systems.
if(KWSYS_TEST_BOGUS_FAILURES)
- set_tests_properties(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
+ set_property(TEST ${KWSYS_TEST_BOGUS_FAILURES} PROPERTY WILL_FAIL ON)
endif()
endif()
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 7f8485e..369ff9a 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -3443,7 +3443,7 @@ bool SystemInformationImplementation::RetrieveInformationFromCpuInfoFile()
FILE* fd = fopen("/proc/cpuinfo", "r");
if (!fd) {
- std::cout << "Problem opening /proc/cpuinfo" << std::endl;
+ std::cerr << "Problem opening /proc/cpuinfo\n";
return false;
}
@@ -3454,7 +3454,7 @@ bool SystemInformationImplementation::RetrieveInformationFromCpuInfoFile()
}
fclose(fd);
if (fileSize < 2) {
- std::cout << "No data in /proc/cpuinfo" << std::endl;
+ std::cerr << "No data in /proc/cpuinfo\n";
return false;
}
buffer.resize(fileSize - 2);
@@ -4162,7 +4162,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
struct utsname unameInfo;
int errorFlag = uname(&unameInfo);
if (errorFlag != 0) {
- std::cout << "Problem calling uname(): " << strerror(errno) << std::endl;
+ std::cerr << "Problem calling uname(): " << strerror(errno) << "\n";
return false;
}
@@ -4182,7 +4182,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
FILE* fd = fopen("/proc/meminfo", "r");
if (!fd) {
- std::cout << "Problem opening /proc/meminfo" << std::endl;
+ std::cerr << "Problem opening /proc/meminfo\n";
return false;
}
@@ -4221,7 +4221,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
this->TotalVirtualMemory = value[mSwapTotal] / 1024;
this->AvailableVirtualMemory = value[mSwapFree] / 1024;
} else {
- std::cout << "Problem parsing /proc/meminfo" << std::endl;
+ std::cerr << "Problem parsing /proc/meminfo\n";
fclose(fd);
return false;
}
@@ -4248,7 +4248,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
this->AvailablePhysicalMemory =
(ap + buffersMem + cachedMem) >> 10 >> 10;
} else {
- std::cout << "Problem parsing /proc/meminfo" << std::endl;
+ std::cerr << "Problem parsing /proc/meminfo\n";
fclose(fd);
return false;
}
@@ -4472,8 +4472,8 @@ void SystemInformationImplementation::CPUCountWindows()
typedef BOOL(WINAPI * GetLogicalProcessorInformationType)(
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
static GetLogicalProcessorInformationType pGetLogicalProcessorInformation =
- (GetLogicalProcessorInformationType)GetProcAddress(
- GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation");
+ reinterpret_cast<GetLogicalProcessorInformationType>(GetProcAddress(
+ GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation"));
if (!pGetLogicalProcessorInformation) {
// Fallback to approximate implementation on ancient Windows versions.
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 5c14de2..225a1e7 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -31,6 +31,7 @@ set(CMakeLib_TESTS
testCMExtAlgorithm.cxx
testCMExtEnumSet.cxx
testList.cxx
+ testCMakePath.cxx
)
if(CMake_ENABLE_DEBUGGER)
list(APPEND CMakeLib_TESTS
@@ -63,10 +64,18 @@ if(WIN32)
endif()
configure_file(testXMLParser.h.in testXMLParser.h @ONLY)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testUVProcessChainInput.txt" "HELLO WORLD!")
create_test_sourcelist(CMakeLib_TEST_SRCS CMakeLibTests.cxx ${CMakeLib_TESTS})
add_executable(CMakeLibTests ${CMakeLib_TEST_SRCS})
-target_link_libraries(CMakeLibTests CMakeLib CTestLib)
+target_link_libraries(CMakeLibTests PRIVATE CTestLib CMakeLib)
+if(CMake_BUILD_PCH)
+ target_precompile_headers(CMakeLibTests PRIVATE "<iostream>" "<cm3p/uv.h>")
+ target_compile_definitions(CMakeLibTests PRIVATE "NOMINMAX")
+endif()
+if(WIN32)
+ target_compile_definitions(CMakeLibTests PRIVATE WIN32_LEAN_AND_MEAN)
+endif()
set_property(TARGET CMakeLibTests PROPERTY C_CLANG_TIDY "")
set_property(TARGET CMakeLibTests PROPERTY CXX_CLANG_TIDY "")
@@ -102,4 +111,7 @@ if(CMake_ENABLE_DEBUGGER)
add_test(NAME CMakeLib.testDebuggerNamedPipe-${case} COMMAND testDebuggerNamedPipe ${testDebuggerNamedPipe_${case}_ARGS})
set_property(TEST CMakeLib.testDebuggerNamedPipe-${case} PROPERTY TIMEOUT 300)
endforeach()
+ if(WIN32)
+ target_compile_definitions(testDebuggerNamedPipe PRIVATE WIN32_LEAN_AND_MEAN)
+ endif()
endif()
diff --git a/Tests/CMakeLib/testCMExtAlgorithm.cxx b/Tests/CMakeLib/testCMExtAlgorithm.cxx
index c909f24..53b0302 100644
--- a/Tests/CMakeLib/testCMExtAlgorithm.cxx
+++ b/Tests/CMakeLib/testCMExtAlgorithm.cxx
@@ -1,6 +1,5 @@
#include <iostream>
#include <memory>
-#include <type_traits>
#include <utility>
#include <vector>
diff --git a/Tests/CMakeLib/testCMakePath.cxx b/Tests/CMakeLib/testCMakePath.cxx
new file mode 100644
index 0000000..aa17e50
--- /dev/null
+++ b/Tests/CMakeLib/testCMakePath.cxx
@@ -0,0 +1,441 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <iostream>
+#include <string>
+#include <utility>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmCMakePath.h"
+
+namespace {
+
+void checkResult(bool success)
+{
+ if (!success) {
+ std::cout << " => failed";
+ }
+ std::cout << std::endl;
+}
+
+bool testConstructors()
+{
+ std::cout << "testConstructors()";
+
+ bool result = true;
+
+ {
+ cmCMakePath path;
+ if (!path.String().empty() || path != cmCMakePath{}) {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path{ "aa/bb" };
+ if (path.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string s{ "aa/bb" };
+ cmCMakePath path{ s };
+ if (path.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path{ "aa/bb"_s };
+ if (path.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2("aa/bb"_s);
+
+ if (path1 != path2) {
+ result = false;
+ }
+ if (path1.String() != "aa/bb") {
+ result = false;
+ }
+ if (path1.String() != path2.String()) {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ path1 };
+
+ if (path1 != path2) {
+ result = false;
+ }
+ if (path1.String() != "aa/bb") {
+ result = false;
+ }
+ if (path1.String() != path2.String()) {
+ result = false;
+ }
+ }
+
+ checkResult(result);
+
+ return result;
+}
+
+bool testAssign()
+{
+ std::cout << "testAssign()";
+
+ bool result = true;
+
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 = path1;
+ if (path1 != path2) {
+ result = false;
+ }
+ if (path1.String() != "aa/bb") {
+ result = false;
+ }
+ if (path1.String() != path2.String()) {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 = std::move(path1);
+ if (path2.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 = path1;
+ if (path2.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 = std::move(path1);
+ if (path2.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cm::string_view path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 = path1;
+ if (path2.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ char path1[] = "aa/bb";
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 = path1;
+ if (path2.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Assign(path1);
+ if (path2.String() != path1) {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Assign(std::move(path1));
+ if (path2.String() != "aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cm::string_view path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Assign(path1);
+ if (path2.String() != path1) {
+ result = false;
+ }
+ }
+ {
+ char path1[] = "aa/bb";
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Assign(path1);
+ if (path2.String() != path1) {
+ result = false;
+ }
+ }
+
+ checkResult(result);
+
+ return result;
+}
+
+bool testConcat()
+{
+ std::cout << "testConcat()";
+
+ bool result = true;
+
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 += path1;
+
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 += std::move(path1);
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 += path1;
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 += std::move(path1);
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ cm::string_view path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 += path1;
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ char path1[] = "aa/bb";
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 += path1;
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Concat(path1);
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Concat(path1);
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Concat(std::move(path1));
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ cm::string_view path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Concat(path1);
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+ {
+ char path1[] = "aa/bb";
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Concat(path1);
+ if (path2.String() != "cc/ddaa/bb") {
+ result = false;
+ }
+ }
+
+ checkResult(result);
+
+ return result;
+}
+
+bool testAppend()
+{
+ std::cout << "testAppend()";
+
+ bool result = true;
+
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 /= path1;
+
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 /= std::move(path1);
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 /= path1;
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 /= std::move(path1);
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cm::string_view path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 /= path1;
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ char path1[] = "aa/bb";
+ cmCMakePath path2{ "cc/dd" };
+
+ path2 /= path1;
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cmCMakePath path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Append(path1);
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Append(path1);
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ std::string path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Append(std::move(path1));
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ cm::string_view path1{ "aa/bb" };
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Append(path1);
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+ {
+ char path1[] = "aa/bb";
+ cmCMakePath path2{ "cc/dd" };
+
+ path2.Append(path1);
+ if (path2.String() != "cc/dd/aa/bb") {
+ result = false;
+ }
+ }
+
+ checkResult(result);
+
+ return result;
+}
+}
+
+int testCMakePath(int /*unused*/, char* /*unused*/[])
+{
+ int result = 0;
+
+ if (!testConstructors()) {
+ result = 1;
+ }
+ if (!testAssign()) {
+ result = 1;
+ }
+ if (!testConcat()) {
+ result = 1;
+ }
+ if (!testAppend()) {
+ result = 1;
+ }
+
+ return result;
+}
diff --git a/Tests/CMakeLib/testDebuggerAdapterPipe.cxx b/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
index 643661d..c0f2e9b 100644
--- a/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
+++ b/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
@@ -19,13 +19,15 @@
#include <cm3p/cppdap/types.h>
#include "cmDebuggerAdapter.h"
-#include "cmDebuggerPipeConnection.h"
#include "cmDebuggerProtocol.h"
#include "cmVersionConfig.h"
#ifdef _WIN32
# include "cmCryptoHash.h"
+# include "cmDebuggerWindowsPipeConnection.h"
# include "cmSystemTools.h"
+#else
+# include "cmDebuggerPosixPipeConnection.h"
#endif
#include "testCommon.h"
@@ -128,7 +130,7 @@ bool testProtocolWithPipes()
auto client2Debugger =
std::make_shared<cmDebugger::cmDebuggerPipeClient>(namedPipe);
- client2Debugger->Start();
+
client2Debugger->WaitForConnection();
client->bind(client2Debugger, client2Debugger);
diff --git a/Tests/CMakeLib/testDebuggerNamedPipe.cxx b/Tests/CMakeLib/testDebuggerNamedPipe.cxx
index ec91706..1ae3f64 100644
--- a/Tests/CMakeLib/testDebuggerNamedPipe.cxx
+++ b/Tests/CMakeLib/testDebuggerNamedPipe.cxx
@@ -16,7 +16,12 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmDebuggerPipeConnection.h"
+#ifdef _WIN32
+# include "cmDebuggerWindowsPipeConnection.h"
+#else
+# include "cmDebuggerPosixPipeConnection.h"
+#endif
+
#include "cmSystemTools.h"
#ifdef _WIN32
@@ -104,7 +109,7 @@ int runTest(int argc, char* argv[])
attempt++;
try {
client = std::make_shared<cmDebugger::cmDebuggerPipeClient>(namedPipe);
- client->Start();
+
client->WaitForConnection();
std::cout << "cmDebuggerPipeClient connected.\n";
break;
diff --git a/Tests/CMakeLib/testEncoding.cxx b/Tests/CMakeLib/testEncoding.cxx
index 4936898..460d845 100644
--- a/Tests/CMakeLib/testEncoding.cxx
+++ b/Tests/CMakeLib/testEncoding.cxx
@@ -1,4 +1,5 @@
#include <iostream>
+#include <iterator>
#include <string>
#include "cmsys/FStream.hxx"
diff --git a/Tests/CMakeLib/testGccDepfileReader.cxx b/Tests/CMakeLib/testGccDepfileReader.cxx
index d46e8f3..fb19c14 100644
--- a/Tests/CMakeLib/testGccDepfileReader.cxx
+++ b/Tests/CMakeLib/testGccDepfileReader.cxx
@@ -1,6 +1,5 @@
#include <cstddef> // IWYU pragma: keep
#include <iostream>
-#include <memory>
#include <string>
#include <utility>
#include <vector>
diff --git a/Tests/CMakeLib/testList.cxx b/Tests/CMakeLib/testList.cxx
index 6d6c218..8822806 100644
--- a/Tests/CMakeLib/testList.cxx
+++ b/Tests/CMakeLib/testList.cxx
@@ -4,7 +4,6 @@
#include <iostream>
#include <stdexcept>
#include <string>
-#include <type_traits>
#include <utility>
#include <vector>
diff --git a/Tests/CMakeLib/testOptional.cxx b/Tests/CMakeLib/testOptional.cxx
index 785f031..933ab70 100644
--- a/Tests/CMakeLib/testOptional.cxx
+++ b/Tests/CMakeLib/testOptional.cxx
@@ -1,5 +1,4 @@
#include <iostream>
-#include <type_traits>
#include <vector>
#include <cm/optional>
diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx
index af34a2f..3509266 100644
--- a/Tests/CMakeLib/testString.cxx
+++ b/Tests/CMakeLib/testString.cxx
@@ -1,14 +1,12 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include <cstddef> // IWYU pragma: keep
#include <cstring>
#include <iostream>
#include <iterator>
#include <sstream>
#include <stdexcept>
#include <string>
-#include <type_traits>
#include <utility>
#include <cm/string_view>
diff --git a/Tests/CMakeLib/testUTF8.cxx b/Tests/CMakeLib/testUTF8.cxx
index fc0b539..180d29d 100644
--- a/Tests/CMakeLib/testUTF8.cxx
+++ b/Tests/CMakeLib/testUTF8.cxx
@@ -1,67 +1,57 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include <cm/string_view>
+
#include <stdio.h>
#include <cm_utf8.h>
-typedef char test_utf8_char[5];
-
-static void test_utf8_char_print(test_utf8_char const c)
-{
- unsigned char const* d = reinterpret_cast<unsigned char const*>(c);
-#ifndef __clang_analyzer__ // somehow thinks arguments are not initialized
- printf("[0x%02X,0x%02X,0x%02X,0x%02X]", static_cast<int>(d[0]),
- static_cast<int>(d[1]), static_cast<int>(d[2]),
- static_cast<int>(d[3]));
-#endif
-}
+using test_utf8_char = const cm::string_view;
-static void byte_array_print(char const* s)
+static void byte_array_print(test_utf8_char s)
{
- unsigned char const* d = reinterpret_cast<unsigned char const*>(s);
bool started = false;
printf("[");
- for (; *d; ++d) {
+ for (char c : s) {
if (started) {
printf(",");
}
started = true;
- printf("0x%02X", static_cast<int>(*d));
+ printf("0x%02X", static_cast<unsigned char>(c));
}
printf("]");
}
struct test_utf8_entry
{
- int n;
test_utf8_char str;
unsigned int chr;
};
static test_utf8_entry const good_entry[] = {
- { 1, "\x20\x00\x00\x00", 0x0020 }, /* Space. */
- { 2, "\xC2\xA9\x00\x00", 0x00A9 }, /* Copyright. */
- { 3, "\xE2\x80\x98\x00", 0x2018 }, /* Open-single-quote. */
- { 3, "\xE2\x80\x99\x00", 0x2019 }, /* Close-single-quote. */
- { 4, "\xF0\xA3\x8E\xB4", 0x233B4 }, /* Example from RFC 3629. */
- { 3, "\xED\x80\x80\x00", 0xD000 }, /* Valid 0xED prefixed codepoint. */
- { 4, "\xF4\x8F\xBF\xBF", 0x10FFFF }, /* Highest valid RFC codepoint. */
- { 0, { 0, 0, 0, 0, 0 }, 0 }
+ { "\x20", 0x0020 }, /* Space. */
+ { "\xC2\xA9", 0x00A9 }, /* Copyright. */
+ { "\xE2\x80\x98", 0x2018 }, /* Open-single-quote. */
+ { "\xE2\x80\x99", 0x2019 }, /* Close-single-quote. */
+ { "\xF0\xA3\x8E\xB4", 0x233B4 }, /* Example from RFC 3629. */
+ { "\xED\x80\x80", 0xD000 }, /* Valid 0xED prefixed codepoint. */
+ { "\xF4\x8F\xBF\xBF", 0x10FFFF }, /* Highest valid RFC codepoint. */
+ { {}, 0 }
};
static test_utf8_char const bad_chars[] = {
- "\x80\x00\x00\x00", /* Leading continuation byte. */
- "\xC0\x80\x00\x00", /* Overlong encoding. */
- "\xC1\x80\x00\x00", /* Overlong encoding. */
- "\xC2\x00\x00\x00", /* Missing continuation byte. */
- "\xE0\x00\x00\x00", /* Missing continuation bytes. */
- "\xE0\x80\x80\x00", /* Overlong encoding. */
+ "\x80", /* Leading continuation byte. */
+ "\xC0\x80", /* Overlong encoding. */
+ "\xC1\x80", /* Overlong encoding. */
+ "\xC2", /* Missing continuation byte. */
+ "\xE0", /* Missing continuation bytes. */
+ "\xE0\x80\x80", /* Overlong encoding. */
"\xF0\x80\x80\x80", /* Overlong encoding. */
- "\xED\xA0\x80\x00", /* UTF-16 surrogate half. */
- "\xED\xBF\xBF\x00", /* UTF-16 surrogate half. */
+ "\xED\xA0\x80", /* UTF-16 surrogate half. */
+ "\xED\xBF\xBF", /* UTF-16 surrogate half. */
"\xF4\x90\x80\x80", /* Lowest out-of-range codepoint. */
"\xF5\x80\x80\x80", /* Prefix forces out-of-range codepoints. */
- { 0, 0, 0, 0, 0 }
+ {}
};
static char const* good_strings[] = { "", "ASCII", "\xC2\xA9 Kitware", 0 };
@@ -71,49 +61,50 @@ static char const* bad_strings[] = {
0
};
-static void report_good(bool passed, test_utf8_char const c)
+static void report_good(bool passed, test_utf8_char c)
{
printf("%s: decoding good ", passed ? "pass" : "FAIL");
- test_utf8_char_print(c);
- printf(" (%s) ", c);
+ byte_array_print(c);
+ printf(" (%s) ", c.data());
}
-static void report_bad(bool passed, test_utf8_char const c)
+static void report_bad(bool passed, test_utf8_char c)
{
printf("%s: decoding bad ", passed ? "pass" : "FAIL");
- test_utf8_char_print(c);
+ byte_array_print(c);
printf(" ");
}
-static bool decode_good(test_utf8_entry const entry)
+static bool decode_good(test_utf8_entry const& entry)
{
+ const auto& s = entry.str;
unsigned int uc;
if (const char* e =
- cm_utf8_decode_character(entry.str, entry.str + 4, &uc)) {
- int used = static_cast<int>(e - entry.str);
+ cm_utf8_decode_character(s.data(), s.data() + s.size(), &uc)) {
+ int used = static_cast<int>(e - s.data());
if (uc != entry.chr) {
- report_good(false, entry.str);
+ report_good(false, s);
printf("expected 0x%04X, got 0x%04X\n", entry.chr, uc);
return false;
}
- if (used != entry.n) {
- report_good(false, entry.str);
- printf("had %d bytes, used %d\n", entry.n, used);
+ if (used != int(s.size())) {
+ report_good(false, s);
+ printf("had %d bytes, used %d\n", int(s.size()), used);
return false;
}
- report_good(true, entry.str);
+ report_good(true, s);
printf("got 0x%04X\n", uc);
return true;
}
- report_good(false, entry.str);
+ report_good(false, s);
printf("failed\n");
return false;
}
-static bool decode_bad(test_utf8_char const s)
+static bool decode_bad(test_utf8_char s)
{
unsigned int uc = 0xFFFFu;
- const char* e = cm_utf8_decode_character(s, s + 4, &uc);
+ const char* e = cm_utf8_decode_character(s.data(), s.data() + s.size(), &uc);
if (e) {
report_bad(false, s);
printf("expected failure, got 0x%04X\n", uc);
@@ -124,23 +115,23 @@ static bool decode_bad(test_utf8_char const s)
return true;
}
-static void report_valid(bool passed, char const* s)
+static void report_valid(bool passed, test_utf8_char s)
{
printf("%s: validity good ", passed ? "pass" : "FAIL");
byte_array_print(s);
- printf(" (%s) ", s);
+ printf(" (%s) ", s.data());
}
-static void report_invalid(bool passed, char const* s)
+static void report_invalid(bool passed, test_utf8_char s)
{
printf("%s: validity bad ", passed ? "pass" : "FAIL");
byte_array_print(s);
printf(" ");
}
-static bool is_valid(const char* s)
+static bool is_valid(test_utf8_char s)
{
- bool valid = cm_utf8_is_valid(s) != 0;
+ bool valid = cm_utf8_is_valid(s.data()) != 0;
if (!valid) {
report_valid(false, s);
printf("expected valid, reported as invalid\n");
@@ -151,9 +142,9 @@ static bool is_valid(const char* s)
return true;
}
-static bool is_invalid(const char* s)
+static bool is_invalid(test_utf8_char s)
{
- bool valid = cm_utf8_is_valid(s) != 0;
+ bool valid = cm_utf8_is_valid(s.data()) != 0;
if (valid) {
report_invalid(false, s);
printf("expected invalid, reported as valid\n");
@@ -167,7 +158,7 @@ static bool is_invalid(const char* s)
int testUTF8(int /*unused*/, char* /*unused*/[])
{
int result = 0;
- for (test_utf8_entry const* e = good_entry; e->n; ++e) {
+ for (test_utf8_entry const* e = good_entry; !e->str.empty(); ++e) {
if (!decode_good(*e)) {
result = 1;
}
@@ -175,7 +166,7 @@ int testUTF8(int /*unused*/, char* /*unused*/[])
result = 1;
}
}
- for (test_utf8_char const* c = bad_chars; (*c)[0]; ++c) {
+ for (test_utf8_char* c = bad_chars; !(*c).empty(); ++c) {
if (!decode_bad(*c)) {
result = 1;
}
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx
index 7027689..aab084b 100644
--- a/Tests/CMakeLib/testUVProcessChain.cxx
+++ b/Tests/CMakeLib/testUVProcessChain.cxx
@@ -1,10 +1,10 @@
#include <algorithm>
#include <csignal>
+#include <cstdio>
#include <functional>
#include <iostream>
#include <sstream>
#include <string>
-#include <type_traits>
#include <utility>
#include <vector>
@@ -12,15 +12,17 @@
#include <cm3p/uv.h>
+#include "cm_fileno.hxx"
+
#include "cmGetPipes.h"
#include "cmStringAlgorithms.h"
#include "cmUVHandlePtr.h"
#include "cmUVProcessChain.h"
+#include "cmUVStream.h"
#include "cmUVStreambuf.h"
struct ExpectedStatus
{
- bool Finished;
bool MatchExitStatus;
bool MatchTermSignal;
cmUVProcessChain::Status Status;
@@ -28,38 +30,6 @@ struct ExpectedStatus
std::string ExceptionString;
};
-static const std::vector<ExpectedStatus> status1 = {
- { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
- { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
- { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
-};
-
-static const std::vector<ExpectedStatus> status2 = {
- { true, true, true, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
- { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
- { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
-};
-
-static const std::vector<ExpectedStatus> status3 = {
- { true, true, true, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
- { true, true, true, { 1, 0 }, cmUVProcessChain::ExceptionCode::None, "" },
-#ifdef _WIN32
- { true,
- true,
- true,
- { STATUS_ACCESS_VIOLATION, 0 },
- cmUVProcessChain::ExceptionCode::Fault,
- "Access violation" },
-#else
- { true,
- false,
- true,
- { 0, SIGABRT },
- cmUVProcessChain::ExceptionCode::Other,
- "Subprocess aborted" },
-#endif
-};
-
static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code)
{
switch (code) {
@@ -73,6 +43,8 @@ static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code)
return "Interrupt";
case cmUVProcessChain::ExceptionCode::Numerical:
return "Numerical";
+ case cmUVProcessChain::ExceptionCode::Spawn:
+ return "Spawn";
case cmUVProcessChain::ExceptionCode::Other:
return "Other";
default:
@@ -83,9 +55,10 @@ static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code)
bool operator==(const cmUVProcessChain::Status* actual,
const ExpectedStatus& expected)
{
- if (!expected.Finished) {
- return !actual;
- } else if (!actual) {
+ if (expected.Status.SpawnResult != actual->SpawnResult) {
+ return false;
+ }
+ if (expected.Status.Finished != actual->Finished) {
return false;
}
if (expected.MatchExitStatus &&
@@ -96,7 +69,7 @@ bool operator==(const cmUVProcessChain::Status* actual,
expected.Status.TermSignal != actual->TermSignal) {
return false;
}
- if (expected.Finished &&
+ if (expected.Status.Finished &&
std::make_pair(expected.ExceptionCode, expected.ExceptionString) !=
actual->GetException()) {
return false;
@@ -150,39 +123,96 @@ static void printResults(
{
std::cout << "Expected: " << std::endl;
for (auto const& e : expected) {
- if (e.Finished) {
- std::cout << " ExitStatus: "
- << printExpected(e.MatchExitStatus, e.Status.ExitStatus)
- << ", TermSignal: "
- << printExpected(e.MatchTermSignal, e.Status.TermSignal)
- << ", ExceptionCode: "
- << printExpected(e.Finished,
- ExceptionCodeToString(e.ExceptionCode))
- << ", ExceptionString: \""
- << printExpected(e.Finished, e.ExceptionString) << '"'
- << std::endl;
- } else {
- std::cout << " null" << std::endl;
- }
+ std::cout << " SpawnResult: " << e.Status.SpawnResult
+ << ", Finished: " << e.Status.Finished << ", ExitStatus: "
+ << printExpected(e.MatchExitStatus, e.Status.ExitStatus)
+ << ", TermSignal: "
+ << printExpected(e.MatchTermSignal, e.Status.TermSignal)
+ << ", ExceptionCode: "
+ << printExpected(e.Status.Finished,
+ ExceptionCodeToString(e.ExceptionCode))
+ << ", ExceptionString: \""
+ << printExpected(e.Status.Finished, e.ExceptionString) << '"'
+ << std::endl;
}
std::cout << "Actual:" << std::endl;
for (auto const& a : actual) {
- if (a) {
- auto exception = a->GetException();
- std::cout << " ExitStatus: " << a->ExitStatus
- << ", TermSignal: " << a->TermSignal << ", ExceptionCode: "
- << ExceptionCodeToString(exception.first)
- << ", ExceptionString: \"" << exception.second << '"'
- << std::endl;
- } else {
- std::cout << " null" << std::endl;
- }
+ auto exception = a->GetException();
+ std::cout << " SpawnResult: " << a->SpawnResult
+ << ", Finished: " << a->Finished
+ << ", ExitStatus: " << a->ExitStatus
+ << ", TermSignal: " << a->TermSignal
+ << ", ExceptionCode: " << ExceptionCodeToString(exception.first)
+ << ", ExceptionString: \"" << exception.second << '"'
+ << std::endl;
}
}
static bool checkExecution(cmUVProcessChainBuilder& builder,
std::unique_ptr<cmUVProcessChain>& chain)
{
+ static const std::vector<ExpectedStatus> status1 = {
+ { false,
+ false,
+ { 0, false, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ { false,
+ false,
+ { 0, false, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ { false,
+ false,
+ { 0, false, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ };
+
+ static const std::vector<ExpectedStatus> status2 = {
+ { true,
+ true,
+ { 0, true, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ { false,
+ false,
+ { 0, false, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ { false,
+ false,
+ { 0, false, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ };
+
+ static const std::vector<ExpectedStatus> status3 = {
+ { true,
+ true,
+ { 0, true, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ { true,
+ true,
+ { 0, true, 1, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+#ifdef _WIN32
+ { true,
+ true,
+ { 0, true, STATUS_ACCESS_VIOLATION, 0 },
+ cmUVProcessChain::ExceptionCode::Fault,
+ "Access violation" },
+#else
+ { false,
+ true,
+ { 0, true, 0, SIGABRT },
+ cmUVProcessChain::ExceptionCode::Other,
+ "Subprocess aborted" },
+#endif
+ };
+
std::vector<const cmUVProcessChain::Status*> status;
chain = cm::make_unique<cmUVProcessChain>(builder.Start());
@@ -201,7 +231,7 @@ static bool checkExecution(cmUVProcessChainBuilder& builder,
return false;
}
- if (chain->Wait(6000)) {
+ if (chain->Wait(9000)) {
std::cout << "Wait() returned true, should be false" << std::endl;
return false;
}
@@ -273,16 +303,19 @@ bool testUVProcessChainBuiltin(const char* helperCommand)
return false;
}
- if (!chain->OutputStream()) {
- std::cout << "OutputStream() was null, expecting not null" << std::endl;
+ if (chain->OutputStream() < 0) {
+ std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
return false;
}
- if (!chain->ErrorStream()) {
- std::cout << "ErrorStream() was null, expecting not null" << std::endl;
+ if (chain->ErrorStream() < 0) {
+ std::cout << "ErrorStream() was invalid, expecting valid" << std::endl;
return false;
}
- if (!checkOutput(*chain->OutputStream(), *chain->ErrorStream())) {
+ cmUVPipeIStream output(chain->GetLoop(), chain->OutputStream());
+ cmUVPipeIStream error(chain->GetLoop(), chain->ErrorStream());
+
+ if (!checkOutput(output, error)) {
return false;
}
@@ -302,12 +335,12 @@ bool testUVProcessChainBuiltinMerged(const char* helperCommand)
return false;
}
- if (!chain->OutputStream()) {
- std::cout << "OutputStream() was null, expecting not null" << std::endl;
+ if (chain->OutputStream() < 0) {
+ std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
return false;
}
- if (!chain->ErrorStream()) {
- std::cout << "ErrorStream() was null, expecting not null" << std::endl;
+ if (chain->ErrorStream() < 0) {
+ std::cout << "ErrorStream() was invalid, expecting valid" << std::endl;
return false;
}
if (chain->OutputStream() != chain->ErrorStream()) {
@@ -316,7 +349,9 @@ bool testUVProcessChainBuiltinMerged(const char* helperCommand)
return false;
}
- std::string merged = getInput(*chain->OutputStream());
+ cmUVPipeIStream mergedStream(chain->GetLoop(), chain->OutputStream());
+
+ std::string merged = getInput(mergedStream);
auto qemuErrorPos = merged.find("qemu:");
if (qemuErrorPos != std::string::npos) {
merged.resize(qemuErrorPos);
@@ -370,12 +405,12 @@ bool testUVProcessChainExternal(const char* helperCommand)
return false;
}
- if (chain->OutputStream()) {
- std::cout << "OutputStream() was not null, expecting null" << std::endl;
+ if (chain->OutputStream() >= 0) {
+ std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
return false;
}
- if (chain->ErrorStream()) {
- std::cout << "ErrorStream() was not null, expecting null" << std::endl;
+ if (chain->ErrorStream() >= 0) {
+ std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
return false;
}
@@ -418,12 +453,12 @@ bool testUVProcessChainNone(const char* helperCommand)
return false;
}
- if (chain->OutputStream()) {
- std::cout << "OutputStream() was not null, expecting null" << std::endl;
+ if (chain->OutputStream() >= 0) {
+ std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
return false;
}
- if (chain->ErrorStream()) {
- std::cout << "ErrorStream() was not null, expecting null" << std::endl;
+ if (chain->ErrorStream() >= 0) {
+ std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
return false;
}
@@ -445,7 +480,8 @@ bool testUVProcessChainCwdUnchanged(const char* helperCommand)
return false;
}
- auto cwd = getInput(*chain.OutputStream());
+ cmUVPipeIStream output(chain.GetLoop(), chain.OutputStream());
+ auto cwd = getInput(output);
if (!cmHasLiteralSuffix(cwd, "/Tests/CMakeLib")) {
std::cout << "Working directory was \"" << cwd
<< "\", expected to end in \"/Tests/CMakeLib\"" << std::endl;
@@ -471,7 +507,8 @@ bool testUVProcessChainCwdChanged(const char* helperCommand)
return false;
}
- auto cwd = getInput(*chain.OutputStream());
+ cmUVPipeIStream output(chain.GetLoop(), chain.OutputStream());
+ auto cwd = getInput(output);
if (!cmHasLiteralSuffix(cwd, "/Tests")) {
std::cout << "Working directory was \"" << cwd
<< "\", expected to end in \"/Tests\"" << std::endl;
@@ -481,6 +518,156 @@ bool testUVProcessChainCwdChanged(const char* helperCommand)
return true;
}
+bool testUVProcessChainSpawnFail(const char* helperCommand)
+{
+ static const std::vector<ExpectedStatus> status1 = {
+ { false,
+ false,
+ { 0, false, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+ { false,
+ false,
+ { UV_ENOENT, true, 0, 0 },
+ cmUVProcessChain::ExceptionCode::Spawn,
+ uv_strerror(UV_ENOENT) },
+#ifdef _WIN32
+ { true,
+ true,
+ { 0, true, STATUS_ACCESS_VIOLATION, 0 },
+ cmUVProcessChain::ExceptionCode::Fault,
+ "Access violation" },
+#else
+ { false,
+ true,
+ { 0, true, 0, SIGABRT },
+ cmUVProcessChain::ExceptionCode::Other,
+ "Subprocess aborted" },
+#endif
+ };
+
+ static const std::vector<ExpectedStatus> status2 = {
+#ifdef _WIN32
+ { true,
+ true,
+ { 0, true, 0, 0 },
+ cmUVProcessChain::ExceptionCode::None,
+ "" },
+#else
+ { false,
+ true,
+ { 0, true, 0, SIGPIPE },
+ cmUVProcessChain::ExceptionCode::Other,
+ "SIGPIPE" },
+#endif
+ { false,
+ false,
+ { UV_ENOENT, true, 0, 0 },
+ cmUVProcessChain::ExceptionCode::Spawn,
+ uv_strerror(UV_ENOENT) },
+#ifdef _WIN32
+ { true,
+ true,
+ { 0, true, STATUS_ACCESS_VIOLATION, 0 },
+ cmUVProcessChain::ExceptionCode::Fault,
+ "Access violation" },
+#else
+ { false,
+ true,
+ { 0, true, 0, SIGABRT },
+ cmUVProcessChain::ExceptionCode::Other,
+ "Subprocess aborted" },
+#endif
+ };
+
+ std::vector<const cmUVProcessChain::Status*> status;
+
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand({ helperCommand, "echo" })
+ .AddCommand({ "this_command_is_for_cmake_and_should_never_exist" })
+ .AddCommand({ helperCommand, "dedup" })
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+
+ auto chain = builder.Start();
+ if (!chain.Valid()) {
+ std::cout << "Valid() returned false, should be true" << std::endl;
+ return false;
+ }
+
+ // Some platforms, like Solaris 10, take a long time to report a trapped
+ // subprocess to the parent process (about 1.7 seconds in the case of
+ // Solaris 10.) Wait 3 seconds to give it enough time.
+ if (chain.Wait(3000)) {
+ std::cout << "Wait() did not time out" << std::endl;
+ return false;
+ }
+
+ status = chain.GetStatus();
+ if (!resultsMatch(status, status1)) {
+ std::cout << "GetStatus() did not produce expected output" << std::endl;
+ printResults(status, status1);
+ return false;
+ }
+
+ if (!chain.Wait()) {
+ std::cout << "Wait() timed out" << std::endl;
+ return false;
+ }
+
+ status = chain.GetStatus();
+ if (!resultsMatch(status, status2)) {
+ std::cout << "GetStatus() did not produce expected output" << std::endl;
+ printResults(status, status2);
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVProcessChainInputFile(const char* helperCommand)
+{
+ std::unique_ptr<FILE, int (*)(FILE*)> f(
+ fopen("testUVProcessChainInput.txt", "rb"), fclose);
+
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand({ helperCommand, "dedup" })
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
+ cm_fileno(f.get()))
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+
+ auto chain = builder.Start();
+
+ if (!chain.Wait()) {
+ std::cout << "Wait() timed out" << std::endl;
+ return false;
+ }
+
+ cmUVPipeIStream stream(chain.GetLoop(), chain.OutputStream());
+ std::string output = getInput(stream);
+ if (output != "HELO WRD!") {
+ std::cout << "Output was \"" << output << "\", expected \"HELO WRD!\""
+ << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVProcessChainWait0(const char* helperCommand)
+{
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand({ helperCommand, "echo" });
+
+ auto chain = builder.Start();
+ if (!chain.Wait(0)) {
+ std::cout << "Wait(0) returned false, should be true" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
int testUVProcessChain(int argc, char** const argv)
{
if (argc < 2) {
@@ -518,5 +705,20 @@ int testUVProcessChain(int argc, char** const argv)
return -1;
}
+ if (!testUVProcessChainSpawnFail(argv[1])) {
+ std::cout << "While executing testUVProcessChainSpawnFail().\n";
+ return -1;
+ }
+
+ if (!testUVProcessChainInputFile(argv[1])) {
+ std::cout << "While executing testUVProcessChainInputFile().\n";
+ return -1;
+ }
+
+ if (!testUVProcessChainWait0(argv[1])) {
+ std::cout << "While executing testUVProcessChainWait0().\n";
+ return -1;
+ }
+
return 0;
}
diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx
index 99743e7..b53cac4 100644
--- a/Tests/CMakeLib/testUVProcessChainHelper.cxx
+++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx
@@ -7,10 +7,6 @@
#include <string>
#include <thread>
-#ifdef _WIN32
-# include <windows.h>
-#endif
-
#include "cmSystemTools.h"
static std::string getStdin()
@@ -32,13 +28,13 @@ int main(int argc, char** argv)
std::string command = argv[1];
if (command == "echo") {
- std::this_thread::sleep_for(std::chrono::milliseconds(3000));
+ std::this_thread::sleep_for(std::chrono::milliseconds(6000));
std::cout << "HELLO world!" << std::flush;
std::cerr << "1" << std::flush;
return 0;
}
if (command == "capitalize") {
- std::this_thread::sleep_for(std::chrono::milliseconds(9000));
+ std::this_thread::sleep_for(std::chrono::milliseconds(12000));
std::string input = getStdin();
for (auto& c : input) {
c = static_cast<char>(std::toupper(c));
diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx
index f9ed6af..af06a8e 100644
--- a/Tests/CMakeLib/testUVStreambuf.cxx
+++ b/Tests/CMakeLib/testUVStreambuf.cxx
@@ -3,11 +3,14 @@
#include <string>
#include <vector>
+#include <cmext/algorithm>
+
#include <cm3p/uv.h>
#include <stdint.h>
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
+#include "cmUVStream.h"
#include "cmUVStreambuf.h"
#define TEST_STR_LINE_1 "This string must be exactly 128 characters long so"
@@ -437,6 +440,139 @@ end:
return success;
}
+bool testUVPipeIStream()
+{
+ int pipe[] = { -1, -1 };
+ if (cmGetPipes(pipe) < 0) {
+ std::cout << "cmGetPipes() returned an error" << std::endl;
+ return false;
+ }
+
+ cm::uv_loop_ptr loop;
+ loop.init();
+ cm::uv_pipe_ptr pipeSink;
+ pipeSink.init(*loop, 0);
+ uv_pipe_open(pipeSink, pipe[1]);
+
+ std::string str = "Hello world!\n";
+ uv_write_t writeReq;
+ uv_buf_t buf;
+ buf.base = &str.front();
+ buf.len = str.length();
+ uv_write(&writeReq, pipeSink, &buf, 1, nullptr);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ cmUVPipeIStream pin(*loop, pipe[0]);
+ std::string line;
+ std::getline(pin, line);
+ if (line != "Hello world!") {
+ std::cout << "Line was \"" << line << "\", should be \"Hello world!\""
+ << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVStreamRead()
+{
+ int pipe[] = { -1, -1 };
+ if (cmGetPipes(pipe) < 0) {
+ std::cout << "cmGetPipes() returned an error" << std::endl;
+ return false;
+ }
+
+ cm::uv_loop_ptr loop;
+ loop.init();
+ cm::uv_pipe_ptr pipeSink;
+ pipeSink.init(*loop, 0);
+ uv_pipe_open(pipeSink, pipe[1]);
+
+ std::string str = "Hello world!";
+ uv_write_t writeReq;
+ uv_buf_t buf;
+ buf.base = &str.front();
+ buf.len = str.length();
+ uv_write(&writeReq, pipeSink, &buf, 1, nullptr);
+ uv_run(loop, UV_RUN_DEFAULT);
+ pipeSink.reset();
+
+ cm::uv_pipe_ptr pipeSource;
+ pipeSource.init(*loop, 0);
+ uv_pipe_open(pipeSource, pipe[0]);
+
+ std::string output;
+ bool finished = false;
+ auto handle = cmUVStreamRead(
+ pipeSource,
+ [&output](std::vector<char> data) { cm::append(output, data); },
+ [&output, &finished]() {
+ if (output != "Hello world!") {
+ std::cout << "Output was \"" << output
+ << "\", should be \"Hello world!\"" << std::endl;
+ return;
+ }
+ finished = true;
+ });
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ if (!finished) {
+ std::cout << "finished was not set" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVStreamReadLeak()
+{
+ int pipe[] = { -1, -1 };
+ if (cmGetPipes(pipe) < 0) {
+ std::cout << "cmGetPipes() returned an error" << std::endl;
+ return false;
+ }
+
+ cm::uv_loop_ptr loop;
+ loop.init();
+ cm::uv_pipe_ptr pipeSink;
+ pipeSink.init(*loop, 0);
+ uv_pipe_open(pipeSink, pipe[1]);
+
+ std::string str = "Hello world!";
+ uv_write_t writeReq;
+ uv_buf_t buf;
+ buf.base = &str.front();
+ buf.len = str.length();
+ uv_write(&writeReq, pipeSink, &buf, 1, nullptr);
+ uv_run(loop, UV_RUN_DEFAULT);
+ pipeSink.reset();
+
+ cm::uv_pipe_ptr pipeSource;
+ pipeSource.init(*loop, 0);
+ uv_pipe_open(pipeSource, pipe[0]);
+
+ std::string output;
+ bool finished = false;
+ auto handle = cmUVStreamRead(
+ pipeSource,
+ [&output](std::vector<char> data) { cm::append(output, data); },
+ [&output, &finished]() {
+ if (output != "Hello world!") {
+ std::cout << "Output was \"" << output
+ << "\", should be \"Hello world!\"" << std::endl;
+ return;
+ }
+ finished = true;
+ });
+
+ if (finished) {
+ std::cout << "finished was set" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
int testUVStreambuf(int argc, char** const argv)
{
if (argc < 2) {
@@ -454,5 +590,20 @@ int testUVStreambuf(int argc, char** const argv)
return -1;
}
+ if (!testUVPipeIStream()) {
+ std::cout << "While executing testUVPipeIStream().\n";
+ return -1;
+ }
+
+ if (!testUVStreamRead()) {
+ std::cout << "While executing testUVStreamRead().\n";
+ return -1;
+ }
+
+ if (!testUVStreamReadLeak()) {
+ std::cout << "While executing testUVStreamReadLeak().\n";
+ return -1;
+ }
+
return 0;
}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 19dea8f..7a71c0a 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -42,8 +42,8 @@ endif()
# Suppress generator deprecation warnings in test suite.
if(CMAKE_GENERATOR MATCHES "^Visual Studio 9 2008")
set(TEST_WARN_VS_CODE "set(ENV{CMAKE_WARN_VS9} OFF)")
-elseif(CMAKE_GENERATOR MATCHES "^Visual Studio 11 2012")
- set(TEST_WARN_VS_CODE "set(ENV{CMAKE_WARN_VS11} OFF)")
+elseif(CMAKE_GENERATOR MATCHES "^Visual Studio 12 2013")
+ set(TEST_WARN_VS_CODE "set(ENV{CMAKE_WARN_VS12} OFF)")
else()
set(TEST_WARN_VS_CODE "")
endif()
@@ -1540,10 +1540,40 @@ if(BUILD_TESTING)
add_subdirectory(GoogleTest)
endif()
- if(CMake_TEST_FindPython OR CMake_TEST_FindPython_SABIModule OR CMake_TEST_FindPython_NumPy
- OR CMake_TEST_FindPython_Conda OR CMake_TEST_FindPython_IronPython OR CMake_TEST_FindPython_PyPy)
- if (CMake_TEST_FindPython AND CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
- set(CMake_TEST_FindPython_SABIModule TRUE)
+ if(CMake_TEST_FindPython)
+ set(CMake_TEST_FindPython2 TRUE)
+ set(CMake_TEST_FindPython3 TRUE)
+ endif()
+ if(CMake_TEST_FindPython_SABIMOdule)
+ set(CMake_TEST_FindPython2_SABIModule TRUE)
+ set(CMake_TEST_FindPython3_SABIModule TRUE)
+ endif()
+ if(CMake_TEST_FindPython_NumPy)
+ set(CMake_TEST_FindPython2_NumPyy TRUE)
+ set(CMake_TEST_FindPython3_NumPy TRUE)
+ endif()
+ if(CMake_TEST_FindPython_Conda)
+ set(CMake_TEST_FindPython3_Conda TRUE)
+ endif()
+ if(CMake_TEST_FindPython_IronPython)
+ set(CMake_TEST_FindPython2_IronPython TRUE)
+ set(CMake_TEST_FindPython3_IronPython TRUE)
+ endif()
+ if(CMake_TEST_FindPython_PyPy)
+ set(CMake_TEST_FindPython2_PyPy TRUE)
+ set(CMake_TEST_FindPython3_PyPy TRUE)
+ endif()
+ if(CMake_TEST_FindPython2 OR CMake_TEST_FindPython3
+ OR CMake_TEST_FindPython2_SABIModule OR CMake_TEST_FindPython3_SABIModule
+ OR CMake_TEST_FindPython2_NumPy OR CMake_TEST_FindPython3_NumPy
+ OR CMake_TEST_FindPython3_Conda
+ OR CMake_TEST_FindPython2_IronPython OR CMake_TEST_FindPython3_IronPython
+ OR CMake_TEST_FindPython2_PyPy OR CMake_TEST_FindPython3_PyPy)
+ if (CMake_TEST_FindPython2 AND CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
+ set(CMake_TEST_FindPython2_SABIModule TRUE)
+ endif()
+ if (CMake_TEST_FindPython3 AND CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
+ set(CMake_TEST_FindPython3_SABIModule TRUE)
endif()
add_subdirectory(FindPython)
endif()
@@ -2279,11 +2309,6 @@ if(BUILD_TESTING)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSWinStorePhone/${name}")
endmacro()
- if(vs11 AND ws80)
- add_test_VSWinStorePhone(vs11-store80-X86 "Visual Studio 11 2012" WindowsStore 8.0 Win32)
- add_test_VSWinStorePhone(vs11-store80-ARM "Visual Studio 11 2012" WindowsStore 8.0 ARM)
- add_test_VSWinStorePhone(vs11-store80-X64 "Visual Studio 11 2012" WindowsStore 8.0 x64)
- endif()
if(vs12 AND ws81)
add_test_VSWinStorePhone(vs12-store81-X86 "Visual Studio 12 2013" WindowsStore 8.1 Win32)
add_test_VSWinStorePhone(vs12-store81-ARM "Visual Studio 12 2013" WindowsStore 8.1 ARM)
@@ -2311,10 +2336,6 @@ if(BUILD_TESTING)
add_test_VSWinStorePhone(vs14-store10_0-ARM "Visual Studio 14 2015" WindowsStore 10.0 ARM)
add_test_VSWinStorePhone(vs14-store10_0-X64 "Visual Studio 14 2015" WindowsStore 10.0 x64)
endif()
- if(vs11 AND wp80)
- add_test_VSWinStorePhone(vs11-phone80-X86 "Visual Studio 11 2012" WindowsPhone 8.0 Win32)
- add_test_VSWinStorePhone(vs11-phone80-ARM "Visual Studio 11 2012" WindowsPhone 8.0 ARM)
- endif()
if(vs12 AND wp81)
add_test_VSWinStorePhone(vs12-phone81-X86 "Visual Studio 12 2013" WindowsPhone 8.1 Win32)
add_test_VSWinStorePhone(vs12-phone81-ARM "Visual Studio 12 2013" WindowsPhone 8.1 ARM)
@@ -2341,10 +2362,6 @@ if(BUILD_TESTING)
endforeach()
endmacro()
- if(vs11)
- add_test_VSWinCE(vs11-ce80-ARM "Visual Studio 11 2012" WindowsCE 8.0 ${wince_sdk})
- endif()
-
if(vs12)
add_test_VSWinCE(vs12-ce80-ARM "Visual Studio 12 2013" WindowsCE 8.0 ${wince_sdk})
endif()
@@ -2471,9 +2488,6 @@ if(BUILD_TESTING)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}")
endmacro()
if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
- if(vs11)
- add_test_VSAndroid(vs11 "Visual Studio 11 2012" "Tegra-Android")
- endif()
if(vs12)
add_test_VSAndroid(vs12 "Visual Studio 12 2013" "Tegra-Android")
endif()
@@ -2751,29 +2765,6 @@ if(BUILD_TESTING)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateP4_DIR}")
endif()
- configure_file(
- "${CMake_SOURCE_DIR}/Tests/CTestTestFailure/testNoBuild.cmake.in"
- "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoBuild.cmake"
- @ONLY ESCAPE_QUOTES)
- add_test(CTestTestNoBuild ${CMAKE_CTEST_COMMAND}
- -S "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoBuild.cmake" -V
- --output-log "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testOut1.log"
- )
- set_tests_properties(CTestTestNoBuild PROPERTIES
- FAIL_REGULAR_EXPRESSION "Error" WILL_FAIL true)
-
- configure_file(
- "${CMake_SOURCE_DIR}/Tests/CTestTestFailure/testNoExe.cmake.in"
- "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoExe.cmake"
- @ONLY ESCAPE_QUOTES)
- add_test(CTestTestNoExe ${CMAKE_CTEST_COMMAND}
- -S "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoExe.cmake" -V
- --output-log "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testOut2.log"
- )
- set_tests_properties(CTestTestNoExe PROPERTIES DEPENDS CTestTestNoBuild
- PASS_REGULAR_EXPRESSION "Could not find executable"
- FAIL_REGULAR_EXPRESSION "SegFault")
-
if(NOT CMake_TEST_NO_NETWORK)
configure_file(
"${CMake_SOURCE_DIR}/Tests/CTestTestUpload/test.cmake.in"
@@ -3264,7 +3255,7 @@ if(BUILD_TESTING)
if(NOT CMake_TEST_EXTERNAL_CMAKE)
configure_file("${CMake_SOURCE_DIR}/Tests/CTestTest2/test.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestTest2/test.cmake" @ONLY ESCAPE_QUOTES)
- add_test(CTestTest2 ${CMAKE_CTEST_COMMAND}
+ add_test(NAME CTestTest2 COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIG>
-S "${CMake_BINARY_DIR}/Tests/CTestTest2/test.cmake" -V
--output-log "${CMake_BINARY_DIR}/Tests/CTestTest2/testOutput.log"
)
diff --git a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
index e6ed559..0f3bd4c 100644
--- a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
+++ b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
@@ -20,7 +20,7 @@ macro(TEST_PASS value msg)
endmacro()
if(CMAKE_COMPILER_IS_GNUCXX)
- exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
+ execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE _gcc_version_info)
string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
# gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the
# patch level, handle this here:
@@ -30,12 +30,12 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
- exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _clang_version_info)
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE _clang_version_info)
string (REGEX REPLACE ".*version ([0-9]\\.[0-9]).*" "\\1" _clang_version "${_clang_version_info}")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES Intel)
- exec_program(${CMAKE_CXX_COMPILER} ARGS -V OUTPUT_VARIABLE _intel_version_info)
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -V OUTPUT_VARIABLE _intel_version_info)
string (REGEX REPLACE ".*Version ([0-9]+(\\.[0-9]+)+).*" "\\1" _intel_version "${_intel_version_info}")
endif()
diff --git a/Tests/CTestTestFailure/CMakeLists.txt b/Tests/CTestTestFailure/CMakeLists.txt
deleted file mode 100644
index b6c1e7a..0000000
--- a/Tests/CTestTestFailure/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-cmake_minimum_required (VERSION 3.5)
-project(CTestTestFailure)
-include(CTest)
-
-add_executable (NoBuild badCode.cxx)
-target_link_libraries (NoBuild ${EXTRA_LIBS})
-
-add_test (TestNoExe NoBuild)
diff --git a/Tests/CTestTestFailure/CTestConfig.cmake b/Tests/CTestTestFailure/CTestConfig.cmake
deleted file mode 100644
index 5bc1e9e..0000000
--- a/Tests/CTestTestFailure/CTestConfig.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
-set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "open.cdash.org")
-set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
diff --git a/Tests/CTestTestFailure/testNoBuild.cmake.in b/Tests/CTestTestFailure/testNoBuild.cmake.in
deleted file mode 100644
index 505916e..0000000
--- a/Tests/CTestTestFailure/testNoBuild.cmake.in
+++ /dev/null
@@ -1,23 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
-set(CTEST_SITE "@SITE@")
-set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-NoBuild")
-
-set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestFailure")
-set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestFailure")
-set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-#CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
-
-CTEST_START(Experimental)
-#CTEST_UPDATE(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestFailure/testNoExe.cmake.in b/Tests/CTestTestFailure/testNoExe.cmake.in
deleted file mode 100644
index e3d7742..0000000
--- a/Tests/CTestTestFailure/testNoExe.cmake.in
+++ /dev/null
@@ -1,21 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
-set(CTEST_SITE "@SITE@")
-set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-NoExe")
-
-set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestFailure")
-set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestFailure")
-set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-#CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
-
-CTEST_START(Experimental)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CommandLineTest/CMakeLists.txt b/Tests/CommandLineTest/CMakeLists.txt
index 96aac10..a44fb39 100644
--- a/Tests/CommandLineTest/CMakeLists.txt
+++ b/Tests/CommandLineTest/CMakeLists.txt
@@ -2,58 +2,58 @@ cmake_minimum_required (VERSION 2.6)
project(CommandLineTest)
get_filename_component(CMAKE_BIN_DIR ${CMAKE_COMMAND} PATH)
-macro(EXEC_CMAKE_COMMAND CMAKE_ARGS)
- exec_program("${CMAKE_COMMAND}" ARGS "${CMAKE_ARGS}" RETURN_VALUE RET)
+macro(EXEC_CMAKE_COMMAND)
+ execute_process(COMMAND "${CMAKE_COMMAND}" ${ARGN} RESULT_VARIABLE RET)
if(${RET})
- message(SEND_ERROR "CMake command failed with arguments \"${CMAKE_ARGS}\"")
+ message(SEND_ERROR "CMake command failed with arguments \"${ARGN}\"")
endif()
endmacro()
-EXEC_CMAKE_COMMAND("-E chdir \"${CMAKE_CURRENT_SOURCE_DIR}\" \"${CMAKE_COMMAND}\" -E echo \"Hello World\"")
-EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -L ${CommandLineTest_SOURCE_DIR}\"")
-EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -LA ${CommandLineTest_SOURCE_DIR}\"")
-EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -LH ${CommandLineTest_SOURCE_DIR}\"")
-EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -LAH ${CommandLineTest_SOURCE_DIR}\"")
-EXEC_CMAKE_COMMAND("--help")
-EXEC_CMAKE_COMMAND("--help-command-list")
-EXEC_CMAKE_COMMAND("--help add_executable")
-EXEC_CMAKE_COMMAND("--help-command add_executable")
-EXEC_CMAKE_COMMAND("--help-full \"${CMAKE_CURRENT_BINARY_DIR}/cmake.txt\"")
-EXEC_CMAKE_COMMAND("--help-man \"${CMAKE_CURRENT_BINARY_DIR}/cmake.man\"")
-EXEC_CMAKE_COMMAND("--help-html \"${CMAKE_CURRENT_BINARY_DIR}/cmake.html\"")
-EXEC_CMAKE_COMMAND("--copyright \"${CMAKE_CURRENT_BINARY_DIR}/Copyright.txt\"")
-EXEC_CMAKE_COMMAND("--version \"${CMAKE_CURRENT_BINARY_DIR}/version.txt\"")
+EXEC_CMAKE_COMMAND(-E chdir "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_COMMAND}" -E echo "Hello World")
+EXEC_CMAKE_COMMAND(-E time "${CMAKE_COMMAND} -N -L ${CommandLineTest_SOURCE_DIR}")
+EXEC_CMAKE_COMMAND(-E time "${CMAKE_COMMAND} -N -LA ${CommandLineTest_SOURCE_DIR}")
+EXEC_CMAKE_COMMAND(-E time "${CMAKE_COMMAND} -N -LH ${CommandLineTest_SOURCE_DIR}")
+EXEC_CMAKE_COMMAND(-E time "${CMAKE_COMMAND} -N -LAH ${CommandLineTest_SOURCE_DIR}")
+EXEC_CMAKE_COMMAND(--help)
+EXEC_CMAKE_COMMAND(--help-command-list)
+EXEC_CMAKE_COMMAND(--help add_executable)
+EXEC_CMAKE_COMMAND(--help-command add_executable)
+EXEC_CMAKE_COMMAND(--help-full "${CMAKE_CURRENT_BINARY_DIR}/cmake.txt")
+EXEC_CMAKE_COMMAND(--help-man "${CMAKE_CURRENT_BINARY_DIR}/cmake.man")
+EXEC_CMAKE_COMMAND(--help-html "${CMAKE_CURRENT_BINARY_DIR}/cmake.html")
+EXEC_CMAKE_COMMAND(--copyright "${CMAKE_CURRENT_BINARY_DIR}/Copyright.txt")
+EXEC_CMAKE_COMMAND(--version "${CMAKE_CURRENT_BINARY_DIR}/version.txt")
add_executable(CommandLineTest CommandLineTest.cxx)
get_filename_component(CMAKE_COMMAND_PATH "${CMAKE_COMMAND}" PATH)
set(CTEST_COMMAND "${CMAKE_COMMAND_PATH}/ctest")
-macro(EXEC_CTEST_COMMAND CMAKE_ARGS)
- exec_program("${CTEST_COMMAND}" ARGS "${CMAKE_ARGS}" RETURN_VALUE RET)
+macro(EXEC_CTEST_COMMAND)
+ execute_process(COMMAND "${CTEST_COMMAND}" ${ARGN} RESULT_VARIABLE RET)
if(${RET})
message(SEND_ERROR "CTest command failed with arguments \"${CMAKE_ARGS}\"")
endif()
endmacro()
-macro(EXEC_CTEST_COMMAND_WITH_DIR DIR CMAKE_ARGS)
- exec_program("${CTEST_COMMAND}" "${DIR}" ARGS "${CMAKE_ARGS}" RETURN_VALUE RET)
+macro(EXEC_CTEST_COMMAND_WITH_DIR DIR)
+ execute_process(COMMAND "${CTEST_COMMAND}" ${ARGN} WORKING_DIRECTORY "${DIR}" RESULT_VARIABLE RET)
if(${RET})
message(SEND_ERROR "CTest command failed with arguments \"${CMAKE_ARGS}\"")
endif()
endmacro()
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N")
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-R complex -N")
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-E Simple -N")
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-E Simple -N")
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N -I -10")
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N -I 10-")
-EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N -I 3,4")
-EXEC_CTEST_COMMAND("--help")
-EXEC_CTEST_COMMAND("--copyright")
-EXEC_CTEST_COMMAND("--help-full \"${CMAKE_CURRENT_BINARY_DIR}/ctest.txt\"")
-EXEC_CTEST_COMMAND("--help-man \"${CMAKE_CURRENT_BINARY_DIR}/ctest.man\"")
-EXEC_CTEST_COMMAND("--help-html \"${CMAKE_CURRENT_BINARY_DIR}/ctest.html\"")
-EXEC_CTEST_COMMAND("--version")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -N)
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -R complex -N)
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -E Simple -N)
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -E Simple -N)
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -N -I -10)
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -N -I 10-)
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." -N -I 3,4)
+EXEC_CTEST_COMMAND(--help)
+EXEC_CTEST_COMMAND(--copyright)
+EXEC_CTEST_COMMAND(--help-full "${CMAKE_CURRENT_BINARY_DIR}/ctest.txt")
+EXEC_CTEST_COMMAND(--help-man "${CMAKE_CURRENT_BINARY_DIR}/ctest.man")
+EXEC_CTEST_COMMAND(--help-html "${CMAKE_CURRENT_BINARY_DIR}/ctest.html")
+EXEC_CTEST_COMMAND(--version)
if(THIS_SHOULD_BE_SET)
message(STATUS "***************************")
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index 9493a2f..d3a184d 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -327,12 +327,12 @@ if (WIN32)
${Complex_SOURCE_DIR}/Library/dummy
"${dir}/${file}"
COPYONLY)
- exec_program(${CMAKE_COMMAND} ARGS "-E write_regv \"${hkey}\" \"${dir}\"")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E write_regv "${hkey}" "${dir}")
find_path(REGISTRY_TEST_PATH
${file}
"[${hkey}]" DOC "Registry_Test_Path")
- exec_program(${CMAKE_COMMAND} ARGS "-E delete_regv \"${hkey}\"")
- exec_program(${CMAKE_COMMAND} ARGS "-E rm -f \"${dir}/${file}\"")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E delete_regv "${hkey}")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E rm -f "${dir}/${file}")
endif ()
endif ()
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index e4fdc68..dd996e1 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -284,12 +284,12 @@ if (WIN32)
${Complex_SOURCE_DIR}/Library/dummy
"${dir}/${file}"
COPYONLY)
- exec_program(${CMAKE_COMMAND} ARGS "-E write_regv \"${hkey}\" \"${dir}\"")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E write_regv "${hkey}" "${dir}")
find_path(REGISTRY_TEST_PATH
${file}
"[${hkey}]" DOC "Registry_Test_Path")
- exec_program(${CMAKE_COMMAND} ARGS "-E delete_regv \"${hkey}\"")
- exec_program(${CMAKE_COMMAND} ARGS "-E rm -f \"${dir}/${file}\"")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E delete_regv "${hkey}")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E rm -f "${dir}/${file}")
endif ()
endif ()
diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt
index 0041b07..c737bcc 100644
--- a/Tests/Cuda/CMakeLists.txt
+++ b/Tests/Cuda/CMakeLists.txt
@@ -13,6 +13,7 @@ add_cuda_test_macro(Cuda.MixedStandardLevels4 MixedStandardLevels4)
add_cuda_test_macro(Cuda.MixedStandardLevels5 MixedStandardLevels5)
add_cuda_test_macro(Cuda.NotEnabled CudaNotEnabled)
add_cuda_test_macro(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly)
+add_cuda_test_macro(Cuda.StubRPATH StubRPATH)
add_cuda_test_macro(Cuda.Toolkit Toolkit)
add_cuda_test_macro(Cuda.IncludePathNoToolkit IncludePathNoToolkit)
add_cuda_test_macro(Cuda.SharedRuntimePlusToolkit SharedRuntimePlusToolkit)
diff --git a/Tests/Cuda/StubRPATH/CMakeLists.txt b/Tests/Cuda/StubRPATH/CMakeLists.txt
new file mode 100644
index 0000000..93643c5
--- /dev/null
+++ b/Tests/Cuda/StubRPATH/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.18)
+project(StubRPATH CXX)
+
+#Verify that linking to a stub library doesn't cause an `-rpath` entry
+
+# Needed for `CUDAToolkit_LIBRARY_SEARCH_DIRS`
+find_package(CUDAToolkit REQUIRED)
+
+find_library(CUDA_DRIVER_STUB_LIBRARY
+ NAMES cuda
+ HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
+ ENV CUDA_PATH
+ PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
+)
+add_library(imported_stub IMPORTED SHARED)
+set_target_properties(imported_stub PROPERTIES IMPORTED_IMPLIB "${CUDA_DRIVER_STUB_LIBRARY}")
+set_target_properties(imported_stub PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CUDAToolkit_INCLUDE_DIRS}")
+
+set(CMAKE_CXX_STANDARD 11)
+add_executable(StubRPATH main.cxx)
+target_link_libraries(StubRPATH PRIVATE imported_stub)
diff --git a/Tests/Cuda/StubRPATH/main.cxx b/Tests/Cuda/StubRPATH/main.cxx
new file mode 100644
index 0000000..877856e
--- /dev/null
+++ b/Tests/Cuda/StubRPATH/main.cxx
@@ -0,0 +1,17 @@
+
+#include <iostream>
+
+#include <cuda.h>
+
+int main(int argc, char** argv)
+{
+ int nDevices = 0;
+ cuInit(0);
+ auto err = cuDeviceGetCount(&nDevices);
+ if (err != CUDA_SUCCESS) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices "
+ << err << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/ExternalOBJ/CMakeLists.txt b/Tests/ExternalOBJ/CMakeLists.txt
index 4ff75b8..141977c 100644
--- a/Tests/ExternalOBJ/CMakeLists.txt
+++ b/Tests/ExternalOBJ/CMakeLists.txt
@@ -3,7 +3,7 @@ project (ExternalOBJ)
if(APPLE)
# set _CMAKE_OSX_MACHINE to umame -m
- exec_program(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+ execute_process(COMMAND uname -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE)
# check for Power PC and change to ppc
if("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
set(_CMAKE_OSX_MACHINE ppc)
diff --git a/Tests/ExternalOBJ/Object/CMakeLists.txt b/Tests/ExternalOBJ/Object/CMakeLists.txt
index dbfe09e..a886da0 100644
--- a/Tests/ExternalOBJ/Object/CMakeLists.txt
+++ b/Tests/ExternalOBJ/Object/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6)
project(Object)
if(APPLE)
# set _CMAKE_OSX_MACHINE to umame -m
- exec_program(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+ execute_process(COMMAND uname -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE)
# check for Power PC and change to ppc
if("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
set(_CMAKE_OSX_MACHINE ppc)
diff --git a/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt b/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
index 99823a6..18f8fda 100644
--- a/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
+++ b/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5)
project(TestArtifactsInteractive LANGUAGES C)
set (components Interpreter Development)
-if (CMake_TEST_FindPython_NumPy)
+if (CMake_TEST_FindPython3_NumPy)
list (APPEND components NumPy)
endif()
@@ -12,13 +12,13 @@ find_package(Python3 REQUIRED COMPONENTS ${components})
if (Python3_ARTIFACTS_INTERACTIVE)
if (NOT DEFINED CACHE{Python3_EXECUTABLE}
OR NOT DEFINED CACHE{Python3_LIBRARY} OR NOT DEFINED CACHE{Python3_INCLUDE_DIR}
- OR (CMake_TEST_FindPython_NumPy AND NOT DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
+ OR (CMake_TEST_FindPython3_NumPy AND NOT DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
message (FATAL_ERROR "Python3_ARTIFACTS_INTERACTIVE=ON Failed.")
endif()
else()
if (DEFINED CACHE{Python3_EXECUTABLE}
OR DEFINED CACHE{Python3_LIBRARY} OR DEFINED CACHE{Python3_INCLUDE_DIR}
- OR (CMake_TEST_FindPython_NumPy AND DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
+ OR (CMake_TEST_FindPython3_NumPy AND DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
message (FATAL_ERROR "Python3_ARTIFACTS_INTERACTIVE=OFF Failed.")
endif()
endif()
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index b6942c9..636a7b0 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -1,4 +1,4 @@
-if(CMake_TEST_FindPython)
+if(CMake_TEST_FindPython2)
add_test(NAME FindPython.Python2.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -44,6 +44,139 @@ if(CMake_TEST_FindPython)
set_tests_properties(FindPython.Python2Fail PROPERTIES
PASS_REGULAR_EXPRESSION "Could NOT find Python2 \\(missing: foobar\\)")
+ add_test(NAME FindPython.Python.V2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.LOCATION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VERSION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.Python2.ExactVersion.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2.ExactVersion.LOCATION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_MAJOR_VERSION=2
+ -DPython_REQUESTED_VERSION=2.1.2
+ -DPython2_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python2.ExactVersion.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2.ExactVersion.VERSION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_MAJOR_VERSION=2
+ -DPython_REQUESTED_VERSION=2.1.2
+ -DPython2_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.Python.V2.ExactVersion.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.ExactVersion.LOCATION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2.1.2
+ -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V2.ExactVersion.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.ExactVersion.VERSION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2.1.2
+ -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.Python2.VersionRange.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2.VersionRange.LOCATION"
+ ${build_generator_args}
+ --build-project TestVersionRange
+ --build-options ${build_options} -DPython=Python2 -DPython_REQUESTED_VERSION=2
+ -DPython2_FIND_STRATEGY=LOCATION
+ )
+ add_test(NAME FindPython.Python2.VersionRange.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2.VersionRange.VERSION"
+ ${build_generator_args}
+ --build-project TestVersionRange
+ --build-options ${build_options} -DPython=Python2 -DPython_REQUESTED_VERSION=2
+ -DPython2_FIND_STRATEGY=VERSION
+ )
+ add_test(NAME FindPython.Python.V2.VersionRange.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VersionRange.LOCATION"
+ ${build_generator_args}
+ --build-project TestVersionRange
+ --build-options ${build_options} -DPython=Python -DPython_REQUESTED_VERSION=2
+ -DPython_FIND_STRATEGY=LOCATION
+ )
+ add_test(NAME FindPython.Python.V2.VersionRange.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VersionRange.VERSION"
+ ${build_generator_args}
+ --build-project TestVersionRange
+ --build-options ${build_options} -DPython=Python -DPython_REQUESTED_VERSION=2
+ -DPython_FIND_STRATEGY=VERSION
+ )
+
+ add_test(NAME FindPython.Python2Embedded COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python2Embedded"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2Embedded"
+ ${build_generator_args}
+ --build-project TestPython2Embedded
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ set_property(TEST FindPython.Python2.LOCATION FindPython.Python2.VERSION
+ FindPython.Python2.Development.Module FindPython.Python2Fail
+ FindPython.Python.V2.LOCATION FindPython.Python.V2.VERSION
+ FindPython.Python2.ExactVersion.LOCATION FindPython.Python2.ExactVersion.VERSION
+ FindPython.Python.V2.ExactVersion.LOCATION FindPython.Python.V2.ExactVersion.VERSION
+ FindPython.Python2.VersionRange.LOCATION FindPython.Python2.VersionRange.VERSION
+ FindPython.Python.V2.VersionRange.LOCATION FindPython.Python.V2.VersionRange.VERSION
+ FindPython.Python2Embedded
+ APPEND PROPERTY LABELS Python2)
+endif()
+
+if(CMake_TEST_FindPython3)
add_test(NAME FindPython.Python3.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -89,46 +222,6 @@ if(CMake_TEST_FindPython)
set_tests_properties(FindPython.Python3Fail PROPERTIES
PASS_REGULAR_EXPRESSION "Could NOT find Python3 \\(missing: foobar\\)")
- add_test(NAME FindPython.Python.LOCATION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.LOCATION"
- ${build_generator_args}
- --build-project TestPython
- --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
- add_test(NAME FindPython.Python.VERSION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.VERSION"
- ${build_generator_args}
- --build-project TestPython
- --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
- add_test(NAME FindPython.Python.V2.LOCATION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.LOCATION"
- ${build_generator_args}
- --build-project TestPython
- --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
- add_test(NAME FindPython.Python.V2.VERSION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VERSION"
- ${build_generator_args}
- --build-project TestPython
- --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
add_test(NAME FindPython.Python.V3.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -150,30 +243,6 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.Python2.ExactVersion.LOCATION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python2.ExactVersion.LOCATION"
- ${build_generator_args}
- --build-project TestExactVersion
- --build-options ${build_options} -DPython_MAJOR_VERSION=2
- -DPython_REQUESTED_VERSION=2.1.2
- -DPython2_FIND_STRATEGY=LOCATION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
- add_test(NAME FindPython.Python2.ExactVersion.VERSION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python2.ExactVersion.VERSION"
- ${build_generator_args}
- --build-project TestExactVersion
- --build-options ${build_options} -DPython_MAJOR_VERSION=2
- -DPython_REQUESTED_VERSION=2.1.2
- -DPython2_FIND_STRATEGY=VERSION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
add_test(NAME FindPython.Python3.ExactVersion.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -198,28 +267,6 @@ if(CMake_TEST_FindPython)
-DPython3_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.Python.V2.ExactVersion.LOCATION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.ExactVersion.LOCATION"
- ${build_generator_args}
- --build-project TestExactVersion
- --build-options ${build_options} -DPython_REQUESTED_VERSION=2.1.2
- -DPython_FIND_STRATEGY=LOCATION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
- add_test(NAME FindPython.Python.V2.ExactVersion.VERSION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.ExactVersion.VERSION"
- ${build_generator_args}
- --build-project TestExactVersion
- --build-options ${build_options} -DPython_REQUESTED_VERSION=2.1.2
- -DPython_FIND_STRATEGY=VERSION
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
add_test(NAME FindPython.Python.V3.ExactVersion.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -263,46 +310,6 @@ if(CMake_TEST_FindPython)
--build-options ${build_options} -DPython=Python3 -DPython_REQUESTED_VERSION=3
-DPython3_FIND_STRATEGY=VERSION
)
- add_test(NAME FindPython.Python2.VersionRange.LOCATION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python2.VersionRange.LOCATION"
- ${build_generator_args}
- --build-project TestVersionRange
- --build-options ${build_options} -DPython=Python2 -DPython_REQUESTED_VERSION=2
- -DPython2_FIND_STRATEGY=LOCATION
- )
- add_test(NAME FindPython.Python2.VersionRange.VERSION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python2.VersionRange.VERSION"
- ${build_generator_args}
- --build-project TestVersionRange
- --build-options ${build_options} -DPython=Python2 -DPython_REQUESTED_VERSION=2
- -DPython2_FIND_STRATEGY=VERSION
- )
- add_test(NAME FindPython.Python.V2.VersionRange.LOCATION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VersionRange.LOCATION"
- ${build_generator_args}
- --build-project TestVersionRange
- --build-options ${build_options} -DPython=Python -DPython_REQUESTED_VERSION=2
- -DPython_FIND_STRATEGY=LOCATION
- )
- add_test(NAME FindPython.Python.V2.VersionRange.VERSION COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VersionRange.VERSION"
- ${build_generator_args}
- --build-project TestVersionRange
- --build-options ${build_options} -DPython=Python -DPython_REQUESTED_VERSION=2
- -DPython_FIND_STRATEGY=VERSION
- )
add_test(NAME FindPython.Python.V3.VersionRange.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -324,17 +331,6 @@ if(CMake_TEST_FindPython)
-DPython_FIND_STRATEGY=VERSION
)
- add_test(NAME FindPython.MultiplePackages COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/MultiplePackages"
- "${CMake_BINARY_DIR}/Tests/FindPython/MultiplePackages"
- ${build_generator_args}
- --build-project TestMultiplePackages
- --build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
-
add_test(NAME FindPython.VirtualEnv COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -346,16 +342,6 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.Python2Embedded COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/Python2Embedded"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python2Embedded"
- ${build_generator_args}
- --build-project TestPython2Embedded
- --build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
- )
add_test(NAME FindPython.Python3Embedded COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -377,7 +363,7 @@ if(CMake_TEST_FindPython)
--build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
"-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
"-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
- "-DCMake_TEST_FindPython_SABIModule=${CMake_TEST_FindPython_SABIModule}"
+ "-DCMake_TEST_FindPython3_SABIModule=${CMake_TEST_FindPython3_SABIModule}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -391,7 +377,7 @@ if(CMake_TEST_FindPython)
--build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
"-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
"-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
- "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ "-DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}"
"-DPython3_ARTIFACTS_INTERACTIVE=ON"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -405,7 +391,7 @@ if(CMake_TEST_FindPython)
--build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
"-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
"-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
- "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ "-DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}"
"-DPython3_ARTIFACTS_INTERACTIVE=OFF"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -420,7 +406,7 @@ if(CMake_TEST_FindPython)
--build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
"-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
"-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
- "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ "-DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -437,6 +423,54 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ set_property(TEST FindPython.Python3.LOCATION FindPython.Python3.VERSION
+ FindPython.Python3.Development.Module FindPython.Python3Fail
+ FindPython.Python.V3.LOCATION FindPython.Python.V3.VERSION
+ FindPython.Python3.ExactVersion.LOCATION FindPython.Python3.ExactVersion.VERSION
+ FindPython.Python.V3.ExactVersion.LOCATION FindPython.Python.V3.ExactVersion.VERSION
+ FindPython.Python3.VersionRange.LOCATION FindPython.Python3.VersionRange.VERSION
+ FindPython.Python.V3.VersionRange.LOCATION FindPython.Python.V3.VersionRange.VERSION
+ FindPython.VirtualEnv FindPython.Python3Embedded FindPython.RequiredArtifacts
+ FindPython.ArtifactsInteractive.ON FindPython.ArtifactsInteractive.OFF
+ FindPython.CustomFailureMessage FindPython.DifferentComponents
+ APPEND PROPERTY LABELS Python3)
+
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ add_test(NAME FindPython.UnversionedNames COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/UnversionedNames"
+ "${CMake_BINARY_DIR}/Tests/FindPython/UnversionedNames"
+ ${build_generator_args}
+ --build-project UnversionedNames
+ --build-options ${build_options}
+ )
+ set_property(TEST FindPython.UnversionedNames APPEND PROPERTY LABELS Python3)
+ endif()
+endif()
+
+if(CMake_TEST_FindPython2 OR CMake_TEST_FindPython3)
+ add_test(NAME FindPython.Python.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.LOCATION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.VERSION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
if (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
add_test(NAME FindPython.Interpreter.SOABI COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
@@ -464,22 +498,28 @@ if(CMake_TEST_FindPython)
"-DCMake_TEST_FindPython_COMPONENT=Development"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
+ set_property(TEST FindPython.Interpreter.SOABI FindPython.Development.SOABI
+ APPEND PROPERTY LABELS Python2 Python3)
endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
- add_test(NAME FindPython.UnversionedNames COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/UnversionedNames"
- "${CMake_BINARY_DIR}/Tests/FindPython/UnversionedNames"
- ${build_generator_args}
- --build-project UnversionedNames
- --build-options ${build_options}
+ add_test(NAME FindPython.MultiplePackages COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/MultiplePackages"
+ "${CMake_BINARY_DIR}/Tests/FindPython/MultiplePackages"
+ ${build_generator_args}
+ --build-project TestMultiplePackages
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- endif()
+
+ set_property(TEST FindPython.Python.LOCATION FindPython.Python.VERSION FindPython.MultiplePackages
+ APPEND PROPERTY LABELS Python2 Python3)
endif()
-if(CMake_TEST_FindPython_SABIModule)
+
+if(CMake_TEST_FindPython2_SABIModule)
add_test(NAME FindPython.Python2.Development.SABIModule COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -490,9 +530,12 @@ if(CMake_TEST_FindPython_SABIModule)
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- set_tests_properties(FindPython.Python2.Development.SABIModule PROPERTIES
- PASS_REGULAR_EXPRESSION "Could NOT find Python2 \\(missing: .*Development\\.SABIModule")
+ set_tests_properties(FindPython.Python2.Development.SABIModule PROPERTIES
+ PASS_REGULAR_EXPRESSION "Could NOT find Python2 \\(missing: .*Development\\.SABIModule")
+ set_property(TEST FindPython.Python2.Development.SABIModule APPEND PROPERTY LABELS Python2)
+endif()
+if(CMake_TEST_FindPython3_SABIModule)
# Use exclusively Release configuration because Debug is, on Windows with MSVC,
# unusable with SABI: Python force link with debug version of full versioned library rather than
# the stable ABI one.
@@ -506,9 +549,10 @@ if(CMake_TEST_FindPython_SABIModule)
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C Release
)
+ set_property(TEST FindPython.Python3.Development.SABIModule APPEND PROPERTY LABELS Python3)
endif()
-if(CMake_TEST_FindPython_NumPy)
+if(CMake_TEST_FindPython2_NumPy OR CMake_TEST_FindPython3_NumPy)
add_test(NAME FindPython.NumPy COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -528,9 +572,11 @@ if(CMake_TEST_FindPython_NumPy)
--build-project TestNumPyOnly
--build-options ${build_options}
)
+
+ set_property(TEST FindPython.NumPy FindPython.NumPyOnly APPEND PROPERTY LABELS Python2 Python3)
endif()
-if(CMake_TEST_FindPython_Conda)
+if(CMake_TEST_FindPython3_Conda)
add_test(NAME FindPython.VirtualEnvConda COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -541,73 +587,83 @@ if(CMake_TEST_FindPython_Conda)
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ set_property(TEST FindPython.VirtualEnvConda APPEND PROPERTY LABELS Python3)
endif()
-if (CMake_TEST_FindPython AND CMake_TEST_FindPython_IronPython)
- add_test(NAME FindPython.Implementation.CPython COMMAND
+if (CMake_TEST_FindPython2 AND CMake_TEST_FindPython2_IronPython)
+ add_test(NAME FindPython.Implementation.CPython2 COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
"${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
- "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.CPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.CPython2"
${build_generator_args}
--build-project TestImplementationCPython
--build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_REQUESTED_IMPLEMENTATIONS=CPython
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.Implementation.IronPython COMMAND
+ add_test(NAME FindPython.Implementation.IronPython2 COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
"${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
- "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.IronPython2"
${build_generator_args}
--build-project TestImplementationIronPython
--build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_REQUESTED_IMPLEMENTATION=IronPython
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
+ set_property(TEST FindPython.Implementation.CPython2 FindPython.Implementation.IronPython2
+ APPEND PROPERTY LABELS Python2)
endif()
-if(CMake_TEST_FindPython_IronPython)
- add_test(NAME FindPython.IronPython2.LOCATION COMMAND
+if (CMake_TEST_FindPython3 AND CMake_TEST_FindPython3_IronPython)
+ add_test(NAME FindPython.Implementation.CPython3 COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython2"
- "${CMake_BINARY_DIR}/Tests/FindPython/IronPython2.LOCATION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.CPython3"
${build_generator_args}
- --build-project TestIronPython2
- --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+ --build-project TestImplementationCPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_REQUESTED_IMPLEMENTATIONS=CPython
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.IronPython2.VERSION COMMAND
+ add_test(NAME FindPython.Implementation.IronPython3 COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython2"
- "${CMake_BINARY_DIR}/Tests/FindPython/IronPython2.VERSION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.IronPython3"
${build_generator_args}
- --build-project TestIronPython2
- --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+ --build-project TestImplementationIronPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_REQUESTED_IMPLEMENTATION=IronPython
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.IronPython.LOCATION COMMAND
+ set_property(TEST FindPython.Implementation.CPython3 FindPython.Implementation.IronPython3
+ APPEND PROPERTY LABELS Python3)
+endif()
+
+if(CMake_TEST_FindPython2_IronPython)
+ add_test(NAME FindPython.IronPython2.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
- "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.LOCATION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython2.LOCATION"
${build_generator_args}
- --build-project TestIronPython
- --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+ --build-project TestIronPython2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.IronPython.VERSION COMMAND
+ add_test(NAME FindPython.IronPython2.VERSION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
- "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.VERSION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython2.VERSION"
${build_generator_args}
- --build-project TestIronPython
- --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+ --build-project TestIronPython2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
add_test(NAME FindPython.IronPython.V2.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -651,71 +707,133 @@ if(CMake_TEST_FindPython_IronPython)
-DPython2_FIND_IMPLEMENTATIONS=IronPython
-DPython2_FIND_STRATEGY=VERSION
)
+
+ set_property(TEST FindPython.IronPython2.LOCATION FindPython.IronPython2.VERSION
+ FindPython.IronPython.V2.LOCATION FindPython.IronPython.V2.VERSION
+ FindPython.IronPython2.VersionRange.LOCATION FindPython.IronPython2.VersionRange.VERSION
+ APPEND PROPERTY LABELS Python2)
endif()
-if(CMake_TEST_FindPython_PyPy)
- add_test(NAME FindPython.PyPy2.LOCATION COMMAND
+if(CMake_TEST_FindPython3_IronPython)
+ add_test(NAME FindPython.IronPython3.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
- "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.LOCATION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython3.LOCATION"
${build_generator_args}
- --build-project TestPyPy2
- --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+ --build-project TestIronPython3
+ --build-options ${build_options} -DPython3_FIND_STRATEGY=LOCATION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.PyPy2.VERSION COMMAND
+ add_test(NAME FindPython.IronPython3.VERSION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
- "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.VERSION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython3.VERSION"
${build_generator_args}
- --build-project TestPyPy2
- --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+ --build-project TestIronPython3
+ --build-options ${build_options} -DPython3_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.PyPy3.LOCATION COMMAND
+ add_test(NAME FindPython.IronPython.V3.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
- "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.LOCATION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.V3.LOCATION"
${build_generator_args}
- --build-project TestPyPy3
- --build-options ${build_options} -DPython3_FIND_STRATEGY=LOCATION
+ --build-project TestIronPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=LOCATION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.PyPy3.VERSION COMMAND
+ add_test(NAME FindPython.IronPython.V3.VERSION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
- "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.VERSION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.V3.VERSION"
${build_generator_args}
- --build-project TestPyPy3
- --build-options ${build_options} -DPython3_FIND_STRATEGY=VERSION
+ --build-project TestIronPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.PyPy.LOCATION COMMAND
+ add_test(NAME FindPython.IronPython3.VersionRange.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
- "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.LOCATION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython3.VersionRange.LOCATION"
${build_generator_args}
- --build-project TestPyPy
+ --build-project TestVersionRange
+ --build-options ${build_options} -DPython=Python3 -DPython_REQUESTED_VERSION=3
+ -DPython3_FIND_IMPLEMENTATIONS=IronPython
+ -DPython3_FIND_STRATEGY=LOCATION
+ )
+ add_test(NAME FindPython.IronPython3.VersionRange.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VersionRange"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython3.VersionRange.VERSION"
+ ${build_generator_args}
+ --build-project TestVersionRange
+ --build-options ${build_options} -DPython=Python3 -DPython_REQUESTED_VERSION=3
+ -DPython3_FIND_IMPLEMENTATIONS=IronPython
+ -DPython3_FIND_STRATEGY=VERSION
+ )
+
+ set_property(TEST FindPython.IronPython3.LOCATION FindPython.IronPython3.VERSION
+ FindPython.IronPython.V3.LOCATION FindPython.IronPython.V3.VERSION
+ FindPython.IronPython3.VersionRange.LOCATION FindPython.IronPython3.VersionRange.VERSION
+ APPEND PROPERTY LABELS Python3)
+endif()
+
+if(CMake_TEST_FindPython2_IronPython OR CMake_TEST_FindPython3_IronPython)
+ add_test(NAME FindPython.IronPython.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.LOCATION"
+ ${build_generator_args}
+ --build-project TestIronPython
--build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- add_test(NAME FindPython.PyPy.VERSION COMMAND
+ add_test(NAME FindPython.IronPython.VERSION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
- "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.VERSION"
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.VERSION"
${build_generator_args}
- --build-project TestPyPy
+ --build-project TestIronPython
--build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
+ set_property(TEST FindPython.IronPython.LOCATION FindPython.IronPython.VERSION
+ APPEND PROPERTY LABELS Python2 Python3)
+endif()
+
+if(CMake_TEST_FindPython2_PyPy)
+ add_test(NAME FindPython.PyPy2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
add_test(NAME FindPython.PyPy.V2.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -736,6 +854,34 @@ if(CMake_TEST_FindPython_PyPy)
--build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
+ set_property(TEST FindPython.PyPy2.LOCATION FindPython.PyPy2.VERSION
+ FindPython.PyPy.V2.LOCATION FindPython.PyPy.V2.VERSION
+ APPEND PROPERTY LABELS Python2)
+endif()
+
+if(CMake_TEST_FindPython3_PyPy)
+ add_test(NAME FindPython.PyPy3.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy3
+ --build-options ${build_options} -DPython3_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy3.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy3
+ --build-options ${build_options} -DPython3_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
add_test(NAME FindPython.PyPy.V3.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -756,4 +902,34 @@ if(CMake_TEST_FindPython_PyPy)
--build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
+ set_property(TEST FindPython.PyPy3.LOCATION FindPython.PyPy3.VERSION
+ FindPython.PyPy.V3.LOCATION FindPython.PyPy.V3.VERSION
+ APPEND PROPERTY LABELS Python3)
+endif()
+
+if(CMake_TEST_FindPython2_PyPy OR CMake_TEST_FindPython3_PyPy)
+ add_test(NAME FindPython.PyPy.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ set_property(TEST FindPython.PyPy.LOCATION FindPython.PyPy.VERSION
+ APPEND PROPERTY LABELS Python2 Python3)
endif()
diff --git a/Tests/FindPython/CustomFailureMessage/CMakeLists.txt b/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
index 283aeec..e0148f3 100644
--- a/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
+++ b/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
@@ -62,7 +62,7 @@ set_tests_properties(FindPython.CustomFailureMessage.Multiple PROPERTIES
PASS_REGULAR_EXPRESSION "Reason given by package:.+Interpreter: Cannot run the interpreter.+Development: Cannot find the library")
-if (CMake_TEST_FindPython_NumPy)
+if (CMake_TEST_FindPython3_NumPy)
add_test(NAME FindPython.CustomFailureMessage.NumPy COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
diff --git a/Tests/FindPython/IronPython3/CMakeLists.txt b/Tests/FindPython/IronPython3/CMakeLists.txt
new file mode 100644
index 0000000..b09097a
--- /dev/null
+++ b/Tests/FindPython/IronPython3/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(TestIronPython3 LANGUAGES NONE)
+
+set (Python3_FIND_IMPLEMENTATIONS "IronPython")
+
+find_package(Python3 COMPONENTS Interpreter Compiler)
+if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Failed to find Python 3")
+endif()
+
+if (NOT Python3_Interpreter_FOUND)
+ message (FATAL_ERROR "Failed to find Python 3 Interpreter")
+endif()
+if (NOT Python3_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python3_INTERPRETER_ID})")
+endif()
+
+if (NOT Python3_Compiler_FOUND)
+ message (FATAL_ERROR "Failed to find Python 3 Compiler")
+endif()
+if (NOT Python3_COMPILER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous compiler ID (${Python3_COMPILER_ID})")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+ message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+if(NOT TARGET Python3::Compiler)
+ message(SEND_ERROR "Python3::Compiler not found")
+endif()
diff --git a/Tests/FindPython/MultiplePackages/CMakeLists.txt b/Tests/FindPython/MultiplePackages/CMakeLists.txt
index 4845035..352a2f6f 100644
--- a/Tests/FindPython/MultiplePackages/CMakeLists.txt
+++ b/Tests/FindPython/MultiplePackages/CMakeLists.txt
@@ -2,32 +2,44 @@ cmake_minimum_required(VERSION 3.5)
project(TestMultiplePackages C)
-find_package (Python2 REQUIRED COMPONENTS Interpreter Development)
-find_package (Python3 REQUIRED COMPONENTS Interpreter Development)
-
-# Must find Python 3
find_package (Python REQUIRED)
-if (NOT Python3_EXECUTABLE STREQUAL Python_EXECUTABLE)
- message (FATAL_ERROR
- "Python interpreters do not match:\n"
- " Python_EXECUTABLE='${Python_EXECUTABLE}'\n"
- " Python3_EXECUTABLE='${Python3_EXECUTABLE}'\n"
+if (CMake_TEST_FindPython2)
+ find_package (Python2 REQUIRED COMPONENTS Interpreter Development)
+
+ if (NOT CMake_TEST_FindPython3 AND NOT Python2_EXECUTABLE STREQUAL Python_EXECUTABLE)
+ message (FATAL_ERROR
+ "Python interpreters do not match:\n"
+ " Python_EXECUTABLE='${Python_EXECUTABLE}'\n"
+ " Python2_EXECUTABLE='${Python3_EXECUTABLE}'\n"
)
-endif()
+ endif()
+
+ Python2_add_library (spam2 MODULE ../spam.c)
+ target_compile_definitions (spam2 PRIVATE PYTHON2)
+ add_test (NAME python2_spam2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+ "${Python2_EXECUTABLE}" -c "import spam2; spam2.system(\"cd\")")
-Python2_add_library (spam2 MODULE ../spam.c)
-target_compile_definitions (spam2 PRIVATE PYTHON2)
+endif()
+
+if (CMake_TEST_FindPython3)
+ find_package (Python3 REQUIRED COMPONENTS Interpreter Development)
-Python3_add_library (spam3 MODULE ../spam.c)
-target_compile_definitions (spam3 PRIVATE PYTHON3)
+ if (NOT Python3_EXECUTABLE STREQUAL Python_EXECUTABLE)
+ message (FATAL_ERROR
+ "Python interpreters do not match:\n"
+ " Python_EXECUTABLE='${Python_EXECUTABLE}'\n"
+ " Python3_EXECUTABLE='${Python3_EXECUTABLE}'\n"
+ )
+ endif()
+ Python3_add_library (spam3 MODULE ../spam.c)
+ target_compile_definitions (spam3 PRIVATE PYTHON3)
-add_test (NAME python2_spam2
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
- "${Python2_EXECUTABLE}" -c "import spam2; spam2.system(\"cd\")")
+ add_test (NAME python3_spam3
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+ "${Python3_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
-add_test (NAME python3_spam3
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
- "${Python3_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
+endif()
diff --git a/Tests/FindPython/NumPy/CMakeLists.txt b/Tests/FindPython/NumPy/CMakeLists.txt
index 9920336..336bb83 100644
--- a/Tests/FindPython/NumPy/CMakeLists.txt
+++ b/Tests/FindPython/NumPy/CMakeLists.txt
@@ -2,21 +2,30 @@ cmake_minimum_required(VERSION 3.5)
project(TestNumPy LANGUAGES C)
-find_package (Python2 REQUIRED COMPONENTS Interpreter Development NumPy)
-find_package (Python3 REQUIRED COMPONENTS Interpreter Development NumPy)
+if(CMake_TEST_FindPython2_NumPy)
-Python2_add_library (arraytest2 MODULE arraytest.c)
-target_compile_definitions (arraytest2 PRIVATE PYTHON2)
-target_link_libraries (arraytest2 PRIVATE Python2::NumPy)
+ find_package (Python2 REQUIRED COMPONENTS Interpreter Development NumPy)
-Python3_add_library (arraytest3 MODULE arraytest.c)
-target_compile_definitions (arraytest3 PRIVATE PYTHON3)
-target_link_libraries (arraytest3 PRIVATE Python3::NumPy)
+ Python2_add_library (arraytest2 MODULE arraytest.c)
+ target_compile_definitions (arraytest2 PRIVATE PYTHON2)
+ target_link_libraries (arraytest2 PRIVATE Python2::NumPy)
-add_test (NAME python2_arraytest
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:arraytest2>"
- "${Python2_EXECUTABLE}" -c "import numpy; import arraytest2; arraytest2.vecsq(numpy.array([1, 2, 3]));")
+ add_test (NAME python2_arraytest
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:arraytest2>"
+ "${Python2_EXECUTABLE}" -c "import numpy; import arraytest2; arraytest2.vecsq(numpy.array([1, 2, 3]));")
-add_test (NAME python3_arraytest
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:arraytest3>"
- "${Python3_EXECUTABLE}" -c "import numpy; import arraytest3; arraytest3.vecsq(numpy.array([1, 2, 3]));")
+endif()
+
+if(CMake_TEST_FindPython3_NumPy)
+
+ find_package (Python3 REQUIRED COMPONENTS Interpreter Development NumPy)
+
+ Python3_add_library (arraytest3 MODULE arraytest.c)
+ target_compile_definitions (arraytest3 PRIVATE PYTHON3)
+ target_link_libraries (arraytest3 PRIVATE Python3::NumPy)
+
+ add_test (NAME python3_arraytest
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:arraytest3>"
+ "${Python3_EXECUTABLE}" -c "import numpy; import arraytest3; arraytest3.vecsq(numpy.array([1, 2, 3]));")
+
+endif()
diff --git a/Tests/FindPython/NumPyOnly/CMakeLists.txt b/Tests/FindPython/NumPyOnly/CMakeLists.txt
index 9aa1bcf..115cf2b 100644
--- a/Tests/FindPython/NumPyOnly/CMakeLists.txt
+++ b/Tests/FindPython/NumPyOnly/CMakeLists.txt
@@ -2,13 +2,23 @@ cmake_minimum_required(VERSION 3.5)
project(TestNumPyOnly LANGUAGES C)
-find_package(Python2 REQUIRED COMPONENTS NumPy)
-find_package(Python3 REQUIRED COMPONENTS NumPy)
+if(CMake_TEST_FindPython2_NumPy)
+
+ find_package(Python2 REQUIRED COMPONENTS NumPy)
+
+ Python2_add_library (arraytest2 MODULE ../NumPy/arraytest.c)
+ target_compile_definitions (arraytest2 PRIVATE PYTHON2)
+ target_link_libraries (arraytest2 PRIVATE Python2::NumPy)
+
+endif()
-Python2_add_library (arraytest2 MODULE ../NumPy/arraytest.c)
-target_compile_definitions (arraytest2 PRIVATE PYTHON2)
-target_link_libraries (arraytest2 PRIVATE Python2::NumPy)
+
+if(CMake_TEST_FindPython3_NumPy)
+
+find_package(Python3 REQUIRED COMPONENTS NumPy)
Python3_add_library (arraytest3 MODULE ../NumPy/arraytest.c)
target_compile_definitions (arraytest3 PRIVATE PYTHON3)
target_link_libraries (arraytest3 PRIVATE Python3::NumPy)
+
+endif()
diff --git a/Tests/FindPython/RequiredArtifacts/CMakeLists.txt b/Tests/FindPython/RequiredArtifacts/CMakeLists.txt
index cb9d4d3..eec28a5 100644
--- a/Tests/FindPython/RequiredArtifacts/CMakeLists.txt
+++ b/Tests/FindPython/RequiredArtifacts/CMakeLists.txt
@@ -4,13 +4,20 @@ project(TestRequiredArtifacts LANGUAGES C)
include(CTest)
-find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
-if (NOT Python2_FOUND)
- message (FATAL_ERROR "Failed to find Python 2")
+if(CMake_TEST_FindPython2)
+ find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+ if (NOT Python2_FOUND)
+ message (FATAL_ERROR "Failed to find Python 2")
+ endif()
+ set(USER_LIBRARY "${Python2_LIBRARY_RELEASE}")
+ set(USER_INCLUDE_DIR "${Python2_INCLUDE_DIRS}")
+else()
+ set(USER_LIBRARY "/path/to/invalid${CMAKE_C_LINK_LIBRARY_SUFFIX}")
+ set(USER_INCLUDE_DIR "/path/to/invalid/dir")
endif()
set(components Interpreter Development)
-if (CMake_TEST_FindPython_SABIModule AND WIN32)
+if (CMake_TEST_FindPython3_SABIModule AND WIN32)
list (APPEND components Development.SABIModule)
endif()
find_package(Python3 REQUIRED COMPONENTS ${components})
@@ -61,7 +68,7 @@ add_test(NAME FindPython.RequiredArtifacts.Library.INVALID COMMAND
${build_generator_args}
--build-project TestRequiredArtifacts.Check
--build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_LIBRARY=ON
- "-DPython3_LIBRARY=${Python2_LIBRARY_RELEASE}"
+ "-DPython3_LIBRARY=${USER_LIBRARY}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -84,7 +91,7 @@ add_test(NAME FindPython.RequiredArtifacts.Include.INVALID COMMAND
${build_generator_args}
--build-project TestRequiredArtifacts.Check
--build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_INCLUDE=ON
- "-DPython3_INCLUDE_DIR=${Python2_INCLUDE_DIRS}"
+ "-DPython3_INCLUDE_DIR=${USER_INCLUDE_DIR}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -97,7 +104,7 @@ add_test(NAME FindPython.RequiredArtifacts.Interpreter-Library.INVALID COMMAND
--build-project TestRequiredArtifacts.Check
--build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_INTERPRETER=ON -DCHECK_LIBRARY=ON
"-DPython3_EXECUTABLE=${Python3_EXECUTABLE}"
- "-DPython3_LIBRARY=${Python2_LIBRARY_RELEASE}"
+ "-DPython3_LIBRARY=${USER_LIBRARY}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -110,11 +117,11 @@ add_test(NAME FindPython.RequiredArtifacts.Library-Include.INVALID COMMAND
--build-project TestRequiredArtifacts.Check
--build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_LIBRARY=ON -DCHECK_INCLUDE=ON
"-DPython3_LIBRARY=${Python3_LIBRARY_RELEASE}"
- "-DPython3_INCLUDE_DIR=${Python2_INCLUDE_DIRS}"
+ "-DPython3_INCLUDE_DIR=${USER_INCLUDE_DIR}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
-if (CMake_TEST_FindPython_SABIModule AND WIN32)
+if (CMake_TEST_FindPython3_SABIModule AND WIN32)
add_test(NAME FindPython.RequiredArtifacts.SABILibrary.VALID COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -134,7 +141,7 @@ if (CMake_TEST_FindPython_SABIModule AND WIN32)
${build_generator_args}
--build-project TestRequiredArtifacts.Check
--build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_SABI_LIBRARY=ON
- "-DPython3_SABI_LIBRARY=${Python2_LIBRARY_RELEASE}"
+ "-DPython3_SABI_LIBRARY=${USER_LIBRARY}"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
endif()
diff --git a/Tests/FindPython/SOABI/CMakeLists.txt b/Tests/FindPython/SOABI/CMakeLists.txt
index 60399d3..6c0e9a9 100644
--- a/Tests/FindPython/SOABI/CMakeLists.txt
+++ b/Tests/FindPython/SOABI/CMakeLists.txt
@@ -2,37 +2,40 @@ cmake_minimum_required(VERSION 3.5)
project(TestSOABI LANGUAGES C)
-find_package(Python3 COMPONENTS ${CMake_TEST_FindPython_COMPONENT})
-if (NOT Python3_FOUND)
- message (FATAL_ERROR "Failed to find Python 3")
-endif()
+if(CMake_TEST_FindPython3)
+ find_package(Python3 COMPONENTS ${CMake_TEST_FindPython_COMPONENT})
+ if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Failed to find Python 3")
+ endif()
-if(NOT DEFINED Python3_SOABI)
- message(FATAL_ERROR "Python3_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found")
-endif()
+ if(NOT DEFINED Python3_SOABI)
+ message(FATAL_ERROR "Python3_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found")
+ endif()
-if (Python3_Development_FOUND AND Python3_SOABI)
- Python3_add_library (spam3 MODULE WITH_SOABI ../spam.c)
- target_compile_definitions (spam3 PRIVATE PYTHON3)
+ if (Python3_Development_FOUND AND Python3_SOABI)
+ Python3_add_library (spam3 MODULE WITH_SOABI ../spam.c)
+ target_compile_definitions (spam3 PRIVATE PYTHON3)
- get_property (suffix TARGET spam3 PROPERTY SUFFIX)
- if (NOT suffix MATCHES "^.${Python3_SOABI}")
- message(FATAL_ERROR "Module suffix do not include Python3_SOABI")
+ get_property (suffix TARGET spam3 PROPERTY SUFFIX)
+ if (NOT suffix MATCHES "^.${Python3_SOABI}")
+ message(FATAL_ERROR "Module suffix do not include Python3_SOABI")
+ endif()
endif()
endif()
+if(CMake_TEST_FindPython2)
+ find_package(Python2 COMPONENTS ${CMake_TEST_FindPython_COMPONENT})
+ if(NOT DEFINED Python2_SOABI)
+ message(FATAL_ERROR "Python2_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found")
+ endif()
-find_package(Python2 COMPONENTS ${CMake_TEST_FindPython_COMPONENT})
-if(NOT DEFINED Python2_SOABI)
- message(FATAL_ERROR "Python2_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found")
-endif()
-
-if (Python2_Development_FOUND AND Python2_SOABI)
- Python2_add_library (spam2 MODULE WITH_SOABI ../spam.c)
- target_compile_definitions (spam2 PRIVATE PYTHON2)
+ if (Python2_Development_FOUND AND Python2_SOABI)
+ Python2_add_library (spam2 MODULE WITH_SOABI ../spam.c)
+ target_compile_definitions (spam2 PRIVATE PYTHON2)
- get_property (suffix TARGET spam2 PROPERTY SUFFIX)
- if (NOT suffix MATCHES "^.${Python2_SOABI}")
- message(FATAL_ERROR "Module suffix do not include Python2_SOABI")
+ get_property (suffix TARGET spam2 PROPERTY SUFFIX)
+ if (NOT suffix MATCHES "^.${Python2_SOABI}")
+ message(FATAL_ERROR "Module suffix do not include Python2_SOABI")
+ endif()
endif()
endif()
diff --git a/Tests/FindPython/VirtualEnv/CMakeLists.txt b/Tests/FindPython/VirtualEnv/CMakeLists.txt
index e2e5bd2..ea742ea 100644
--- a/Tests/FindPython/VirtualEnv/CMakeLists.txt
+++ b/Tests/FindPython/VirtualEnv/CMakeLists.txt
@@ -27,21 +27,23 @@ add_test(NAME FindPython3.VirtualEnvDefault
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvDefault.cmake")
-add_test(NAME FindPython3.VirtualEnvOnly
- COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
- --unset=CONDA_PREFIX
- "VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
- "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
- -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
-add_test(NAME FindPython3.UnsetVirtualEnvOnly
- COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
- --unset=VIRTUAL_ENV
- --unset=CONDA_PREFIX
- "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
-
add_test(NAME FindPython3.VirtualEnvStandard
COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
--unset=CONDA_PREFIX
"VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvStandard.cmake")
+
+if(CMake_TEST_FindPython2)
+ add_test(NAME FindPython3.VirtualEnvOnly
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=CONDA_PREFIX
+ "VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
+ "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
+ add_test(NAME FindPython3.UnsetVirtualEnvOnly
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=VIRTUAL_ENV
+ --unset=CONDA_PREFIX
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
+endif()
diff --git a/Tests/FindPython/VirtualEnvConda/CMakeLists.txt b/Tests/FindPython/VirtualEnvConda/CMakeLists.txt
index 2f7c0db..3a64c31 100644
--- a/Tests/FindPython/VirtualEnvConda/CMakeLists.txt
+++ b/Tests/FindPython/VirtualEnvConda/CMakeLists.txt
@@ -26,21 +26,23 @@ add_test(NAME FindPython3.VirtualEnvDefaultConda
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvDefault.cmake")
-add_test(NAME FindPython3.VirtualEnvOnlyConda
- COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
- --unset=VIRTUAL_ENV
- "CONDA_PREFIX=${Python3_VIRTUAL_ENV}"
- "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
- -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
-add_test(NAME FindPython3.UnsetVirtualEnvOnlyConda
- COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
- --unset=CONDA_PREFIX
- --unset=VIRTUAL_ENV
- "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
-
add_test(NAME FindPython3.VirtualEnvStandardConda
COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
--unset=VIRTUAL_ENV
"CONDA_PREFIX=${Python3_VIRTUAL_ENV}"
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvStandard.cmake")
+
+if(Cmake_TEST_FindPython2)
+ add_test(NAME FindPython3.VirtualEnvOnlyConda
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=VIRTUAL_ENV
+ "CONDA_PREFIX=${Python3_VIRTUAL_ENV}"
+ "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
+ add_test(NAME FindPython3.UnsetVirtualEnvOnlyConda
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=CONDA_PREFIX
+ --unset=VIRTUAL_ENV
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
+endif()
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index ef115e6..df7cda0 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -214,6 +214,22 @@ set_property(TARGET importedFallback2 PROPERTY IMPORTED_IMPLIB_SPECIAL special_i
set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_NOCONFIG SPECIAL "")
set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_DEBUG SPECIAL "")
set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_RELEASE SPECIAL "")
+set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_RELWITHDEBINFO SPECIAL "")
+
+add_library(importedFallback3 SHARED IMPORTED)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_LOCATION_DEBUG debug_loc)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_LOCATION_RELEASE release_loc)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_LOCATION fallback_loc)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_IMPLIB imp_loc)
+set_property(TARGET importedFallback3 PROPERTY MAP_IMPORTED_CONFIG_DEBUG "" DEBUG)
+set_property(TARGET importedFallback3 PROPERTY MAP_IMPORTED_CONFIG_RELEASE "")
+
+add_library(importedFallback4 SHARED IMPORTED)
+set_property(TARGET importedFallback4 PROPERTY IMPORTED_LOCATION fallback_loc)
+set_property(TARGET importedFallback4 PROPERTY IMPORTED_IMPLIB imp_loc)
+
+add_library(importedFallback5 SHARED IMPORTED)
+set_property(TARGET importedFallback5 PROPERTY IMPORTED_IMPLIB imp_loc)
add_library(importedFallback_genex STATIC IMPORTED)
set_property(TARGET importedFallback_genex PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
@@ -232,7 +248,10 @@ add_custom_target(check-part3 ALL
-Dconfig=$<CONFIGURATION>
-Dtest_imported_includes=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
-Dtest_imported_fallback=$<STREQUAL:$<TARGET_FILE_NAME:importedFallback>,fallback_loc>
- -Dtest_imported_fallback2=$<IF:$<OR:$<PLATFORM_ID:Windows,CYGWIN,MSYS>,$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${CMAKE_TAPI}>>>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback2>,special_imp>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback2>,fallback_loc>>
+ -Dtest_imported_fallback2=$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback2>,special_imp>
+ -Dtest_imported_fallback3=$<IF:$<PLATFORM_ID:Windows,CYGWIN,MSYS>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback3>,imp_loc>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback3>,fallback_loc>>
+ -Dtest_imported_fallback4=$<IF:$<PLATFORM_ID:Windows,CYGWIN,MSYS>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback4>,imp_loc>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback4>,fallback_loc>>
+ -Dtest_imported_fallback5=$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback5>,imp_loc>
-Dtest_imported_fallback_genex=$<STREQUAL:$<TARGET_PROPERTY:importedFallback_genex,INTERFACE_COMPILE_DEFINITIONS>,FOOBAR=1>
-Dtest_alias_file_exe=$<STREQUAL:$<TARGET_FILE:Alias::SomeExe>,$<TARGET_FILE:someexe>>
-Dtest_alias_file_lib=$<STREQUAL:$<TARGET_FILE:Alias::SomeLib>,$<TARGET_FILE:empty1>>
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index 7bb0d85..eda3bc1 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -20,6 +20,9 @@ endif()
check(test_imported_fallback "1")
check(test_imported_fallback2 "1")
+check(test_imported_fallback3 "1")
+check(test_imported_fallback4 "1")
+check(test_imported_fallback5 "1")
check(test_imported_fallback_genex "1")
check(test_alias_file_exe "1")
diff --git a/Tests/RunCMake/BuildDepends/FortranInclude.cmake b/Tests/RunCMake/BuildDepends/FortranInclude.cmake
index fa9f399..ad5fd0a 100644
--- a/Tests/RunCMake/BuildDepends/FortranInclude.cmake
+++ b/Tests/RunCMake/BuildDepends/FortranInclude.cmake
@@ -1,5 +1,10 @@
enable_language(Fortran)
+if("${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "^Intel(LLVM)?;MSVC$")
+ string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -Z7")
+ string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO " -Z7")
+endif()
+
set(check_pairs "")
add_executable(preprocess FortranIncludePreprocess.F)
diff --git a/Tests/RunCMake/CMP0111/CMP0111-Common.cmake b/Tests/RunCMake/CMP0111/CMP0111-Common.cmake
index c31e4ba..ab9e405 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-Common.cmake
+++ b/Tests/RunCMake/CMP0111/CMP0111-Common.cmake
@@ -1,6 +1,3 @@
-# Prevent duplicate errors on some platforms.
-set(CMAKE_IMPORT_LIBRARY_SUFFIX "placeholder")
-
add_library(unknown_lib UNKNOWN IMPORTED)
add_library(static_lib STATIC IMPORTED)
add_library(shared_lib SHARED IMPORTED)
diff --git a/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt b/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt
index 91a90e5..c6439e2 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt
+++ b/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt
@@ -1,17 +1,6 @@
-^CMake Error in CMakeLists.txt:
- IMPORTED_LOCATION not set for imported target "unknown_lib"( configuration
+^(CMake Error in CMakeLists.txt:
+ IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static)_lib"( configuration
"[^"]+")?.
-+
-CMake Error in CMakeLists.txt:
- IMPORTED_LOCATION not set for imported target "static_lib"( configuration
- "[^"]+")?.
-+
-CMake Error in CMakeLists.txt:
- IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
- "[^"]+")?.(
-+
-CMake Error in CMakeLists.txt:
- IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
- "[^"]+")?.)*
-+
+)+
+.*(IMPORTED_LOCATION or )?IMPORTED_IMPLIB not set for imported target.*"shared_lib".*
CMake Generate step failed. Build files cannot be regenerated correctly.$
diff --git a/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt b/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
index 27af911..7a46c41 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
@@ -1,39 +1,19 @@
-^CMake Warning \(dev\) in CMakeLists.txt:
+^(CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
- IMPORTED_LOCATION not set for imported target "unknown_lib"( configuration
+ IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static)_lib"( configuration
"[^"]+")?.
This warning is for project developers. Use -Wno-dev to suppress it.
-+
-CMake Warning \(dev\) in CMakeLists.txt:
++)+CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
- IMPORTED_LOCATION not set for imported target "static_lib"( configuration
+ IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static)_lib"( configuration
"[^"]+")?.
-This warning is for project developers. Use -Wno-dev to suppress it.
-+
-CMake Warning \(dev\) in CMakeLists.txt:
- Policy CMP0111 is not set: An imported target missing its location property
- fails during generation. Run "cmake --help-policy CMP0111" for policy
- details. Use the cmake_policy command to set the policy and suppress this
- warning.
-
- IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
- "[^"]+")?.
-This warning is for project developers. Use -Wno-dev to suppress it.(
-+
-CMake Warning \(dev\) in CMakeLists.txt:
- Policy CMP0111 is not set: An imported target missing its location property
- fails during generation. Run "cmake --help-policy CMP0111" for policy
- details. Use the cmake_policy command to set the policy and suppress this
- warning.
-
- IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
- "[^"]+")?.
-This warning is for project developers. Use -Wno-dev to suppress it.)*$
+.*(IMPORTED_LOCATION or )?IMPORTED_IMPLIB not set for imported target.*"shared_lib".*
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
index 67d00f7..3472f33 100644
--- a/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
@@ -1,4 +1,13 @@
-^CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+^CMake Deprecation Warning at CMakeLists\.txt:[0-9]+ \(cmake_minimum_required\):
+ The OLD behavior for policy CMP0115 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
++
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
Cannot find source file:
noexist
diff --git a/Tests/RunCMake/CMP0116/CMP0116-Mixed-stderr.txt b/Tests/RunCMake/CMP0116/CMP0116-Mixed-stderr.txt
index 10e83a9..930dd3c 100644
--- a/Tests/RunCMake/CMP0116/CMP0116-Mixed-stderr.txt
+++ b/Tests/RunCMake/CMP0116/CMP0116-Mixed-stderr.txt
@@ -1,4 +1,15 @@
-^CMake Warning \(dev\) at CMP0116-Mixed\.cmake:1 \(add_custom_command\):
+^CMake Deprecation Warning at CMP0116-Mixed\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0116 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Warning \(dev\) at CMP0116-Mixed\.cmake:1 \(add_custom_command\):
Policy CMP0116 is not set: Ninja generators transform DEPFILEs from
add_custom_command\(\)\. Run "cmake --help-policy CMP0116" for policy
details\. Use the cmake_policy command to set the policy and suppress this
diff --git a/Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN-stderr.txt b/Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN-stderr.txt
new file mode 100644
index 0000000..887601c
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Deprecation Warning at CMakeLists\.txt:[0-9]+ \(cmake_minimum_required\):
+ The OLD behavior for policy CMP0116 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.$
diff --git a/Tests/RunCMake/CMP0116/CMP0116-OLD-WARN-stderr.txt b/Tests/RunCMake/CMP0116/CMP0116-OLD-WARN-stderr.txt
new file mode 100644
index 0000000..887601c
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-OLD-WARN-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Deprecation Warning at CMakeLists\.txt:[0-9]+ \(cmake_minimum_required\):
+ The OLD behavior for policy CMP0116 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.$
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test1-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test1-stderr.txt
index 2af72a4..9285f9d 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test1-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test1-stderr.txt
@@ -1,4 +1,15 @@
-^prop: `0`
+^CMake Deprecation Warning at CMP0118-OLD-Test1\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+prop: `0`
CMake Error at CMP0118-Common-Test1\.cmake:[0-9]+ \(target_sources\):
Cannot find source file:
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test10-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test10-stderr.txt
index 6109f65..9bd3d33 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test10-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test10-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source0\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test10\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source0\.txt: # 1a # GENERATED = `1`
Generated_source0\.txt: # 1b # GENERATED = `1`
Generated_source0\.txt: # 2a # GENERATED = `1`
Generated_source0\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test11-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test11-stderr.txt
index e5e97de..4730caf 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test11-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test11-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source0\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test11\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source0\.txt: # 1a # GENERATED = `1`
Generated_source0\.txt: # 1b # GENERATED = `1`
Generated_source0\.txt: # 2a # GENERATED = `1`
Generated_source0\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test12-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test12-stderr.txt
index e6c429c..69a07e1 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test12-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test12-stderr.txt
@@ -1,4 +1,15 @@
-^CMake Error at subdir-Common-Test12/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
+^CMake Deprecation Warning at CMP0118-OLD-Test12\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at subdir-Common-Test12/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
TARGET 'custom[4-6]' was not created in this directory\.
+
CMake Error at subdir-Common-Test12/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test13-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test13-stderr.txt
index 75dbf23..45c1dcb 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test13-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test13-stderr.txt
@@ -1,4 +1,15 @@
-^CMake Error at subdir-Common-Test13/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
+^CMake Deprecation Warning at CMP0118-OLD-Test13\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at subdir-Common-Test13/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
TARGET 'custom[4-6]' was not created in this directory\.
+
CMake Error at subdir-Common-Test13/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test14-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test14-stderr.txt
index f5b3d1a..7ade0cf 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test14-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test14-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source0\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test14\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source0\.txt: # 1a # GENERATED = `1`
Generated_source0\.txt: # 1b # GENERATED = `1`
Generated_source0\.txt: # 2a # GENERATED = `1`
Generated_source0\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test15-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test15-stderr.txt
index a30bc84..5735539 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test15-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test15-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source0\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test15\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source0\.txt: # 1a # GENERATED = `1`
Generated_source0\.txt: # 1b # GENERATED = `1`
Generated_source0\.txt: # 2a # GENERATED = `1`
Generated_source0\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test2-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test2-stderr.txt
index 403ce5a..74eb3e1 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test2-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test2-stderr.txt
@@ -1 +1,12 @@
-^prop: `1`$
+^CMake Deprecation Warning at CMP0118-OLD-Test2\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+prop: `1`$
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3-stderr.txt
index 4f4fea3..cce5b19 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_with_full_path1\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test3\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_with_full_path1\.txt: # 1a # GENERATED = `1`
Generated_with_full_path1\.txt: # 1b # GENERATED = `1`
Generated_with_full_path1\.txt: # 2a # GENERATED = `1`
Generated_with_full_path1\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3b-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3b-stderr.txt
index 3c80531..47eee2e 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3b-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test3b-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_with_full_path1\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test3b\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_with_full_path1\.txt: # 1a # GENERATED = `1`
Generated_with_full_path1\.txt: # 1b # GENERATED = `1`
Generated_with_full_path1\.txt: # 2a # GENERATED = `1`
Generated_with_full_path1\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4-stderr.txt
index 9600fee..f17c9be 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_with_full_path1\.txt: # 1a # GENERATED = `0`
+^CMake Deprecation Warning at CMP0118-OLD-Test4\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_with_full_path1\.txt: # 1a # GENERATED = `0`
Generated_with_full_path1\.txt: # 1b # GENERATED = `0`
Generated_with_full_path1\.txt: # 2a # GENERATED = `0`
Generated_with_full_path1\.txt: # 2b # GENERATED = `0`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4b-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4b-stderr.txt
index e638660..388e90e 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4b-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test4b-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_with_full_path1\.txt: # 1a # GENERATED = `0`
+^CMake Deprecation Warning at CMP0118-OLD-Test4b\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_with_full_path1\.txt: # 1a # GENERATED = `0`
Generated_with_full_path1\.txt: # 1b # GENERATED = `0`
Generated_with_full_path1\.txt: # 2a # GENERATED = `0`
Generated_with_full_path1\.txt: # 2b # GENERATED = `0`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test5-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test5-stderr.txt
index 18e6a8c..4a67fa7 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test5-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test5-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_with_full_path1\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test5\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_with_full_path1\.txt: # 1a # GENERATED = `1`
Generated_with_full_path1\.txt: # 1b # GENERATED = `1`
Generated_with_full_path1\.txt: # 2a # GENERATED = `1`
Generated_with_full_path1\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test6-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test6-stderr.txt
index a60545f..0cad373 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test6-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test6-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source1\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test6\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source1\.txt: # 1a # GENERATED = `1`
Generated_source1\.txt: # 1b # GENERATED = `1`
Generated_source1\.txt: # 2a # GENERATED = `1`
Generated_source1\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test7-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test7-stderr.txt
index fd496cb..7f232d5 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test7-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test7-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source1\.txt: # 1a # GENERATED = `1`
+^CMake Deprecation Warning at CMP0118-OLD-Test7\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source1\.txt: # 1a # GENERATED = `1`
Generated_source1\.txt: # 1b # GENERATED = `1`
Generated_source1\.txt: # 2a # GENERATED = `1`
Generated_source1\.txt: # 2b # GENERATED = `1`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test8-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test8-stderr.txt
index 3505242..dd9d2ef 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test8-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test8-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source1\.txt: # 1a # GENERATED = `0`
+^CMake Deprecation Warning at CMP0118-OLD-Test8\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source1\.txt: # 1a # GENERATED = `0`
Generated_source1\.txt: # 1b # GENERATED = `0`
Generated_source1\.txt: # 2a # GENERATED = `0`
Generated_source1\.txt: # 2b # GENERATED = `0`
diff --git a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test9-stderr.txt b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test9-stderr.txt
index 63a9341..e01f782 100644
--- a/Tests/RunCMake/CMP0118/CMP0118-OLD-Test9-stderr.txt
+++ b/Tests/RunCMake/CMP0118/CMP0118-OLD-Test9-stderr.txt
@@ -1,4 +1,15 @@
-^Generated_source1\.txt: # 1a # GENERATED = `0`
+^CMake Deprecation Warning at CMP0118-OLD-Test9\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+Generated_source1\.txt: # 1a # GENERATED = `0`
Generated_source1\.txt: # 1b # GENERATED = `0`
Generated_source1\.txt: # 2a # GENERATED = `0`
Generated_source1\.txt: # 2b # GENERATED = `0`
diff --git a/Tests/RunCMake/CMP0118/GenInSubdir-OLD-stderr.txt b/Tests/RunCMake/CMP0118/GenInSubdir-OLD-stderr.txt
index 5e9cf6c..2fc472b 100644
--- a/Tests/RunCMake/CMP0118/GenInSubdir-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0118/GenInSubdir-OLD-stderr.txt
@@ -1,4 +1,15 @@
-^CMake Error at GenInSubdir/CMakeLists\.txt:[0-9]+ \(target_sources\):
+^CMake Deprecation Warning at GenInSubdir-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0118 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at GenInSubdir/CMakeLists\.txt:[0-9]+ \(target_sources\):
Cannot find source file:
[^
diff --git a/Tests/RunCMake/CMP0119/CMP0119-OLD-stderr.txt b/Tests/RunCMake/CMP0119/CMP0119-OLD-stderr.txt
new file mode 100644
index 0000000..86eac41
--- /dev/null
+++ b/Tests/RunCMake/CMP0119/CMP0119-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0119-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0119 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0152/CMP0152-Common.cmake b/Tests/RunCMake/CMP0152/CMP0152-Common.cmake
new file mode 100644
index 0000000..6429cca
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-Common.cmake
@@ -0,0 +1,5 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin/")
+file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin" "${CMAKE_CURRENT_BINARY_DIR}/dir/bin" SYMBOLIC)
+file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../" real_path)
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-OFF.cmake b/Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt
index e69de29..e69de29 100644
--- a/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-OFF.cmake
+++ b/Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt
diff --git a/Tests/RunCMake/CMP0152/CMP0152-NEW.cmake b/Tests/RunCMake/CMP0152/CMP0152-NEW.cmake
new file mode 100644
index 0000000..86a3b55
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0152 NEW)
+include(CMP0152-Common.cmake)
diff --git a/Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt b/Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt
diff --git a/Tests/RunCMake/CMP0152/CMP0152-OLD.cmake b/Tests/RunCMake/CMP0152/CMP0152-OLD.cmake
new file mode 100644
index 0000000..62ac300
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0152 OLD)
+include(CMP0152-Common.cmake)
diff --git a/Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt b/Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt
new file mode 100644
index 0000000..8d63168
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt
@@ -0,0 +1,27 @@
+^CMake Warning \(dev\) at CMP0152-Common\.cmake:[0-9]+ \(file\):
+ Policy CMP0152 is not set: file\(REAL_PATH\) resolves symlinks before
+ collapsing \.\./ components\. Run "cmake --help-policy CMP0152" for policy
+ details\. Use the cmake_policy command to set the policy and suppress this
+ warning\.
+
+ From input path:
+
+ [^
+]*/Tests/RunCMake/CMP0152/CMP0152-WARN-build/dir/bin/\.\./
+
+ the policy OLD behavior produces path:
+
+ [^
+]*/Tests/RunCMake/CMP0152/CMP0152-WARN-build/dir
+
+ but the policy NEW behavior produces path:
+
+ [^
+]*/Tests/RunCMake/CMP0152/CMP0152-WARN-build/dir/nested
+
+ Since the policy is not set, CMake is using the OLD behavior for
+ compatibility.
+Call Stack \(most recent call first\):
+ CMP0152-WARN\.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/CMP0152/CMP0152-WARN.cmake b/Tests/RunCMake/CMP0152/CMP0152-WARN.cmake
new file mode 100644
index 0000000..e85589e
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-WARN.cmake
@@ -0,0 +1,2 @@
+
+include(CMP0152-Common.cmake)
diff --git a/Tests/RunCMake/CMP0152/CMakeLists.txt b/Tests/RunCMake/CMP0152/CMakeLists.txt
new file mode 100644
index 0000000..5ff8d3e
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0152/RunCMakeTest.cmake b/Tests/RunCMake/CMP0152/RunCMakeTest.cmake
new file mode 100644
index 0000000..7a9bab3
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+if(NOT CMAKE_GENERATOR_NO_COMPILER_ENV)
+ run_cmake(CMP0152-WARN)
+ run_cmake(CMP0152-OLD)
+ run_cmake(CMP0152-NEW)
+endif()
diff --git a/Tests/RunCMake/CMP0153/CMP0153-NEW-result.txt b/Tests/RunCMake/CMP0153/CMP0153-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0153/CMP0153-NEW-stderr.txt b/Tests/RunCMake/CMP0153/CMP0153-NEW-stderr.txt
new file mode 100644
index 0000000..e24eee7
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-NEW-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error at [^
+]*/Tests/RunCMake/CMP0153/CMP0153-NEW\.cmake:[0-9]+ \(exec_program\):
+ The exec_program command should not be called; see CMP0153\.$
diff --git a/Tests/RunCMake/CMP0153/CMP0153-NEW-stdout.txt b/Tests/RunCMake/CMP0153/CMP0153-NEW-stdout.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-NEW-stdout.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/CMP0153/CMP0153-NEW.cmake b/Tests/RunCMake/CMP0153/CMP0153-NEW.cmake
new file mode 100644
index 0000000..d252b46
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0153 NEW)
+exec_program("${CMAKE_COMMAND}" ARGS "-E echo \"exec_program() called\"")
diff --git a/Tests/RunCMake/CMP0153/CMP0153-OLD-stdout.txt b/Tests/RunCMake/CMP0153/CMP0153-OLD-stdout.txt
new file mode 100644
index 0000000..1aa5183
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-OLD-stdout.txt
@@ -0,0 +1 @@
+exec_program\(\) called
diff --git a/Tests/RunCMake/CMP0153/CMP0153-OLD.cmake b/Tests/RunCMake/CMP0153/CMP0153-OLD.cmake
new file mode 100644
index 0000000..d3c47a7
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0153 OLD)
+exec_program("${CMAKE_COMMAND}" ARGS "-E echo \"exec_program() called\"")
diff --git a/Tests/RunCMake/CMP0153/CMP0153-WARN-stderr.txt b/Tests/RunCMake/CMP0153/CMP0153-WARN-stderr.txt
new file mode 100644
index 0000000..8f22d4e
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-WARN-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Warning \(dev\) at [^
+]*/Tests/RunCMake/CMP0153/CMP0153-WARN\.cmake:[0-9]+ \(exec_program\):
+ Policy CMP0153 is not set: The exec_program command should not be called\.
+ Run "cmake --help-policy CMP0153" for policy details\. Use the cmake_policy
+ command to set the policy and suppress this warning\.
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/CMP0153/CMP0153-WARN-stdout.txt b/Tests/RunCMake/CMP0153/CMP0153-WARN-stdout.txt
new file mode 100644
index 0000000..1aa5183
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-WARN-stdout.txt
@@ -0,0 +1 @@
+exec_program\(\) called
diff --git a/Tests/RunCMake/CMP0153/CMP0153-WARN.cmake b/Tests/RunCMake/CMP0153/CMP0153-WARN.cmake
new file mode 100644
index 0000000..ba81501
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMP0153-WARN.cmake
@@ -0,0 +1 @@
+exec_program("${CMAKE_COMMAND}" ARGS "-E echo \"exec_program() called\"")
diff --git a/Tests/RunCMake/CMP0153/CMakeLists.txt b/Tests/RunCMake/CMP0153/CMakeLists.txt
new file mode 100644
index 0000000..922aad6
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.27)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0153/RunCMakeTest.cmake b/Tests/RunCMake/CMP0153/RunCMakeTest.cmake
new file mode 100644
index 0000000..3d01dbf
--- /dev/null
+++ b/Tests/RunCMake/CMP0153/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+function(run_cmp0153 name)
+ run_cmake_command(${name} ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/${name}.cmake")
+endfunction()
+
+run_cmp0153(CMP0153-WARN)
+run_cmp0153(CMP0153-OLD)
+run_cmp0153(CMP0153-NEW)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 63b7568..02efb25 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -165,14 +165,21 @@ if(GIT_EXECUTABLE)
add_RunCMake_test(CMP0150)
endif()
+if(NOT WIN32 OR CYGWIN)
+ add_RunCMake_test(CMP0152)
+endif()
+
+add_RunCMake_test(CMP0153)
+
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
# generators ignore. The policy will have no effect on those generators.
if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
add_RunCMake_test(CMP0065 -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
endif()
+add_executable(detect_jobserver detect_jobserver.c)
if(CMAKE_GENERATOR MATCHES "Make")
- add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU})
+ add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU} -DDETECT_JOBSERVER=$<TARGET_FILE:detect_jobserver>)
endif()
unset(ninja_test_with_qt_version)
unset(ninja_qt_args)
@@ -363,7 +370,8 @@ if(CMake_TEST_FindOpenSSL)
endif()
if(CMake_TEST_UseSWIG)
add_RunCMake_test(FindSWIG)
- add_RunCMake_test(UseSWIG -DCMake_TEST_FindPython=${CMake_TEST_FindPython})
+ add_RunCMake_test(UseSWIG -DCMake_TEST_FindPython2=${CMake_TEST_FindPython2}
+ -DCMake_TEST_FindPython3=${CMake_TEST_FindPython3})
endif()
if(NOT CMAKE_C_COMPILER_ID MATCHES "Watcom")
add_RunCMake_test(GenerateExportHeader)
@@ -458,6 +466,7 @@ add_RunCMake_test(build_command)
add_executable(exit_code exit_code.c)
set(execute_process_ARGS
-DEXIT_CODE_EXE=$<TARGET_FILE:exit_code>
+ -DPRINT_STDIN_EXE=$<TARGET_FILE:print_stdin>
-DPython_EXECUTABLE=${Python_EXECUTABLE}
)
if(NOT CMake_TEST_EXTERNAL_CMAKE)
@@ -465,6 +474,9 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
endif()
add_RunCMake_test(execute_process)
add_RunCMake_test(export)
+if(CMake_TEST_MSYSTEM_PREFIX)
+ list(APPEND cmake_host_system_information_ARGS -DCMake_TEST_MSYSTEM_PREFIX=${CMake_TEST_MSYSTEM_PREFIX})
+endif()
add_RunCMake_test(cmake_host_system_information)
add_RunCMake_test(cmake_language)
add_RunCMake_test(cmake_minimum_required)
@@ -528,6 +540,7 @@ add_RunCMake_test(option)
add_RunCMake_test(PrintHelpers)
add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES})
add_RunCMake_test(project_injected)
+add_RunCMake_test(property_init)
add_RunCMake_test(DependencyProviders)
add_RunCMake_test(return)
add_RunCMake_test(separate_arguments)
@@ -695,6 +708,23 @@ endif()
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
add_RunCMake_test(Framework)
+ if(NOT DEFINED CMake_TEST_XcFramework)
+ set(CMake_TEST_XcFramework ON)
+ endif()
+ if(CMake_TEST_XcFramework AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 11.0)
+ set(XcFramework_ARGS -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
+ add_RunCMake_test(XcFramework)
+
+ # This test can take a very long time due to lots of combinations.
+ # Use a long default timeout and provide an option to customize it.
+ if(NOT DEFINED CMake_TEST_XcFramework_TIMEOUT)
+ set(CMake_TEST_XcFramework_TIMEOUT 3000)
+ endif()
+ set_tests_properties(RunCMake.XcFramework PROPERTIES
+ TIMEOUT "${CMake_TEST_XcFramework_TIMEOUT}"
+ RUN_SERIAL TRUE
+ )
+ endif()
endif()
add_RunCMake_test(File_Archive)
@@ -825,7 +855,7 @@ endif()
if(CMake_TEST_RunCMake_ExternalProject_DOWNLOAD_SERVER_TIMEOUT)
list(APPEND ExternalProject_ARGS -DDOWNLOAD_SERVER_TIMEOUT=${CMake_TEST_RunCMake_ExternalProject_DOWNLOAD_SERVER_TIMEOUT})
endif()
-add_RunCMake_test(ExternalProject)
+add_RunCMake_test(ExternalProject -DDETECT_JOBSERVER=$<TARGET_FILE:detect_jobserver>)
add_RunCMake_test(FetchContent)
add_RunCMake_test(FetchContent_find_package)
set(CTestCommandLine_ARGS -DPython_EXECUTABLE=${Python_EXECUTABLE})
@@ -1038,6 +1068,7 @@ add_RunCMake_test(CMakePresetsWorkflow
)
add_RunCMake_test(VerifyHeaderSets)
+add_RunCMake_test(set_tests_properties)
if(${CMAKE_GENERATOR} MATCHES "Make|Ninja")
add_RunCMake_test(TransformDepfile)
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index c90d543..223a61c 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -472,7 +472,7 @@ add_test(test1 \"${CMAKE_COMMAND}\" -E false)
add_test(test2 \"${CMAKE_COMMAND}\" -E echo \"hello world\")
add_test(test3 \"${CMAKE_COMMAND}\" -E true)
set_tests_properties(test3 PROPERTIES DISABLED \"ON\")
-add_test(test4 \"${CMAKE_COMMAND}/doesnt_exist\")
+add_test(test4 \"${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist\")
add_test(test5 \"${CMAKE_COMMAND}\" -E echo \"please skip\")
set_tests_properties(test5 PROPERTIES SKIP_REGULAR_EXPRESSION \"please skip\")
")
diff --git a/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt b/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt
index ce30dc8..c57c378 100644
--- a/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt
+++ b/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt
@@ -1 +1,2 @@
-Unable to find executable: .*doesnt_exist
+Unable to find executable:[^
+]*does_not_exist
diff --git a/Tests/RunCMake/CTestResourceAllocation/CMakeLists.txt.in b/Tests/RunCMake/CTestResourceAllocation/CMakeLists.txt.in
index 9984421..7c08dcc 100644
--- a/Tests/RunCMake/CTestResourceAllocation/CMakeLists.txt.in
+++ b/Tests/RunCMake/CTestResourceAllocation/CMakeLists.txt.in
@@ -4,6 +4,8 @@ if(CASE_NAME MATCHES "^(.*)-ctest-s")
set(projname "${CMAKE_MATCH_1}")
project(${projname} NONE)
include(CTest)
- include("@RunCMake_SOURCE_DIR@/ResourceCommon.cmake")
+ if(NOT CASE_NAME MATCHES "^dynamic-resource-")
+ include("@RunCMake_SOURCE_DIR@/resource-common.cmake")
+ endif()
include("@RunCMake_SOURCE_DIR@/${projname}.cmake")
endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
index f5f0699..42e13fc 100644
--- a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
@@ -179,3 +179,19 @@ run_ctest_resource(ensure_parallel 2 0 0)
set(ENV{CTEST_RESOURCE_GROUP_COUNT} 2)
run_ctest_resource(process_count 1 0 0)
unset(ENV{CTEST_RESOURCE_GROUP_COUNT})
+
+function(run_ctest_resource_dynamic name)
+ run_ctest("${name}-ctest-s" ${ARGN})
+endfunction()
+
+run_ctest_resource_dynamic(dynamic-resource -VV)
+run_ctest_resource_dynamic(dynamic-resource-notenough)
+run_ctest_resource_dynamic(dynamic-resource-nofile)
+run_ctest_resource_dynamic(dynamic-resource-multiple-generators)
+run_ctest_resource_dynamic(dynamic-resource-no-setup-fixture)
+run_ctest_resource_dynamic(dynamic-resource-multiple-setup-fixtures)
+run_ctest_resource_dynamic(dynamic-resource-no-required-fixture)
+run_ctest_resource_dynamic(dynamic-resource-conflicting-spec -DCTEST_RESOURCE_SPEC_SOURCE=CACHE)
+run_ctest_resource_dynamic(dynamic-resource-circular)
+run_ctest_resource_dynamic(dynamic-resource-circular-no-required-fixtures)
+run_ctest_resource_dynamic(dynamic-resource-relative-path)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-stderr.txt
new file mode 100644
index 0000000..397ca38
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-ctest-s-stderr.txt
@@ -0,0 +1,3 @@
+^Error: a cycle exists in the test dependency graph for the test "GenerateSpecFile"\.
+Please fix the cycle and run ctest again.
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-stderr.txt
new file mode 100644
index 0000000..06ea90f
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^All tests that have RESOURCE_GROUPS must include the resource spec generator fixture in their FIXTURES_REQUIRED
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures.cmake
new file mode 100644
index 0000000..9accdf3
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular-no-required-fixtures.cmake
@@ -0,0 +1,11 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular.cmake
new file mode 100644
index 0000000..4917e30
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-circular.cmake
@@ -0,0 +1,12 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-stderr.txt
new file mode 100644
index 0000000..4e4c01c
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^GENERATED_RESOURCE_SPEC_FILE test property cannot be used in conjunction with ResourceSpecFile option
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec.cmake
new file mode 100644
index 0000000..668b049
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-conflicting-spec.cmake
@@ -0,0 +1,10 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-stdout.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-stdout.txt
new file mode 100644
index 0000000..ec97787
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-stdout.txt
@@ -0,0 +1,24 @@
+test 2
+ Start 2: GenerateSpecFile
+
+2: Test command: "?[^
+]*[\\/]bin([\\/][^\\/
+]+)?[\\/]cmake(\.exe)?"? "-E" "copy" "[^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resspec\.json" "[^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-build"
+2: Working Directory: [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-build
+2: Test timeout computed to be: 600
+1/2 Test #2: GenerateSpecFile ................. Passed +[0-9]+\.[0-9]+ sec
+Using generated resource spec file [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-build/dynamic-resspec\.json
+test 1
+ Start 1: RealTest
+
+1: Test command: "?[^
+]*[\\/]bin([\\/][^\\/
+]+)?[\\/]cmake(\.exe)?"? "-E" "true"
+1: Working Directory: [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-ctest-s-build
+1: Test timeout computed to be: 600
+2/2 Test #1: RealTest ......................... Passed +[0-9]+\.[0-9]+ sec
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-stderr.txt
new file mode 100644
index 0000000..273cb80
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^Only one test may define the GENERATED_RESOURCE_SPEC_FILE property
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators.cmake
new file mode 100644
index 0000000..7ee58d4
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-generators.cmake
@@ -0,0 +1,11 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile1 COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile2 COMMAND "${CMAKE_COMMAND}" -E true)
+set_tests_properties(GenerateSpecFile1 GenerateSpecFile2 PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-stderr.txt
new file mode 100644
index 0000000..39ee275
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^Test that defines GENERATED_RESOURCE_SPEC_FILE must have exactly one FIXTURES_SETUP
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures.cmake
new file mode 100644
index 0000000..a9e72ea
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-multiple-setup-fixtures.cmake
@@ -0,0 +1,10 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec;InvalidResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-stderr.txt
new file mode 100644
index 0000000..06ea90f
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^All tests that have RESOURCE_GROUPS must include the resource spec generator fixture in their FIXTURES_REQUIRED
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture.cmake
new file mode 100644
index 0000000..1983678
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-required-fixture.cmake
@@ -0,0 +1,9 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-stderr.txt
new file mode 100644
index 0000000..39ee275
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^Test that defines GENERATED_RESOURCE_SPEC_FILE must have exactly one FIXTURES_SETUP
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture.cmake
new file mode 100644
index 0000000..b6dec5e
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-no-setup-fixture.cmake
@@ -0,0 +1,9 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stderr.txt
new file mode 100644
index 0000000..343f632
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stderr.txt
@@ -0,0 +1,7 @@
+^Could not read/parse resource spec file [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-build/dynamic-resspec\.json:[ ]
+File not found: [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-build/dynamic-resspec\.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s/test\.cmake:[0-9]+ \(message\):
+ Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stdout.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stdout.txt
new file mode 100644
index 0000000..fcf8ace
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile-ctest-s-stdout.txt
@@ -0,0 +1,5 @@
+ Start 2: GenerateSpecFile
+1/2 Test #2: GenerateSpecFile .................\*\*\*Failed Invalid resource spec file +[0-9]+\.[0-9]+ sec
+ Start 1: RealTest
+Failed test dependencies: GenerateSpecFile
+2/2 Test #1: RealTest .........................\*\*\*Not Run +[0-9]+\.[0-9]+ sec
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile.cmake
new file mode 100644
index 0000000..e771c60
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-nofile.cmake
@@ -0,0 +1,10 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E true)
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stderr.txt
new file mode 100644
index 0000000..393ab84
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stderr.txt
@@ -0,0 +1,14 @@
+^Insufficient resources for test RealTest:
+
+ Test requested resources of type 'widgets' in the following amounts:
+ 2 slots
+ but only the following units were available:
+ '0': 1 slot
+
+Resource spec file:
+
+ [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-build/dynamic-resspec\.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s/test\.cmake:[0-9]+ \(message\):
+ Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stdout.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stdout.txt
new file mode 100644
index 0000000..b411a74
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough-ctest-s-stdout.txt
@@ -0,0 +1,4 @@
+ Start 2: GenerateSpecFile
+1/2 Test #2: GenerateSpecFile ................. Passed +[0-9]+\.[0-9]+ sec
+ Start 1: RealTest
+2/2 Test #1: RealTest .........................\*\*\*Not Run +[0-9]+\.[0-9]+ sec
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough.cmake
new file mode 100644
index 0000000..c8e1313
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-notenough.cmake
@@ -0,0 +1,10 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:2"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-result.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-stderr.txt
new file mode 100644
index 0000000..2c4dff8
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path-ctest-s-stderr.txt
@@ -0,0 +1,2 @@
+^GENERATED_RESOURCE_SPEC_FILE must be an absolute path
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path.cmake
new file mode 100644
index 0000000..3ee83d7
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource-relative-path.cmake
@@ -0,0 +1,10 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resource.cmake b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource.cmake
new file mode 100644
index 0000000..668b049
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resource.cmake
@@ -0,0 +1,10 @@
+add_test(NAME RealTest COMMAND "${CMAKE_COMMAND}" -E true)
+add_test(NAME GenerateSpecFile COMMAND "${CMAKE_COMMAND}" -E copy "${CTEST_DYNAMIC_RESOURCE_SPEC_FILE}" "${CMAKE_BINARY_DIR}")
+set_tests_properties(GenerateSpecFile PROPERTIES
+ GENERATED_RESOURCE_SPEC_FILE "${CMAKE_BINARY_DIR}/dynamic-resspec.json"
+ FIXTURES_SETUP "ResourceSpec"
+ )
+set_tests_properties(RealTest PROPERTIES
+ FIXTURES_REQUIRED "ResourceSpec"
+ RESOURCE_GROUPS "widgets:1"
+ )
diff --git a/Tests/RunCMake/CTestResourceAllocation/dynamic-resspec.json b/Tests/RunCMake/CTestResourceAllocation/dynamic-resspec.json
new file mode 100644
index 0000000..f9bedaf
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/dynamic-resspec.json
@@ -0,0 +1,16 @@
+{
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "local": [
+ {
+ "widgets": [
+ {
+ "id": "0",
+ "slots": 1
+ }
+ ]
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake b/Tests/RunCMake/CTestResourceAllocation/resource-common.cmake
index ef79dce..ef79dce 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake
+++ b/Tests/RunCMake/CTestResourceAllocation/resource-common.cmake
diff --git a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
index 9ad9ac8..319ebf1 100644
--- a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
+++ b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
@@ -8,9 +8,15 @@ set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
-set(config_options
- "-DCTEST_RESOURCE_ALLOC_ENABLED=${CTEST_RESOURCE_ALLOC_ENABLED};-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}"
- )
+if("@CASE_NAME@" MATCHES "^dynamic-resource-")
+ set(config_options
+ "-DCTEST_DYNAMIC_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/dynamic-resspec.json"
+ )
+else()
+ set(config_options
+ "-DCTEST_RESOURCE_ALLOC_ENABLED=${CTEST_RESOURCE_ALLOC_ENABLED};-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}"
+ )
+endif()
if(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "CMDLINE")
list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/noexist.json")
diff --git a/Tests/RunCMake/CXXModules/CMakeLists.txt b/Tests/RunCMake/CXXModules/CMakeLists.txt
index 88eb282..e23023d 100644
--- a/Tests/RunCMake/CXXModules/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.23)
project(${RunCMake_TEST} NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CXXModules/NoCXX-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
index aa7f406..102d497 100644
--- a/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
@@ -6,15 +6,15 @@ Call Stack \(most recent call first\):
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Error in CMakeLists.txt:
- The "nocxx" target has C\+\+ module sources but the "CXX" language has not
- been enabled
+ The target named "nocxx" has C\+\+ sources that export modules but the "CXX"
+ language has not been enabled
(
CMake Error in CMakeLists.txt:
-( The "nocxx" target has C\+\+ module sources but the "CXX" language has not
- been enabled
-| The "nocxx" target contains C\+\+ module sources which are not supported by
- the generator
+( The target named "nocxx" has C\+\+ sources that export modules but the "CXX"
+ language has not been enabled
+| The target named "nocxx" contains C\+\+ sources that export modules which is
+ not supported by the generator
)
)*
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
index 95d73b1..dd25689 100644
--- a/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
@@ -6,15 +6,17 @@ Call Stack \(most recent call first\):
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Error in CMakeLists.txt:
- The "nocxx20" target has C\+\+ module sources but is not using at least
- "cxx_std_20"
+ The target named "nocxx20" has C\+\+ sources that export modules but does not
+ include "cxx_std_20" \(or newer\) among its `target_compile_features`; found
+ "cxx_std_17"
(
CMake Error in CMakeLists.txt:
-( The "nocxx20" target has C\+\+ module sources but is not using at least
- "cxx_std_20"
-| The "nocxx20" target contains C\+\+ module sources which are not supported by
- the generator
+( The target named "nocxx20" has C\+\+ sources that export modules but does not
+ include "cxx_std_20" \(or newer\) among its `target_compile_features`; found
+ "cxx_std_17"
+| The target named "nocxx20" contains C\+\+ sources that export modules which
+ is not supported by the generator
)
)*
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt
index aa99af0..c2dc0b6 100644
--- a/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt
@@ -6,15 +6,15 @@ Call Stack \(most recent call first\):
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Error in CMakeLists.txt:
- The "noexperimentalflag" target has C\+\+ module sources but its experimental
- support has not been requested
+ The target named "noexperimentalflag" has C\+\+ sources that export modules
+ but its experimental support has not been requested
(
CMake Error in CMakeLists.txt:
-( The "noexperimentalflag" target has C\+\+ module sources but its experimental
- support has not been requested
-| The "noexperimentalflag" target contains C\+\+ module sources which are not
- supported by the generator
+( The target named "noexperimentalflag" has C\+\+ sources that export modules
+ but its experimental support has not been requested
+| The target named "noexperimentalflag" contains C\+\+ sources that export
+ modules which is not supported by the generator
)
)*
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt b/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
index b63d291..c82a35a 100644
--- a/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
@@ -13,13 +13,13 @@ This warning is for project developers. Use -Wno-dev to suppress it.
due to lack of required features. Ninja 1.11 or higher is required.
|CMake Error in CMakeLists.txt:
- The "nodyndep" target contains C\+\+ module sources which are not supported
- by the generator
+ The target named "nodyndep" contains C\+\+ sources that export modules which
+ is not supported by the generator
(
CMake Error in CMakeLists.txt:
- The "nodyndep" target contains C\+\+ module sources which are not supported
- by the generator
+ The target named "nodyndep" contains C\+\+ sources that export modules which
+ is not supported by the generator
)*)
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index d324ec9..0ca9945 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -148,6 +148,8 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(duplicate)
set(RunCMake_CXXModules_NO_TEST 1)
run_cxx_module_test(circular)
+ run_cxx_module_test(try-compile)
+ run_cxx_module_test(try-run)
unset(RunCMake_CXXModules_NO_TEST)
run_cxx_module_test(same-src-name)
run_cxx_module_test(scan_properties)
@@ -185,7 +187,20 @@ endif ()
if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(export-interface-no-properties-build)
run_cxx_module_test(export-interface-build)
+ run_cxx_module_test(export-usage-build)
run_cxx_module_test(export-bmi-and-interface-build)
+
+ if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
+ "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ set(test_suffix export-interface-build)
+ run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build")
+
+ set(test_suffix export-interface-no-properties-build)
+ run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DNO_PROPERTIES=1)
+
+ set(test_suffix export-bmi-and-interface-build)
+ run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DWITH_BMIS=1)
+ endif ()
endif ()
# All of the following tests perform installation.
@@ -199,6 +214,21 @@ if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(export-interface-no-properties-install)
run_cxx_module_test(export-interface-install)
+ run_cxx_module_test(export-usage-install)
run_cxx_module_test(export-bmi-and-interface-install)
+
+ if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
+ "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ set(RunCMake_CXXModules_INSTALL 0)
+ set(test_suffix export-interface-install)
+ run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install")
+
+ set(test_suffix export-interface-no-properties-install)
+ run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DNO_PROPERTIES=1)
+
+ set(test_suffix export-bmi-and-interface-install)
+ run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DWITH_BMIS=1)
+ set(RunCMake_CXXModules_INSTALL 1)
+ endif ()
endif ()
endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake
index ff7219a..5f32364 100644
--- a/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake
+++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake
@@ -1,4 +1,4 @@
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
if (NOT EXISTS "${CMake_TEST_MODULE_COMPILATION_RULES}")
message(FATAL_ERROR
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt b/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt
index 78bdf2b..659414d 100644
--- a/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt
@@ -1,4 +1,4 @@
-CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+CMake Warning \(dev\) at CMakeLists.txt:15 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
index 515b240..78a1d0b 100644
--- a/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
@@ -3,6 +3,14 @@ project(cxx_modules_deep_chain CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ include(CheckCompilerFlag)
+ check_compiler_flag(CXX "-Wread-modules-implicitly" have_implicit_module_warning)
+ if (have_implicit_module_warning)
+ add_compile_options(-Werror=read-modules-implicitly)
+ endif ()
+endif ()
+
add_library(a STATIC)
target_sources(a
PUBLIC
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt
index d227e55..c17577c 100644
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
find_package(export_bmi_and_interfaces REQUIRED)
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt
index d46d28b..d608d67 100644
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
find_package(export_bmi_and_interfaces REQUIRED)
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt
index 3cd156a..106bd1e 100644
--- a/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
find_package(export_interfaces REQUIRED)
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt
index 71bf86c..c19283b 100644
--- a/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
find_package(export_interfaces REQUIRED)
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt
index 0c094ac..fba05f4 100644
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
find_package(export_interfaces_no_properties REQUIRED)
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt
index 0c094ac..fba05f4 100644
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
find_package(export_interfaces_no_properties REQUIRED)
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt
new file mode 100644
index 0000000..78bdf2b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt
@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt
new file mode 100644
index 0000000..86a608b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt
@@ -0,0 +1,110 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_usage CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(export_usage STATIC)
+target_sources(export_usage
+ PRIVATE
+ forward.cxx
+ PRIVATE
+ FILE_SET modules_private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ private.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(export_usage PUBLIC cxx_std_20)
+
+list(APPEND CMAKE_CXX_KNOWN_FEATURES
+ exported
+ buildiface
+ installiface
+ buildlocaliface)
+
+target_include_directories(export_usage
+ PRIVATE
+ "/usr/exported"
+ "$<BUILD_INTERFACE:/usr/buildiface>"
+ "$<INSTALL_INTERFACE:/usr/installiface>"
+ "$<BUILD_LOCAL_INTERFACE:/usr/buildlocaliface>")
+target_compile_definitions(export_usage
+ PRIVATE
+ "exported"
+ "$<BUILD_INTERFACE:buildiface>"
+ "$<INSTALL_INTERFACE:installiface>"
+ "$<BUILD_LOCAL_INTERFACE:buildlocaliface>")
+target_compile_features(export_usage
+ PRIVATE
+ "cxx_std_11"
+ "$<BUILD_INTERFACE:cxx_std_14>"
+ "$<INSTALL_INTERFACE:cxx_std_17>"
+ "$<BUILD_LOCAL_INTERFACE:cxx_std_20>")
+
+if (MSVC)
+ set(variable_flag "-constexpr:depth")
+else ()
+ set(variable_flag "-fconstexpr-depth=")
+endif ()
+
+target_compile_options(export_usage
+ PRIVATE
+ "${variable_flag}100"
+ "$<BUILD_INTERFACE:${variable_flag}200>"
+ "$<INSTALL_INTERFACE:${variable_flag}300>"
+ "$<BUILD_LOCAL_INTERFACE:${variable_flag}400>")
+
+add_library(export_used INTERFACE)
+add_library(export_build INTERFACE)
+add_library(export_install INTERFACE)
+add_library(export_never INTERFACE)
+
+target_link_libraries(export_usage
+ PRIVATE
+ "export_used"
+ "$<BUILD_INTERFACE:export_build>"
+ "$<INSTALL_INTERFACE:export_install>"
+ "$<BUILD_LOCAL_INTERFACE:export_never>")
+
+install(TARGETS export_usage
+ EXPORT CXXModules
+ FILE_SET modules DESTINATION "lib/cxx/miu")
+export(EXPORT CXXModules
+ NAMESPACE CXXModules::
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-targets.cmake")
+install(TARGETS export_used export_build export_install
+ EXPORT CXXModulesDeps)
+export(EXPORT CXXModulesDeps
+ NAMESPACE CXXModules::
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-dep-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-dep-targets.cmake\")
+include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME export_usage_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}"
+ "-Dexport_interfaces_flag=${variable_flag}"
+ "-Dexport_usage_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx
new file mode 100644
index 0000000..7f53271
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx
@@ -0,0 +1,6 @@
+import priv;
+
+int forwarding()
+{
+ return from_private();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx
new file mode 100644
index 0000000..8dfc41b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx
@@ -0,0 +1,10 @@
+export module importable;
+
+extern "C++" {
+int forwarding();
+}
+
+export int from_import()
+{
+ return forwarding();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx
new file mode 100644
index 0000000..c5b719a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int from_private()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt
new file mode 100644
index 0000000..adec9e7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt
@@ -0,0 +1,69 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
+
+find_package(export_usage REQUIRED)
+
+if (NOT TARGET CXXModules::export_usage)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (NOT TARGET CXXModules::export_used)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (NOT TARGET CXXModules::export_build)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (NOT TARGET CXXModules::export_install)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (TARGET CXXModules::export_never)
+ message(FATAL_ERROR
+ "Extra imported target")
+endif ()
+
+function (check_property expected property)
+ get_property(actual TARGET CXXModules::export_usage
+ PROPERTY "${property}")
+ if (NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: ${actual}")
+ endif ()
+endfunction ()
+
+check_property("/usr/exported;/usr/buildiface" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES")
+check_property("exported;buildiface" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS")
+check_property("cxx_std_20;cxx_std_11;cxx_std_14" "IMPORTED_CXX_MODULES_COMPILE_FEATURES")
+check_property("${export_interfaces_flag}100;${export_interfaces_flag}200" "IMPORTED_CXX_MODULES_COMPILE_OPTIONS")
+check_property("$<COMPILE_ONLY:CXXModules::export_used>;$<COMPILE_ONLY:CXXModules::export_build>" "IMPORTED_CXX_MODULES_LINK_LIBRARIES")
+
+# Extract the export-dependent targets from the export file.
+file(STRINGS "${export_usage_DIR}/export_usage-targets.cmake" usage_dependent_targets
+ REGEX "foreach._target ")
+# Rudimentary argument splitting.
+string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}")
+# Keep only "target" names.
+list(FILTER usage_dependent_targets INCLUDE REGEX "CXXModules::")
+# Strip quotes.
+string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}")
+
+if (NOT "CXXModules::export_used" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export does not require the 'CXXModules::export_used' target")
+endif ()
+if (NOT "CXXModules::export_build" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export does not require the 'CXXModules::export_build' target")
+endif ()
+if ("CXXModules::export_install" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export requires the 'CXXModules::export_install' target")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt
new file mode 100644
index 0000000..78bdf2b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt
@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt
new file mode 100644
index 0000000..11f53b0
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt
@@ -0,0 +1,114 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_usage CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(export_usage STATIC)
+target_sources(export_usage
+ PRIVATE
+ forward.cxx
+ PRIVATE
+ FILE_SET modules_private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ private.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(export_usage PUBLIC cxx_std_20)
+
+list(APPEND CMAKE_CXX_KNOWN_FEATURES
+ exported
+ buildiface
+ installiface
+ buildlocaliface)
+
+target_include_directories(export_usage
+ PRIVATE
+ "/usr/exported"
+ "$<BUILD_INTERFACE:/usr/buildiface>"
+ "$<INSTALL_INTERFACE:/usr/installiface>"
+ "$<BUILD_LOCAL_INTERFACE:/usr/buildlocaliface>")
+target_compile_definitions(export_usage
+ PRIVATE
+ "exported"
+ "$<BUILD_INTERFACE:buildiface>"
+ "$<INSTALL_INTERFACE:installiface>"
+ "$<BUILD_LOCAL_INTERFACE:buildlocaliface>")
+target_compile_features(export_usage
+ PRIVATE
+ "cxx_std_11"
+ "$<BUILD_INTERFACE:cxx_std_14>"
+ "$<INSTALL_INTERFACE:cxx_std_17>"
+ "$<BUILD_LOCAL_INTERFACE:cxx_std_20>")
+
+if (MSVC)
+ set(variable_flag "-constexpr:depth")
+else ()
+ set(variable_flag "-fconstexpr-depth=")
+endif ()
+
+target_compile_options(export_usage
+ PRIVATE
+ "${variable_flag}100"
+ "$<BUILD_INTERFACE:${variable_flag}200>"
+ "$<INSTALL_INTERFACE:${variable_flag}300>"
+ "$<BUILD_LOCAL_INTERFACE:${variable_flag}400>")
+
+add_library(export_used INTERFACE)
+add_library(export_build INTERFACE)
+add_library(export_install INTERFACE)
+add_library(export_never INTERFACE)
+
+target_link_libraries(export_usage
+ PRIVATE
+ "export_used"
+ "$<BUILD_INTERFACE:export_build>"
+ "$<INSTALL_INTERFACE:export_install>"
+ "$<BUILD_LOCAL_INTERFACE:export_never>")
+
+install(TARGETS export_usage
+ EXPORT CXXModules
+ FILE_SET modules DESTINATION "lib/cxx/miu")
+install(EXPORT CXXModules
+ NAMESPACE CXXModules::
+ DESTINATION "lib/cmake/export_usage"
+ FILE "export_usage-targets.cmake")
+install(TARGETS export_used export_build export_install
+ EXPORT CXXModulesDeps)
+install(EXPORT CXXModulesDeps
+ NAMESPACE CXXModules::
+ DESTINATION "lib/cmake/export_usage"
+ FILE "export_usage-dep-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-dep-targets.cmake\")
+include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/export_usage-config.cmake"
+ DESTINATION "lib/cmake/export_usage")
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME export_usage_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
+ "-Dexport_interfaces_flag=${variable_flag}"
+ "-Dexport_usage_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_usage"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx
new file mode 100644
index 0000000..7f53271
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx
@@ -0,0 +1,6 @@
+import priv;
+
+int forwarding()
+{
+ return from_private();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx
new file mode 100644
index 0000000..8dfc41b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx
@@ -0,0 +1,10 @@
+export module importable;
+
+extern "C++" {
+int forwarding();
+}
+
+export int from_import()
+{
+ return forwarding();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx
new file mode 100644
index 0000000..c5b719a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int from_private()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt
new file mode 100644
index 0000000..9ccd63a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt
@@ -0,0 +1,69 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
+
+find_package(export_usage REQUIRED)
+
+if (NOT TARGET CXXModules::export_usage)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (NOT TARGET CXXModules::export_used)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (NOT TARGET CXXModules::export_build)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (NOT TARGET CXXModules::export_install)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+if (TARGET CXXModules::export_never)
+ message(FATAL_ERROR
+ "Extra imported target")
+endif ()
+
+function (check_property expected property)
+ get_property(actual TARGET CXXModules::export_usage
+ PROPERTY "${property}")
+ if (NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual : ${actual}")
+ endif ()
+endfunction ()
+
+check_property("/usr/exported;/usr/installiface" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES")
+check_property("exported;installiface" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS")
+check_property("cxx_std_20;cxx_std_11;cxx_std_17" "IMPORTED_CXX_MODULES_COMPILE_FEATURES")
+check_property("${export_interfaces_flag}100;${export_interfaces_flag}300" "IMPORTED_CXX_MODULES_COMPILE_OPTIONS")
+check_property("$<COMPILE_ONLY:CXXModules::export_used>;$<COMPILE_ONLY:CXXModules::export_install>" "IMPORTED_CXX_MODULES_LINK_LIBRARIES")
+
+# Extract the export-dependent targets from the export file.
+file(STRINGS "${export_usage_DIR}/export_usage-targets.cmake" usage_dependent_targets
+ REGEX "foreach._target ")
+# Rudimentary argument splitting.
+string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}")
+# Keep only "target" names.
+list(FILTER usage_dependent_targets INCLUDE REGEX "CXXModules::")
+# Strip quotes.
+string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}")
+
+if (NOT "CXXModules::export_used" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export does not require the 'CXXModules::export_used' target")
+endif ()
+if ("CXXModules::export_build" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export requires the 'CXXModules::export_build' target")
+endif ()
+if (NOT "CXXModules::export_install" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export does not require the 'CXXModules::export_install' target")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/generated-stderr.txt b/Tests/RunCMake/CXXModules/examples/generated-stderr.txt
index 1dd9876..06160ce 100644
--- a/Tests/RunCMake/CXXModules/examples/generated-stderr.txt
+++ b/Tests/RunCMake/CXXModules/examples/generated-stderr.txt
@@ -1,4 +1,4 @@
-CMake Warning \(dev\) at CMakeLists.txt:12 \(target_sources\):
+CMake Warning \(dev\) at CMakeLists.txt:16 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt
index 73f7ff7..9a8da3d 100644
--- a/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt
@@ -3,10 +3,14 @@ project(cxx_modules_generated CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
-configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in"
- "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx"
- COPYONLY)
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in"
+ COMMAND "${CMAKE_COMMAND}"
+ -E copy_if_different
+ "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx"
+ COMMENT "Copying 'importable.cxx'")
add_executable(generated)
target_sources(generated
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt
new file mode 100644
index 0000000..71ee795
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-build/export_bmi_and_interfaces-targets.cmake:[0-9]* \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-build/export_bmi_and_interfaces-config.cmake:1 \(include\)
+ CMakeLists.txt:15 \(find_package\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt
new file mode 100644
index 0000000..d22b2a1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-install/lib/cmake/export_bmi_and_interfaces/export_bmi_and_interfaces-targets.cmake:[0-9]* \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-install/lib/cmake/export_bmi_and_interfaces/export_bmi_and_interfaces-config.cmake:1 \(include\)
+ CMakeLists.txt:15 \(find_package\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt
new file mode 100644
index 0000000..f79abbc
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-build-build/export_interfaces-targets.cmake:[0-9]* \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Tests/RunCMake/CXXModules/examples/export-interface-build-build/export_interfaces-config.cmake:1 \(include\)
+ CMakeLists.txt:15 \(find_package\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt
new file mode 100644
index 0000000..32f9452
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-install-install/lib/cmake/export_interfaces/export_interfaces-targets.cmake:[0-9]* \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Tests/RunCMake/CXXModules/examples/export-interface-install-install/lib/cmake/export_interfaces/export_interfaces-config.cmake:1 \(include\)
+ CMakeLists.txt:15 \(find_package\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt
new file mode 100644
index 0000000..9254936
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build-build/export_interfaces_no_properties-targets.cmake:[0-9]* \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build-build/export_interfaces_no_properties-config.cmake:1 \(include\)
+ CMakeLists.txt:15 \(find_package\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt
new file mode 100644
index 0000000..71269f4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install-install/lib/cmake/export_interfaces_no_properties/export_interfaces_no_properties-targets.cmake:[0-9]* \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install-install/lib/cmake/export_interfaces_no_properties/export_interfaces_no_properties-config.cmake:1 \(include\)
+ CMakeLists.txt:15 \(find_package\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt
new file mode 100644
index 0000000..3e6f379
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_import_interfaces CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+if (NO_PROPERTIES)
+ set(package_name "export_interfaces_no_properties")
+elseif (WITH_BMIS)
+ set(package_name "export_bmi_and_interfaces")
+else ()
+ set(package_name "export_interfaces")
+endif ()
+set(target_name "CXXModules::${package_name}")
+
+find_package("${package_name}" REQUIRED)
+
+add_executable(use_import_interfaces)
+target_sources(use_import_interfaces
+ PRIVATE
+ use.cxx)
+target_compile_features(use_import_interfaces PRIVATE cxx_std_20)
+target_link_libraries(use_import_interfaces PRIVATE "${target_name}")
+
+add_test(NAME use_import_interfaces COMMAND use_import_interfaces)
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx b/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx
new file mode 100644
index 0000000..feb38d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt b/Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt
new file mode 100644
index 0000000..571bb9c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt
@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:[0-9]* \(try_compile\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt
new file mode 100644
index 0000000..dee61f1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_try_compile CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
+try_compile(can_use_modules
+ SOURCES_TYPE CXX_MODULE
+ SOURCES
+ "${CMAKE_CURRENT_LIST_DIR}/importable.cxx"
+ SOURCES_TYPE NORMAL
+ SOURCE_FROM_FILE
+ use_importable.cxx "${CMAKE_CURRENT_LIST_DIR}/use_importable.cxx"
+ CXX_STANDARD 20)
+
+if (NOT can_use_modules)
+ message(FATAL_ERROR
+ "`try_compile` could not compile sources using modules.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx b/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx b/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx
new file mode 100644
index 0000000..8d6bab2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int foo()
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-run-stderr.txt b/Tests/RunCMake/CXXModules/examples/try-run-stderr.txt
new file mode 100644
index 0000000..508db55
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run-stderr.txt
@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:[0-9]* \(try_run\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
new file mode 100644
index 0000000..fb03571
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_try_run CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+try_run(can_run_modules_result can_compile_modules
+ SOURCES_TYPE CXX_MODULE
+ SOURCES
+ "${CMAKE_CURRENT_LIST_DIR}/importable.cxx"
+ SOURCES_TYPE NORMAL
+ SOURCE_FROM_FILE
+ main.cxx "${CMAKE_CURRENT_LIST_DIR}/main.cxx"
+ CXX_STANDARD 20)
+
+if (NOT can_compile_modules)
+ message(FATAL_ERROR
+ "`try_run` could not compile sources using modules.")
+endif ()
+
+if (can_run_modules_result)
+ message(FATAL_ERROR
+ "`try_run` could not run sources using modules.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx b/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/main.cxx b/Tests/RunCMake/CXXModules/examples/try-run/main.cxx
new file mode 100644
index 0000000..5c1bb42
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import() == 1;
+}
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON-stderr.txt b/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON-stderr.txt
deleted file mode 100644
index 9080942..0000000
--- a/Tests/RunCMake/CommandLine/DeprecateVS11-WARN-ON-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Warning:
- The "Visual Studio 11 2012" generator is deprecated and will be removed in
- a future version of CMake.
-
- Add CMAKE_WARN_VS11=OFF to the cache to disable this warning.$
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-OFF.cmake b/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-OFF.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-OFF.cmake
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON-stderr.txt b/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON-stderr.txt
new file mode 100644
index 0000000..b69408e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning:
+ The "Visual Studio 12 2013" generator is deprecated and will be removed in
+ a future version of CMake.
+
+ Add CMAKE_WARN_VS12=OFF to the cache to disable this warning.$
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON.cmake b/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS12-WARN-ON.cmake
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 45b4c0e..611dde2 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -1119,9 +1119,9 @@ if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 2008")
run_cmake_with_options(DeprecateVS9-WARN-OFF -DCMAKE_WARN_VS9=OFF)
endif()
-if(RunCMake_GENERATOR MATCHES "^Visual Studio 11 2012")
- run_cmake_with_options(DeprecateVS11-WARN-ON -DCMAKE_WARN_VS11=ON)
- unset(ENV{CMAKE_WARN_VS11})
- run_cmake(DeprecateVS11-WARN-ON)
- run_cmake_with_options(DeprecateVS11-WARN-OFF -DCMAKE_WARN_VS11=OFF)
+if(RunCMake_GENERATOR MATCHES "^Visual Studio 12 2013")
+ run_cmake_with_options(DeprecateVS12-WARN-ON -DCMAKE_WARN_VS12=ON)
+ unset(ENV{CMAKE_WARN_VS12})
+ run_cmake(DeprecateVS12-WARN-ON)
+ run_cmake_with_options(DeprecateVS12-WARN-OFF -DCMAKE_WARN_VS12=OFF)
endif()
diff --git a/Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator-stdout.txt b/Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator-stdout.txt
new file mode 100644
index 0000000..9a7d746
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator-stdout.txt
@@ -0,0 +1,2 @@
+-- env_emulator='pseudo_emulator(\.exe)?'
+-- emulator='pseudo_emulator(\.exe)?'
diff --git a/Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator.cmake b/Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator.cmake
new file mode 100644
index 0000000..55fc483
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/EnvCrossCompilingEmulator.cmake
@@ -0,0 +1,6 @@
+message(STATUS "ENV{CMAKE_CROSS_COMPILING_EMULATOR}='$ENV{CMAKE_CROSSCOMPILING_EMULATOR}'")
+message(STATUS "CMAKE_CROSSCOMPLING_EMULATOR='${CMAKE_CROSSCOMPILING_EMULATOR}'")
+get_filename_component(env_emulator "$ENV{CMAKE_CROSSCOMPILING_EMULATOR}" NAME)
+message(STATUS "env_emulator='${env_emulator}'")
+get_filename_component(emulator "${CMAKE_CROSSCOMPILING_EMULATOR}" NAME)
+message(STATUS "emulator='${emulator}'")
diff --git a/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake
index 97b7b5a..1ffd91c 100644
--- a/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake
@@ -26,3 +26,11 @@ set(RunCMake_TEST_OPTIONS
"-DCMAKE_CROSSCOMPILING_EMULATOR=${PSEUDO_EMULATOR_CUSTOM_COMMAND_ARG}\;custom_argument")
CustomCommandGenerator_run_and_build(AddCustomCommandWithArg)
CustomCommandGenerator_run_and_build(AddCustomTargetWithArg)
+unset(RunCMake_TEST_OPTIONS)
+
+function(run_EnvCrossCompilingEmulator)
+ set(ENV{CMAKE_CROSSCOMPILING_EMULATOR} "${PSEUDO_EMULATOR}")
+ run_cmake(EnvCrossCompilingEmulator)
+ unset(ENV{CMAKE_CROSSCOMPILING_EMULATOR})
+endfunction()
+run_EnvCrossCompilingEmulator()
diff --git a/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake b/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake
index 891e138..6847a23 100644
--- a/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake
+++ b/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake
@@ -59,3 +59,5 @@ run_optimize_test(OptimizeStatic StaticTop)
if(CMAKE_Fortran_COMPILER)
run_optimize_test(OptimizeFortran FortranTop)
endif()
+
+run_cmake_build(RuntimeTargets mylib SharedTop)
diff --git a/Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake b/Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake
new file mode 100644
index 0000000..21531cd
--- /dev/null
+++ b/Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake
@@ -0,0 +1,18 @@
+enable_language(C)
+
+set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE)
+add_library(mylib STATIC mylib.c)
+add_library(neverbuild SHARED neverbuild.c)
+
+# Building mylib should not require building neverbuild
+target_link_libraries(mylib PRIVATE neverbuild)
+set_target_properties(neverbuild PROPERTIES EXCLUDE_FROM_ALL YES)
+
+# Building SharedTop should require SharedBottom to be built
+add_library(SharedTop SHARED top.c)
+add_library(StaticMiddle STATIC middle.c)
+add_library(SharedBottom SHARED bottom.c)
+target_link_libraries(SharedTop PRIVATE StaticMiddle)
+target_link_libraries(StaticMiddle PRIVATE SharedBottom)
+set_target_properties(StaticMiddle SharedBottom PROPERTIES EXCLUDE_FROM_ALL YES)
+set_target_properties(StaticMiddle PROPERTIES POSITION_INDEPENDENT_CODE YES)
diff --git a/Tests/RunCMake/DependencyGraph/bottom.c b/Tests/RunCMake/DependencyGraph/bottom.c
new file mode 100644
index 0000000..c8ea481
--- /dev/null
+++ b/Tests/RunCMake/DependencyGraph/bottom.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int bottom(void)
+{
+ return 23;
+}
diff --git a/Tests/RunCMake/DependencyGraph/middle.c b/Tests/RunCMake/DependencyGraph/middle.c
new file mode 100644
index 0000000..3b1b84c
--- /dev/null
+++ b/Tests/RunCMake/DependencyGraph/middle.c
@@ -0,0 +1,9 @@
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+ int bottom(void);
+
+int middle(void)
+{
+ return bottom() + 19;
+}
diff --git a/Tests/RunCMake/DependencyGraph/neverbuild.c b/Tests/RunCMake/DependencyGraph/neverbuild.c
new file mode 100644
index 0000000..e490510
--- /dev/null
+++ b/Tests/RunCMake/DependencyGraph/neverbuild.c
@@ -0,0 +1 @@
+#error I should not be built
diff --git a/Tests/RunCMake/DependencyGraph/top.c b/Tests/RunCMake/DependencyGraph/top.c
new file mode 100644
index 0000000..eceb0a5
--- /dev/null
+++ b/Tests/RunCMake/DependencyGraph/top.c
@@ -0,0 +1,9 @@
+int middle(void);
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int top(void)
+{
+ return middle() + 2;
+}
diff --git a/Tests/RunCMake/ExternalProject/DetectJobServer.cmake b/Tests/RunCMake/ExternalProject/DetectJobServer.cmake
new file mode 100644
index 0000000..c6e1412
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/DetectJobServer.cmake
@@ -0,0 +1,16 @@
+include(ExternalProject)
+ExternalProject_Add(Foo
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Foo
+ BUILD_COMMAND ${DETECT_JOBSERVER} "ep.txt"
+ BUILD_JOB_SERVER_AWARE 1
+ INSTALL_COMMAND ""
+)
+
+# Add a second step to test JOB_SERVER_AWARE
+ExternalProject_Add_Step(Foo
+ second_step
+ COMMAND ${DETECT_JOBSERVER} "ep_second_step.txt"
+ DEPENDEES build
+ ALWAYS 1
+ JOB_SERVER_AWARE 1
+)
diff --git a/Tests/RunCMake/ExternalProject/Foo/CMakeLists.txt b/Tests/RunCMake/ExternalProject/Foo/CMakeLists.txt
new file mode 100644
index 0000000..b38b173
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Foo/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.27)
+project(Foo NONE)
+
+add_custom_target(drive ALL COMMAND ${CMAKE_COMMAND} -E true)
diff --git a/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake
new file mode 100644
index 0000000..55a9f0d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware-check.cmake
@@ -0,0 +1,16 @@
+set(BUILD_DIR "${RunCMake_BINARY_DIR}/GNUMakeJobServerAware-build")
+
+function(check target regex)
+ file(STRINGS ${BUILD_DIR}/${target} lines
+ REGEX ${regex}
+ )
+
+ list(LENGTH lines len)
+ if(len EQUAL 0)
+ message(FATAL_ERROR "Could not find matching lines '${regex}' in ${BUILD_DIR}/${target}")
+ endif()
+endfunction()
+
+check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? --build "?.*"?]])
+check("/CMakeFiles/Foo.dir/build.make" [[\+cd (/d )?"?.*"? && "?.*"? -E touch "?.*"?]])
+check("/CMakeFiles/Foo.dir/build.make" [[\+"?.*"? -E true]])
diff --git a/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake
new file mode 100644
index 0000000..3f688ca
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/GNUMakeJobServerAware.cmake
@@ -0,0 +1,16 @@
+include(ExternalProject)
+ExternalProject_Add(Foo
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Foo
+ BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR>
+ BUILD_JOB_SERVER_AWARE 1
+ INSTALL_COMMAND ""
+)
+
+# Add a second step to test JOB_SERVER_AWARE
+ExternalProject_Add_Step(Foo
+ second_step
+ COMMAND ${CMAKE_COMMAND} -E true
+ DEPENDEES build
+ ALWAYS 1
+ JOB_SERVER_AWARE 1
+)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index 4afdef8..ffaa46c 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -144,6 +144,24 @@ function(__ep_test_with_build_with_server testName)
run_cmake_command(${testName}-build ${CMAKE_COMMAND} --build .)
endfunction()
+if(RunCMake_GENERATOR MATCHES "(MSYS|MinGW|Unix) Makefiles")
+ __ep_test_with_build(GNUMakeJobServerAware)
+endif()
+
+function(__ep_test_jobserver)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DetectJobServer-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_with_options(DetectJobServer -DDETECT_JOBSERVER=${DETECT_JOBSERVER})
+ run_cmake_command(DetectJobServer-clean ${CMAKE_COMMAND} --build . --target clean)
+ run_cmake_command(DetectJobServer-build ${CMAKE_COMMAND} --build . -j4)
+endfunction()
+
+if(RunCMake_GENERATOR MATCHES "(MinGW|Unix) Makefiles")
+ __ep_test_jobserver()
+endif()
+
__ep_test_with_build(MultiCommand)
set(RunCMake_TEST_OUTPUT_MERGE 1)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
index 521e464..93df8a6 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
@@ -73,6 +73,47 @@
{
"define": "interface_exe_EXPORTS",
"backtrace": null
+ },
+ {
+ "define": "COMPILED_WITH_INTERFACE_LIB",
+ "backtrace": [
+ {
+ "file": "^include_test\\.cmake$",
+ "line": 4,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^include_test\\.cmake$",
+ "line": null,
+ "command": null,
+ "hasParent": true
+ },
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 3,
+ "command": "include",
+ "hasParent": true
+ },
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": null,
+ "command": null,
+ "hasParent": true
+ },
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": 3,
+ "command": "include",
+ "hasParent": true
+ },
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
}
],
"compileCommandFragments": null
diff --git a/Tests/RunCMake/FileAPI/include_test.cmake b/Tests/RunCMake/FileAPI/include_test.cmake
index c74d264..c188cb3 100644
--- a/Tests/RunCMake/FileAPI/include_test.cmake
+++ b/Tests/RunCMake/FileAPI/include_test.cmake
@@ -1,7 +1,7 @@
add_library(interface_lib INTERFACE)
target_compile_definitions(interface_lib INTERFACE COMPILED_WITH_INTERFACE_LIB)
add_executable(interface_exe empty.c)
-target_link_libraries(interface_exe PRIVATE inteface_lib)
+target_link_libraries(interface_exe PRIVATE interface_lib)
set_property(TARGET interface_exe PROPERTY ENABLE_EXPORTS ON)
set_property(TARGET interface_exe PROPERTY RUNTIME_OUTPUT_DIRECTORY bin)
set_property(TARGET interface_exe PROPERTY ARCHIVE_OUTPUT_DIRECTORY lib)
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
deleted file mode 100644
index 539e5ef..0000000
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
+++ /dev/null
@@ -1,3 +0,0 @@
--- ZOT_LIBRARIES='zot'
--- ZOT_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/root/lib/prefix-zot-suffix'
--- ZOT_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/root/lib;-lzot'
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-stdout.txt
new file mode 100644
index 0000000..012458d
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-stdout.txt
@@ -0,0 +1,4 @@
+-- ZOT_LIBRARIES='zot'
+-- ZOT_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-build/root/lib/prefix-zot-suffix'
+-- ZOT_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-build/root/lib;-lzot'
+-- ZOT_CFLAGS='-I[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH-build/root/include'
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH.cmake
index 1278c49..e58cefb 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_SYSTEM_PATH.cmake
@@ -3,16 +3,19 @@ find_package(PkgConfig REQUIRED)
set(ROOT "${CMAKE_CURRENT_BINARY_DIR}/root")
string(REPLACE " " "\\ " ESCAPED_ROOT "${ROOT}")
set(LIB_DIR "${ROOT}/lib")
+set(INCLUDE_DIR "${ROOT}/include")
set(PKGCONFIG_DIR "${LIB_DIR}/pkgconfig")
file(WRITE "${PKGCONFIG_DIR}/zot.pc" "
prefix=${ESCAPED_ROOT}
libdir=\${prefix}/lib
+includedir=\${prefix}/include
Name: Zot
Description: Dummy package to test LIBRARY_DIR support
Version: 1.0
Libs: -L\${libdir} -lzot
+Cflags: -I\${includedir}
")
# Create a "library" file to find in libdir.
@@ -22,9 +25,13 @@ file(WRITE "${LIB_DIR}/prefix-zot-suffix")
# 'pkg-config --libs' drops -L flags in PKG_CONFIG_SYSTEM_LIBRARY_PATH by default.
set(ENV{PKG_CONFIG_SYSTEM_LIBRARY_PATH} "${LIB_DIR}")
+# 'pkg-config --cflags' drops -I flags in PKG_CONFIG_SYSTEM_INCLUDE_PATH by default.
+set(ENV{PKG_CONFIG_SYSTEM_INCLUDE_PATH} "${INCLUDE_DIR}")
# 'pkgconf --libs' also drops -L flags in LIBRARY_PATH by default.
set(ENV{LIBRARY_PATH} "${LIB_DIR}")
+# 'pkgconf --cflags' also drops -I flags in CPATH by default.
+set(ENV{CPATH} "${INCLUDE_DIR}")
set(ENV{PKG_CONFIG_PATH} "${PKGCONFIG_DIR}")
pkg_check_modules(ZOT REQUIRED zot)
@@ -32,3 +39,4 @@ pkg_check_modules(ZOT REQUIRED zot)
message(STATUS "ZOT_LIBRARIES='${ZOT_LIBRARIES}'")
message(STATUS "ZOT_LINK_LIBRARIES='${ZOT_LINK_LIBRARIES}'")
message(STATUS "ZOT_LDFLAGS='${ZOT_LDFLAGS}'")
+message(STATUS "ZOT_CFLAGS='${ZOT_CFLAGS}'")
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index 6b8e884..2bfe028 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -59,6 +59,6 @@ Libs: -L\${libdir}
run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME)
run_cmake(FindPkgConfig_empty_target)
if(NOT PKG_CONFIG_DONT_SUPPORT_SPACES_IN_PATH)
- run_cmake(FindPkgConfig_LIBRARY_PATH)
+ run_cmake(FindPkgConfig_SYSTEM_PATH)
endif()
endif ()
diff --git a/Tests/RunCMake/Framework/FrameworkConsumption.cmake b/Tests/RunCMake/Framework/FrameworkConsumption.cmake
index 2180cf9..f831a94 100644
--- a/Tests/RunCMake/Framework/FrameworkConsumption.cmake
+++ b/Tests/RunCMake/Framework/FrameworkConsumption.cmake
@@ -1,5 +1,7 @@
enable_language(C)
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")
+
# Create framework and ensure header is placed in Headers
set(input_header "${CMAKE_SOURCE_DIR}/Gui.h")
add_library(Gui SHARED Gui.c "${input_header}")
@@ -8,6 +10,8 @@ set_target_properties(Gui PROPERTIES
FRAMEWORK TRUE
)
+install(TARGETS Gui DESTINATION .)
+
add_executable(app main.c)
target_link_libraries(app PRIVATE Gui)
diff --git a/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake b/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake
index bcf6c29..94c0b87 100644
--- a/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake
+++ b/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake
@@ -22,3 +22,15 @@ set_target_properties(Example::Example2 PROPERTIES
add_library(testcase2 FrameworkSystemIncludeTest.c)
target_compile_options(testcase2 PRIVATE "-Werror=#pragma-messages")
target_link_libraries(testcase2 PRIVATE Example::Example2)
+
+
+
+add_library(Example::Example3 SHARED IMPORTED)
+set_target_properties(Example::Example3 PROPERTIES
+ FRAMEWORK 1
+ IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/subdir/Example.framework"
+)
+
+add_library(testcase3 FrameworkSystemIncludeTest.c)
+target_compile_options(testcase3 PRIVATE "-Werror=#pragma-messages")
+target_link_libraries(testcase3 PRIVATE Example::Example3)
diff --git a/Tests/RunCMake/Framework/ImportedFrameworkConsumption.cmake b/Tests/RunCMake/Framework/ImportedFrameworkConsumption.cmake
new file mode 100644
index 0000000..c44a1bb
--- /dev/null
+++ b/Tests/RunCMake/Framework/ImportedFrameworkConsumption.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+
+add_library(Gui IMPORTED UNKNOWN)
+set_property(TARGET Gui PROPERTY IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/../FrameworkConsumption-build/install/Gui.framework")
+
+add_executable(app main.c)
+target_link_libraries(app PRIVATE Gui)
diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake
index a767130..7319a59 100644
--- a/Tests/RunCMake/Framework/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake
@@ -113,7 +113,16 @@ function(framework_consumption)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(FrameworkConsumption)
- run_cmake_command(FrameworkConsumption-build ${CMAKE_COMMAND} --build .)
+ run_cmake_command(FrameworkConsumption-build ${CMAKE_COMMAND} --build . --config Release)
+ run_cmake_command(FrameworkConsumption-install ${CMAKE_COMMAND} --install . --config Release)
+
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ImportedFrameworkConsumption-build")
+ set(RunCMake_TEST_NO_CLEAN 1)
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(ImportedFrameworkConsumption)
+ run_cmake_command(ImportedFrameworkConsumption-build ${CMAKE_COMMAND} --build . --config Release)
endfunction()
framework_consumption()
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-stderr.txt
new file mode 100644
index 0000000..61188b6
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+ Generator
+
+ Xcode
+
+ toolset specification field
+
+ buildsystem=1
+
+ is not allowed with Xcode [0-9.]+\.$
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1.cmake b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1.cmake
new file mode 100644
index 0000000..2fc38e5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem1.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
index a742391..71cc2d4 100644
--- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
@@ -89,7 +89,11 @@ elseif("${RunCMake_GENERATOR}" STREQUAL "Xcode")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
run_cmake(TestToolsetXcodeBuildSystemDefault12)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,buildsystem=1")
- run_cmake(TestToolsetXcodeBuildSystem1)
+ if(XCODE_VERSION VERSION_GREATER_EQUAL 14)
+ run_cmake(BadToolsetXcodeBuildSystem1)
+ else()
+ run_cmake(TestToolsetXcodeBuildSystem1)
+ endif()
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,buildsystem=12")
run_cmake(TestToolsetXcodeBuildSystem12)
else()
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD-stderr.txt b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD-stderr.txt
new file mode 100644
index 0000000..4499d97
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0117-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0117 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Make/DetectJobServer-present.cmake b/Tests/RunCMake/Make/DetectJobServer-present.cmake
new file mode 100644
index 0000000..cfaf7be
--- /dev/null
+++ b/Tests/RunCMake/Make/DetectJobServer-present.cmake
@@ -0,0 +1,13 @@
+# Verifies that the jobserver is present
+add_custom_command(OUTPUT custom_command.txt
+ JOB_SERVER_AWARE ON
+ COMMENT "Should detect jobserver support"
+ COMMAND ${DETECT_JOBSERVER} "custom_command.txt"
+)
+
+# trigger the custom command to run
+add_custom_target(dummy ALL
+ JOB_SERVER_AWARE ON
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/custom_command.txt
+ COMMAND ${DETECT_JOBSERVER} "custom_target.txt"
+)
diff --git a/Tests/RunCMake/Make/Foo/CMakeLists.txt b/Tests/RunCMake/Make/Foo/CMakeLists.txt
new file mode 100644
index 0000000..baa6634
--- /dev/null
+++ b/Tests/RunCMake/Make/Foo/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.26)
+project(Foo NONE)
+
+add_custom_target(drive ALL COMMAND ${CMAKE_COMMAND} -E true)
diff --git a/Tests/RunCMake/Make/GNUMakeJobServerAware-check.cmake b/Tests/RunCMake/Make/GNUMakeJobServerAware-check.cmake
new file mode 100644
index 0000000..dbc1555
--- /dev/null
+++ b/Tests/RunCMake/Make/GNUMakeJobServerAware-check.cmake
@@ -0,0 +1,18 @@
+set(BUILD_DIR "${RunCMake_BINARY_DIR}/GNUMakeJobServerAware-build")
+
+function(check target regex)
+ file(STRINGS ${BUILD_DIR}/${target} lines
+ REGEX ${regex}
+ )
+
+ list(LENGTH lines len)
+ if(len EQUAL 0)
+ message(FATAL_ERROR "Could not find matching lines '${regex}' in ${BUILD_DIR}/${target}")
+ endif()
+endfunction()
+
+check("CMakeFiles/dummy.dir/build.make" [[\+\$\(CMAKE_COMMAND\) -E true]])
+check("CMakeFiles/dummy2.dir/build.make" [[\+\$\(CMAKE_COMMAND\) -E true]])
+
+check("CMakeFiles/dummy3.dir/build.make" [[\+cd (/d )?"?.*"? && \$\(CMAKE_COMMAND\) -E true]])
+check("CMakeFiles/dummy4.dir/build.make" [[\+cd (/d )?"?.*"? && \$\(CMAKE_COMMAND\) -E true]])
diff --git a/Tests/RunCMake/Make/GNUMakeJobServerAware.cmake b/Tests/RunCMake/Make/GNUMakeJobServerAware.cmake
new file mode 100644
index 0000000..d92e842
--- /dev/null
+++ b/Tests/RunCMake/Make/GNUMakeJobServerAware.cmake
@@ -0,0 +1,31 @@
+# Test JOB_SERVER_AWARE with custom commands
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/missing"
+ JOB_SERVER_AWARE ON
+ COMMAND $(CMAKE_COMMAND) -E true
+)
+add_custom_target(dummy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/missing")
+
+# Test JOB_SERVER_AWARE with custom targets
+add_custom_target(
+ dummy2 ALL
+ JOB_SERVER_AWARE ON
+ COMMAND $(CMAKE_COMMAND) -E true
+)
+
+# Test JOB_SERVER_AWARE with custom commands with WORKING_DIRECTORY
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/missing2"
+ JOB_SERVER_AWARE ON
+ COMMAND $(CMAKE_COMMAND) -E true
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Foo"
+)
+add_custom_target(dummy3 ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/missing2")
+
+# Test JOB_SERVER_AWARE with custom targets with WORKING_DIRECTORY
+add_custom_target(
+ dummy4 ALL
+ JOB_SERVER_AWARE ON
+ COMMAND $(CMAKE_COMMAND) -E true
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Foo"
+)
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index c7717ec..5d1ba48 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -70,3 +70,22 @@ if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
run_CMP0113(OLD)
run_CMP0113(NEW)
endif()
+
+function(detect_jobserver_present)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DetectJobServer-present-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DDETECT_JOBSERVER=${DETECT_JOBSERVER}")
+ run_cmake(DetectJobServer-present)
+ run_cmake_command(DetectJobServer-present-parallel-build ${CMAKE_COMMAND} --build . -j4)
+endfunction()
+
+# Jobservers are currently only supported by GNU makes, except MSYS2 make
+if(MAKE_IS_GNU AND NOT RunCMake_GENERATOR MATCHES "MSYS Makefiles")
+ detect_jobserver_present()
+endif()
+
+if(MAKE_IS_GNU)
+ # In GNU makes, `JOB_SERVER_AWARE` support is implemented by prefixing
+ # commands with the '+' operator.
+ run_cmake(GNUMakeJobServerAware)
+endif()
diff --git a/Tests/RunCMake/Ninja/QtAutoMocDeps-stderr.txt b/Tests/RunCMake/Ninja/QtAutoMocDeps-stderr.txt
new file mode 100644
index 0000000..6024984
--- /dev/null
+++ b/Tests/RunCMake/Ninja/QtAutoMocDeps-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Deprecation Warning at QtSubDir1/CMakeLists\.txt:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0116 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.$
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index bc4a330..3e5ddc5 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -145,7 +145,19 @@ function(run_cmake test)
${maybe_timeout}
${maybe_input_file}
)]])
+ if(DEFINED ENV{PWD})
+ set(old_pwd "$ENV{PWD}")
+ else()
+ set(old_pwd)
+ endif()
+ # Emulate a shell using this directory.
+ set(ENV{PWD} "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}")
cmake_language(EVAL CODE "${_code}")
+ if(DEFINED old_pwd)
+ set(ENV{PWD} "${old_pwd}")
+ else()
+ set(ENV{PWD})
+ endif()
set(msg "")
if(NOT "${actual_result}" MATCHES "${expect_result}")
string(APPEND msg "Result is [${actual_result}], not [${expect_result}].\n")
diff --git a/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake b/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake
index 58a111a..12f004b 100644
--- a/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake
+++ b/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake
@@ -29,8 +29,6 @@ function (run_symlink_test case src bin src_from_bin bin_from_src)
# Test running in binary directory.
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
- # Emulate a shell using this directory.
- set(ENV{PWD} "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}")
# Pass absolute path to the source tree, plain.
set(RunCMake_TEST_VARIANT_DESCRIPTION " $abs/${name}/${src}")
@@ -50,8 +48,6 @@ function (run_symlink_test case src bin src_from_bin bin_from_src)
# Test running in source directory.
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
- # Emulate a shell using this directory.
- set(ENV{PWD} "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}")
# Pass absolute path to the binary tree with -B.
set(RunCMake_TEST_VARIANT_DESCRIPTION " -B $abs/${name}/${bin}")
@@ -63,8 +59,6 @@ function (run_symlink_test case src bin src_from_bin bin_from_src)
# Test running in another directory.
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_BINARY_DIR}/${name}")
- # Emulate a shell using this directory.
- set(ENV{PWD} "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}")
# Pass absolute paths to the source and binary trees.
set(RunCMake_TEST_VARIANT_DESCRIPTION " -S $abs/${name}/${src} -B $abs/${name}/${bin}")
diff --git a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
index c7a118f..537f67d 100644
--- a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
+++ b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
@@ -6,7 +6,7 @@ run_cmake(CMP0078-NEW)
run_cmake(CMP0086-WARN)
-if (CMake_TEST_FindPython)
+if (CMake_TEST_FindPython2 OR CMake_TEST_FindPython3)
macro(run_cmake_target test subtest target)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-Direct-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-Direct-stderr.txt
new file mode 100644
index 0000000..53f603e
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-Direct-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0120-OLD-Direct\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0120 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-stderr.txt
new file mode 100644
index 0000000..fea708f
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/CMP0120-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0120-OLD\.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0120 will be removed from a future version
+ of CMake\.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances\. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/XcFramework/CMakeLists.txt b/Tests/RunCMake/XcFramework/CMakeLists.txt
new file mode 100644
index 0000000..54a4d62
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.26)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/XcFramework/RunCMakeTest.cmake b/Tests/RunCMake/XcFramework/RunCMakeTest.cmake
new file mode 100644
index 0000000..22c28b4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/RunCMakeTest.cmake
@@ -0,0 +1,107 @@
+include(RunCMake)
+
+function(create_library type platform system_name archs sysroot)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-${type}-${platform}-build)
+ run_cmake_with_options(create-${type}-${platform} -DCMAKE_SYSTEM_NAME=${system_name} -DCMAKE_OSX_ARCHITECTURES=${archs} -DCMAKE_OSX_SYSROOT=${sysroot} -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install)
+
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(create-${type}-${platform}-build ${CMAKE_COMMAND} --build . --config Release)
+ run_cmake_command(create-${type}-${platform}-install ${CMAKE_COMMAND} --install . --config Release)
+endfunction()
+
+function(create_libraries type)
+ create_library(${type} macos Darwin "${macos_archs_2}" macosx)
+ create_library(${type} ios iOS "arm64" iphoneos)
+ create_library(${type} tvos tvOS "arm64" appletvos)
+ create_library(${type} watchos watchOS "armv7k\\\\;arm64_32" watchos)
+ if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
+ create_library(${type} visionos visionOS "arm64" xros)
+ endif()
+ create_library(${type} ios-simulator iOS "${macos_archs_2}" iphonesimulator)
+ create_library(${type} tvos-simulator tvOS "${macos_archs_2}" appletvsimulator)
+ create_library(${type} watchos-simulator watchOS "${watch_sim_archs_2}" watchsimulator)
+ if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
+ create_library(${type} visionos-simulator visionOS "${macos_archs_2}" xrsimulator)
+ endif()
+endfunction()
+
+function(create_xcframework name type platforms)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-xcframework-${name}-build)
+ set(args)
+ foreach(platform IN LISTS platforms)
+ if(type STREQUAL "framework")
+ list(APPEND args -framework ${RunCMake_BINARY_DIR}/create-${type}-${platform}-build/install/lib/mylib.framework)
+ else()
+ list(APPEND args -library ${RunCMake_BINARY_DIR}/create-${type}-${platform}-build/install/lib/libmylib.a -headers ${RunCMake_SOURCE_DIR}/mylib/include)
+ endif()
+ endforeach()
+ run_cmake_command(create-xcframework-${name} xcodebuild -create-xcframework ${args} -output ${RunCMake_TEST_BINARY_DIR}/mylib.xcframework)
+endfunction()
+
+function(create_executable name xcfname system_name archs sysroot)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-executable-${name}-build)
+ run_cmake_with_options(create-executable-${name} -DCMAKE_SYSTEM_NAME=${system_name} -DCMAKE_OSX_ARCHITECTURES=${archs} -DCMAKE_OSX_SYSROOT=${sysroot} -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-${xcfname}-build/mylib.xcframework)
+
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(create-executable-${name}-build ${CMAKE_COMMAND} --build . --config Release)
+endfunction()
+
+function(create_executables name type)
+ create_executable(${name}-macos ${type} Darwin "${macos_archs_2}" macosx)
+ create_executable(${name}-ios ${type} iOS "arm64" iphoneos)
+ create_executable(${name}-tvos ${type} tvOS "arm64" appletvos)
+ create_executable(${name}-watchos ${type} watchOS "armv7k\\\\;arm64_32" watchos)
+ if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
+ create_executable(${name}-visionos ${type} visionOS "arm64" xros)
+ endif()
+ create_executable(${name}-ios-simulator ${type} iOS "${macos_archs_2}" iphonesimulator)
+ create_executable(${name}-tvos-simulator ${type} tvOS "${macos_archs_2}" appletvsimulator)
+ create_executable(${name}-watchos-simulator ${type} watchOS "${watch_sim_archs_2}" watchsimulator)
+ if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
+ create_executable(${name}-visionos-simulator ${type} visionOS "${macos_archs_2}" xrsimulator)
+ endif()
+endfunction()
+
+set(xcframework_platforms macos ios tvos watchos ios-simulator tvos-simulator watchos-simulator)
+if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
+ list(APPEND xcframework_platforms visionos visionos-simulator)
+endif()
+if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
+ set(macos_archs_1 "x86_64\\;arm64")
+ set(macos_archs_2 "x86_64\\\\;arm64")
+ set(watch_sim_archs_2 "x86_64")
+else()
+ set(macos_archs_1 "x86_64")
+ set(macos_archs_2 "x86_64")
+ set(watch_sim_archs_2 "i386")
+endif()
+
+create_libraries(library)
+create_libraries(framework)
+create_xcframework(library library "${xcframework_platforms}")
+create_xcframework(framework framework "${xcframework_platforms}")
+create_xcframework(incomplete framework "tvos;watchos")
+create_executables(library library)
+create_executables(framework framework)
+run_cmake_with_options(create-executable-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+create_executables(target-library library)
+create_executables(target-framework framework)
+run_cmake_with_options(create-executable-target-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+if(RunCMake_GENERATOR STREQUAL "Xcode" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
+ create_executables(library-link-phase library)
+ create_executables(framework-link-phase framework)
+ run_cmake_with_options(create-executable-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+ create_executables(target-library-link-phase library)
+ create_executables(target-framework-link-phase framework)
+ run_cmake_with_options(create-executable-target-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
+endif()
+
+# Ensure that .xcframework is found before .framework
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-xcframework-framework-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(copy-framework ${CMAKE_COMMAND} -E copy_directory ${RunCMake_BINARY_DIR}/create-framework-macos-build/install/lib/mylib.framework ${RunCMake_TEST_BINARY_DIR}/mylib.framework)
+unset(RunCMake_TEST_NO_CLEAN)
+unset(RunCMake_TEST_BINARY_DIR)
+
+run_cmake(find-library)
+run_cmake_command(find-library-script ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/find-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-ios-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-ios.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-ios.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-ios.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-macos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-macos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-link-phase-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-macos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-macos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-tvos-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-tvos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-visionos-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-visionos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-watchos-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-framework-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-framework-watchos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-framework-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-result.txt b/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-stderr.txt b/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-stderr.txt
new file mode 100644
index 0000000..5b43e19
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at create-executable\.cmake:[0-9]+ \(target_link_libraries\):
+ Unable to find suitable library in:
+
+ [^
+]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
+
+ for system name "Darwin"
+Call Stack \(most recent call first\):
+ create-executable-link-phase\.cmake:[0-9]+ \(include\)
+ create-executable-incomplete-link-phase\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase.cmake b/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-incomplete-link-phase.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-incomplete-result.txt b/Tests/RunCMake/XcFramework/create-executable-incomplete-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-incomplete-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/XcFramework/create-executable-incomplete-stderr.txt b/Tests/RunCMake/XcFramework/create-executable-incomplete-stderr.txt
new file mode 100644
index 0000000..66b7d62
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-incomplete-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at create-executable\.cmake:[0-9]+ \(target_link_libraries\):
+ Unable to find suitable library in:
+
+ [^
+]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
+
+ for system name "Darwin"
+Call Stack \(most recent call first\):
+ create-executable-incomplete\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/XcFramework/create-executable-incomplete.cmake b/Tests/RunCMake/XcFramework/create-executable-incomplete.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-incomplete.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-ios-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-library-ios.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-ios.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-ios.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-macos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-macos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos-simulator.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos.cmake
new file mode 100644
index 0000000..2888c85
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-link-phase-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-macos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-macos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-tvos-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-tvos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-visionos-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-visionos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-library-watchos-simulator.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-library-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-library-watchos.cmake
new file mode 100644
index 0000000..760d9d4
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-library-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-link-phase.cmake b/Tests/RunCMake/XcFramework/create-executable-link-phase.cmake
new file mode 100644
index 0000000..9884781
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-link-phase.cmake
@@ -0,0 +1,2 @@
+include(create-executable.cmake)
+set_property(TARGET myexe PROPERTY XCODE_LINK_BUILD_PHASE_MODE "KNOWN_LOCATION")
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-ios-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-ios.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-ios.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-ios.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-macos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-macos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-link-phase-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-macos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-macos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-tvos-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-tvos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-visionos-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-visionos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-watchos-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-framework-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-framework-watchos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-framework-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-result.txt b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-stderr.txt b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-stderr.txt
new file mode 100644
index 0000000..1308933
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at create-executable-target\.cmake:[0-9]+ \(target_link_libraries\):
+ Unable to find suitable library in:
+
+ [^
+]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
+
+ for system name "Darwin"
+Call Stack \(most recent call first\):
+ create-executable-target-link-phase\.cmake:[0-9]+ \(include\)
+ create-executable-target-incomplete-link-phase\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase.cmake b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-link-phase.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-incomplete-result.txt b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-incomplete-stderr.txt b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-stderr.txt
new file mode 100644
index 0000000..716b17d
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-incomplete-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at create-executable-target\.cmake:[0-9]+ \(target_link_libraries\):
+ Unable to find suitable library in:
+
+ [^
+]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
+
+ for system name "Darwin"
+Call Stack \(most recent call first\):
+ create-executable-target-incomplete\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-incomplete.cmake b/Tests/RunCMake/XcFramework/create-executable-target-incomplete.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-incomplete.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-ios-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-ios.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-ios.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-ios.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-macos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-macos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos-simulator.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos.cmake
new file mode 100644
index 0000000..dfeccb9
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-link-phase-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable-target-link-phase.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-macos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-macos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-macos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-tvos-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-tvos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-tvos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-tvos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-visionos-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-visionos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-visionos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-visionos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-watchos-simulator.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-library-watchos.cmake b/Tests/RunCMake/XcFramework/create-executable-target-library-watchos.cmake
new file mode 100644
index 0000000..b2e3469
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-library-watchos.cmake
@@ -0,0 +1 @@
+include(create-executable-target.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-executable-target-link-phase.cmake b/Tests/RunCMake/XcFramework/create-executable-target-link-phase.cmake
new file mode 100644
index 0000000..9c0b0d5
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target-link-phase.cmake
@@ -0,0 +1,2 @@
+include(create-executable-target.cmake)
+set_property(TARGET myexe PROPERTY XCODE_LINK_BUILD_PHASE_MODE "KNOWN_LOCATION")
diff --git a/Tests/RunCMake/XcFramework/create-executable-target.cmake b/Tests/RunCMake/XcFramework/create-executable-target.cmake
new file mode 100644
index 0000000..0cc356c
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable-target.cmake
@@ -0,0 +1,21 @@
+enable_language(C)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
+endif()
+
+add_library(mylib IMPORTED STATIC)
+set_property(TARGET mylib PROPERTY IMPORTED_LOCATION ${MYLIB_LIBRARY})
+
+add_executable(myexe myexe/myexe.c)
+target_link_libraries(myexe PRIVATE mylib)
diff --git a/Tests/RunCMake/XcFramework/create-executable.cmake b/Tests/RunCMake/XcFramework/create-executable.cmake
new file mode 100644
index 0000000..6706b9f
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-executable.cmake
@@ -0,0 +1,18 @@
+enable_language(C)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
+endif()
+
+add_executable(myexe myexe/myexe.c)
+target_link_libraries(myexe PRIVATE ${MYLIB_LIBRARY})
diff --git a/Tests/RunCMake/XcFramework/create-framework-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-framework-ios-simulator.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-ios.cmake b/Tests/RunCMake/XcFramework/create-framework-ios.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-ios.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-macos.cmake b/Tests/RunCMake/XcFramework/create-framework-macos.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-macos.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-framework-tvos-simulator.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-tvos.cmake b/Tests/RunCMake/XcFramework/create-framework-tvos.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-tvos.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-framework-visionos-simulator.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-visionos.cmake b/Tests/RunCMake/XcFramework/create-framework-visionos.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-visionos.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-framework-watchos-simulator.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework-watchos.cmake b/Tests/RunCMake/XcFramework/create-framework-watchos.cmake
new file mode 100644
index 0000000..8b7df9b
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework-watchos.cmake
@@ -0,0 +1 @@
+include(create-framework.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-framework.cmake b/Tests/RunCMake/XcFramework/create-framework.cmake
new file mode 100644
index 0000000..f4406e6
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-framework.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_FRAMEWORK ON)
+include(create-library-common.cmake)
+install(FILES mylib/include/mylib/mylib.h DESTINATION lib/mylib.framework/Headers)
diff --git a/Tests/RunCMake/XcFramework/create-library-common.cmake b/Tests/RunCMake/XcFramework/create-library-common.cmake
new file mode 100644
index 0000000..958660d
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-common.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
+endif()
+
+add_library(mylib STATIC mylib/mylib.c)
+install(TARGETS mylib DESTINATION lib)
diff --git a/Tests/RunCMake/XcFramework/create-library-ios-simulator.cmake b/Tests/RunCMake/XcFramework/create-library-ios-simulator.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-ios-simulator.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-ios.cmake b/Tests/RunCMake/XcFramework/create-library-ios.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-ios.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-macos.cmake b/Tests/RunCMake/XcFramework/create-library-macos.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-macos.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-tvos-simulator.cmake b/Tests/RunCMake/XcFramework/create-library-tvos-simulator.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-tvos-simulator.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-tvos.cmake b/Tests/RunCMake/XcFramework/create-library-tvos.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-tvos.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-visionos-simulator.cmake b/Tests/RunCMake/XcFramework/create-library-visionos-simulator.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-visionos-simulator.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-visionos.cmake b/Tests/RunCMake/XcFramework/create-library-visionos.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-visionos.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-watchos-simulator.cmake b/Tests/RunCMake/XcFramework/create-library-watchos-simulator.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-watchos-simulator.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library-watchos.cmake b/Tests/RunCMake/XcFramework/create-library-watchos.cmake
new file mode 100644
index 0000000..a9f5dee
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library-watchos.cmake
@@ -0,0 +1 @@
+include(create-library.cmake)
diff --git a/Tests/RunCMake/XcFramework/create-library.cmake b/Tests/RunCMake/XcFramework/create-library.cmake
new file mode 100644
index 0000000..f2a5249
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/create-library.cmake
@@ -0,0 +1 @@
+include(create-library-common.cmake)
diff --git a/Tests/RunCMake/XcFramework/find-library.cmake b/Tests/RunCMake/XcFramework/find-library.cmake
new file mode 100644
index 0000000..c5fe8db
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/find-library.cmake
@@ -0,0 +1,5 @@
+find_library(MYLIB_XCFRAMEWORK mylib NO_DEFAULT_PATH PATHS "${CMAKE_BINARY_DIR}/../create-xcframework-framework-build")
+file(REAL_PATH "${CMAKE_BINARY_DIR}/../create-xcframework-framework-build/mylib.xcframework" expected_path)
+if(NOT MYLIB_XCFRAMEWORK STREQUAL expected_path)
+ message(FATAL_ERROR "Expected value of MYLIB_XCFRAMEWORK:\n ${expected_path}\nActual value:\n ${MYLIB_XCFRAMEWORK}")
+endif()
diff --git a/Tests/RunCMake/XcFramework/myexe/myexe.c b/Tests/RunCMake/XcFramework/myexe/myexe.c
new file mode 100644
index 0000000..d04efbd
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/myexe/myexe.c
@@ -0,0 +1,7 @@
+#include <mylib/mylib.h>
+
+int main(void)
+{
+ mylib();
+ return 0;
+}
diff --git a/Tests/RunCMake/XcFramework/mylib/include/mylib/mylib.h b/Tests/RunCMake/XcFramework/mylib/include/mylib/mylib.h
new file mode 100644
index 0000000..1de07aa
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/mylib/include/mylib/mylib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+extern void mylib(void);
diff --git a/Tests/RunCMake/XcFramework/mylib/mylib.c b/Tests/RunCMake/XcFramework/mylib/mylib.c
new file mode 100644
index 0000000..4489684
--- /dev/null
+++ b/Tests/RunCMake/XcFramework/mylib/mylib.c
@@ -0,0 +1,3 @@
+void mylib(void)
+{
+}
diff --git a/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.c b/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.c
index 5e0f40f..c00fce7 100644
--- a/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.c
+++ b/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.c
@@ -5,6 +5,10 @@
# if __MAC_OS_X_VERSION_MIN_REQUIRED != __MAC_10_11
# error macOS deployment version mismatch
# endif
+#elif TARGET_OS_XR
+# if __XR_OS_VERSION_MIN_REQUIRED != __XROS_1_0
+# error visionOS deployment version mismatch
+# endif
#elif TARGET_OS_IOS
# if __IPHONE_OS_VERSION_MIN_REQUIRED != __IPHONE_9_1
# error iOS deployment version mismatch
diff --git a/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.cmake b/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.cmake
index 234ceef..80e3877 100644
--- a/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.cmake
+++ b/Tests/RunCMake/XcodeProject-Device/DeploymentTarget.cmake
@@ -7,6 +7,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS")
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "1.0")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
elseif(CMAKE_SYSTEM_NAME STREQUAL "watchOS")
set(CMAKE_OSX_DEPLOYMENT_TARGET "2.0")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
diff --git a/Tests/RunCMake/XcodeProject-Device/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject-Device/RunCMakeTest.cmake
index e2ed045..abb357b 100644
--- a/Tests/RunCMake/XcodeProject-Device/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject-Device/RunCMakeTest.cmake
@@ -93,6 +93,25 @@ if(NOT XCODE_VERSION VERSION_LESS 7.1)
unset(RunCMake_TEST_OPTIONS)
endif()
+if(NOT XCODE_VERSION VERSION_LESS 15)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesVisionOS-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_SYSTEM_NAME=visionOS"
+ "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeBundles)
+ run_cmake_command(XcodeBundles-build-visionOS ${CMAKE_COMMAND} --build .)
+ run_cmake_command(XcodeBundles-install-visionOS ${CMAKE_COMMAND} --build . --target install)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
+
if(NOT XCODE_VERSION VERSION_LESS 7)
set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/osx.cmake")
run_cmake(XcodeTbdStub)
@@ -242,6 +261,10 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 8)
deployment_target_test(tvOS appletvsimulator)
deployment_target_test(watchOS watchos)
deployment_target_test(watchOS watchsimulator)
+ if(XCODE_VERSION VERSION_GREATER_EQUAL 15)
+ deployment_target_test(visionOS xros)
+ deployment_target_test(visionOS xrsimulator)
+ endif()
endif()
if(XCODE_VERSION VERSION_GREATER_EQUAL 8)
@@ -288,9 +311,11 @@ if (XCODE_VERSION VERSION_GREATER_EQUAL 7.3)
endfunction()
if(XCODE_VERSION VERSION_GREATER_EQUAL 12)
- xctest_add_bundle_test(Darwin macosx "1" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns")
xctest_add_bundle_test(Darwin macosx "12" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns")
- xctest_add_bundle_test(iOS iphonesimulator "1" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns")
+ if(XCODE_VERSION VERSION_LESS 14)
+ xctest_add_bundle_test(Darwin macosx "1" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns")
+ xctest_add_bundle_test(iOS iphonesimulator "1" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns")
+ endif()
if (XCODE_VERSION VERSION_LESS 12.5)
xctest_add_bundle_test(iOS iphonesimulator "12" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>")
else()
diff --git a/Tests/RunCMake/XcodeProject-Device/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject-Device/XcodeBundles.cmake
index a9fafd2..376a7fc 100644
--- a/Tests/RunCMake/XcodeProject-Device/XcodeBundles.cmake
+++ b/Tests/RunCMake/XcodeProject-Device/XcodeBundles.cmake
@@ -9,7 +9,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
endif()
-if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
+if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns-macOS-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns-macOS-check.cmake
index 576be11..66db44e 100644
--- a/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns-macOS-check.cmake
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns-macOS-check.cmake
@@ -1,4 +1,3 @@
include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake)
-findAttribute(${test} "RemoveHeadersOnCopy" TRUE)
findAttribute(${test} "CodeSignOnCopy" FALSE)
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns.cmake
index 1bd1bd0..f5c9364 100644
--- a/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns.cmake
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedPlugIns.cmake
@@ -1,4 +1,4 @@
-add_executable(plug_in MACOS_BUNDLE Empty.txt)
+add_executable(plug_in MACOSX_BUNDLE Empty.txt)
set_target_properties(plug_in PROPERTIES
LINKER_LANGUAGE CXX
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS-check.cmake
new file mode 100644
index 0000000..75aaa91
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS-check.cmake
@@ -0,0 +1,3 @@
+include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake)
+
+findAttribute(${test} "Embed Resources" TRUE)
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS.cmake
new file mode 100644
index 0000000..54f9fc8
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-iOS.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/EmbedResources.cmake)
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS-check.cmake
new file mode 100644
index 0000000..75aaa91
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS-check.cmake
@@ -0,0 +1,3 @@
+include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake)
+
+findAttribute(${test} "Embed Resources" TRUE)
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS.cmake
new file mode 100644
index 0000000..54f9fc8
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedResources-macOS.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/EmbedResources.cmake)
diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedResources.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedResources.cmake
new file mode 100644
index 0000000..0638037
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject-Embed/EmbedResources.cmake
@@ -0,0 +1,18 @@
+add_executable(app MACOSX_BUNDLE main.m)
+
+set(EMBED_RESOURCES_FOLDER ${CMAKE_BINARY_DIR}/runtime/shaders)
+
+# ensure embed resources folder exists
+if (NOT (IS_DIRECTORY ${EMBED_RESOURCES_FOLDER}))
+ file(MAKE_DIRECTORY ${EMBED_RESOURCES_FOLDER})
+endif()
+
+set_target_properties(app PROPERTIES
+ XCODE_EMBED_RESOURCES_PATH ${EMBED_RESOURCES_FOLDER}
+)
+
+set_target_properties(app PROPERTIES
+ XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
+ MACOSX_BUNDLE_GUI_IDENTIFIER "com.example.app"
+)
diff --git a/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake
index a7bccee..3798ddc 100644
--- a/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake
@@ -83,6 +83,25 @@ function(TestExtensionKitExtension platform)
)
endfunction()
+function(TestEmbedCommon what platform)
+ set(testName Embed${what}-${platform})
+ if(NOT platform STREQUAL "macOS")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_SYSTEM_NAME=${platform})
+ endif()
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-build)
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(${testName})
+ run_cmake_command(${testName}-build
+ ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR}
+ --config Debug
+ --target app
+ )
+endfunction()
+
# Isolate device tests from host architecture selection.
unset(ENV{CMAKE_OSX_ARCHITECTURES})
@@ -100,4 +119,7 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 14.1)
# defaults, which is to remove headers on copy, but not code sign.
TestAppExtension(macOS)
TestAppExtension(iOS)
+ TestEmbedCommon(Resources macOS)
+ TestEmbedCommon(Resources iOS)
+ TestEmbedCommon(PlugIns macOS)
endif()
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt
new file mode 100644
index 0000000..d5a0ca8
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt
@@ -0,0 +1 @@
+MSYSTEM_PREFIX=''
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake
new file mode 100644
index 0000000..ac36c8d
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake
@@ -0,0 +1,3 @@
+unset(ENV{MSYSTEM})
+cmake_host_system_information(RESULT result QUERY MSYSTEM_PREFIX)
+message(STATUS "MSYSTEM_PREFIX='${result}'")
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt
new file mode 100644
index 0000000..89c4e9b
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error at [^
+]*/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake:[0-9]+ \(cmake_host_system_information\):
+ cmake_host_system_information does not recognize <key> MSYSTEM_PREFIX$
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake
new file mode 100644
index 0000000..dc1def3
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake
@@ -0,0 +1,2 @@
+unset(ENV{MSYSTEM})
+cmake_host_system_information(RESULT result QUERY MSYSTEM_PREFIX)
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt
new file mode 100644
index 0000000..f6e2549
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt
@@ -0,0 +1,2 @@
+-- MSYSTEM_PREFIX='[^
+]+'
diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake
new file mode 100644
index 0000000..d1c996b
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake
@@ -0,0 +1,7 @@
+cmake_host_system_information(RESULT result QUERY MSYSTEM_PREFIX)
+message(STATUS "MSYSTEM_PREFIX='${result}'")
+if(CMake_TEST_MSYSTEM_PREFIX)
+ if(NOT "${result}" STREQUAL "${CMake_TEST_MSYSTEM_PREFIX}")
+ message(FATAL_ERROR "Actual result:\n ${result}\nis not expected result:\n ${CMake_TEST_MSYSTEM_PREFIX}")
+ endif()
+endif()
diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
index 9122470..0b3576d 100644
--- a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
@@ -22,6 +22,17 @@ else()
run_cmake(VsMSBuildMissing)
endif()
+if(CMAKE_HOST_WIN32)
+ run_cmake_script(MSYSTEM_PREFIX-Empty)
+ if("$ENV{MSYSTEM}" MATCHES "(MSYS|MINGW32|MINGW64|UCRT64)")
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-$ENV{MSYSTEM}")
+ run_cmake_script(MSYSTEM_PREFIX -DCMake_TEST_MSYSTEM_PREFIX=${CMake_TEST_MSYSTEM_PREFIX})
+ unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+ endif()
+else()
+ run_cmake_script(MSYSTEM_PREFIX-Missing)
+endif()
+
# WINDOWS_REGISTRY tests
run_cmake(Registry_NoArgs)
run_cmake(Registry_BadQuery1)
diff --git a/Tests/CTestTestFailure/badCode.cxx b/Tests/RunCMake/ctest_build/BuildFailure.cxx
index 8102883..8102883 100644
--- a/Tests/CTestTestFailure/badCode.cxx
+++ b/Tests/RunCMake/ctest_build/BuildFailure.cxx
diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
index 12525f2..af56ead 100644
--- a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
@@ -13,18 +13,18 @@ endfunction()
run_ctest_build(BuildQuiet QUIET)
run_ctest_build(ParallelLevel PARALLEL_LEVEL 1)
-function(run_BuildFailure)
- set(CASE_CMAKELISTS_SUFFIX_CODE [[
-add_custom_target(BuildFailure ALL COMMAND command-does-not-exist)
-]])
+block()
+ set(LANG CXX)
+ configure_file("${RunCMake_SOURCE_DIR}/BuildFailure.cxx" "${RunCMake_BINARY_DIR}/BuildFailure/BuildFailure.cxx" COPYONLY)
+ set(CASE_CMAKELISTS_SUFFIX_CODE [=[
+ add_executable(BuildFailure BuildFailure.cxx)
+ ]=])
set(CASE_CMAKELISTS_PREFIX_CODE [[
if(NOT CTEST_USE_LAUNCHERS)
message(FATAL_ERROR "CTEST_USE_LAUNCHERS not set")
endif()
]])
- set(CASE_TEST_PREFIX_CODE [[
-cmake_policy(SET CMP0061 NEW)
-]])
+ set(CASE_TEST_PREFIX_CODE "")
set(CASE_TEST_SUFFIX_CODE [[
if (ctest_build_return_value)
message("ctest_build returned non-zero")
@@ -35,13 +35,16 @@ endif()
run_ctest(BuildFailure)
if (RunCMake_GENERATOR MATCHES "Makefiles")
+ set(LANG NONE)
set(CASE_TEST_PREFIX_CODE [[
cmake_policy(VERSION 3.2)
]])
+ set(CASE_CMAKELISTS_SUFFIX_CODE [[
+add_custom_target(BuildFailure ALL COMMAND command-does-not-exist)
+]])
run_ctest(BuildFailure-CMP0061-OLD)
endif()
-endfunction()
-run_BuildFailure()
+endblock()
function(run_BuildChangeId)
set(CASE_TEST_PREFIX_CODE [[
diff --git a/Tests/RunCMake/ctest_test/NotRun-result.txt b/Tests/RunCMake/ctest_test/NotRun-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/NotRun-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_test/NotRun-stderr.txt b/Tests/RunCMake/ctest_test/NotRun-stderr.txt
new file mode 100644
index 0000000..85907f3
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/NotRun-stderr.txt
@@ -0,0 +1,2 @@
+.*Unable to find executable[^
+]*does_not_exist
diff --git a/Tests/RunCMake/ctest_test/NotRun-stdout.txt b/Tests/RunCMake/ctest_test/NotRun-stdout.txt
new file mode 100644
index 0000000..8d60833
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/NotRun-stdout.txt
@@ -0,0 +1,7 @@
+.*Could not find executable[^
+]*does_not_exist
+.*
+50% tests passed, 1 tests failed out of 2
+.*
+The following tests FAILED:
+.*testNotRun \(Not Run\)
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
index 242a059..d2f3da3 100644
--- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -53,6 +53,13 @@ unset(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING})
unset(CASE_CTEST_TEST_LOAD)
unset(RunCTest_VERBOSE_FLAG)
+block()
+ set(CASE_CMAKELISTS_SUFFIX_CODE [[
+ add_test(NAME testNotRun COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist)
+ ]])
+ run_ctest_test(NotRun)
+endblock()
+
function(run_TestChangeId)
set(CASE_TEST_PREFIX_CODE [[
set(CTEST_CHANGE_ID "<>1")
@@ -131,8 +138,7 @@ run_TestRepeat(AfterTimeout RETURN_VALUE:0 REPEAT AFTER_TIMEOUT:3)
# test repeat and not run tests interact correctly
set(CASE_CMAKELISTS_SUFFIX_CODE [[
-add_test(NAME testNotRun
- COMMAND ${CMAKE_COMMAND}/doesnt_exist)
+ add_test(NAME testNotRun COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist)
set_property(TEST testNotRun PROPERTY TIMEOUT 5)
]])
run_TestRepeat(NotRun RETURN_VALUE:1 REPEAT UNTIL_PASS:3)
diff --git a/Tests/RunCMake/ctest_test/TestRepeatNotRun-stderr.txt b/Tests/RunCMake/ctest_test/TestRepeatNotRun-stderr.txt
index a69932d..85907f3 100644
--- a/Tests/RunCMake/ctest_test/TestRepeatNotRun-stderr.txt
+++ b/Tests/RunCMake/ctest_test/TestRepeatNotRun-stderr.txt
@@ -1 +1,2 @@
-.*Unable to find executable.*
+.*Unable to find executable[^
+]*does_not_exist
diff --git a/Tests/RunCMake/ctest_test/TestRepeatNotRun-stdout.txt b/Tests/RunCMake/ctest_test/TestRepeatNotRun-stdout.txt
index 72c98bc..8d60833 100644
--- a/Tests/RunCMake/ctest_test/TestRepeatNotRun-stdout.txt
+++ b/Tests/RunCMake/ctest_test/TestRepeatNotRun-stdout.txt
@@ -1,5 +1,7 @@
+.*Could not find executable[^
+]*does_not_exist
.*
50% tests passed, 1 tests failed out of 2
.*
The following tests FAILED:
-.*testNotRun.*Not Run.*
+.*testNotRun \(Not Run\)
diff --git a/Tests/RunCMake/detect_jobserver.c b/Tests/RunCMake/detect_jobserver.c
new file mode 100644
index 0000000..8cbfe2e
--- /dev/null
+++ b/Tests/RunCMake/detect_jobserver.c
@@ -0,0 +1,179 @@
+#ifndef _CRT_SECURE_NO_WARNINGS
+# define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1928
+# pragma warning(disable : 5105) /* macro expansion warning in windows.h */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_MESSAGE_LENGTH 1023
+#define USAGE "Usage: %s <output_file>\n"
+
+// Extracts the jobserver details from the MAKEFLAGS environment variable.
+//
+// Returns a pointer to either a string of the form "R,W" where R and W are fds
+// or "fifo:PATH".
+//
+// Returns NULL if MAKEFLAGS is not set or does not contain recognized
+// jobserver flags.
+char* jobserver_auth(char* message)
+{
+ const char* jobserver_flags[3] = { "--jobserver-auth=", "--jobserver-fds=",
+ "-J" };
+ char* start = NULL;
+ char* end;
+ char* result;
+ size_t len;
+ int i;
+
+ char* makeflags = getenv("MAKEFLAGS");
+ if (makeflags == NULL) {
+ strncpy(message, "MAKEFLAGS not set", MAX_MESSAGE_LENGTH);
+ return NULL;
+ }
+
+ fprintf(stdout, "MAKEFLAGS: %s\n", makeflags);
+
+ for (i = 0; i < 3; i++) {
+ start = strstr(makeflags, jobserver_flags[i]);
+ if (start != NULL) {
+ start += strlen(jobserver_flags[i]);
+ break;
+ }
+ }
+
+ if (start == NULL) {
+ strncpy(message, "No jobserver flags found", MAX_MESSAGE_LENGTH);
+ return NULL;
+ }
+
+ // Skip leading white space
+ while (*start == ' ' || *start == '\t') {
+ start++;
+ }
+
+ end = strchr(start, ' ');
+ if (end == NULL) {
+ end = start + strlen(start);
+ }
+ len = (size_t)(end - start);
+ result = (char*)malloc(len + 1);
+ strncpy(result, start, len);
+ result[len] = '\0';
+
+ return result;
+}
+
+#if defined(_WIN32)
+# include <windows.h>
+
+int windows_semaphore(const char* semaphore, char* message)
+{
+ // Open the semaphore
+ HANDLE hSemaphore = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, semaphore);
+
+ if (hSemaphore == NULL) {
+# if defined(_MSC_VER) && _MSC_VER < 1900
+ sprintf(message, "Error opening semaphore: %s (%ld)\n", semaphore,
+ GetLastError());
+# else
+ snprintf(message, MAX_MESSAGE_LENGTH,
+ "Error opening semaphore: %s (%ld)\n", semaphore, GetLastError());
+# endif
+ return 1;
+ }
+
+ strncpy(message, "Success", MAX_MESSAGE_LENGTH);
+ return 0;
+}
+#else
+# include <errno.h>
+# include <fcntl.h>
+
+int test_fd(int read_fd, int write_fd, char* message)
+{
+ // Detect if the file descriptors are valid
+ int read_good = fcntl(read_fd, F_GETFD) != -1;
+ int read_error = errno;
+
+ int write_good = fcntl(write_fd, F_GETFD) != -1;
+ int write_error = errno;
+
+ if (!read_good || !write_good) {
+ snprintf(message, MAX_MESSAGE_LENGTH,
+ "Error opening file descriptors: %d (%s), %d (%s)\n", read_fd,
+ strerror(read_error), write_fd, strerror(write_error));
+ return 1;
+ }
+
+ snprintf(message, MAX_MESSAGE_LENGTH, "Success\n");
+ return 0;
+}
+
+int posix(const char* jobserver, char* message)
+{
+ int read_fd;
+ int write_fd;
+ const char* path;
+
+ // First try to parse as "R,W" file descriptors
+ if (sscanf(jobserver, "%d,%d", &read_fd, &write_fd) == 2) {
+ return test_fd(read_fd, write_fd, message);
+ }
+
+ // Then try to parse as "fifo:PATH"
+ if (strncmp(jobserver, "fifo:", 5) == 0) {
+ path = jobserver + 5;
+ read_fd = open(path, O_RDONLY);
+ write_fd = open(path, O_WRONLY);
+ return test_fd(read_fd, write_fd, message);
+ }
+
+ // We don't understand the format
+ snprintf(message, MAX_MESSAGE_LENGTH, "Unrecognized jobserver format: %s\n",
+ jobserver);
+ return 1;
+}
+#endif
+
+// Takes 1 argument: an outfile to write results to.
+int main(int argc, char** argv)
+{
+ char message[MAX_MESSAGE_LENGTH + 1];
+ char* output_file;
+ FILE* fp;
+ char* jobserver;
+ int result;
+
+ if (argc != 2) {
+ fprintf(stderr, USAGE, argv[0]);
+ return 2;
+ }
+
+ output_file = argv[1];
+ fp = fopen(output_file, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "Error opening output file: %s\n", output_file);
+ return 2;
+ }
+
+ jobserver = jobserver_auth(message);
+ if (jobserver == NULL) {
+ fprintf(stderr, "%s\n", message);
+ return 1;
+ }
+
+#if defined(_WIN32)
+ result = windows_semaphore(jobserver, message);
+#else
+ result = posix(jobserver, message);
+#endif
+ free(jobserver);
+ message[MAX_MESSAGE_LENGTH] = '\0';
+
+ return result;
+}
diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake
index c2f9144..1f89829 100644
--- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake
+++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake
@@ -34,6 +34,7 @@ run_cmake_command(AnyCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyC
run_cmake_command(LastCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandError.cmake)
run_cmake_command(LastCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandTimeout.cmake)
run_cmake_command(LastCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGood.cmake)
+run_cmake_command(Stdin ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/Stdin.cmake)
if(UNIX AND Python_EXECUTABLE)
run_cmake_command(AnyCommandAbnormalExit ${CMAKE_COMMAND} -DPython_EXECUTABLE=${Python_EXECUTABLE} -P ${RunCMake_SOURCE_DIR}/AnyCommandAbnormalExit.cmake)
diff --git a/Tests/RunCMake/execute_process/Stdin-stdin.txt b/Tests/RunCMake/execute_process/Stdin-stdin.txt
new file mode 100644
index 0000000..cd08755
--- /dev/null
+++ b/Tests/RunCMake/execute_process/Stdin-stdin.txt
@@ -0,0 +1 @@
+Hello world!
diff --git a/Tests/RunCMake/execute_process/Stdin-stdout.txt b/Tests/RunCMake/execute_process/Stdin-stdout.txt
new file mode 100644
index 0000000..04bd136
--- /dev/null
+++ b/Tests/RunCMake/execute_process/Stdin-stdout.txt
@@ -0,0 +1 @@
+^Hello world!$
diff --git a/Tests/RunCMake/execute_process/Stdin.cmake b/Tests/RunCMake/execute_process/Stdin.cmake
new file mode 100644
index 0000000..e8a2098
--- /dev/null
+++ b/Tests/RunCMake/execute_process/Stdin.cmake
@@ -0,0 +1 @@
+execute_process(COMMAND ${PRINT_STDIN_EXE})
diff --git a/Tests/RunCMake/file/REAL_PATH.cmake b/Tests/RunCMake/file/REAL_PATH.cmake
index 9c5d4ea..08d400d 100644
--- a/Tests/RunCMake/file/REAL_PATH.cmake
+++ b/Tests/RunCMake/file/REAL_PATH.cmake
@@ -13,6 +13,43 @@ if (NOT WIN32 OR CYGWIN)
if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt")
message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"")
endif()
+
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/")
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/")
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin/")
+ file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin" "${CMAKE_CURRENT_BINARY_DIR}/dir/bin" SYMBOLIC)
+
+ cmake_policy(SET CMP0152 NEW)
+ file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../" real_path)
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested\"")
+ endif()
+
+ file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../bin" real_path)
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin\"")
+ endif()
+
+ file(REAL_PATH "dir/bin/../bin" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin\"")
+ endif()
+
+ file(REAL_PATH "../bin" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/" )
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin\"")
+ endif()
+
+ cmake_policy(SET CMP0152 OLD)
+ file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../" real_path)
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested\"")
+ endif()
+ file(REAL_PATH "../" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/")
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir\"")
+ endif()
+
endif()
diff --git a/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt b/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt
index 185720b..b0bf460 100644
--- a/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt
+++ b/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt
@@ -1,4 +1,4 @@
.*find_library considered the following locations.*
-.*\(lib\)library_no_exist\(\\.tbd\|\\.dylib\|\\.so\|\\.a\).*
+.*liblibrary_no_exist\(\\.tbd\|\\.dylib\|\\.so\|\\.a\).*
.*The item was found at.*
.*lib/libcreated.a.*
diff --git a/Tests/RunCMake/find_library/FromScriptMode-stderr.txt b/Tests/RunCMake/find_library/FromScriptMode-stderr.txt
index 046f680..6f25184 100644
--- a/Tests/RunCMake/find_library/FromScriptMode-stderr.txt
+++ b/Tests/RunCMake/find_library/FromScriptMode-stderr.txt
@@ -1,4 +1,4 @@
.*find_library considered the following locations.*
-.*\(lib\)library_no_exist\(\\.so\|\\.a\).*
+.*liblibrary_no_exist\(\\.so\|\\.a\).*
.*The item was found at.*
.*lib/libcreated.a.*
diff --git a/Tests/RunCMake/get_property/test_properties-stderr.txt b/Tests/RunCMake/get_property/test_properties-stderr.txt
index a447280..9f5a10f 100644
--- a/Tests/RunCMake/get_property/test_properties-stderr.txt
+++ b/Tests/RunCMake/get_property/test_properties-stderr.txt
@@ -1,6 +1,12 @@
-^get_test_property: --><--
+^get_test_property: -->value<--
+get_property: -->value<--
+get_test_property: --><--
get_property: --><--
get_test_property: -->value<--
get_property: -->value<--
get_test_property: -->NOTFOUND<--
-get_property: --><--$
+get_property: --><--
+get_test_property: -->anotherValue<--
+get_property: -->anotherValue<--
+get_test_property: -->anotherValue<--
+get_property: -->anotherValue<--$
diff --git a/Tests/RunCMake/get_property/test_properties.cmake b/Tests/RunCMake/get_property/test_properties.cmake
index 1d0295c..f1cbca4 100644
--- a/Tests/RunCMake/get_property/test_properties.cmake
+++ b/Tests/RunCMake/get_property/test_properties.cmake
@@ -1,7 +1,11 @@
-function (check_test_property test prop)
- get_test_property("${test}" "${prop}" gtp_val)
+function (check_test_property test prop dir)
+ set(dir_args)
+ if(dir)
+ set(dir_args DIRECTORY ${dir})
+ endif()
+ get_test_property("${test}" "${prop}" ${dir_args} gtp_val)
get_property(gp_val
- TEST "${test}"
+ TEST "${test}" ${dir_args}
PROPERTY "${prop}")
message("get_test_property: -->${gtp_val}<--")
@@ -11,7 +15,10 @@ endfunction ()
include(CTest)
add_test(NAME test COMMAND "${CMAKE_COMMAND}" --help)
set_tests_properties(test PROPERTIES empty "" custom value)
+add_subdirectory(test_properties)
-check_test_property(test empty)
-check_test_property(test custom)
-check_test_property(test noexist)
+check_test_property(test empty "")
+check_test_property(test custom "")
+check_test_property(test noexist "")
+check_test_property(test custom test_properties)
+check_test_property(test custom ${CMAKE_BINARY_DIR}/test_properties)
diff --git a/Tests/RunCMake/get_property/test_properties/CMakeLists.txt b/Tests/RunCMake/get_property/test_properties/CMakeLists.txt
new file mode 100644
index 0000000..ee90344
--- /dev/null
+++ b/Tests/RunCMake/get_property/test_properties/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_test(NAME test COMMAND "${CMAKE_COMMAND}" --help)
+set_tests_properties(test PROPERTIES empty "" custom anotherValue)
+
+check_test_property(test custom ..)
diff --git a/Tests/RunCMake/property_init/Always.cmake b/Tests/RunCMake/property_init/Always.cmake
new file mode 100644
index 0000000..db23563
--- /dev/null
+++ b/Tests/RunCMake/property_init/Always.cmake
@@ -0,0 +1,15 @@
+set(properties
+ # property expected alias
+ # Test a property which should never be initialized.
+ "notset" "<UNSET>" "<SAME>"
+
+ # Build graph properties
+ "VERIFY_INTERFACE_HEADER_SETS" "TRUE" "<SAME>"
+
+ # Metadata
+ "FOLDER" "folder" "<SAME>"
+ )
+
+prepare_target_types(always ${all_target_types})
+
+run_property_tests(always properties)
diff --git a/Tests/RunCMake/property_init/CMakeLists.txt b/Tests/RunCMake/property_init/CMakeLists.txt
new file mode 100644
index 0000000..51883af
--- /dev/null
+++ b/Tests/RunCMake/property_init/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.12)
+project(${RunCMake_TEST} C)
+
+set(main_sources main.c)
+set(library_sources library.c)
+
+include(util.cmake)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/property_init/CompileSources.cmake b/Tests/RunCMake/property_init/CompileSources.cmake
new file mode 100644
index 0000000..e8c5554
--- /dev/null
+++ b/Tests/RunCMake/property_init/CompileSources.cmake
@@ -0,0 +1,274 @@
+set(dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+set(properties
+ # property expected alias
+ # Compilation properties
+ "COMPILE_WARNING_AS_ERROR" "ON" "<SAME>"
+ "INTERPROCEDURAL_OPTIMIZATION" "OFF" "<SAME>"
+ "NO_SYSTEM_FROM_IMPORTED" "ON" "<SAME>"
+ "VISIBILITY_INLINES_HIDDEN" "ON" "<SAME>"
+ ## Features
+ ### PCH
+ "DISABLE_PRECOMPILE_HEADERS" "ON" "<SAME>"
+ "PCH_WARN_INVALID" "OFF" "<SAME>"
+ "PCH_INSTANTIATE_TEMPLATES" "OFF" "<SAME>"
+ ## Platforms
+ ### Android
+ "ANDROID_API" "9" "<SAME>"
+ "ANDROID_API_MIN" "9" "<SAME>"
+ "ANDROID_ARCH" "arm64-v8a" "<SAME>"
+ "ANDROID_ASSETS_DIRECTORIES" "${dir}" "<SAME>"
+ "ANDROID_JAVA_SOURCE_DIR" "${dir}" "<SAME>"
+ "ANDROID_STL_TYPE" "system" "<SAME>"
+ ### macOS
+ "OSX_ARCHITECTURES" "arm64" "<SAME>"
+ ### Windows
+ "MSVC_DEBUG_INFORMATION_FORMAT" "Embedded" "<SAME>"
+ "MSVC_RUNTIME_LIBRARY" "MultiThreaded" "<SAME>"
+ "VS_JUST_MY_CODE_DEBUGGING" "ON" "<SAME>"
+ ### OpenWatcom
+ "WATCOM_RUNTIME_LIBRARY" "MultiThreaded" "<SAME>"
+ ## Language
+ ### CUDA
+ "CUDA_SEPARABLE_COMPILATION" "ON" "<SAME>"
+ "CUDA_ARCHITECTURES" "naive" "<SAME>"
+ ### Fortran
+ "Fortran_FORMAT" "FREE" "<SAME>"
+ "Fortran_MODULE_DIRECTORY" "${dir}" "<SAME>"
+ "Fortran_COMPILER_LAUNCHER" "ccache" "<SAME>"
+ "Fortran_PREPROCESS" "ON" "<SAME>"
+ "Fortran_VISIBILITY_PRESET" "hidden" "<SAME>"
+ ### HIP
+ "HIP_ARCHITECTURES" "gfx801" "<SAME>"
+ ### ISPC
+ "ISPC_COMPILER_LAUNCHER" "ccache" "<SAME>"
+ "ISPC_HEADER_DIRECTORY" "${dir}" "<SAME>"
+ "ISPC_HEADER_SUFFIX" "_i.h" "<SAME>"
+ "ISPC_INSTRUCTION_SETS" "avx2-i32x4" "<SAME>"
+ ### Swift
+ "Swift_LANGUAGE_VERSION" "2.3" "<SAME>"
+ "Swift_MODULE_DIRECTORY" "${dir}" "<SAME>"
+ ### moc
+ "AUTOMOC" "OFF" "<SAME>"
+ "AUTOMOC_COMPILER_PREDEFINES" "OFF" "<SAME>"
+ "AUTOMOC_MACRO_NAMES" "MOC_CLASS" "<SAME>"
+ "AUTOMOC_MOC_OPTIONS" "-v" "<SAME>"
+ "AUTOMOC_PATH_PREFIX" "moc_" "<SAME>"
+ "AUTOMOC_EXECUTABLE" "automoc" "<SAME>"
+ ### uic
+ "AUTOUIC" "OFF" "<SAME>"
+ "AUTOUIC_OPTIONS" "-v" "<SAME>"
+ "AUTOUIC_SEARCH_PATHS" "${dir}" "<SAME>"
+ "AUTOUIC_EXECUTABLE" "autouic" "<SAME>"
+ ### rcc
+ "AUTORCC" "OFF" "<SAME>"
+ "AUTORCC_OPTIONS" "-v" "<SAME>"
+ "AUTORCC_EXECUTABLE" "autorcc" "<SAME>"
+
+ # Linking properties
+ "LINK_SEARCH_START_STATIC" "-Bstatic" "<SAME>"
+ "LINK_SEARCH_END_STATIC" "-Bdynamic" "<SAME>"
+ ## Dependent library lookup
+ "MACOSX_RPATH" "@loader_path/" "<SAME>"
+ ### Build
+ "BUILD_RPATH" "../lib" "<SAME>"
+ "BUILD_RPATH_USE_ORIGIN" "ON" "<SAME>"
+ "SKIP_BUILD_RPATH" "ON" "<SAME>"
+ "BUILD_WITH_INSTALL_RPATH" "ON" "<SAME>"
+ "BUILD_WITH_INSTALL_NAME_DIR" "@rpath/" "<SAME>"
+ ### Install
+ "INSTALL_NAME_DIR" "@rpath/" "<SAME>"
+ "INSTALL_REMOVE_ENVIRONMENT_RPATH" "ON" "<SAME>"
+ "INSTALL_RPATH" "@rpath/" "<SAME>"
+ "INSTALL_RPATH_USE_LINK_PATH" "ON" "<SAME>"
+ ## Platforms
+ ### Android
+ "ANDROID_JAR_DIRECTORIES" "${dir}" "<SAME>"
+ "ANDROID_JAR_DEPENDENCIES" "${dir}/foo.jar" "<SAME>"
+ "ANDROID_NATIVE_LIB_DIRECTORIES" "${dir}" "<SAME>"
+ "ANDROID_NATIVE_LIB_DEPENDENCIES" "${dir}/native.a" "<SAME>"
+ "ANDROID_PROGUARD" "ON" "<SAME>"
+ "ANDROID_PROGUARD_CONFIG_PATH" "proguard.props" "<SAME>"
+ "ANDROID_SECURE_PROPS_PATH" "secure.props" "<SAME>"
+ ### iOS
+ "IOS_INSTALL_COMBINED" "ON" "<SAME>"
+ ### Windows
+ "GNUtoMS" "ON" "<SAME>"
+ "WIN32_EXECUTABLE" "OFF" "<SAME>"
+ ## Languages
+ ### C
+ "C_LINKER_LAUNCHER" "ccache" "<SAME>"
+ ### C++
+ "CXX_LINKER_LAUNCHER" "ccache" "<SAME>"
+ ### CUDA
+ "CUDA_RESOLVE_DEVICE_SYMBOLS" "ON" "<SAME>"
+ "CUDA_RUNTIME_LIBRARY" "Static" "<SAME>"
+ ### HIP
+ "HIP_RUNTIME_LIBRARY" "SHARED" "<SAME>"
+ ### Objective C
+ "OBJC_LINKER_LAUNCHER" "ccache" "<SAME>"
+ ### Objective C++
+ "OBJCXX_LINKER_LAUNCHER" "ccache" "<SAME>"
+
+ # Static analysis
+ ## C
+ "C_CLANG_TIDY" "clang-tidy" "<SAME>"
+ "C_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
+ "C_CPPLINT" "cpplint" "<SAME>"
+ "C_CPPCHECK" "cppcheck" "<SAME>"
+ "C_INCLUDE_WHAT_YOU_USE" "iwyu" "<SAME>"
+ ## C++
+ "CXX_CLANG_TIDY" "clang-tidy" "<SAME>"
+ "CXX_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
+ "CXX_CPPLINT" "cpplint" "<SAME>"
+ "CXX_CPPCHECK" "cppcheck" "<SAME>"
+ "CXX_INCLUDE_WHAT_YOU_USE" "iwyu" "<SAME>"
+ ## Objective C
+ "OBJC_CLANG_TIDY" "clang-tidy" "<SAME>"
+ "OBJC_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
+ ## Objective C++
+ "OBJCXX_CLANG_TIDY" "clang-tidy" "<SAME>"
+ "OBJCXX_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
+ ## Linking
+ "LINK_WHAT_YOU_USE" "lwyu" "<SAME>"
+
+ # Build graph properties
+ "LINK_DEPENDS_NO_SHARED" "OFF" "<SAME>"
+ "UNITY_BUILD" "OFF" "<SAME>"
+ "UNITY_BUILD_UNIQUE_ID" "unity" "<SAME>"
+ "UNITY_BUILD_BATCH_SIZE" "10" "<SAME>"
+ "UNITY_BUILD_MODE" "GROUP" "<SAME>"
+ "OPTIMIZE_DEPENDENCIES" "ON" "<SAME>"
+ ## Android
+ "ANDROID_ANT_ADDITIONAL_OPTIONS" "-v" "<SAME>"
+ "ANDROID_PROCESS_MAX" "2" "<SAME>"
+ "ANDROID_SKIP_ANT_STEP" "ON" "<SAME>"
+ ## Autogen
+ "AUTOGEN_ORIGIN_DEPENDS" "OFF" "<SAME>"
+ "AUTOGEN_PARALLEL" "ON" "<SAME>"
+ "AUTOGEN_USE_SYSTEM_INCLUDE" "ON" "<SAME>"
+ ## moc
+ "AUTOMOC_DEPEND_FILTERS" "FIRST<SEMI>SECOND" "<SAME>"
+ ## C++
+ "CXX_SCAN_FOR_MODULES" "ON" "<SAME>"
+ ## Ninja
+ "JOB_POOL_COMPILE" "compile_pool" "<SAME>"
+ "JOB_POOL_LINK" "link_pool" "<SAME>"
+ "JOB_POOL_PRECOMPILE_HEADER" "pch_pool" "<SAME>"
+ ## Visual Studio
+ "VS_NO_COMPILE_BATCHING" "ON" "<SAME>"
+ "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION" "10.0.10240.0" "<SAME>"
+
+ # Output location properties
+ "ARCHIVE_OUTPUT_DIRECTORY" "${dir}" "<SAME>"
+ "COMPILE_PDB_OUTPUT_DIRECTORY" "${dir}" "<SAME>"
+ "LIBRARY_OUTPUT_DIRECTORY" "${dir}" "<SAME>"
+ "PDB_OUTPUT_DIRECTORY" "${dir}" "<SAME>"
+ "RUNTIME_OUTPUT_DIRECTORY" "${dir}" "<SAME>"
+
+ # macOS bundle properties
+ "FRAMEWORK" "OFF" "<SAME>"
+ "FRAMEWORK_MULTI_CONFIG_POSTFIX" ".mcpostfix" "<SAME>"
+ "MACOSX_BUNDLE" "OFF" "<SAME>"
+
+ # Usage requirement properties
+ "LINK_INTERFACE_LIBRARIES" "c" "<SAME>"
+
+ # Metadata
+ "EXPORT_COMPILE_COMMANDS" "OFF" "<SAME>"
+ )
+
+if (CMAKE_HOST_APPLE) # compile-guarded in CMake
+ if (CMAKE_GENERATOR STREQUAL "Xcode")
+ list(APPEND properties
+ # property expected alias
+ # Xcode properties
+ "XCODE_SCHEME_ADDRESS_SANITIZER" "ON" "<SAME>"
+ "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN" "ON" "<SAME>"
+ "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING" "ON" "<SAME>"
+ "XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE" "ON" "<SAME>"
+ "XCODE_SCHEME_THREAD_SANITIZER" "ON" "<SAME>"
+ "XCODE_SCHEME_THREAD_SANITIZER_STOP" "ON" "<SAME>"
+ "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER" "ON" "<SAME>"
+ "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP" "ON" "<SAME>"
+ "XCODE_SCHEME_LAUNCH_CONFIGURATION" "ON" "<SAME>"
+ "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION" "ON" "<SAME>"
+ "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION" "ON" "<SAME>"
+ "XCODE_SCHEME_WORKING_DIRECTORY" "ON" "<SAME>"
+ "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER" "ON" "<SAME>"
+ "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP" "ON" "<SAME>"
+ "XCODE_SCHEME_MALLOC_SCRIBBLE" "ON" "<SAME>"
+ "XCODE_SCHEME_MALLOC_GUARD_EDGES" "ON" "<SAME>"
+ "XCODE_SCHEME_GUARD_MALLOC" "ON" "<SAME>"
+ "XCODE_SCHEME_LAUNCH_MODE" "ON" "<SAME>"
+ "XCODE_SCHEME_ZOMBIE_OBJECTS" "ON" "<SAME>"
+ "XCODE_SCHEME_MALLOC_STACK" "ON" "<SAME>"
+ "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE" "ON" "<SAME>"
+ "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS" "ON" "<SAME>"
+ "XCODE_SCHEME_ENVIRONMENT" "ON" "<SAME>"
+ "XCODE_LINK_BUILD_PHASE_MODE" "BUILT_ONLY" "<SAME>"
+ )
+ endif ()
+endif ()
+
+macro (add_language_properties lang std)
+ list(APPEND properties
+ # property expected alias
+ "${lang}_COMPILER_LAUNCHER" "ccache" "<SAME>"
+ "${lang}_STANDARD" "${std}" "<SAME>"
+ "${lang}_STANDARD_REQUIRED" "TRUE" "<SAME>"
+ "${lang}_EXTENSIONS" "FALSE" "<SAME>"
+ "${lang}_VISIBILITY_PRESET" "hidden" "<SAME>"
+ )
+endmacro ()
+
+# Mock up knowing the standard flag. This doesn't actually build, so nothing
+# should care at this point.
+set(CMAKE_Cc_std_11_STANDARD_COMPILE_OPTION "-std=c11")
+
+add_language_properties(C c_std_11)
+add_language_properties(CXX cxx_std_11)
+add_language_properties(CUDA cuda_std_11)
+add_language_properties(HIP hip_std_11)
+add_language_properties(OBJC c_std_99)
+add_language_properties(OBJCXX cxx_std_11)
+
+# Set up pools for properties set above.
+if (CMAKE_GENERATOR MATCHES "Ninja")
+ set_property(GLOBAL APPEND
+ PROPERTY
+ JOB_POOLS
+ compile_pool=1
+ link_pool=1
+ pch_pool=1)
+endif ()
+
+prepare_target_types(can_compile_sources
+ EXECUTABLE SHARED STATIC MODULE OBJECT)
+
+run_property_tests(can_compile_sources properties)
+
+set(properties_with_defaults
+ # property expected alias
+ "PCH_WARN_INVALID" "ON" "<SAME>"
+ "PCH_INSTANTIATE_TEMPLATES" "ON" "<SAME>"
+ "ISPC_HEADER_SUFFIX" "_ispc.h" "<SAME>"
+ "SKIP_BUILD_RPATH" "OFF" "<SAME>"
+ "BUILD_WITH_INSTALL_RPATH" "OFF" "<SAME>"
+ "INSTALL_RPATH" "" "<SAME>"
+ "INSTALL_RPATH_USE_LINK_PATH" "OFF" "<SAME>"
+ "UNITY_BUILD_BATCH_SIZE" "8" "<SAME>"
+ "UNITY_BUILD_MODE" "BATCH" "<SAME>"
+ )
+
+if (CMAKE_HOST_APPLE)
+ if (CMAKE_GENERATOR STREQUAL "Xcode")
+ list(APPEND properties_with_defaults
+ # property expected alias
+ "XCODE_LINK_BUILD_PHASE_MODE" "NONE" "<SAME>"
+ )
+ endif ()
+endif ()
+
+set(with_defaults 1)
+run_property_tests(can_compile_sources properties_with_defaults)
diff --git a/Tests/RunCMake/property_init/Executable.cmake b/Tests/RunCMake/property_init/Executable.cmake
new file mode 100644
index 0000000..ede0e4b
--- /dev/null
+++ b/Tests/RunCMake/property_init/Executable.cmake
@@ -0,0 +1,25 @@
+set(dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+set(properties
+ # property expected alias
+ # Compilation properties
+ ## Platforms
+ ### Windows
+ "VS_DEBUGGER_COMMAND" "vsdbg" "<SAME>"
+ "VS_DEBUGGER_COMMAND_ARGUMENTS" "/?" "<SAME>"
+ "VS_DEBUGGER_ENVIRONMENT" "env=val" "<SAME>"
+ "VS_DEBUGGER_WORKING_DIRECTORY" "${dir}" "<SAME>"
+
+ # Linking properties
+ ## Platforms
+ ### Android
+ "ANDROID_GUI" "OFF" "<SAME>"
+
+ # Metadata
+ "CROSSCOMPILING_EMULATOR" "emu" "<SAME>"
+ )
+
+prepare_target_types(executable
+ EXECUTABLE
+ IMPORTED_EXECUTABLE)
+run_property_tests(executable properties)
diff --git a/Tests/RunCMake/property_init/ImportedTargets.cmake b/Tests/RunCMake/property_init/ImportedTargets.cmake
new file mode 100644
index 0000000..0b51998
--- /dev/null
+++ b/Tests/RunCMake/property_init/ImportedTargets.cmake
@@ -0,0 +1,9 @@
+set(properties
+ # property expected alias
+ "SYSTEM" "ON" "<SAME>"
+ )
+
+prepare_target_types(imported
+ IMPORTED_EXECUTABLE IMPORTED_INTERFACE IMPORTED_MODULE IMPORTED_OBJECT IMPORTED_SHARED IMPORTED_STATIC)
+set(with_defaults 1)
+run_property_tests(imported properties)
diff --git a/Tests/RunCMake/property_init/LibraryArtifact.cmake b/Tests/RunCMake/property_init/LibraryArtifact.cmake
new file mode 100644
index 0000000..942b433
--- /dev/null
+++ b/Tests/RunCMake/property_init/LibraryArtifact.cmake
@@ -0,0 +1,10 @@
+per_config(properties
+ # property expected alias
+ # Linking properties
+ "_POSTFIX" "test" "<UNSET>"
+ )
+
+prepare_target_types(library_with_artifact
+ MODULE SHARED STATIC
+ IMPORTED_MODULE IMPORTED_SHARED IMPORTED_STATIC)
+run_property_tests(library_with_artifact properties)
diff --git a/Tests/RunCMake/property_init/Linkable.cmake b/Tests/RunCMake/property_init/Linkable.cmake
new file mode 100644
index 0000000..e5d75d1
--- /dev/null
+++ b/Tests/RunCMake/property_init/Linkable.cmake
@@ -0,0 +1,12 @@
+per_config(properties
+ # property expected alias
+ # Linking properties
+ ## Platforms
+ ### macOS
+ "FRAMEWORK_MULTI_CONFIG_POSTFIX_" ".fw" "<UNSET>"
+ )
+
+prepare_target_types(linkable
+ EXECUTABLE SHARED STATIC
+ IMPORTED_EXECUTABLE IMPORTED_SHARED IMPORTED_STATIC)
+run_property_tests(linkable properties)
diff --git a/Tests/RunCMake/property_init/NonImportedNormalTarget.cmake b/Tests/RunCMake/property_init/NonImportedNormalTarget.cmake
new file mode 100644
index 0000000..cf3b726
--- /dev/null
+++ b/Tests/RunCMake/property_init/NonImportedNormalTarget.cmake
@@ -0,0 +1,9 @@
+set(properties
+ # property expected alias
+ # Linking properties
+ "LINK_LIBRARIES_ONLY_TARGETS" "OFF" "<SAME>"
+ )
+
+prepare_target_types(normal_non_imported
+ EXECUTABLE SHARED STATIC MODULE OBJECT INTERFACE)
+run_property_tests(normal_non_imported properties)
diff --git a/Tests/RunCMake/property_init/NonImportedTarget.cmake b/Tests/RunCMake/property_init/NonImportedTarget.cmake
new file mode 100644
index 0000000..7e2e22c
--- /dev/null
+++ b/Tests/RunCMake/property_init/NonImportedTarget.cmake
@@ -0,0 +1,11 @@
+set(properties
+ # property expected alias
+ # Compilation properties
+ ## Language
+ ### CSharp
+ "DOTNET_SDK" "Microsoft.NET.Sdk" "<SAME>"
+ )
+
+prepare_target_types(non_imported
+ EXECUTABLE SHARED STATIC MODULE OBJECT INTERFACE CUSTOM)
+run_property_tests(non_imported properties)
diff --git a/Tests/RunCMake/property_init/NormalTarget.cmake b/Tests/RunCMake/property_init/NormalTarget.cmake
new file mode 100644
index 0000000..99507cf
--- /dev/null
+++ b/Tests/RunCMake/property_init/NormalTarget.cmake
@@ -0,0 +1,10 @@
+per_config(properties
+ # property expected alias
+ # Usage requirement properties
+ "MAP_IMPORTED_CONFIG_" "Release" "<UNSET>"
+ )
+
+prepare_target_types(normal
+ EXECUTABLE INTERFACE MODULE OBJECT SHARED STATIC
+ IMPORTED_EXECUTABLE IMPORTED_INTERFACE IMPORTED_MODULE IMPORTED_OBJECT IMPORTED_SHARED IMPORTED_STATIC)
+run_property_tests(normal properties)
diff --git a/Tests/RunCMake/property_init/PICTargets.cmake b/Tests/RunCMake/property_init/PICTargets.cmake
new file mode 100644
index 0000000..6c99505
--- /dev/null
+++ b/Tests/RunCMake/property_init/PICTargets.cmake
@@ -0,0 +1,21 @@
+set(properties
+ # property expected alias
+ # Compilation properties
+ "POSITION_INDEPENDENT_CODE" "True" "<SAME>"
+ )
+
+prepare_target_types(pic_targets
+ EXECUTABLE MODULE OBJECT SHARED STATIC
+ IMPORTED_MODULE IMPORTED_SHARED)
+run_property_tests(pic_targets properties)
+
+set(APPEND properties_with_defaults
+ # property expected alias
+ "POSITION_INDEPENDENT_CODE" "True" "<SAME>"
+ )
+
+prepare_target_types(pic_default_targets
+ MODULE SHARED
+ IMPORTED_MODULE IMPORTED_SHARED)
+set(with_defaults 1)
+run_property_tests(pic_default_targets properties_with_defaults)
diff --git a/Tests/RunCMake/property_init/RunCMakeTest.cmake b/Tests/RunCMake/property_init/RunCMakeTest.cmake
new file mode 100644
index 0000000..310da72
--- /dev/null
+++ b/Tests/RunCMake/property_init/RunCMakeTest.cmake
@@ -0,0 +1,16 @@
+include(RunCMake)
+
+run_cmake(Always)
+run_cmake(CompileSources)
+run_cmake(Executable)
+run_cmake(ImportedTargets)
+run_cmake(LibraryArtifact)
+run_cmake(Linkable)
+run_cmake(NonImportedNormalTarget)
+run_cmake(NonImportedTarget)
+run_cmake(NormalTarget)
+run_cmake(PICTargets)
+run_cmake(SharedLibrary)
+run_cmake(TargetsWithArtifact)
+run_cmake(TargetsWithCommands)
+run_cmake(TargetsWithExports)
diff --git a/Tests/RunCMake/property_init/SharedLibrary.cmake b/Tests/RunCMake/property_init/SharedLibrary.cmake
new file mode 100644
index 0000000..49715a4
--- /dev/null
+++ b/Tests/RunCMake/property_init/SharedLibrary.cmake
@@ -0,0 +1,12 @@
+set(dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+set(properties
+ # property expected alias
+ # Linking properties
+ "DLL_NAME_WITH_SOVERSION" "OFF" "<SAME>"
+ )
+
+prepare_target_types(shared_library
+ SHARED
+ IMPORTED_SHARED)
+run_property_tests(shared_library properties)
diff --git a/Tests/RunCMake/property_init/TargetsWithArtifact.cmake b/Tests/RunCMake/property_init/TargetsWithArtifact.cmake
new file mode 100644
index 0000000..0c19ea3
--- /dev/null
+++ b/Tests/RunCMake/property_init/TargetsWithArtifact.cmake
@@ -0,0 +1,19 @@
+set(dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+per_config(properties
+ # property expected alias
+ # Compilation properties
+ "INTERPROCEDURAL_OPTIMIZATION_" "OFF" "<UNSET>"
+
+ # Output location properties
+ "ARCHIVE_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
+ "COMPILE_PDB_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
+ "LIBRARY_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
+ "PDB_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
+ "RUNTIME_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
+ )
+
+prepare_target_types(with_artifact
+ EXECUTABLE MODULE SHARED STATIC
+ IMPORTED_EXECUTABLE IMPORTED_MODULE IMPORTED_SHARED IMPORTED_STATIC)
+run_property_tests(with_artifact properties)
diff --git a/Tests/RunCMake/property_init/TargetsWithCommands.cmake b/Tests/RunCMake/property_init/TargetsWithCommands.cmake
new file mode 100644
index 0000000..4db0ca3
--- /dev/null
+++ b/Tests/RunCMake/property_init/TargetsWithCommands.cmake
@@ -0,0 +1,13 @@
+set(properties
+ # property expected alias
+ # Compilation properties
+ ## Language
+ ### CSharp
+ "DOTNET_TARGET_FRAMEWORK" "netcoreapp2.1" "<SAME>"
+ "DOTNET_TARGET_FRAMEWORK_VERSION" "v4.5" "<SAME>"
+ )
+
+prepare_target_types(with_commands
+ EXECUTABLE MODULE OBJECT SHARED STATIC CUSTOM
+ IMPORTED_EXECUTABLE IMPORTED_MODULE IMPORTED_OBJECT IMPORTED_SHARED IMPORTED_STATIC)
+run_property_tests(with_commands properties)
diff --git a/Tests/RunCMake/property_init/TargetsWithExports.cmake b/Tests/RunCMake/property_init/TargetsWithExports.cmake
new file mode 100644
index 0000000..9b2e213
--- /dev/null
+++ b/Tests/RunCMake/property_init/TargetsWithExports.cmake
@@ -0,0 +1,51 @@
+set(properties
+ # property expected alias
+ # Linking properties
+ ## Platforms
+ ### AIX
+ "AIX_EXPORT_ALL_SYMBOLS" "OFF" "<SAME>"
+ ### Windows
+ "WINDOWS_EXPORT_ALL_SYMBOLS" "OFF" "<SAME>"
+ )
+
+prepare_target_types(symbol_export_target
+ EXECUTABLE SHARED
+ IMPORTED_EXECUTABLE IMPORTED_SHARED)
+run_property_tests(symbol_export_target properties)
+
+# `ENABLE_EXPORTS` has a more complicated initialization.
+set(properties
+ # property expected alias
+ # Linking properties
+ "ENABLE_EXPORTS" "OFF" "<SAME>"
+ )
+
+prepare_target_types(executable
+ EXECUTABLE
+ IMPORTED_EXECUTABLE)
+set(iteration "-ENABLE_EXPORTS")
+run_property_tests(executable_target properties)
+
+set(with_defaults 1)
+
+set(CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS OFF)
+set(properties
+ # property expected alias
+ # Linking properties
+ "ENABLE_EXPORTS" "OFF" "<SAME>"
+ )
+
+set(iteration "-SHARED_LIBRARY_ENABLE_EXPORTS")
+run_property_tests(shared_library_target properties)
+unset(CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS)
+
+set(CMAKE_EXECUTABLE_ENABLE_EXPORTS OFF)
+set(properties
+ # property expected alias
+ # Linking properties
+ "ENABLE_EXPORTS" "OFF" "<SAME>"
+ )
+
+set(iteration "-EXECUTABLE_ENABLE_EXPORTS")
+run_property_tests(executable_target properties)
+unset(CMAKE_EXECUTABLE_ENABLE_EXPORTS)
diff --git a/Tests/RunCMake/property_init/library.c b/Tests/RunCMake/property_init/library.c
new file mode 100644
index 0000000..ad6a649
--- /dev/null
+++ b/Tests/RunCMake/property_init/library.c
@@ -0,0 +1,4 @@
+int foo(int arg)
+{
+ return arg;
+}
diff --git a/Tests/RunCMake/property_init/main.c b/Tests/RunCMake/property_init/main.c
new file mode 100644
index 0000000..14917b7
--- /dev/null
+++ b/Tests/RunCMake/property_init/main.c
@@ -0,0 +1,4 @@
+int main(int argc, char* argv[])
+{
+ return argc - 1;
+}
diff --git a/Tests/RunCMake/property_init/util.cmake b/Tests/RunCMake/property_init/util.cmake
new file mode 100644
index 0000000..7edc6f9
--- /dev/null
+++ b/Tests/RunCMake/property_init/util.cmake
@@ -0,0 +1,191 @@
+set(all_target_types
+ "EXECUTABLE"
+
+ "IMPORTED_EXECUTABLE"
+
+ "INTERFACE"
+ "MODULE"
+ "OBJECT"
+ "SHARED"
+ "STATIC"
+
+ "IMPORTED_INTERFACE"
+ "IMPORTED_MODULE"
+ "IMPORTED_OBJECT"
+ "IMPORTED_SHARED"
+ "IMPORTED_STATIC"
+
+ "CUSTOM")
+
+function (prepare_target_types name)
+ set("${name}" "${ARGN}" PARENT_SCOPE)
+ list(REMOVE_ITEM all_target_types ${ARGN})
+ set("not_${name}" "${all_target_types}" PARENT_SCOPE)
+endfunction ()
+
+function (per_config variable)
+ prepare_properties("${property_table}" properties expected_values expected_alias)
+
+ get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ if (is_multi_config)
+ set(configs "${CMAKE_CONFIGURATION_TYPES}")
+ else ()
+ if (NOT CMAKE_BUILD_TYPE STREQUAL "")
+ set(configs "${CMAKE_BUILD_TYPE}")
+ endif ()
+ endif ()
+
+ foreach (property expected alias IN ZIP_LISTS expected_properties expected_values expected_alias)
+ if (property MATCHES "^_")
+ set(prepend 1)
+ elseif (property MATCHES "_$")
+ set(prepend 0)
+ else ()
+ message(SEND_ERROR
+ "Per-config properties must have a `_` at one end of their name: '${property}'")
+ endif ()
+ foreach (config IN LISTS configs)
+ if (prepend)
+ list(APPEND "${variable}"
+ "${config}_${property}" "${value}/${config}" "${alias}")
+ else ()
+ list(APPEND "${variable}"
+ "${property}_${config}" "${value}/${config}" "${alias}")
+ endif ()
+ endforeach ()
+ endforeach ()
+
+ set("${variable}" "${${variable}}" PARENT_SCOPE)
+endfunction ()
+
+function (make_target name type)
+ if (type STREQUAL "EXECUTABLE")
+ add_executable("${name}")
+ target_sources("${name}" PRIVATE ${main_sources})
+ elseif (type STREQUAL "IMPORTED_EXECUTABLE")
+ add_executable("${name}" IMPORTED)
+ set_property(TARGET "${name}" PROPERTY IMPORTED_LOCATION "${CMAKE_COMMAND}")
+ elseif (type STREQUAL "CUSTOM")
+ add_custom_target("${name}" COMMAND "${CMAKE_EXECUTABLE}" -E echo "${name}")
+ elseif (type MATCHES "IMPORTED_")
+ string(REPLACE "IMPORTED_" "" type "${type}")
+ add_library("${name}" IMPORTED ${type})
+ if (NOT type STREQUAL "INTERFACE")
+ set_property(TARGET "${name}" PROPERTY IMPORTED_LOCATION "${default_library_location}")
+ endif ()
+ else ()
+ add_library("${name}" ${type})
+ target_sources("${name}" PRIVATE ${library_sources})
+ endif ()
+
+ if (type MATCHES "EXECUTABLE")
+ add_executable("alias::${name}" ALIAS "${name}")
+ elseif (NOT type STREQUAL "CUSTOM")
+ add_library("alias::${name}" ALIAS "${name}")
+ endif ()
+endfunction ()
+
+function (check_property target property expected)
+ if (NOT TARGET "${target}")
+ message(SEND_ERROR
+ "No such target '${target}'")
+ return ()
+ endif ()
+
+ get_property(is_set TARGET "${target}" PROPERTY "${property}" SET)
+ if (is_set)
+ get_property(actual TARGET "${target}" PROPERTY "${property}")
+ endif ()
+ if (expected STREQUAL "<UNSET>")
+ if (is_set)
+ message(SEND_ERROR
+ "Target '${target}' should not have '${property}' set at all, but is '${actual}'")
+ endif ()
+ elseif (is_set AND NOT expected STREQUAL actual)
+ message(SEND_ERROR
+ "Target '${target}' should have '${property}' set to '${expected}', but is '${actual}'")
+ elseif (NOT is_set)
+ message(SEND_ERROR
+ "Target '${target}' should have '${property}' set to '${expected}', but is not set at all")
+ endif ()
+endfunction ()
+
+function (prepare_properties table output_properties output_expected output_alias)
+ set(_properties)
+ set(_expected)
+ set(_alias)
+
+ set(variable "_properties")
+ foreach (item IN LISTS "${table}")
+ list(APPEND "${variable}" "${item}")
+ if (variable STREQUAL "_properties")
+ set(variable "_expected")
+ elseif (variable STREQUAL "_expected")
+ set(variable "_alias")
+ elseif (variable STREQUAL "_alias")
+ set(variable "_properties")
+ else ()
+ message(FATAL_ERROR
+ "Failed to track property table parsing")
+ endif ()
+ endforeach ()
+ if (NOT variable STREQUAL "_properties")
+ message(FATAL_ERROR
+ "Table does not have a multiple of 3 items")
+ endif ()
+
+ set("${output_properties}" "${_properties}" PARENT_SCOPE)
+ set("${output_expected}" "${_expected}" PARENT_SCOPE)
+ set("${output_alias}" "${_alias}" PARENT_SCOPE)
+endfunction ()
+
+# Contextual variables:
+# iteration: make unique target names
+# with_defaults: if set, do not set variables, but instead test internal
+# default calculations
+function (run_property_tests applied_types property_table)
+ prepare_properties("${property_table}" expected_properties expected_values expected_alias)
+
+ if (NOT with_defaults)
+ foreach (property expected IN ZIP_LISTS expected_properties expected_values)
+ string(REPLACE "<SEMI>" ";" expected "${expected}")
+ set("CMAKE_${property}" "${expected}")
+ endforeach ()
+ endif ()
+
+ foreach (target_type IN LISTS "${applied_types}")
+ set(target_name "${RunCMake_TEST}${iteration}-${target_type}")
+ if (with_defaults)
+ string(APPEND target_name "-defaults")
+ endif ()
+ make_target("${target_name}" "${target_type}")
+ foreach (property expected alias IN ZIP_LISTS expected_properties expected_values expected_alias)
+ string(REPLACE "<SEMI>" ";" expected "${expected}")
+ check_property("${target_name}" "${property}" "${expected}")
+ if (NOT target_type STREQUAL "CUSTOM")
+ if (alias STREQUAL "<SAME>")
+ check_property("alias::${target_name}" "${property}" "${expected}")
+ elseif (alias STREQUAL "<UNSET>")
+ check_property("alias::${target_name}" "${property}" "<UNSET>")
+ else ()
+ message(FATAL_ERROR
+ "Invalid `alias` entry for property '${property}': '${alias}'")
+ endif ()
+ endif ()
+ endforeach ()
+ endforeach ()
+
+ foreach (target_type IN LISTS "not_${applied_types}")
+ set(target_name "${RunCMake_TEST}${iteration}-${target_type}-unset")
+ if (with_defaults)
+ string(APPEND target_name "-defaults")
+ endif ()
+ make_target("${target_name}" "${target_type}")
+ foreach (property IN LISTS expected_properties)
+ check_property("${target_name}" "${property}" "<UNSET>")
+ if (NOT target_type STREQUAL "CUSTOM")
+ check_property("alias::${target_name}" "${property}" "<UNSET>")
+ endif ()
+ endforeach ()
+ endforeach ()
+endfunction ()
diff --git a/Tests/RunCMake/set/CacheErrors-result.txt b/Tests/RunCMake/set/CacheErrors-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/set/CacheErrors-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/set/CacheErrors-stderr.txt b/Tests/RunCMake/set/CacheErrors-stderr.txt
new file mode 100644
index 0000000..9983160
--- /dev/null
+++ b/Tests/RunCMake/set/CacheErrors-stderr.txt
@@ -0,0 +1,19 @@
+^CMake Error at CacheErrors\.cmake:1 \(set\):
+ set given invalid arguments for CACHE mode: missing type and docstring
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at CacheErrors\.cmake:2 \(set\):
+ set given invalid arguments for CACHE mode: missing type or docstring
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at CacheErrors\.cmake:3 \(set\):
+ set given invalid arguments for CACHE mode: missing type or docstring
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at CacheErrors\.cmake:4 \(set\):
+ set given invalid arguments: FORCE specified without CACHE
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/set/CacheErrors.cmake b/Tests/RunCMake/set/CacheErrors.cmake
new file mode 100644
index 0000000..d177474
--- /dev/null
+++ b/Tests/RunCMake/set/CacheErrors.cmake
@@ -0,0 +1,4 @@
+set (var val CACHE)
+set (var val CACHE STRING)
+set (var val CACHE "")
+set (var val CACH3 STRING "" FORCE)
diff --git a/Tests/RunCMake/set/RunCMakeTest.cmake b/Tests/RunCMake/set/RunCMakeTest.cmake
index b3bd0a4..c785450 100644
--- a/Tests/RunCMake/set/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set/RunCMakeTest.cmake
@@ -1,5 +1,6 @@
include(RunCMake)
+run_cmake(CacheErrors)
run_cmake(ParentScope)
run_cmake(ParentPulling)
run_cmake(ParentPullingRecursive)
diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake
index 692c6b9..1a5498d 100644
--- a/Tests/RunCMake/set_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake
@@ -10,6 +10,12 @@ run_cmake(LINK_DIRECTORIES)
run_cmake(LINK_LIBRARIES)
run_cmake(SOURCES)
run_cmake(SOURCE_FILE)
+run_cmake(TEST-invalid)
run_cmake(TYPE)
run_cmake(USER_PROP)
run_cmake(USER_PROP_INHERITED)
+
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/TEST-build")
+run_cmake(TEST)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(TEST-test ${CMAKE_CTEST_COMMAND} -C Debug)
diff --git a/Tests/RunCMake/set_property/TEST-invalid-result.txt b/Tests/RunCMake/set_property/TEST-invalid-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/set_property/TEST-invalid-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/set_property/TEST-invalid-stderr.txt b/Tests/RunCMake/set_property/TEST-invalid-stderr.txt
new file mode 100644
index 0000000..c0a40d6
--- /dev/null
+++ b/Tests/RunCMake/set_property/TEST-invalid-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at TEST-invalid\.cmake:[0-9]+ \(set_property\):
+ set_property called with incorrect number of arguments no value provided to
+ the DIRECTORY option
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at TEST-invalid\.cmake:[0-9]+ \(set_property\):
+ set_property given non-existent DIRECTORY nonexistent
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/set_property/TEST-invalid.cmake b/Tests/RunCMake/set_property/TEST-invalid.cmake
new file mode 100644
index 0000000..6828c96
--- /dev/null
+++ b/Tests/RunCMake/set_property/TEST-invalid.cmake
@@ -0,0 +1,4 @@
+enable_testing()
+
+set_property(TEST t DIRECTORY PROPERTY PASS_REGULAR_EXPRESSION "Invalid")
+set_property(TEST t DIRECTORY nonexistent PROPERTY PASS_REGULAR_EXPRESSION "Invalid")
diff --git a/Tests/RunCMake/set_property/TEST-subdir1/CMakeLists.txt b/Tests/RunCMake/set_property/TEST-subdir1/CMakeLists.txt
new file mode 100644
index 0000000..b1fad66
--- /dev/null
+++ b/Tests/RunCMake/set_property/TEST-subdir1/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t2 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t3 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
diff --git a/Tests/RunCMake/set_property/TEST-subdir2/CMakeLists.txt b/Tests/RunCMake/set_property/TEST-subdir2/CMakeLists.txt
new file mode 100644
index 0000000..8621b00
--- /dev/null
+++ b/Tests/RunCMake/set_property/TEST-subdir2/CMakeLists.txt
@@ -0,0 +1 @@
+set_property(TEST t3 DIRECTORY ../TEST-subdir1 PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")
diff --git a/Tests/RunCMake/set_property/TEST.cmake b/Tests/RunCMake/set_property/TEST.cmake
new file mode 100644
index 0000000..7ef5aa3
--- /dev/null
+++ b/Tests/RunCMake/set_property/TEST.cmake
@@ -0,0 +1,9 @@
+enable_testing()
+
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Top directory")
+add_subdirectory(TEST-subdir1)
+add_subdirectory(TEST-subdir2)
+
+set_property(TEST t PROPERTY PASS_REGULAR_EXPRESSION "Top directory")
+set_property(TEST t DIRECTORY TEST-subdir1 PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")
+set_property(TEST t2 DIRECTORY "${CMAKE_BINARY_DIR}/TEST-subdir1" PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")
diff --git a/Tests/RunCMake/set_tests_properties/CMakeLists.txt b/Tests/RunCMake/set_tests_properties/CMakeLists.txt
new file mode 100644
index 0000000..922aad6
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.27)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-result.txt b/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-stderr.txt b/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-stderr.txt
new file mode 100644
index 0000000..e219399
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-stderr.txt
@@ -0,0 +1,13 @@
+^CMake Error at DIRECTORY-invalid\.cmake:[0-9]+ \(set_tests_properties\):
+ Error after keyword "DIRECTORY":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at DIRECTORY-invalid\.cmake:[0-9]+ \(set_tests_properties\):
+ set_tests_properties given non-existent DIRECTORY nonexistent
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid.cmake b/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid.cmake
new file mode 100644
index 0000000..4d87df1
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/DIRECTORY-invalid.cmake
@@ -0,0 +1,4 @@
+enable_testing()
+
+set_tests_properties(t DIRECTORY PROPERTIES PASS_REGULAR_EXPRESSION "Top directory")
+set_tests_properties(t DIRECTORY nonexistent PROPERTIES PASS_REGULAR_EXPRESSION "Top directory")
diff --git a/Tests/RunCMake/set_tests_properties/DIRECTORY-subdir1/CMakeLists.txt b/Tests/RunCMake/set_tests_properties/DIRECTORY-subdir1/CMakeLists.txt
new file mode 100644
index 0000000..b1fad66
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/DIRECTORY-subdir1/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t2 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t3 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
diff --git a/Tests/RunCMake/set_tests_properties/DIRECTORY-subdir2/CMakeLists.txt b/Tests/RunCMake/set_tests_properties/DIRECTORY-subdir2/CMakeLists.txt
new file mode 100644
index 0000000..8859597
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/DIRECTORY-subdir2/CMakeLists.txt
@@ -0,0 +1 @@
+set_tests_properties(t3 DIRECTORY ../DIRECTORY-subdir1 PROPERTIES PASS_REGULAR_EXPRESSION "Subdirectory")
diff --git a/Tests/RunCMake/set_tests_properties/DIRECTORY.cmake b/Tests/RunCMake/set_tests_properties/DIRECTORY.cmake
new file mode 100644
index 0000000..87d13e3
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/DIRECTORY.cmake
@@ -0,0 +1,9 @@
+enable_testing()
+
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Top directory")
+add_subdirectory(DIRECTORY-subdir1)
+add_subdirectory(DIRECTORY-subdir2)
+
+set_tests_properties(t PROPERTIES PASS_REGULAR_EXPRESSION "Top directory")
+set_tests_properties(t DIRECTORY DIRECTORY-subdir1 PROPERTIES PASS_REGULAR_EXPRESSION "Subdirectory")
+set_tests_properties(t2 DIRECTORY "${CMAKE_BINARY_DIR}/DIRECTORY-subdir1" PROPERTIES PASS_REGULAR_EXPRESSION "Subdirectory")
diff --git a/Tests/RunCMake/set_tests_properties/RunCMakeTest.cmake b/Tests/RunCMake/set_tests_properties/RunCMakeTest.cmake
new file mode 100644
index 0000000..b49158f
--- /dev/null
+++ b/Tests/RunCMake/set_tests_properties/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(DIRECTORY-invalid)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DIRECTORY-build)
+run_cmake(DIRECTORY)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(DIRECTORY-test ${CMAKE_CTEST_COMMAND} -C Debug)
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
index 4a0f068..65c708c 100644
--- a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
@@ -14,8 +14,14 @@ set_property(TARGET import-local PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMA
set_property(TARGET import-local PROPERTY IMPORTED_IMPLIB "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_IMPORT_LIBRARY_SUFFIX}")
add_library(alias::local ALIAS import-local)
+if(NOT DEFINED CMAKE_IMPORT_LIBRARY_SUFFIX)
+ add_library(import-local-stub SHARED IMPORTED)
+ set_property(TARGET import-local-stub PROPERTY IMPORTED_IMPLIB "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ add_library(alias::local-stub ALIAS import-local-stub)
+endif()
+
add_library (lib-local SHARED lib.c)
-target_link_libraries (lib-local PRIVATE alias::local)
+target_link_libraries (lib-local PRIVATE alias::local $<TARGET_NAME_IF_EXISTS:alias::local-stub>)
add_executable (main-local main.c)
target_link_libraries (main-local PRIVATE alias::local)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake
index 9b6581c..8e4745a 100644
--- a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake
@@ -126,7 +126,7 @@ if ((CMAKE_SYSTEM_NAME STREQUAL "Windows" AND
((DEFINED MSVC_VERSION AND MSVC_VERSION GREATER "1900") OR (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang" AND NOT CMAKE_C_SIMULATE_ID STREQUAL "MSVC")))
OR (CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND
(NOT CMAKE_C_COMPILER_ID STREQUAL "SunPro" OR CMAKE_C_COMPILER_VERSION GREATER "5.9"))
- OR CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS|Linux|BSD|MSYS|CYGWIN")
+ OR CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|visionOS|watchOS|Linux|BSD|MSYS|CYGWIN")
run_cmake(feature-WHOLE_ARCHIVE)
run_cmake_target(feature-WHOLE_ARCHIVE link-exe main)
endif()
diff --git a/Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake b/Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake
new file mode 100644
index 0000000..04f9cfb
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake
@@ -0,0 +1,2 @@
+add_library(SharedStubImportedGlobal SHARED IMPORTED GLOBAL)
+set_target_properties(SharedStubImportedGlobal PROPERTIES IMPORTED_IMPLIB z)
diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
index 7c5d77d..0e3877a 100644
--- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
@@ -23,6 +23,7 @@ run_cmake(CMP0079-link-NEW-bogus)
run_cmake(CMP0108-OLD-self-link)
run_cmake(CMP0108-NEW-self-link)
run_cmake(ImportedTarget)
+run_cmake(ImportedTargetStub)
run_cmake(ImportedTargetFailure)
run_cmake(MixedSignature)
run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake
new file mode 100644
index 0000000..0f897fe
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake
@@ -0,0 +1,4 @@
+
+if (NOT actual_stdout MATCHES "BADFLAG_\\$dollar")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_$dollar'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake
index bb04841..879151b 100644
--- a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake
@@ -53,3 +53,7 @@ target_link_options(LinkOptions_mod PRIVATE $<$<CONFIG:Release>:${pre}BADFLAG_RE
# executable with generator expression
add_executable(LinkOptions_exe LinkOptionsExe.c)
target_link_options(LinkOptions_exe PRIVATE $<$<CONFIG:Release>:${pre}BADFLAG_RELEASE${obj}>)
+
+# executable with dollar character
+add_executable(LinkOptions_dollar_exe LinkOptionsExe.c)
+target_link_options(LinkOptions_dollar_exe PRIVATE "${pre}BADFLAG_$dollar${obj}")
diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
index 1a29ecf..ff0c5a8 100644
--- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
@@ -30,7 +30,7 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
run_cmake_target(LINK_OPTIONS shared LinkOptions_shared --config Release)
run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
-
+ run_cmake_target(LINK_OPTIONS dollar-option LinkOptions_dollar_exe --config Release)
run_cmake(genex_LINK_LANGUAGE)
diff --git a/Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirExport.cmake b/Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirExport.cmake
new file mode 100644
index 0000000..f049d91
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirExport.cmake
@@ -0,0 +1,16 @@
+enable_language(C)
+
+# According to https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html#module:GNUInstallDirs
+# relative CMAKE_INSTALL_<dir> are encouraged, but absolute path's are also allowed.
+# Construct an absolute CMAKE_INSTALL_INCLUDEDIR.
+set(CMAKE_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include")
+
+add_library(lib1)
+target_sources(lib1
+ PRIVATE lib1.c
+ PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES h1.h)
+# Expect install(TARGETS) to respect absolute CMAKE_INSTALL_INCLUDEDIR
+# when installing the HEADERS.
+# Must not prepend the CMAKE_INSTALL_PREFIX in the <pkg>-config.cmake.
+install(TARGETS lib1 EXPORT lib1-config FILE_SET HEADERS)
+install(EXPORT lib1-config NAMESPACE lib1:: DESTINATION share/lib1)
diff --git a/Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirImport.cmake b/Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirImport.cmake
new file mode 100644
index 0000000..123d6ae
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirImport.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+
+get_filename_component(CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}" DIRECTORY)
+string(APPEND CMAKE_PREFIX_PATH "/FileSetAbsoluteInstallIncludeDirExport-build/install")
+
+find_package(lib1 REQUIRED)
+
+add_executable(exe main.cpp)
+target_link_libraries(exe PRIVATE lib1::lib1)
diff --git a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake
index 44f1626..9a8429d 100644
--- a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake
+++ b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake
@@ -1,6 +1,6 @@
enable_language(C)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
add_library(lib1 STATIC empty.c)
target_sources(lib1 PRIVATE FILE_SET UNKNOWN)
diff --git a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake
index adf1185..f63308c 100644
--- a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake
+++ b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake
@@ -1,6 +1,6 @@
enable_language(C)
-set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6")
add_library(lib1 STATIC empty.c)
target_sources(lib1 PRIVATE FILE_SET a TYPE UNKNOWN)
diff --git a/Tests/RunCMake/target_sources/RunCMakeTest.cmake b/Tests/RunCMake/target_sources/RunCMakeTest.cmake
index 90915cd..8505f71 100644
--- a/Tests/RunCMake/target_sources/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_sources/RunCMakeTest.cmake
@@ -99,3 +99,4 @@ function(run_export_import name)
endfunction()
run_export_import(FileSet)
+run_export_import(FileSetAbsoluteInstallIncludeDir)
diff --git a/Tests/SourceGroups/CMakeLists.txt b/Tests/SourceGroups/CMakeLists.txt
index d726395..550fe9e 100644
--- a/Tests/SourceGroups/CMakeLists.txt
+++ b/Tests/SourceGroups/CMakeLists.txt
@@ -63,3 +63,5 @@ add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c
${tree_files_with_prefix} ${tree_files_without_prefix}
${tree_files_with_empty_prefix} README.txt
nested.c)
+
+add_subdirectory(sub2)
diff --git a/Tests/SourceGroups/sub2/CMakeLists.txt b/Tests/SourceGroups/sub2/CMakeLists.txt
new file mode 100644
index 0000000..e457bc4
--- /dev/null
+++ b/Tests/SourceGroups/sub2/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_executable(SourceGroups2 main.c
+ qux.c subsub/qax.c)
+
+source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" ) #PREFIX TheSubDir2 )
diff --git a/Tests/SourceGroups/sub2/main.c b/Tests/SourceGroups/sub2/main.c
new file mode 100644
index 0000000..4cd8ae0
--- /dev/null
+++ b/Tests/SourceGroups/sub2/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+extern int qax(void);
+extern int qux(void);
+
+int main()
+{
+ printf("qux: %d qax: %d\n", qux(), qax());
+
+ return 0;
+}
diff --git a/Tests/SourceGroups/sub2/qux.c b/Tests/SourceGroups/sub2/qux.c
new file mode 100644
index 0000000..1a8b6f9
--- /dev/null
+++ b/Tests/SourceGroups/sub2/qux.c
@@ -0,0 +1,4 @@
+int qux(void)
+{
+ return 1234;
+}
diff --git a/Tests/SourceGroups/sub2/subsub/qax.c b/Tests/SourceGroups/sub2/subsub/qax.c
new file mode 100644
index 0000000..c1b1042
--- /dev/null
+++ b/Tests/SourceGroups/sub2/subsub/qax.c
@@ -0,0 +1,4 @@
+int qax(void)
+{
+ return 123;
+}
diff --git a/Tests/UseSWIG/AlternateLibraryName/CMakeLists.txt b/Tests/UseSWIG/AlternateLibraryName/CMakeLists.txt
index a2c239c..f20593c 100644
--- a/Tests/UseSWIG/AlternateLibraryName/CMakeLists.txt
+++ b/Tests/UseSWIG/AlternateLibraryName/CMakeLists.txt
@@ -7,7 +7,7 @@ include(CTest)
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
-find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+find_package(Python REQUIRED COMPONENTS Interpreter Development)
# Path separator
if (WIN32)
@@ -27,9 +27,9 @@ swig_add_library(example_python
set_target_properties (example_python PROPERTIES
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.."
SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
-target_link_libraries(example_python PRIVATE Python2::Python)
+target_link_libraries(example_python PRIVATE Python::Python)
add_test (NAME AlternateLibraryName.example1
COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}${PS}$<TARGET_FILE_DIR:example_python>"
- "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+ "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index 7c4925e..3d80270 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -147,16 +147,18 @@ add_test(NAME UseSWIG.MultipleModules COMMAND
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
-add_test(NAME UseSWIG.MultiplePython COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/UseSWIG/MultiplePython"
- "${CMake_BINARY_DIR}/Tests/UseSWIG/MultiplePython"
- ${build_generator_args}
- --build-project TestMultiplePython
- --build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+if(CMake_TEST_FindPython2 AND CMake_TEST_FindPython3)
+ add_test(NAME UseSWIG.MultiplePython COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/MultiplePython"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/MultiplePython"
+ ${build_generator_args}
+ --build-project TestMultiplePython
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+endif()
add_test(NAME UseSWIG.MultipleFiles COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -165,20 +167,20 @@ add_test(NAME UseSWIG.MultipleFiles COMMAND
${build_generator_args}
--build-project TestMultipleFiles
--build-options ${build_options}
- )
-
+)
-add_test(NAME UseSWIG.ModuleVersion2 COMMAND
- ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/UseSWIG/ModuleVersion2"
- "${CMake_BINARY_DIR}/Tests/UseSWIG/ModuleVersion2"
- ${build_generator_args}
- --build-project TestModuleVersion2
- --build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+if(CMake_TEST_FindPython2 OR CMake_TEST_FindPython3)
+ add_test(NAME UseSWIG.ModuleVersion2 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/ModuleVersion2"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/ModuleVersion2"
+ ${build_generator_args}
+ --build-project TestModuleVersion2
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
-
+endif()
add_test(NAME UseSWIG.UseTargetINCLUDE_DIRECTORIES COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
diff --git a/Tests/UseSWIG/ModuleName/CMakeLists.txt b/Tests/UseSWIG/ModuleName/CMakeLists.txt
index 435b441..c62319f 100644
--- a/Tests/UseSWIG/ModuleName/CMakeLists.txt
+++ b/Tests/UseSWIG/ModuleName/CMakeLists.txt
@@ -8,14 +8,7 @@ find_package(SWIG REQUIRED)
cmake_policy(SET CMP0086 NEW)
include(${SWIG_USE_FILE})
-find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
-
-# Path separator
-if (WIN32)
- set (PS "$<SEMICOLON>")
-else()
- set (PS ":")
-endif()
+find_package(Python REQUIRED COMPONENTS Interpreter Development)
unset(CMAKE_SWIG_FLAGS)
@@ -34,9 +27,9 @@ set_target_properties (example1 PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1")
-target_link_libraries(example1 PRIVATE Python2::Module)
+target_link_libraries(example1 PRIVATE Python::Module)
add_test (NAME ModuleName.example1
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/Python2${PS}$<TARGET_FILE_DIR:example1>"
- "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py")
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:example1>"
+ "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py")
diff --git a/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt b/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt
index 093e858..317ed47 100644
--- a/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt
+++ b/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt
@@ -7,9 +7,6 @@ include(CTest)
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
-find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
-find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
-
if (WIN32)
set (PS $<SEMICOLON>)
else()
@@ -25,32 +22,69 @@ set_property(SOURCE "../example.i" PROPERTY COMPILE_OPTIONS -includeall)
set_property(SOURCE "../example.i"
PROPERTY GENERATED_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/..")
-swig_add_library(example1
- LANGUAGE python
- SOURCES ../example.i ../example.cxx)
-set_target_properties (example1 PROPERTIES
- OUTPUT_NAME example
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2"
- ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2"
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2")
-target_link_libraries(example1 PRIVATE Python2::Module)
-
-# re-use sample interface file for another plugin
-swig_add_library(example2
- LANGUAGE python
- SOURCES ../example.i ../example.cxx)
-set_target_properties (example2 PROPERTIES
- OUTPUT_NAME example
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3"
- ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3"
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3")
-target_link_libraries(example2 PRIVATE Python3::Module)
-
-
-add_test (NAME ModuleVersion2.example1
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example1,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example1>"
- "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
-
-add_test (NAME ModuleVersion2.example2
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example2,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example2>"
- "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+if(CMake_TEST_FindPython2)
+ find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+
+ swig_add_library(example1
+ LANGUAGE python
+ SOURCES ../example.i ../example.cxx)
+ set_target_properties (example1 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2-1"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2-1"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2-1")
+ target_link_libraries(example1 PRIVATE Python2::Module)
+
+ add_test (NAME ModuleVersion2.example1
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example1,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example1>"
+ "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+
+ # re-use sample interface file for another plugin
+ swig_add_library(example2
+ LANGUAGE python
+ SOURCES ../example.i ../example.cxx)
+ set_target_properties (example2 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2-2"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2-2"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2-2")
+ target_link_libraries(example2 PRIVATE Python2::Module)
+
+ add_test (NAME ModuleVersion2.example2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example2,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example2>"
+ "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+endif()
+
+if(CMake_TEST_FindPython3)
+ find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+
+ swig_add_library(example3
+ LANGUAGE python
+ SOURCES ../example.i ../example.cxx)
+ set_target_properties (example3 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3-1"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3-1"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3-1")
+ target_link_libraries(example3 PRIVATE Python3::Module)
+
+ add_test (NAME ModuleVersion2.example3
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example3,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example3>"
+ "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+
+
+ # re-use sample interface file for another plugin
+ swig_add_library(example4
+ LANGUAGE python
+ SOURCES ../example.i ../example.cxx)
+ set_target_properties (example2 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3-2"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3-2"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3-2")
+ target_link_libraries(example4 PRIVATE Python3::Module)
+
+ add_test (NAME ModuleVersion2.example4
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example4,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example4>"
+ "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+endif()
diff --git a/Tests/UseSWIG/MultipleFiles/CMakeLists.txt b/Tests/UseSWIG/MultipleFiles/CMakeLists.txt
index bf3d946..36734f9 100644
--- a/Tests/UseSWIG/MultipleFiles/CMakeLists.txt
+++ b/Tests/UseSWIG/MultipleFiles/CMakeLists.txt
@@ -11,7 +11,7 @@ unset(SWIG_LANG_DEFINITIONS)
unset(SWIG_LANG_OPTIONS)
unset(SWIG_LANG_LIBRARIES)
-find_package(Python3 REQUIRED COMPONENTS Development)
+find_package(Python REQUIRED COMPONENTS Development)
set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/add.i" PROPERTY CPLUSPLUS ON)
set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/sub.i" PROPERTY CPLUSPLUS ON)
@@ -27,4 +27,4 @@ swig_add_library(example
"${CMAKE_CURRENT_SOURCE_DIR}/add.cxx"
"${CMAKE_CURRENT_SOURCE_DIR}/sub.cxx")
target_include_directories(example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
-target_link_libraries(example PRIVATE Python3::Module)
+target_link_libraries(example PRIVATE Python::Module)
diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
index 80a2e16..6cdf987 100644
--- a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
+++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
@@ -7,7 +7,7 @@ include(CTest)
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
-find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+find_package(Python REQUIRED COMPONENTS Interpreter Development)
unset(CMAKE_SWIG_FLAGS)
@@ -25,7 +25,7 @@ set_target_properties (example1 PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1")
-target_link_libraries(example1 PRIVATE Python3::Module)
+target_link_libraries(example1 PRIVATE Python::Module)
# Check that source property override target property
@@ -42,4 +42,4 @@ set_target_properties (example2 PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2")
-target_link_libraries(example2 PRIVATE Python3::Module)
+target_link_libraries(example2 PRIVATE Python::Module)
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index fee21b6..12b5407 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 3.13...3.25 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index 0f03c33..6056030 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -1,4 +1,6 @@
[
+ # https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUMappings.md
+
# C++ alternatives to C standard headers
{ include: [ "<assert.h>", public, "<cassert>", public ] },
{ include: [ "<complex.h>", public, "<ccomplex>", public ] },
@@ -30,7 +32,7 @@
{ include: [ "<bits/std_abs.h>", private, "<stdlib.h>", public ] },
{ include: [ "<bits/stdint-intn.h>", private, "<stdint.h>", public ] },
{ include: [ "<bits/stdint-uintn.h>", private, "<stdint.h>", public ] },
- { include: [ "<bits/string_view.tcc>", private, "<string_view>", private ] },
+ { include: [ "<bits/string_view.tcc>", private, "<string_view>", public ] },
{ include: [ "<bits/time.h>", private, "<time.h>", public ] },
{ include: [ "<bits/types/clock_t.h>", private, "<time.h>", public ] },
{ include: [ "<bits/types/mbstate_t.h>", private, "<wchar.h>", public ] },
@@ -41,70 +43,16 @@
# HACK: check whether this can be removed with next iwyu release.
{ symbol: [ "__GLIBC__", private, "<stdlib.h>", public ] },
- { symbol: [ "_Noreturn", private, "<stdlib.h>", public ] },
# HACK: iwyu wrongly thinks that including <iosfwd> is sufficient.
{ symbol: [ "std::stringstream", private, "<sstream>", public ] },
{ symbol: [ "std::istringstream", private, "<sstream>", public ] },
{ symbol: [ "std::ostringstream", private, "<sstream>", public ] },
- # HACK: iwyu suggests <ext/alloc_traits.h> and <memory> each time vector[] is used.
- # https://github.com/include-what-you-use/include-what-you-use/issues/166
- { include: [ "<ext/alloc_traits.h>", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmFileLock> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmFileLockPool::ScopePool> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmComputeComponentGraph::TarjanEntry> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmFortranFile> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmGraphEdgeList> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmOrderDirectories::ConflictList> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<cmStateSnapshot> >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<std::basic_string<char> > >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > > >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::value_type", private, "<vector>", public ] },
- { symbol: [ "std::allocator_traits<std::allocator<uv_stdio_container_s> >::value_type", private, "<vector>", public ] },
-
- # TODO: enable this block and remove some <utility> includes?
- #{ symbol: [ "std::pair", private, "<utility>", public ] },
- #{ symbol: [ "std::pair", private, "<map>", public ] },
- #{ symbol: [ "std::pair", private, "<set>", public ] },
-
- # HACK: iwyu wrongly thinks that <system_error> is needed for std::hash
- { symbol: [ "std::hash", private, "<functional>", public ] },
-
- # HACK: iwyu thinks we use a libstdc++ private type
- { symbol: [ "__gnu_cxx::size_t", private, "<cstddef>", public ] },
-
- # __decay_and_strip is used internally in the C++11 standard library.
- # IWYU does not classify it as internal and suggests to add <type_traits>.
- # To ignore it, we simply map it to a file that is included anyway.
- # Use 'CMake_IWYU_VERBOSE' to see the fully qualified names that need this.
- # TODO: Can this be simplified with an @-expression?
- #{ symbol: [ "@std::__decay_and_strip<.*>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<int>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<bool>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<char const (&)[1]>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cmCommand *&>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cmGeneratorTarget *&>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cmFindCommon::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cmSearchPath>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cm::string_view>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<std::basic_string<char> &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<const std::basic_string<char> &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cmFindPackageCommand::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<cmGlobalNinjaGenerator::TargetAlias &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<__gnu_cxx::__normal_iterator<const cmCTestTestHandler::cmCTestTestProperties *, std::vector<cmCTestTestHandler::cmCTestTestProperties, std::allocator<cmCTestTestHandler::cmCTestTestProperties> > > &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<const __gnu_cxx::__normal_iterator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> > *, std::vector<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> >, std::allocator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> > > > > &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__success_type<std::chrono::duration<double, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__success_type<std::chrono::duration<long, std::ratio<1, 1000000000> > >::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<60, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1000> > >::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "__gnu_cxx::__enable_if<true, bool>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::remove_reference<std::basic_string<char, std::char_traits<char>, std::allocator<char> > &>::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::remove_reference<cmCTestTestHandler::Signal &>::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::remove_reference<Defer &>::type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::remove_reference<dap::StoppedEvent &>::type", private, "\"cmConfigure.h\"", public ] },
+ # HACK: iwyu attributes vector's usage of std::max to its caller.
+ # https://github.com/include-what-you-use/include-what-you-use/issues/908
+ { symbol: ["std::max", "private", "<algorithm>", "public" ] },
+ { symbol: ["std::max", "private", "<vector>", "public" ] },
# Wrappers for 3rd-party libraries
{ include: [ "@<.*curl/curlver.h>", private, "<cm3p/curl/curl.h>", public ] },
@@ -127,10 +75,14 @@
{ include: [ "<ostream>", public, "\"cmsys/FStream.hxx\"", public ] },
{ include: [ "<fstream>", public, "\"cmsys/FStream.hxx\"", public ] },
- { include: [ "<filesystem>", private, "<cm/filesystem>", public ] },
- { include: [ "<optional>", private, "<cm/optional>", public ] },
- { include: [ "<shared_mutex>", private, "<cm/shared_mutex>", public ] },
- { include: [ "<string_view>", private, "<cm/string_view>", public ] },
+ { symbol: [ "mode_t", private, "\"cm_sys_stat.h\"", public ] },
+ { symbol: [ "S_IWUSR", private, "\"cm_sys_stat.h\"", public ] },
+ { symbol: [ "S_IWGRP", private, "\"cm_sys_stat.h\"", public ] },
+
+ { include: [ "<filesystem>", public, "<cm/filesystem>", public ] },
+ { include: [ "<optional>", public, "<cm/optional>", public ] },
+ { include: [ "<shared_mutex>", public, "<cm/shared_mutex>", public ] },
+ { include: [ "<string_view>", public, "<cm/string_view>", public ] },
# major and minor are used as macro arguments. Those are false matches.
{ symbol: [ "major", private, "\"cmVersion.h\"", public ] },
diff --git a/Utilities/Release/linux/x86_64/Dockerfile b/Utilities/Release/linux/x86_64/Dockerfile
index 736ee26..71c8776 100644
--- a/Utilities/Release/linux/x86_64/Dockerfile
+++ b/Utilities/Release/linux/x86_64/Dockerfile
@@ -6,8 +6,8 @@
# The resulting image will have an '/out' directory containing the package.
# Keep this in sync with the `.gitlab/os-linux.yml` `.linux_release_x86_64` image.
-ARG FROM_IMAGE_NAME=kitware/cmake:build-linux-x86_64-deps-2020-04-02
-ARG FROM_IMAGE_DIGEST=@sha256:77e9ab183f34680990db9da5945473e288f0d6556bce79ecc1589670d656e157
+ARG FROM_IMAGE_NAME=kitware/cmake:build-linux-x86_64-deps-2023-08-16
+ARG FROM_IMAGE_DIGEST=@sha256:aa0ebdbd90a51cc83d31f393c5c48ec4599a28f7ccdc288558522c6265b24fae
ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
FROM $FROM_IMAGE
@@ -19,8 +19,7 @@ RUN : \
&& mkdir -p /opt/cmake/src/cmake-build \
&& cd /opt/cmake/src/cmake-build \
&& cp ../cmake/Utilities/Release/linux/x86_64/cache.txt CMakeCache.txt \
- && source /opt/rh/devtoolset-6/enable \
- && source /opt/rh/rh-python36/enable \
+ && source /opt/rh/devtoolset-7/enable \
&& set -x \
&& ../cmake/bootstrap --parallel=$(nproc) --docdir=doc/cmake \
&& nice make -j $(nproc) \
diff --git a/Utilities/Release/linux/x86_64/base/Dockerfile b/Utilities/Release/linux/x86_64/base/Dockerfile
index dfc7df8..5df138e 100644
--- a/Utilities/Release/linux/x86_64/base/Dockerfile
+++ b/Utilities/Release/linux/x86_64/base/Dockerfile
@@ -4,8 +4,8 @@
# Produce a base image with a build environment for portable CMake binaries.
# Build using the directory containing this file as its own build context.
-ARG FROM_IMAGE_NAME=centos:6
-ARG FROM_IMAGE_DIGEST=@sha256:dec8f471302de43f4cfcf82f56d99a5227b5ea1aa6d02fa56344986e1f4610e7
+ARG FROM_IMAGE_NAME=centos:7
+ARG FROM_IMAGE_DIGEST=@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
FROM $FROM_IMAGE
@@ -14,8 +14,8 @@ RUN : \
&& yum install -y \
ca-certificates \
curl \
- devtoolset-6-gcc \
- devtoolset-6-gcc-c++ \
+ devtoolset-7-gcc \
+ devtoolset-7-gcc-c++ \
fontconfig-devel \
freetype-devel \
git \
@@ -24,7 +24,8 @@ RUN : \
make \
patch \
perl \
- rh-python36-python-pip \
+ python3-pip \
xz \
+ which \
&& yum clean all \
&& :
diff --git a/Utilities/Release/linux/x86_64/deps/Dockerfile b/Utilities/Release/linux/x86_64/deps/Dockerfile
index 7864aac..b8bd164 100644
--- a/Utilities/Release/linux/x86_64/deps/Dockerfile
+++ b/Utilities/Release/linux/x86_64/deps/Dockerfile
@@ -4,17 +4,11 @@
# Produce an image with custom-built dependencies for portable CMake binaries.
# Build using the directory containing this file as its own build context.
-ARG FROM_IMAGE_NAME=kitware/cmake:build-linux-x86_64-base-2019-08-09
-ARG FROM_IMAGE_DIGEST=@sha256:d2c13617f01181a3143a069e4496d6b78eafffa19d181c42be196d5dfd588151
+ARG FROM_IMAGE_NAME=kitware/cmake:build-linux-x86_64-base-2023-08-16
+ARG FROM_IMAGE_DIGEST=@sha256:95c4d937a635067096dc8fa21b20cce6108ced091d3c42d56cf0261f40406a10
ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
FROM $FROM_IMAGE
-# Sphinx
-RUN : \
- && source /opt/rh/rh-python36/enable \
- && pip install sphinx==2.1.2 \
- && :
-
# Qt
# Version 5.12.0 was the last to bundle xkbcommon.
COPY qt-install.patch /opt/qt/src/
@@ -25,7 +19,7 @@ RUN : \
&& sha512sum qt-everywhere-src-5.12.0.tar.xz | grep -q 0dd03d2645fb6dac5b58c8caf92b4a0a6900131f1ccfb02443a0df4702b5da0458f4c45e758d1b929ec709b0f4b36900df2fd60a058af9cc8c1a0748b6d57aae \
&& tar xJf qt-everywhere-src-5.12.0.tar.xz \
&& cd qt-build \
- && source /opt/rh/devtoolset-6/enable \
+ && source /opt/rh/devtoolset-7/enable \
&& ../qt-everywhere-src-5.12.0/configure \
-prefix /opt/qt \
-static \
@@ -97,7 +91,7 @@ RUN : \
-skip qtxmlpatterns \
-nomake examples \
-nomake tests \
- && make install -j $(nproc) \
+ && make install \
&& cd /opt/qt \
&& patch -p1 -i src/qt-install.patch \
&& cd /opt \
@@ -112,7 +106,7 @@ RUN : \
&& sha512sum ncurses-6.1.tar.gz | grep -q e308af43f8b7e01e98a55f4f6c4ee4d1c39ce09d95399fa555b3f0cdf5fd0db0f4c4d820b4af78a63f6cf6d8627587114a40af48cfc066134b600520808a77ee \
&& tar xzf ncurses-6.1.tar.gz \
&& cd ncurses-build \
- && source /opt/rh/devtoolset-6/enable \
+ && source /opt/rh/devtoolset-7/enable \
&& ../ncurses-6.1/configure \
--prefix=/opt/ncurses \
--with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo \
@@ -129,12 +123,12 @@ COPY openssl-source.patch /opt/openssl/src/
RUN : \
&& mkdir -p /opt/openssl/src \
&& cd /opt/openssl/src \
- && curl -O https://www.openssl.org/source/openssl-1.1.1f.tar.gz \
- && sha512sum openssl-1.1.1f.tar.gz | grep -q b00bd9b5ad5298fbceeec6bb19c1ab0c106ca5cfb31178497c58bf7e0e0cf30fcc19c20f84e23af31cc126bf2447d3e4f8461db97bafa7bd78f69561932f000c \
- && tar xzf openssl-1.1.1f.tar.gz \
- && cd openssl-1.1.1f \
+ && curl -O https://www.openssl.org/source/openssl-1.1.1v.tar.gz \
+ && sha512sum openssl-1.1.1v.tar.gz | grep -q 1a67340d99026aa62bf50ff89165d9f77fe4a6690fe30d1751b5021dd3f238391afd581b41724687c322c4e3af1770c44a63766a06e9b8cab6425101153e0c7e \
+ && tar xzf openssl-1.1.1v.tar.gz \
+ && cd openssl-1.1.1v \
&& patch -p1 -i ../openssl-source.patch \
- && source /opt/rh/devtoolset-6/enable \
+ && source /opt/rh/devtoolset-7/enable \
&& ./Configure --prefix=/opt/openssl linux-elf no-asm no-shared -D_POSIX_C_SOURCE=199506L -D_POSIX_SOURCE=1 -D_SVID_SOURCE=1 -D_BSD_SOURCE=1 \
&& make install_dev -j $(nproc) \
&& cd /opt \
diff --git a/Utilities/Release/linux/x86_64/test/Dockerfile b/Utilities/Release/linux/x86_64/test/Dockerfile
index 6629156..e6c195e 100644
--- a/Utilities/Release/linux/x86_64/test/Dockerfile
+++ b/Utilities/Release/linux/x86_64/test/Dockerfile
@@ -4,8 +4,8 @@
# Produce a base image with a test environment for packaged CMake binaries.
# Build using the directory containing this file as its own build context.
-ARG FROM_IMAGE_NAME=debian:9
-ARG FROM_IMAGE_DIGEST=@sha256:397b2157a9ea8d7f16c613aded70284292106e8b813fb1ed5de8a8785310a26a
+ARG FROM_IMAGE_NAME=debian:10
+ARG FROM_IMAGE_DIGEST=@sha256:b86bfc1dd2fb1820fea6c1e0b6e23d155198b518b3a506f6edad71bf6e9a8cef
ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
FROM $FROM_IMAGE
diff --git a/Utilities/Release/win/qt-5.12.1-win-x86-msvc-install.patch b/Utilities/Release/win/qt-5.15.10-win-x86-msvc-install.patch
index 39a649e..de31d52 100644
--- a/Utilities/Release/win/qt-5.12.1-win-x86-msvc-install.patch
+++ b/Utilities/Release/win/qt-5.15.10-win-x86-msvc-install.patch
@@ -1,26 +1,26 @@
diff --git a/lib/cmake/Qt5Core/Qt5CoreConfig.cmake b/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
-index 04ec302..75d5596 100644
+index 5bad1af..25bf3e3 100644
--- a/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
+++ b/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
-@@ -118,7 +118,7 @@ if (NOT TARGET Qt5::Core)
- list(REMOVE_DUPLICATES Qt5Core_COMPILE_DEFINITIONS)
- list(REMOVE_DUPLICATES Qt5Core_EXECUTABLE_COMPILE_FLAGS)
+@@ -264,7 +264,7 @@ if (NOT TARGET Qt5::Core)
+ return()
+ endif()
- set(_Qt5Core_LIB_DEPENDENCIES "")
+ set(_Qt5Core_LIB_DEPENDENCIES "${_qt5Core_install_prefix}/lib/qtpcre2.lib;netapi32.lib;version.lib")
- add_library(Qt5::Core STATIC IMPORTED)
+ if(NOT Qt5_EXCLUDE_STATIC_DEPENDENCIES)
diff --git a/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake b/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
-index a07b953..2e07371 100644
+index d9966ad..308e4cb 100644
--- a/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
+++ b/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
-@@ -118,7 +118,7 @@ if (NOT TARGET Qt5::Widgets)
- list(REMOVE_DUPLICATES Qt5Widgets_COMPILE_DEFINITIONS)
- list(REMOVE_DUPLICATES Qt5Widgets_EXECUTABLE_COMPILE_FLAGS)
+@@ -264,7 +264,7 @@ if (NOT TARGET Qt5::Widgets)
+ return()
+ endif()
- set(_Qt5Widgets_LIB_DEPENDENCIES "Qt5::Gui;Qt5::Core")
+ set(_Qt5Widgets_LIB_DEPENDENCIES "Qt5::Gui;Qt5::Core;dwmapi.lib;uxtheme.lib")
- add_library(Qt5::Widgets STATIC IMPORTED)
+ if(NOT Qt5_EXCLUDE_STATIC_DEPENDENCIES)
diff --git a/Utilities/Release/win/qt-5.12.1-win-x86-msvc.ps1 b/Utilities/Release/win/qt-5.15.10-win-x86-msvc.ps1
index d9e9617..e1d9ad1 100755
--- a/Utilities/Release/win/qt-5.12.1-win-x86-msvc.ps1
+++ b/Utilities/Release/win/qt-5.15.10-win-x86-msvc.ps1
@@ -32,8 +32,8 @@ if ($env:VCToolsVersion -match '^(?<version>[0-9][0-9]\.[0-9])') {
Write-Host "VCToolsVersion env var not set. Run this from a Visual Studio Command Prompt."
}
-$srcname = "qt-everywhere-src-5.12.1"
-$pkgname = "qt-5.12.1-win-$arch-$toolset-1"
+$srcname = "qt-everywhere-src-5.15.10"
+$pkgname = "qt-5.15.10-win-$arch-$toolset-1"
$topdir = $pwd.Path
$srcdir = Join-Path $topdir $srcname
$blddir = Join-Path $topdir "$pkgname-build"
@@ -41,8 +41,9 @@ $prefix = Join-Path $topdir $pkgname
# JOM
if ( -not (Test-Path -Path "jom")) {
- Invoke-WebRequest -Uri "http://download.qt-project.org/official_releases/jom/unstable-jom.zip" -OutFile jom.zip
- if ($(Get-FileHash "jom.zip").Hash -ne '128fdd846fe24f8594eed37d1d8929a0ea78df563537c0c1b1861a635013fff8') {
+ Invoke-WebRequest -Uri "http://download.qt-project.org/official_releases/jom/jom_1_1_4.zip" -OutFile jom.zip
+ if ($(Get-FileHash "jom.zip").Hash -ne 'd533c1ef49214229681e90196ed2094691e8c4a0a0bef0b2c901debcb562682b') {
+ Write-Host "jom hash does not match"
exit 1
}
Expand-Archive -Path jom.zip -DestinationPath jom
@@ -52,8 +53,9 @@ $jom = "$topdir\jom\jom.exe"
# Qt Source
if ( -not (Test-Path -Path $srcdir)) {
- Invoke-WebRequest -Uri "https://download.qt.io/official_releases/qt/5.12/5.12.1/single/qt-everywhere-src-5.12.1.tar.xz" -OutFile qt.tar.xz
- if ($(Get-FileHash "qt.tar.xz").Hash -ne 'caffbd625c7bc10ff8c5c7a27dbc7d84fa4de146975c0e1ffe904b514ccd6da4') {
+ Invoke-WebRequest -Uri "https://download.qt.io/archive/qt/5.15/5.15.10/single/qt-everywhere-opensource-src-5.15.10.tar.xz" -OutFile qt.tar.xz
+ if ($(Get-FileHash "qt.tar.xz").Hash -ne 'b545cb83c60934adc9a6bbd27e2af79e5013de77d46f5b9f5bb2a3c762bf55ca') {
+ Write-Host "qt hash does not match"
exit 1
}
& $cmake -E tar xvf qt.tar.xz
@@ -94,6 +96,7 @@ if ( -not (Test-Path -Path $blddir)) {
-skip qtlocation `
-skip qtmultimedia `
-skip qtsensors `
+ -skip qtserialbus `
-skip qtserialport `
-skip qtsvg `
-skip qtwayland `
@@ -110,7 +113,7 @@ if ( -not (Test-Path -Path $prefix)) {
& $jom install
# Patch the installation.
Set-Location -Path $prefix
- & $git apply -v (Join-Path $PSScriptRoot qt-5.12.1-win-x86-msvc-install.patch)
+ & $git apply -v (Join-Path $PSScriptRoot qt-5.15.10-win-x86-msvc-install.patch)
}
# Package Qt
diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash
index 4cd75c5..4dae07a 100755
--- a/Utilities/Scripts/update-curl.bash
+++ b/Utilities/Scripts/update-curl.bash
@@ -8,7 +8,7 @@ readonly name="curl"
readonly ownership="Curl Upstream <curl-library@lists.haxx.se>"
readonly subtree="Utilities/cmcurl"
readonly repo="https://github.com/curl/curl.git"
-readonly tag="curl-8_1_2"
+readonly tag="curl-8_2_1"
readonly shortlog=false
readonly paths="
CMake/*
diff --git a/Utilities/Scripts/update-libuv.bash b/Utilities/Scripts/update-libuv.bash
index 280c684..1027436 100755
--- a/Utilities/Scripts/update-libuv.bash
+++ b/Utilities/Scripts/update-libuv.bash
@@ -8,6 +8,10 @@ readonly name="libuv"
readonly ownership="libuv upstream <libuv@googlegroups.com>"
readonly subtree="Utilities/cmlibuv"
readonly repo="https://github.com/libuv/libuv.git"
+# We cannot import libuv 1.45 or higher because it has higher
+# minimum system requirements than we do:
+# - It requires C11 atomics from GCC 4.9+. We support GCC 4.8.
+# - It requires Windows 8, we support Windows 7.
readonly tag="v1.44.2"
readonly shortlog=false
readonly paths="
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index bde6c6b..694ba3c 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 3.13...3.25 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/cmbzip2/CMakeLists.txt b/Utilities/cmbzip2/CMakeLists.txt
index 1d7b265..b52358e 100644
--- a/Utilities/cmbzip2/CMakeLists.txt
+++ b/Utilities/cmbzip2/CMakeLists.txt
@@ -19,3 +19,7 @@ endif()
add_definitions(-D_FILE_OFFSET_BITS=64)
add_library(cmbzip2
blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c)
+
+if(WIN32 AND CMake_BUILD_PCH)
+ target_precompile_headers(cmbzip2 PRIVATE "bzlib.h")
+endif()
diff --git a/Utilities/cmcppdap/CMakeLists.txt b/Utilities/cmcppdap/CMakeLists.txt
index b6841f1..fe48132 100644
--- a/Utilities/cmcppdap/CMakeLists.txt
+++ b/Utilities/cmcppdap/CMakeLists.txt
@@ -37,4 +37,8 @@ if(CMake_HAVE_CXX_ATOMIC_LIB)
target_link_libraries(cmcppdap PRIVATE atomic)
endif()
+if(CMake_BUILD_PCH)
+ target_precompile_headers(cmcppdap PRIVATE "include/dap/protocol.h")
+endif()
+
install(FILES NOTICE DESTINATION ${CMAKE_DOC_DIR}/cmcppdap)
diff --git a/Utilities/cmcurl/CMake/FindNGTCP2.cmake b/Utilities/cmcurl/CMake/FindNGTCP2.cmake
index ff0d49e..ae92e41 100644
--- a/Utilities/cmcurl/CMake/FindNGTCP2.cmake
+++ b/Utilities/cmcurl/CMake/FindNGTCP2.cmake
@@ -31,7 +31,7 @@ Find the ngtcp2 library
This module accepts optional COMPONENTS to control the crypto library (these are
mutually exclusive)::
- OpenSSL: Use libngtcp2_crypto_openssl
+ OpenSSL: Use libngtcp2_crypto_quictls
GnuTLS: Use libngtcp2_crypto_gnutls
Result Variables
@@ -71,7 +71,7 @@ endif()
if(NGTCP2_FIND_COMPONENTS)
set(NGTCP2_CRYPTO_BACKEND "")
foreach(component IN LISTS NGTCP2_FIND_COMPONENTS)
- if(component MATCHES "^(BoringSSL|OpenSSL|wolfSSL|GnuTLS)")
+ if(component MATCHES "^(BoringSSL|quictls|wolfSSL|GnuTLS)")
if(NGTCP2_CRYPTO_BACKEND)
message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected")
endif()
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 82f9b0b..ced5af4 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -242,6 +242,8 @@ endif()
include_directories(${CURL_SOURCE_DIR}/include)
+set(CMAKE_UNITY_BUILD_BATCH_SIZE 0)
+
option(CURL_WERROR "Turn compiler warnings into errors" OFF)
option(PICKY_COMPILER "Enable picky compiler options" ON)
option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
@@ -689,7 +691,7 @@ endif()
option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF)
set(HAVE_BROTLI OFF)
if(CURL_BROTLI)
- find_package(Brotli QUIET)
+ find_package(Brotli REQUIRED)
if(BROTLI_FOUND)
set(HAVE_BROTLI ON)
list(APPEND CURL_LIBS ${BROTLI_LIBRARIES})
@@ -768,7 +770,7 @@ if(USE_NGTCP2)
elseif(HAVE_BORINGSSL)
find_package(NGTCP2 REQUIRED BoringSSL)
else()
- find_package(NGTCP2 REQUIRED OpenSSL)
+ find_package(NGTCP2 REQUIRED quictls)
endif()
CheckQuicSupportInOpenSSL()
elseif(USE_GNUTLS)
@@ -839,9 +841,7 @@ if(NOT CURL_DISABLE_LDAP)
endif()
# Now that we know, we're not using windows LDAP...
- if(USE_WIN32_LDAP)
- check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
- else()
+ if(NOT USE_WIN32_LDAP)
# Check for LDAP
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
diff --git a/Utilities/cmcurl/include/curl/curl.h b/Utilities/cmcurl/include/curl/curl.h
index cae9b1c..b668dc0 100644
--- a/Utilities/cmcurl/include/curl/curl.h
+++ b/Utilities/cmcurl/include/curl/curl.h
@@ -93,7 +93,7 @@
defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
(defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \
- defined(__sun__) || defined(__serenity__)
+ defined(__sun__) || defined(__serenity__) || defined(__vxworks__)
#include <sys/select.h>
#endif
@@ -781,7 +781,7 @@ typedef enum {
CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
HTTP/1.0 */
CURLPROXY_HTTPS = 2, /* HTTPS but stick to HTTP/1 added in 7.52.0 */
- CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.1.0 */
+ CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.2.0 */
CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
in 7.10 */
CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
@@ -2113,7 +2113,7 @@ typedef enum {
CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289),
/* allow RCPT TO command to fail for some recipients */
- CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290),
+ CURLOPT(CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOPTTYPE_LONG, 290),
/* the private SSL-certificate as a "blob" */
CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
@@ -2207,6 +2207,9 @@ typedef enum {
/* Can leak things, gonna exit() soon */
CURLOPT(CURLOPT_QUICK_EXIT, CURLOPTTYPE_LONG, 322),
+ /* set a specific client IP for HAProxy PROXY protocol header? */
+ CURLOPT(CURLOPT_HAPROXY_CLIENT_IP, CURLOPTTYPE_STRINGPOINT, 323),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2235,6 +2238,9 @@ typedef enum {
/* */
#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT
+/* Added in 8.2.0 */
+#define CURLOPT_MAIL_RCPT_ALLLOWFAILS CURLOPT_MAIL_RCPT_ALLOWFAILS
+
#else
/* This is set if CURL_NO_OLDIES is defined at compile-time */
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
@@ -2918,7 +2924,9 @@ typedef enum {
CURLINFO_REFERER = CURLINFO_STRING + 60,
CURLINFO_CAINFO = CURLINFO_STRING + 61,
CURLINFO_CAPATH = CURLINFO_STRING + 62,
- CURLINFO_LASTONE = 62
+ CURLINFO_XFER_ID = CURLINFO_OFF_T + 63,
+ CURLINFO_CONN_ID = CURLINFO_OFF_T + 64,
+ CURLINFO_LASTONE = 64
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
index 5588fa5..4c39a6d 100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -32,13 +32,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "8.1.2"
+#define LIBCURL_VERSION "8.2.1"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 8
-#define LIBCURL_VERSION_MINOR 1
-#define LIBCURL_VERSION_PATCH 2
+#define LIBCURL_VERSION_MINOR 2
+#define LIBCURL_VERSION_PATCH 1
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
@@ -59,7 +59,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x080102
+#define LIBCURL_VERSION_NUM 0x080201
/*
* This is the date and time when the full source package was created. The
diff --git a/Utilities/cmcurl/include/curl/system.h b/Utilities/cmcurl/include/curl/system.h
index def7739..b2640c8 100644
--- a/Utilities/cmcurl/include/curl/system.h
+++ b/Utilities/cmcurl/include/curl/system.h
@@ -237,33 +237,28 @@
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__MVS__)
-# if defined(__IBMC__) || defined(__IBMCPP__)
-# if defined(_ILP32)
-# elif defined(_LP64)
-# endif
-# if defined(_LONG_LONG)
-# define CURL_TYPEOF_CURL_OFF_T long long
-# define CURL_FORMAT_CURL_OFF_T "lld"
-# define CURL_FORMAT_CURL_OFF_TU "llu"
-# define CURL_SUFFIX_CURL_OFF_T LL
-# define CURL_SUFFIX_CURL_OFF_TU ULL
-# elif defined(_LP64)
-# define CURL_TYPEOF_CURL_OFF_T long
-# define CURL_FORMAT_CURL_OFF_T "ld"
-# define CURL_FORMAT_CURL_OFF_TU "lu"
-# define CURL_SUFFIX_CURL_OFF_T L
-# define CURL_SUFFIX_CURL_OFF_TU UL
-# else
-# define CURL_TYPEOF_CURL_OFF_T long
-# define CURL_FORMAT_CURL_OFF_T "ld"
-# define CURL_FORMAT_CURL_OFF_TU "lu"
-# define CURL_SUFFIX_CURL_OFF_T L
-# define CURL_SUFFIX_CURL_OFF_TU UL
-# endif
-# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
-# define CURL_PULL_SYS_TYPES_H 1
-# define CURL_PULL_SYS_SOCKET_H 1
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__370__)
# if defined(__IBMC__) || defined(__IBMCPP__)
diff --git a/Utilities/cmcurl/include/curl/typecheck-gcc.h b/Utilities/cmcurl/include/curl/typecheck-gcc.h
index bc8d7a7..b880f3d 100644
--- a/Utilities/cmcurl/include/curl/typecheck-gcc.h
+++ b/Utilities/cmcurl/include/curl/typecheck-gcc.h
@@ -280,6 +280,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
(option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_HSTS || \
+ (option) == CURLOPT_HAPROXY_CLIENT_IP || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_ISSUERCERT || \
(option) == CURLOPT_KEYPASSWD || \
diff --git a/Utilities/cmcurl/include/curl/websockets.h b/Utilities/cmcurl/include/curl/websockets.h
index fd6a916..6ef6a2b 100644
--- a/Utilities/cmcurl/include/curl/websockets.h
+++ b/Utilities/cmcurl/include/curl/websockets.h
@@ -54,13 +54,13 @@ struct curl_ws_frame {
*/
CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
size_t *recv,
- struct curl_ws_frame **metap);
+ const struct curl_ws_frame **metap);
-/* sendflags for curl_ws_send() */
+/* flags for curl_ws_send() */
#define CURLWS_PONG (1<<6)
/*
- * NAME curl_easy_send()
+ * NAME curl_ws_send()
*
* DESCRIPTION
*
@@ -69,13 +69,13 @@ CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
*/
CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
size_t buflen, size_t *sent,
- curl_off_t framesize,
- unsigned int sendflags);
+ curl_off_t fragsize,
+ unsigned int flags);
/* bits for the CURLOPT_WS_OPTIONS bitmask: */
#define CURLWS_RAW_MODE (1<<0)
-CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl);
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl);
#ifdef __cplusplus
}
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
index f1d0f76..d5d3aa6 100644
--- a/Utilities/cmcurl/lib/CMakeLists.txt
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -89,16 +89,35 @@ add_library(
${CMAKE_CURL_SSL_DLLS}
)
+if(0) # This code not needed for building within CMake.
+add_library(
+ curlu # special libcurlu library just for unittests
+ STATIC
+ EXCLUDE_FROM_ALL
+ ${HHEADERS} ${CSOURCES}
+)
+target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB)
+endif()
+
add_library(
${PROJECT_NAME}::${LIB_NAME}
ALIAS ${LIB_NAME}
)
+if(ENABLE_CURLDEBUG)
+ # We must compile memdebug.c separately to avoid memdebug.h redefinitions
+ # being applied to memdebug.c itself.
+ set_source_files_properties(memdebug.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
+endif()
+
if(NOT BUILD_SHARED_LIBS)
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
endif()
target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS})
+if(0) # This code not needed for building within CMake.
+target_link_libraries(curlu PRIVATE ${CURL_LIBS})
+endif()
if(0) # This code not needed for building within CMake.
transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
@@ -110,6 +129,10 @@ set_target_properties(${LIB_NAME} PROPERTIES
OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
)
+if(WIN32 AND CMake_BUILD_PCH)
+ target_precompile_headers(${LIB_NAME} PRIVATE "curl_setup.h" "curl_sspi.h" "${CURL_SOURCE_DIR}/include/curl/curl.h")
+endif()
+
if(0) # This code not needed for building within CMake.
if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
diff --git a/Utilities/cmcurl/lib/Makefile.inc b/Utilities/cmcurl/lib/Makefile.inc
index f815170..cc7d287 100644
--- a/Utilities/cmcurl/lib/Makefile.inc
+++ b/Utilities/cmcurl/lib/Makefile.inc
@@ -72,6 +72,7 @@ LIB_VTLS_HFILES = \
vtls/openssl.h \
vtls/rustls.h \
vtls/schannel.h \
+ vtls/schannel_int.h \
vtls/sectransp.h \
vtls/vtls.h \
vtls/vtls_int.h \
@@ -179,6 +180,7 @@ LIB_CFILES = \
krb5.c \
ldap.c \
llist.c \
+ macos.c \
md4.c \
md5.c \
memdebug.c \
@@ -315,6 +317,7 @@ LIB_HFILES = \
inet_ntop.h \
inet_pton.h \
llist.h \
+ macos.h \
memdebug.h \
mime.h \
mqtt.h \
diff --git a/Utilities/cmcurl/lib/altsvc.c b/Utilities/cmcurl/lib/altsvc.c
index f812baf..11009d5 100644
--- a/Utilities/cmcurl/lib/altsvc.c
+++ b/Utilities/cmcurl/lib/altsvc.c
@@ -424,7 +424,7 @@ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
#ifdef DEBUGBUILD
/* to play well with debug builds, we can *set* a fixed time this will
return */
-static time_t debugtime(void *unused)
+static time_t altsvc_debugtime(void *unused)
{
char *timestr = getenv("CURL_TIME");
(void)unused;
@@ -434,7 +434,8 @@ static time_t debugtime(void *unused)
}
return time(NULL);
}
-#define time(x) debugtime(x)
+#undef time
+#define time(x) altsvc_debugtime(x)
#endif
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
diff --git a/Utilities/cmcurl/lib/amigaos.c b/Utilities/cmcurl/lib/amigaos.c
index b0a9500..139309b 100644
--- a/Utilities/cmcurl/lib/amigaos.c
+++ b/Utilities/cmcurl/lib/amigaos.c
@@ -178,6 +178,7 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
#endif /* CURLRES_AMIGA */
#ifdef USE_AMISSL
+#include <signal.h>
int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *errorfds, struct timeval *timeout)
{
diff --git a/Utilities/cmcurl/lib/base64.c b/Utilities/cmcurl/lib/base64.c
index 971300e..9d495d4 100644
--- a/Utilities/cmcurl/lib/base64.c
+++ b/Utilities/cmcurl/lib/base64.c
@@ -43,7 +43,7 @@
/* ---- Base64 Encoding/Decoding Table --- */
/* Padding character string starts at offset 64. */
-static const char base64[]=
+static const char base64encdec[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
@@ -120,7 +120,7 @@ CURLcode Curl_base64_decode(const char *src,
/* replaces
{
unsigned char c;
- const unsigned char *p = (const unsigned char *)base64;
+ const unsigned char *p = (const unsigned char *)base64encdec;
for(c = 0; *p; c++, p++)
lookup[*p] = c;
}
@@ -264,7 +264,7 @@ static CURLcode base64_encode(const char *table64,
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
- return base64_encode(base64, inputbuff, insize, outptr, outlen);
+ return base64_encode(base64encdec, inputbuff, insize, outptr, outlen);
}
/*
diff --git a/Utilities/cmcurl/lib/bufq.c b/Utilities/cmcurl/lib/bufq.c
index 30598cf..1555449 100644
--- a/Utilities/cmcurl/lib/bufq.c
+++ b/Utilities/cmcurl/lib/bufq.c
@@ -418,7 +418,8 @@ ssize_t Curl_bufq_write(struct bufq *q,
break;
}
n = chunk_append(tail, buf, len);
- DEBUGASSERT(n);
+ if(!n)
+ break;
nwritten += n;
buf += n;
len -= n;
@@ -528,6 +529,14 @@ ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
}
break;
}
+ if(!chunk_written) {
+ if(!nwritten) {
+ /* treat as blocked */
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ }
+ break;
+ }
Curl_bufq_skip(q, (size_t)chunk_written);
nwritten += chunk_written;
}
@@ -551,7 +560,8 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */
return -1;
}
- /* would block */
+ /* would block, bufq is full, give up */
+ break;
}
}
@@ -562,16 +572,25 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */
return -1;
}
- /* no room in bufq, bail out */
- goto out;
+ /* no room in bufq */
+ break;
}
+ /* edge case of writer returning 0 (and len is >0)
+ * break or we might enter an infinite loop here */
+ if(n == 0)
+ break;
+
/* Maybe only part of `data` has been added, continue to loop */
buf += (size_t)n;
len -= (size_t)n;
nwritten += (size_t)n;
}
-out:
+ if(!nwritten && len) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ *err = CURLE_OK;
return nwritten;
}
diff --git a/Utilities/cmcurl/lib/c-hyper.c b/Utilities/cmcurl/lib/c-hyper.c
index 756aebe..c29983c 100644
--- a/Utilities/cmcurl/lib/c-hyper.c
+++ b/Utilities/cmcurl/lib/c-hyper.c
@@ -71,9 +71,11 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
DEBUGASSERT(conn);
(void)ctx;
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu)", buflen));
result = Curl_read(data, conn->sockfd, (char *)buf, buflen, &nread);
if(result == CURLE_AGAIN) {
/* would block, register interest */
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> EAGAIN", buflen));
if(data->hyp.read_waker)
hyper_waker_free(data->hyp.read_waker);
data->hyp.read_waker = hyper_context_waker(ctx);
@@ -87,6 +89,7 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
failf(data, "Curl_read failed");
return HYPER_IO_ERROR;
}
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> %zd", buflen, nread));
return (size_t)nread;
}
@@ -98,8 +101,12 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx,
CURLcode result;
ssize_t nwrote;
+ DEBUGF(infof(data, "Curl_hyper_send(%zu)", buflen));
result = Curl_write(data, conn->sockfd, (void *)buf, buflen, &nwrote);
+ if(!result && !nwrote)
+ result = CURLE_AGAIN;
if(result == CURLE_AGAIN) {
+ DEBUGF(infof(data, "Curl_hyper_send(%zu) -> EAGAIN", buflen));
/* would block, register interest */
if(data->hyp.write_waker)
hyper_waker_free(data->hyp.write_waker);
@@ -114,6 +121,7 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx,
failf(data, "Curl_write failed");
return HYPER_IO_ERROR;
}
+ DEBUGF(infof(data, "Curl_hyper_send(%zu) -> %zd", buflen, nwrote));
return (size_t)nwrote;
}
@@ -433,8 +441,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
break;
}
else if(t != HYPER_TASK_RESPONSE) {
- *didwhat = KEEP_RECV;
- break;
+ continue;
}
/* HYPER_TASK_RESPONSE */
diff --git a/Utilities/cmcurl/lib/cf-h1-proxy.c b/Utilities/cmcurl/lib/cf-h1-proxy.c
index b42c4e6..c9b157c 100644
--- a/Utilities/cmcurl/lib/cf-h1-proxy.c
+++ b/Utilities/cmcurl/lib/cf-h1-proxy.c
@@ -54,16 +54,16 @@
typedef enum {
- TUNNEL_INIT, /* init/default/no tunnel state */
- TUNNEL_CONNECT, /* CONNECT request is being send */
- TUNNEL_RECEIVE, /* CONNECT answer is being received */
- TUNNEL_RESPONSE, /* CONNECT response received completely */
- TUNNEL_ESTABLISHED,
- TUNNEL_FAILED
-} tunnel_state;
+ H1_TUNNEL_INIT, /* init/default/no tunnel state */
+ H1_TUNNEL_CONNECT, /* CONNECT request is being send */
+ H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
+ H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
+ H1_TUNNEL_ESTABLISHED,
+ H1_TUNNEL_FAILED
+} h1_tunnel_state;
/* struct for HTTP CONNECT tunneling */
-struct tunnel_state {
+struct h1_tunnel_state {
int sockindex;
const char *hostname;
int remote_port;
@@ -78,23 +78,23 @@ struct tunnel_state {
KEEPON_IGNORE
} keepon;
curl_off_t cl; /* size of content to read and ignore */
- tunnel_state tunnel_state;
+ h1_tunnel_state tunnel_state;
BIT(chunked_encoding);
BIT(close_connection);
};
-static bool tunnel_is_established(struct tunnel_state *ts)
+static bool tunnel_is_established(struct h1_tunnel_state *ts)
{
- return ts && (ts->tunnel_state == TUNNEL_ESTABLISHED);
+ return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED);
}
-static bool tunnel_is_failed(struct tunnel_state *ts)
+static bool tunnel_is_failed(struct h1_tunnel_state *ts)
{
- return ts && (ts->tunnel_state == TUNNEL_FAILED);
+ return ts && (ts->tunnel_state == H1_TUNNEL_FAILED);
}
-static CURLcode tunnel_reinit(struct tunnel_state *ts,
+static CURLcode tunnel_reinit(struct h1_tunnel_state *ts,
struct connectdata *conn,
struct Curl_easy *data)
{
@@ -102,7 +102,7 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts,
DEBUGASSERT(ts);
Curl_dyn_reset(&ts->rcvbuf);
Curl_dyn_reset(&ts->req);
- ts->tunnel_state = TUNNEL_INIT;
+ ts->tunnel_state = H1_TUNNEL_INIT;
ts->keepon = KEEPON_CONNECT;
ts->cl = 0;
ts->close_connection = FALSE;
@@ -124,12 +124,12 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts,
return CURLE_OK;
}
-static CURLcode tunnel_init(struct tunnel_state **pts,
+static CURLcode tunnel_init(struct h1_tunnel_state **pts,
struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
- struct tunnel_state *ts;
+ struct h1_tunnel_state *ts;
CURLcode result;
if(conn->handler->flags & PROTOPT_NOTCPPROXY) {
@@ -157,16 +157,16 @@ static CURLcode tunnel_init(struct tunnel_state **pts,
return tunnel_reinit(ts, conn, data);
}
-static void tunnel_go_state(struct Curl_cfilter *cf,
- struct tunnel_state *ts,
- tunnel_state new_state,
- struct Curl_easy *data)
+static void h1_tunnel_go_state(struct Curl_cfilter *cf,
+ struct h1_tunnel_state *ts,
+ h1_tunnel_state new_state,
+ struct Curl_easy *data)
{
if(ts->tunnel_state == new_state)
return;
/* leaving this one */
switch(ts->tunnel_state) {
- case TUNNEL_CONNECT:
+ case H1_TUNNEL_CONNECT:
data->req.ignorebody = FALSE;
break;
default:
@@ -174,36 +174,36 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
}
/* entering this one */
switch(new_state) {
- case TUNNEL_INIT:
+ case H1_TUNNEL_INIT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
tunnel_reinit(ts, cf->conn, data);
break;
- case TUNNEL_CONNECT:
+ case H1_TUNNEL_CONNECT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
- ts->tunnel_state = TUNNEL_CONNECT;
+ ts->tunnel_state = H1_TUNNEL_CONNECT;
ts->keepon = KEEPON_CONNECT;
Curl_dyn_reset(&ts->rcvbuf);
break;
- case TUNNEL_RECEIVE:
+ case H1_TUNNEL_RECEIVE:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'receive'"));
- ts->tunnel_state = TUNNEL_RECEIVE;
+ ts->tunnel_state = H1_TUNNEL_RECEIVE;
break;
- case TUNNEL_RESPONSE:
+ case H1_TUNNEL_RESPONSE:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
- ts->tunnel_state = TUNNEL_RESPONSE;
+ ts->tunnel_state = H1_TUNNEL_RESPONSE;
break;
- case TUNNEL_ESTABLISHED:
+ case H1_TUNNEL_ESTABLISHED:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
infof(data, "CONNECT phase completed");
data->state.authproxy.done = TRUE;
data->state.authproxy.multipass = FALSE;
/* FALLTHROUGH */
- case TUNNEL_FAILED:
- if(new_state == TUNNEL_FAILED)
+ case H1_TUNNEL_FAILED:
+ if(new_state == H1_TUNNEL_FAILED)
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
ts->tunnel_state = new_state;
Curl_dyn_reset(&ts->rcvbuf);
@@ -225,9 +225,9 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
static void tunnel_free(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
- struct tunnel_state *ts = cf->ctx;
+ struct h1_tunnel_state *ts = cf->ctx;
if(ts) {
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
Curl_dyn_free(&ts->rcvbuf);
Curl_dyn_free(&ts->req);
free(ts);
@@ -270,7 +270,7 @@ static CURLcode CONNECT_host(struct Curl_easy *data,
#ifndef USE_HYPER
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts)
+ struct h1_tunnel_state *ts)
{
struct connectdata *conn = cf->conn;
char *hostheader = NULL;
@@ -351,7 +351,7 @@ out:
static CURLcode send_CONNECT(struct Curl_easy *data,
struct connectdata *conn,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
struct SingleRequest *k = &data->req;
@@ -399,7 +399,7 @@ out:
static CURLcode on_resp_header(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
const char *header)
{
CURLcode result = CURLE_OK;
@@ -475,7 +475,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
CURLcode result = CURLE_OK;
@@ -671,7 +671,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
/* The Hyper version of CONNECT */
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts)
+ struct h1_tunnel_state *ts)
{
struct connectdata *conn = cf->conn;
struct hyptransfer *h = &data->hyp;
@@ -882,7 +882,7 @@ error:
static CURLcode send_CONNECT(struct Curl_easy *data,
struct connectdata *conn,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
struct hyptransfer *h = &data->hyp;
@@ -919,7 +919,7 @@ error:
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
struct hyptransfer *h = &data->hyp;
@@ -949,9 +949,9 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
#endif /* USE_HYPER */
-static CURLcode CONNECT(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct tunnel_state *ts)
+static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts)
{
struct connectdata *conn = cf->conn;
CURLcode result;
@@ -973,25 +973,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
}
switch(ts->tunnel_state) {
- case TUNNEL_INIT:
+ case H1_TUNNEL_INIT:
/* Prepare the CONNECT request and make a first attempt to send. */
DEBUGF(LOG_CF(data, cf, "CONNECT start"));
result = start_CONNECT(cf, data, ts);
if(result)
goto out;
- tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_CONNECT, data);
/* FALLTHROUGH */
- case TUNNEL_CONNECT:
+ case H1_TUNNEL_CONNECT:
/* see that the request is completely sent */
DEBUGF(LOG_CF(data, cf, "CONNECT send"));
result = send_CONNECT(data, cf->conn, ts, &done);
if(result || !done)
goto out;
- tunnel_go_state(cf, ts, TUNNEL_RECEIVE, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_RECEIVE, data);
/* FALLTHROUGH */
- case TUNNEL_RECEIVE:
+ case H1_TUNNEL_RECEIVE:
/* read what is there */
DEBUGF(LOG_CF(data, cf, "CONNECT receive"));
result = recv_CONNECT_resp(cf, data, ts, &done);
@@ -1003,10 +1003,10 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
if(result || !done)
goto out;
/* got it */
- tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_RESPONSE, data);
/* FALLTHROUGH */
- case TUNNEL_RESPONSE:
+ case H1_TUNNEL_RESPONSE:
DEBUGF(LOG_CF(data, cf, "CONNECT response"));
if(data->req.newurl) {
/* not the "final" response, we need to do a follow up request.
@@ -1028,7 +1028,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
}
else {
/* staying on this connection, reset state */
- tunnel_go_state(cf, ts, TUNNEL_INIT, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_INIT, data);
}
}
break;
@@ -1039,25 +1039,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
} while(data->req.newurl);
- DEBUGASSERT(ts->tunnel_state == TUNNEL_RESPONSE);
+ DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE);
if(data->info.httpproxycode/100 != 2) {
/* a non-2xx response and we have no next url to try. */
Curl_safefree(data->req.newurl);
/* failure, close this connection to avoid re-use */
streamclose(conn, "proxy CONNECT failure");
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
return CURLE_RECV_ERROR;
}
/* 2xx response, SUCCESS! */
- tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data);
infof(data, "CONNECT tunnel established, response %d",
data->info.httpproxycode);
result = CURLE_OK;
out:
if(result)
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
return result;
}
@@ -1066,7 +1066,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
bool blocking, bool *done)
{
CURLcode result;
- struct tunnel_state *ts = cf->ctx;
+ struct h1_tunnel_state *ts = cf->ctx;
if(cf->connected) {
*done = TRUE;
@@ -1074,7 +1074,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
}
DEBUGF(LOG_CF(data, cf, "connect"));
- result = cf->next->cft->connect(cf->next, data, blocking, done);
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
if(result || !*done)
return result;
@@ -1089,7 +1089,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
/* TODO: can we do blocking? */
/* We want "seamless" operations through HTTP proxy tunnel */
- result = CONNECT(cf, data, ts);
+ result = H1_CONNECT(cf, data, ts);
if(result)
goto out;
Curl_safefree(data->state.aptr.proxyuserpwd);
@@ -1107,7 +1107,7 @@ static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
{
- struct tunnel_state *ts = cf->ctx;
+ struct h1_tunnel_state *ts = cf->ctx;
int fds;
fds = cf->next->cft->get_select_socks(cf->next, data, socks);
@@ -1143,10 +1143,10 @@ static void cf_h1_proxy_close(struct Curl_cfilter *cf,
DEBUGF(LOG_CF(data, cf, "close"));
cf->connected = FALSE;
if(cf->ctx) {
- tunnel_go_state(cf, cf->ctx, TUNNEL_INIT, data);
+ h1_tunnel_go_state(cf, cf->ctx, H1_TUNNEL_INIT, data);
}
if(cf->next)
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
}
diff --git a/Utilities/cmcurl/lib/cf-h2-proxy.c b/Utilities/cmcurl/lib/cf-h2-proxy.c
index 8e76ff8..f6acfc5 100644
--- a/Utilities/cmcurl/lib/cf-h2-proxy.c
+++ b/Utilities/cmcurl/lib/cf-h2-proxy.c
@@ -44,26 +44,25 @@
#include "curl_memory.h"
#include "memdebug.h"
-#define H2_NW_CHUNK_SIZE (128*1024)
-#define H2_NW_RECV_CHUNKS 1
-#define H2_NW_SEND_CHUNKS 1
+#define H2_CHUNK_SIZE (16*1024)
-#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
+#define PROXY_HTTP2_HUGE_WINDOW_SIZE (100 * 1024 * 1024)
+#define H2_TUNNEL_WINDOW_SIZE (10 * 1024 * 1024)
+
+#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / H2_CHUNK_SIZE)
+#define PROXY_H2_NW_SEND_CHUNKS 1
+
+#define H2_TUNNEL_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / H2_CHUNK_SIZE)
+#define H2_TUNNEL_SEND_CHUNKS ((128 * 1024) / H2_CHUNK_SIZE)
-#define H2_TUNNEL_WINDOW_SIZE (1024 * 1024)
-#define H2_TUNNEL_CHUNK_SIZE (32 * 1024)
-#define H2_TUNNEL_RECV_CHUNKS \
- (H2_TUNNEL_WINDOW_SIZE / H2_TUNNEL_CHUNK_SIZE)
-#define H2_TUNNEL_SEND_CHUNKS \
- (H2_TUNNEL_WINDOW_SIZE / H2_TUNNEL_CHUNK_SIZE)
typedef enum {
- TUNNEL_INIT, /* init/default/no tunnel state */
- TUNNEL_CONNECT, /* CONNECT request is being send */
- TUNNEL_RESPONSE, /* CONNECT response received completely */
- TUNNEL_ESTABLISHED,
- TUNNEL_FAILED
-} tunnel_state;
+ H2_TUNNEL_INIT, /* init/default/no tunnel state */
+ H2_TUNNEL_CONNECT, /* CONNECT request is being send */
+ H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
+ H2_TUNNEL_ESTABLISHED,
+ H2_TUNNEL_FAILED
+} h2_tunnel_state;
struct tunnel_stream {
struct http_resp *resp;
@@ -72,10 +71,11 @@ struct tunnel_stream {
char *authority;
int32_t stream_id;
uint32_t error;
- tunnel_state state;
- bool has_final_response;
- bool closed;
- bool reset;
+ size_t upload_blocked_len;
+ h2_tunnel_state state;
+ BIT(has_final_response);
+ BIT(closed);
+ BIT(reset);
};
static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
@@ -85,11 +85,11 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
int port;
bool ipv6_ip = cf->conn->bits.ipv6_ip;
- ts->state = TUNNEL_INIT;
+ ts->state = H2_TUNNEL_INIT;
ts->stream_id = -1;
- Curl_bufq_init2(&ts->recvbuf, H2_TUNNEL_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
+ Curl_bufq_init2(&ts->recvbuf, H2_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
BUFQ_OPT_SOFT_LIMIT);
- Curl_bufq_init(&ts->sendbuf, H2_TUNNEL_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
+ Curl_bufq_init(&ts->sendbuf, H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
if(cf->conn->bits.conn_to_host)
hostname = cf->conn->conn_to_host.name;
@@ -123,13 +123,13 @@ static void tunnel_stream_clear(struct tunnel_stream *ts)
Curl_bufq_free(&ts->sendbuf);
Curl_safefree(ts->authority);
memset(ts, 0, sizeof(*ts));
- ts->state = TUNNEL_INIT;
+ ts->state = H2_TUNNEL_INIT;
}
-static void tunnel_go_state(struct Curl_cfilter *cf,
- struct tunnel_stream *ts,
- tunnel_state new_state,
- struct Curl_easy *data)
+static void h2_tunnel_go_state(struct Curl_cfilter *cf,
+ struct tunnel_stream *ts,
+ h2_tunnel_state new_state,
+ struct Curl_easy *data)
{
(void)cf;
@@ -137,7 +137,7 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
return;
/* leaving this one */
switch(ts->state) {
- case TUNNEL_CONNECT:
+ case H2_TUNNEL_CONNECT:
data->req.ignorebody = FALSE;
break;
default:
@@ -145,29 +145,29 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
}
/* entering this one */
switch(new_state) {
- case TUNNEL_INIT:
+ case H2_TUNNEL_INIT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
tunnel_stream_clear(ts);
break;
- case TUNNEL_CONNECT:
+ case H2_TUNNEL_CONNECT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
- ts->state = TUNNEL_CONNECT;
+ ts->state = H2_TUNNEL_CONNECT;
break;
- case TUNNEL_RESPONSE:
+ case H2_TUNNEL_RESPONSE:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
- ts->state = TUNNEL_RESPONSE;
+ ts->state = H2_TUNNEL_RESPONSE;
break;
- case TUNNEL_ESTABLISHED:
+ case H2_TUNNEL_ESTABLISHED:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
infof(data, "CONNECT phase completed");
data->state.authproxy.done = TRUE;
data->state.authproxy.multipass = FALSE;
/* FALLTHROUGH */
- case TUNNEL_FAILED:
- if(new_state == TUNNEL_FAILED)
+ case H2_TUNNEL_FAILED:
+ if(new_state == H2_TUNNEL_FAILED)
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
ts->state = new_state;
/* If a proxy-authorization header was used for the proxy, then we should
@@ -191,9 +191,11 @@ struct cf_h2_proxy_ctx {
int32_t last_stream_id;
BIT(conn_closed);
BIT(goaway);
+ BIT(nw_out_blocked);
};
/* How to access `call_data` from a cf_h2 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
@@ -219,35 +221,54 @@ static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx)
}
}
-static ssize_t nw_in_reader(void *reader_ctx,
- unsigned char *buf, size_t buflen,
- CURLcode *err)
+static void drain_tunnel(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *tunnel)
+{
+ unsigned char bits;
+
+ (void)cf;
+ bits = CURL_CSELECT_IN;
+ if(!tunnel->closed && !tunnel->reset && tunnel->upload_blocked_len)
+ bits |= CURL_CSELECT_OUT;
+ if(data->state.dselect_bits != bits) {
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] DRAIN dselect_bits=%x",
+ tunnel->stream_id, bits));
+ data->state.dselect_bits = bits;
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ }
+}
+
+static ssize_t proxy_nw_in_reader(void *reader_ctx,
+ unsigned char *buf, size_t buflen,
+ CURLcode *err)
{
struct Curl_cfilter *cf = reader_ctx;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
nread = Curl_conn_cf_recv(cf->next, data, (char *)buf, buflen, err);
- DEBUGF(LOG_CF(data, cf, "nw_in recv(len=%zu) -> %zd, %d",
+ DEBUGF(LOG_CF(data, cf, "nw_in_reader(len=%zu) -> %zd, %d",
buflen, nread, *err));
return nread;
}
-static ssize_t nw_out_writer(void *writer_ctx,
- const unsigned char *buf, size_t buflen,
- CURLcode *err)
+static ssize_t proxy_h2_nw_out_writer(void *writer_ctx,
+ const unsigned char *buf, size_t buflen,
+ CURLcode *err)
{
struct Curl_cfilter *cf = writer_ctx;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, err);
- DEBUGF(LOG_CF(data, cf, "nw_out send(len=%zu) -> %zd", buflen, nwritten));
+ DEBUGF(LOG_CF(data, cf, "nw_out_writer(len=%zu) -> %zd, %d",
+ buflen, nwritten, *err));
return nwritten;
}
-static int h2_client_new(struct Curl_cfilter *cf,
- nghttp2_session_callbacks *cbs)
+static int proxy_h2_client_new(struct Curl_cfilter *cf,
+ nghttp2_session_callbacks *cbs)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
nghttp2_option *o;
@@ -271,15 +292,18 @@ static int h2_client_new(struct Curl_cfilter *cf,
static ssize_t on_session_send(nghttp2_session *h2,
const uint8_t *buf, size_t blen,
int flags, void *userp);
-static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
- void *userp);
-static int on_stream_close(nghttp2_session *session, int32_t stream_id,
- uint32_t error_code, void *userp);
-static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
- const uint8_t *name, size_t namelen,
- const uint8_t *value, size_t valuelen,
- uint8_t flags,
- void *userp);
+static int proxy_h2_on_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp);
+static int proxy_h2_on_stream_close(nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code, void *userp);
+static int proxy_h2_on_header(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp);
static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const uint8_t *mem, size_t len, void *userp);
@@ -298,8 +322,8 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
DEBUGASSERT(!ctx->h2);
memset(&ctx->tunnel, 0, sizeof(ctx->tunnel));
- Curl_bufq_init(&ctx->inbufq, H2_NW_CHUNK_SIZE, H2_NW_RECV_CHUNKS);
- Curl_bufq_init(&ctx->outbufq, H2_NW_CHUNK_SIZE, H2_NW_SEND_CHUNKS);
+ Curl_bufq_init(&ctx->inbufq, H2_CHUNK_SIZE, PROXY_H2_NW_RECV_CHUNKS);
+ Curl_bufq_init(&ctx->outbufq, H2_CHUNK_SIZE, PROXY_H2_NW_SEND_CHUNKS);
if(tunnel_stream_init(cf, &ctx->tunnel))
goto out;
@@ -311,14 +335,16 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
}
nghttp2_session_callbacks_set_send_callback(cbs, on_session_send);
- nghttp2_session_callbacks_set_on_frame_recv_callback(cbs, on_frame_recv);
+ nghttp2_session_callbacks_set_on_frame_recv_callback(
+ cbs, proxy_h2_on_frame_recv);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
cbs, tunnel_recv_callback);
- nghttp2_session_callbacks_set_on_stream_close_callback(cbs, on_stream_close);
- nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
+ nghttp2_session_callbacks_set_on_stream_close_callback(
+ cbs, proxy_h2_on_stream_close);
+ nghttp2_session_callbacks_set_on_header_callback(cbs, proxy_h2_on_header);
/* The nghttp2 session is not yet setup, do it */
- rc = h2_client_new(cf, cbs);
+ rc = proxy_h2_client_new(cf, cbs);
if(rc) {
failf(data, "Couldn't initialize nghttp2");
goto out;
@@ -343,7 +369,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
}
rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0,
- HTTP2_HUGE_WINDOW_SIZE);
+ PROXY_HTTP2_HUGE_WINDOW_SIZE);
if(rc) {
failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
nghttp2_strerror(rc), rc);
@@ -362,27 +388,35 @@ out:
return result;
}
-static CURLcode nw_out_flush(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static int should_close_session(struct cf_h2_proxy_ctx *ctx)
+{
+ return !nghttp2_session_want_read(ctx->h2) &&
+ !nghttp2_session_want_write(ctx->h2);
+}
+
+static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
- size_t buflen = Curl_bufq_len(&ctx->outbufq);
ssize_t nwritten;
CURLcode result;
(void)data;
- if(!buflen)
+ if(Curl_bufq_is_empty(&ctx->outbufq))
return CURLE_OK;
- DEBUGF(LOG_CF(data, cf, "h2 conn flush %zu bytes", buflen));
- nwritten = Curl_bufq_pass(&ctx->outbufq, nw_out_writer, cf, &result);
+ nwritten = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf,
+ &result);
if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ DEBUGF(LOG_CF(data, cf, "flush nw send buffer(%zu) -> EAGAIN",
+ Curl_bufq_len(&ctx->outbufq)));
+ ctx->nw_out_blocked = 1;
+ }
return result;
}
- if((size_t)nwritten < buflen) {
- return CURLE_AGAIN;
- }
- return CURLE_OK;
+ DEBUGF(LOG_CF(data, cf, "nw send buffer flushed"));
+ return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
}
/*
@@ -390,9 +424,9 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
* This function returns 0 if it succeeds, or -1 and error code will
* be assigned to *err.
*/
-static int h2_process_pending_input(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- CURLcode *err)
+static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ CURLcode *err)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
const unsigned char *buf;
@@ -422,19 +456,11 @@ static int h2_process_pending_input(struct Curl_cfilter *cf,
}
}
- if(nghttp2_session_check_request_allowed(ctx->h2) == 0) {
- /* No more requests are allowed in the current session, so
- the connection may not be reused. This is set when a
- GOAWAY frame has been received or when the limit of stream
- identifiers has been reached. */
- connclose(cf->conn, "http/2: No new requests allowed");
- }
-
return 0;
}
-static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
CURLcode result = CURLE_OK;
@@ -442,9 +468,9 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
/* Process network input buffer fist */
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
- DEBUGF(LOG_CF(data, cf, "Process %zd bytes in connection buffer",
+ DEBUGF(LOG_CF(data, cf, "Process %zu bytes in connection buffer",
Curl_bufq_len(&ctx->inbufq)));
- if(h2_process_pending_input(cf, data, &result) < 0)
+ if(proxy_h2_process_pending_input(cf, data, &result) < 0)
return result;
}
@@ -455,8 +481,8 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
!Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
- nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
- DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
+ nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
+ DEBUGF(LOG_CF(data, cf, "read %zu bytes nw data -> %zd, %d",
Curl_bufq_len(&ctx->inbufq), nread, result));
if(nread < 0) {
if(result != CURLE_AGAIN) {
@@ -470,7 +496,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
break;
}
- if(h2_process_pending_input(cf, data, &result))
+ if(proxy_h2_process_pending_input(cf, data, &result))
return result;
}
@@ -481,25 +507,22 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
return CURLE_OK;
}
-/*
- * Check if there's been an update in the priority /
- * dependency settings and if so it submits a PRIORITY frame with the updated
- * info.
- * Flush any out data pending in the network buffer.
- */
-static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode proxy_h2_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
int rv = 0;
- rv = nghttp2_session_send(ctx->h2);
+ ctx->nw_out_blocked = 0;
+ while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2))
+ rv = nghttp2_session_send(ctx->h2);
+
if(nghttp2_is_fatal(rv)) {
DEBUGF(LOG_CF(data, cf, "nghttp2_session_send error (%s)%d",
nghttp2_strerror(rv), rv));
return CURLE_SEND_ERROR;
}
- return nw_out_flush(cf, data);
+ return proxy_h2_nw_out_flush(cf, data);
}
static ssize_t on_session_send(nghttp2_session *h2,
@@ -517,7 +540,7 @@ static ssize_t on_session_send(nghttp2_session *h2,
DEBUGASSERT(data);
nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
- nw_out_writer, cf, &result);
+ proxy_h2_nw_out_writer, cf, &result);
if(nwritten < 0) {
if(result == CURLE_AGAIN) {
return NGHTTP2_ERR_WOULDBLOCK;
@@ -532,8 +555,9 @@ static ssize_t on_session_send(nghttp2_session *h2,
return nwritten;
}
-static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
- void *userp)
+static int proxy_h2_on_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp)
{
struct Curl_cfilter *cf = userp;
struct cf_h2_proxy_ctx *ctx = cf->ctx;
@@ -616,11 +640,12 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
return 0;
}
-static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
- const uint8_t *name, size_t namelen,
- const uint8_t *value, size_t valuelen,
- uint8_t flags,
- void *userp)
+static int proxy_h2_on_header(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp)
{
struct Curl_cfilter *cf = userp;
struct cf_h2_proxy_ctx *ctx = cf->ctx;
@@ -752,8 +777,9 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
return 0;
}
-static int on_stream_close(nghttp2_session *session, int32_t stream_id,
- uint32_t error_code, void *userp)
+static int proxy_h2_on_stream_close(nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code, void *userp)
{
struct Curl_cfilter *cf = userp;
struct cf_h2_proxy_ctx *ctx = cf->ctx;
@@ -765,7 +791,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
if(stream_id != ctx->tunnel.stream_id)
return 0;
- DEBUGF(LOG_CF(data, cf, "[h2sid=%u] on_stream_close, %s (err %d)",
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%u] proxy_h2_on_stream_close, %s (err %d)",
stream_id, nghttp2_http2_strerror(error_code), error_code));
ctx->tunnel.closed = TRUE;
ctx->tunnel.error = error_code;
@@ -773,15 +799,15 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return 0;
}
-static CURLcode h2_submit(int32_t *pstream_id,
- struct Curl_cfilter *cf,
- struct Curl_easy *data,
- nghttp2_session *h2,
- struct httpreq *req,
- const nghttp2_priority_spec *pri_spec,
- void *stream_user_data,
- nghttp2_data_source_read_callback read_callback,
- void *read_ctx)
+static CURLcode proxy_h2_submit(int32_t *pstream_id,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ nghttp2_session *h2,
+ struct httpreq *req,
+ const nghttp2_priority_spec *pri_spec,
+ void *stream_user_data,
+ nghttp2_data_source_read_callback read_callback,
+ void *read_ctx)
{
struct dynhds h2_headers;
nghttp2_nv *nva = NULL;
@@ -881,8 +907,8 @@ static CURLcode submit_CONNECT(struct Curl_cfilter *cf,
if(result)
goto out;
- result = h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
- NULL, ts, tunnel_send_callback, cf);
+ result = proxy_h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
+ NULL, ts, tunnel_send_callback, cf);
if(result) {
DEBUGF(LOG_CF(data, cf, "send: nghttp2_submit_request error (%s)%u",
nghttp2_strerror(ts->stream_id), ts->stream_id));
@@ -907,7 +933,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
DEBUGASSERT(ts->resp);
if(ts->resp->status/100 == 2) {
infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
- tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data);
return CURLE_OK;
}
@@ -928,7 +954,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
if(data->req.newurl) {
/* Inidicator that we should try again */
Curl_safefree(data->req.newurl);
- tunnel_go_state(cf, ts, TUNNEL_INIT, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_INIT, data);
return CURLE_OK;
}
}
@@ -937,9 +963,9 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
return CURLE_RECV_ERROR;
}
-static CURLcode CONNECT(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct tunnel_stream *ts)
+static CURLcode H2_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *ts)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
CURLcode result = CURLE_OK;
@@ -948,27 +974,27 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
DEBUGASSERT(ts->authority);
do {
switch(ts->state) {
- case TUNNEL_INIT:
+ case H2_TUNNEL_INIT:
/* Prepare the CONNECT request and make a first attempt to send. */
DEBUGF(LOG_CF(data, cf, "CONNECT start for %s", ts->authority));
result = submit_CONNECT(cf, data, ts);
if(result)
goto out;
- tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_CONNECT, data);
/* FALLTHROUGH */
- case TUNNEL_CONNECT:
+ case H2_TUNNEL_CONNECT:
/* see that the request is completely sent */
- result = h2_progress_ingress(cf, data);
+ result = proxy_h2_progress_ingress(cf, data);
if(!result)
- result = h2_progress_egress(cf, data);
- if(result) {
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ result = proxy_h2_progress_egress(cf, data);
+ if(result && result != CURLE_AGAIN) {
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
break;
}
if(ts->has_final_response) {
- tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_RESPONSE, data);
}
else {
result = CURLE_OK;
@@ -976,28 +1002,28 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
}
/* FALLTHROUGH */
- case TUNNEL_RESPONSE:
+ case H2_TUNNEL_RESPONSE:
DEBUGASSERT(ts->has_final_response);
result = inspect_response(cf, data, ts);
if(result)
goto out;
break;
- case TUNNEL_ESTABLISHED:
+ case H2_TUNNEL_ESTABLISHED:
return CURLE_OK;
- case TUNNEL_FAILED:
+ case H2_TUNNEL_FAILED:
return CURLE_RECV_ERROR;
default:
break;
}
- } while(ts->state == TUNNEL_INIT);
+ } while(ts->state == H2_TUNNEL_INIT);
out:
if(result || ctx->tunnel.closed)
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
return result;
}
@@ -1043,10 +1069,10 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
- result = CONNECT(cf, data, ts);
+ result = H2_CONNECT(cf, data, ts);
out:
- *done = (result == CURLE_OK) && (ts->state == TUNNEL_ESTABLISHED);
+ *done = (result == CURLE_OK) && (ts->state == H2_TUNNEL_ESTABLISHED);
cf->connected = *done;
CF_DATA_RESTORE(cf, save);
return result;
@@ -1082,7 +1108,7 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) ||
- (ctx && ctx->tunnel.state == TUNNEL_ESTABLISHED &&
+ (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED &&
!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
return TRUE;
return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
@@ -1188,14 +1214,14 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
struct cf_call_data save;
CURLcode result;
- if(ctx->tunnel.state != TUNNEL_ESTABLISHED) {
+ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
*err = CURLE_RECV_ERROR;
return -1;
}
CF_DATA_SAVE(save, cf, data);
if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) {
- *err = h2_progress_ingress(cf, data);
+ *err = proxy_h2_progress_ingress(cf, data);
if(*err)
goto out;
}
@@ -1208,13 +1234,19 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, (size_t)nread);
}
- result = h2_progress_egress(cf, data);
- if(result) {
+ result = proxy_h2_progress_egress(cf, data);
+ if(result && result != CURLE_AGAIN) {
*err = result;
nread = -1;
}
out:
+ if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) &&
+ (nread >= 0 || *err == CURLE_AGAIN)) {
+ /* data pending and no fatal error to report. Need to trigger
+ * draining to avoid stalling when no socket events happen. */
+ drain_tunnel(cf, data, &ctx->tunnel);
+ }
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] cf_recv(len=%zu) -> %zd %d",
ctx->tunnel.stream_id, len, nread, *err));
CF_DATA_RESTORE(cf, save);
@@ -1223,93 +1255,188 @@ out:
static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
- const void *mem, size_t len, CURLcode *err)
+ const void *buf, size_t len, CURLcode *err)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
struct cf_call_data save;
- ssize_t nwritten = -1;
- const unsigned char *buf = mem;
- size_t start_len = len;
int rv;
+ ssize_t nwritten;
+ CURLcode result;
+ int blocked = 0;
- if(ctx->tunnel.state != TUNNEL_ESTABLISHED) {
+ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
*err = CURLE_SEND_ERROR;
return -1;
}
CF_DATA_SAVE(save, cf, data);
- while(len) {
+ if(ctx->tunnel.closed) {
+ nwritten = -1;
+ *err = CURLE_SEND_ERROR;
+ goto out;
+ }
+ else if(ctx->tunnel.upload_blocked_len) {
+ /* the data in `buf` has alread been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= ctx->tunnel.upload_blocked_len);
+ if(len < ctx->tunnel.upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happend. We are not prepared to handle that. */
+ failf(data, "HTTP/2 proxy, send again with decreased length");
+ *err = CURLE_HTTP2;
+ nwritten = -1;
+ goto out;
+ }
+ nwritten = (ssize_t)ctx->tunnel.upload_blocked_len;
+ ctx->tunnel.upload_blocked_len = 0;
+ }
+ else {
nwritten = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, err);
- if(nwritten <= 0) {
- if(*err && *err != CURLE_AGAIN) {
- DEBUGF(LOG_CF(data, cf, "error adding data to tunnel sendbuf: %d",
- *err));
- nwritten = -1;
+ if(nwritten < 0) {
+ if(*err != CURLE_AGAIN)
goto out;
- }
- /* blocked */
nwritten = 0;
}
- else {
- DEBUGASSERT((size_t)nwritten <= len);
- buf += (size_t)nwritten;
- len -= (size_t)nwritten;
- }
+ }
- /* resume the tunnel stream and let the h2 session send, which
- * triggers reading from tunnel.sendbuf */
+ if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
+ /* req body data is buffered, resume the potentially suspended stream */
rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id);
if(nghttp2_is_fatal(rv)) {
*err = CURLE_SEND_ERROR;
nwritten = -1;
goto out;
}
- *err = h2_progress_egress(cf, data);
- if(*err) {
- nwritten = -1;
- goto out;
- }
-
- if(!nwritten && Curl_bufq_is_full(&ctx->tunnel.sendbuf)) {
- size_t rwin;
- /* we could not add to the buffer and after session processing,
- * it is still full. */
- rwin = nghttp2_session_get_stream_remote_window_size(
- ctx->h2, ctx->tunnel.stream_id);
- DEBUGF(LOG_CF(data, cf, "cf_send: tunnel win %u/%zu",
- nghttp2_session_get_remote_window_size(ctx->h2), rwin));
- if(rwin == 0) {
- /* We cannot upload more as the stream's remote window size
- * is 0. We need to receive WIN_UPDATEs before we can continue.
- */
- data->req.keepon |= KEEP_SEND_HOLD;
- DEBUGF(LOG_CF(data, cf, "pausing send as remote flow "
- "window is exhausted"));
- }
- break;
- }
}
- nwritten = start_len - len;
- if(nwritten > 0) {
- *err = CURLE_OK;
+ /* Call the nghttp2 send loop and flush to write ALL buffered data,
+ * headers and/or request body completely out to the network */
+ result = proxy_h2_progress_egress(cf, data);
+ if(result == CURLE_AGAIN) {
+ blocked = 1;
}
- else if(ctx->tunnel.closed) {
+ else if(result) {
+ *err = result;
nwritten = -1;
- *err = CURLE_SEND_ERROR;
+ goto out;
}
- else {
- nwritten = -1;
+ else if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
+ /* although we wrote everything that nghttp2 wants to send now,
+ * there is data left in our stream send buffer unwritten. This may
+ * be due to the stream's HTTP/2 flow window being exhausted. */
+ blocked = 1;
+ }
+
+ if(blocked) {
+ /* Unable to send all data, due to connection blocked or H2 window
+ * exhaustion. Data is left in our stream buffer, or nghttp2's internal
+ * frame buffer or our network out buffer. */
+ size_t rwin = nghttp2_session_get_stream_remote_window_size(
+ ctx->h2, ctx->tunnel.stream_id);
+ if(rwin == 0) {
+ /* H2 flow window exhaustion.
+ * FIXME: there is no way to HOLD all transfers that use this
+ * proxy connection AND to UNHOLD all of them again when the
+ * window increases.
+ * We *could* iterate over all data on this conn maybe? */
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] remote flow "
+ "window is exhausted", ctx->tunnel.stream_id));
+ }
+
+ /* Whatever the cause, we need to return CURL_EAGAIN for this call.
+ * We have unwritten state that needs us being invoked again and EAGAIN
+ * is the only way to ensure that. */
+ ctx->tunnel.upload_blocked_len = nwritten;
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) BLOCK: win %u/%zu "
+ "blocked_len=%zu",
+ ctx->tunnel.stream_id, len,
+ nghttp2_session_get_remote_window_size(ctx->h2), rwin,
+ nwritten));
*err = CURLE_AGAIN;
+ nwritten = -1;
+ goto out;
+ }
+ else if(should_close_session(ctx)) {
+ /* nghttp2 thinks this session is done. If the stream has not been
+ * closed, this is an error state for out transfer */
+ if(ctx->tunnel.closed) {
+ *err = CURLE_SEND_ERROR;
+ nwritten = -1;
+ }
+ else {
+ DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
+ *err = CURLE_HTTP2;
+ nwritten = -1;
+ }
}
out:
- DEBUGF(LOG_CF(data, cf, "cf_send(len=%zu) -> %zd, %d ",
- start_len, nwritten, *err));
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) -> %zd, %d, "
+ "h2 windows %d-%d (stream-conn), "
+ "buffers %zu-%zu (stream-conn)",
+ ctx->tunnel.stream_id, len, nwritten, *err,
+ nghttp2_session_get_stream_remote_window_size(
+ ctx->h2, ctx->tunnel.stream_id),
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&ctx->tunnel.sendbuf),
+ Curl_bufq_len(&ctx->outbufq)));
CF_DATA_RESTORE(cf, save);
return nwritten;
}
+static bool proxy_h2_connisalive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ bool alive = TRUE;
+
+ *input_pending = FALSE;
+ if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending))
+ return FALSE;
+
+ if(*input_pending) {
+ /* This happens before we've sent off a request and the connection is
+ not in use by any other transfer, there shouldn't be any data here,
+ only "protocol frames" */
+ CURLcode result;
+ ssize_t nread = -1;
+
+ *input_pending = FALSE;
+ nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
+ if(nread != -1) {
+ if(proxy_h2_process_pending_input(cf, data, &result) < 0)
+ /* immediate error, considered dead */
+ alive = FALSE;
+ else {
+ alive = !should_close_session(ctx);
+ }
+ }
+ else if(result != CURLE_AGAIN) {
+ /* the read failed so let's say this is dead anyway */
+ alive = FALSE;
+ }
+ }
+
+ return alive;
+}
+
+static bool cf_h2_proxy_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result;
+ struct cf_call_data save;
+
+ CF_DATA_SAVE(save, cf, data);
+ result = (ctx && ctx->h2 && proxy_h2_connisalive(cf, data, input_pending));
+ DEBUGF(LOG_CF(data, cf, "conn alive -> %d, input_pending=%d",
+ result, *input_pending));
+ CF_DATA_RESTORE(cf, save);
+ return result;
+}
+
struct Curl_cftype Curl_cft_h2_proxy = {
"H2-PROXY",
CF_TYPE_IP_CONNECT,
@@ -1323,7 +1450,7 @@ struct Curl_cftype Curl_cft_h2_proxy = {
cf_h2_proxy_send,
cf_h2_proxy_recv,
Curl_cf_def_cntrl,
- Curl_cf_def_conn_is_alive,
+ cf_h2_proxy_is_alive,
Curl_cf_def_conn_keep_alive,
Curl_cf_def_query,
};
diff --git a/Utilities/cmcurl/lib/cf-haproxy.c b/Utilities/cmcurl/lib/cf-haproxy.c
index 86d7fd1..ec0100c 100644
--- a/Utilities/cmcurl/lib/cf-haproxy.c
+++ b/Utilities/cmcurl/lib/cf-haproxy.c
@@ -71,6 +71,7 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
struct cf_haproxy_ctx *ctx = cf->ctx;
CURLcode result;
const char *tcp_version;
+ const char *client_ip;
DEBUGASSERT(ctx);
DEBUGASSERT(ctx->state == HAPROXY_INIT);
@@ -82,11 +83,15 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
#endif /* USE_UNIX_SOCKETS */
/* Emit the correct prefix for IPv6 */
tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4";
+ if(data->set.str[STRING_HAPROXY_CLIENT_IP])
+ client_ip = data->set.str[STRING_HAPROXY_CLIENT_IP];
+ else
+ client_ip = data->info.conn_primary_ip;
result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
tcp_version,
data->info.conn_local_ip,
- data->info.conn_primary_ip,
+ client_ip,
data->info.conn_local_port,
data->info.conn_primary_port);
@@ -110,7 +115,7 @@ static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf,
return CURLE_OK;
}
- result = cf->next->cft->connect(cf->next, data, blocking, done);
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
if(result || !*done)
return result;
@@ -163,7 +168,7 @@ static void cf_haproxy_close(struct Curl_cfilter *cf,
cf->connected = FALSE;
cf_haproxy_ctx_reset(cf->ctx);
if(cf->next)
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
}
static int cf_haproxy_get_select_socks(struct Curl_cfilter *cf,
diff --git a/Utilities/cmcurl/lib/cf-https-connect.c b/Utilities/cmcurl/lib/cf-https-connect.c
index d03cd1e..4e4d4b1 100644
--- a/Utilities/cmcurl/lib/cf-https-connect.c
+++ b/Utilities/cmcurl/lib/cf-https-connect.c
@@ -376,9 +376,9 @@ static bool cf_hc_data_pending(struct Curl_cfilter *cf,
|| cf_hc_baller_data_pending(&ctx->h21_baller, data);
}
-static struct curltime get_max_baller_time(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- int query)
+static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query)
{
struct cf_hc_ctx *ctx = cf->ctx;
struct Curl_cfilter *cfb;
@@ -408,12 +408,12 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
switch(query) {
case CF_QUERY_TIMER_CONNECT: {
struct curltime *when = pres2;
- *when = get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
+ *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
return CURLE_OK;
}
case CF_QUERY_TIMER_APPCONNECT: {
struct curltime *when = pres2;
- *when = get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
+ *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
return CURLE_OK;
}
default:
@@ -432,7 +432,7 @@ static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data)
cf->connected = FALSE;
if(cf->next) {
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
Curl_conn_cf_discard_chain(&cf->next, data);
}
}
diff --git a/Utilities/cmcurl/lib/cf-socket.c b/Utilities/cmcurl/lib/cf-socket.c
index 960979b..5729fe0 100644
--- a/Utilities/cmcurl/lib/cf-socket.c
+++ b/Utilities/cmcurl/lib/cf-socket.c
@@ -871,7 +871,7 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
/* this is our local socket, we did never publish it */
DEBUGF(LOG_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
", not active)", ctx->sock));
- sclose(ctx->sock);
+ socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
ctx->sock = CURL_SOCKET_BAD;
}
Curl_bufq_reset(&ctx->recvbuf);
@@ -901,22 +901,26 @@ static CURLcode set_local_ip(struct Curl_cfilter *cf,
struct cf_socket_ctx *ctx = cf->ctx;
#ifdef HAVE_GETSOCKNAME
- char buffer[STRERROR_LEN];
- struct Curl_sockaddr_storage ssloc;
- curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
+ if(!(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+ /* TFTP does not connect, so it cannot get the IP like this */
- memset(&ssloc, 0, sizeof(ssloc));
- if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
- int error = SOCKERRNO;
- failf(data, "getsockname() failed with errno %d: %s",
- error, Curl_strerror(error, buffer, sizeof(buffer)));
- return CURLE_FAILED_INIT;
- }
- if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
- ctx->l_ip, &ctx->l_port)) {
- failf(data, "ssloc inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- return CURLE_FAILED_INIT;
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssloc;
+ curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
+
+ memset(&ssloc, 0, sizeof(ssloc));
+ if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
+ int error = SOCKERRNO;
+ failf(data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+ ctx->l_ip, &ctx->l_port)) {
+ failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
}
#else
(void)data;
@@ -1356,26 +1360,31 @@ out:
static void conn_set_primary_ip(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
- struct cf_socket_ctx *ctx = cf->ctx;
#ifdef HAVE_GETPEERNAME
- char buffer[STRERROR_LEN];
- struct Curl_sockaddr_storage ssrem;
- curl_socklen_t plen;
- int port;
+ struct cf_socket_ctx *ctx = cf->ctx;
+ if(!(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+ /* TFTP does not connect the endpoint: getpeername() failed with errno
+ 107: Transport endpoint is not connected */
- plen = sizeof(ssrem);
- memset(&ssrem, 0, plen);
- if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
- int error = SOCKERRNO;
- failf(data, "getpeername() failed with errno %d: %s",
- error, Curl_strerror(error, buffer, sizeof(buffer)));
- return;
- }
- if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
- cf->conn->primary_ip, &port)) {
- failf(data, "ssrem inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- return;
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssrem;
+ curl_socklen_t plen;
+ int port;
+
+ plen = sizeof(ssrem);
+ memset(&ssrem, 0, plen);
+ if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
+ int error = SOCKERRNO;
+ failf(data, "getpeername() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+ cf->conn->primary_ip, &port)) {
+ failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return;
+ }
}
#else
cf->conn->primary_ip[0] = 0;
diff --git a/Utilities/cmcurl/lib/cfilters.c b/Utilities/cmcurl/lib/cfilters.c
index 291c823..216d0b4 100644
--- a/Utilities/cmcurl/lib/cfilters.c
+++ b/Utilities/cmcurl/lib/cfilters.c
@@ -50,7 +50,7 @@ void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
cf->connected = FALSE;
if(cf->next)
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
}
#endif
@@ -161,7 +161,7 @@ void Curl_conn_close(struct Curl_easy *data, int index)
/* it is valid to call that without filters being present */
cf = data->conn->cfilter[index];
if(cf) {
- cf->cft->close(cf, data);
+ cf->cft->do_close(cf, data);
}
}
@@ -179,7 +179,7 @@ ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
if(cf) {
return cf->cft->do_recv(cf, data, buf, len, code);
}
- failf(data, CMSGI(data->conn, num, "recv: no filter connected"));
+ failf(data, "recv: no filter connected");
*code = CURLE_FAILED_INIT;
return -1;
}
@@ -198,7 +198,7 @@ ssize_t Curl_conn_send(struct Curl_easy *data, int num,
if(cf) {
return cf->cft->do_send(cf, data, mem, len, code);
}
- failf(data, CMSGI(data->conn, num, "send: no filter connected"));
+ failf(data, "send: no filter connected");
DEBUGASSERT(0);
*code = CURLE_FAILED_INIT;
return -1;
@@ -293,14 +293,14 @@ CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
bool blocking, bool *done)
{
if(cf)
- return cf->cft->connect(cf, data, blocking, done);
+ return cf->cft->do_connect(cf, data, blocking, done);
return CURLE_FAILED_INIT;
}
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
if(cf)
- cf->cft->close(cf, data);
+ cf->cft->do_close(cf, data);
}
int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
@@ -348,7 +348,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
*done = cf->connected;
if(!*done) {
- result = cf->cft->connect(cf, data, blocking, done);
+ result = cf->cft->do_connect(cf, data, blocking, done);
if(!result && *done) {
Curl_conn_ev_update_info(data, data->conn);
conn_report_connect_stats(data, data->conn);
diff --git a/Utilities/cmcurl/lib/cfilters.h b/Utilities/cmcurl/lib/cfilters.h
index 70dcbe7..2c65264 100644
--- a/Utilities/cmcurl/lib/cfilters.h
+++ b/Utilities/cmcurl/lib/cfilters.h
@@ -168,8 +168,8 @@ struct Curl_cftype {
int flags; /* flags of filter type */
int log_level; /* log level for such filters */
Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
- Curl_cft_connect *connect; /* establish connection */
- Curl_cft_close *close; /* close conn */
+ Curl_cft_connect *do_connect; /* establish connection */
+ Curl_cft_close *do_close; /* close conn */
Curl_cft_get_host *get_host; /* host filter talks to */
Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */
Curl_cft_data_pending *has_data_pending;/* conn has data pending */
diff --git a/Utilities/cmcurl/lib/conncache.h b/Utilities/cmcurl/lib/conncache.h
index 959767d..c60f844 100644
--- a/Utilities/cmcurl/lib/conncache.h
+++ b/Utilities/cmcurl/lib/conncache.h
@@ -39,7 +39,8 @@ struct connectdata;
struct conncache {
struct Curl_hash hash;
size_t num_conn;
- long next_connection_id;
+ curl_off_t next_connection_id;
+ curl_off_t next_easy_id;
struct curltime last_cleanup;
/* handle used for closing cached connections */
struct Curl_easy *closure_handle;
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
index ed55121..dc93533 100644
--- a/Utilities/cmcurl/lib/connect.c
+++ b/Utilities/cmcurl/lib/connect.c
@@ -253,7 +253,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
}
struct connfind {
- long id_tofind;
+ curl_off_t id_tofind;
struct connectdata *found;
};
@@ -937,7 +937,7 @@ static void cf_he_close(struct Curl_cfilter *cf,
ctx->state = SCFST_INIT;
if(cf->next) {
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
Curl_conn_cf_discard_chain(&cf->next, data);
}
}
@@ -1291,7 +1291,7 @@ static void cf_setup_close(struct Curl_cfilter *cf,
ctx->state = CF_SETUP_INIT;
if(cf->next) {
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
Curl_conn_cf_discard_chain(&cf->next, data);
}
}
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 0303efb..4345a84 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -123,8 +123,9 @@ static void freecookie(struct Cookie *co)
free(co);
}
-static bool tailmatch(const char *cookie_domain, size_t cookie_domain_len,
- const char *hostname)
+static bool cookie_tailmatch(const char *cookie_domain,
+ size_t cookie_domain_len,
+ const char *hostname)
{
size_t hostname_len = strlen(hostname);
@@ -696,7 +697,7 @@ Curl_cookie_add(struct Curl_easy *data,
if(!domain
|| (is_ip && !strncmp(valuep, domain, vlen) &&
(vlen == strlen(domain)))
- || (!is_ip && tailmatch(valuep, vlen, domain))) {
+ || (!is_ip && cookie_tailmatch(valuep, vlen, domain))) {
strstore(&co->domain, valuep, vlen);
if(!co->domain) {
badcookie = TRUE;
@@ -1431,7 +1432,7 @@ struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
/* now check if the domain is correct */
if(!co->domain ||
(co->tailmatch && !is_ip &&
- tailmatch(co->domain, strlen(co->domain), host)) ||
+ cookie_tailmatch(co->domain, strlen(co->domain), host)) ||
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
/*
* the right part of the host matches the domain stuff in the
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
index 6e2458d..4ab8242 100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -443,6 +443,9 @@
/* Define to 1 if you have the sigsetjmp function or macro. */
#cmakedefine HAVE_SIGSETJMP 1
+/* Define to 1 if you have the `snprintf' function. */
+#cmakedefine HAVE_SNPRINTF
+
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
@@ -572,9 +575,6 @@
/* Define to 1 if you have the windows.h header file. */
#cmakedefine HAVE_WINDOWS_H 1
-/* Define to 1 if you have the winldap.h header file. */
-#cmakedefine HAVE_WINLDAP_H 1
-
/* Define to 1 if you have the winsock2.h header file. */
#cmakedefine HAVE_WINSOCK2_H 1
diff --git a/Utilities/cmcurl/lib/curl_log.c b/Utilities/cmcurl/lib/curl_log.c
index 71024cf..782c35a 100644
--- a/Utilities/cmcurl/lib/curl_log.c
+++ b/Utilities/cmcurl/lib/curl_log.c
@@ -130,13 +130,11 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...)
{
DEBUGASSERT(cf);
- if(data && Curl_log_cf_is_debug(cf)) {
+ if(data && Curl_log_cf_is_debug(cf, data)) {
va_list ap;
int len;
char buffer[MAXINFO + 2];
- len = msnprintf(buffer, MAXINFO, "[CONN-%ld%s-%s] ",
- cf->conn->connection_id, cf->sockindex? "/2" : "",
- cf->cft->name);
+ len = msnprintf(buffer, MAXINFO, "[%s] ", cf->cft->name);
va_start(ap, fmt);
len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
va_end(ap);
diff --git a/Utilities/cmcurl/lib/curl_log.h b/Utilities/cmcurl/lib/curl_log.h
index ad6143f..ebfa5a0 100644
--- a/Utilities/cmcurl/lib/curl_log.h
+++ b/Utilities/cmcurl/lib/curl_log.h
@@ -74,7 +74,7 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type,
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define LOG_CF(data, cf, ...) \
- do { if(Curl_log_cf_is_debug(cf)) \
+ do { if(Curl_log_cf_is_debug(cf, data)) \
Curl_log_cf_debug(data, cf, __VA_ARGS__); } while(0)
#else
#define LOG_CF Curl_log_cf_debug
@@ -90,8 +90,10 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...);
#endif
-#define Curl_log_cf_is_debug(cf) \
- ((cf) && (cf)->cft->log_level >= CURL_LOG_DEBUG)
+#define Curl_log_cf_is_debug(cf, data) \
+ ((data) && (data)->set.verbose && \
+ (cf) && (cf)->cft->log_level >= CURL_LOG_DEBUG)
+
#else /* !DEBUGBUILD */
@@ -110,29 +112,10 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...);
#endif
-#define Curl_log_cf_is_debug(x) ((void)(x), FALSE)
+#define Curl_log_cf_is_debug(x,y) ((void)(x), (void)(y), FALSE)
#endif /* !DEBUGBUILD */
-#define LOG_CF_IS_DEBUG(x) Curl_log_cf_is_debug(x)
-
-/* Macros intended for DEBUGF logging, use like:
- * DEBUGF(infof(data, CFMSG(cf, "this filter %s rocks"), "very much"));
- * and it will output:
- * [CONN-1-0][CF-SSL] this filter very much rocks
- * on connection #1 with sockindex 0 for filter of type "SSL". */
-#define DMSG(d,msg) \
- "[CONN-%ld] "msg, (d)->conn->connection_id
-#define DMSGI(d,i,msg) \
- "[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i)
-#define CMSG(c,msg) \
- "[CONN-%ld] "msg, (c)->connection_id
-#define CMSGI(c,i,msg) \
- "[CONN-%ld-%d] "msg, (c)->connection_id, (i)
-#define CFMSG(cf,msg) \
- "[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \
- (cf)->sockindex, (cf)->cft->name
-
-
+#define LOG_CF_IS_DEBUG(cf, data) Curl_log_cf_is_debug(cf, data)
#endif /* HEADER_CURL_LOG_H */
diff --git a/Utilities/cmcurl/lib/curl_memory.h b/Utilities/cmcurl/lib/curl_memory.h
index 1a21c5a..b8c46d7 100644
--- a/Utilities/cmcurl/lib/curl_memory.h
+++ b/Utilities/cmcurl/lib/curl_memory.h
@@ -55,9 +55,65 @@
*/
#ifdef HEADER_CURL_MEMDEBUG_H
-#error "Header memdebug.h shall not be included before curl_memory.h"
+/* cleanup after memdebug.h */
+
+#ifdef MEMDEBUG_NODEFINES
+#ifdef CURLDEBUG
+
+#undef strdup
+#undef malloc
+#undef calloc
+#undef realloc
+#undef free
+#undef send
+#undef recv
+
+#ifdef WIN32
+# ifdef UNICODE
+# undef wcsdup
+# undef _wcsdup
+# undef _tcsdup
+# else
+# undef _tcsdup
+# endif
+#endif
+
+#undef socket
+#undef accept
+#ifdef HAVE_SOCKETPAIR
+#undef socketpair
#endif
+#ifdef HAVE_GETADDRINFO
+#if defined(getaddrinfo) && defined(__osf__)
+#undef ogetaddrinfo
+#else
+#undef getaddrinfo
+#endif
+#endif /* HAVE_GETADDRINFO */
+
+#ifdef HAVE_FREEADDRINFO
+#undef freeaddrinfo
+#endif /* HAVE_FREEADDRINFO */
+
+/* sclose is probably already defined, redefine it! */
+#undef sclose
+#undef fopen
+#undef fdopen
+#undef fclose
+
+#endif /* MEMDEBUG_NODEFINES */
+#endif /* CURLDEBUG */
+
+#undef HEADER_CURL_MEMDEBUG_H
+#endif /* HEADER_CURL_MEMDEBUG_H */
+
+/*
+** Following section applies even when CURLDEBUG is not defined.
+*/
+
+#undef fake_sclose
+
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
/*
* The following memory function replacement typedef's are COPIED from
diff --git a/Utilities/cmcurl/lib/curl_printf.h b/Utilities/cmcurl/lib/curl_printf.h
index 6d3d492..46ef344 100644
--- a/Utilities/cmcurl/lib/curl_printf.h
+++ b/Utilities/cmcurl/lib/curl_printf.h
@@ -37,6 +37,7 @@
# undef vprintf
# undef vfprintf
# undef vsnprintf
+# undef mvsnprintf
# undef aprintf
# undef vaprintf
# define printf curl_mprintf
diff --git a/Utilities/cmcurl/lib/curl_sasl.c b/Utilities/cmcurl/lib/curl_sasl.c
index 119fb9b..1cb0e54 100644
--- a/Utilities/cmcurl/lib/curl_sasl.c
+++ b/Utilities/cmcurl/lib/curl_sasl.c
@@ -221,12 +221,12 @@ void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
}
/*
- * state()
+ * sasl_state()
*
* This is the ONLY way to change SASL state!
*/
-static void state(struct SASL *sasl, struct Curl_easy *data,
- saslstate newstate)
+static void sasl_state(struct SASL *sasl, struct Curl_easy *data,
+ saslstate newstate)
{
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* for debug purposes */
@@ -508,7 +508,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
if(!result) {
*progress = SASL_INPROGRESS;
- state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
+ sasl_state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
}
}
@@ -548,14 +548,14 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
if(code != sasl->params->finalcode)
result = CURLE_LOGIN_DENIED;
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return result;
}
if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
code != sasl->params->contcode) {
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return CURLE_LOGIN_DENIED;
}
@@ -698,7 +698,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
if(code == sasl->params->finalcode) {
/* Final response was received so we are done */
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return result;
}
else if(code == sasl->params->contcode) {
@@ -708,7 +708,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
}
else {
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return CURLE_LOGIN_DENIED;
}
@@ -745,7 +745,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
Curl_bufref_free(&resp);
- state(sasl, data, newstate);
+ sasl_state(sasl, data, newstate);
return result;
}
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
index 9043d97..e395be5 100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -262,7 +262,7 @@
#if defined(__APPLE__) && !defined(USE_ARES)
#include <TargetConditionals.h>
#define USE_RESOLVE_ON_IPS 1
-# if defined(TARGET_OS_OSX) && TARGET_OS_OSX
+# if !defined(TARGET_OS_OSX) || TARGET_OS_OSX
# define CURL_OSX_CALL_COPYPROXIES 1
# endif
#endif
@@ -302,6 +302,7 @@
# if defined(HAVE_PROTO_BSDSOCKET_H) && \
(!defined(__amigaos4__) || defined(USE_AMISSL))
/* use bsdsocket.library directly, instead of libc networking functions */
+# define _SYS_MBUF_H /* m_len define clashes with curl */
# include <proto/bsdsocket.h>
# ifdef __amigaos4__
int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
diff --git a/Utilities/cmcurl/lib/curl_setup_once.h b/Utilities/cmcurl/lib/curl_setup_once.h
index dde7229..c1ed059 100644
--- a/Utilities/cmcurl/lib/curl_setup_once.h
+++ b/Utilities/cmcurl/lib/curl_setup_once.h
@@ -77,6 +77,12 @@
# endif
#endif
+#ifdef USE_SCHANNEL
+/* Must set this before <schannel.h> is included directly or indirectly by
+ another Windows header. */
+# define SCHANNEL_USE_BLACKLISTS 1
+#endif
+
#ifdef __hpux
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
# ifdef _APP32_64BIT_OFF_T
diff --git a/Utilities/cmcurl/lib/dynbuf.h b/Utilities/cmcurl/lib/dynbuf.h
index 57ad62b..6291eab 100644
--- a/Utilities/cmcurl/lib/dynbuf.h
+++ b/Utilities/cmcurl/lib/dynbuf.h
@@ -81,8 +81,6 @@ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
#define DYN_PAUSE_BUFFER (64 * 1024 * 1024)
#define DYN_HAXPROXY 2048
#define DYN_HTTP_REQUEST (1024*1024)
-#define DYN_H2_HEADERS (128*1024)
-#define DYN_H2_TRAILERS (128*1024)
#define DYN_APRINTF 8000000
#define DYN_RTSP_REQ_HEADER (64*1024)
#define DYN_TRAILERS (64*1024)
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
index d36cc03..d034629 100644
--- a/Utilities/cmcurl/lib/easy.c
+++ b/Utilities/cmcurl/lib/easy.c
@@ -63,6 +63,7 @@
#include "slist.h"
#include "mime.h"
#include "amigaos.h"
+#include "macos.h"
#include "warnless.h"
#include "sigpipe.h"
#include "vssh/ssh.h"
@@ -83,7 +84,7 @@
/* true globals -- for curl_global_init() and curl_global_cleanup() */
static unsigned int initialized;
-static long init_flags;
+static long easy_init_flags;
#ifdef GLOBAL_INIT_IS_THREADSAFE
@@ -181,6 +182,11 @@ static CURLcode global_init(long flags, bool memoryfuncs)
}
#endif
+ if(Curl_macos_init()) {
+ DEBUGF(fprintf(stderr, "Error: Curl_macos_init failed\n"));
+ goto fail;
+ }
+
if(Curl_resolver_global_init()) {
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
goto fail;
@@ -199,7 +205,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
}
#endif
- init_flags = flags;
+ easy_init_flags = flags;
#ifdef DEBUGBUILD
if(getenv("CURL_GLOBAL_INIT"))
@@ -274,7 +280,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
/**
* curl_global_cleanup() globally cleanups curl, uses the value of
- * "init_flags" to determine what needs to be cleaned up and what doesn't.
+ * "easy_init_flags" to determine what needs to be cleaned up and what doesn't.
*/
void curl_global_cleanup(void)
{
@@ -294,7 +300,7 @@ void curl_global_cleanup(void)
Curl_resolver_global_cleanup();
#ifdef WIN32
- Curl_win32_cleanup(init_flags);
+ Curl_win32_cleanup(easy_init_flags);
#endif
Curl_amiga_cleanup();
@@ -308,7 +314,7 @@ void curl_global_cleanup(void)
free(leakpointer);
#endif
- init_flags = 0;
+ easy_init_flags = 0;
global_init_unlock();
}
@@ -893,6 +899,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
/* the connection cache is setup on demand */
outcurl->state.conn_cache = NULL;
outcurl->state.lastconnect_id = -1;
+ outcurl->state.recent_conn_id = -1;
+ outcurl->id = -1;
outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
diff --git a/Utilities/cmcurl/lib/easy_lock.h b/Utilities/cmcurl/lib/easy_lock.h
index 5fa9477..6399a39 100644
--- a/Utilities/cmcurl/lib/easy_lock.h
+++ b/Utilities/cmcurl/lib/easy_lock.h
@@ -1,3 +1,5 @@
+#ifndef HEADER_CURL_EASY_LOCK_H
+#define HEADER_CURL_EASY_LOCK_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -103,3 +105,5 @@ static inline void curl_simple_lock_unlock(curl_simple_lock *lock)
#undef GLOBAL_INIT_IS_THREADSAFE
#endif
+
+#endif /* HEADER_CURL_EASY_LOCK_H */
diff --git a/Utilities/cmcurl/lib/easyoptions.c b/Utilities/cmcurl/lib/easyoptions.c
index a9c1efd..e69c658 100644
--- a/Utilities/cmcurl/lib/easyoptions.c
+++ b/Utilities/cmcurl/lib/easyoptions.c
@@ -120,6 +120,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS,
CURLOT_LONG, 0},
{"HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0},
+ {"HAPROXY_CLIENT_IP", CURLOPT_HAPROXY_CLIENT_IP, CURLOT_STRING, 0},
{"HEADER", CURLOPT_HEADER, CURLOT_LONG, 0},
{"HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0},
{"HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0},
@@ -164,7 +165,9 @@ struct curl_easyoption Curl_easyopts[] = {
{"MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0},
{"MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0},
{"MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0},
- {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOT_LONG, 0},
+ {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS,
+ CURLOT_LONG, CURLOT_FLAG_ALIAS},
+ {"MAIL_RCPT_ALLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOT_LONG, 0},
{"MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0},
{"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0},
{"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0},
@@ -370,6 +373,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (322 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (323 + 1));
}
#endif
diff --git a/Utilities/cmcurl/lib/fopen.c b/Utilities/cmcurl/lib/fopen.c
index f710dbf..b6e3cad 100644
--- a/Utilities/cmcurl/lib/fopen.c
+++ b/Utilities/cmcurl/lib/fopen.c
@@ -56,13 +56,13 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
int fd = -1;
*tempname = NULL;
- if(stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode)) {
- /* a non-regular file, fallback to direct fopen() */
- *fh = fopen(filename, FOPEN_WRITETEXT);
- if(*fh)
- return CURLE_OK;
+ *fh = fopen(filename, FOPEN_WRITETEXT);
+ if(!*fh)
goto fail;
- }
+ if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode))
+ return CURLE_OK;
+ fclose(*fh);
+ *fh = NULL;
result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix));
if(result)
@@ -85,7 +85,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
if((fstat(fd, &nsb) != -1) &&
(nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) {
/* if the user and group are the same, clone the original mode */
- if(fchmod(fd, sb.st_mode) == -1)
+ if(fchmod(fd, (mode_t)sb.st_mode) == -1)
goto fail;
}
}
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index 4f50cb4..a1cfa65 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -93,14 +93,14 @@
/* Local API functions */
#ifndef DEBUGBUILD
-static void _state(struct Curl_easy *data,
- ftpstate newstate);
-#define state(x,y) _state(x,y)
+static void _ftp_state(struct Curl_easy *data,
+ ftpstate newstate);
+#define ftp_state(x,y) _ftp_state(x,y)
#else
-static void _state(struct Curl_easy *data,
- ftpstate newstate,
- int lineno);
-#define state(x,y) _state(x,y,__LINE__)
+static void _ftp_state(struct Curl_easy *data,
+ ftpstate newstate,
+ int lineno);
+#define ftp_state(x,y) _ftp_state(x,y,__LINE__)
#endif
static CURLcode ftp_sendquote(struct Curl_easy *data,
@@ -463,7 +463,7 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
@@ -591,7 +591,7 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
* generically is a good idea.
*/
infof(data, "We got a 421 - timeout");
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OPERATION_TIMEDOUT;
}
@@ -750,10 +750,10 @@ static const char * const ftp_state_names[]={
#endif
/* This is the ONLY way to change FTP state! */
-static void _state(struct Curl_easy *data,
- ftpstate newstate
+static void _ftp_state(struct Curl_easy *data,
+ ftpstate newstate
#ifdef DEBUGBUILD
- , int lineno
+ , int lineno
#endif
)
{
@@ -784,7 +784,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
if(!result) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
ftpc->ftp_trying_alternative = FALSE;
- state(data, FTP_USER);
+ ftp_state(data, FTP_USER);
}
return result;
}
@@ -794,7 +794,7 @@ static CURLcode ftp_state_pwd(struct Curl_easy *data,
{
CURLcode result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PWD");
if(!result)
- state(data, FTP_PWD);
+ ftp_state(data, FTP_PWD);
return result;
}
@@ -872,7 +872,7 @@ static CURLcode ftp_state_cwd(struct Curl_easy *data,
for all upcoming ones in the ftp->dirs[] array */
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath);
if(!result)
- state(data, FTP_CWD);
+ ftp_state(data, FTP_CWD);
}
else {
if(ftpc->dirdepth) {
@@ -882,7 +882,7 @@ static CURLcode ftp_state_cwd(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount -1]);
if(!result)
- state(data, FTP_CWD);
+ ftp_state(data, FTP_CWD);
}
else {
/* No CWD necessary */
@@ -1261,11 +1261,11 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
if(result)
goto out;
portsock = CURL_SOCKET_BAD; /* now held in filter */
- state(data, FTP_PORT);
+ ftp_state(data, FTP_PORT);
out:
if(result) {
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
}
if(portsock != CURL_SOCKET_BAD)
Curl_socket_close(data, conn, portsock);
@@ -1307,7 +1307,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
if(!result) {
ftpc->count1 = modeoff;
- state(data, FTP_PASV);
+ ftp_state(data, FTP_PASV);
infof(data, "Connect data stream passively");
}
return result;
@@ -1330,7 +1330,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
/* doesn't transfer any data */
/* still possibly do PRE QUOTE jobs */
- state(data, FTP_RETR_PREQUOTE);
+ ftp_state(data, FTP_RETR_PREQUOTE);
result = ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE);
}
else if(data->set.ftp_use_port) {
@@ -1355,7 +1355,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s",
conn->proto.ftpc.file);
if(!result)
- state(data, FTP_PRET);
+ ftp_state(data, FTP_PRET);
}
else
result = ftp_state_use_pasv(data, conn);
@@ -1377,7 +1377,7 @@ static CURLcode ftp_state_rest(struct Curl_easy *data,
whether it supports range */
result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0);
if(!result)
- state(data, FTP_REST);
+ ftp_state(data, FTP_REST);
}
else
result = ftp_state_prepare_transfer(data);
@@ -1398,7 +1398,7 @@ static CURLcode ftp_state_size(struct Curl_easy *data,
/* we know ftpc->file is a valid pointer to a file name */
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(data, FTP_SIZE);
+ ftp_state(data, FTP_SIZE);
}
else
result = ftp_state_rest(data, conn);
@@ -1466,7 +1466,7 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
free(cmd);
if(!result)
- state(data, FTP_LIST);
+ ftp_state(data, FTP_LIST);
return result;
}
@@ -1530,7 +1530,7 @@ static CURLcode ftp_state_mdtm(struct Curl_easy *data)
result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file);
if(!result)
- state(data, FTP_MDTM);
+ ftp_state(data, FTP_MDTM);
}
else
result = ftp_state_type(data);
@@ -1569,7 +1569,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
/* Got no given size to start from, figure it out */
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(data, FTP_STOR_SIZE);
+ ftp_state(data, FTP_STOR_SIZE);
return result;
}
@@ -1624,7 +1624,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
* ftp_done() because we didn't transfer anything! */
ftp->transfer = PPTRANSFER_NONE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
}
@@ -1634,7 +1634,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s",
ftpc->file);
if(!result)
- state(data, FTP_STOR);
+ ftp_state(data, FTP_STOR);
return result;
}
@@ -1695,7 +1695,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
if(result)
return result;
- state(data, instate);
+ ftp_state(data, instate);
quote = TRUE;
}
}
@@ -1709,7 +1709,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
break;
case FTP_RETR_PREQUOTE:
if(ftp->transfer != PPTRANSFER_BODY)
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
else {
if(ftpc->known_filesize != -1) {
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
@@ -1731,12 +1731,12 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
*/
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(data, FTP_RETR);
+ ftp_state(data, FTP_RETR);
}
else {
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(data, FTP_RETR_SIZE);
+ ftp_state(data, FTP_RETR_SIZE);
}
}
}
@@ -1780,7 +1780,7 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
if(!result) {
conn->proto.ftpc.count1++;
/* remain in/go to the FTP_PASV state */
- state(data, FTP_PASV);
+ ftp_state(data, FTP_PASV);
}
return result;
}
@@ -2005,7 +2005,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
conn->bits.do_more = TRUE;
- state(data, FTP_STOP); /* this phase is completed */
+ ftp_state(data, FTP_STOP); /* this phase is completed */
return result;
}
@@ -2039,7 +2039,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
}
else {
infof(data, "Connect data stream actively");
- state(data, FTP_STOP); /* end of DO phase */
+ ftp_state(data, FTP_STOP); /* end of DO phase */
result = ftp_dophase_done(data, FALSE);
}
@@ -2151,7 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
infof(data, "The requested document is not new enough");
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
data->info.timecond = TRUE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
break;
@@ -2160,7 +2160,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
infof(data, "The requested document is not old enough");
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
data->info.timecond = TRUE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
break;
@@ -2268,7 +2268,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
/* Set ->transfer so that we won't get any error in ftp_done()
* because we didn't transfer the any file */
ftp->transfer = PPTRANSFER_NONE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
@@ -2279,13 +2279,13 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
data->state.resume_from);
if(!result)
- state(data, FTP_RETR_REST);
+ ftp_state(data, FTP_RETR_REST);
}
else {
/* no resume */
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(data, FTP_RETR);
+ ftp_state(data, FTP_RETR);
}
return result;
@@ -2385,7 +2385,7 @@ static CURLcode ftp_state_rest_resp(struct Curl_easy *data,
else {
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(data, FTP_RETR);
+ ftp_state(data, FTP_RETR);
}
break;
}
@@ -2401,7 +2401,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
if(ftpcode >= 400) {
failf(data, "Failed FTP upload: %0d", ftpcode);
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
/* oops, we never close the sockets! */
return CURLE_UPLOAD_FAILED;
}
@@ -2412,7 +2412,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
if(data->set.ftp_use_port) {
bool connected;
- state(data, FTP_STOP); /* no longer in STOR state */
+ ftp_state(data, FTP_STOP); /* no longer in STOR state */
result = AllowServerConnect(data, &connected);
if(result)
@@ -2535,7 +2535,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately");
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
ftpc->wait_data_conn = TRUE;
}
}
@@ -2546,7 +2546,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
if((instate == FTP_LIST) && (ftpcode == 450)) {
/* simply no matching files in the dir listing */
ftp->transfer = PPTRANSFER_NONE; /* don't download anything */
- state(data, FTP_STOP); /* this phase is over */
+ ftp_state(data, FTP_STOP); /* this phase is over */
}
else {
failf(data, "RETR response: %03d", ftpcode);
@@ -2582,7 +2582,7 @@ static CURLcode ftp_state_loggedin(struct Curl_easy *data)
*/
result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "PBSZ %d", 0);
if(!result)
- state(data, FTP_PBSZ);
+ ftp_state(data, FTP_PBSZ);
}
else {
result = ftp_state_pwd(data, conn);
@@ -2605,7 +2605,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
conn->passwd?conn->passwd:"");
if(!result)
- state(data, FTP_PASS);
+ ftp_state(data, FTP_PASS);
}
else if(ftpcode/100 == 2) {
/* 230 User ... logged in.
@@ -2617,7 +2617,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s",
data->set.str[STRING_FTP_ACCOUNT]);
if(!result)
- state(data, FTP_ACCT);
+ ftp_state(data, FTP_ACCT);
}
else {
failf(data, "ACCT requested but none available");
@@ -2638,7 +2638,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
if(!result) {
ftpc->ftp_trying_alternative = TRUE;
- state(data, FTP_USER);
+ ftp_state(data, FTP_USER);
}
}
else {
@@ -2741,7 +2741,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s",
ftpauth[ftpc->count1]);
if(!result)
- state(data, FTP_AUTH);
+ ftp_state(data, FTP_AUTH);
}
else
result = ftp_state_user(data, conn);
@@ -2808,7 +2808,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
Curl_pp_sendf(data, &ftpc->pp, "PROT %c",
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
if(!result)
- state(data, FTP_PROT);
+ ftp_state(data, FTP_PROT);
break;
case FTP_PROT:
@@ -2827,7 +2827,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
*/
result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC");
if(!result)
- state(data, FTP_CCC);
+ ftp_state(data, FTP_CCC);
}
else
result = ftp_state_pwd(data, conn);
@@ -2919,7 +2919,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
infof(data, "Entry path is '%s'", ftpc->entrypath);
/* also save it where getinfo can access it: */
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
- state(data, FTP_SYST);
+ ftp_state(data, FTP_SYST);
break;
}
@@ -2935,7 +2935,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
infof(data, "Failed to figure out path");
}
}
- state(data, FTP_STOP); /* we are done with the CONNECT phase! */
+ ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE"));
break;
@@ -2970,7 +2970,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* remember target server OS */
Curl_safefree(ftpc->server_os);
ftpc->server_os = os;
- state(data, FTP_NAMEFMT);
+ ftp_state(data, FTP_NAMEFMT);
break;
}
/* Nothing special for the target server. */
@@ -2982,7 +2982,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* Cannot identify server OS. Continue anyway and cross fingers. */
}
- state(data, FTP_STOP); /* we are done with the CONNECT phase! */
+ ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE"));
break;
@@ -2993,7 +2993,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
break;
}
- state(data, FTP_STOP); /* we are done with the CONNECT phase! */
+ ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE"));
break;
@@ -3026,7 +3026,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "MKD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
if(!result)
- state(data, FTP_MKD);
+ ftp_state(data, FTP_MKD);
}
else {
/* return failure */
@@ -3055,7 +3055,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
result = CURLE_REMOTE_ACCESS_DENIED;
}
else {
- state(data, FTP_CWD);
+ ftp_state(data, FTP_CWD);
/* send CWD */
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
@@ -3114,7 +3114,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* fallthrough, just stop! */
default:
/* internal error */
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
break;
}
} /* if(ftpcode) */
@@ -3191,7 +3191,7 @@ static CURLcode ftp_connect(struct Curl_easy *data,
/* When we connect, we start in the state where we await the 220
response */
- state(data, FTP_WAIT220);
+ ftp_state(data, FTP_WAIT220);
result = ftp_multi_statemach(data, done);
@@ -3516,13 +3516,13 @@ static CURLcode ftp_nb_type(struct Curl_easy *data,
char want = (char)(ascii?'A':'I');
if(ftpc->transfertype == want) {
- state(data, newstate);
+ ftp_state(data, newstate);
return ftp_state_type_resp(data, 200, newstate);
}
result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want);
if(!result) {
- state(data, newstate);
+ ftp_state(data, newstate);
/* keep track of our current transfer type */
ftpc->transfertype = want;
@@ -4040,11 +4040,11 @@ static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn)
curl_easy_strerror(result));
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
connclose(conn, "QUIT command failed"); /* mark for connection closure */
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return result;
}
- state(data, FTP_QUIT);
+ ftp_state(data, FTP_QUIT);
result = ftp_block_statemach(data, conn);
}
diff --git a/Utilities/cmcurl/lib/getinfo.c b/Utilities/cmcurl/lib/getinfo.c
index 826ffd0..f1574e0 100644
--- a/Utilities/cmcurl/lib/getinfo.c
+++ b/Utilities/cmcurl/lib/getinfo.c
@@ -415,6 +415,13 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
case CURLINFO_RETRY_AFTER:
*param_offt = data->info.retry_after;
break;
+ case CURLINFO_XFER_ID:
+ *param_offt = data->id;
+ break;
+ case CURLINFO_CONN_ID:
+ *param_offt = data->conn?
+ data->conn->connection_id : data->state.recent_conn_id;
+ break;
default:
return CURLE_UNKNOWN_OPTION;
}
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
index d721403..1a289de 100644
--- a/Utilities/cmcurl/lib/hostip.c
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -67,10 +67,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
-#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
-#endif
-
#if defined(CURLRES_SYNCH) && \
defined(HAVE_ALARM) && \
defined(SIGALRM) && \
@@ -561,6 +557,7 @@ static struct Curl_addrinfo *get_localhost6(int port, const char *name)
static struct Curl_addrinfo *get_localhost(int port, const char *name)
{
struct Curl_addrinfo *ca;
+ struct Curl_addrinfo *ca6;
const size_t ss_size = sizeof(struct sockaddr_in);
const size_t hostlen = strlen(name);
struct sockaddr_in sa;
@@ -587,8 +584,12 @@ static struct Curl_addrinfo *get_localhost(int port, const char *name)
memcpy(ca->ai_addr, &sa, ss_size);
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
strcpy(ca->ai_canonname, name);
- ca->ai_next = get_localhost6(port, name);
- return ca;
+
+ ca6 = get_localhost6(port, name);
+ if(!ca6)
+ return ca;
+ ca6->ai_next = ca;
+ return ca6;
}
#ifdef ENABLE_IPV6
@@ -743,23 +744,6 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
return CURLRESOLV_ERROR;
}
-#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
- {
- /*
- * The automagic conversion from IPv4 literals to IPv6 literals only
- * works if the SCDynamicStoreCopyProxies system function gets called
- * first. As Curl currently doesn't support system-wide HTTP proxies, we
- * therefore don't use any value this function might return.
- *
- * This function is only available on a macOS and is not needed for
- * IPv4-only builds, hence the conditions above.
- */
- CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
- if(dict)
- CFRelease(dict);
- }
-#endif
-
#ifndef USE_RESOLVE_ON_IPS
/* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
diff --git a/Utilities/cmcurl/lib/hsts.c b/Utilities/cmcurl/lib/hsts.c
index 53c01fc..7ecf004 100644
--- a/Utilities/cmcurl/lib/hsts.c
+++ b/Utilities/cmcurl/lib/hsts.c
@@ -57,7 +57,7 @@
/* to play well with debug builds, we can *set* a fixed time this will
return */
time_t deltatime; /* allow for "adjustments" for unit test purposes */
-static time_t debugtime(void *unused)
+static time_t hsts_debugtime(void *unused)
{
char *timestr = getenv("CURL_TIME");
(void)unused;
@@ -70,7 +70,8 @@ static time_t debugtime(void *unused)
}
return time(NULL);
}
-#define time(x) debugtime(x)
+#undef time
+#define time(x) hsts_debugtime(x)
#endif
struct hsts *Curl_hsts_init(void)
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index 219dcc2..e611d27 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -1308,7 +1308,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|| IS_HTTPS_PROXY(conn->http_proxy.proxytype)
#endif
)
- && conn->httpversion != 20) {
+ && conn->httpversion < 20) {
/* Make sure this doesn't send more body bytes than what the max send
speed says. The request bytes do not count to the max speed.
*/
@@ -2667,11 +2667,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
#ifndef USE_HYPER
/* With Hyper the body is always passed on separately */
if(data->set.postfields) {
-
- /* In HTTP2, we send request body in DATA frame regardless of
- its size. */
- if(conn->httpversion < 20 &&
- !data->state.expect100header &&
+ if(!data->state.expect100header &&
(http->postsize < MAX_INITIAL_POST_SIZE)) {
/* if we don't use expect: 100 AND
postsize is less than MAX_INITIAL_POST_SIZE
@@ -2832,16 +2828,18 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
}
if(co) {
struct Cookie *store = co;
+ size_t clen = 8; /* hold the size of the generated Cookie: header */
/* now loop through all cookies that matched */
while(co) {
if(co->value) {
- if(0 == count) {
+ size_t add;
+ if(!count) {
result = Curl_dyn_addn(r, STRCONST("Cookie: "));
if(result)
break;
}
- if((Curl_dyn_len(r) + strlen(co->name) + strlen(co->value) + 1) >=
- MAX_COOKIE_HEADER_LEN) {
+ add = strlen(co->name) + strlen(co->value) + 1;
+ if(clen + add >= MAX_COOKIE_HEADER_LEN) {
infof(data, "Restricted outgoing cookies due to header size, "
"'%s' not sent", co->name);
linecap = TRUE;
@@ -2851,6 +2849,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
co->name, co->value);
if(result)
break;
+ clen += add + (count ? 2 : 0);
count++;
}
co = co->next; /* next cookie please */
@@ -3381,6 +3380,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
}
}
+ if(data->req.upload_done)
+ Curl_conn_ev_data_done_send(data);
+
if((conn->httpversion >= 20) && data->req.upload_chunky)
/* upload_chunky was set above to set up the request in a chunky fashion,
but is disabled here again to avoid that the chunked encoded version is
@@ -4569,8 +4571,8 @@ CURLcode Curl_http_req_make(struct httpreq **preq,
if(!req->path)
goto out;
}
- Curl_dynhds_init(&req->headers, 0, DYN_H2_HEADERS);
- Curl_dynhds_init(&req->trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST);
+ Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST);
result = CURLE_OK;
out:
@@ -4727,8 +4729,8 @@ CURLcode Curl_http_req_make2(struct httpreq **preq,
if(result)
goto out;
- Curl_dynhds_init(&req->headers, 0, DYN_H2_HEADERS);
- Curl_dynhds_init(&req->trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST);
+ Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST);
result = CURLE_OK;
out:
@@ -4858,8 +4860,8 @@ CURLcode Curl_http_resp_make(struct http_resp **presp,
if(!resp->description)
goto out;
}
- Curl_dynhds_init(&resp->headers, 0, DYN_H2_HEADERS);
- Curl_dynhds_init(&resp->trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&resp->headers, 0, DYN_HTTP_REQUEST);
+ Curl_dynhds_init(&resp->trailers, 0, DYN_HTTP_REQUEST);
result = CURLE_OK;
out:
diff --git a/Utilities/cmcurl/lib/http1.c b/Utilities/cmcurl/lib/http1.c
index 46fe855..a442d3e 100644
--- a/Utilities/cmcurl/lib/http1.c
+++ b/Utilities/cmcurl/lib/http1.c
@@ -38,124 +38,97 @@
#include "memdebug.h"
-#define MAX_URL_LEN (4*1024)
+#define H1_MAX_URL_LEN (8*1024)
void Curl_h1_req_parse_init(struct h1_req_parser *parser, size_t max_line_len)
{
memset(parser, 0, sizeof(*parser));
parser->max_line_len = max_line_len;
- Curl_bufq_init(&parser->scratch, max_line_len, 1);
+ Curl_dyn_init(&parser->scratch, max_line_len);
}
void Curl_h1_req_parse_free(struct h1_req_parser *parser)
{
if(parser) {
Curl_http_req_free(parser->req);
- Curl_bufq_free(&parser->scratch);
+ Curl_dyn_free(&parser->scratch);
parser->req = NULL;
parser->done = FALSE;
}
}
+static CURLcode trim_line(struct h1_req_parser *parser, int options)
+{
+ DEBUGASSERT(parser->line);
+ if(parser->line_len) {
+ if(parser->line[parser->line_len - 1] == '\n')
+ --parser->line_len;
+ if(parser->line_len) {
+ if(parser->line[parser->line_len - 1] == '\r')
+ --parser->line_len;
+ else if(options & H1_PARSE_OPT_STRICT)
+ return CURLE_URL_MALFORMAT;
+ }
+ else if(options & H1_PARSE_OPT_STRICT)
+ return CURLE_URL_MALFORMAT;
+ }
+ else if(options & H1_PARSE_OPT_STRICT)
+ return CURLE_URL_MALFORMAT;
+
+ if(parser->line_len > parser->max_line_len) {
+ return CURLE_URL_MALFORMAT;
+ }
+ return CURLE_OK;
+}
+
static ssize_t detect_line(struct h1_req_parser *parser,
- const char *buf, const size_t buflen, int options,
+ const char *buf, const size_t buflen,
CURLcode *err)
{
const char *line_end;
- size_t len;
DEBUGASSERT(!parser->line);
line_end = memchr(buf, '\n', buflen);
if(!line_end) {
- *err = (buflen > parser->max_line_len)? CURLE_URL_MALFORMAT : CURLE_AGAIN;
+ *err = CURLE_AGAIN;
return -1;
}
- len = line_end - buf + 1;
- if(len > parser->max_line_len) {
- *err = CURLE_URL_MALFORMAT;
- return -1;
- }
-
- if(options & H1_PARSE_OPT_STRICT) {
- if((len == 1) || (buf[len - 2] != '\r')) {
- *err = CURLE_URL_MALFORMAT;
- return -1;
- }
- parser->line = buf;
- parser->line_len = len - 2;
- }
- else {
- parser->line = buf;
- parser->line_len = len - (((len == 1) || (buf[len - 2] != '\r'))? 1 : 2);
- }
+ parser->line = buf;
+ parser->line_len = line_end - buf + 1;
*err = CURLE_OK;
- return (ssize_t)len;
+ return (ssize_t)parser->line_len;
}
static ssize_t next_line(struct h1_req_parser *parser,
const char *buf, const size_t buflen, int options,
CURLcode *err)
{
- ssize_t nread = 0, n;
+ ssize_t nread = 0;
if(parser->line) {
- if(parser->scratch_skip) {
- /* last line was from scratch. Remove it now, since we are done
- * with it and look for the next one. */
- Curl_bufq_skip_and_shift(&parser->scratch, parser->scratch_skip);
- parser->scratch_skip = 0;
- }
parser->line = NULL;
parser->line_len = 0;
+ Curl_dyn_reset(&parser->scratch);
}
- if(Curl_bufq_is_empty(&parser->scratch)) {
- nread = detect_line(parser, buf, buflen, options, err);
- if(nread < 0) {
- if(*err != CURLE_AGAIN)
+ nread = detect_line(parser, buf, buflen, err);
+ if(nread >= 0) {
+ if(Curl_dyn_len(&parser->scratch)) {
+ /* append detected line to scratch to have the complete line */
+ *err = Curl_dyn_addn(&parser->scratch, parser->line, parser->line_len);
+ if(*err)
return -1;
- /* not a complete line, add to scratch for later revisit */
- nread = Curl_bufq_write(&parser->scratch,
- (const unsigned char *)buf, buflen, err);
- return nread;
+ parser->line = Curl_dyn_ptr(&parser->scratch);
+ parser->line_len = Curl_dyn_len(&parser->scratch);
}
- /* found one */
+ *err = trim_line(parser, options);
+ if(*err)
+ return -1;
}
- else {
- const char *sbuf;
- size_t sbuflen;
-
- /* scratch contains bytes from last attempt, add more to it */
- if(buflen) {
- const char *line_end;
- size_t add_len;
- ssize_t pos;
-
- line_end = memchr(buf, '\n', buflen);
- pos = line_end? (line_end - buf + 1) : -1;
- add_len = (pos >= 0)? (size_t)pos : buflen;
- nread = Curl_bufq_write(&parser->scratch,
- (const unsigned char *)buf, add_len, err);
- if(nread < 0) {
- /* Unable to add anything to scratch is an error, since we should
- * have seen a line there then before. */
- if(*err == CURLE_AGAIN)
- *err = CURLE_URL_MALFORMAT;
- return -1;
- }
- }
-
- if(Curl_bufq_peek(&parser->scratch,
- (const unsigned char **)&sbuf, &sbuflen)) {
- n = detect_line(parser, sbuf, sbuflen, options, err);
- if(n < 0 && *err != CURLE_AGAIN)
- return -1; /* real error */
- parser->scratch_skip = (size_t)n;
- }
- else {
- /* we SHOULD be able to peek at scratch data */
- DEBUGASSERT(0);
- }
+ else if(*err == CURLE_AGAIN) {
+ /* no line end in `buf`, add it to our scratch */
+ *err = Curl_dyn_addn(&parser->scratch, (const unsigned char *)buf, buflen);
+ nread = (*err)? -1 : (ssize_t)buflen;
}
return nread;
}
@@ -231,7 +204,7 @@ static CURLcode start_req(struct h1_req_parser *parser,
else {
/* origin-form OR absolute-form */
CURLUcode uc;
- char tmp[MAX_URL_LEN];
+ char tmp[H1_MAX_URL_LEN];
/* default, unless we see an absolute URL */
path = target;
@@ -328,7 +301,7 @@ ssize_t Curl_h1_req_parse_read(struct h1_req_parser *parser,
goto out;
}
parser->done = TRUE;
- Curl_bufq_free(&parser->scratch);
+ Curl_dyn_reset(&parser->scratch);
/* last chance adjustments */
}
else {
diff --git a/Utilities/cmcurl/lib/http1.h b/Utilities/cmcurl/lib/http1.h
index 93111ef..b1eaa96 100644
--- a/Utilities/cmcurl/lib/http1.h
+++ b/Utilities/cmcurl/lib/http1.h
@@ -33,11 +33,11 @@
#define H1_PARSE_OPT_NONE (0)
#define H1_PARSE_OPT_STRICT (1 << 0)
-#define H1_PARSE_DEFAULT_MAX_LINE_LEN (8 * 1024)
+#define H1_PARSE_DEFAULT_MAX_LINE_LEN DYN_HTTP_REQUEST
struct h1_req_parser {
struct httpreq *req;
- struct bufq scratch;
+ struct dynbuf scratch;
size_t scratch_skip;
const char *line;
size_t max_line_len;
diff --git a/Utilities/cmcurl/lib/http2.c b/Utilities/cmcurl/lib/http2.c
index 191d8cd..6c09ec1 100644
--- a/Utilities/cmcurl/lib/http2.c
+++ b/Utilities/cmcurl/lib/http2.c
@@ -134,9 +134,11 @@ struct cf_h2_ctx {
BIT(conn_closed);
BIT(goaway);
BIT(enable_push);
+ BIT(nw_out_blocked);
};
/* How to access `call_data` from a cf_h2 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_h2_ctx *)(cf)->ctx)->call_data
@@ -175,6 +177,7 @@ struct stream_ctx {
struct bufq sendbuf; /* request buffer */
struct dynhds resp_trailers; /* response trailer fields */
size_t resp_hds_len; /* amount of response header bytes in recvbuf */
+ size_t upload_blocked_len;
curl_off_t upload_left; /* number of request bytes left to upload */
char **push_headers; /* allocated array */
@@ -183,6 +186,7 @@ struct stream_ctx {
int status_code; /* HTTP response status code */
uint32_t error; /* stream error code */
+ uint32_t local_window_size; /* the local recv window size */
bool closed; /* TRUE on stream close */
bool reset; /* TRUE on stream reset */
bool close_handled; /* TRUE if stream closure is handled by libcurl */
@@ -209,9 +213,12 @@ static void drain_stream(struct Curl_cfilter *cf,
(void)cf;
bits = CURL_CSELECT_IN;
- if(!stream->send_closed && stream->upload_left)
+ if(!stream->send_closed &&
+ (stream->upload_left || stream->upload_blocked_len))
bits |= CURL_CSELECT_OUT;
if(data->state.dselect_bits != bits) {
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] DRAIN dselect_bits=%x",
+ stream->id, bits));
data->state.dselect_bits = bits;
Curl_expire(data, 0, EXPIRE_RUN_NOW);
}
@@ -245,13 +252,14 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf,
H2_STREAM_SEND_CHUNKS, BUFQ_OPT_NONE);
Curl_bufq_initp(&stream->recvbuf, &ctx->stream_bufcp,
H2_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
- Curl_dynhds_init(&stream->resp_trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&stream->resp_trailers, 0, DYN_HTTP_REQUEST);
stream->resp_hds_len = 0;
stream->bodystarted = FALSE;
stream->status_code = -1;
stream->closed = FALSE;
stream->close_handled = FALSE;
stream->error = NGHTTP2_NO_ERROR;
+ stream->local_window_size = H2_STREAM_WINDOW_SIZE;
stream->upload_left = 0;
H2_STREAM_LCTX(data) = stream;
@@ -580,7 +588,6 @@ static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data,
ssize_t nread = -1;
*input_pending = FALSE;
- Curl_attach_connection(data, cf->conn);
nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
if(nread != -1) {
DEBUGF(LOG_CF(data, cf, "%zd bytes stray data read before trying "
@@ -592,11 +599,10 @@ static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data,
alive = !should_close_session(ctx);
}
}
- else {
+ else if(result != CURLE_AGAIN) {
/* the read failed so let's say this is dead anyway */
alive = FALSE;
}
- Curl_detach_connection(data);
}
return alive;
@@ -644,13 +650,17 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
if(Curl_bufq_is_empty(&ctx->outbufq))
return CURLE_OK;
- DEBUGF(LOG_CF(data, cf, "h2 conn flush %zu bytes",
- Curl_bufq_len(&ctx->outbufq)));
nwritten = Curl_bufq_pass(&ctx->outbufq, nw_out_writer, cf, &result);
- if(nwritten < 0 && result != CURLE_AGAIN) {
+ if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ DEBUGF(LOG_CF(data, cf, "flush nw send buffer(%zu) -> EAGAIN",
+ Curl_bufq_len(&ctx->outbufq)));
+ ctx->nw_out_blocked = 1;
+ }
return result;
}
- return CURLE_OK;
+ DEBUGF(LOG_CF(data, cf, "nw send buffer flushed"));
+ return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
}
/*
@@ -676,15 +686,17 @@ static ssize_t send_callback(nghttp2_session *h2,
nw_out_writer, cf, &result);
if(nwritten < 0) {
if(result == CURLE_AGAIN) {
+ ctx->nw_out_blocked = 1;
return NGHTTP2_ERR_WOULDBLOCK;
}
failf(data, "Failed sending HTTP2 data");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- if(!nwritten)
+ if(!nwritten) {
+ ctx->nw_out_blocked = 1;
return NGHTTP2_ERR_WOULDBLOCK;
-
+ }
return nwritten;
}
@@ -964,6 +976,7 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
struct stream_ctx *stream = H2_STREAM_CTX(data);
int32_t stream_id = frame->hd.stream_id;
CURLcode result;
+ size_t rbuflen;
int rv;
if(!stream) {
@@ -973,10 +986,10 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
switch(frame->hd.type) {
case NGHTTP2_DATA:
+ rbuflen = Curl_bufq_len(&stream->recvbuf);
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] FRAME[DATA len=%zu pad=%zu], "
"buffered=%zu, window=%d/%d",
- stream_id, frame->hd.length, frame->data.padlen,
- Curl_bufq_len(&stream->recvbuf),
+ stream_id, frame->hd.length, frame->data.padlen, rbuflen,
nghttp2_session_get_stream_effective_recv_data_length(
ctx->h2, stream->id),
nghttp2_session_get_stream_effective_local_window_size(
@@ -993,6 +1006,20 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
drain_stream(cf, data, stream);
}
+ else if(rbuflen > stream->local_window_size) {
+ int32_t wsize = nghttp2_session_get_stream_local_window_size(
+ ctx->h2, stream->id);
+ if(wsize > 0 && (uint32_t)wsize != stream->local_window_size) {
+ /* H2 flow control is not absolute, as the server might not have the
+ * same view, yet. When we recieve more than we want, we enforce
+ * the local window size again to make nghttp2 send WINDOW_UPATEs
+ * accordingly. */
+ nghttp2_session_set_local_window_size(ctx->h2,
+ NGHTTP2_FLAG_NONE,
+ stream->id,
+ stream->local_window_size);
+ }
+ }
break;
case NGHTTP2_HEADERS:
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] FRAME[HEADERS]", stream_id));
@@ -1095,6 +1122,21 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
ctx->max_concurrent_streams));
multi_connchanged(data->multi);
}
+ /* Since the initial stream window is 64K, a request might be on HOLD,
+ * due to exhaustion. The (initial) SETTINGS may announce a much larger
+ * window and *assume* that we treat this like a WINDOW_UPDATE. Some
+ * servers send an explicit WINDOW_UPDATE, but not all seem to do that.
+ * To be safe, we UNHOLD a stream in order not to stall. */
+ if((data->req.keepon & KEEP_SEND_HOLD) &&
+ (data->req.keepon & KEEP_SEND)) {
+ struct stream_ctx *stream = H2_STREAM_CTX(data);
+ data->req.keepon &= ~KEEP_SEND_HOLD;
+ if(stream) {
+ drain_stream(cf, data, stream);
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] un-holding after SETTINGS",
+ stream_id));
+ }
+ }
break;
}
case NGHTTP2_GOAWAY:
@@ -1448,8 +1490,8 @@ static ssize_t req_body_read_callback(nghttp2_session *session,
if(nread > 0 && stream->upload_left != -1)
stream->upload_left -= nread;
- DEBUGF(LOG_CF(data_s, cf, "[h2sid=%d] req_body_read(len=%zu) left=%zd"
- " -> %zd, %d",
+ DEBUGF(LOG_CF(data_s, cf, "[h2sid=%d] req_body_read(len=%zu) left=%"
+ CURL_FORMAT_CURL_OFF_T " -> %zd, %d",
stream_id, length, stream->upload_left, nread, result));
if(stream->upload_left == 0)
@@ -1555,11 +1597,6 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf,
*err = CURLE_SEND_ERROR; /* trigger Curl_retry_request() later */
return -1;
}
- else if(stream->reset) {
- failf(data, "HTTP/2 stream %u was reset", stream->id);
- *err = stream->bodystarted? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR;
- return -1;
- }
else if(stream->error != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %u)",
stream->id, nghttp2_http2_strerror(stream->error),
@@ -1567,6 +1604,11 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf,
*err = CURLE_HTTP2_STREAM;
return -1;
}
+ else if(stream->reset) {
+ failf(data, "HTTP/2 stream %u was reset", stream->id);
+ *err = stream->bodystarted? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR;
+ return -1;
+ }
if(!stream->bodystarted) {
failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
@@ -1659,9 +1701,10 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
struct stream_ctx *stream = H2_STREAM_CTX(data);
int rv = 0;
- if((sweight_wanted(data) != sweight_in_effect(data)) ||
- (data->set.priority.exclusive != data->state.priority.exclusive) ||
- (data->set.priority.parent != data->state.priority.parent) ) {
+ if(stream && stream->id > 0 &&
+ ((sweight_wanted(data) != sweight_in_effect(data)) ||
+ (data->set.priority.exclusive != data->state.priority.exclusive) ||
+ (data->set.priority.parent != data->state.priority.parent)) ) {
/* send new weight and/or dependency */
nghttp2_priority_spec pri_spec;
@@ -1675,7 +1718,8 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
goto out;
}
- while(!rv && nghttp2_session_want_write(ctx->h2))
+ ctx->nw_out_blocked = 0;
+ while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2))
rv = nghttp2_session_send(ctx->h2);
out:
@@ -1739,7 +1783,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
/* Process network input buffer fist */
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
- DEBUGF(LOG_CF(data, cf, "Process %zd bytes in connection buffer",
+ DEBUGF(LOG_CF(data, cf, "Process %zu bytes in connection buffer",
Curl_bufq_len(&ctx->inbufq)));
if(h2_process_pending_input(cf, data, &result) < 0)
return result;
@@ -1760,7 +1804,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
}
nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
- /* DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
+ /* DEBUGF(LOG_CF(data, cf, "read %zu bytes nw data -> %zd, %d",
Curl_bufq_len(&ctx->inbufq), nread, result)); */
if(nread < 0) {
if(result != CURLE_AGAIN) {
@@ -1836,7 +1880,7 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
out:
result = h2_progress_egress(cf, data);
- if(result) {
+ if(result && result != CURLE_AGAIN) {
*err = result;
nread = -1;
}
@@ -1864,7 +1908,8 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
struct h1_req_parser h1;
struct dynhds h2_headers;
nghttp2_nv *nva = NULL;
- size_t nheader, i;
+ const void *body = NULL;
+ size_t nheader, bodylen, i;
nghttp2_data_provider data_prd;
int32_t stream_id;
nghttp2_priority_spec pri_spec;
@@ -1929,8 +1974,8 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
h2_pri_spec(data, &pri_spec);
- DEBUGF(LOG_CF(data, cf, "send request allowed %d (easy handle %p)",
- nghttp2_session_check_request_allowed(ctx->h2), (void *)data));
+ DEBUGF(LOG_CF(data, cf, "send request allowed %d",
+ nghttp2_session_check_request_allowed(ctx->h2)));
switch(data->state.httpreq) {
case HTTPREQ_POST:
@@ -1966,9 +2011,35 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) submit %s",
stream_id, len, data->state.url));
- infof(data, "Using Stream ID: %u (easy handle %p)",
- stream_id, (void *)data);
+ infof(data, "Using Stream ID: %u", stream_id);
stream->id = stream_id;
+ stream->local_window_size = H2_STREAM_WINDOW_SIZE;
+ if(data->set.max_recv_speed) {
+ /* We are asked to only receive `max_recv_speed` bytes per second.
+ * Let's limit our stream window size around that, otherwise the server
+ * will send in large bursts only. We make the window 50% larger to
+ * allow for data in flight and avoid stalling. */
+ curl_off_t n = (((data->set.max_recv_speed - 1) / H2_CHUNK_SIZE) + 1);
+ n += CURLMAX((n/2), 1);
+ if(n < (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE) &&
+ n < (UINT_MAX / H2_CHUNK_SIZE)) {
+ stream->local_window_size = (uint32_t)n * H2_CHUNK_SIZE;
+ }
+ }
+
+ body = (const char *)buf + nwritten;
+ bodylen = len - nwritten;
+
+ if(bodylen) {
+ /* We have request body to send in DATA frame */
+ ssize_t n = Curl_bufq_write(&stream->sendbuf, body, bodylen, err);
+ if(n < 0) {
+ *err = CURLE_SEND_ERROR;
+ nwritten = -1;
+ goto out;
+ }
+ nwritten += n;
+ }
out:
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] submit -> %zd, %d",
@@ -1982,17 +2053,13 @@ out:
static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
- /*
- * Currently, we send request in this function, but this function is also
- * used to send request body. It would be nice to add dedicated function for
- * request.
- */
struct cf_h2_ctx *ctx = cf->ctx;
struct stream_ctx *stream = H2_STREAM_CTX(data);
struct cf_call_data save;
int rv;
ssize_t nwritten;
CURLcode result;
+ int blocked = 0;
CF_DATA_SAVE(save, cf, data);
@@ -2007,18 +2074,35 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
nwritten = http2_handle_stream_close(cf, data, stream, err);
goto out;
}
- /* If stream_id != -1, we have dispatched request HEADERS, and now
- are going to send or sending request body in DATA frame */
- nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err);
- if(nwritten < 0) {
- if(*err != CURLE_AGAIN)
+ else if(stream->upload_blocked_len) {
+ /* the data in `buf` has alread been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= stream->upload_blocked_len);
+ if(len < stream->upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happend. We are not prepared to handle that. */
+ failf(data, "HTTP/2 send again with decreased length");
+ *err = CURLE_HTTP2;
+ nwritten = -1;
goto out;
- nwritten = 0;
+ }
+ nwritten = (ssize_t)stream->upload_blocked_len;
+ stream->upload_blocked_len = 0;
+ }
+ else {
+ /* If stream_id != -1, we have dispatched request HEADERS and
+ * optionally request body, and now are going to send or sending
+ * more request body in DATA frame */
+ nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err);
+ if(nwritten < 0) {
+ if(*err != CURLE_AGAIN)
+ goto out;
+ nwritten = 0;
+ }
}
- DEBUGF(LOG_CF(data, cf, "[h2sid=%u] bufq_write(len=%zu) -> %zd, %d",
- stream->id, len, nwritten, *err));
if(!Curl_bufq_is_empty(&stream->sendbuf)) {
+ /* req body data is buffered, resume the potentially suspended stream */
rv = nghttp2_session_resume_data(ctx->h2, stream->id);
if(nghttp2_is_fatal(rv)) {
*err = CURLE_SEND_ERROR;
@@ -2026,104 +2110,99 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
goto out;
}
}
-
- result = h2_progress_ingress(cf, data);
- if(result) {
- *err = result;
- nwritten = -1;
- goto out;
- }
-
- result = h2_progress_egress(cf, data);
- if(result) {
- *err = result;
- nwritten = -1;
- goto out;
- }
-
- if(should_close_session(ctx)) {
- if(stream->closed) {
- nwritten = http2_handle_stream_close(cf, data, stream, err);
- }
- else {
- DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
- *err = CURLE_HTTP2;
- nwritten = -1;
- }
- goto out;
- }
-
- if(!nwritten) {
- size_t rwin = nghttp2_session_get_stream_remote_window_size(ctx->h2,
- stream->id);
- DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send: win %u/%zu",
- stream->id,
- nghttp2_session_get_remote_window_size(ctx->h2), rwin));
- if(rwin == 0) {
- /* We cannot upload more as the stream's remote window size
- * is 0. We need to receive WIN_UPDATEs before we can continue.
- */
- data->req.keepon |= KEEP_SEND_HOLD;
- DEBUGF(LOG_CF(data, cf, "[h2sid=%d] holding send as remote flow "
- "window is exhausted", stream->id));
- }
- nwritten = -1;
- *err = CURLE_AGAIN;
- }
- /* handled writing BODY for open stream. */
- goto out;
}
else {
nwritten = h2_submit(&stream, cf, data, buf, len, err);
if(nwritten < 0) {
goto out;
}
+ DEBUGASSERT(stream);
+ }
- result = h2_progress_ingress(cf, data);
- if(result) {
- *err = result;
- nwritten = -1;
- goto out;
+ /* Call the nghttp2 send loop and flush to write ALL buffered data,
+ * headers and/or request body completely out to the network */
+ result = h2_progress_egress(cf, data);
+ /* if the stream has been closed in egress handling (nghttp2 does that
+ * when it does not like the headers, for example */
+ if(stream && stream->closed) {
+ nwritten = http2_handle_stream_close(cf, data, stream, err);
+ goto out;
+ }
+ else if(result == CURLE_AGAIN) {
+ blocked = 1;
+ }
+ else if(result) {
+ *err = result;
+ nwritten = -1;
+ goto out;
+ }
+ else if(stream && !Curl_bufq_is_empty(&stream->sendbuf)) {
+ /* although we wrote everything that nghttp2 wants to send now,
+ * there is data left in our stream send buffer unwritten. This may
+ * be due to the stream's HTTP/2 flow window being exhausted. */
+ blocked = 1;
+ }
+
+ if(stream && blocked) {
+ /* Unable to send all data, due to connection blocked or H2 window
+ * exhaustion. Data is left in our stream buffer, or nghttp2's internal
+ * frame buffer or our network out buffer. */
+ size_t rwin = nghttp2_session_get_stream_remote_window_size(ctx->h2,
+ stream->id);
+ if(rwin == 0) {
+ /* H2 flow window exhaustion. We need to HOLD upload until we get
+ * a WINDOW_UPDATE from the server. */
+ data->req.keepon |= KEEP_SEND_HOLD;
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] holding send as remote flow "
+ "window is exhausted", stream->id));
+ }
+
+ /* Whatever the cause, we need to return CURL_EAGAIN for this call.
+ * We have unwritten state that needs us being invoked again and EAGAIN
+ * is the only way to ensure that. */
+ stream->upload_blocked_len = nwritten;
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) BLOCK: win %u/%zu "
+ "blocked_len=%zu",
+ stream->id, len,
+ nghttp2_session_get_remote_window_size(ctx->h2), rwin,
+ nwritten));
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ goto out;
+ }
+ else if(should_close_session(ctx)) {
+ /* nghttp2 thinks this session is done. If the stream has not been
+ * closed, this is an error state for out transfer */
+ if(stream->closed) {
+ nwritten = http2_handle_stream_close(cf, data, stream, err);
}
-
- result = h2_progress_egress(cf, data);
- if(result) {
- *err = result;
+ else {
+ DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
+ *err = CURLE_HTTP2;
nwritten = -1;
- goto out;
- }
-
- if(should_close_session(ctx)) {
- if(stream->closed) {
- nwritten = http2_handle_stream_close(cf, data, stream, err);
- }
- else {
- DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
- *err = CURLE_HTTP2;
- nwritten = -1;
- }
- goto out;
}
}
out:
if(stream) {
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) -> %zd, %d, "
- "buffered=%zu, upload_left=%zu, stream-window=%d, "
- "connection-window=%d",
+ "upload_left=%" CURL_FORMAT_CURL_OFF_T ", "
+ "h2 windows %d-%d (stream-conn), "
+ "buffers %zu-%zu (stream-conn)",
stream->id, len, nwritten, *err,
- Curl_bufq_len(&stream->sendbuf),
(ssize_t)stream->upload_left,
nghttp2_session_get_stream_remote_window_size(
ctx->h2, stream->id),
- nghttp2_session_get_remote_window_size(ctx->h2)));
- drain_stream(cf, data, stream);
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&stream->sendbuf),
+ Curl_bufq_len(&ctx->outbufq)));
}
else {
DEBUGF(LOG_CF(data, cf, "cf_send(len=%zu) -> %zd, %d, "
- "connection-window=%d",
+ "connection-window=%d, nw_send_buffer(%zu)",
len, nwritten, *err,
- nghttp2_session_get_remote_window_size(ctx->h2)));
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&ctx->outbufq)));
}
CF_DATA_RESTORE(cf, save);
return nwritten;
@@ -2241,8 +2320,7 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf,
DEBUGASSERT(data);
if(ctx && ctx->h2 && stream) {
- uint32_t window = !pause * H2_STREAM_WINDOW_SIZE;
- CURLcode result;
+ uint32_t window = pause? 0 : stream->local_window_size;
int rv = nghttp2_session_set_local_window_size(ctx->h2,
NGHTTP2_FLAG_NONE,
@@ -2257,10 +2335,8 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf,
if(!pause)
drain_stream(cf, data, stream);
- /* make sure the window update gets sent */
- result = h2_progress_egress(cf, data);
- if(result)
- return result;
+ /* attempt to send the window update */
+ (void)h2_progress_egress(cf, data);
if(!pause) {
/* Unpausing a h2 transfer, requires it to be run again. The server
@@ -2510,7 +2586,7 @@ CURLcode Curl_http2_switch(struct Curl_easy *data,
CURLcode result;
DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex));
- DEBUGF(infof(data, DMSGI(data, sockindex, "switching to HTTP/2")));
+ DEBUGF(infof(data, "switching to HTTP/2"));
result = http2_cfilter_add(&cf, data, conn, sockindex);
if(result)
@@ -2569,7 +2645,7 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data,
CURLcode result;
DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex));
- DEBUGF(infof(data, DMSGI(data, sockindex, "upgrading to HTTP/2")));
+ DEBUGF(infof(data, "upgrading to HTTP/2"));
DEBUGASSERT(data->req.upgr101 == UPGR101_RECEIVED);
result = http2_cfilter_add(&cf, data, conn, sockindex);
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
index add376b..4fd998a 100644
--- a/Utilities/cmcurl/lib/http_proxy.c
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -71,7 +71,7 @@ static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf,
DEBUGF(LOG_CF(data, cf, "connect"));
connect_sub:
- result = cf->next->cft->connect(cf->next, data, blocking, done);
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
if(result || !*done)
return result;
@@ -181,7 +181,7 @@ static void http_proxy_cf_close(struct Curl_cfilter *cf,
ctx->cf_protocol = NULL;
}
if(cf->next)
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
}
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
index ed197c9..045fe24 100644
--- a/Utilities/cmcurl/lib/imap.c
+++ b/Utilities/cmcurl/lib/imap.c
@@ -385,11 +385,11 @@ static CURLcode imap_get_message(struct Curl_easy *data, struct bufref *out)
/***********************************************************************
*
- * state()
+ * imap_state()
*
* This is the ONLY way to change IMAP state!
*/
-static void state(struct Curl_easy *data, imapstate newstate)
+static void imap_state(struct Curl_easy *data, imapstate newstate)
{
struct imap_conn *imapc = &data->conn->proto.imapc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -441,7 +441,7 @@ static CURLcode imap_perform_capability(struct Curl_easy *data,
result = imap_sendf(data, "CAPABILITY");
if(!result)
- state(data, IMAP_CAPABILITY);
+ imap_state(data, IMAP_CAPABILITY);
return result;
}
@@ -458,7 +458,7 @@ static CURLcode imap_perform_starttls(struct Curl_easy *data)
CURLcode result = imap_sendf(data, "STARTTLS");
if(!result)
- state(data, IMAP_STARTTLS);
+ imap_state(data, IMAP_STARTTLS);
return result;
}
@@ -487,7 +487,7 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
if(!result) {
imapc->ssldone = ssldone;
if(imapc->state != IMAP_UPGRADETLS)
- state(data, IMAP_UPGRADETLS);
+ imap_state(data, IMAP_UPGRADETLS);
if(imapc->ssldone) {
imap_to_imaps(conn);
@@ -514,7 +514,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!data->state.aptr.user) {
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -531,7 +531,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
free(passwd);
if(!result)
- state(data, IMAP_LOGIN);
+ imap_state(data, IMAP_LOGIN);
return result;
}
@@ -615,7 +615,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
with and end the connect phase if we don't */
if(imapc->preauth ||
!Curl_sasl_can_authenticate(&imapc->sasl, data)) {
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -624,7 +624,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
if(!result) {
if(progress == SASL_INPROGRESS)
- state(data, IMAP_AUTHENTICATE);
+ imap_state(data, IMAP_AUTHENTICATE);
else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
/* Perform clear text authentication */
result = imap_perform_login(data, conn);
@@ -667,7 +667,7 @@ static CURLcode imap_perform_list(struct Curl_easy *data)
}
if(!result)
- state(data, IMAP_LIST);
+ imap_state(data, IMAP_LIST);
return result;
}
@@ -707,7 +707,7 @@ static CURLcode imap_perform_select(struct Curl_easy *data)
free(mailbox);
if(!result)
- state(data, IMAP_SELECT);
+ imap_state(data, IMAP_SELECT);
return result;
}
@@ -749,7 +749,7 @@ static CURLcode imap_perform_fetch(struct Curl_easy *data)
return CURLE_URL_MALFORMAT;
}
if(!result)
- state(data, IMAP_FETCH);
+ imap_state(data, IMAP_FETCH);
return result;
}
@@ -820,7 +820,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data)
free(mailbox);
if(!result)
- state(data, IMAP_APPEND);
+ imap_state(data, IMAP_APPEND);
return result;
}
@@ -846,7 +846,7 @@ static CURLcode imap_perform_search(struct Curl_easy *data)
result = imap_sendf(data, "SEARCH %s", imap->query);
if(!result)
- state(data, IMAP_SEARCH);
+ imap_state(data, IMAP_SEARCH);
return result;
}
@@ -863,7 +863,7 @@ static CURLcode imap_perform_logout(struct Curl_easy *data)
CURLcode result = imap_sendf(data, "LOGOUT");
if(!result)
- state(data, IMAP_LOGOUT);
+ imap_state(data, IMAP_LOGOUT);
return result;
}
@@ -1017,7 +1017,7 @@ static CURLcode imap_state_auth_resp(struct Curl_easy *data,
if(!result)
switch(progress) {
case SASL_DONE:
- state(data, IMAP_STOP); /* Authenticated */
+ imap_state(data, IMAP_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
@@ -1049,7 +1049,7 @@ static CURLcode imap_state_login_resp(struct Curl_easy *data,
}
else
/* End of connect phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1075,7 +1075,7 @@ static CURLcode imap_state_listsearch_resp(struct Curl_easy *data,
result = CURLE_QUOTE_ERROR;
else
/* End of DO phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1143,7 +1143,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
if(imapcode != '*') {
Curl_pgrsSetDownloadSize(data, -1);
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return CURLE_REMOTE_FILE_NOT_FOUND;
}
@@ -1178,7 +1178,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
if(!chunk) {
/* no size, we're done with the data */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return CURLE_OK;
}
result = Curl_client_write(data, CLIENTWRITE_BODY, pp->cache, chunk);
@@ -1224,7 +1224,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
}
/* End of DO phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1242,7 +1242,7 @@ static CURLcode imap_state_fetch_final_resp(struct Curl_easy *data,
result = CURLE_WEIRD_SERVER_REPLY;
else
/* End of DONE phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1265,7 +1265,7 @@ static CURLcode imap_state_append_resp(struct Curl_easy *data, int imapcode,
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
}
return result;
@@ -1284,7 +1284,7 @@ static CURLcode imap_state_append_final_resp(struct Curl_easy *data,
result = CURLE_UPLOAD_FAILED;
else
/* End of DONE phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1372,7 +1372,7 @@ static CURLcode imap_statemachine(struct Curl_easy *data,
/* fallthrough, just stop! */
default:
/* internal error */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
break;
}
} while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
@@ -1475,7 +1475,7 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done)
return result;
/* Start off waiting for the server greeting response */
- state(data, IMAP_SERVERGREET);
+ imap_state(data, IMAP_SERVERGREET);
/* Start off with an response id of '*' */
strcpy(imapc->resptag, "*");
@@ -1516,12 +1516,12 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
/* Handle responses after FETCH or APPEND transfer has finished */
if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
- state(data, IMAP_FETCH_FINAL);
+ imap_state(data, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
result = Curl_pp_sendf(data, &conn->proto.imapc.pp, "%s", "");
if(!result)
- state(data, IMAP_APPEND_FINAL);
+ imap_state(data, IMAP_APPEND_FINAL);
}
/* Run the state-machine */
@@ -1777,7 +1777,7 @@ static CURLcode imap_sendf(struct Curl_easy *data, const char *fmt, ...)
/* Calculate the tag based on the connection ID and command ID */
msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
- 'A' + curlx_sltosi(data->conn->connection_id % 26),
+ 'A' + curlx_sltosi((long)(data->conn->connection_id % 26)),
++imapc->cmdid);
/* start with a blank buffer */
@@ -1925,6 +1925,7 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
const char *ptr = conn->options;
+ bool prefer_login = false;
while(!result && ptr && *ptr) {
const char *key = ptr;
@@ -1938,26 +1939,39 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
while(*ptr && *ptr != ';')
ptr++;
- if(strncasecompare(key, "AUTH=", 5))
+ if(strncasecompare(key, "AUTH=+LOGIN", 11)) {
+ /* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */
+ prefer_login = true;
+ imapc->sasl.prefmech = SASL_AUTH_NONE;
+ }
+ else if(strncasecompare(key, "AUTH=", 5)) {
+ prefer_login = false;
result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
value, ptr - value);
- else
+ }
+ else {
+ prefer_login = false;
result = CURLE_URL_MALFORMAT;
+ }
if(*ptr == ';')
ptr++;
}
- switch(imapc->sasl.prefmech) {
- case SASL_AUTH_NONE:
- imapc->preftype = IMAP_TYPE_NONE;
- break;
- case SASL_AUTH_DEFAULT:
- imapc->preftype = IMAP_TYPE_ANY;
- break;
- default:
- imapc->preftype = IMAP_TYPE_SASL;
- break;
+ if(prefer_login)
+ imapc->preftype = IMAP_TYPE_CLEARTEXT;
+ else {
+ switch(imapc->sasl.prefmech) {
+ case SASL_AUTH_NONE:
+ imapc->preftype = IMAP_TYPE_NONE;
+ break;
+ case SASL_AUTH_DEFAULT:
+ imapc->preftype = IMAP_TYPE_ANY;
+ break;
+ default:
+ imapc->preftype = IMAP_TYPE_SASL;
+ break;
+ }
}
return result;
diff --git a/Utilities/cmcurl/lib/krb5.c b/Utilities/cmcurl/lib/krb5.c
index a71779a..c2ba815 100644
--- a/Utilities/cmcurl/lib/krb5.c
+++ b/Utilities/cmcurl/lib/krb5.c
@@ -261,7 +261,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
}
/* We pass NULL as |output_name_type| to avoid a leak. */
gss_display_name(&min, gssname, &output_buffer, NULL);
- infof(data, "Trying against %s", output_buffer.value);
+ infof(data, "Trying against %s", (char *)output_buffer.value);
gssresp = GSS_C_NO_BUFFER;
*context = GSS_C_NO_CONTEXT;
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
index 4c88b0a..6b30ffb 100644
--- a/Utilities/cmcurl/lib/ldap.c
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -50,6 +50,14 @@
#endif
#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */
+# ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4201)
+# endif
+# include <subauth.h> /* for [P]UNICODE_STRING */
+# ifdef _MSC_VER
+# pragma warning(pop)
+# endif
# include <winldap.h>
# ifndef LDAP_VENDOR_NAME
# error Your Platform SDK is NOT sufficient for LDAP support! \
diff --git a/Utilities/cmcurl/lib/macos.c b/Utilities/cmcurl/lib/macos.c
new file mode 100644
index 0000000..5fe4e0b
--- /dev/null
+++ b/Utilities/cmcurl/lib/macos.c
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__APPLE__)
+
+#if !defined(TARGET_OS_OSX) || TARGET_OS_OSX
+
+#include <curl/curl.h>
+
+#include "macos.h"
+
+#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
+#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
+#endif
+
+CURLcode Curl_macos_init(void)
+{
+#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
+ {
+ /*
+ * The automagic conversion from IPv4 literals to IPv6 literals only
+ * works if the SCDynamicStoreCopyProxies system function gets called
+ * first. As Curl currently doesn't support system-wide HTTP proxies, we
+ * therefore don't use any value this function might return.
+ *
+ * This function is only available on a macOS and is not needed for
+ * IPv4-only builds, hence the conditions above.
+ */
+ CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
+ if(dict)
+ CFRelease(dict);
+ }
+#endif
+ return CURLE_OK;
+}
+
+#endif /* TARGET_OS_OSX */
+
+#endif /* __APPLE__ */
diff --git a/Utilities/cmcurl/lib/macos.h b/Utilities/cmcurl/lib/macos.h
new file mode 100644
index 0000000..3388acd
--- /dev/null
+++ b/Utilities/cmcurl/lib/macos.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_MACOS_H
+#define HEADER_CURL_MACOS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(__APPLE__) && (!defined(TARGET_OS_OSX) || TARGET_OS_OSX)
+
+CURLcode Curl_macos_init(void);
+
+#else
+
+#define Curl_macos_init() CURLE_OK
+
+#endif
+
+#endif /* HEADER_CURL_MACOS_H */
diff --git a/Utilities/cmcurl/lib/mime.c b/Utilities/cmcurl/lib/mime.c
index 39aac8f..0a57e1e 100644
--- a/Utilities/cmcurl/lib/mime.c
+++ b/Utilities/cmcurl/lib/mime.c
@@ -84,7 +84,7 @@ static const struct mime_encoder encoders[] = {
};
/* Base64 encoding table */
-static const char base64[] =
+static const char base64enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* Quoted-printable character class table.
@@ -469,10 +469,10 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
i = st->buf[st->bufbeg++] & 0xFF;
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
- *ptr++ = base64[(i >> 18) & 0x3F];
- *ptr++ = base64[(i >> 12) & 0x3F];
- *ptr++ = base64[(i >> 6) & 0x3F];
- *ptr++ = base64[i & 0x3F];
+ *ptr++ = base64enc[(i >> 18) & 0x3F];
+ *ptr++ = base64enc[(i >> 12) & 0x3F];
+ *ptr++ = base64enc[(i >> 6) & 0x3F];
+ *ptr++ = base64enc[i & 0x3F];
cursize += 4;
st->pos += 4;
size -= 4;
@@ -496,10 +496,10 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
i |= (st->buf[st->bufbeg] & 0xFF) << 16;
- ptr[0] = base64[(i >> 18) & 0x3F];
- ptr[1] = base64[(i >> 12) & 0x3F];
+ ptr[0] = base64enc[(i >> 18) & 0x3F];
+ ptr[1] = base64enc[(i >> 12) & 0x3F];
if(++st->bufbeg != st->bufend) {
- ptr[2] = base64[(i >> 6) & 0x3F];
+ ptr[2] = base64enc[(i >> 6) & 0x3F];
st->bufbeg++;
}
cursize += 4;
diff --git a/Utilities/cmcurl/lib/mqtt.c b/Utilities/cmcurl/lib/mqtt.c
index dbe7239..799a21a 100644
--- a/Utilities/cmcurl/lib/mqtt.c
+++ b/Utilities/cmcurl/lib/mqtt.c
@@ -636,7 +636,7 @@ MQTT_SUBACK_COMING:
/* -- switched state -- */
remlen = mq->remaining_length;
- infof(data, "Remaining length: %zd bytes", remlen);
+ infof(data, "Remaining length: %zu bytes", remlen);
if(data->set.max_filesize &&
(curl_off_t)remlen > data->set.max_filesize) {
failf(data, "Maximum file size exceeded");
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index d1d32b7..50bf15a 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -112,7 +112,7 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
static void process_pending_handles(struct Curl_multi *multi);
#ifdef DEBUGBUILD
-static const char * const statename[]={
+static const char * const multi_statename[]={
"INIT",
"PENDING",
"CONNECT",
@@ -194,15 +194,10 @@ static void mstate(struct Curl_easy *data, CURLMstate state
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
if(data->mstate >= MSTATE_PENDING &&
data->mstate < MSTATE_COMPLETED) {
- long connection_id = -5000;
-
- if(data->conn)
- connection_id = data->conn->connection_id;
-
infof(data,
- "STATE: %s => %s handle %p; line %d (connection #%ld)",
- statename[oldstate], statename[data->mstate],
- (void *)data, lineno, connection_id);
+ "STATE: %s => %s handle %p; line %d",
+ multi_statename[oldstate], multi_statename[data->mstate],
+ (void *)data, lineno);
}
#endif
@@ -464,6 +459,20 @@ struct Curl_multi *curl_multi_init(void)
CURL_DNS_HASH_SIZE);
}
+#ifdef DEBUGBUILD
+static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
+{
+ if(!multi->warned) {
+ infof(data, "!!! WARNING !!!");
+ infof(data, "This is a debug build of libcurl, "
+ "do not use in production.");
+ multi->warned = true;
+ }
+}
+#else
+#define multi_warn_debug(x,y) Curl_nop_stmt
+#endif
+
/* returns TRUE if the easy handle is supposed to be present in the main link
list */
static bool in_main_list(struct Curl_easy *data)
@@ -623,8 +632,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->set.server_response_timeout;
data->state.conn_cache->closure_handle->set.no_signal =
data->set.no_signal;
+ data->id = data->state.conn_cache->next_easy_id++;
+ if(data->state.conn_cache->next_easy_id <= 0)
+ data->state.conn_cache->next_easy_id = 0;
CONNCACHE_UNLOCK(data);
+ multi_warn_debug(multi, data);
+ infof(data, "processing: %s", data->state.url);
+
return CURLM_OK;
}
@@ -742,6 +757,7 @@ static CURLcode multi_done(struct Curl_easy *data,
but currently we have no such detail knowledge.
*/
+ data->state.recent_conn_id = conn->connection_id;
if((data->set.reuse_forbid
#if defined(USE_NTLM)
&& !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
@@ -753,8 +769,9 @@ static CURLcode multi_done(struct Curl_easy *data,
#endif
) || conn->bits.close
|| (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) {
- DEBUGF(infof(data, "multi_done, not re-using connection=%ld, forbid=%d"
- ", close=%d, premature=%d, conn_multiplex=%d",
+ DEBUGF(infof(data, "multi_done, not re-using connection=%"
+ CURL_FORMAT_CURL_OFF_T ", forbid=%d"
+ ", close=%d, premature=%d, conn_multiplex=%d",
conn->connection_id,
data->set.reuse_forbid, conn->bits.close, premature,
Curl_conn_is_multiplex(conn, FIRSTSOCKET)));
@@ -774,15 +791,16 @@ static CURLcode multi_done(struct Curl_easy *data,
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname;
/* create string before returning the connection */
- long connection_id = conn->connection_id;
+ curl_off_t connection_id = conn->connection_id;
msnprintf(buffer, sizeof(buffer),
- "Connection #%ld to host %s left intact",
+ "Connection #%" CURL_FORMAT_CURL_OFF_T " to host %s left intact",
connection_id, host);
/* the connection is no longer in use by this transfer */
CONNCACHE_UNLOCK(data);
if(Curl_conncache_return_conn(data, conn)) {
/* remember the most recently used connection */
data->state.lastconnect_id = connection_id;
+ data->state.recent_conn_id = connection_id;
infof(data, "%s", buffer);
}
else
@@ -1895,14 +1913,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, MSTATE_COMPLETED);
}
-#ifdef DEBUGBUILD
- if(!multi->warned) {
- infof(data, "!!! WARNING !!!");
- infof(data, "This is a debug build of libcurl, "
- "do not use in production.");
- multi->warned = true;
- }
-#endif
+ multi_warn_debug(multi, data);
do {
/* A "stream" here is a logical stream if the protocol can handle that
@@ -3690,7 +3701,7 @@ void Curl_expire_clear(struct Curl_easy *data)
}
#ifdef DEBUGBUILD
- infof(data, "Expire cleared (transfer %p)", data);
+ infof(data, "Expire cleared");
#endif
nowp->tv_sec = 0;
nowp->tv_usec = 0;
@@ -3798,7 +3809,7 @@ void Curl_multi_dump(struct Curl_multi *multi)
/* only display handles that are not completed */
fprintf(stderr, "handle %p, state %s, %d sockets\n",
(void *)data,
- statename[data->mstate], data->numsocks);
+ multi_statename[data->mstate], data->numsocks);
for(i = 0; i < data->numsocks; i++) {
curl_socket_t s = data->sockets[i];
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
index 0de34cc..ddb98bf 100644
--- a/Utilities/cmcurl/lib/pop3.c
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -282,11 +282,11 @@ static CURLcode pop3_get_message(struct Curl_easy *data, struct bufref *out)
/***********************************************************************
*
- * state()
+ * pop3_state()
*
* This is the ONLY way to change POP3 state!
*/
-static void state(struct Curl_easy *data, pop3state newstate)
+static void pop3_state(struct Curl_easy *data, pop3state newstate)
{
struct pop3_conn *pop3c = &data->conn->proto.pop3c;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -335,7 +335,7 @@ static CURLcode pop3_perform_capa(struct Curl_easy *data,
result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA");
if(!result)
- state(data, POP3_CAPA);
+ pop3_state(data, POP3_CAPA);
return result;
}
@@ -353,7 +353,7 @@ static CURLcode pop3_perform_starttls(struct Curl_easy *data,
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "STLS");
if(!result)
- state(data, POP3_STARTTLS);
+ pop3_state(data, POP3_STARTTLS);
return result;
}
@@ -383,7 +383,7 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
if(!result) {
pop3c->ssldone = ssldone;
if(pop3c->state != POP3_UPGRADETLS)
- state(data, POP3_UPGRADETLS);
+ pop3_state(data, POP3_UPGRADETLS);
if(pop3c->ssldone) {
pop3_to_pop3s(conn);
@@ -408,7 +408,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!data->state.aptr.user) {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -417,7 +417,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "USER %s",
conn->user ? conn->user : "");
if(!result)
- state(data, POP3_USER);
+ pop3_state(data, POP3_USER);
return result;
}
@@ -442,7 +442,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!data->state.aptr.user) {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -468,7 +468,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
if(!result)
- state(data, POP3_APOP);
+ pop3_state(data, POP3_APOP);
return result;
}
@@ -552,7 +552,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
/* Check we have enough data to authenticate with and end the
connect phase if we don't */
if(!Curl_sasl_can_authenticate(&pop3c->sasl, data)) {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -562,7 +562,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
if(!result)
if(progress == SASL_INPROGRESS)
- state(data, POP3_AUTH);
+ pop3_state(data, POP3_AUTH);
}
if(!result && progress == SASL_IDLE) {
@@ -620,7 +620,7 @@ static CURLcode pop3_perform_command(struct Curl_easy *data)
pop3->custom : command));
if(!result)
- state(data, POP3_COMMAND);
+ pop3_state(data, POP3_COMMAND);
return result;
}
@@ -638,7 +638,7 @@ static CURLcode pop3_perform_quit(struct Curl_easy *data,
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "QUIT");
if(!result)
- state(data, POP3_QUIT);
+ pop3_state(data, POP3_QUIT);
return result;
}
@@ -831,7 +831,7 @@ static CURLcode pop3_state_auth_resp(struct Curl_easy *data,
if(!result)
switch(progress) {
case SASL_DONE:
- state(data, POP3_STOP); /* Authenticated */
+ pop3_state(data, POP3_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
#ifndef CURL_DISABLE_CRYPTO_AUTH
@@ -869,7 +869,7 @@ static CURLcode pop3_state_apop_resp(struct Curl_easy *data, int pop3code,
}
else
/* End of connect phase */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -892,7 +892,7 @@ static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "PASS %s",
conn->passwd ? conn->passwd : "");
if(!result)
- state(data, POP3_PASS);
+ pop3_state(data, POP3_PASS);
return result;
}
@@ -910,7 +910,7 @@ static CURLcode pop3_state_pass_resp(struct Curl_easy *data, int pop3code,
}
else
/* End of connect phase */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -929,7 +929,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
(void)instate; /* no use for this yet */
if(pop3code != '+') {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return CURLE_WEIRD_SERVER_REPLY;
}
@@ -967,7 +967,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
}
/* End of DO phase */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -1037,12 +1037,12 @@ static CURLcode pop3_statemachine(struct Curl_easy *data,
break;
case POP3_QUIT:
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
break;
default:
/* internal error */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
break;
}
} while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
@@ -1143,7 +1143,7 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done)
return result;
/* Start off waiting for the server greeting response */
- state(data, POP3_SERVERGREET);
+ pop3_state(data, POP3_SERVERGREET);
result = pop3_multi_statemach(data, done);
diff --git a/Utilities/cmcurl/lib/sendf.c b/Utilities/cmcurl/lib/sendf.c
index 81ee864..437fa74 100644
--- a/Utilities/cmcurl/lib/sendf.c
+++ b/Utilities/cmcurl/lib/sendf.c
@@ -419,8 +419,6 @@ CURLcode Curl_read(struct Curl_easy *data, /* transfer */
*n += nread;
result = CURLE_OK;
out:
- /* DEBUGF(infof(data, "Curl_read(handle=%p) -> %d, nread=%ld",
- data, result, nread)); */
return result;
}
diff --git a/Utilities/cmcurl/lib/setopt.c b/Utilities/cmcurl/lib/setopt.c
index 0c3b963..b05162a 100644
--- a/Utilities/cmcurl/lib/setopt.c
+++ b/Utilities/cmcurl/lib/setopt.c
@@ -1867,6 +1867,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
*/
data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
+ case CURLOPT_HAPROXY_CLIENT_IP:
+ /*
+ * Set the client IP to send through HAProxy PROXY protocol
+ */
+ result = Curl_setstropt(&data->set.str[STRING_HAPROXY_CLIENT_IP],
+ va_arg(param, char *));
+ /* We enable implicitly the HAProxy protocol if we use this flag. */
+ data->set.haproxyprotocol = TRUE;
+ break;
#endif
case CURLOPT_INTERFACE:
/*
@@ -2711,7 +2720,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
/* Set the list of mail recipients */
data->set.mail_rcpt = va_arg(param, struct curl_slist *);
break;
- case CURLOPT_MAIL_RCPT_ALLLOWFAILS:
+ case CURLOPT_MAIL_RCPT_ALLOWFAILS:
/* allow RCPT TO command to fail for some recipients */
data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
index d682221..bc4e883 100644
--- a/Utilities/cmcurl/lib/smb.c
+++ b/Utilities/cmcurl/lib/smb.c
@@ -27,8 +27,6 @@
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
-#define BUILDING_CURL_SMB_C
-
#ifdef WIN32
#define getpid GetCurrentProcessId
#endif
@@ -50,6 +48,199 @@
#include "curl_memory.h"
#include "memdebug.h"
+/*
+ * Definitions for SMB protocol data structures
+ */
+#if defined(_MSC_VER) || defined(__ILEC400__)
+# define PACK
+# pragma pack(push)
+# pragma pack(1)
+#elif defined(__GNUC__)
+# define PACK __attribute__((packed))
+#else
+# define PACK
+#endif
+
+#define SMB_COM_CLOSE 0x04
+#define SMB_COM_READ_ANDX 0x2e
+#define SMB_COM_WRITE_ANDX 0x2f
+#define SMB_COM_TREE_DISCONNECT 0x71
+#define SMB_COM_NEGOTIATE 0x72
+#define SMB_COM_SETUP_ANDX 0x73
+#define SMB_COM_TREE_CONNECT_ANDX 0x75
+#define SMB_COM_NT_CREATE_ANDX 0xa2
+#define SMB_COM_NO_ANDX_COMMAND 0xff
+
+#define SMB_WC_CLOSE 0x03
+#define SMB_WC_READ_ANDX 0x0c
+#define SMB_WC_WRITE_ANDX 0x0e
+#define SMB_WC_SETUP_ANDX 0x0d
+#define SMB_WC_TREE_CONNECT_ANDX 0x04
+#define SMB_WC_NT_CREATE_ANDX 0x18
+
+#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
+#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
+#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
+#define SMB_FLAGS2_IS_LONG_NAME 0x0040
+#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
+
+#define SMB_CAP_LARGE_FILES 0x08
+#define SMB_GENERIC_WRITE 0x40000000
+#define SMB_GENERIC_READ 0x80000000
+#define SMB_FILE_SHARE_ALL 0x07
+#define SMB_FILE_OPEN 0x01
+#define SMB_FILE_OVERWRITE_IF 0x05
+
+#define SMB_ERR_NOACCESS 0x00050001
+
+struct smb_header {
+ unsigned char nbt_type;
+ unsigned char nbt_flags;
+ unsigned short nbt_length;
+ unsigned char magic[4];
+ unsigned char command;
+ unsigned int status;
+ unsigned char flags;
+ unsigned short flags2;
+ unsigned short pid_high;
+ unsigned char signature[8];
+ unsigned short pad;
+ unsigned short tid;
+ unsigned short pid;
+ unsigned short uid;
+ unsigned short mid;
+} PACK;
+
+struct smb_negotiate_response {
+ struct smb_header h;
+ unsigned char word_count;
+ unsigned short dialect_index;
+ unsigned char security_mode;
+ unsigned short max_mpx_count;
+ unsigned short max_number_vcs;
+ unsigned int max_buffer_size;
+ unsigned int max_raw_size;
+ unsigned int session_key;
+ unsigned int capabilities;
+ unsigned int system_time_low;
+ unsigned int system_time_high;
+ unsigned short server_time_zone;
+ unsigned char encryption_key_length;
+ unsigned short byte_count;
+ char bytes[1];
+} PACK;
+
+struct andx {
+ unsigned char command;
+ unsigned char pad;
+ unsigned short offset;
+} PACK;
+
+struct smb_setup {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short max_buffer_size;
+ unsigned short max_mpx_count;
+ unsigned short vc_number;
+ unsigned int session_key;
+ unsigned short lengths[2];
+ unsigned int pad;
+ unsigned int capabilities;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_tree_connect {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short flags;
+ unsigned short pw_len;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_nt_create {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned char pad;
+ unsigned short name_length;
+ unsigned int flags;
+ unsigned int root_fid;
+ unsigned int access;
+ curl_off_t allocation_size;
+ unsigned int ext_file_attributes;
+ unsigned int share_access;
+ unsigned int create_disposition;
+ unsigned int create_options;
+ unsigned int impersonation_level;
+ unsigned char security_flags;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_nt_create_response {
+ struct smb_header h;
+ unsigned char word_count;
+ struct andx andx;
+ unsigned char op_lock_level;
+ unsigned short fid;
+ unsigned int create_disposition;
+
+ curl_off_t create_time;
+ curl_off_t last_access_time;
+ curl_off_t last_write_time;
+ curl_off_t last_change_time;
+ unsigned int ext_file_attributes;
+ curl_off_t allocation_size;
+ curl_off_t end_of_file;
+} PACK;
+
+struct smb_read {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short fid;
+ unsigned int offset;
+ unsigned short max_bytes;
+ unsigned short min_bytes;
+ unsigned int timeout;
+ unsigned short remaining;
+ unsigned int offset_high;
+ unsigned short byte_count;
+} PACK;
+
+struct smb_write {
+ struct smb_header h;
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short fid;
+ unsigned int offset;
+ unsigned int timeout;
+ unsigned short write_mode;
+ unsigned short remaining;
+ unsigned short pad;
+ unsigned short data_length;
+ unsigned short data_offset;
+ unsigned int offset_high;
+ unsigned short byte_count;
+ unsigned char pad2;
+} PACK;
+
+struct smb_close {
+ unsigned char word_count;
+ unsigned short fid;
+ unsigned int last_mtime;
+ unsigned short byte_count;
+} PACK;
+
+struct smb_tree_disconnect {
+ unsigned char word_count;
+ unsigned short byte_count;
+} PACK;
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+# pragma pack(pop)
+#endif
+
/* Local API functions */
static CURLcode smb_setup_connection(struct Curl_easy *data,
struct connectdata *conn);
diff --git a/Utilities/cmcurl/lib/smb.h b/Utilities/cmcurl/lib/smb.h
index c35f3e9..437f4a5 100644
--- a/Utilities/cmcurl/lib/smb.h
+++ b/Utilities/cmcurl/lib/smb.h
@@ -48,203 +48,6 @@ struct smb_conn {
size_t got;
};
-/*
- * Definitions for SMB protocol data structures
- */
-#ifdef BUILDING_CURL_SMB_C
-
-#if defined(_MSC_VER) || defined(__ILEC400__)
-# define PACK
-# pragma pack(push)
-# pragma pack(1)
-#elif defined(__GNUC__)
-# define PACK __attribute__((packed))
-#else
-# define PACK
-#endif
-
-#define SMB_COM_CLOSE 0x04
-#define SMB_COM_READ_ANDX 0x2e
-#define SMB_COM_WRITE_ANDX 0x2f
-#define SMB_COM_TREE_DISCONNECT 0x71
-#define SMB_COM_NEGOTIATE 0x72
-#define SMB_COM_SETUP_ANDX 0x73
-#define SMB_COM_TREE_CONNECT_ANDX 0x75
-#define SMB_COM_NT_CREATE_ANDX 0xa2
-#define SMB_COM_NO_ANDX_COMMAND 0xff
-
-#define SMB_WC_CLOSE 0x03
-#define SMB_WC_READ_ANDX 0x0c
-#define SMB_WC_WRITE_ANDX 0x0e
-#define SMB_WC_SETUP_ANDX 0x0d
-#define SMB_WC_TREE_CONNECT_ANDX 0x04
-#define SMB_WC_NT_CREATE_ANDX 0x18
-
-#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
-#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
-#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
-#define SMB_FLAGS2_IS_LONG_NAME 0x0040
-#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
-
-#define SMB_CAP_LARGE_FILES 0x08
-#define SMB_GENERIC_WRITE 0x40000000
-#define SMB_GENERIC_READ 0x80000000
-#define SMB_FILE_SHARE_ALL 0x07
-#define SMB_FILE_OPEN 0x01
-#define SMB_FILE_OVERWRITE_IF 0x05
-
-#define SMB_ERR_NOACCESS 0x00050001
-
-struct smb_header {
- unsigned char nbt_type;
- unsigned char nbt_flags;
- unsigned short nbt_length;
- unsigned char magic[4];
- unsigned char command;
- unsigned int status;
- unsigned char flags;
- unsigned short flags2;
- unsigned short pid_high;
- unsigned char signature[8];
- unsigned short pad;
- unsigned short tid;
- unsigned short pid;
- unsigned short uid;
- unsigned short mid;
-} PACK;
-
-struct smb_negotiate_response {
- struct smb_header h;
- unsigned char word_count;
- unsigned short dialect_index;
- unsigned char security_mode;
- unsigned short max_mpx_count;
- unsigned short max_number_vcs;
- unsigned int max_buffer_size;
- unsigned int max_raw_size;
- unsigned int session_key;
- unsigned int capabilities;
- unsigned int system_time_low;
- unsigned int system_time_high;
- unsigned short server_time_zone;
- unsigned char encryption_key_length;
- unsigned short byte_count;
- char bytes[1];
-} PACK;
-
-struct andx {
- unsigned char command;
- unsigned char pad;
- unsigned short offset;
-} PACK;
-
-struct smb_setup {
- unsigned char word_count;
- struct andx andx;
- unsigned short max_buffer_size;
- unsigned short max_mpx_count;
- unsigned short vc_number;
- unsigned int session_key;
- unsigned short lengths[2];
- unsigned int pad;
- unsigned int capabilities;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_tree_connect {
- unsigned char word_count;
- struct andx andx;
- unsigned short flags;
- unsigned short pw_len;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_nt_create {
- unsigned char word_count;
- struct andx andx;
- unsigned char pad;
- unsigned short name_length;
- unsigned int flags;
- unsigned int root_fid;
- unsigned int access;
- curl_off_t allocation_size;
- unsigned int ext_file_attributes;
- unsigned int share_access;
- unsigned int create_disposition;
- unsigned int create_options;
- unsigned int impersonation_level;
- unsigned char security_flags;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_nt_create_response {
- struct smb_header h;
- unsigned char word_count;
- struct andx andx;
- unsigned char op_lock_level;
- unsigned short fid;
- unsigned int create_disposition;
-
- curl_off_t create_time;
- curl_off_t last_access_time;
- curl_off_t last_write_time;
- curl_off_t last_change_time;
- unsigned int ext_file_attributes;
- curl_off_t allocation_size;
- curl_off_t end_of_file;
-} PACK;
-
-struct smb_read {
- unsigned char word_count;
- struct andx andx;
- unsigned short fid;
- unsigned int offset;
- unsigned short max_bytes;
- unsigned short min_bytes;
- unsigned int timeout;
- unsigned short remaining;
- unsigned int offset_high;
- unsigned short byte_count;
-} PACK;
-
-struct smb_write {
- struct smb_header h;
- unsigned char word_count;
- struct andx andx;
- unsigned short fid;
- unsigned int offset;
- unsigned int timeout;
- unsigned short write_mode;
- unsigned short remaining;
- unsigned short pad;
- unsigned short data_length;
- unsigned short data_offset;
- unsigned int offset_high;
- unsigned short byte_count;
- unsigned char pad2;
-} PACK;
-
-struct smb_close {
- unsigned char word_count;
- unsigned short fid;
- unsigned int last_mtime;
- unsigned short byte_count;
-} PACK;
-
-struct smb_tree_disconnect {
- unsigned char word_count;
- unsigned short byte_count;
-} PACK;
-
-#if defined(_MSC_VER) || defined(__ILEC400__)
-# pragma pack(pop)
-#endif
-
-#endif /* BUILDING_CURL_SMB_C */
-
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
(SIZEOF_CURL_OFF_T > 4)
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
index c182cac..afcdd10 100644
--- a/Utilities/cmcurl/lib/smtp.c
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -281,11 +281,11 @@ static CURLcode smtp_get_message(struct Curl_easy *data, struct bufref *out)
/***********************************************************************
*
- * state()
+ * smtp_state()
*
* This is the ONLY way to change SMTP state!
*/
-static void state(struct Curl_easy *data, smtpstate newstate)
+static void smtp_state(struct Curl_easy *data, smtpstate newstate)
{
struct smtp_conn *smtpc = &data->conn->proto.smtpc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -338,7 +338,7 @@ static CURLcode smtp_perform_ehlo(struct Curl_easy *data)
result = Curl_pp_sendf(data, &smtpc->pp, "EHLO %s", smtpc->domain);
if(!result)
- state(data, SMTP_EHLO);
+ smtp_state(data, SMTP_EHLO);
return result;
}
@@ -362,7 +362,7 @@ static CURLcode smtp_perform_helo(struct Curl_easy *data,
result = Curl_pp_sendf(data, &smtpc->pp, "HELO %s", smtpc->domain);
if(!result)
- state(data, SMTP_HELO);
+ smtp_state(data, SMTP_HELO);
return result;
}
@@ -381,7 +381,7 @@ static CURLcode smtp_perform_starttls(struct Curl_easy *data,
"%s", "STARTTLS");
if(!result)
- state(data, SMTP_STARTTLS);
+ smtp_state(data, SMTP_STARTTLS);
return result;
}
@@ -410,7 +410,7 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
if(!result) {
smtpc->ssldone = ssldone;
if(smtpc->state != SMTP_UPGRADETLS)
- state(data, SMTP_UPGRADETLS);
+ smtp_state(data, SMTP_UPGRADETLS);
if(smtpc->ssldone) {
smtp_to_smtps(conn);
@@ -499,7 +499,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
server supports authentication, and end the connect phase if not */
if(!smtpc->auth_supported ||
!Curl_sasl_can_authenticate(&smtpc->sasl, data)) {
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
return result;
}
@@ -508,7 +508,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
if(!result) {
if(progress == SASL_INPROGRESS)
- state(data, SMTP_AUTH);
+ smtp_state(data, SMTP_AUTH);
else {
/* Other mechanisms not supported */
infof(data, "No known authentication mechanisms supported");
@@ -586,7 +586,7 @@ static CURLcode smtp_perform_command(struct Curl_easy *data)
smtp->custom : "HELP");
if(!result)
- state(data, SMTP_COMMAND);
+ smtp_state(data, SMTP_COMMAND);
return result;
}
@@ -771,7 +771,7 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data)
free(size);
if(!result)
- state(data, SMTP_MAIL);
+ smtp_state(data, SMTP_MAIL);
return result;
}
@@ -812,7 +812,7 @@ static CURLcode smtp_perform_rcpt_to(struct Curl_easy *data)
free(address);
if(!result)
- state(data, SMTP_RCPT);
+ smtp_state(data, SMTP_RCPT);
return result;
}
@@ -830,7 +830,7 @@ static CURLcode smtp_perform_quit(struct Curl_easy *data,
CURLcode result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "QUIT");
if(!result)
- state(data, SMTP_QUIT);
+ smtp_state(data, SMTP_QUIT);
return result;
}
@@ -996,7 +996,7 @@ static CURLcode smtp_state_helo_resp(struct Curl_easy *data, int smtpcode,
}
else
/* End of connect phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
return result;
}
@@ -1017,7 +1017,7 @@ static CURLcode smtp_state_auth_resp(struct Curl_easy *data,
if(!result)
switch(progress) {
case SASL_DONE:
- state(data, SMTP_STOP); /* Authenticated */
+ smtp_state(data, SMTP_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
failf(data, "Authentication cancelled");
@@ -1064,11 +1064,11 @@ static CURLcode smtp_state_command_resp(struct Curl_easy *data, int smtpcode,
}
else
/* End of DO phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
}
else
/* End of DO phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
}
}
@@ -1145,7 +1145,7 @@ static CURLcode smtp_state_rcpt_resp(struct Curl_easy *data,
result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "DATA");
if(!result)
- state(data, SMTP_DATA);
+ smtp_state(data, SMTP_DATA);
}
}
}
@@ -1172,7 +1172,7 @@ static CURLcode smtp_state_data_resp(struct Curl_easy *data, int smtpcode,
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
}
return result;
@@ -1192,7 +1192,7 @@ static CURLcode smtp_state_postdata_resp(struct Curl_easy *data,
result = CURLE_WEIRD_SERVER_REPLY;
/* End of DONE phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
return result;
}
@@ -1274,7 +1274,7 @@ static CURLcode smtp_statemachine(struct Curl_easy *data,
/* fallthrough, just stop! */
default:
/* internal error */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
break;
}
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
@@ -1379,7 +1379,7 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done)
return result;
/* Start off waiting for the server greeting response */
- state(data, SMTP_SERVERGREET);
+ smtp_state(data, SMTP_SERVERGREET);
result = smtp_multi_statemach(data, done);
@@ -1461,7 +1461,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
free(eob);
}
- state(data, SMTP_POSTDATA);
+ smtp_state(data, SMTP_POSTDATA);
/* Run the state-machine */
result = smtp_block_statemach(data, conn, FALSE);
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c
index 53d798a..c492d66 100644
--- a/Utilities/cmcurl/lib/socks.c
+++ b/Utilities/cmcurl/lib/socks.c
@@ -161,7 +161,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data,
enum connect_t oldstate = sx->state;
#ifdef DEBUG_AND_VERBOSE
/* synced with the state list in urldata.h */
- static const char * const statename[] = {
+ static const char * const socks_statename[] = {
"INIT",
"SOCKS_INIT",
"SOCKS_SEND",
@@ -193,7 +193,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data,
#ifdef DEBUG_AND_VERBOSE
infof(data,
"SXSTATE: %s => %s; line %d",
- statename[oldstate], statename[sx->state],
+ socks_statename[oldstate], socks_statename[sx->state],
lineno);
#endif
}
@@ -567,7 +567,6 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
*/
struct connectdata *conn = cf->conn;
unsigned char *socksreq = (unsigned char *)data->state.buffer;
- char dest[256] = "unknown"; /* printable hostname:port */
int idx;
CURLcode result;
CURLproxycode presult;
@@ -820,8 +819,8 @@ CONNECT_REQ_INIT:
/* FALLTHROUGH */
CONNECT_RESOLVED:
case CONNECT_RESOLVED: {
+ char dest[MAX_IPADR_LEN] = "unknown"; /* printable address */
struct Curl_addrinfo *hp = NULL;
- size_t destlen;
if(dns)
hp = dns->addr;
if(!hp) {
@@ -831,8 +830,6 @@ CONNECT_RESOLVED:
}
Curl_printable_address(hp, dest, sizeof(dest));
- destlen = strlen(dest);
- msnprintf(dest + destlen, sizeof(dest) - destlen, ":%d", sx->remote_port);
len = 0;
socksreq[len++] = 5; /* version (SOCKS5) */
@@ -848,7 +845,8 @@ CONNECT_RESOLVED:
socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
}
- infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)", dest);
+ infof(data, "SOCKS5 connect to %s:%d (locally resolved)", dest,
+ sx->remote_port);
}
#ifdef ENABLE_IPV6
else if(hp->ai_family == AF_INET6) {
@@ -862,7 +860,8 @@ CONNECT_RESOLVED:
((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
}
- infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)", dest);
+ infof(data, "SOCKS5 connect to [%s]:%d (locally resolved)", dest,
+ sx->remote_port);
}
#endif
else {
@@ -1115,7 +1114,7 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf,
return CURLE_OK;
}
- result = cf->next->cft->connect(cf->next, data, blocking, done);
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
if(result || !*done)
return result;
@@ -1193,7 +1192,7 @@ static void socks_proxy_cf_close(struct Curl_cfilter *cf,
DEBUGASSERT(cf->next);
cf->connected = FALSE;
socks_proxy_cf_free(cf);
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
}
static void socks_proxy_cf_destroy(struct Curl_cfilter *cf,
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
index 643e43d..1d7a592 100644
--- a/Utilities/cmcurl/lib/telnet.c
+++ b/Utilities/cmcurl/lib/telnet.c
@@ -1534,7 +1534,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
}
while(keepon) {
- DEBUGF(infof(data, "telnet_do(handle=%p), poll %d fds", data, poll_cnt));
+ DEBUGF(infof(data, "telnet_do, poll %d fds", poll_cnt));
switch(Curl_poll(pfd, poll_cnt, interval_ms)) {
case -1: /* error, stop reading */
keepon = FALSE;
@@ -1558,8 +1558,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
* in a clean way? Seems to be timing related, happens more
* on slow debug build */
if(data->state.os_errno == ECONNRESET) {
- DEBUGF(infof(data, "telnet_do(handle=%p), unexpected ECONNRESET"
- " on recv", data));
+ DEBUGF(infof(data, "telnet_do, unexpected ECONNRESET on recv"));
}
break;
}
diff --git a/Utilities/cmcurl/lib/timeval.c b/Utilities/cmcurl/lib/timeval.c
index dca1c6f..2de79be 100644
--- a/Utilities/cmcurl/lib/timeval.c
+++ b/Utilities/cmcurl/lib/timeval.c
@@ -58,7 +58,8 @@ struct curltime Curl_now(void)
return now;
}
-#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) || \
+ defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
struct curltime Curl_now(void)
{
@@ -87,6 +88,19 @@ struct curltime Curl_now(void)
have_clock_gettime = TRUE;
#endif
+#ifdef HAVE_CLOCK_GETTIME_MONOTONIC_RAW
+ if(
+#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
+ (HAVE_BUILTIN_AVAILABLE == 1)
+ have_clock_gettime &&
+#endif
+ (0 == clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow))) {
+ cnow.tv_sec = tsnow.tv_sec;
+ cnow.tv_usec = (unsigned int)(tsnow.tv_nsec / 1000);
+ }
+ else
+#endif
+
if(
#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
(HAVE_BUILTIN_AVAILABLE == 1)
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index d2ff0c2..b678004 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -428,6 +428,8 @@ static CURLcode readwrite_data(struct Curl_easy *data,
size_t excess = 0; /* excess bytes read */
bool readmore = FALSE; /* used by RTP to signal for more data */
int maxloops = 100;
+ curl_off_t max_recv = data->set.max_recv_speed?
+ data->set.max_recv_speed : CURL_OFF_T_MAX;
char *buf = data->state.buffer;
DEBUGASSERT(buf);
@@ -472,7 +474,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
else {
/* read nothing but since we wanted nothing we consider this an OK
situation to proceed from */
- DEBUGF(infof(data, DMSG(data, "readwrite_data: we're done")));
+ DEBUGF(infof(data, "readwrite_data: we're done"));
nread = 0;
}
@@ -666,6 +668,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
}
k->bytecount += nread;
+ max_recv -= nread;
Curl_pgrsSetDownloadCounter(data, k->bytecount);
@@ -749,9 +752,9 @@ static CURLcode readwrite_data(struct Curl_easy *data,
break;
}
- } while(data_pending(data) && maxloops--);
+ } while((max_recv > 0) && data_pending(data) && maxloops--);
- if(maxloops <= 0) {
+ if(maxloops <= 0 || max_recv <= 0) {
/* we mark it as read-again-please */
data->state.dselect_bits = CURL_CSELECT_IN;
*comeback = TRUE;
@@ -768,7 +771,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
out:
if(result)
- DEBUGF(infof(data, DMSG(data, "readwrite_data() -> %d"), result));
+ DEBUGF(infof(data, "readwrite_data() -> %d", result));
return result;
}
@@ -1233,7 +1236,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
*done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE;
out:
if(result)
- DEBUGF(infof(data, DMSG(data, "Curl_readwrite() -> %d"), result));
+ DEBUGF(infof(data, "Curl_readwrite() -> %d", result));
return result;
}
@@ -1551,10 +1554,11 @@ CURLcode Curl_follow(struct Curl_easy *data,
if((type != FOLLOW_RETRY) &&
(data->req.httpcode != 401) && (data->req.httpcode != 407) &&
- Curl_is_absolute_url(newurl, NULL, 0, FALSE))
+ Curl_is_absolute_url(newurl, NULL, 0, FALSE)) {
/* If this is not redirect due to a 401 or 407 response and an absolute
URL: don't allow a custom port number */
disallowport = TRUE;
+ }
DEBUGASSERT(data->state.uh);
uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 0fb6268..e3e7f45 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -659,6 +659,9 @@ CURLcode Curl_open(struct Curl_easy **curl)
/* most recent connection is not yet defined */
data->state.lastconnect_id = -1;
+ data->state.recent_conn_id = -1;
+ /* and not assigned an id yet */
+ data->id = -1;
data->progress.flags |= PGRS_HIDE;
data->state.current_speed = -1; /* init to negative == impossible */
@@ -680,7 +683,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
static void conn_shutdown(struct Curl_easy *data)
{
DEBUGASSERT(data);
- infof(data, "Closing connection %ld", data->conn->connection_id);
+ infof(data, "Closing connection");
/* possible left-overs from the async name resolvers */
Curl_resolver_cancel(data);
@@ -763,7 +766,8 @@ void Curl_disconnect(struct Curl_easy *data,
/* the transfer must be detached from the connection */
DEBUGASSERT(!data->conn);
- DEBUGF(infof(data, "Curl_disconnect(conn #%ld, dead=%d)",
+ DEBUGF(infof(data, "Curl_disconnect(conn #%"
+ CURL_FORMAT_CURL_OFF_T ", dead=%d)",
conn->connection_id, dead_connection));
/*
* If this connection isn't marked to force-close, leave it open if there
@@ -937,6 +941,7 @@ static bool extract_if_dead(struct connectdata *conn,
else {
bool input_pending;
+ Curl_attach_connection(data, conn);
dead = !Curl_conn_is_alive(data, conn, &input_pending);
if(input_pending) {
/* For reuse, we want a "clean" connection state. The includes
@@ -949,10 +954,12 @@ static bool extract_if_dead(struct connectdata *conn,
*/
dead = TRUE;
}
+ Curl_detach_connection(data);
}
if(dead) {
- infof(data, "Connection %ld seems to be dead", conn->connection_id);
+ infof(data, "Connection %" CURL_FORMAT_CURL_OFF_T " seems to be dead",
+ conn->connection_id);
Curl_conncache_remove_conn(data, conn, FALSE);
return TRUE;
}
@@ -1147,8 +1154,8 @@ ConnectionExists(struct Curl_easy *data,
/* primary_ip[0] is NUL only if the resolving of the name hasn't
completed yet and until then we don't re-use this connection */
if(!check->primary_ip[0]) {
- infof(data,
- "Connection #%ld is still name resolving, can't reuse",
+ infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T " is still "
+ "name resolving, can't reuse",
check->connection_id);
continue;
}
@@ -1158,8 +1165,8 @@ ConnectionExists(struct Curl_easy *data,
if(!Curl_conn_is_connected(check, FIRSTSOCKET)) {
foundPendingCandidate = TRUE;
/* Don't pick a connection that hasn't connected yet */
- infof(data, "Connection #%ld isn't open enough, can't reuse",
- check->connection_id);
+ infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T
+ "isn't open enough, can't reuse", check->connection_id);
continue;
}
@@ -1335,8 +1342,8 @@ ConnectionExists(struct Curl_easy *data,
if(!Curl_ssl_config_matches(&needle->ssl_config,
&check->ssl_config)) {
DEBUGF(infof(data,
- "Connection #%ld has different SSL parameters, "
- "can't reuse",
+ "Connection #%" CURL_FORMAT_CURL_OFF_T
+ " has different SSL parameters, can't reuse",
check->connection_id));
continue;
}
@@ -1477,14 +1484,14 @@ void Curl_verboseconnect(struct Curl_easy *data,
struct connectdata *conn)
{
if(data->set.verbose)
- infof(data, "Connected to %s (%s) port %u (#%ld)",
+ infof(data, "Connected to %s (%s) port %u",
#ifndef CURL_DISABLE_PROXY
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
#endif
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname,
- conn->primary_ip, conn->port, conn->connection_id);
+ conn->primary_ip, conn->port);
}
#endif
@@ -1857,7 +1864,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
* User name and password set with their own options override the
* credentials possibly set in the URL.
*/
- if(!data->state.aptr.passwd) {
+ if(!data->set.str[STRING_PASSWORD]) {
uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
if(!uc) {
char *decoded;
@@ -3678,15 +3685,14 @@ static CURLcode create_conn(struct Curl_easy *data,
*in_connect = conn;
#ifndef CURL_DISABLE_PROXY
- infof(data, "Re-using existing connection #%ld with %s %s",
- conn->connection_id,
+ infof(data, "Re-using existing connection with %s %s",
conn->bits.proxy?"proxy":"host",
conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
conn->host.dispname);
#else
- infof(data, "Re-using existing connection #%ld with host %s",
- conn->connection_id, conn->host.dispname);
+ infof(data, "Re-using existing connection with host %s",
+ conn->host.dispname);
#endif
}
else {
diff --git a/Utilities/cmcurl/lib/urlapi.c b/Utilities/cmcurl/lib/urlapi.c
index a4530f9..e0c5476 100644
--- a/Utilities/cmcurl/lib/urlapi.c
+++ b/Utilities/cmcurl/lib/urlapi.c
@@ -201,7 +201,7 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url,
size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
bool guess_scheme)
{
- int i;
+ int i = 0;
DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
(void)buflen; /* only used in debug-builds */
if(buf)
@@ -210,17 +210,18 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url))
return 0;
#endif
- for(i = 0; i < MAX_SCHEME_LEN; ++i) {
- char s = url[i];
- if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) {
- /* RFC 3986 3.1 explains:
- scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
- */
- }
- else {
- break;
+ if(ISALPHA(url[0]))
+ for(i = 1; i < MAX_SCHEME_LEN; ++i) {
+ char s = url[i];
+ if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) {
+ /* RFC 3986 3.1 explains:
+ scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ */
+ }
+ else {
+ break;
+ }
}
- }
if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) {
/* If this does not guess scheme, the scheme always ends with the colon so
that this also detects data: URLs etc. In guessing mode, data: could
@@ -1546,7 +1547,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
}
}
- url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
scheme,
u->user ? u->user : "",
u->password ? ":": "",
@@ -1557,7 +1558,6 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
allochost ? allochost : u->host,
port ? ":": "",
port ? port : "",
- (u->path && (u->path[0] != '/')) ? "/": "",
u->path ? u->path : "/",
(u->query && u->query[0]) ? "?": "",
(u->query && u->query[0]) ? u->query : "",
@@ -1639,8 +1639,10 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0;
bool plusencode = FALSE;
bool urlskipslash = FALSE;
+ bool leadingslash = FALSE;
bool appendquery = FALSE;
bool equalsencode = FALSE;
+ size_t nalloc;
if(!u)
return CURLUE_BAD_HANDLE;
@@ -1693,6 +1695,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_OK;
}
+ nalloc = strlen(part);
+ if(nalloc > CURL_MAX_INPUT_LENGTH)
+ /* excessive input length */
+ return CURLUE_MALFORMED_INPUT;
+
switch(what) {
case CURLUPART_SCHEME: {
size_t plen = strlen(part);
@@ -1706,13 +1713,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_UNSUPPORTED_SCHEME;
storep = &u->scheme;
urlencode = FALSE; /* never */
- /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
- while(plen--) {
- if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.'))
- s++; /* fine */
- else
- return CURLUE_BAD_SCHEME;
+ if(ISALPHA(*s)) {
+ /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
+ while(--plen) {
+ if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.'))
+ s++; /* fine */
+ else
+ return CURLUE_BAD_SCHEME;
+ }
}
+ else
+ return CURLUE_BAD_SCHEME;
break;
}
case CURLUPART_USER:
@@ -1746,6 +1757,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
break;
case CURLUPART_PATH:
urlskipslash = TRUE;
+ leadingslash = TRUE; /* enforce */
storep = &u->path;
break;
case CURLUPART_QUERY:
@@ -1794,18 +1806,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
DEBUGASSERT(storep);
{
- const char *newp = part;
- size_t nalloc = strlen(part);
-
- if(nalloc > CURL_MAX_INPUT_LENGTH)
- /* excessive input length */
- return CURLUE_MALFORMED_INPUT;
+ const char *newp;
+ struct dynbuf enc;
+ Curl_dyn_init(&enc, nalloc * 3 + 1 + leadingslash);
+ if(leadingslash && (part[0] != '/')) {
+ CURLcode result = Curl_dyn_addn(&enc, "/", 1);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
+ }
if(urlencode) {
const unsigned char *i;
- struct dynbuf enc;
-
- Curl_dyn_init(&enc, nalloc * 3 + 1);
for(i = (const unsigned char *)part; *i; i++) {
CURLcode result;
@@ -1833,14 +1844,13 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_OUT_OF_MEMORY;
}
}
- newp = Curl_dyn_ptr(&enc);
}
else {
char *p;
- newp = strdup(part);
- if(!newp)
+ CURLcode result = Curl_dyn_add(&enc, part);
+ if(result)
return CURLUE_OUT_OF_MEMORY;
- p = (char *)newp;
+ p = Curl_dyn_ptr(&enc);
while(*p) {
/* make sure percent encoded are lower case */
if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) &&
@@ -1853,6 +1863,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
p++;
}
}
+ newp = Curl_dyn_ptr(&enc);
if(appendquery) {
/* Append the 'newp' string onto the old query. Add a '&' separator if
@@ -1861,24 +1872,24 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
size_t querylen = u->query ? strlen(u->query) : 0;
bool addamperand = querylen && (u->query[querylen -1] != '&');
if(querylen) {
- struct dynbuf enc;
- Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+ struct dynbuf qbuf;
+ Curl_dyn_init(&qbuf, CURL_MAX_INPUT_LENGTH);
- if(Curl_dyn_addn(&enc, u->query, querylen)) /* add original query */
+ if(Curl_dyn_addn(&qbuf, u->query, querylen)) /* add original query */
goto nomem;
if(addamperand) {
- if(Curl_dyn_addn(&enc, "&", 1))
+ if(Curl_dyn_addn(&qbuf, "&", 1))
goto nomem;
}
- if(Curl_dyn_add(&enc, newp))
+ if(Curl_dyn_add(&qbuf, newp))
goto nomem;
- free((char *)newp);
+ Curl_dyn_free(&enc);
free(*storep);
- *storep = Curl_dyn_ptr(&enc);
+ *storep = Curl_dyn_ptr(&qbuf);
return CURLUE_OK;
nomem:
- free((char *)newp);
+ Curl_dyn_free(&enc);
return CURLUE_OUT_OF_MEMORY;
}
}
@@ -1890,7 +1901,7 @@ nomem:
}
else {
if(!n || hostname_check(u, (char *)newp, n)) {
- free((char *)newp);
+ Curl_dyn_free(&enc);
return CURLUE_BAD_HOSTNAME;
}
}
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index f02e665..c45913b 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -882,8 +882,8 @@ struct connectdata {
#define CONN_INUSE(c) ((c)->easyq.size)
/**** Fields set when inited and not modified again */
- long connection_id; /* Contains a unique number to make it easier to
- track the connections in the log output */
+ curl_off_t connection_id; /* Contains a unique number to make it easier to
+ track the connections in the log output */
/* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -1294,7 +1294,9 @@ struct UrlState {
/* buffers to store authentication data in, as parsed from input options */
struct curltime keeps_speed; /* for the progress meter really */
- long lastconnect_id; /* The last connection, -1 if undefined */
+ curl_off_t lastconnect_id; /* The last connection, -1 if undefined */
+ curl_off_t recent_conn_id; /* The most recent connection used, might no
+ * longer exist */
struct dynbuf headerb; /* buffer to store headers in */
char *buffer; /* download buffer */
@@ -1563,6 +1565,7 @@ enum dupstring {
STRING_DNS_LOCAL_IP6,
STRING_SSL_EC_CURVES,
STRING_AWS_SIGV4, /* Parameters for V4 signature */
+ STRING_HAPROXY_CLIENT_IP, /* CURLOPT_HAPROXY_CLIENT_IP */
/* -- end of null-terminated strings -- */
@@ -1902,6 +1905,13 @@ struct Curl_easy {
/* First a simple identifier to easier detect if a user mix up this easy
handle with a multi handle. Set this to CURLEASY_MAGIC_NUMBER */
unsigned int magic;
+ /* once an easy handle is tied to a connection cache
+ a non-negative number to distinguish this transfer from
+ other using the same cache. For easier tracking
+ in log output.
+ This may wrap around after LONG_MAX to 0 again, so it
+ has no uniqueness guarantuee for very large processings. */
+ curl_off_t id;
/* first, two fields for the linked list of these */
struct Curl_easy *next;
diff --git a/Utilities/cmcurl/lib/version.c b/Utilities/cmcurl/lib/version.c
index 5800ad3..f99dd38 100644
--- a/Utilities/cmcurl/lib/version.c
+++ b/Utilities/cmcurl/lib/version.c
@@ -300,7 +300,7 @@ char *curl_version(void)
protocol line has its own #if line to make things easier on the eye.
*/
-static const char * const protocols[] = {
+static const char * const supported_protocols[] = {
#ifndef CURL_DISABLE_DICT
"dict",
#endif
@@ -535,7 +535,7 @@ static curl_version_info_data version_info = {
NULL, /* ssl_version */
0, /* ssl_version_num, this is kept at zero */
NULL, /* zlib_version */
- protocols,
+ supported_protocols,
NULL, /* c-ares version */
0, /* c-ares version numerical */
NULL, /* libidn version */
diff --git a/Utilities/cmcurl/lib/vquic/curl_msh3.c b/Utilities/cmcurl/lib/vquic/curl_msh3.c
index 1738867..02b5334 100644
--- a/Utilities/cmcurl/lib/vquic/curl_msh3.c
+++ b/Utilities/cmcurl/lib/vquic/curl_msh3.c
@@ -123,6 +123,7 @@ struct cf_msh3_ctx {
};
/* How to access `call_data` from a cf_msh3 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_msh3_ctx *)(cf)->ctx)->call_data
@@ -172,7 +173,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
msh3_lock_initialize(&stream->recv_lock);
Curl_bufq_init2(&stream->recvbuf, H3_STREAM_CHUNK_SIZE,
H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
- DEBUGF(LOG_CF(data, cf, "data setup (easy %p)", (void *)data));
+ DEBUGF(LOG_CF(data, cf, "data setup"));
return CURLE_OK;
}
@@ -645,7 +646,7 @@ static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data,
}
else {
/* request is open */
- DEBUGF(LOG_CF(data, cf, "req: send %zd body bytes", len));
+ DEBUGF(LOG_CF(data, cf, "req: send %zu body bytes", len));
if(len > 0xFFFFFFFF) {
len = 0xFFFFFFFF;
}
diff --git a/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c b/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c
index 7627940..a430aa1 100644
--- a/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c
+++ b/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c
@@ -33,7 +33,7 @@
#ifdef OPENSSL_IS_BORINGSSL
#include <ngtcp2/ngtcp2_crypto_boringssl.h>
#else
-#include <ngtcp2/ngtcp2_crypto_openssl.h>
+#include <ngtcp2/ngtcp2_crypto_quictls.h>
#endif
#include "vtls/openssl.h"
#elif defined(USE_GNUTLS)
@@ -165,17 +165,19 @@ struct cf_ngtcp2_ctx {
};
/* How to access `call_data` from a cf_ngtcp2 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data
/**
* All about the H3 internals of a stream
*/
-struct stream_ctx {
+struct h3_stream_ctx {
int64_t id; /* HTTP/3 protocol identifier */
struct bufq sendbuf; /* h3 request body */
struct bufq recvbuf; /* h3 response body */
size_t sendbuf_len_in_flight; /* sendbuf amount "in flight" */
+ size_t upload_blocked_len; /* the amount written last and EGAINed */
size_t recv_buf_nonflow; /* buffered bytes, not counting for flow control */
uint64_t error3; /* HTTP/3 stream error code */
curl_off_t upload_left; /* number of request bytes left to upload */
@@ -186,18 +188,18 @@ struct stream_ctx {
bool send_closed; /* stream is local closed */
};
-#define H3_STREAM_CTX(d) ((struct stream_ctx *)(((d) && (d)->req.p.http)? \
- ((struct HTTP *)(d)->req.p.http)->h3_ctx \
- : NULL))
-#define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
-#define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \
- H3_STREAM_CTX(d)->id : -2)
+#define H3_STREAM_CTX(d) ((struct h3_stream_ctx *)(((d) && (d)->req.p.http)? \
+ ((struct HTTP *)(d)->req.p.http)->h3_ctx \
+ : NULL))
+#define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
+#define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \
+ H3_STREAM_CTX(d)->id : -2)
static CURLcode h3_data_setup(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
if(!data || !data->req.p.http) {
failf(data, "initialization failure, transfer not http initialized");
@@ -223,13 +225,13 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
stream->recv_buf_nonflow = 0;
H3_STREAM_LCTX(data) = stream;
- DEBUGF(LOG_CF(data, cf, "data setup (easy %p)", (void *)data));
+ DEBUGF(LOG_CF(data, cf, "data setup"));
return CURLE_OK;
}
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
(void)cf;
if(stream) {
@@ -246,10 +248,37 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
the maximum packet burst to MAX_PKT_BURST packets. */
#define MAX_PKT_BURST 10
-static CURLcode cf_process_ingress(struct Curl_cfilter *cf,
- struct Curl_easy *data);
-static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
- struct Curl_easy *data);
+struct pkt_io_ctx {
+ struct Curl_cfilter *cf;
+ struct Curl_easy *data;
+ ngtcp2_tstamp ts;
+ size_t pkt_count;
+ ngtcp2_path_storage ps;
+};
+
+static ngtcp2_tstamp timestamp(void)
+{
+ struct curltime ct = Curl_now();
+ return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
+}
+
+static void pktx_init(struct pkt_io_ctx *pktx,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ pktx->cf = cf;
+ pktx->data = data;
+ pktx->ts = timestamp();
+ pktx->pkt_count = 0;
+ ngtcp2_path_storage_zero(&pktx->ps);
+}
+
+static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx);
+static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx);
static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
uint64_t datalen, void *user_data,
void *stream_user_data);
@@ -261,12 +290,6 @@ static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
return ctx->qconn;
}
-static ngtcp2_tstamp timestamp(void)
-{
- struct curltime ct = Curl_now();
- return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
-}
-
#ifdef DEBUG_NGTCP2
static void quic_printf(void *user_data, const char *fmt, ...)
{
@@ -300,7 +323,8 @@ static void qlog_callback(void *user_data, uint32_t flags,
}
static void quic_settings(struct cf_ngtcp2_ctx *ctx,
- struct Curl_easy *data)
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
ngtcp2_settings *s = &ctx->settings;
ngtcp2_transport_params *t = &ctx->transport_params;
@@ -314,7 +338,7 @@ static void quic_settings(struct cf_ngtcp2_ctx *ctx,
#endif
(void)data;
- s->initial_ts = timestamp();
+ s->initial_ts = pktx->ts;
s->handshake_timeout = QUIC_HANDSHAKE_TIMEOUT;
s->max_window = 100 * ctx->max_stream_window;
s->max_stream_window = ctx->max_stream_window;
@@ -327,7 +351,7 @@ static void quic_settings(struct cf_ngtcp2_ctx *ctx,
t->initial_max_streams_uni = QUIC_MAX_STREAMS;
t->max_idle_timeout = QUIC_IDLE_TIMEOUT;
if(ctx->qlogfd != -1) {
- s->qlog.write = qlog_callback;
+ s->qlog_write = qlog_callback;
}
}
@@ -383,8 +407,8 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
goto out;
}
#else
- if(ngtcp2_crypto_openssl_configure_client_context(ssl_ctx) != 0) {
- failf(data, "ngtcp2_crypto_openssl_configure_client_context failed");
+ if(ngtcp2_crypto_quictls_configure_client_context(ssl_ctx) != 0) {
+ failf(data, "ngtcp2_crypto_quictls_configure_client_context failed");
goto out;
}
#endif
@@ -686,7 +710,7 @@ static void report_consumed_data(struct Curl_cfilter *cf,
struct Curl_easy *data,
size_t consumed)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
struct cf_ngtcp2_ctx *ctx = cf->ctx;
if(!stream)
@@ -902,13 +926,13 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
return 0;
}
-static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_crypto_level level,
+static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_encryption_level level,
void *user_data)
{
struct Curl_cfilter *cf = user_data;
(void)tconn;
- if(level != NGTCP2_CRYPTO_LEVEL_APPLICATION) {
+ if(level != NGTCP2_ENCRYPTION_LEVEL_1RTT) {
return 0;
}
@@ -962,6 +986,61 @@ static ngtcp2_callbacks ng_callbacks = {
NULL, /* early_data_rejected */
};
+/**
+ * Connection maintenance like timeouts on packet ACKs etc. are done by us, not
+ * the OS like for TCP. POLL events on the socket therefore are not
+ * sufficient.
+ * ngtcp2 tells us when it wants to be invoked again. We handle that via
+ * the `Curl_expire()` mechanisms.
+ */
+static CURLcode check_and_set_expiry(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
+{
+ struct cf_ngtcp2_ctx *ctx = cf->ctx;
+ struct pkt_io_ctx local_pktx;
+ ngtcp2_tstamp expiry;
+
+ if(!pktx) {
+ pktx_init(&local_pktx, cf, data);
+ pktx = &local_pktx;
+ }
+ else {
+ pktx->ts = timestamp();
+ }
+
+ expiry = ngtcp2_conn_get_expiry(ctx->qconn);
+ if(expiry != UINT64_MAX) {
+ if(expiry <= pktx->ts) {
+ CURLcode result;
+ int rv = ngtcp2_conn_handle_expiry(ctx->qconn, pktx->ts);
+ if(rv) {
+ failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
+ ngtcp2_strerror(rv));
+ ngtcp2_ccerr_set_liberr(&ctx->last_error, rv, NULL, 0);
+ return CURLE_SEND_ERROR;
+ }
+ result = cf_progress_ingress(cf, data, pktx);
+ if(result)
+ return result;
+ result = cf_progress_egress(cf, data, pktx);
+ if(result)
+ return result;
+ /* ask again, things might have changed */
+ expiry = ngtcp2_conn_get_expiry(ctx->qconn);
+ }
+
+ if(expiry > pktx->ts) {
+ ngtcp2_duration timeout = expiry - pktx->ts;
+ if(timeout % NGTCP2_MILLISECONDS) {
+ timeout += NGTCP2_MILLISECONDS;
+ }
+ Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
+ }
+ }
+ return CURLE_OK;
+}
+
static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
@@ -969,7 +1048,7 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct SingleRequest *k = &data->req;
int rv = GETSOCK_BLANK;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
struct cf_call_data save;
CF_DATA_SAVE(save, cf, data);
@@ -991,15 +1070,15 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
return rv;
}
-static void drain_stream(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static void h3_drain_stream(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
unsigned char bits;
(void)cf;
bits = CURL_CSELECT_IN;
- if(stream && !stream->send_closed && stream->upload_left)
+ if(stream && stream->upload_left && !stream->send_closed)
bits |= CURL_CSELECT_OUT;
if(data->state.dselect_bits != bits) {
data->state.dselect_bits = bits;
@@ -1013,7 +1092,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
(void)conn;
(void)stream_id;
(void)app_error_code;
@@ -1031,7 +1110,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
stream->reset = TRUE;
stream->send_closed = TRUE;
}
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
return 0;
}
@@ -1045,7 +1124,7 @@ static CURLcode write_resp_raw(struct Curl_cfilter *cf,
const void *mem, size_t memlen,
bool flow)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
CURLcode result = CURLE_OK;
ssize_t nwritten;
@@ -1085,7 +1164,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
(void)stream3_id;
result = write_resp_raw(cf, data, buf, buflen, TRUE);
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
return result? -1 : 0;
}
@@ -1110,7 +1189,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
CURLcode result = CURLE_OK;
(void)conn;
(void)stream_id;
@@ -1130,7 +1209,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
if(stream->status_code / 100 != 1) {
stream->resp_hds_complete = TRUE;
}
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
return 0;
}
@@ -1143,7 +1222,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
CURLcode result = CURLE_OK;
(void)conn;
(void)stream_id;
@@ -1207,7 +1286,8 @@ static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
(void)conn;
(void)stream_user_data;
- rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, stream_id, app_error_code);
+ rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, stream_id,
+ app_error_code);
if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -1225,7 +1305,7 @@ static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id,
(void)conn;
(void)data;
- rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, stream_id,
+ rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, 0, stream_id,
app_error_code);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] reset -> %d", stream_id, rv));
if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
@@ -1249,7 +1329,8 @@ static nghttp3_callbacks ngh3_callbacks = {
cb_h3_stop_sending,
NULL, /* end_stream */
cb_h3_reset_stream,
- NULL /* shutdown */
+ NULL, /* shutdown */
+ NULL /* recv_settings */
};
static int init_ngh3_conn(struct Curl_cfilter *cf)
@@ -1314,7 +1395,7 @@ fail:
static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct stream_ctx *stream,
+ struct h3_stream_ctx *stream,
CURLcode *err)
{
ssize_t nread = -1;
@@ -1364,9 +1445,10 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
ssize_t nread = -1;
struct cf_call_data save;
+ struct pkt_io_ctx pktx;
(void)ctx;
@@ -1377,6 +1459,8 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
DEBUGASSERT(ctx->h3conn);
*err = CURLE_OK;
+ pktx_init(&pktx, cf, data);
+
if(!stream) {
*err = CURLE_RECV_ERROR;
goto out;
@@ -1392,7 +1476,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
report_consumed_data(cf, data, nread);
}
- if(cf_process_ingress(cf, data)) {
+ if(cf_progress_ingress(cf, data, &pktx)) {
*err = CURLE_RECV_ERROR;
nread = -1;
goto out;
@@ -1410,7 +1494,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
}
if(nread > 0) {
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
}
else {
if(stream->closed) {
@@ -1422,10 +1506,17 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
}
out:
- if(cf_flush_egress(cf, data)) {
+ if(cf_progress_egress(cf, data, &pktx)) {
*err = CURLE_SEND_ERROR;
nread = -1;
}
+ else {
+ CURLcode result2 = check_and_set_expiry(cf, data, &pktx);
+ if(result2) {
+ *err = result2;
+ nread = -1;
+ }
+ }
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv(len=%zu) -> %zd, %d",
stream? stream->id : -1, len, nread, *err));
CF_DATA_RESTORE(cf, save);
@@ -1438,7 +1529,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
size_t skiplen;
(void)cf;
@@ -1454,10 +1545,8 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
Curl_bufq_skip(&stream->sendbuf, skiplen);
stream->sendbuf_len_in_flight -= skiplen;
- /* `sendbuf` *might* now have more room. If so, resume this
- * possibly paused stream. And also tell our transfer engine that
- * it may continue KEEP_SEND if told to PAUSE. */
- if(!Curl_bufq_is_full(&stream->sendbuf)) {
+ /* Everything ACKed, we resume upload processing */
+ if(!stream->sendbuf_len_in_flight) {
int rv = nghttp3_conn_resume_stream(conn, stream_id);
if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
@@ -1465,7 +1554,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
if((data->req.keepon & KEEP_SEND_HOLD) &&
(data->req.keepon & KEEP_SEND)) {
data->req.keepon &= ~KEEP_SEND_HOLD;
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] unpausing acks",
stream_id));
}
@@ -1481,7 +1570,7 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
ssize_t nwritten = 0;
size_t nvecs = 0;
(void)cf;
@@ -1530,8 +1619,10 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
}
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] read req body -> "
- "%d vecs%s with %zu (buffered=%zu, left=%zd)", stream->id,
- (int)nvecs, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
+ "%d vecs%s with %zu (buffered=%zu, left=%"
+ CURL_FORMAT_CURL_OFF_T ")",
+ stream->id, (int)nvecs,
+ *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
nwritten, Curl_bufq_len(&stream->sendbuf),
stream->upload_left));
return (nghttp3_ssize)nvecs;
@@ -1547,7 +1638,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
CURLcode *err)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = NULL;
+ struct h3_stream_ctx *stream = NULL;
struct h1_req_parser h1;
struct dynhds h2_headers;
size_t nheader;
@@ -1614,16 +1705,19 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
else
/* data sending without specifying the data amount up front */
stream->upload_left = -1; /* unknown */
- reader.read_data = cb_h3_read_req_body;
- preader = &reader;
break;
default:
/* there is not request body */
stream->upload_left = 0; /* no request body */
- preader = NULL;
break;
}
+ stream->send_closed = (stream->upload_left == 0);
+ if(!stream->send_closed) {
+ reader.read_data = cb_h3_read_req_body;
+ preader = &reader;
+ }
+
rc = nghttp3_conn_submit_request(ctx->h3conn, stream->id,
nva, nheader, preader, data);
if(rc) {
@@ -1642,8 +1736,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
goto out;
}
- infof(data, "Using HTTP/3 Stream ID: %" PRId64 " (easy handle %p)",
- stream->id, (void *)data);
+ infof(data, "Using HTTP/3 Stream ID: %" PRId64, stream->id);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] opened for %s",
stream->id, data->state.url));
@@ -1658,20 +1751,23 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
ssize_t sent = 0;
struct cf_call_data save;
+ struct pkt_io_ctx pktx;
+ CURLcode result;
CF_DATA_SAVE(save, cf, data);
DEBUGASSERT(cf->connected);
DEBUGASSERT(ctx->qconn);
DEBUGASSERT(ctx->h3conn);
+ pktx_init(&pktx, cf, data);
*err = CURLE_OK;
- if(stream && stream->closed) {
- *err = CURLE_HTTP3;
+ result = cf_progress_ingress(cf, data, &pktx);
+ if(result) {
+ *err = result;
sent = -1;
- goto out;
}
if(!stream || stream->id < 0) {
@@ -1681,32 +1777,66 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
goto out;
}
}
+ else if(stream->upload_blocked_len) {
+ /* the data in `buf` has alread been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= stream->upload_blocked_len);
+ if(len < stream->upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happen. We are not prepared to handle that. */
+ failf(data, "HTTP/3 send again with decreased length");
+ *err = CURLE_HTTP3;
+ sent = -1;
+ goto out;
+ }
+ sent = (ssize_t)stream->upload_blocked_len;
+ stream->upload_blocked_len = 0;
+ }
+ else if(stream->closed) {
+ *err = CURLE_HTTP3;
+ sent = -1;
+ goto out;
+ }
else {
sent = Curl_bufq_write(&stream->sendbuf, buf, len, err);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_send, add to "
"sendbuf(len=%zu) -> %zd, %d",
stream->id, len, sent, *err));
if(sent < 0) {
- if(*err == CURLE_AGAIN) {
- /* Can't add more to the send buf, needs to drain first.
- * Pause the sending to avoid a busy loop. */
- data->req.keepon |= KEEP_SEND_HOLD;
- DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] pause send",
- stream->id));
- }
goto out;
}
(void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id);
}
- if(cf_flush_egress(cf, data)) {
- *err = CURLE_SEND_ERROR;
+ result = cf_progress_egress(cf, data, &pktx);
+ if(result) {
+ *err = result;
sent = -1;
- goto out;
+ }
+
+ if(stream && sent > 0 && stream->sendbuf_len_in_flight) {
+ /* We have unacknowledged DATA and cannot report success to our
+ * caller. Instead we EAGAIN and remember how much we have already
+ * "written" into our various internal connection buffers.
+ * We put the stream upload on HOLD, until this gets ACKed. */
+ stream->upload_blocked_len = sent;
+ DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_send(len=%zu), "
+ "%zu bytes in flight -> EGAIN", stream->id, len,
+ stream->sendbuf_len_in_flight));
+ *err = CURLE_AGAIN;
+ sent = -1;
+ data->req.keepon |= KEEP_SEND_HOLD;
}
out:
+ result = check_and_set_expiry(cf, data, &pktx);
+ if(result) {
+ *err = result;
+ sent = -1;
+ }
+ DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_send(len=%zu) -> %zd, %d",
+ stream? stream->id : -1, len, sent, *err));
CF_DATA_RESTORE(cf, save);
return sent;
}
@@ -1763,34 +1893,27 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
return result;
}
-struct recv_ctx {
- struct Curl_cfilter *cf;
- struct Curl_easy *data;
- ngtcp2_tstamp ts;
- size_t pkt_count;
-};
-
static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
struct sockaddr_storage *remote_addr,
socklen_t remote_addrlen, int ecn,
void *userp)
{
- struct recv_ctx *r = userp;
- struct cf_ngtcp2_ctx *ctx = r->cf->ctx;
+ struct pkt_io_ctx *pktx = userp;
+ struct cf_ngtcp2_ctx *ctx = pktx->cf->ctx;
ngtcp2_pkt_info pi;
ngtcp2_path path;
int rv;
- ++r->pkt_count;
+ ++pktx->pkt_count;
ngtcp2_addr_init(&path.local, (struct sockaddr *)&ctx->q.local_addr,
ctx->q.local_addrlen);
ngtcp2_addr_init(&path.remote, (struct sockaddr *)remote_addr,
remote_addrlen);
pi.ecn = (uint32_t)ecn;
- rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, pkt, pktlen, r->ts);
+ rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, pkt, pktlen, pktx->ts);
if(rv) {
- DEBUGF(LOG_CF(r->data, r->cf, "ingress, read_pkt -> %s",
+ DEBUGF(LOG_CF(pktx->data, pktx->cf, "ingress, read_pkt -> %s",
ngtcp2_strerror(rv)));
if(!ctx->last_error.error_code) {
if(rv == NGTCP2_ERR_CRYPTO) {
@@ -1813,41 +1936,40 @@ static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
return CURLE_OK;
}
-static CURLcode cf_process_ingress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct recv_ctx rctx;
+ struct pkt_io_ctx local_pktx;
size_t pkts_chunk = 128, i;
size_t pkts_max = 10 * pkts_chunk;
- CURLcode result;
+ CURLcode result = CURLE_OK;
- rctx.cf = cf;
- rctx.data = data;
- rctx.ts = timestamp();
- rctx.pkt_count = 0;
+ if(!pktx) {
+ pktx_init(&local_pktx, cf, data);
+ pktx = &local_pktx;
+ }
+ else {
+ pktx->ts = timestamp();
+ }
for(i = 0; i < pkts_max; i += pkts_chunk) {
- rctx.pkt_count = 0;
+ pktx->pkt_count = 0;
result = vquic_recv_packets(cf, data, &ctx->q, pkts_chunk,
- recv_pkt, &rctx);
+ recv_pkt, pktx);
if(result) /* error */
break;
- if(rctx.pkt_count < pkts_chunk) /* got less than we could */
+ if(pktx->pkt_count < pkts_chunk) /* got less than we could */
break;
/* give egress a chance before we receive more */
- result = cf_flush_egress(cf, data);
+ result = cf_progress_egress(cf, data, pktx);
+ if(result) /* error */
+ break;
}
return result;
}
-struct read_ctx {
- struct Curl_cfilter *cf;
- struct Curl_easy *data;
- ngtcp2_tstamp ts;
- ngtcp2_path_storage *ps;
-};
-
/**
* Read a network packet to send from ngtcp2 into `buf`.
* Return number of bytes written or -1 with *err set.
@@ -1856,7 +1978,7 @@ static ssize_t read_pkt_to_send(void *userp,
unsigned char *buf, size_t buflen,
CURLcode *err)
{
- struct read_ctx *x = userp;
+ struct pkt_io_ctx *x = userp;
struct cf_ngtcp2_ctx *ctx = x->cf->ctx;
nghttp3_vec vec[16];
nghttp3_ssize veccnt;
@@ -1896,7 +2018,7 @@ static ssize_t read_pkt_to_send(void *userp,
flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
(fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
- n = ngtcp2_conn_writev_stream(ctx->qconn, x->ps? &x->ps->path : NULL,
+ n = ngtcp2_conn_writev_stream(ctx->qconn, &x->ps.path,
NULL, buf, buflen,
&ndatalen, flags, stream_id,
(const ngtcp2_vec *)vec, veccnt, x->ts);
@@ -1955,28 +2077,25 @@ out:
return nwritten;
}
-static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- int rv;
ssize_t nread;
size_t max_payload_size, path_max_payload_size, max_pktcnt;
size_t pktcnt = 0;
size_t gsolen = 0; /* this disables gso until we have a clue */
- ngtcp2_path_storage ps;
- ngtcp2_tstamp ts = timestamp();
- ngtcp2_tstamp expiry;
- ngtcp2_duration timeout;
CURLcode curlcode;
- struct read_ctx readx;
+ struct pkt_io_ctx local_pktx;
- rv = ngtcp2_conn_handle_expiry(ctx->qconn, ts);
- if(rv) {
- failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
- ngtcp2_strerror(rv));
- ngtcp2_ccerr_set_liberr(&ctx->last_error, rv, NULL, 0);
- return CURLE_SEND_ERROR;
+ if(!pktx) {
+ pktx_init(&local_pktx, cf, data);
+ pktx = &local_pktx;
+ }
+ else {
+ pktx->ts = timestamp();
+ ngtcp2_path_storage_zero(&pktx->ps);
}
curlcode = vquic_flush(cf, data, &ctx->q);
@@ -1988,8 +2107,6 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
return curlcode;
}
- ngtcp2_path_storage_zero(&ps);
-
/* In UDP, there is a maximum theoretical packet paload length and
* a minimum payload length that is "guarantueed" to work.
* To detect if this minimum payload can be increased, ngtcp2 sends
@@ -2008,15 +2125,10 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
max_pktcnt = CURLMIN(MAX_PKT_BURST,
ctx->q.sendbuf.chunk_size / max_payload_size);
- readx.cf = cf;
- readx.data = data;
- readx.ts = ts;
- readx.ps = &ps;
-
for(;;) {
/* add the next packet to send, if any, to our buffer */
nread = Curl_bufq_sipn(&ctx->q.sendbuf, max_payload_size,
- read_pkt_to_send, &readx, &curlcode);
+ read_pkt_to_send, pktx, &curlcode);
/* DEBUGF(LOG_CF(data, cf, "sip packet(maxlen=%zu) -> %zd, %d",
max_payload_size, nread, curlcode)); */
if(nread < 0) {
@@ -2076,21 +2188,6 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
}
out:
- /* non-errored exit. check when we should run again. */
- expiry = ngtcp2_conn_get_expiry(ctx->qconn);
- if(expiry != UINT64_MAX) {
- if(expiry <= ts) {
- timeout = 0;
- }
- else {
- timeout = expiry - ts;
- if(timeout % NGTCP2_MILLISECONDS) {
- timeout += NGTCP2_MILLISECONDS;
- }
- }
- Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
- }
-
return CURLE_OK;
}
@@ -2101,7 +2198,7 @@ out:
static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
- const struct stream_ctx *stream = H3_STREAM_CTX(data);
+ const struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
(void)cf;
return stream && !Curl_bufq_is_empty(&stream->recvbuf);
}
@@ -2113,7 +2210,7 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
/* TODO: there seems right now no API in ngtcp2 to shrink/enlarge
* the streams windows. As we do in HTTP/2. */
if(!pause) {
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
Curl_expire(data, 0, EXPIRE_RUN_NOW);
}
return CURLE_OK;
@@ -2141,7 +2238,7 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
break;
}
case CF_CTRL_DATA_DONE_SEND: {
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
if(stream && !stream->send_closed) {
stream->send_closed = TRUE;
stream->upload_left = Curl_bufq_len(&stream->sendbuf);
@@ -2150,11 +2247,7 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
break;
}
case CF_CTRL_DATA_IDLE:
- if(timestamp() >= ngtcp2_conn_get_expiry(ctx->qconn)) {
- if(cf_flush_egress(cf, data)) {
- result = CURLE_SEND_ERROR;
- }
- }
+ result = check_and_set_expiry(cf, data, NULL);
break;
default:
break;
@@ -2250,7 +2343,8 @@ static void cf_ngtcp2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
* Might be called twice for happy eyeballs.
*/
static CURLcode cf_connect_start(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
int rc;
@@ -2294,7 +2388,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
(void)Curl_qlogdir(data, ctx->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
ctx->qlogfd = qfd; /* -1 if failure above */
- quic_settings(ctx, data);
+ quic_settings(ctx, data, pktx);
result = vquic_ctx_init(&ctx->q);
if(result)
@@ -2344,6 +2438,7 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
CURLcode result = CURLE_OK;
struct cf_call_data save;
struct curltime now;
+ struct pkt_io_ctx pktx;
if(cf->connected) {
*done = TRUE;
@@ -2359,6 +2454,7 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
*done = FALSE;
now = Curl_now();
+ pktx_init(&pktx, cf, data);
CF_DATA_SAVE(save, cf, data);
@@ -2370,19 +2466,19 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
if(!ctx->qconn) {
ctx->started_at = now;
- result = cf_connect_start(cf, data);
+ result = cf_connect_start(cf, data, &pktx);
if(result)
goto out;
- result = cf_flush_egress(cf, data);
+ result = cf_progress_egress(cf, data, &pktx);
/* we do not expect to be able to recv anything yet */
goto out;
}
- result = cf_process_ingress(cf, data);
+ result = cf_progress_ingress(cf, data, &pktx);
if(result)
goto out;
- result = cf_flush_egress(cf, data);
+ result = cf_progress_egress(cf, data, &pktx);
if(result)
goto out;
@@ -2402,7 +2498,7 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
out:
if(result == CURLE_RECV_ERROR && ctx->qconn &&
- ngtcp2_conn_is_in_draining_period(ctx->qconn)) {
+ ngtcp2_conn_in_draining_period(ctx->qconn)) {
/* When a QUIC server instance is shutting down, it may send us a
* CONNECTION_CLOSE right away. Our connection then enters the DRAINING
* state.
@@ -2439,6 +2535,9 @@ out:
r_ip, r_port, curl_easy_strerror(result));
}
#endif
+ if(!result && ctx->qconn) {
+ result = check_and_set_expiry(cf, data, &pktx);
+ }
DEBUGF(LOG_CF(data, cf, "connect -> %d, done=%d", result, *done));
CF_DATA_RESTORE(cf, save);
return result;
@@ -2510,13 +2609,11 @@ static bool cf_ngtcp2_conn_is_alive(struct Curl_cfilter *cf,
not in use by any other transfer, there shouldn't be any data here,
only "protocol frames" */
*input_pending = FALSE;
- Curl_attach_connection(data, cf->conn);
- if(cf_process_ingress(cf, data))
+ if(cf_progress_ingress(cf, data, NULL))
alive = FALSE;
else {
alive = TRUE;
}
- Curl_detach_connection(data);
}
return alive;
diff --git a/Utilities/cmcurl/lib/vquic/curl_quiche.c b/Utilities/cmcurl/lib/vquic/curl_quiche.c
index 3a4f9f9..39cc16e 100644
--- a/Utilities/cmcurl/lib/vquic/curl_quiche.c
+++ b/Utilities/cmcurl/lib/vquic/curl_quiche.c
@@ -277,7 +277,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
stream->id = -1;
Curl_bufq_initp(&stream->recvbuf, &ctx->stream_bufcp,
H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
- DEBUGF(LOG_CF(data, cf, "data setup (easy %p)", (void *)data));
+ DEBUGF(LOG_CF(data, cf, "data setup"));
return CURLE_OK;
}
@@ -329,7 +329,7 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
else {
DEBUGASSERT(data->multi);
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
- if(H3_STREAM_ID(sdata) == stream3_id) {
+ if((sdata->conn == data->conn) && H3_STREAM_ID(sdata) == stream3_id) {
return sdata;
}
}
@@ -425,12 +425,8 @@ static ssize_t stream_resp_read(void *reader_ctx,
*err = CURLE_OK;
return nread;
}
- else if(nread < 0) {
- *err = CURLE_AGAIN;
- return -1;
- }
else {
- *err = stream->resp_got_header? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR;
+ *err = CURLE_AGAIN;
return -1;
}
}
@@ -461,8 +457,8 @@ static CURLcode cf_recv_body(struct Curl_cfilter *cf,
if(nwritten < 0 && result != CURLE_AGAIN) {
DEBUGF(LOG_CF(data, cf, "[h3sid=%"PRId64"] recv_body error %zd",
stream->id, nwritten));
- failf(data, "Error %zd in HTTP/3 response body for stream[%"PRId64"]",
- nwritten, stream->id);
+ failf(data, "Error %d in HTTP/3 response body for stream[%"PRId64"]",
+ result, stream->id);
stream->closed = TRUE;
stream->reset = TRUE;
stream->send_closed = TRUE;
@@ -595,8 +591,13 @@ static CURLcode cf_poll_events(struct Curl_cfilter *cf,
"for [h3sid=%"PRId64"] -> %d",
stream? stream->id : -1, cf_ev_name(ev),
stream3_id, result));
- quiche_h3_event_free(ev);
- return result;
+ if(data == sdata) {
+ /* Only report this error to the caller if it is about the
+ * transfer we were called with. Otherwise we fail a transfer
+ * due to a problem in another one. */
+ quiche_h3_event_free(ev);
+ return result;
+ }
}
quiche_h3_event_free(ev);
}
@@ -649,7 +650,7 @@ static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
}
}
else if((size_t)nread < pktlen) {
- DEBUGF(LOG_CF(r->data, r->cf, "ingress, quiche only read %zd/%zd bytes",
+ DEBUGF(LOG_CF(r->data, r->cf, "ingress, quiche only read %zd/%zu bytes",
nread, pktlen));
}
@@ -826,7 +827,7 @@ static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
if(!stream) {
*err = CURLE_RECV_ERROR;
- goto out;
+ return -1;
}
if(!Curl_bufq_is_empty(&stream->recvbuf)) {
@@ -883,8 +884,10 @@ out:
}
if(nread > 0)
ctx->data_recvd += nread;
- DEBUGF(LOG_CF(data, cf, "[h3sid=%"PRId64"] cf_recv(total=%zd) -> %zd, %d",
- stream->id, ctx->data_recvd, nread, *err));
+ DEBUGF(LOG_CF(data, cf, "[h3sid=%"PRId64"] cf_recv(total=%"
+ CURL_FORMAT_CURL_OFF_T ") -> %zd, %d",
+ stream ? stream->id : (int64_t)0,
+ ctx->data_recvd, nread, *err));
return nread;
}
@@ -909,8 +912,7 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf,
if(!stream) {
*err = h3_data_setup(cf, data);
if(*err) {
- nwritten = -1;
- goto out;
+ return -1;
}
stream = H3_STREAM_CTX(data);
DEBUGASSERT(stream);
@@ -995,8 +997,7 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf,
stream->closed = FALSE;
stream->reset = FALSE;
- infof(data, "Using HTTP/3 Stream ID: %" PRId64 " (easy handle %p)",
- stream3_id, (void *)data);
+ infof(data, "Using HTTP/3 Stream ID: %" PRId64, stream3_id);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] opened for %s",
stream3_id, data->state.url));
@@ -1068,7 +1069,7 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
stream->send_closed = TRUE;
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] send body(len=%zu, "
- "left=%zd) -> %zd",
+ "left=%" CURL_FORMAT_CURL_OFF_T ") -> %zd",
stream->id, len, stream->upload_left, nwritten));
*err = CURLE_OK;
}
@@ -1151,10 +1152,8 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf,
(void)arg1;
(void)arg2;
switch(event) {
- case CF_CTRL_DATA_SETUP: {
- result = h3_data_setup(cf, data);
+ case CF_CTRL_DATA_SETUP:
break;
- }
case CF_CTRL_DATA_PAUSE:
result = h3_data_pause(cf, data, (arg1 != 0));
break;
@@ -1343,11 +1342,6 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
}
#endif
- /* we do not get a setup event for the initial transfer */
- result = h3_data_setup(cf, data);
- if(result)
- return result;
-
result = cf_flush_egress(cf, data);
if(result)
return result;
@@ -1555,13 +1549,11 @@ static bool cf_quiche_conn_is_alive(struct Curl_cfilter *cf,
not in use by any other transfer, there shouldn't be any data here,
only "protocol frames" */
*input_pending = FALSE;
- Curl_attach_connection(data, cf->conn);
if(cf_process_ingress(cf, data))
alive = FALSE;
else {
alive = TRUE;
}
- Curl_detach_connection(data);
}
return alive;
diff --git a/Utilities/cmcurl/lib/vquic/vquic.c b/Utilities/cmcurl/lib/vquic/vquic.c
index f850029..399de0b 100644
--- a/Utilities/cmcurl/lib/vquic/vquic.c
+++ b/Utilities/cmcurl/lib/vquic/vquic.c
@@ -362,7 +362,7 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf,
}
out:
- DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zd bytes -> %d",
+ DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d",
pkts, total_nread, result));
return result;
}
@@ -425,7 +425,7 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf,
}
out:
- DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zd bytes -> %d",
+ DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d",
pkts, total_nread, result));
return result;
}
@@ -482,7 +482,7 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf,
}
out:
- DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zd bytes -> %d",
+ DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d",
pkts, total_nread, result));
return result;
}
diff --git a/Utilities/cmcurl/lib/vssh/libssh2.c b/Utilities/cmcurl/lib/vssh/libssh2.c
index 14c2784..98fce51 100644
--- a/Utilities/cmcurl/lib/vssh/libssh2.c
+++ b/Utilities/cmcurl/lib/vssh/libssh2.c
@@ -100,11 +100,9 @@
/* Local functions: */
static const char *sftp_libssh2_strerror(unsigned long err);
-#ifdef CURL_LIBSSH2_DEBUG
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
static LIBSSH2_FREE_FUNC(my_libssh2_free);
-#endif
static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data);
static CURLcode ssh_connect(struct Curl_easy *data, bool *done);
static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done);
@@ -284,8 +282,6 @@ static CURLcode libssh2_session_error_to_CURLE(int err)
return CURLE_SSH;
}
-#ifdef CURL_LIBSSH2_DEBUG
-
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
{
(void)abstract; /* arg not used */
@@ -305,8 +301,6 @@ static LIBSSH2_FREE_FUNC(my_libssh2_free)
free(ptr);
}
-#endif
-
/*
* SSH State machine related code
*/
@@ -895,6 +889,7 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data)
}
if(found) {
+ int rc;
infof(data, "Found host %s in %s",
conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
@@ -944,9 +939,15 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data)
}
infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method);
- result = libssh2_session_error_to_CURLE(
- libssh2_session_method_pref(
- sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method));
+ rc = libssh2_session_method_pref(sshc->ssh_session,
+ LIBSSH2_METHOD_HOSTKEY, hostkey_method);
+ if(rc) {
+ char *errmsg = NULL;
+ int errlen;
+ libssh2_session_last_error(sshc->ssh_session, &errmsg, &errlen, 0);
+ failf(data, "libssh2: %s", errmsg);
+ result = libssh2_session_error_to_CURLE(rc);
+ }
}
else {
infof(data, "Did not find host %s in %s",
@@ -3268,13 +3269,12 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
sock = conn->sock[FIRSTSOCKET];
#endif /* CURL_LIBSSH2_DEBUG */
-#ifdef CURL_LIBSSH2_DEBUG
+ /* libcurl MUST to set custom memory functions so that the kbd_callback
+ funciton's memory allocations can be properled freed */
sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
my_libssh2_free,
my_libssh2_realloc, data);
-#else
- sshc->ssh_session = libssh2_session_init_ex(NULL, NULL, NULL, data);
-#endif
+
if(!sshc->ssh_session) {
failf(data, "Failure initialising ssh session");
return CURLE_FAILED_INIT;
diff --git a/Utilities/cmcurl/lib/vssh/wolfssh.c b/Utilities/cmcurl/lib/vssh/wolfssh.c
index 780b612..b47c231 100644
--- a/Utilities/cmcurl/lib/vssh/wolfssh.c
+++ b/Utilities/cmcurl/lib/vssh/wolfssh.c
@@ -277,7 +277,7 @@ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex,
return -1;
}
DEBUGASSERT(rc == (int)len);
- infof(data, "sent %zd bytes SFTP from offset %zd",
+ infof(data, "sent %zu bytes SFTP from offset %" CURL_FORMAT_CURL_OFF_T,
len, sshc->offset);
sshc->offset += len;
return (ssize_t)rc;
diff --git a/Utilities/cmcurl/lib/vtls/bearssl.c b/Utilities/cmcurl/lib/vtls/bearssl.c
index 2b666ca..6ed453b 100644
--- a/Utilities/cmcurl/lib/vtls/bearssl.c
+++ b/Utilities/cmcurl/lib/vtls/bearssl.c
@@ -52,7 +52,7 @@ struct x509_context {
int cert_num;
};
-struct ssl_backend_data {
+struct bearssl_ssl_backend_data {
br_ssl_client_context ctx;
struct x509_context x509;
unsigned char buf[BR_SSL_BUFSIZE_BIDI];
@@ -574,7 +574,8 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
@@ -751,7 +752,8 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
unsigned target)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
unsigned state;
unsigned char *buf;
size_t len;
@@ -820,7 +822,8 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
CURLcode ret;
DEBUGASSERT(backend);
@@ -842,7 +845,8 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode ret;
@@ -889,7 +893,8 @@ static ssize_t bearssl_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
unsigned char *app;
size_t applen;
@@ -923,7 +928,8 @@ static ssize_t bearssl_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
unsigned char *app;
size_t applen;
@@ -1050,10 +1056,12 @@ static bool bearssl_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct bearssl_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- return br_ssl_engine_current_state(&ctx->backend->ctx.eng) & BR_SSL_RECVAPP;
+ backend = (struct bearssl_ssl_backend_data *)ctx->backend;
+ return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
}
static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
@@ -1101,7 +1109,8 @@ static CURLcode bearssl_connect_nonblocking(struct Curl_cfilter *cf,
static void *bearssl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
return &backend->ctx;
}
@@ -1109,7 +1118,8 @@ static void *bearssl_get_internals(struct ssl_connect_data *connssl,
static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
size_t i;
DEBUGASSERT(backend);
@@ -1147,7 +1157,7 @@ static CURLcode bearssl_sha256sum(const unsigned char *input,
const struct Curl_ssl Curl_ssl_bearssl = {
{ CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct bearssl_ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
index 749dc91..c128293 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.c
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -103,14 +103,14 @@
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
#define CURL_GSKPROTO_LAST 5
-struct ssl_backend_data {
+struct gskit_ssl_backend_data {
gsk_handle handle;
int iocport;
int localfd;
int remotefd;
};
-#define BACKEND connssl->backend
+#define BACKEND ((struct gskit_ssl_backend_data *)connssl->backend)
/* Supported ciphers. */
struct gskit_cipher {
@@ -518,6 +518,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
struct ssl_connect_data *connssl_next = cf_ssl_next?
cf_ssl_next->ctx : NULL;
+ struct gskit_ssl_backend_data *backend_next;
struct pollfd fds[2];
int n;
int m;
@@ -531,6 +532,8 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
return 0; /* No SSL over SSL: OK. */
DEBUGASSERT(connssl_next->backend);
+ backend_next = (struct gskit_ssl_backend_data *)connssl_next->backend;
+
n = 1;
fds[0].fd = BACKEND->remotefd;
fds[1].fd = Curl_conn_cf_get_socket(cf, data);
@@ -550,8 +553,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
if(fds[0].revents & POLLOUT) {
/* Try getting data from HTTPS proxy and pipe it upstream. */
n = 0;
- i = gsk_secure_soc_read(connssl_next->backend->handle,
- buf, sizeof(buf), &n);
+ i = gsk_secure_soc_read(backend_next->handle, buf, sizeof(buf), &n);
switch(i) {
case GSK_OK:
if(n) {
@@ -575,7 +577,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
if(n < 0)
return -1;
if(n) {
- i = gsk_secure_soc_write(connssl_next->backend->handle, buf, n, &m);
+ i = gsk_secure_soc_write(backend_next->handle, buf, n, &m);
if(i != GSK_OK || n != m)
return -1;
ret = 1;
@@ -1294,7 +1296,7 @@ const struct Curl_ssl Curl_ssl_gskit = {
SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct gskit_ssl_backend_data),
gskit_init, /* init */
gskit_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
index 3d1906e..f6f1e10 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.c
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -76,7 +76,7 @@ static bool gtls_inited = FALSE;
# include <gnutls/ocsp.h>
-struct ssl_backend_data {
+struct gtls_ssl_backend_data {
struct gtls_instance gtls;
};
@@ -91,7 +91,9 @@ static ssize_t gtls_push(void *s, const void *buf, size_t blen)
DEBUGASSERT(data);
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
if(nwritten < 0) {
- gnutls_transport_set_errno(connssl->backend->gtls.session,
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
+ gnutls_transport_set_errno(backend->gtls.session,
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
nwritten = -1;
}
@@ -109,7 +111,9 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen)
DEBUGASSERT(data);
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
if(nread < 0) {
- gnutls_transport_set_errno(connssl->backend->gtls.session,
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
+ gnutls_transport_set_errno(backend->gtls.session,
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
nread = -1;
}
@@ -212,7 +216,8 @@ static CURLcode handshake(struct Curl_cfilter *cf,
bool nonblocking)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
gnutls_session_t session;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
@@ -679,7 +684,8 @@ static CURLcode
gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
long * const pverifyresult = &ssl_config->certverifyresult;
@@ -1346,7 +1352,8 @@ gtls_connect_common(struct Curl_cfilter *cf,
/* Finish connecting once the handshake is done */
if(ssl_connect_1 == connssl->connecting_state) {
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
gnutls_session_t session;
DEBUGASSERT(backend);
session = backend->gtls.session;
@@ -1390,11 +1397,13 @@ static bool gtls_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct gtls_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->gtls.session &&
- 0 != gnutls_record_check_pending(ctx->backend->gtls.session))
+ backend = (struct gtls_ssl_backend_data *)ctx->backend;
+ if(backend->gtls.session &&
+ 0 != gnutls_record_check_pending(backend->gtls.session))
return TRUE;
return FALSE;
}
@@ -1406,7 +1415,8 @@ static ssize_t gtls_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
ssize_t rc;
(void)data;
@@ -1428,7 +1438,8 @@ static void gtls_close(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
(void) data;
DEBUGASSERT(backend);
@@ -1463,7 +1474,8 @@ static int gtls_shutdown(struct Curl_cfilter *cf,
{
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
int retval = 0;
DEBUGASSERT(backend);
@@ -1541,7 +1553,8 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
ssize_t ret;
(void)data;
@@ -1620,7 +1633,8 @@ static bool gtls_cert_status_request(void)
static void *gtls_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->gtls.session;
@@ -1634,7 +1648,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct gtls_ssl_backend_data),
gtls_init, /* init */
gtls_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.c b/Utilities/cmcurl/lib/vtls/mbedtls.c
index d95888c..8d0fa39 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.c
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.c
@@ -81,7 +81,7 @@
# endif
#endif
-struct ssl_backend_data {
+struct mbed_ssl_backend_data {
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
mbedtls_ssl_context ssl;
@@ -255,7 +255,8 @@ static CURLcode
set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3;
@@ -307,7 +308,8 @@ static CURLcode
mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
@@ -697,7 +699,8 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
int ret;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const mbedtls_x509_crt *peercert;
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
@@ -860,7 +863,8 @@ mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
CURLcode retcode = CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -915,7 +919,8 @@ static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
(void)data;
@@ -939,7 +944,8 @@ static void mbedtls_close_all(struct Curl_easy *data)
static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
char buf[32];
(void)data;
@@ -968,7 +974,8 @@ static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
ssize_t len = -1;
@@ -1204,10 +1211,12 @@ static bool mbedtls_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct mbed_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- return mbedtls_ssl_get_bytes_avail(&ctx->backend->ssl) != 0;
+ backend = (struct mbed_ssl_backend_data *)ctx->backend;
+ return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
}
static CURLcode mbedtls_sha256sum(const unsigned char *input,
@@ -1234,7 +1243,8 @@ static CURLcode mbedtls_sha256sum(const unsigned char *input,
static void *mbedtls_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return &backend->ssl;
@@ -1249,7 +1259,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
SSLSUPP_SSL_CTX |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct mbed_ssl_backend_data),
mbedtls_init, /* init */
mbedtls_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
index 5e5dbb7..322f507 100644
--- a/Utilities/cmcurl/lib/vtls/nss.c
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -81,7 +81,7 @@
/* enough to fit the string "PEM Token #[0|1]" */
#define SLOTSIZE 13
-struct ssl_backend_data {
+struct nss_ssl_backend_data {
PRFileDesc *handle;
char *client_nickname;
struct Curl_easy *data;
@@ -489,7 +489,8 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl,
const int slot_id = (cacert) ? 0 : 1;
char *slot_name = aprintf("PEM Token #%d", slot_id);
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -806,7 +807,9 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
- struct Curl_easy *data = connssl->backend->data;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ struct Curl_easy *data = backend->data;
DEBUGASSERT(data);
#ifdef SSL_ENABLE_OCSP_STAPLING
@@ -851,7 +854,9 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
struct ssl_connect_data *connssl = cf->ctx;
- struct Curl_easy *data = connssl->backend->data;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ struct Curl_easy *data = backend->data;
unsigned int buflenmax = 50;
unsigned char buf[50];
unsigned int buflen;
@@ -1055,7 +1060,9 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
struct ssl_connect_data *connssl = cf->ctx;
- struct Curl_easy *data = connssl->backend->data;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ struct Curl_easy *data = backend->data;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config;
PRErrorCode err = PR_GetError();
@@ -1117,7 +1124,8 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
const char *pinnedpubkey)
{
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = NULL;
CERTCertificate *cert;
@@ -1173,7 +1181,8 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
struct SECKEYPrivateKeyStr **pRetKey)
{
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = NULL;
const char *nickname = NULL;
static const char pem_slotname[] = "PEM Token #1";
@@ -1538,7 +1547,8 @@ static void nss_cleanup(void)
static void close_one(struct ssl_connect_data *connssl)
{
/* before the cleanup, check whether we are using a client certificate */
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
bool client_cert = true;
DEBUGASSERT(backend);
@@ -1580,7 +1590,8 @@ static void close_one(struct ssl_connect_data *connssl)
static void nss_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -1796,7 +1807,8 @@ static CURLcode nss_fail_connect(struct Curl_cfilter *cf,
CURLcode curlerr)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -1826,7 +1838,8 @@ static CURLcode nss_set_blocking(struct Curl_cfilter *cf,
{
struct ssl_connect_data *connssl = cf->ctx;
PRSocketOptionData sock_opt;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -1849,7 +1862,8 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
PRBool ssl_cbc_random_iv;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
@@ -2031,14 +2045,16 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
/* Is there an SSL filter "in front" of us or are we writing directly
* to the socket? */
if(connssl_next) {
+ struct nss_ssl_backend_data *backend_next =
+ (struct nss_ssl_backend_data *)connssl_next->backend;
/* The filter should be connected by now, with full handshake */
- DEBUGASSERT(connssl_next->backend->handle);
+ DEBUGASSERT(backend_next->handle);
DEBUGASSERT(ssl_connection_complete == connssl_next->state);
/* We tell our NSS instance to use do IO with the 'next' NSS
* instance. This NSS instance will take ownership of the next
* one, including its destruction. We therefore need to `disown`
* the next filter's handle, once import succeeds. */
- nspr_io = connssl_next->backend->handle;
+ nspr_io = backend->handle;
second_layer = TRUE;
}
else {
@@ -2077,8 +2093,11 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
PR_Close(model); /* We don't need this any more */
model = NULL;
- if(connssl_next) /* steal the NSS handle we just imported successfully */
- connssl_next->backend->handle = NULL;
+ if(connssl_next) { /* steal the NSS handle we just imported successfully */
+ struct nss_ssl_backend_data *backend_next =
+ (struct nss_ssl_backend_data *)connssl_next->backend;
+ backend_next->handle = NULL;
+ }
/* This is the password associated with the cert that we're using */
if(ssl_config->key_passwd) {
@@ -2154,7 +2173,8 @@ static CURLcode nss_do_connect(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_SSL_CONNECT_ERROR;
@@ -2299,7 +2319,8 @@ static ssize_t nss_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
ssize_t rc;
(void)data;
@@ -2337,7 +2358,9 @@ static bool
nss_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- PRFileDesc *fd = connssl->backend->handle->lower;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ PRFileDesc *fd = backend->handle->lower;
char buf;
(void) data;
@@ -2353,7 +2376,8 @@ static ssize_t nss_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
ssize_t nread;
(void)data;
@@ -2455,7 +2479,8 @@ static bool nss_false_start(void)
static void *nss_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->handle;
@@ -2465,9 +2490,11 @@ static bool nss_attach_data(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
- if(!connssl->backend->data)
- connssl->backend->data = data;
+ if(!backend->data)
+ backend->data = data;
return TRUE;
}
@@ -2475,9 +2502,11 @@ static void nss_detach_data(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
- if(connssl->backend->data == data)
- connssl->backend->data = NULL;
+ if(backend->data == data)
+ backend->data = NULL;
}
const struct Curl_ssl Curl_ssl_nss = {
@@ -2488,7 +2517,7 @@ const struct Curl_ssl Curl_ssl_nss = {
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct nss_ssl_backend_data),
nss_init, /* init */
nss_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index 1c6c786..e6dd398 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -296,7 +296,7 @@ typedef unsigned long sslerr_t;
#define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
#endif /* !LIBRESSL_VERSION_NUMBER */
-struct ssl_backend_data {
+struct ossl_ssl_backend_data {
/* these ones requires specific SSL-types */
SSL_CTX* ctx;
SSL* handle;
@@ -722,6 +722,8 @@ static int bio_cf_out_write(BIO *bio, const char *buf, int blen)
{
struct Curl_cfilter *cf = BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
CURLcode result = CURLE_SEND_ERROR;
@@ -731,7 +733,7 @@ static int bio_cf_out_write(BIO *bio, const char *buf, int blen)
DEBUGF(LOG_CF(data, cf, "bio_cf_out_write(len=%d) -> %d, err=%d",
blen, (int)nwritten, result));
BIO_clear_retry_flags(bio);
- connssl->backend->io_result = result;
+ backend->io_result = result;
if(nwritten < 0) {
if(CURLE_AGAIN == result)
BIO_set_retry_write(bio);
@@ -743,6 +745,8 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
{
struct Curl_cfilter *cf = BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
CURLcode result = CURLE_RECV_ERROR;
@@ -756,7 +760,7 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
DEBUGF(LOG_CF(data, cf, "bio_cf_in_read(len=%d) -> %d, err=%d",
blen, (int)nread, result));
BIO_clear_retry_flags(bio);
- connssl->backend->io_result = result;
+ backend->io_result = result;
if(nread < 0) {
if(CURLE_AGAIN == result)
BIO_set_retry_read(bio);
@@ -764,13 +768,13 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
/* Before returning server replies to the SSL instance, we need
* to have setup the x509 store or verification will fail. */
- if(!connssl->backend->x509_store_setup) {
- result = Curl_ssl_setup_x509_store(cf, data, connssl->backend->ctx);
+ if(!backend->x509_store_setup) {
+ result = Curl_ssl_setup_x509_store(cf, data, backend->ctx);
if(result) {
- connssl->backend->io_result = result;
+ backend->io_result = result;
return -1;
}
- connssl->backend->x509_store_setup = TRUE;
+ backend->x509_store_setup = TRUE;
}
return (int)nread;
@@ -1885,7 +1889,8 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data)
static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -1931,7 +1936,8 @@ static int ossl_shutdown(struct Curl_cfilter *cf,
int buffsize;
int err;
bool done = FALSE;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
int loop = 10;
DEBUGASSERT(backend);
@@ -2329,7 +2335,8 @@ static CURLcode verifystatus(struct Curl_cfilter *cf,
OCSP_BASICRESP *br = NULL;
X509_STORE *st = NULL;
STACK_OF(X509) *ch = NULL;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
X509 *cert;
OCSP_CERTID *id = NULL;
int cert_status, crl_reason;
@@ -2729,7 +2736,7 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
#ifdef HAS_MODERN_SET_PROTO_VER
static CURLcode
-set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
+ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
/* first, TLS min version... */
@@ -2826,9 +2833,9 @@ typedef long ctx_option_t;
#if !defined(HAS_MODERN_SET_PROTO_VER)
static CURLcode
-set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
- struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ossl_set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
@@ -2841,8 +2848,10 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
#ifdef TLS1_3_VERSION
{
struct ssl_connect_data *connssl = cf->ctx;
- DEBUGASSERT(connssl->backend);
- SSL_CTX_set_max_proto_version(connssl->backend->ctx, TLS1_3_VERSION);
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
+ DEBUGASSERT(backend);
+ SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2;
}
#else
@@ -3447,7 +3456,8 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
const char * const ssl_cert_type = ssl_config->cert_type;
const bool verifypeer = conn_config->verifypeer;
char error_buffer[256];
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
DEBUGASSERT(backend);
@@ -3589,9 +3599,9 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
ctx_options |= SSL_OP_NO_SSLv3;
#if HAS_MODERN_SET_PROTO_VER /* 1.1.0 */
- result = set_ssl_version_min_max(cf, backend->ctx);
+ result = ossl_set_ssl_version_min_max(cf, backend->ctx);
#else
- result = set_ssl_version_min_max_legacy(&ctx_options, cf, data);
+ result = ossl_set_ssl_version_min_max_legacy(&ctx_options, cf, data);
#endif
if(result != CURLE_OK)
return result;
@@ -3820,7 +3830,8 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
{
int err;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -3983,8 +3994,8 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
*/
-static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
- const char *pinnedpubkey)
+static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
+ const char *pinnedpubkey)
{
/* Scratch */
int len1 = 0, len2 = 0;
@@ -4062,7 +4073,8 @@ static CURLcode servercert(struct Curl_cfilter *cf,
char buffer[2048];
const char *ptr;
BIO *mem = BIO_new(BIO_s_mem());
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -4077,7 +4089,7 @@ static CURLcode servercert(struct Curl_cfilter *cf,
if(data->set.ssl.certinfo)
/* asked to gather certificate info */
- (void)Curl_ossl_certchain(data, connssl->backend->handle);
+ (void)Curl_ossl_certchain(data, backend->handle);
backend->server_cert = SSL_get1_peer_certificate(backend->handle);
if(!backend->server_cert) {
@@ -4245,7 +4257,7 @@ static CURLcode servercert(struct Curl_cfilter *cf,
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
- result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
+ result = ossl_pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result)
failf(data, "SSL: public key does not match pinned public key");
}
@@ -4414,11 +4426,13 @@ static CURLcode ossl_connect(struct Curl_cfilter *cf,
static bool ossl_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
- struct ssl_connect_data *ctx = cf->ctx;
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
- DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->handle && SSL_pending(ctx->backend->handle))
+ DEBUGASSERT(connssl && backend);
+ if(backend->handle && SSL_pending(backend->handle))
return TRUE;
return FALSE;
}
@@ -4437,7 +4451,8 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
int memlen;
int rc;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -4533,7 +4548,8 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
int buffsize;
struct connectdata *conn = cf->conn;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -4756,7 +4772,8 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info)
{
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
return info == CURLINFO_TLS_SESSION ?
(void *)backend->ctx : (void *)backend->handle;
@@ -4789,7 +4806,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
#endif
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct ossl_ssl_backend_data),
ossl_init, /* init */
ossl_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/rustls.c b/Utilities/cmcurl/lib/vtls/rustls.c
index 097c58c..76d3e24 100644
--- a/Utilities/cmcurl/lib/vtls/rustls.c
+++ b/Utilities/cmcurl/lib/vtls/rustls.c
@@ -40,7 +40,7 @@
#include "strerror.h"
#include "multiif.h"
-struct ssl_backend_data
+struct rustls_ssl_backend_data
{
const struct rustls_client_config *config;
struct rustls_connection *conn;
@@ -67,10 +67,12 @@ static bool
cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct rustls_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- return ctx->backend->data_pending;
+ backend = (struct rustls_ssl_backend_data *)ctx->backend;
+ return backend->data_pending;
}
static CURLcode
@@ -136,7 +138,8 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf,
struct Curl_easy *data, CURLcode *err)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct io_ctx io_ctx;
size_t tls_bytes_read = 0;
rustls_io_result io_error;
@@ -191,7 +194,8 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *plainbuf, size_t plainlen, CURLcode *err)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
size_t n = 0;
size_t plain_bytes_copied = 0;
@@ -283,7 +287,8 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *plainbuf, size_t plainlen, CURLcode *err)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
struct io_ctx io_ctx;
size_t plainwritten = 0;
@@ -373,7 +378,7 @@ cr_hostname_is_ip(const char *hostname)
static CURLcode
cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
- struct ssl_backend_data *const backend)
+ struct rustls_ssl_backend_data *const backend)
{
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
@@ -491,7 +496,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
{
struct ssl_connect_data *const connssl = cf->ctx;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
CURLcode tmperr = CURLE_OK;
int result;
@@ -504,7 +510,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
DEBUGASSERT(backend);
if(ssl_connection_none == connssl->state) {
- result = cr_init_backend(cf, data, connssl->backend);
+ result = cr_init_backend(cf, data,
+ (struct rustls_ssl_backend_data *)connssl->backend);
if(result != CURLE_OK) {
return result;
}
@@ -594,7 +601,8 @@ cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
{
struct ssl_connect_data *const connssl = cf->ctx;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
(void)data;
@@ -617,7 +625,8 @@ static void *
cr_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct rustls_ssl_backend_data *backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
return &backend->conn;
}
@@ -626,7 +635,8 @@ static void
cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct rustls_ssl_backend_data *backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
CURLcode tmperr = CURLE_OK;
ssize_t n = 0;
@@ -659,7 +669,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
SSLSUPP_CAINFO_BLOB | /* supports */
SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct rustls_ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
index 513811d..5dcf5ba 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.c
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -33,13 +33,12 @@
#ifdef USE_SCHANNEL
-#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
-
#ifndef USE_WINDOWS_SSPI
# error "Can't compile SCHANNEL support without SSPI."
#endif
#include "schannel.h"
+#include "schannel_int.h"
#include "vtls.h"
#include "vtls_int.h"
#include "strcase.h"
@@ -186,9 +185,9 @@
#define PKCS12_NO_PERSIST_KEY 0x00008000
#endif
-static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char *pinnedpubkey);
+static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char *pinnedpubkey);
static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
void *BufDataPtr, unsigned long BufByteSize)
@@ -207,9 +206,9 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
}
static CURLcode
-set_ssl_version_min_max(DWORD *enabled_protocols,
- struct Curl_cfilter *cf,
- struct Curl_easy *data)
+schannel_set_ssl_version_min_max(DWORD *enabled_protocols,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
@@ -500,7 +499,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
DWORD flags = 0;
DWORD enabled_protocols = 0;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)(connssl->backend);
DEBUGASSERT(backend);
@@ -563,7 +563,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- result = set_ssl_version_min_max(&enabled_protocols, cf, data);
+ result = schannel_set_ssl_version_min_max(&enabled_protocols, cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -1075,7 +1075,8 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
ssize_t written = -1;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SecBuffer outbuf;
@@ -1349,7 +1350,8 @@ static CURLcode
schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
int i;
ssize_t nread = -1, written = -1;
@@ -1607,7 +1609,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(pubkey_ptr) {
- result = pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
+ result = schannel_pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
if(result) {
failf(data, "SSL: public key does not match pinned public key");
return result;
@@ -1686,7 +1688,8 @@ static CURLcode
schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_OK;
SECURITY_STATUS sspi_status = SEC_E_OK;
@@ -1931,7 +1934,8 @@ schannel_connect_common(struct Curl_cfilter *cf,
* Available on Windows 7 or later.
*/
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
cf->conn->sslContext = &backend->ctxt->ctxt_handle;
}
@@ -1960,7 +1964,8 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -2110,7 +2115,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
/* we want the length of the encrypted buffer to be at least large enough
that it can hold all the bytes requested and some TLS record overhead. */
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -2443,12 +2449,13 @@ static bool schannel_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
const struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
- if(connssl->backend->ctxt) /* SSL/TLS is in use */
+ if(backend->ctxt) /* SSL/TLS is in use */
return (backend->decdata_offset > 0 ||
(backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
else
@@ -2486,12 +2493,13 @@ static int schannel_shutdown(struct Curl_cfilter *cf,
* Shutting Down an Schannel Connection
*/
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(data);
DEBUGASSERT(backend);
- if(connssl->backend->ctxt) {
+ if(backend->ctxt) {
infof(data, "schannel: shutting down SSL/TLS connection with %s port %d",
connssl->hostname, connssl->port);
}
@@ -2611,12 +2619,13 @@ static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM,
return Curl_win32_random(entropy, length);
}
-static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char *pinnedpubkey)
+static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char *pinnedpubkey)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
CERT_CONTEXT *pCertContextServer = NULL;
/* Result is returned to caller */
@@ -2742,7 +2751,8 @@ static CURLcode schannel_sha256sum(const unsigned char *input,
static void *schannel_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return &backend->ctxt->ctxt_handle;
@@ -2759,7 +2769,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct schannel_ssl_backend_data),
schannel_init, /* init */
schannel_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.h b/Utilities/cmcurl/lib/vtls/schannel.h
index 7fae39f..b8cb494 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.h
+++ b/Utilities/cmcurl/lib/vtls/schannel.h
@@ -28,8 +28,6 @@
#ifdef USE_SCHANNEL
-#define SCHANNEL_USE_BLACKLISTS 1
-
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4201)
@@ -81,119 +79,5 @@ extern const struct Curl_ssl Curl_ssl_schannel;
CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
struct Curl_easy *data);
-/* structs to expose only in schannel.c and schannel_verify.c */
-#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
-
-#ifdef __MINGW32__
-#ifdef __MINGW64_VERSION_MAJOR
-#define HAS_MANUAL_VERIFY_API
-#endif
-#else
-#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
-#define HAS_MANUAL_VERIFY_API
-#endif
-#endif
-
-#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
- && !defined(DISABLE_SCHANNEL_CLIENT_CERT)
-#define HAS_CLIENT_CERT_PATH
-#endif
-
-#ifndef SCH_CREDENTIALS_VERSION
-
-#define SCH_CREDENTIALS_VERSION 0x00000005
-
-typedef enum _eTlsAlgorithmUsage
-{
- TlsParametersCngAlgUsageKeyExchange,
- TlsParametersCngAlgUsageSignature,
- TlsParametersCngAlgUsageCipher,
- TlsParametersCngAlgUsageDigest,
- TlsParametersCngAlgUsageCertSig
-} eTlsAlgorithmUsage;
-
-typedef struct _CRYPTO_SETTINGS
-{
- eTlsAlgorithmUsage eAlgorithmUsage;
- UNICODE_STRING strCngAlgId;
- DWORD cChainingModes;
- PUNICODE_STRING rgstrChainingModes;
- DWORD dwMinBitLength;
- DWORD dwMaxBitLength;
-} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
-
-typedef struct _TLS_PARAMETERS
-{
- DWORD cAlpnIds;
- PUNICODE_STRING rgstrAlpnIds;
- DWORD grbitDisabledProtocols;
- DWORD cDisabledCrypto;
- PCRYPTO_SETTINGS pDisabledCrypto;
- DWORD dwFlags;
-} TLS_PARAMETERS, * PTLS_PARAMETERS;
-
-typedef struct _SCH_CREDENTIALS
-{
- DWORD dwVersion;
- DWORD dwCredFormat;
- DWORD cCreds;
- PCCERT_CONTEXT* paCred;
- HCERTSTORE hRootStore;
-
- DWORD cMappers;
- struct _HMAPPER **aphMappers;
-
- DWORD dwSessionLifespan;
- DWORD dwFlags;
- DWORD cTlsParameters;
- PTLS_PARAMETERS pTlsParameters;
-} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
-
-#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
-#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
-#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
-#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
-
-#endif
-
-struct Curl_schannel_cred {
- CredHandle cred_handle;
- TimeStamp time_stamp;
- TCHAR *sni_hostname;
-#ifdef HAS_CLIENT_CERT_PATH
- HCERTSTORE client_cert_store;
-#endif
- int refcount;
-};
-
-struct Curl_schannel_ctxt {
- CtxtHandle ctxt_handle;
- TimeStamp time_stamp;
-};
-
-struct ssl_backend_data {
- struct Curl_schannel_cred *cred;
- struct Curl_schannel_ctxt *ctxt;
- SecPkgContext_StreamSizes stream_sizes;
- size_t encdata_length, decdata_length;
- size_t encdata_offset, decdata_offset;
- unsigned char *encdata_buffer, *decdata_buffer;
- /* encdata_is_incomplete: if encdata contains only a partial record that
- can't be decrypted without another recv() (that is, status is
- SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
- more bytes into encdata then set this back to false. */
- bool encdata_is_incomplete;
- unsigned long req_flags, ret_flags;
- CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
- bool recv_sspi_close_notify; /* true if connection closed by close_notify */
- bool recv_connection_closed; /* true if connection closed, regardless how */
- bool recv_renegotiating; /* true if recv is doing renegotiation */
- bool use_alpn; /* true if ALPN is used for this connection */
-#ifdef HAS_MANUAL_VERIFY_API
- bool use_manual_cred_validation; /* true if manual cred validation is used */
-#endif
-};
-#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
-
#endif /* USE_SCHANNEL */
#endif /* HEADER_CURL_SCHANNEL_H */
diff --git a/Utilities/cmcurl/lib/vtls/schannel_int.h b/Utilities/cmcurl/lib/vtls/schannel_int.h
new file mode 100644
index 0000000..d8b6cce
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/schannel_int.h
@@ -0,0 +1,142 @@
+#ifndef HEADER_CURL_SCHANNEL_INT_H
+#define HEADER_CURL_SCHANNEL_INT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Marc Hoersken, <info@marc-hoersken.de>, et al.
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#ifdef __MINGW32__
+#ifdef __MINGW64_VERSION_MAJOR
+#define HAS_MANUAL_VERIFY_API
+#endif
+#else
+#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
+#define HAS_MANUAL_VERIFY_API
+#endif
+#endif
+
+#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
+ && !defined(DISABLE_SCHANNEL_CLIENT_CERT)
+#define HAS_CLIENT_CERT_PATH
+#endif
+
+#ifndef SCH_CREDENTIALS_VERSION
+
+#define SCH_CREDENTIALS_VERSION 0x00000005
+
+typedef enum _eTlsAlgorithmUsage
+{
+ TlsParametersCngAlgUsageKeyExchange,
+ TlsParametersCngAlgUsageSignature,
+ TlsParametersCngAlgUsageCipher,
+ TlsParametersCngAlgUsageDigest,
+ TlsParametersCngAlgUsageCertSig
+} eTlsAlgorithmUsage;
+
+typedef struct _CRYPTO_SETTINGS
+{
+ eTlsAlgorithmUsage eAlgorithmUsage;
+ UNICODE_STRING strCngAlgId;
+ DWORD cChainingModes;
+ PUNICODE_STRING rgstrChainingModes;
+ DWORD dwMinBitLength;
+ DWORD dwMaxBitLength;
+} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
+
+typedef struct _TLS_PARAMETERS
+{
+ DWORD cAlpnIds;
+ PUNICODE_STRING rgstrAlpnIds;
+ DWORD grbitDisabledProtocols;
+ DWORD cDisabledCrypto;
+ PCRYPTO_SETTINGS pDisabledCrypto;
+ DWORD dwFlags;
+} TLS_PARAMETERS, * PTLS_PARAMETERS;
+
+typedef struct _SCH_CREDENTIALS
+{
+ DWORD dwVersion;
+ DWORD dwCredFormat;
+ DWORD cCreds;
+ PCCERT_CONTEXT* paCred;
+ HCERTSTORE hRootStore;
+
+ DWORD cMappers;
+ struct _HMAPPER **aphMappers;
+
+ DWORD dwSessionLifespan;
+ DWORD dwFlags;
+ DWORD cTlsParameters;
+ PTLS_PARAMETERS pTlsParameters;
+} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
+
+#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
+#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
+#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
+#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
+
+#endif /* SCH_CREDENTIALS_VERSION */
+
+struct Curl_schannel_cred {
+ CredHandle cred_handle;
+ TimeStamp time_stamp;
+ TCHAR *sni_hostname;
+#ifdef HAS_CLIENT_CERT_PATH
+ HCERTSTORE client_cert_store;
+#endif
+ int refcount;
+};
+
+struct Curl_schannel_ctxt {
+ CtxtHandle ctxt_handle;
+ TimeStamp time_stamp;
+};
+
+struct schannel_ssl_backend_data {
+ struct Curl_schannel_cred *cred;
+ struct Curl_schannel_ctxt *ctxt;
+ SecPkgContext_StreamSizes stream_sizes;
+ size_t encdata_length, decdata_length;
+ size_t encdata_offset, decdata_offset;
+ unsigned char *encdata_buffer, *decdata_buffer;
+ /* encdata_is_incomplete: if encdata contains only a partial record that
+ can't be decrypted without another recv() (that is, status is
+ SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
+ more bytes into encdata then set this back to false. */
+ bool encdata_is_incomplete;
+ unsigned long req_flags, ret_flags;
+ CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
+ bool recv_sspi_close_notify; /* true if connection closed by close_notify */
+ bool recv_connection_closed; /* true if connection closed, regardless how */
+ bool recv_renegotiating; /* true if recv is doing renegotiation */
+ bool use_alpn; /* true if ALPN is used for this connection */
+#ifdef HAS_MANUAL_VERIFY_API
+ bool use_manual_cred_validation; /* true if manual cred validation is used */
+#endif
+};
+
+#endif /* USE_SCHANNEL */
+#endif /* HEADER_CURL_SCHANNEL_INT_H */
diff --git a/Utilities/cmcurl/lib/vtls/schannel_verify.c b/Utilities/cmcurl/lib/vtls/schannel_verify.c
index d75ee8d..c582ee4 100644
--- a/Utilities/cmcurl/lib/vtls/schannel_verify.c
+++ b/Utilities/cmcurl/lib/vtls/schannel_verify.c
@@ -36,8 +36,8 @@
# error "Can't compile SCHANNEL support without SSPI."
#endif
-#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
#include "schannel.h"
+#include "schannel_int.h"
#ifdef HAS_MANUAL_VERIFY_API
@@ -54,7 +54,7 @@
#include "curl_memory.h"
#include "memdebug.h"
-#define BACKEND connssl->backend
+#define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend)
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.c b/Utilities/cmcurl/lib/vtls/sectransp.c
index c9f02f2..32bb3a5 100644
--- a/Utilities/cmcurl/lib/vtls/sectransp.c
+++ b/Utilities/cmcurl/lib/vtls/sectransp.c
@@ -146,7 +146,7 @@
#define ioErr -36
#define paramErr -50
-struct ssl_backend_data {
+struct st_ssl_backend_data {
SSLContextRef ssl_ctx;
bool ssl_direction; /* true if writing, false if reading */
size_t ssl_write_buffered_length;
@@ -836,7 +836,8 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
CURLcode result;
@@ -859,6 +860,9 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
}
nread = 0;
}
+ else if(nread == 0) {
+ rtn = errSSLClosedGraceful;
+ }
else if((size_t)nread < *dataLength) {
rtn = errSSLWouldBlock;
}
@@ -872,7 +876,8 @@ static OSStatus bio_cf_out_write(SSLConnectionRef connection,
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
CURLcode result;
@@ -1338,7 +1343,8 @@ static CURLcode set_ssl_version_min_max(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
long ssl_version_max = conn_config->version_max;
@@ -1633,7 +1639,8 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
const struct curl_blob *ssl_cablob = conn_config->ca_info_blob;
@@ -2515,7 +2522,8 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
OSStatus err;
SSLCipherSuite cipher;
@@ -2896,7 +2904,8 @@ static CURLcode collect_server_cert(struct Curl_cfilter *cf,
CURLcode result = ssl_config->certinfo ?
CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
OSStatus err;
@@ -3139,7 +3148,8 @@ static CURLcode sectransp_connect(struct Curl_cfilter *cf,
static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
(void) data;
@@ -3166,7 +3176,8 @@ static int sectransp_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
ssize_t nread;
int what;
int rc;
@@ -3244,7 +3255,8 @@ static bool sectransp_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
const struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
OSStatus err;
size_t buffer;
@@ -3308,7 +3320,8 @@ static ssize_t sectransp_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
size_t processed = 0UL;
OSStatus err;
@@ -3376,7 +3389,8 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
size_t processed = 0UL;
OSStatus err;
@@ -3434,7 +3448,8 @@ again:
static void *sectransp_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->ssl_ctx;
@@ -3450,7 +3465,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
#endif /* SECTRANSP_PINNEDPUBKEY */
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct st_ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index a4ff7d6..510bcfe 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -453,7 +453,7 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf,
}
}
- DEBUGF(infof(data, DMSG(data, "%s Session ID in cache for %s %s://%s:%d"),
+ DEBUGF(infof(data, "%s Session ID in cache for %s %s://%s:%d",
no_match? "Didn't find": "Found",
Curl_ssl_cf_is_proxy(cf) ? "proxy" : "host",
cf->conn->handler->scheme, connssl->hostname, connssl->port));
@@ -601,8 +601,8 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
if(added)
*added = TRUE;
- DEBUGF(infof(data, DMSG(data, "Added Session ID to cache for %s://%s:%d"
- " [%s]"), store->scheme, store->name, store->remote_port,
+ DEBUGF(infof(data, "Added Session ID to cache for %s://%s:%d [%s]",
+ store->scheme, store->name, store->remote_port,
Curl_ssl_cf_is_proxy(cf) ? "PROXY" : "server"));
return CURLE_OK;
}
@@ -893,8 +893,8 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
/* only do this if pinnedpubkey starts with "sha256//", length 8 */
if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
CURLcode encode;
- size_t encodedlen, pinkeylen;
- char *encoded, *pinkeycopy, *begin_pos, *end_pos;
+ size_t encodedlen = 0, pinkeylen;
+ char *encoded = NULL, *pinkeycopy, *begin_pos, *end_pos;
unsigned char *sha256sumdigest;
if(!Curl_ssl->sha256sum) {
@@ -907,14 +907,12 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
if(!sha256sumdigest)
return CURLE_OUT_OF_MEMORY;
encode = Curl_ssl->sha256sum(pubkey, pubkeylen,
- sha256sumdigest, CURL_SHA256_DIGEST_LENGTH);
+ sha256sumdigest, CURL_SHA256_DIGEST_LENGTH);
- if(encode != CURLE_OK)
- return encode;
-
- encode = Curl_base64_encode((char *)sha256sumdigest,
- CURL_SHA256_DIGEST_LENGTH, &encoded,
- &encodedlen);
+ if(!encode)
+ encode = Curl_base64_encode((char *)sha256sumdigest,
+ CURL_SHA256_DIGEST_LENGTH, &encoded,
+ &encodedlen);
Curl_safefree(sha256sumdigest);
if(encode)
@@ -1506,7 +1504,7 @@ static void ssl_cf_close(struct Curl_cfilter *cf,
CF_DATA_SAVE(save, cf, data);
cf_close(cf, data);
- cf->next->cft->close(cf->next, data);
+ cf->next->cft->do_close(cf->next, data);
CF_DATA_RESTORE(cf, save);
}
@@ -1530,7 +1528,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
DEBUGASSERT(connssl);
DEBUGASSERT(cf->conn->host.name);
- result = cf->next->cft->connect(cf->next, data, blocking, done);
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
if(result || !*done)
goto out;
@@ -1594,6 +1592,7 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
ssize_t nread;
CF_DATA_SAVE(save, cf, data);
+ *err = CURLE_OK;
nread = Curl_ssl->recv_plain(cf, data, buf, len, err);
if(nread > 0) {
DEBUGASSERT((size_t)nread <= len);
diff --git a/Utilities/cmcurl/lib/vtls/vtls_int.h b/Utilities/cmcurl/lib/vtls/vtls_int.h
index ed49339..fe0115c 100644
--- a/Utilities/cmcurl/lib/vtls/vtls_int.h
+++ b/Utilities/cmcurl/lib/vtls/vtls_int.h
@@ -73,7 +73,7 @@ struct ssl_connect_data {
char *hostname; /* hostname for verification */
char *dispname; /* display version of hostname */
const struct alpn_spec *alpn; /* ALPN to use or NULL for none */
- struct ssl_backend_data *backend; /* vtls backend specific props */
+ void *backend; /* vtls backend specific props */
struct cf_call_data call_data; /* data handle used in current call */
struct curltime handshake_done; /* time when handshake finished */
int port; /* remote port at origin */
@@ -81,6 +81,7 @@ struct ssl_connect_data {
};
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct ssl_connect_data *)(cf)->ctx)->call_data
diff --git a/Utilities/cmcurl/lib/vtls/wolfssl.c b/Utilities/cmcurl/lib/vtls/wolfssl.c
index 2928728..6cfc201 100644
--- a/Utilities/cmcurl/lib/vtls/wolfssl.c
+++ b/Utilities/cmcurl/lib/vtls/wolfssl.c
@@ -91,7 +91,7 @@
#undef USE_BIO_CHAIN
#endif
-struct ssl_backend_data {
+struct wolfssl_ssl_backend_data {
SSL_CTX* ctx;
SSL* handle;
CURLcode io_result; /* result of last BIO cfilter operation */
@@ -281,13 +281,15 @@ static int bio_cf_out_write(WOLFSSL_BIO *bio, const char *buf, int blen)
{
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
CURLcode result = CURLE_OK;
DEBUGASSERT(data);
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
- connssl->backend->io_result = result;
+ backend->io_result = result;
DEBUGF(LOG_CF(data, cf, "bio_write(len=%d) -> %zd, %d",
blen, nwritten, result));
wolfSSL_BIO_clear_retry_flags(bio);
@@ -300,6 +302,8 @@ static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
{
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
CURLcode result = CURLE_OK;
@@ -310,7 +314,7 @@ static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
return 0;
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
- connssl->backend->io_result = result;
+ backend->io_result = result;
DEBUGF(LOG_CF(data, cf, "bio_read(len=%d) -> %zd, %d",
blen, nread, result));
wolfSSL_BIO_clear_retry_flags(bio);
@@ -352,8 +356,10 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
char *ciphers, *curves;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SSL_METHOD* req_method = NULL;
#ifdef HAVE_LIBOQS
@@ -366,6 +372,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
#else
#define use_sni(x) Curl_nop_stmt
#endif
+ bool imported_ca_info_blob = false;
DEBUGASSERT(backend);
@@ -410,8 +417,13 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
#endif
break;
case CURL_SSLVERSION_TLSv1_2:
+#ifndef WOLFSSL_NO_TLS12
req_method = TLSv1_2_client_method();
use_sni(TRUE);
+#else
+ failf(data, "wolfSSL does not support TLS 1.2");
+ return CURLE_NOT_BUILT_IN;
+#endif
break;
case CURL_SSLVERSION_TLSv1_3:
#ifdef WOLFSSL_TLS13
@@ -494,13 +506,28 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
}
}
}
+
+ if(ca_info_blob) {
+ if(wolfSSL_CTX_load_verify_buffer(
+ backend->ctx, ca_info_blob->data, ca_info_blob->len,
+ SSL_FILETYPE_PEM
+ ) != SSL_SUCCESS) {
+ failf(data, "error importing CA certificate blob");
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else {
+ imported_ca_info_blob = true;
+ infof(data, "successfully imported CA certificate blob");
+ }
+ }
+
#ifndef NO_FILESYSTEM
/* load trusted cacert */
if(conn_config->CAfile) {
if(1 != SSL_CTX_load_verify_locations(backend->ctx,
conn_config->CAfile,
conn_config->CApath)) {
- if(conn_config->verifypeer) {
+ if(conn_config->verifypeer && !imported_ca_info_blob) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:"
" CAfile: %s CApath: %s",
@@ -699,7 +726,8 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
int ret = -1;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
@@ -892,7 +920,8 @@ wolfssl_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -950,7 +979,8 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
int rc;
@@ -992,7 +1022,8 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf,
static void wolfssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
(void) data;
@@ -1019,7 +1050,8 @@ static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int buffsize = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
int nread;
@@ -1108,11 +1140,14 @@ static bool wolfssl_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->handle) /* SSL is in use */
- return (0 != SSL_pending(ctx->backend->handle)) ? TRUE : FALSE;
+
+ backend = (struct wolfssl_ssl_backend_data *)ctx->backend;
+ if(backend->handle) /* SSL is in use */
+ return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
else
return FALSE;
}
@@ -1126,15 +1161,17 @@ static int wolfssl_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend;
int retval = 0;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->handle) {
+ backend = (struct wolfssl_ssl_backend_data *)ctx->backend;
+ if(backend->handle) {
ERR_clear_error();
- SSL_free(ctx->backend->handle);
- ctx->backend->handle = NULL;
+ SSL_free(backend->handle);
+ backend->handle = NULL;
}
return retval;
}
@@ -1305,7 +1342,8 @@ static CURLcode wolfssl_sha256sum(const unsigned char *tmp, /* input */
static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->handle;
@@ -1320,9 +1358,10 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
#ifdef USE_BIO_CHAIN
SSLSUPP_HTTPS_PROXY |
#endif
+ SSLSUPP_CAINFO_BLOB |
SSLSUPP_SSL_CTX,
- sizeof(struct ssl_backend_data),
+ sizeof(struct wolfssl_ssl_backend_data),
wolfssl_init, /* init */
wolfssl_cleanup, /* cleanup */
diff --git a/Utilities/cmcurl/lib/warnless.c b/Utilities/cmcurl/lib/warnless.c
index 10c91fb..65c5ec5 100644
--- a/Utilities/cmcurl/lib/warnless.c
+++ b/Utilities/cmcurl/lib/warnless.c
@@ -35,10 +35,13 @@
#endif /* __INTEL_COMPILER && __unix__ */
-#define BUILDING_WARNLESS_C 1
-
#include "warnless.h"
+#ifdef WIN32
+#undef read
+#undef write
+#endif
+
#include <limits.h>
#define CURL_MASK_UCHAR ((unsigned char)~0)
@@ -376,6 +379,9 @@ ssize_t curlx_write(int fd, const void *buf, size_t count)
return (ssize_t)write(fd, buf, curlx_uztoui(count));
}
+/* Ensure that warnless.h continues to have an effect in "unity" builds. */
+#undef HEADER_CURL_WARNLESS_H
+
#endif /* WIN32 */
#if defined(__INTEL_COMPILER) && defined(__unix__)
diff --git a/Utilities/cmcurl/lib/warnless.h b/Utilities/cmcurl/lib/warnless.h
index 99b2433..2a53016 100644
--- a/Utilities/cmcurl/lib/warnless.h
+++ b/Utilities/cmcurl/lib/warnless.h
@@ -75,12 +75,10 @@ ssize_t curlx_read(int fd, void *buf, size_t count);
ssize_t curlx_write(int fd, const void *buf, size_t count);
-#ifndef BUILDING_WARNLESS_C
-# undef read
-# define read(fd, buf, count) curlx_read(fd, buf, count)
-# undef write
-# define write(fd, buf, count) curlx_write(fd, buf, count)
-#endif
+#undef read
+#define read(fd, buf, count) curlx_read(fd, buf, count)
+#undef write
+#define write(fd, buf, count) curlx_write(fd, buf, count)
#endif /* WIN32 */
diff --git a/Utilities/cmcurl/lib/ws.c b/Utilities/cmcurl/lib/ws.c
index c60bbc9..3c1964b 100644
--- a/Utilities/cmcurl/lib/ws.c
+++ b/Utilities/cmcurl/lib/ws.c
@@ -126,8 +126,9 @@ static void ws_dec_info(struct ws_decoder *dec, struct Curl_easy *data,
dec->head_len, dec->head_total);
}
else {
- infof(data, "WS-DEC: %s [%s%s payload=%zd/%zd]", msg,
- ws_frame_name_of_op(dec->head[0]),
+ infof(data, "WS-DEC: %s [%s%s payload=%" CURL_FORMAT_CURL_OFF_T
+ "/%" CURL_FORMAT_CURL_OFF_T "]",
+ msg, ws_frame_name_of_op(dec->head[0]),
(dec->head[0] & WSBIT_FIN)? "" : " NON-FINAL",
dec->payload_offset, dec->payload_len);
}
@@ -272,7 +273,8 @@ static CURLcode ws_dec_pass_payload(struct ws_decoder *dec,
Curl_bufq_skip(inraw, (size_t)nwritten);
dec->payload_offset += (curl_off_t)nwritten;
remain = dec->payload_len - dec->payload_offset;
- /* infof(data, "WS-DEC: passed %zd bytes payload, %zd remain",
+ /* infof(data, "WS-DEC: passed %zd bytes payload, %"
+ CURL_FORMAT_CURL_OFF_T " remain",
nwritten, remain); */
}
@@ -351,8 +353,9 @@ static void update_meta(struct websocket *ws,
static void ws_enc_info(struct ws_encoder *enc, struct Curl_easy *data,
const char *msg)
{
- infof(data, "WS-ENC: %s [%s%s%s payload=%zd/%zd]", msg,
- ws_frame_name_of_op(enc->firstbyte),
+ infof(data, "WS-ENC: %s [%s%s%s payload=%" CURL_FORMAT_CURL_OFF_T
+ "/%" CURL_FORMAT_CURL_OFF_T "]",
+ msg, ws_frame_name_of_op(enc->firstbyte),
(enc->firstbyte & WSBIT_OPCODE_MASK) == WSBIT_OPCODE_CONT ?
" CONT" : "",
(enc->firstbyte & WSBIT_FIN)? "" : " NON-FIN",
@@ -839,7 +842,7 @@ static ssize_t nw_in_recv(void *reader_ctx,
CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer,
size_t buflen, size_t *nread,
- struct curl_ws_frame **metap)
+ const struct curl_ws_frame **metap)
{
struct connectdata *conn = data->conn;
struct websocket *ws;
@@ -921,7 +924,8 @@ CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer,
ctx.payload_len, ctx.bufidx);
*metap = &ws->frame;
*nread = ws->frame.len;
- /* infof(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %zd, %zd left)",
+ /* infof(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %"
+ CURL_FORMAT_CURL_OFF_T ", %" CURL_FORMAT_CURL_OFF_T " left)",
buflen, *nread, ws->frame.offset, ws->frame.bytesleft); */
return CURLE_OK;
}
@@ -966,10 +970,10 @@ static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws,
return CURLE_OK;
}
-CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer,
+CURL_EXTERN CURLcode curl_ws_send(CURL *data, const void *buffer,
size_t buflen, size_t *sent,
- curl_off_t totalsize,
- unsigned int sendflags)
+ curl_off_t fragsize,
+ unsigned int flags)
{
struct websocket *ws;
ssize_t nwritten, n;
@@ -987,14 +991,13 @@ CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer,
return CURLE_SEND_ERROR;
}
if(!data->conn->proto.ws) {
- failf(data, "Not a websocket transfer on connection #%ld",
- data->conn->connection_id);
+ failf(data, "Not a websocket transfer");
return CURLE_SEND_ERROR;
}
ws = data->conn->proto.ws;
if(data->set.ws_raw_mode) {
- if(totalsize || sendflags)
+ if(fragsize || flags)
return CURLE_BAD_FUNCTION_ARGUMENT;
if(!buflen)
/* nothing to do */
@@ -1027,23 +1030,24 @@ CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer,
if(space < 14)
return CURLE_AGAIN;
- if(sendflags & CURLWS_OFFSET) {
- if(totalsize) {
- /* a frame series 'totalsize' bytes big, this is the first */
- n = ws_enc_write_head(data, &ws->enc, sendflags, totalsize,
+ if(flags & CURLWS_OFFSET) {
+ if(fragsize) {
+ /* a frame series 'fragsize' bytes big, this is the first */
+ n = ws_enc_write_head(data, &ws->enc, flags, fragsize,
&ws->sendbuf, &result);
if(n < 0)
return result;
}
else {
if((curl_off_t)buflen > ws->enc.payload_remain) {
- infof(data, "WS: unaligned frame size (sending %zu instead of %zd)",
+ infof(data, "WS: unaligned frame size (sending %zu instead of %"
+ CURL_FORMAT_CURL_OFF_T ")",
buflen, ws->enc.payload_remain);
}
}
}
else if(!ws->enc.payload_remain) {
- n = ws_enc_write_head(data, &ws->enc, sendflags, (curl_off_t)buflen,
+ n = ws_enc_write_head(data, &ws->enc, flags, (curl_off_t)buflen,
&ws->sendbuf, &result);
if(n < 0)
return result;
@@ -1082,7 +1086,7 @@ CURLcode Curl_ws_disconnect(struct Curl_easy *data,
return CURLE_OK;
}
-CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
{
/* we only return something for websocket, called from within the callback
when not using raw mode */
@@ -1096,7 +1100,7 @@ CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
size_t *nread,
- struct curl_ws_frame **metap)
+ const struct curl_ws_frame **metap)
{
(void)curl;
(void)buffer;
@@ -1108,19 +1112,19 @@ CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
size_t buflen, size_t *sent,
- curl_off_t framesize,
- unsigned int sendflags)
+ curl_off_t fragsize,
+ unsigned int flags)
{
(void)curl;
(void)buffer;
(void)buflen;
(void)sent;
- (void)framesize;
- (void)sendflags;
+ (void)fragsize;
+ (void)flags;
return CURLE_NOT_BUILT_IN;
}
-CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
{
(void)data;
return NULL;
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index bee69c2..e820853 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -246,6 +246,10 @@ ENDIF()
ADD_LIBRARY(cmlibarchive STATIC ${libarchive_SOURCES} ${include_HEADERS})
TARGET_LINK_LIBRARIES(cmlibarchive ${ADDITIONAL_LIBS})
+if(WIN32 AND CMake_BUILD_PCH)
+ target_precompile_headers(cmlibarchive PRIVATE "archive_platform.h" "archive_entry.h" "<cm3p/bzlib.h>")
+endif()
+
IF(0) # CMake does not build libarchive's full package.
# Libarchive is a shared library
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt
index 3121fbe..3ba3ce9 100644
--- a/Utilities/cmliblzma/CMakeLists.txt
+++ b/Utilities/cmliblzma/CMakeLists.txt
@@ -186,4 +186,8 @@ ELSEIF((CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "LCC"
SET_PROPERTY(TARGET cmliblzma PROPERTY COMPILE_FLAGS "-O0")
ENDIF()
+if(WIN32 AND CMake_BUILD_PCH)
+ target_precompile_headers(cmliblzma PRIVATE "common/mythread.h")
+endif()
+
INSTALL(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmliblzma)
diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt
index ad3d433..a0b161b 100644
--- a/Utilities/cmlibuv/CMakeLists.txt
+++ b/Utilities/cmlibuv/CMakeLists.txt
@@ -294,27 +294,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
)
list(APPEND uv_defines
__EXTENSIONS__
+ _XOPEN_SOURCE=600
)
+ if(NOT CMAKE_C_STANDARD OR CMAKE_C_STANDARD EQUAL 90)
+ set(CMAKE_C_STANDARD 11)
+ endif()
if(CMAKE_SYSTEM_VERSION STREQUAL "5.10")
- set(CMAKE_C_STANDARD 90)
- if(CMAKE_VERSION VERSION_LESS 3.8.20170504 AND CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.14)
- # The running version of CMake does not know how to add this flag.
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c90")
- endif()
- list(APPEND uv_defines
- _XOPEN_SOURCE=500
- )
- else()
- if(NOT CMAKE_C_STANDARD OR CMAKE_C_STANDARD EQUAL 90)
- set(CMAKE_C_STANDARD 11)
- endif()
- if(CMAKE_VERSION VERSION_LESS 3.8.20170505 AND CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5.14)
- # The running version of CMake does not know how to add this flag.
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -xc99")
- endif()
- list(APPEND uv_defines
- _XOPEN_SOURCE=600
- )
+ list(APPEND uv_defines SUNOS_NO_IFADDRS)
endif()
list(APPEND uv_sources
src/unix/no-proctitle.c
@@ -365,4 +351,8 @@ add_library(cmlibuv STATIC ${uv_sources})
target_link_libraries(cmlibuv ${uv_libraries})
set_property(TARGET cmlibuv PROPERTY COMPILE_DEFINITIONS ${uv_defines})
+if(WIN32 AND CMake_BUILD_PCH)
+ target_precompile_headers(cmlibuv PRIVATE "include/uv.h" "src/win/internal.h")
+endif()
+
install(FILES LICENSE DESTINATION ${CMAKE_DOC_DIR}/cmlibuv)
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c
index 0de5c46..30872cf 100644
--- a/Utilities/cmlibuv/src/unix/process.c
+++ b/Utilities/cmlibuv/src/unix/process.c
@@ -75,7 +75,9 @@ extern char **environ;
#endif
#endif
-#if defined(__APPLE__) || \
+#ifdef CMAKE_BOOTSTRAP
+#define UV_USE_SIGCHLD
+#elif defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__NetBSD__) || \
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c
index 248b7ea..3b5b2800 100644
--- a/Utilities/cmlibuv/src/win/process.c
+++ b/Utilities/cmlibuv/src/win/process.c
@@ -394,7 +394,7 @@ static WCHAR* search_path(const WCHAR *file,
name_has_ext);
while (result == NULL) {
- if (*dir_end == L'\0') {
+ if (dir_end == NULL || *dir_end == L'\0') {
break;
}
@@ -1027,22 +1027,19 @@ int uv_spawn(uv_loop_t* loop,
DWORD path_len, r;
path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
- if (path_len == 0) {
- err = GetLastError();
- goto done;
- }
-
- alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
- if (alloc_path == NULL) {
- err = ERROR_OUTOFMEMORY;
- goto done;
- }
- path = alloc_path;
+ if (path_len != 0) {
+ alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
+ if (alloc_path == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+ path = alloc_path;
- r = GetEnvironmentVariableW(L"PATH", path, path_len);
- if (r == 0 || r >= path_len) {
- err = GetLastError();
- goto done;
+ r = GetEnvironmentVariableW(L"PATH", path, path_len);
+ if (r == 0 || r >= path_len) {
+ err = GetLastError();
+ goto done;
+ }
}
}
diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm
index 11514fc..46377f4 100644
--- a/Utilities/std/cmext/algorithm
+++ b/Utilities/std/cmext/algorithm
@@ -16,6 +16,7 @@
#if defined(__SUNPRO_CC) && defined(__sparc)
# include <list>
+# include <string>
# include <vector>
#endif
@@ -67,11 +68,15 @@ namespace cm {
APPEND_TWO(C1, C2) \
APPEND_TWO(C2, C1)
-// For now, manage only support for std::vector and std::list.
-// Other sequential container support can be added if needed.
+// For now, manage only support for std::vector, std::list, and
+// std::basic_string. Other sequential container support can be added if
+// needed.
APPEND(std::vector)
APPEND(std::list)
+APPEND(std::basic_string)
APPEND_MIX(std::vector, std::list)
+APPEND_MIX(std::vector, std::basic_string)
+APPEND_MIX(std::list, std::basic_string)
# undef APPEND
# undef APPEND_MIX
diff --git a/Utilities/std/cmext/iterator b/Utilities/std/cmext/iterator
index eba10dd..85a28fa 100644
--- a/Utilities/std/cmext/iterator
+++ b/Utilities/std/cmext/iterator
@@ -24,9 +24,18 @@ using is_input_iterator =
// checks if a type is a range type: std::begin() and std::end() are supported
template <typename Range>
-using is_range = cm::bool_constant<
- cm::is_iterator<decltype(std::begin(std::declval<const Range>()))>::value &&
- cm::is_iterator<decltype(std::end(std::declval<const Range>()))>::value>;
+using is_range =
+#if defined(_MSC_VER) && _MSC_VER < 1920
+ // MS C++ is not able to evaluate complex type introspection,
+ // so use a simplified version
+ cm::bool_constant<std::is_class<Range>::value ||
+ std::is_array<Range>::value>;
+#else
+ cm::bool_constant<
+ cm::is_iterator<decltype(std::begin(
+ std::declval<const Range>()))>::value &&
+ cm::is_iterator<decltype(std::end(std::declval<const Range>()))>::value>;
+#endif
// checks if a type is an input range type: std::begin() and std::end() are
// returning an input iterator
diff --git a/bootstrap b/bootstrap
index cc60425..2b7ddfe 100755
--- a/bootstrap
+++ b/bootstrap
@@ -333,6 +333,7 @@ CMAKE_CXX_SOURCES="\
cmCustomCommandGenerator \
cmCustomCommandLines \
cmCxxModuleMapper \
+ cmCxxModuleUsageEffects \
cmDefinePropertyCommand \
cmDefinitions \
cmDocumentationFormatter \
@@ -392,6 +393,7 @@ CMAKE_CXX_SOURCES="\
cmGlobVerificationManager \
cmHexFileConverter \
cmIfCommand \
+ cmImportedCxxModuleInfo \
cmIncludeCommand \
cmIncludeGuardCommand \
cmIncludeDirectoryCommand \
@@ -414,6 +416,8 @@ CMAKE_CXX_SOURCES="\
cmInstallTargetGenerator \
cmInstallTargetsCommand \
cmInstalledFile \
+ cmJSONHelpers \
+ cmJSONState \
cmLDConfigLDConfigTool \
cmLDConfigTool \
cmLinkDirectoriesCommand \
@@ -450,6 +454,7 @@ CMAKE_CXX_SOURCES="\
cmGccDepfileReader \
cmReturnCommand \
cmPlaceholderExpander \
+ cmPlistParser \
cmRulePlaceholderExpander \
cmRuntimeDependencyArchive \
cmScriptGenerator \
@@ -499,9 +504,11 @@ CMAKE_CXX_SOURCES="\
cmWhileCommand \
cmWindowsRegistry \
cmWorkingDirectory \
+ cmXcFramework \
cmake \
cmakemain \
cmcmd \
+ cm_fileno \
"
if ${cmake_system_mingw}; then
@@ -588,6 +595,12 @@ LIBRHASH_C_SOURCES="\
librhash/sha512.c \
"
+JSONCPP_CXX_SOURCES="\
+ src/lib_json/json_reader.cpp \
+ src/lib_json/json_value.cpp \
+ src/lib_json/json_writer.cpp \
+ "
+
if ${cmake_system_mingw}; then
LIBUV_C_SOURCES="\
src/fs-poll.c \
@@ -1091,12 +1104,6 @@ if test "${cmake_bootstrap_generator}" = "Ninja"; then
cmFortranLexer \
cmFortranParser \
"
-
- JSONCPP_CXX_SOURCES="\
- src/lib_json/json_reader.cpp \
- src/lib_json/json_value.cpp \
- src/lib_json/json_writer.cpp \
- "
else
CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
cmDepends \
@@ -1110,8 +1117,6 @@ else
cmMakefileUtilityTargetGenerator \
cmProcessTools \
"
-
- JSONCPP_CXX_SOURCES=
fi
# Add Cygwin-specific flags
@@ -1725,12 +1730,10 @@ if test "x${bootstrap_system_librhash}" = "x"; then
objs="${objs} rhash-`cmake_obj ${a}`"
done
fi
-if test "${cmake_bootstrap_generator}" = "Ninja"; then
- if test "x${bootstrap_system_jsoncpp}" = "x"; then
- for a in ${JSONCPP_CXX_SOURCES}; do
- objs="${objs} jsoncpp-`cmake_obj ${a}`"
- done
- fi
+if test "x${bootstrap_system_jsoncpp}" = "x"; then
+ for a in ${JSONCPP_CXX_SOURCES}; do
+ objs="${objs} jsoncpp-`cmake_obj ${a}`"
+ done
fi
libs=""
@@ -1762,8 +1765,6 @@ else
libs="${libs} -lkvm"
;;
*SunOS*)
- # Normally libuv uses '-D_XOPEN_SOURCE=500 -std=c90' on Solaris 5.10,
- # but we do not need to do that because we bootstrap using POSIX APIs.
uv_c_flags="${uv_c_flags} -D__EXTENSIONS__ -D_XOPEN_SOURCE=600"
libs="${libs} -lkstat -lnsl -lsendfile -lsocket -lrt"
;;
@@ -1799,17 +1800,15 @@ if test "x${bootstrap_system_librhash}" != "x"; then
libs="${libs} -lrhash"
fi
-if test "${cmake_bootstrap_generator}" = "Ninja"; then
- jsoncpp_cxx_flags=
- if test "x${bootstrap_system_jsoncpp}" = "x"; then
- jsoncpp_cxx_flags="${jsoncpp_cxx_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmjsoncpp/include"`"
- else
- if test `which pkg-config`; then
- use_jsoncpp_flags="`pkg-config --cflags jsoncpp`"
- cmake_cxx_flags="${cmake_cxx_flags} ${use_jsoncpp_flags}"
- fi
- libs="${libs} -ljsoncpp"
+jsoncpp_cxx_flags=
+if test "x${bootstrap_system_jsoncpp}" = "x"; then
+ jsoncpp_cxx_flags="${jsoncpp_cxx_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmjsoncpp/include"`"
+else
+ if test `which pkg-config`; then
+ use_jsoncpp_flags="`pkg-config --cflags jsoncpp`"
+ cmake_cxx_flags="${cmake_cxx_flags} ${use_jsoncpp_flags}"
fi
+ libs="${libs} -ljsoncpp"
fi
if test "x${cmake_ansi_cxx_flags}" != "x"; then
@@ -1949,13 +1948,11 @@ if test "x${bootstrap_system_librhash}" = "x"; then
write_source_rule "c" "rhash-`cmake_obj ${a}`" "${src}" ""
done
fi
-if test "${cmake_bootstrap_generator}" = "Ninja"; then
- if test "x${bootstrap_system_jsoncpp}" = "x"; then
- for a in ${JSONCPP_CXX_SOURCES}; do
- src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmjsoncpp/${a}"`
- write_source_rule "cxx" "jsoncpp-`cmake_obj ${a}`" "${src}" "${jsoncpp_cxx_flags}"
- done
- fi
+if test "x${bootstrap_system_jsoncpp}" = "x"; then
+ for a in ${JSONCPP_CXX_SOURCES}; do
+ src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmjsoncpp/${a}"`
+ write_source_rule "cxx" "jsoncpp-`cmake_obj ${a}`" "${src}" "${jsoncpp_cxx_flags}"
+ done
fi
if test "${cmake_bootstrap_generator}" = "Ninja"; then
echo "
diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in
index b5fc700..9e61b00 100644
--- a/cmake_uninstall.cmake.in
+++ b/cmake_uninstall.cmake.in
@@ -7,10 +7,10 @@ string(REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if(EXISTS "$ENV{DESTDIR}${file}")
- exec_program(
- "@CMAKE_COMMAND@" ARGS "-E rm -f \"$ENV{DESTDIR}${file}\""
+ execute_process(
+ COMMAND "@CMAKE_COMMAND@" -E rm -f "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
- RETURN_VALUE rm_retval
+ RESULT_VARIABLE rm_retval
)
if("${rm_retval}" STREQUAL 0)
else()