summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--CMakeLists.txt21
-rw-r--r--Help/command/ctest_start.rst29
-rw-r--r--Help/command/target_precompile_headers.rst56
-rw-r--r--Help/dev/source.rst2
-rw-r--r--Help/manual/OPTIONS_BUILD.txt3
-rw-r--r--Help/manual/cmake-commands.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst5
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/manual/ctest.1.rst11
-rw-r--r--Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst13
-rw-r--r--Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst8
-rw-r--r--Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst14
-rw-r--r--Help/prop_tgt/PRECOMPILE_HEADERS.rst12
-rw-r--r--Help/prop_tgt/Swift_LANGUAGE_VERSION.rst6
-rw-r--r--Help/prop_tgt/VS_CONFIGURATION_TYPE.rst2
-rw-r--r--Help/release/dev/cmake-initial-cache-dirs.rst6
-rw-r--r--Help/release/dev/precompile-headers.rst6
-rw-r--r--Help/release/dev/vs-configuration-type-genex.rst5
-rw-r--r--Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst6
-rw-r--r--Modules/Compiler/Clang.cmake2
-rw-r--r--Modules/Compiler/GNU.cmake8
-rw-r--r--Modules/Compiler/Intel.cmake7
-rw-r--r--Modules/FindLibLZMA.cmake45
-rw-r--r--Modules/GNUInstallDirs.cmake3
-rw-r--r--Modules/GetPrerequisites.cmake2
-rwxr-xr-xModules/Internal/CPack/CPack.STGZ_Header.sh.in22
-rw-r--r--Modules/Platform/Windows-Clang.cmake7
-rw-r--r--Modules/Platform/Windows-Embarcadero.cmake7
-rw-r--r--Modules/Platform/Windows-MSVC.cmake9
-rw-r--r--Source/CMakeLists.txt4
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/IFW/cmCPackIFWCommon.cxx6
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx122
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx3
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx14
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx8
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx3
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx12
-rw-r--r--Source/CPack/cmCPackGenerator.cxx34
-rw-r--r--Source/CPack/cmCPackLog.cxx10
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx8
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx4
-rw-r--r--Source/CPack/cpack.cxx3
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx13
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx27
-rw-r--r--Source/CTest/cmCTestBuildHandler.h4
-rw-r--r--Source/CTest/cmCTestGIT.cxx3
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx5
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx9
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx5
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx3
-rw-r--r--Source/CTest/cmCTestP4.cxx3
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.cxx6
-rw-r--r--Source/CTest/cmCTestRunTest.cxx3
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx9
-rw-r--r--Source/CTest/cmCTestStartCommand.cxx14
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx6
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx17
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx38
-rw-r--r--Source/Checks/cm_cxx17_check.cpp5
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx3
-rw-r--r--Source/cmAddExecutableCommand.cxx4
-rw-r--r--Source/cmAddLibraryCommand.cxx68
-rw-r--r--Source/cmAffinity.cxx2
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx5
-rw-r--r--Source/cmCTest.cxx63
-rw-r--r--Source/cmCTest.h6
-rw-r--r--Source/cmCacheManager.cxx3
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx4
-rw-r--r--Source/cmCommands.cxx26
-rw-r--r--Source/cmComputeLinkDepends.cxx3
-rw-r--r--Source/cmComputeLinkInformation.cxx15
-rw-r--r--Source/cmConditionEvaluator.cxx3
-rw-r--r--Source/cmCoreTryCompile.cxx3
-rw-r--r--Source/cmDisallowedCommand.cxx29
-rw-r--r--Source/cmDisallowedCommand.h47
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx7
-rw-r--r--Source/cmExportBuildFileGenerator.cxx3
-rw-r--r--Source/cmExportFileGenerator.cxx7
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx16
-rw-r--r--Source/cmExportLibraryDependenciesCommand.h16
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx3
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx2
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx15
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx9
-rw-r--r--Source/cmFileAPICodemodel.cxx2
-rw-r--r--Source/cmFileCopier.cxx9
-rw-r--r--Source/cmFindBase.cxx2
-rw-r--r--Source/cmFunctionCommand.cxx4
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h3
-rw-r--r--Source/cmGeneratorExpressionNode.cxx15
-rw-r--r--Source/cmGeneratorTarget.cxx197
-rw-r--r--Source/cmGeneratorTarget.h12
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx4
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx3
-rw-r--r--Source/cmGlobalGenerator.cxx21
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx4
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx21
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h7
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx18
-rw-r--r--Source/cmGraphVizWriter.cxx4
-rw-r--r--Source/cmInstallCommand.cxx16
-rw-r--r--Source/cmJsonObjects.cxx2
-rw-r--r--Source/cmLDConfigLDConfigTool.cxx3
-rw-r--r--Source/cmListCommand.cxx160
-rw-r--r--Source/cmListFileCache.cxx3
-rw-r--r--Source/cmLoadCommandCommand.cxx28
-rw-r--r--Source/cmLoadCommandCommand.h16
-rw-r--r--Source/cmLocalGenerator.cxx130
-rw-r--r--Source/cmLocalGenerator.h2
-rw-r--r--Source/cmLocalNinjaGenerator.cxx3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx10
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx5
-rw-r--r--Source/cmMacroCommand.cxx5
-rw-r--r--Source/cmMakefile.cxx66
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx2
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.cxx39
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx2
-rw-r--r--Source/cmMessageCommand.cxx4
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx3
-rw-r--r--Source/cmNinjaTargetGenerator.cxx19
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx3
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx44
-rw-r--r--Source/cmOutputRequiredFilesCommand.h26
-rw-r--r--Source/cmParseArgumentsCommand.cxx3
-rw-r--r--Source/cmQtAutoGen.cxx138
-rw-r--r--Source/cmQtAutoGen.h14
-rw-r--r--Source/cmQtAutoGenInitializer.cxx149
-rw-r--r--Source/cmQtAutoGenInitializer.h4
-rw-r--r--Source/cmQtAutoGenerator.cxx77
-rw-r--r--Source/cmQtAutoGenerator.h19
-rw-r--r--Source/cmQtAutoMocUic.cxx504
-rw-r--r--Source/cmQtAutoMocUic.h17
-rw-r--r--Source/cmQtAutoRcc.cxx120
-rw-r--r--Source/cmSearchPath.cxx6
-rw-r--r--Source/cmSourceFile.cxx26
-rw-r--r--Source/cmSourceFile.h2
-rw-r--r--Source/cmState.cxx11
-rw-r--r--Source/cmState.h3
-rw-r--r--Source/cmStringCommand.cxx195
-rw-r--r--Source/cmSubdirDependsCommand.cxx4
-rw-r--r--Source/cmSubdirDependsCommand.h16
-rw-r--r--Source/cmTarget.cxx77
-rw-r--r--Source/cmTarget.h5
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx36
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.h41
-rw-r--r--Source/cmTestGenerator.cxx3
-rw-r--r--Source/cmTimestamp.cxx4
-rw-r--r--Source/cmTryRunCommand.cxx3
-rw-r--r--Source/cmUseMangledMesaCommand.cxx22
-rw-r--r--Source/cmUseMangledMesaCommand.h20
-rw-r--r--Source/cmUtilitySourceCommand.cxx43
-rw-r--r--Source/cmUtilitySourceCommand.h16
-rw-r--r--Source/cmVSSetupHelper.h22
-rw-r--r--Source/cmVariableRequiresCommand.cxx21
-rw-r--r--Source/cmVariableRequiresCommand.h16
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx22
-rw-r--r--Source/cmXCodeScheme.cxx6
-rw-r--r--Source/cm_optional.hxx343
-rw-r--r--Source/cm_utility.hxx35
-rw-r--r--Source/cmake.cxx46
-rw-r--r--Source/cmcmd.cxx9
-rw-r--r--Source/ctest.cxx4
-rw-r--r--Tests/CMakeLib/CMakeLists.txt1
-rw-r--r--Tests/CMakeLib/testOptional.cxx690
-rw-r--r--Tests/CMakeLists.txt24
-rw-r--r--Tests/COnly/CMakeLists.txt6
-rw-r--r--Tests/MakeClean/ToClean/CMakeLists.txt86
-rw-r--r--Tests/RunCMake/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir-stderr.txt8
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt6
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir/src/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir/src/PreLoad.cmake6
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/PrecompileHeaders/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake17
-rw-r--r--Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake14
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake36
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchInterface.cmake20
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake12
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue.cmake11
-rw-r--r--Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/PrecompileHeaders/SkipPrecompileHeaders.cmake13
-rw-r--r--Tests/RunCMake/PrecompileHeaders/foo.c6
-rw-r--r--Tests/RunCMake/PrecompileHeaders/foobar.c7
-rw-r--r--Tests/RunCMake/PrecompileHeaders/include/bar.h9
-rw-r--r--Tests/RunCMake/PrecompileHeaders/include/foo.h6
-rw-r--r--Tests/RunCMake/PrecompileHeaders/main.cpp4
-rw-r--r--Tests/RunCMake/PrecompileHeaders/non-pch.cpp3
-rw-r--r--Tests/RunCMake/PrecompileHeaders/pch.h3
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/VS10Project/VsConfigurationType-check.cmake2
-rw-r--r--Tests/RunCMake/VS10Project/VsConfigurationType.cmake2
-rw-r--r--Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake69
-rw-r--r--Tests/RunCMake/VS10Project/VsPrecompileHeaders.cmake4
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeBundles.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake35
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePrecompileHeaders.cmake4
-rw-r--r--Tests/RunCMake/color_warning.c7
-rw-r--r--Tests/RunCMake/ctest_build/IgnoreColor-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_build/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/ctest_build/test.cmake.in5
-rw-r--r--Tests/RunCMake/ctest_start/AppendDifferentGroup-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_start/AppendDifferentGroup-stdout.txt8
-rw-r--r--Tests/RunCMake/ctest_start/AppendDifferentTrack-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_start/MissingGroupArg-result.txt1
-rw-r--r--Tests/RunCMake/ctest_start/MissingGroupArg-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/MissingGroupArgAppend-result.txt1
-rw-r--r--Tests/RunCMake/ctest_start/MissingGroupArgAppend-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/MissingGroupArgQuiet-result.txt1
-rw-r--r--Tests/RunCMake/ctest_start/MissingGroupArgQuiet-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/MissingTrackArg-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/MissingTrackArgAppend-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/MissingTrackArgQuiet-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_start/NoAppendDifferentGroup-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_start/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/ctest_start/WriteModelToTagNoMatchingGroup-check.cmake1
-rw-r--r--Tests/RunCMake/find_path/EmptyOldStyle-stdout.txt1
-rw-r--r--Tests/RunCMake/find_path/EmptyOldStyle.cmake2
-rw-r--r--Tests/RunCMake/find_path/RunCMakeTest.cmake1
-rw-r--r--Tests/SourceFileProperty/CMakeLists.txt22
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/IWYU/mapping.imp2
-rw-r--r--Utilities/Release/README18
-rw-r--r--Utilities/Release/README.rst84
-rw-r--r--Utilities/Release/WiX/CustomAction/CMakeLists.txt18
-rw-r--r--Utilities/Release/create-cmake-release.cmake2
-rw-r--r--Utilities/Release/linux/x86_64/Dockerfile35
-rw-r--r--Utilities/Release/linux/x86_64/base/Dockerfile30
-rw-r--r--Utilities/Release/linux/x86_64/cache.txt44
-rw-r--r--Utilities/Release/linux/x86_64/deps/Dockerfile142
-rw-r--r--Utilities/Release/linux/x86_64/deps/openssl-source.patch12
-rw-r--r--Utilities/Release/linux/x86_64/deps/qt-install.patch24
-rw-r--r--Utilities/Release/linux/x86_64/test/Dockerfile26
-rw-r--r--Utilities/Release/linux/x86_64/test/cache-ninja.txt4
-rw-r--r--Utilities/Release/linux/x86_64/test/test-make.bash17
-rw-r--r--Utilities/Release/linux/x86_64/test/test-ninja.bash17
-rw-r--r--Utilities/Release/linux64_release.cmake53
-rw-r--r--Utilities/Release/osx_release.cmake2
-rw-r--r--Utilities/Release/win32_release.cmake5
-rw-r--r--Utilities/Release/win64_release.cmake3
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
-rwxr-xr-xbootstrap18
255 files changed, 3951 insertions, 1966 deletions
diff --git a/.gitattributes b/.gitattributes
index 3854b73..3da2d60 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -11,6 +11,7 @@
bootstrap eol=lf
configure eol=lf
*.[1-9] eol=lf
+*.bash eol=lf
*.sh eol=lf
*.sh.in eol=lf
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5e3d39d..21e8c46 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,24 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.1...3.15 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
project(CMake)
unset(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX)
unset(CMAKE_USER_MAKE_RULES_OVERRIDE_C)
+# FIXME: This block should go away after a transition period.
+if(MSVC AND NOT CMAKE_VERSION VERSION_LESS 3.15)
+ # Filter out MSVC runtime library flags that may have come from
+ # the cache of an existing build tree or from scripts.
+ foreach(l C CXX)
+ foreach(c DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
+ string(REGEX REPLACE "[-/]M[DT]d?( |$)" "" "CMAKE_${l}_FLAGS_${c}" "${CMAKE_${l}_FLAGS_${c}}")
+ endforeach()
+ endforeach()
+endif()
+
# Make sure we can find internal find_package modules only used for
# building CMake and not for shipping externally
list(INSERT CMAKE_MODULE_PATH 0 ${CMake_SOURCE_DIR}/Source/Modules)
@@ -18,6 +29,10 @@ if(CMAKE_BOOTSTRAP)
unset(CMAKE_BOOTSTRAP CACHE)
endif()
+if(CMake_TEST_HOST_CMAKE)
+ get_filename_component(CMake_TEST_EXTERNAL_CMAKE "${CMAKE_COMMAND}" DIRECTORY)
+endif()
+
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
message(FATAL_ERROR
@@ -508,7 +523,7 @@ macro (CMAKE_BUILD_UTILITIES)
#---------------------------------------------------------------------
# Build or use system libarchive for CMake and CTest.
if(CMAKE_USE_SYSTEM_LIBARCHIVE)
- find_package(LibArchive 3.1.0)
+ find_package(LibArchive 3.3.3)
if(NOT LibArchive_FOUND)
message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBARCHIVE is ON but LibArchive is not found!")
endif()
@@ -673,7 +688,7 @@ endif()
# to a cdash4simpletest database. In these cases, the CDash dashboards
# should be run first.
#
-if("x${CMAKE_TESTS_CDASH_SERVER}" STREQUAL "x")
+if("x${CMAKE_TESTS_CDASH_SERVER}" STREQUAL "x" AND NOT CMake_TEST_NO_NETWORK)
set(CMAKE_TESTS_CDASH_SERVER "http://open.cdash.org")
endif()
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst
index 6db9a48..f0704ac 100644
--- a/Help/command/ctest_start.rst
+++ b/Help/command/ctest_start.rst
@@ -5,9 +5,9 @@ Starts the testing for a given model
::
- ctest_start(<model> [<source> [<binary>]] [TRACK <track>] [QUIET])
+ ctest_start(<model> [<source> [<binary>]] [GROUP <group>] [QUIET])
- ctest_start([<model> [<source> [<binary>]]] [TRACK <track>] APPEND [QUIET])
+ ctest_start([<model> [<source> [<binary>]]] [GROUP <group>] APPEND [QUIET])
Starts the testing for a given model. The command should be called
after the binary directory is initialized.
@@ -26,20 +26,21 @@ The parameters are as follows:
Set the binary directory. If not specified, the value of
:variable:`CTEST_BINARY_DIRECTORY` is used instead.
-``TRACK <track>``
- If ``TRACK`` is used, the submissions will go to the specified track on the
- CDash server. If no ``TRACK`` is specified, the name of the model is used by
- default.
+``GROUP <group>``
+ If ``GROUP`` is used, the submissions will go to the specified group on the
+ CDash server. If no ``GROUP`` is specified, the name of the model is used by
+ default. This replaces the deprecated option ``TRACK``. Despite the name
+ change its behavior is unchanged.
``APPEND``
If ``APPEND`` is used, the existing ``TAG`` is used rather than creating a new
one based on the current time stamp. If you use ``APPEND``, you can omit the
- ``<model>`` and ``TRACK <track>`` parameters, because they will be read from
+ ``<model>`` and ``GROUP <group>`` parameters, because they will be read from
the generated ``TAG`` file. For example:
.. code-block:: cmake
- ctest_start(Experimental TRACK TrackExperimental)
+ ctest_start(Experimental GROUP GroupExperimental)
Later, in another ``ctest -S`` script:
@@ -48,11 +49,11 @@ The parameters are as follows:
ctest_start(APPEND)
When the second script runs ``ctest_start(APPEND)``, it will read the
- ``Experimental`` model and ``TrackExperimental`` track from the ``TAG`` file
+ ``Experimental`` model and ``GroupExperimental`` group from the ``TAG`` file
generated by the first ``ctest_start()`` command. Please note that if you
- call ``ctest_start(APPEND)`` and specify a different model or track than
+ call ``ctest_start(APPEND)`` and specify a different model or group than
in the first ``ctest_start()`` command, a warning will be issued, and the
- new model and track will be used.
+ new model and group will be used.
``QUIET``
If ``QUIET`` is used, CTest will suppress any non-error messages that it
@@ -65,11 +66,11 @@ equivalent:
.. code-block:: cmake
- ctest_start(Experimental path/to/source path/to/binary TRACK SomeTrack QUIET APPEND)
+ ctest_start(Experimental path/to/source path/to/binary GROUP SomeGroup QUIET APPEND)
- ctest_start(TRACK SomeTrack Experimental QUIET path/to/source APPEND path/to/binary)
+ ctest_start(GROUP SomeGroup Experimental QUIET path/to/source APPEND path/to/binary)
- ctest_start(APPEND QUIET Experimental path/to/source TRACK SomeTrack path/to/binary)
+ ctest_start(APPEND QUIET Experimental path/to/source GROUP SomeGroup path/to/binary)
However, for the sake of readability, it is recommended that you order your
parameters in the order listed at the top of this page.
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst
new file mode 100644
index 0000000..3e28265
--- /dev/null
+++ b/Help/command/target_precompile_headers.rst
@@ -0,0 +1,56 @@
+target_precompile_headers
+-------------------------
+
+Add a list of header files to precompile.
+
+.. code-block:: cmake
+
+ target_precompile_headers(<target>
+ <INTERFACE|PUBLIC|PRIVATE> [header1...]
+ [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
+
+Adds header files to :prop_tgt:`PRECOMPILE_HEADERS` or
+:prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` target properties.
+
+Precompiling header files can speed up compilation by creating a partially
+processed version of some header files, and then using that version during
+compilations rather than repeatedly parsing the original headers.
+
+The named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be an
+:ref:`ALIAS target <Alias Targets>`.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
+items will populate the :prop_tgt:`PRECOMPILE_HEADERS` property of
+``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` property of ``<target>``.
+(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+Repeated calls for the same ``<target>`` append items in the order called.
+
+Arguments to ``target_precompile_headers`` may use "generator expressions"
+with the syntax ``$<...>``.
+See the :manual:`cmake-generator-expressions(7)` manual for available
+expressions. See the :manual:`cmake-compile-features(7)` manual for
+information on compile features and a list of supported compilers.
+
+.. code-block:: cmake
+
+ target_precompile_headers(<target>
+ PUBLIC
+ "project_header.h"
+ PRIVATE
+ <unordered_map>
+ )
+
+Header files will be double quoted if they are not specified with double
+quotes or angle brackets.
+
+See Also
+^^^^^^^^
+
+For disabling precompile headers for specific targets there is the
+property :prop_tgt:`DISABLE_PRECOMPILE_HEADERS`.
+
+For skipping certain source files there is the source file property
+:prop_sf:`SKIP_PRECOMPILE_HEADERS`.
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 47baff4..0f7488b 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -74,6 +74,8 @@ The CMake source tree is organized as follows.
* ``Utilities/Release/``:
Scripts used to package CMake itself for distribution on ``cmake.org``.
+ See `Utilities/Release/README.rst`_.
.. _`CMake Documentation Guide`: documentation.rst
.. _`Tests/README.rst`: ../../Tests/README.rst
+.. _`Utilities/Release/README.rst`: ../../Utilities/Release/README.rst
diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt
index 810aaa9..0947e41 100644
--- a/Help/manual/OPTIONS_BUILD.txt
+++ b/Help/manual/OPTIONS_BUILD.txt
@@ -18,6 +18,9 @@
containing :command:`set` commands that use the ``CACHE`` option, not a
cache-format file.
+ References to :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`
+ within the script evaluate to the top-level source and build tree.
+
``-D <var>:<type>=<value>, -D <var>=<value>``
Create or update a CMake ``CACHE`` entry.
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index a3bc465..59ba897 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -112,6 +112,7 @@ These commands are available only in CMake projects.
/command/target_link_directories
/command/target_link_libraries
/command/target_link_options
+ /command/target_precompile_headers
/command/target_sources
/command/try_compile
/command/try_run
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 62d23c7..25d6b24 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -181,6 +181,7 @@ Properties on Targets
/prop_tgt/DEFINE_SYMBOL
/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES
+ /prop_tgt/DISABLE_PRECOMPILE_HEADERS
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
/prop_tgt/EchoString
/prop_tgt/ENABLE_EXPORTS
@@ -240,6 +241,7 @@ Properties on Targets
/prop_tgt/INTERFACE_LINK_DIRECTORIES
/prop_tgt/INTERFACE_LINK_LIBRARIES
/prop_tgt/INTERFACE_LINK_OPTIONS
+ /prop_tgt/INTERFACE_PRECOMPILE_HEADERS
/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
/prop_tgt/INTERFACE_SOURCES
/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
@@ -295,6 +297,7 @@ Properties on Targets
/prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG
/prop_tgt/PDB_OUTPUT_DIRECTORY
/prop_tgt/POSITION_INDEPENDENT_CODE
+ /prop_tgt/PRECOMPILE_HEADERS
/prop_tgt/PREFIX
/prop_tgt/PRIVATE_HEADER
/prop_tgt/PROJECT_LABEL
@@ -316,6 +319,7 @@ Properties on Targets
/prop_tgt/STATIC_LIBRARY_OPTIONS
/prop_tgt/SUFFIX
/prop_tgt/Swift_DEPENDENCIES_FILE
+ /prop_tgt/Swift_LANGUAGE_VERSION
/prop_tgt/Swift_MODULE_DIRECTORY
/prop_tgt/Swift_MODULE_NAME
/prop_tgt/TYPE
@@ -445,6 +449,7 @@ Properties on Source Files
/prop_sf/SKIP_AUTOMOC
/prop_sf/SKIP_AUTORCC
/prop_sf/SKIP_AUTOUIC
+ /prop_sf/SKIP_PRECOMPILE_HEADERS
/prop_sf/Swift_DEPENDENCIES_FILE
/prop_sf/Swift_DIAGNOSTICS_FILE
/prop_sf/SYMBOLIC
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 9ad1195..668b2a2 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -355,6 +355,7 @@ Variables that Control the Build
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
/variable/CMAKE_DEBUG_POSTFIX
+ /variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
/variable/CMAKE_ENABLE_EXPORTS
/variable/CMAKE_EXE_LINKER_FLAGS
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index c6b1425..9d93bb8 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -482,14 +482,17 @@ a `CDash`_ server. The command-line signature used to submit to `CDash`_ is::
Options for Dashboard Client include:
-``--track <track>``
- Specify the track to submit dashboard to
+``--group <group>``
+ Specify what group you'd like to submit results to
- Submit dashboard to specified track instead of default one. By
+ Submit dashboard to specified group instead of default one. By
default, the dashboard is submitted to Nightly, Experimental, or
- Continuous track, but by specifying this option, the track can be
+ Continuous group, but by specifying this option, the group can be
arbitrary.
+ This replaces the deprecated option ``--track``.
+ Despite the name change its behavior is unchanged.
+
``-A <file>, --add-notes <file>``
Add a notes file with submission.
diff --git a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
new file mode 100644
index 0000000..5f39f30
--- /dev/null
+++ b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
@@ -0,0 +1,13 @@
+SKIP_PRECOMPILE_HEADERS
+-----------------------
+
+Is this source file skipped by :prop_tgt:`PRECOMPILE_HEADERS` feature.
+
+This property helps with build problems that one would run into
+when using the :prop_tgt:`PRECOMPILE_HEADERS` feature.
+
+One example would be the usage of Objective-C (*.m) files, and
+Objective-C++ (*.mm) files, which lead to compilation failure
+because they are treated (in case of Ninja / Makefile generator)
+as C, and CXX respectively. The precompile headers are not
+compatible between languages.
diff --git a/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst b/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
new file mode 100644
index 0000000..4cef023
--- /dev/null
+++ b/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
@@ -0,0 +1,8 @@
+DISABLE_PRECOMPILE_HEADERS
+--------------------------
+
+Disables the precompilation of header files specified by
+:prop_tgt:`PRECOMPILE_HEADERS` property.
+
+If the property is not set, CMake will use the value provided
+by :variable:`CMAKE_DISABLE_PRECOMPILE_HEADERS`.
diff --git a/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst b/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
new file mode 100644
index 0000000..8ff7e8b
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
@@ -0,0 +1,14 @@
+INTERFACE_PRECOMPILE_HEADERS
+----------------------------
+
+List of interface header files to precompile into consuming targets.
+
+Targets may populate this property to publish the header files
+for consuming targets to precompile. The :command:`target_precompile_headers`
+command populates this property with values given to the ``PUBLIC`` and
+``INTERFACE`` keywords. Projects may also get and set the property directly.
+
+Contents of ``INTERFACE_PRECOMPILE_HEADERS`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS.rst b/Help/prop_tgt/PRECOMPILE_HEADERS.rst
new file mode 100644
index 0000000..9e70b65
--- /dev/null
+++ b/Help/prop_tgt/PRECOMPILE_HEADERS.rst
@@ -0,0 +1,12 @@
+PRECOMPILE_HEADERS
+------------------
+
+List of header files to precompile.
+
+This property holds a :ref:`semicolon-separated list <CMake Language Lists>`
+of header files to precompile specified so far for its target.
+Use the :command:`target_precompile_headers` command to append more header
+files.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
new file mode 100644
index 0000000..7579447
--- /dev/null
+++ b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
@@ -0,0 +1,6 @@
+Swift_LANGUAGE_VERSION
+----------------------
+
+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.
diff --git a/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst b/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
index ff987ff..640bed5 100644
--- a/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
+++ b/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
@@ -4,6 +4,8 @@ VS_CONFIGURATION_TYPE
Visual Studio project configuration type.
Sets the ``ConfigurationType`` attribute for a generated Visual Studio project.
+The property value may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
If this property is set, it overrides the default setting that is based on the
target type (e.g. ``StaticLibrary``, ``Application``, ...).
diff --git a/Help/release/dev/cmake-initial-cache-dirs.rst b/Help/release/dev/cmake-initial-cache-dirs.rst
new file mode 100644
index 0000000..be91902
--- /dev/null
+++ b/Help/release/dev/cmake-initial-cache-dirs.rst
@@ -0,0 +1,6 @@
+cmake-initial-cache-dirs
+------------------------
+
+* The :manual:`cmake(1)` ``-C <initial-cache>`` option now evaluates the
+ initial cache script with :variable:`CMAKE_SOURCE_DIR` and
+ :variable:`CMAKE_BINARY_DIR` set to the top-level source and build trees.
diff --git a/Help/release/dev/precompile-headers.rst b/Help/release/dev/precompile-headers.rst
new file mode 100644
index 0000000..8b62da7
--- /dev/null
+++ b/Help/release/dev/precompile-headers.rst
@@ -0,0 +1,6 @@
+Precompile Headers
+------------------
+
+* The :prop_tgt:`PRECOMPILE_HEADERS` target property was added to tell
+ generators to use a list of precompile headers for faster compilation
+ times.
diff --git a/Help/release/dev/vs-configuration-type-genex.rst b/Help/release/dev/vs-configuration-type-genex.rst
new file mode 100644
index 0000000..d930d5b
--- /dev/null
+++ b/Help/release/dev/vs-configuration-type-genex.rst
@@ -0,0 +1,5 @@
+vs-configuration-type-genex
+---------------------------
+
+* :prop_tgt:`VS_CONFIGURATION_TYPE` now supports
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst b/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
new file mode 100644
index 0000000..7c30ede
--- /dev/null
+++ b/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
@@ -0,0 +1,6 @@
+CMAKE_DISABLE_PRECOMPILE_HEADERS
+--------------------------------
+
+Default value for :prop_tgt:`DISABLE_PRECOMPILE_HEADERS` of targets.
+
+By default ``CMAKE_DISABLE_PRECOMPILE_HEADERS`` is ``OFF``.
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index c3f13f3..45c33fb 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -96,5 +96,7 @@ else()
set(CMAKE_${lang}_ARCHIVE_FINISH_IPO
"\"${__ranlib}\" <TARGET>"
)
+
+ set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
endmacro()
endif()
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index 6b1bd3a..e0ff174 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -11,6 +11,9 @@ set(__COMPILER_GNU 1)
include(Compiler/CMakeCommonCompilerMacros)
include(Internal/CMakeCheckCompilerFlag)
+set(__pch_header_C "c-header")
+set(__pch_header_CXX "c++-header")
+
macro(__compiler_gnu lang)
# Feature flags.
set(CMAKE_${lang}_VERBOSE_FLAG "-v")
@@ -104,4 +107,9 @@ macro(__compiler_gnu lang)
unset(_COMPILER_ARGS)
endif()
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
+
+ set(CMAKE_PCH_EXTENSION .gch)
+ set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
endmacro()
diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake
index f2f16e0..d895ed0 100644
--- a/Modules/Compiler/Intel.cmake
+++ b/Modules/Compiler/Intel.cmake
@@ -32,5 +32,12 @@ else()
unset(_COMPILER_ARGS)
endif()
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
+
+ # Precompile Headers
+ set(CMAKE_PCH_EXTENSION .pchi)
+ set(CMAKE_LINK_PCH ON)
+ set(CMAKE_PCH_EPILOGUE "#pragma hdrstop")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
endmacro()
endif()
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index fc97655..200d6bf 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -42,7 +42,14 @@ This module will set the following variables in your project:
#]=======================================================================]
find_path(LIBLZMA_INCLUDE_DIR lzma.h )
-find_library(LIBLZMA_LIBRARY NAMES lzma liblzma)
+if(NOT LIBLZMA_LIBRARY)
+ find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma PATH_SUFFIXES lib)
+ find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad PATH_SUFFIXES lib)
+ include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ select_library_configurations(LIBLZMA)
+else()
+ file(TO_CMAKE_PATH "${LIBLZMA_LIBRARY}" LIBLZMA_LIBRARY)
+endif()
if(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
file(STRINGS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h" LIBLZMA_HEADER_CONTENTS REGEX "#define LZMA_VERSION_[A-Z]+ [0-9]+")
@@ -62,9 +69,17 @@ if (LIBLZMA_LIBRARY)
include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET ${LibLZMA_FIND_QUIETLY})
- CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY} lzma_auto_decoder "" LIBLZMA_HAS_AUTO_DECODER)
- CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY} lzma_easy_encoder "" LIBLZMA_HAS_EASY_ENCODER)
- CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY} lzma_lzma_preset "" LIBLZMA_HAS_LZMA_PRESET)
+ if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
+ set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY})
+ elseif(LIBLZMA_LIBRARY_RELEASE)
+ set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_RELEASE})
+ elseif(LIBLZMA_LIBRARY_DEBUG)
+ set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_DEBUG})
+ endif()
+ CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_auto_decoder "" LIBLZMA_HAS_AUTO_DECODER)
+ CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_easy_encoder "" LIBLZMA_HAS_EASY_ENCODER)
+ CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_lzma_preset "" LIBLZMA_HAS_LZMA_PRESET)
+ unset(LIBLZMA_LIBRARY_check)
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
endif ()
@@ -85,7 +100,25 @@ if (LIBLZMA_FOUND)
add_library(LibLZMA::LibLZMA UNKNOWN IMPORTED)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${LIBLZMA_INCLUDE_DIR}
- IMPORTED_LINK_INTERFACE_LANGUAGES C
- IMPORTED_LOCATION ${LIBLZMA_LIBRARY})
+ IMPORTED_LINK_INTERFACE_LANGUAGES C)
+
+ if(LIBLZMA_LIBRARY_RELEASE)
+ set_property(TARGET LibLZMA::LibLZMA APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(LibLZMA::LibLZMA PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${LIBLZMA_LIBRARY_RELEASE}")
+ endif()
+
+ if(LIBLZMA_LIBRARY_DEBUG)
+ set_property(TARGET LibLZMA::LibLZMA APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(LibLZMA::LibLZMA PROPERTIES
+ IMPORTED_LOCATION_DEBUG "${LIBLZMA_LIBRARY_DEBUG}")
+ endif()
+
+ if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
+ set_target_properties(LibLZMA::LibLZMA PROPERTIES
+ IMPORTED_LOCATION "${LIBLZMA_LIBRARY}")
+ endif()
endif()
endif ()
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index 4db4e18..f95e6e2 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -222,7 +222,8 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
# updated to the new default, unless the user explicitly changed it.
endif()
if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
- AND NOT CMAKE_CROSSCOMPILING)
+ AND NOT CMAKE_CROSSCOMPILING
+ AND NOT EXISTS "/etc/arch-release")
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 2beea00..57ae446 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -729,7 +729,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
if(gp_tool MATCHES "ldd$")
set(gp_cmd_args "")
- set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
+ set(gp_regex "^[\t ]*[^\t ]+ =>[\t ]+([^\t\(]+)( \(.+\))?${eol_char}$")
set(gp_regex_error "not found${eol_char}$")
set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
set(gp_regex_cmp_count 1)
diff --git a/Modules/Internal/CPack/CPack.STGZ_Header.sh.in b/Modules/Internal/CPack/CPack.STGZ_Header.sh.in
index 003fcfe..a857aa5 100755
--- a/Modules/Internal/CPack/CPack.STGZ_Header.sh.in
+++ b/Modules/Internal/CPack/CPack.STGZ_Header.sh.in
@@ -86,15 +86,19 @@ then
@CPACK_RESOURCE_FILE_LICENSE_CONTENT@
____cpack__here_doc____
echo
- echo "Do you accept the license? [yN]: "
- read line leftover
- case ${line} in
- y* | Y*)
- cpack_license_accepted=TRUE;;
- *)
- echo "License not accepted. Exiting ..."
- exit 1;;
- esac
+ while true
+ do
+ echo "Do you accept the license? [yn]: "
+ read line leftover
+ case ${line} in
+ y* | Y*)
+ cpack_license_accepted=TRUE
+ break;;
+ n* | N* | q* | Q* | e* | E*)
+ echo "License not accepted. Exiting ..."
+ exit 1;;
+ esac
+ done
fi
if [ "x${cpack_include_subdir}x" = "xx" ]
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 728e0b9..220649c 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -8,6 +8,9 @@ if(__WINDOWS_CLANG)
endif()
set(__WINDOWS_CLANG 1)
+set(__pch_header_C "c-header")
+set(__pch_header_CXX "c++-header")
+
macro(__windows_compiler_clang_gnu lang)
set(CMAKE_LIBRARY_PATH_FLAG "-L")
set(CMAKE_LINK_LIBRARY_FLAG "-l")
@@ -73,6 +76,10 @@ macro(__windows_compiler_clang_gnu lang)
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG -Xclang -gcodeview ${__ADDED_FLAGS}")
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
+ set(CMAKE_PCH_EXTENSION .gch)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
+
unset(__ADDED_FLAGS)
unset(__ADDED_FLAGS_DEBUG)
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_LOWER)
diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake
index 48b936e..370b56e 100644
--- a/Modules/Platform/Windows-Embarcadero.cmake
+++ b/Modules/Platform/Windows-Embarcadero.cmake
@@ -119,6 +119,13 @@ macro(__embarcadero_language lang)
"tlib ${CMAKE_START_TEMP_FILE}/p512 <LINK_FLAGS> /a <TARGET_QUOTED> <OBJECTS>${CMAKE_END_TEMP_FILE}"
)
+ # Precompile Headers
+ if (EMBARCADERO)
+ set(CMAKE_PCH_EXTENSION .pch)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
+ endif()
+
# Initial configuration flags.
string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_tM}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -Od -v")
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 7a83859..6ddcaa3 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -329,6 +329,15 @@ macro(__windows_compiler_msvc lang)
set(CMAKE_${lang}_LINK_EXECUTABLE
"${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ set(CMAKE_PCH_EXTENSION .pch)
+ set(CMAKE_LINK_PCH ON)
+ if(MSVC_VERSION GREATER_EQUAL 1910)
+ # VS 2017 or greater
+ set(CMAKE_PCH_PROLOGUE "#pragma system_header")
+ endif()
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /FI<PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /FI<PCH_HEADER>)
+
if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 7cd07a8..2ff6c8c 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -493,8 +493,6 @@ set(SRCS
cmCreateTestSourceList.h
cmDefinePropertyCommand.cxx
cmDefinePropertyCommand.h
- cmDisallowedCommand.cxx
- cmDisallowedCommand.h
cmEnableLanguageCommand.cxx
cmEnableLanguageCommand.h
cmEnableTestingCommand.cxx
@@ -656,6 +654,8 @@ set(SRCS
cmTargetLinkDirectoriesCommand.h
cmTargetLinkLibrariesCommand.cxx
cmTargetLinkLibrariesCommand.h
+ cmTargetPrecompileHeadersCommand.cxx
+ cmTargetPrecompileHeadersCommand.h
cmTargetPropCommandBase.cxx
cmTargetPropCommandBase.h
cmTargetSourcesCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index fdc482d..1b06e45 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 15)
-set(CMake_VERSION_PATCH 20190823)
+set(CMake_VERSION_PATCH 20190829)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 5b1ccbd..f9ce822 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -78,8 +78,7 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version)
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::map<std::string, std::string>& argsOut)
{
- std::vector<std::string> args;
- cmExpandList(arg, args, false);
+ std::vector<std::string> args = cmExpandedList(arg, false);
if (args.empty()) {
return;
}
@@ -100,8 +99,7 @@ void cmCPackIFWCommon::ExpandListArgument(
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::multimap<std::string, std::string>& argsOut)
{
- std::vector<std::string> args;
- cmExpandList(arg, args, false);
+ std::vector<std::string> args = cmExpandedList(arg, false);
if (args.empty()) {
return;
}
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 234da2f..d1ffcef 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -39,24 +39,31 @@ int cmCPackIFWGenerator::PackageFiles()
// Run repogen
if (!this->Installer.RemoteRepositories.empty()) {
- std::string ifwCmd = this->RepoGen;
+ std::vector<std::string> ifwCmd;
+ std::string ifwArg;
+
+ ifwCmd.emplace_back(this->RepoGen);
if (this->IsVersionLess("2.0.0")) {
- ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ ifwCmd.emplace_back("-c");
+ ifwCmd.emplace_back(this->toplevel + "/config/config.xml");
}
- ifwCmd += " -p " + this->toplevel + "/packages";
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(this->toplevel + "/packages");
if (!this->PkgsDirsVector.empty()) {
for (std::string const& it : this->PkgsDirsVector) {
- ifwCmd += " -p " + it;
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(it);
}
}
if (!this->RepoDirsVector.empty()) {
if (!this->IsVersionLess("3.1")) {
for (std::string const& rd : this->RepoDirsVector) {
- ifwCmd += " --repository " + rd;
+ ifwCmd.emplace_back("--repository");
+ ifwCmd.emplace_back(rd);
}
} else {
cmCPackIFWLogger(WARNING,
@@ -69,18 +76,21 @@ int cmCPackIFWGenerator::PackageFiles()
}
if (!this->OnlineOnly && !this->DownloadedPackages.empty()) {
- ifwCmd += " -i ";
+ ifwCmd.emplace_back("-i");
std::set<cmCPackIFWPackage*>::iterator it =
this->DownloadedPackages.begin();
- ifwCmd += (*it)->Name;
+ ifwArg = (*it)->Name;
++it;
while (it != this->DownloadedPackages.end()) {
- ifwCmd += "," + (*it)->Name;
+ ifwArg += "," + (*it)->Name;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
}
- ifwCmd += " " + this->toplevel + "/repository";
- cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl);
+ ifwCmd.emplace_back(this->toplevel + "/repository");
+ cmCPackIFWLogger(VERBOSE,
+ "Execute: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl);
std::string output;
int retVal = 1;
cmCPackIFWLogger(OUTPUT, "- Generate repository" << std::endl);
@@ -89,14 +99,15 @@ int cmCPackIFWGenerator::PackageFiles()
cmDuration::zero());
if (!res || retVal) {
cmGeneratedFileStream ofs(ifwTmpFile);
- ofs << "# Run command: " << ifwCmd << std::endl
+ ofs << "# Run command: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl
<< "# Output:" << std::endl
<< output << std::endl;
- cmCPackIFWLogger(ERROR,
- "Problem running IFW command: "
- << ifwCmd << std::endl
- << "Please check " << ifwTmpFile << " for errors"
- << std::endl);
+ cmCPackIFWLogger(
+ ERROR,
+ "Problem running IFW command: "
+ << cmSystemTools::PrintSingleCommand(ifwCmd) << std::endl
+ << "Please check \"" << ifwTmpFile << "\" for errors" << std::endl);
return 0;
}
@@ -104,46 +115,55 @@ int cmCPackIFWGenerator::PackageFiles()
!this->Repository.PatchUpdatesXml()) {
cmCPackIFWLogger(WARNING,
"Problem patch IFW \"Updates\" "
- << "file: "
- << this->toplevel + "/repository/Updates.xml"
- << std::endl);
+ << "file: \"" << this->toplevel
+ << "/repository/Updates.xml\"" << std::endl);
}
cmCPackIFWLogger(OUTPUT,
- "- repository: " << this->toplevel
- << "/repository generated" << std::endl);
+ "- repository: \"" << this->toplevel
+ << "/repository\" generated"
+ << std::endl);
}
// Run binary creator
{
- std::string ifwCmd =
- cmStrCat(this->BinCreator, " -c ", this->toplevel, "/config/config.xml");
+ std::vector<std::string> ifwCmd;
+ std::string ifwArg;
+
+ ifwCmd.emplace_back(this->BinCreator);
+
+ ifwCmd.emplace_back("-c");
+ ifwCmd.emplace_back(this->toplevel + "/config/config.xml");
if (!this->Installer.Resources.empty()) {
- ifwCmd += " -r ";
+ ifwCmd.emplace_back("-r");
std::vector<std::string>::iterator it =
this->Installer.Resources.begin();
std::string path = this->toplevel + "/resources/";
- ifwCmd += path + *it;
+ ifwArg = path + *it;
++it;
while (it != this->Installer.Resources.end()) {
- ifwCmd += "," + path + *it;
+ ifwArg += "," + path + *it;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
}
- ifwCmd += " -p " + this->toplevel + "/packages";
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(this->toplevel + "/packages");
if (!this->PkgsDirsVector.empty()) {
for (std::string const& it : this->PkgsDirsVector) {
- ifwCmd += " -p " + it;
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(it);
}
}
if (!this->RepoDirsVector.empty()) {
if (!this->IsVersionLess("3.1")) {
for (std::string const& rd : this->RepoDirsVector) {
- ifwCmd += " --repository " + rd;
+ ifwCmd.emplace_back("--repository");
+ ifwCmd.emplace_back(rd);
}
} else {
cmCPackIFWLogger(WARNING,
@@ -156,44 +176,48 @@ int cmCPackIFWGenerator::PackageFiles()
}
if (this->OnlineOnly) {
- ifwCmd += " --online-only";
+ ifwCmd.emplace_back("--online-only");
} else if (!this->DownloadedPackages.empty() &&
!this->Installer.RemoteRepositories.empty()) {
- ifwCmd += " -e ";
+ ifwCmd.emplace_back("-e");
std::set<cmCPackIFWPackage*>::iterator it =
this->DownloadedPackages.begin();
- ifwCmd += (*it)->Name;
+ ifwArg = (*it)->Name;
++it;
while (it != this->DownloadedPackages.end()) {
- ifwCmd += "," + (*it)->Name;
+ ifwArg += "," + (*it)->Name;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
} else if (!this->DependentPackages.empty()) {
- ifwCmd += " -i ";
+ ifwCmd.emplace_back("-i");
+ ifwArg.clear();
// Binary
std::set<cmCPackIFWPackage*>::iterator bit =
this->BinaryPackages.begin();
while (bit != this->BinaryPackages.end()) {
- ifwCmd += (*bit)->Name + ",";
+ ifwArg += (*bit)->Name + ",";
++bit;
}
// Depend
DependenceMap::iterator it = this->DependentPackages.begin();
- ifwCmd += it->second.Name;
+ ifwArg += it->second.Name;
++it;
while (it != this->DependentPackages.end()) {
- ifwCmd += "," + it->second.Name;
+ ifwArg += "," + it->second.Name;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
}
// TODO: set correct name for multipackages
if (!this->packageFileNames.empty()) {
- ifwCmd += " " + this->packageFileNames[0];
+ ifwCmd.emplace_back(this->packageFileNames[0]);
} else {
- ifwCmd += " installer";
- ifwCmd += this->OutputExtension;
+ ifwCmd.emplace_back("installer" + this->OutputExtension);
}
- cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl);
+ cmCPackIFWLogger(VERBOSE,
+ "Execute: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl);
std::string output;
int retVal = 1;
cmCPackIFWLogger(OUTPUT, "- Generate package" << std::endl);
@@ -202,14 +226,15 @@ int cmCPackIFWGenerator::PackageFiles()
cmDuration::zero());
if (!res || retVal) {
cmGeneratedFileStream ofs(ifwTmpFile);
- ofs << "# Run command: " << ifwCmd << std::endl
+ ofs << "# Run command: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl
<< "# Output:" << std::endl
<< output << std::endl;
- cmCPackIFWLogger(ERROR,
- "Problem running IFW command: "
- << ifwCmd << std::endl
- << "Please check " << ifwTmpFile << " for errors"
- << std::endl);
+ cmCPackIFWLogger(
+ ERROR,
+ "Problem running IFW command: "
+ << cmSystemTools::PrintSingleCommand(ifwCmd) << std::endl
+ << "Please check \"" << ifwTmpFile << "\" for errors" << std::endl);
return 0;
}
}
@@ -316,8 +341,7 @@ int cmCPackIFWGenerator::InitializeInternal()
// Repositories
if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
- std::vector<std::string> RepoAllVector;
- cmExpandList(RepoAllStr, RepoAllVector);
+ std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr);
for (std::string const& r : RepoAllVector) {
this->GetRepository(r);
}
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 7407c49..fb75145 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -431,8 +431,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
if (this->IsSetToEmpty(option)) {
this->AlienAutoDependOn.clear();
} else if (const char* value = this->GetOption(option)) {
- std::vector<std::string> depsOn;
- cmExpandList(value, depsOn);
+ std::vector<std::string> depsOn = cmExpandedList(value);
for (std::string const& d : depsOn) {
DependenceStruct dep(d);
if (this->Generator->Packages.count(dep.Name)) {
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index e960fab..b0b2df2 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -228,8 +228,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if (patchFilePath) {
- std::vector<std::string> patchFilePaths;
- cmExpandList(patchFilePath, patchFilePaths);
+ std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath);
for (std::string const& p : patchFilePaths) {
if (!this->Patch->LoadFragments(p)) {
@@ -312,9 +311,8 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
if (!cpackWixExtraObjects)
return;
- std::vector<std::string> expandedExtraObjects;
-
- cmExpandList(cpackWixExtraObjects, expandedExtraObjects);
+ std::vector<std::string> expandedExtraObjects =
+ cmExpandedList(cpackWixExtraObjects);
for (std::string const& obj : expandedExtraObjects) {
stream << " " << QuotePath(obj);
@@ -1131,8 +1129,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list;
- cmExpandList(variableContent, list);
+ std::vector<std::string> list = cmExpandedList(variableContent);
extensions.insert(list.begin(), list.end());
}
@@ -1143,8 +1140,7 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list;
- cmExpandList(variableContent, list);
+ std::vector<std::string> list = cmExpandedList(variableContent);
for (std::string const& i : list) {
stream << " " << QuotePath(i);
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index f58cc0a..4d5f43f 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -89,11 +89,10 @@ int cmCPackBundleGenerator::ConstructBundle()
// The staging directory contains everything that will end-up inside the
// final disk image ...
- std::ostringstream staging;
- staging << toplevel;
+ std::string const staging = toplevel;
std::ostringstream contents;
- contents << staging.str() << "/" << cpack_bundle_name << ".app/"
+ contents << staging << "/" << cpack_bundle_name << ".app/"
<< "Contents";
std::ostringstream application;
@@ -204,8 +203,7 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES")
: "";
- std::vector<std::string> relFiles;
- cmExpandList(sign_files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(sign_files);
// sign the files supplied by the user, ie. frameworks.
for (auto const& file : relFiles) {
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index db336b0..cefbc90 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -376,8 +376,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// default
control_tar.ClearPermissions();
- std::vector<std::string> controlExtraList;
- cmExpandList(ControlExtra, controlExtraList);
+ std::vector<std::string> controlExtraList = cmExpandedList(ControlExtra);
for (std::string const& i : controlExtraList) {
std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
std::string localcopy = WorkDir + "/" + filenamename;
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 2aa0612..ca06b81 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -128,8 +128,8 @@ int cmCPackDragNDropGenerator::InitializeInternal()
return 0;
}
- std::vector<std::string> languages;
- cmExpandList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"), languages);
+ std::vector<std::string> languages =
+ cmExpandedList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"));
if (languages.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl);
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index b90a27c..a35977c 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -228,8 +228,8 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
manifest << ManifestKeyValue(
"desc", var_lookup("CPACK_FREEBSD_PACKAGE_DESCRIPTION"));
manifest << ManifestKeyValue("www", var_lookup("CPACK_FREEBSD_PACKAGE_WWW"));
- std::vector<std::string> licenses;
- cmExpandList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"), licenses);
+ std::vector<std::string> licenses =
+ cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"));
std::string licenselogic("single");
if (licenses.empty()) {
cmSystemTools::SetFatalErrorOccured();
@@ -238,12 +238,12 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
}
manifest << ManifestKeyValue("licenselogic", licenselogic);
manifest << (ManifestKeyListValue("licenses") << licenses);
- std::vector<std::string> categories;
- cmExpandList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"), categories);
+ std::vector<std::string> categories =
+ cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"));
manifest << (ManifestKeyListValue("categories") << categories);
manifest << ManifestKeyValue("prefix", var_lookup("CMAKE_INSTALL_PREFIX"));
- std::vector<std::string> deps;
- cmExpandList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"), deps);
+ std::vector<std::string> deps =
+ cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"));
if (!deps.empty()) {
manifest << (ManifestKeyDepsValue("deps") << deps);
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 0e9f1b6..288d5d8 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -210,8 +210,8 @@ int cmCPackGenerator::InstallProject()
const char* default_dir_install_permissions =
this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (default_dir_install_permissions && *default_dir_install_permissions) {
- std::vector<std::string> items;
- cmExpandList(default_dir_install_permissions, items);
+ std::vector<std::string> items =
+ cmExpandedList(default_dir_install_permissions);
for (const auto& arg : items) {
if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -273,8 +273,8 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
std::string tempInstallDirectoryEnv =
cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
cmSystemTools::PutEnv(tempInstallDirectoryEnv);
- std::vector<std::string> installCommandsVector;
- cmExpandList(installCommands, installCommandsVector);
+ std::vector<std::string> installCommandsVector =
+ cmExpandedList(installCommands);
for (std::string const& ic : installCommandsVector) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ic << std::endl);
std::string output;
@@ -310,8 +310,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
std::vector<cmsys::RegularExpression> ignoreFilesRegex;
const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
if (cpackIgnoreFiles) {
- std::vector<std::string> ignoreFilesRegexString;
- cmExpandList(cpackIgnoreFiles, ignoreFilesRegexString);
+ std::vector<std::string> ignoreFilesRegexString =
+ cmExpandedList(cpackIgnoreFiles);
for (std::string const& ifr : ignoreFilesRegexString) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Create ignore files regex for: " << ifr << std::endl);
@@ -321,8 +321,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
const char* installDirectories =
this->GetOption("CPACK_INSTALLED_DIRECTORIES");
if (installDirectories && *installDirectories) {
- std::vector<std::string> installDirectoriesVector;
- cmExpandList(installDirectories, installDirectoriesVector);
+ std::vector<std::string> installDirectoriesVector =
+ cmExpandedList(installDirectories);
if (installDirectoriesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -460,8 +460,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
if (cmakeScripts && *cmakeScripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install scripts: " << cmakeScripts << std::endl);
- std::vector<std::string> cmakeScriptsVector;
- cmExpandList(cmakeScripts, cmakeScriptsVector);
+ std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts);
for (std::string const& installScript : cmakeScriptsVector) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
@@ -525,8 +524,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< std::endl);
return 0;
}
- std::vector<std::string> cmakeProjectsVector;
- cmExpandList(cmakeProjects, cmakeProjectsVector);
+ std::vector<std::string> cmakeProjectsVector =
+ cmExpandedList(cmakeProjects);
std::vector<std::string>::iterator it;
for (it = cmakeProjectsVector.begin(); it != cmakeProjectsVector.end();
++it) {
@@ -570,8 +569,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
const char* installTypes = this->GetOption(installTypesVar);
if (installTypes && *installTypes) {
- std::vector<std::string> installTypesVector;
- cmExpandList(installTypes, installTypesVector);
+ std::vector<std::string> installTypesVector =
+ cmExpandedList(installTypes);
for (std::string const& installType : installTypesVector) {
project.InstallationTypes.push_back(
this->GetInstallationType(project.ProjectName, installType));
@@ -1493,8 +1492,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the installation types.
const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
if (installTypes && *installTypes) {
- std::vector<std::string> installTypesVector;
- cmExpandList(installTypes, installTypesVector);
+ std::vector<std::string> installTypesVector =
+ cmExpandedList(installTypes);
for (std::string const& installType : installTypesVector) {
component->InstallationTypes.push_back(
this->GetInstallationType(projectName, installType));
@@ -1504,8 +1503,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the component dependencies.
const char* depends = this->GetOption(macroPrefix + "_DEPENDS");
if (depends && *depends) {
- std::vector<std::string> dependsVector;
- cmExpandList(depends, dependsVector);
+ std::vector<std::string> dependsVector = cmExpandedList(depends);
for (std::string const& depend : dependsVector) {
cmCPackComponent* child = GetComponent(projectName, depend);
component->Dependencies.push_back(child);
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index a3ca4b5..ca675fd 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -83,7 +83,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "VERBOSE";
+ tagString += "VERBOSE";
}
}
if (tag & LOG_WARNING) {
@@ -93,7 +93,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "WARNING";
+ tagString += "WARNING";
}
}
if (tag & LOG_ERROR) {
@@ -103,7 +103,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "ERROR";
+ tagString += "ERROR";
}
}
if (tag & LOG_DEBUG && this->Debug) {
@@ -113,7 +113,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "DEBUG";
+ tagString += "DEBUG";
}
useFileAndLine = true;
}
@@ -124,7 +124,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "VERBOSE";
+ tagString += "VERBOSE";
}
}
if (this->Quiet) {
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 41ffa0e..8098edf 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -471,8 +471,8 @@ int cmCPackNSISGenerator::InitializeInternal()
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackPackageExecutables: " << cpackPackageExecutables
<< "." << std::endl);
- std::vector<std::string> cpackPackageExecutablesVector;
- cmExpandList(cpackPackageExecutables, cpackPackageExecutablesVector);
+ std::vector<std::string> cpackPackageExecutablesVector =
+ cmExpandedList(cpackPackageExecutables);
if (cpackPackageExecutablesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -524,8 +524,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackMenuLinks: " << cpackMenuLinks << "." << std::endl);
- std::vector<std::string> cpackMenuLinksVector;
- cmExpandList(cpackMenuLinks, cpackMenuLinksVector);
+ std::vector<std::string> cpackMenuLinksVector =
+ cmExpandedList(cpackMenuLinks);
if (cpackMenuLinksVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index ffa8a42..992299a 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -29,8 +29,8 @@ int cmCPackOSXX11Generator::PackageFiles()
<< "." << std::endl);
std::ostringstream str;
std::ostringstream deleteStr;
- std::vector<std::string> cpackPackageExecutablesVector;
- cmExpandList(cpackPackageExecutables, cpackPackageExecutablesVector);
+ std::vector<std::string> cpackPackageExecutablesVector =
+ cmExpandedList(cpackPackageExecutables);
if (cpackPackageExecutablesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index a98fabc..69dac88 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -333,8 +333,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack generator not specified" << std::endl);
} else {
- std::vector<std::string> generatorsVector;
- cmExpandList(genList, generatorsVector);
+ std::vector<std::string> generatorsVector = cmExpandedList(genList);
for (std::string const& gen : generatorsVector) {
cmMakefile::ScopePushPop raii(&globalMF);
cmMakefile* mf = &globalMF;
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 6e76f08..cb22fa6 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -154,16 +154,15 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
{
bool ret = cmCTestHandlerCommand::InitialPass(args, status);
if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) {
- std::ostringstream str;
- str << this->Handler->GetTotalErrors();
- this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS], str.str());
+ this->Makefile->AddDefinition(
+ this->Values[ctb_NUMBER_ERRORS],
+ std::to_string(this->Handler->GetTotalErrors()));
}
if (this->Values[ctb_NUMBER_WARNINGS] &&
*this->Values[ctb_NUMBER_WARNINGS]) {
- std::ostringstream str;
- str << this->Handler->GetTotalWarnings();
- this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS],
- str.str());
+ this->Makefile->AddDefinition(
+ this->Values[ctb_NUMBER_WARNINGS],
+ std::to_string(this->Handler->GetTotalWarnings()));
}
return ret;
}
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 8d1f76b..147286e 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -10,6 +10,7 @@
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
+#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
@@ -408,6 +409,9 @@ int cmCTestBuildHandler::ProcessHandler()
// Remember start build time
this->StartBuild = this->CTest->CurrentTime();
this->StartBuildTime = std::chrono::system_clock::now();
+
+ cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr);
+ this->ColorRemover = &colorRemover;
int retVal = 0;
int res = cmsysProcess_State_Exited;
if (!this->CTest->GetShowOnly()) {
@@ -1070,7 +1074,12 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
return b_REGULAR_LINE;
}
- cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl,
+ // Ignore ANSI color codes when checking for errors and warnings.
+ std::string input(data);
+ std::string line;
+ this->ColorRemover->Replace(input, line);
+
+ cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << line << "]" << std::endl,
this->Quiet);
int warningLine = 0;
@@ -1082,10 +1091,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
// Errors
int wrxCnt = 0;
for (cmsys::RegularExpression& rx : this->ErrorMatchRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
errorLine = 1;
cmCTestOptionalLog(this->CTest, DEBUG,
- " Error Line: " << data << " (matches: "
+ " Error Line: " << line << " (matches: "
<< this->CustomErrorMatches[wrxCnt]
<< ")" << std::endl,
this->Quiet);
@@ -1096,11 +1105,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
// Error exceptions
wrxCnt = 0;
for (cmsys::RegularExpression& rx : this->ErrorExceptionRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
errorLine = 0;
cmCTestOptionalLog(this->CTest, DEBUG,
" Not an error Line: "
- << data << " (matches: "
+ << line << " (matches: "
<< this->CustomErrorExceptions[wrxCnt] << ")"
<< std::endl,
this->Quiet);
@@ -1113,11 +1122,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
// Warnings
int wrxCnt = 0;
for (cmsys::RegularExpression& rx : this->WarningMatchRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
warningLine = 1;
cmCTestOptionalLog(this->CTest, DEBUG,
" Warning Line: "
- << data << " (matches: "
+ << line << " (matches: "
<< this->CustomWarningMatches[wrxCnt] << ")"
<< std::endl,
this->Quiet);
@@ -1129,11 +1138,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
wrxCnt = 0;
// Warning exceptions
for (cmsys::RegularExpression& rx : this->WarningExceptionRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
warningLine = 0;
cmCTestOptionalLog(this->CTest, DEBUG,
" Not a warning Line: "
- << data << " (matches: "
+ << line << " (matches: "
<< this->CustomWarningExceptions[wrxCnt] << ")"
<< std::endl,
this->Quiet);
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index 722c590..87f1534 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -18,6 +18,7 @@
#include <vector>
class cmMakefile;
+class cmStringReplaceHelper;
class cmXMLWriter;
/** \class cmCTestBuildHandler
@@ -143,6 +144,9 @@ private:
int MaxErrors;
int MaxWarnings;
+ // Used to remove ANSI color codes before checking for errors and warnings.
+ cmStringReplaceHelper* ColorRemover;
+
bool UseCTestLaunch;
std::string CTestLaunchDir;
class LaunchHelper;
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index c13cc80..f7319ef 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -211,8 +211,7 @@ bool cmCTestGIT::UpdateByFetchAndReset()
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
- std::vector<std::string> git_custom_command;
- cmExpandList(custom, git_custom_command, true);
+ std::vector<std::string> git_custom_command = cmExpandedList(custom, true);
std::vector<char const*> git_custom;
git_custom.reserve(git_custom_command.size() + 1);
for (std::string const& i : git_custom_command) {
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 8ceca08..6add717 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -228,9 +228,8 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
int res = handler->ProcessHandler();
if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
- std::ostringstream str;
- str << res;
- this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], str.str());
+ this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
+ std::to_string(res));
}
this->ProcessAdditionalValues(handler);
// log the error message if there was an error
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index d7d42bf..804efa5 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
-#include <sstream>
+#include <string>
#include <vector>
#include "cmCTest.h"
@@ -44,8 +44,9 @@ void cmCTestMemCheckCommand::ProcessAdditionalValues(
cmCTestGenericHandler* handler)
{
if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) {
- std::ostringstream str;
- str << static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount();
- this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT], str.str());
+ this->Makefile->AddDefinition(
+ this->Values[ctm_DEFECT_COUNT],
+ std::to_string(
+ static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount()));
}
}
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index b09e7bb..259240f 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -1074,10 +1074,7 @@ void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res,
void cmCTestMemCheckHandler::TestOutputFileNames(
int test, std::vector<std::string>& files)
{
- std::string index;
- std::ostringstream stream;
- stream << test;
- index = stream.str();
+ std::string index = std::to_string(test);
std::string ofile = this->MemoryTesterOutputFile;
std::string::size_type pos = ofile.find("??");
ofile.replace(pos, 2, index);
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 9925dc1..af1980a 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -189,10 +189,13 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
std::strerror(workdir.GetLastResult()));
} else {
if (testRun->StartTest(this->Completed, this->Total)) {
+ // Ownership of 'testRun' has moved to another structure.
+ // When the test finishes, FinishTestProcess will be called.
return true;
}
}
+ // Pass ownership of 'testRun'.
this->FinishTestProcess(testRun, false);
return false;
}
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 80eb8d9..64354e8 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -460,8 +460,7 @@ bool cmCTestP4::LoadModifications()
bool cmCTestP4::UpdateCustom(const std::string& custom)
{
- std::vector<std::string> p4_custom_command;
- cmExpandList(custom, p4_custom_command, true);
+ std::vector<std::string> p4_custom_command = cmExpandedList(custom, true);
std::vector<char const*> p4_custom;
p4_custom.reserve(p4_custom_command.size() + 1);
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
index c03cffd..f59ca57 100644
--- a/Source/CTest/cmCTestRunScriptCommand.cxx
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -5,8 +5,6 @@
#include "cmCTestScriptHandler.h"
#include "cmMakefile.h"
-#include <sstream>
-
class cmExecutionStatus;
bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
@@ -41,9 +39,7 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
int ret;
cmCTestScriptHandler::RunScript(this->CTest, this->Makefile,
args[i].c_str(), !np, &ret);
- std::ostringstream str;
- str << ret;
- this->Makefile->AddDefinition(returnVariable, str.str());
+ this->Makefile->AddDefinition(returnVariable, std::to_string(ret));
}
}
return true;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 89b585e..23c6b0d 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -142,8 +142,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
this->TestResult.CompletionStatus = s.str();
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped ");
skipped = true;
- } else if ((success && !this->TestProperties->WillFail) ||
- (!success && this->TestProperties->WillFail)) {
+ } else if (success != this->TestProperties->WillFail) {
this->TestResult.Status = cmCTestTestHandler::COMPLETED;
outputStream << " Passed ";
} else {
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 52d4596..81966dd 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -544,8 +544,7 @@ int cmCTestScriptHandler::RunCurrentScript()
// set any environment variables
if (!this->CTestEnv.empty()) {
- std::vector<std::string> envArgs;
- cmExpandList(this->CTestEnv, envArgs);
+ std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv);
cmSystemTools::AppendEnv(envArgs);
}
@@ -649,8 +648,7 @@ int cmCTestScriptHandler::PerformExtraUpdates()
// do an initial cvs update as required
command = this->UpdateCmd;
for (std::string const& eu : this->ExtraUpdates) {
- std::vector<std::string> cvsArgs;
- cmExpandList(eu, cvsArgs);
+ std::vector<std::string> cvsArgs = cmExpandedList(eu);
if (cvsArgs.size() == 2) {
std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]);
output.clear();
@@ -789,8 +787,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
}
// run ctest, it may be more than one command in here
- std::vector<std::string> ctestCommands;
- cmExpandList(this->CTestCmd, ctestCommands);
+ std::vector<std::string> ctestCommands = cmExpandedList(this->CTestCmd);
// for each variable/argument do a putenv
for (std::string const& ctestCommand : ctestCommands) {
command = ctestCommand;
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index 67ff2db..e4a1844 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -33,14 +33,16 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
const char* bld_dir = nullptr;
while (cnt < args.size()) {
- if (args[cnt] == "TRACK") {
+ if (args[cnt] == "GROUP" || args[cnt] == "TRACK") {
cnt++;
if (cnt >= args.size() || args[cnt] == "APPEND" ||
args[cnt] == "QUIET") {
- this->SetError("TRACK argument missing track name");
+ std::ostringstream e;
+ e << args[cnt - 1] << " argument missing group name";
+ this->SetError(e.str());
return false;
}
- this->CTest->SetSpecificTrack(args[cnt].c_str());
+ this->CTest->SetSpecificGroup(args[cnt].c_str());
cnt++;
} else if (args[cnt] == "APPEND") {
cnt++;
@@ -113,10 +115,10 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
<< " Build directory: " << bld_dir << std::endl,
this->Quiet);
}
- const char* track = this->CTest->GetSpecificTrack();
- if (track) {
+ const char* group = this->CTest->GetSpecificGroup();
+ if (group) {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Track: " << track << std::endl, this->Quiet);
+ " Group: " << group << std::endl, this->Quiet);
}
// Log startup actions.
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index ec1e9bb..d16aac0 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -68,16 +68,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
const char* notesFilesVariable =
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable) {
- std::vector<std::string> notesFiles;
- cmExpandList(notesFilesVariable, notesFiles);
+ std::vector<std::string> notesFiles = cmExpandedList(notesFilesVariable);
this->CTest->GenerateNotesFile(notesFiles);
}
const char* extraFilesVariable =
this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
if (extraFilesVariable) {
- std::vector<std::string> extraFiles;
- cmExpandList(extraFilesVariable, extraFiles);
+ std::vector<std::string> extraFiles = cmExpandedList(extraFilesVariable);
if (!this->CTest->SubmitExtraFiles(extraFiles)) {
this->SetError("problem submitting extra files.");
return nullptr;
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index a30999b..a178b44 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -155,8 +155,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args;
- cmExpandList(curlopt, args);
+ std::vector<std::string> args = cmExpandedList(curlopt);
bool verifyPeerOff = false;
bool verifyHostOff = false;
for (std::string const& arg : args) {
@@ -499,8 +498,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
cmCTestCurl curl(this->CTest);
curl.SetQuiet(this->Quiet);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args;
- cmExpandList(curlopt, args);
+ std::vector<std::string> args = cmExpandedList(curlopt);
curl.SetCurlOptions(args);
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
@@ -569,6 +567,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
<< curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&"
<< "site=" << curl.Escape(this->CTest->GetCTestConfiguration("Site"))
<< "&"
+ << "group=" << curl.Escape(this->CTest->GetTestModelString())
+ << "&"
+ // For now, we send both "track" and "group" to CDash in case we're
+ // submitting to an older instance that still expects the prior
+ // terminology.
<< "track=" << curl.Escape(this->CTest->GetTestModelString()) << "&"
<< "starttime=" << timeNow << "&"
<< "endtime=" << timeNow << "&"
@@ -837,10 +840,10 @@ int cmCTestSubmitHandler::ProcessHandler()
}
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n",
this->Quiet);
- const char* specificTrack = this->CTest->GetSpecificTrack();
- if (specificTrack) {
+ const char* specificGroup = this->CTest->GetSpecificGroup();
+ if (specificGroup) {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Send to track: " << specificTrack << std::endl,
+ " Send to group: " << specificGroup << std::endl,
this->Quiet);
}
this->SetLogFile(&ofs);
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4cb19f8..9181daa 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -695,8 +695,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
}
// if we are doing sub projects and this label is one, then use it
// if we are not doing sub projects and the label is not one use it
- if ((doSubProject && isSubprojectLabel) ||
- (!doSubProject && !isSubprojectLabel)) {
+ if (doSubProject == isSubprojectLabel) {
if (l.size() > maxlen) {
maxlen = l.size();
}
@@ -889,7 +888,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
cnt++;
// if this test is not in our list of tests to run, then skip it.
- if ((!this->TestsToRun.empty() && !cmContains(TestsToRun, cnt))) {
+ if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
continue;
}
@@ -2185,26 +2184,22 @@ bool cmCTestTestHandler::SetTestsProperties(
cmExpandList(val, rt.AttachOnFail);
}
if (key == "RESOURCE_LOCK") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.LockedResources.insert(lval.begin(), lval.end());
}
if (key == "FIXTURES_SETUP") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesSetup.insert(lval.begin(), lval.end());
}
if (key == "FIXTURES_CLEANUP") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesCleanup.insert(lval.begin(), lval.end());
}
if (key == "FIXTURES_REQUIRED") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesRequired.insert(lval.begin(), lval.end());
}
@@ -2222,15 +2217,13 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.RunSerial = cmIsOn(val);
}
if (key == "FAIL_REGULAR_EXPRESSION") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
}
if (key == "SKIP_REGULAR_EXPRESSION") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.SkipRegularExpressions.emplace_back(cr, cr);
}
@@ -2257,8 +2250,7 @@ bool cmCTestTestHandler::SetTestsProperties(
cmExpandList(val, rt.Environment);
}
if (key == "LABELS") {
- std::vector<std::string> Labels;
- cmExpandList(val, Labels);
+ std::vector<std::string> Labels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
std::sort(rt.Labels.begin(), rt.Labels.end());
@@ -2278,8 +2270,7 @@ bool cmCTestTestHandler::SetTestsProperties(
}
}
if (key == "PASS_REGULAR_EXPRESSION") {
- std::vector<std::string> lval;
- cmExpandList(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
@@ -2288,16 +2279,14 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Directory = val;
}
if (key == "TIMEOUT_AFTER_MATCH") {
- std::vector<std::string> propArgs;
- cmExpandList(val, propArgs);
+ std::vector<std::string> propArgs = cmExpandedList(val);
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
"TIMEOUT_AFTER_MATCH expects two arguments, found "
<< propArgs.size() << std::endl);
} else {
rt.AlternateTimeout = cmDuration(atof(propArgs[0].c_str()));
- std::vector<std::string> lval;
- cmExpandList(propArgs[1], lval);
+ std::vector<std::string> lval = cmExpandedList(propArgs[1]);
for (std::string const& cr : lval) {
rt.TimeoutRegularExpressions.emplace_back(cr, cr);
}
@@ -2339,8 +2328,7 @@ bool cmCTestTestHandler::SetDirectoryProperties(
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
if (key == "LABELS") {
- std::vector<std::string> DirectoryLabels;
- cmExpandList(val, DirectoryLabels);
+ std::vector<std::string> DirectoryLabels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
diff --git a/Source/Checks/cm_cxx17_check.cpp b/Source/Checks/cm_cxx17_check.cpp
index 593d9b2..29863b1 100644
--- a/Source/Checks/cm_cxx17_check.cpp
+++ b/Source/Checks/cm_cxx17_check.cpp
@@ -1,6 +1,7 @@
#include <cstdio>
#include <iterator>
#include <memory>
+#include <optional>
#include <unordered_map>
#ifdef _MSC_VER
@@ -27,5 +28,7 @@ int main()
IDispatchPtr disp(ptr);
#endif
- return *u + *ai + *(bi - 1) + (3 - static_cast<int>(ci));
+ std::optional<int> oi = 0;
+
+ return *u + *ai + *(bi - 1) + (3 - static_cast<int>(ci)) + oi.value();
}
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index f7e3920..f450a1c 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -71,8 +71,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
cmCursesOptionsWidget* ow =
new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1);
this->Entry = ow;
- std::vector<std::string> options;
- cmExpandList(stringsProp, options);
+ std::vector<std::string> options = cmExpandedList(stringsProp);
for (auto const& opt : options) {
ow->AddOption(opt);
}
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 59d6be3..f1264d5 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -93,9 +93,7 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args,
return false;
}
if (args.size() != 3) {
- std::ostringstream e;
- e << "ALIAS requires exactly one target argument.";
- status.SetError(e.str());
+ status.SetError("ALIAS requires exactly one target argument.");
return false;
}
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 46fc61d..c067aea 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -49,9 +49,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
std::string libType = *s;
if (libType == "STATIC") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting STATIC type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting STATIC type.");
return false;
}
++s;
@@ -59,9 +58,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "SHARED") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting SHARED type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting SHARED type.");
return false;
}
++s;
@@ -69,9 +67,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "MODULE") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting MODULE type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting MODULE type.");
return false;
}
++s;
@@ -79,9 +76,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "OBJECT") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting OBJECT type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting OBJECT type.");
return false;
}
++s;
@@ -89,9 +85,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "UNKNOWN") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting UNKNOWN type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting UNKNOWN type.");
return false;
}
++s;
@@ -99,30 +94,26 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "ALIAS") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting ALIAS type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting ALIAS type.");
return false;
}
++s;
isAlias = true;
} else if (libType == "INTERFACE") {
if (haveSpecifiedType) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting/multiple types.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting/multiple types.");
return false;
}
if (isAlias) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting ALIAS type.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting ALIAS type.");
return false;
}
if (excludeFromAll) {
- std::ostringstream e;
- e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
return false;
}
++s;
@@ -130,9 +121,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (*s == "EXCLUDE_FROM_ALL") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
return false;
}
++s;
@@ -144,9 +134,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
++s;
importGlobal = true;
} else if (type == cmStateEnums::INTERFACE_LIBRARY && *s == "GLOBAL") {
- std::ostringstream e;
- e << "GLOBAL option may only be used with IMPORTED libraries.";
- status.SetError(e.str());
+ status.SetError(
+ "GLOBAL option may only be used with IMPORTED libraries.");
return false;
} else {
break;
@@ -155,15 +144,12 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (s != args.end()) {
- std::ostringstream e;
- e << "INTERFACE library requires no source arguments.";
- status.SetError(e.str());
+ status.SetError("INTERFACE library requires no source arguments.");
return false;
}
if (importGlobal && !importTarget) {
- std::ostringstream e;
- e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
- status.SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified as GLOBAL, but not as IMPORTED.");
return false;
}
}
@@ -192,9 +178,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
return false;
}
if (args.size() != 3) {
- std::ostringstream e;
- e << "ALIAS requires exactly one target argument.";
- status.SetError(e.str());
+ status.SetError("ALIAS requires exactly one target argument.");
return false;
}
diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx
index 588b2f2..09b0298 100644
--- a/Source/cmAffinity.cxx
+++ b/Source/cmAffinity.cxx
@@ -12,6 +12,8 @@
# define CM_HAVE_CPU_AFFINITY
# include <pthread.h>
# include <sched.h>
+// On some platforms CPU_ZERO needs memset but sched.h forgets string.h
+# include <string.h> // IWYU pragma: keep
# if defined(__FreeBSD__)
# include <pthread_np.h>
# include <sys/cpuset.h>
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 1669853..974b984 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeHostSystemInformationCommand.h"
-#include <sstream>
#include <stddef.h>
#include "cmExecutionStatus.h"
@@ -183,9 +182,7 @@ bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
std::string ValueToString(size_t value)
{
- std::ostringstream tmp;
- tmp << value;
- return tmp.str();
+ return std::to_string(value);
}
std::string ValueToString(const char* value)
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 866d262..f51ed0b 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -155,7 +155,7 @@ struct cmCTest::Private
bool TomorrowTag = false;
int TestModel = cmCTest::EXPERIMENTAL;
- std::string SpecificTrack;
+ std::string SpecificGroup;
cmDuration TimeOut = cmDuration::zero();
@@ -508,10 +508,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
day != lctime->tm_mday) {
tag.clear();
}
- std::string track;
- if (cmSystemTools::GetLineFromStream(tfin, track) &&
+ std::string group;
+ if (cmSystemTools::GetLineFromStream(tfin, group) &&
!this->Impl->Parts[PartStart] && !command) {
- this->Impl->SpecificTrack = track;
+ this->Impl->SpecificGroup = group;
}
std::string model;
if (cmSystemTools::GetLineFromStream(tfin, model) &&
@@ -564,13 +564,13 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
}
} else {
- std::string track;
+ std::string group;
std::string modelStr;
int model = cmCTest::UNKNOWN;
if (tfin) {
cmSystemTools::GetLineFromStream(tfin, tag);
- cmSystemTools::GetLineFromStream(tfin, track);
+ cmSystemTools::GetLineFromStream(tfin, group);
if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
model = GetTestModelFromString(modelStr.c_str());
}
@@ -605,15 +605,15 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
quiet);
}
- if (!this->Impl->SpecificTrack.empty() &&
- track != this->Impl->SpecificTrack) {
+ if (!this->Impl->SpecificGroup.empty() &&
+ group != this->Impl->SpecificGroup) {
cmCTestOptionalLog(this, WARNING,
- "Track given in TAG does not match "
- "track given in ctest_start()"
+ "Group given in TAG does not match "
+ "group given in ctest_start()"
<< std::endl,
quiet);
} else {
- this->Impl->SpecificTrack = track;
+ this->Impl->SpecificGroup = group;
}
cmCTestOptionalLog(this, OUTPUT,
@@ -1017,8 +1017,8 @@ int cmCTest::ProcessSteps()
std::string cmCTest::GetTestModelString()
{
- if (!this->Impl->SpecificTrack.empty()) {
- return this->Impl->SpecificTrack;
+ if (!this->Impl->SpecificGroup.empty()) {
+ return this->Impl->SpecificGroup;
}
switch (this->Impl->TestModel) {
case cmCTest::NIGHTLY:
@@ -1218,9 +1218,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
timeout != cmCTest::MaxDuration() &&
timeout > cmDuration::zero()) {
args.emplace_back("--test-timeout");
- std::ostringstream msg;
- msg << cmDurationTo<unsigned int>(timeout);
- args.push_back(msg.str());
+ args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout)));
}
args.emplace_back(i);
}
@@ -1448,8 +1446,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
if (labels) {
xml.StartElement("Labels");
std::string l = labels;
- std::vector<std::string> args;
- cmExpandList(l, args);
+ std::vector<std::string> args = cmExpandedList(l);
for (std::string const& i : args) {
xml.Element("Label", i);
}
@@ -1481,8 +1478,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects()
{
std::string labelsForSubprojects =
this->GetCTestConfiguration("LabelsForSubprojects");
- std::vector<std::string> subprojects;
- cmExpandList(labelsForSubprojects, subprojects);
+ std::vector<std::string> subprojects = cmExpandedList(labelsForSubprojects);
// sort the array
std::sort(subprojects.begin(), subprojects.end());
@@ -1904,9 +1900,15 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
this->Impl->Debug = true;
this->Impl->ShowLineNumbers = true;
}
+ if (this->CheckArgument(arg, "--group") && i < args.size() - 1) {
+ i++;
+ this->Impl->SpecificGroup = args[i];
+ }
+ // This is an undocumented / deprecated option.
+ // "Track" has been renamed to "Group".
if (this->CheckArgument(arg, "--track") && i < args.size() - 1) {
i++;
- this->Impl->SpecificTrack = args[i];
+ this->Impl->SpecificGroup = args[i];
}
if (this->CheckArgument(arg, "--show-line-numbers")) {
this->Impl->ShowLineNumbers = true;
@@ -2125,6 +2127,11 @@ bool cmCTest::ColoredOutputSupportedByConsole()
return false;
#else
// On UNIX we need a non-dumb tty.
+ std::string clicolor_force;
+ if (cmSystemTools::GetEnv("CLICOLOR_FORCE", clicolor_force) &&
+ !clicolor_force.empty() && clicolor_force != "0") {
+ return true;
+ }
return ConsoleIsNotDumb();
#endif
}
@@ -2762,21 +2769,21 @@ std::vector<std::string>& cmCTest::GetInitialCommandLineArguments()
return this->Impl->InitialCommandLineArguments;
}
-const char* cmCTest::GetSpecificTrack()
+const char* cmCTest::GetSpecificGroup()
{
- if (this->Impl->SpecificTrack.empty()) {
+ if (this->Impl->SpecificGroup.empty()) {
return nullptr;
}
- return this->Impl->SpecificTrack.c_str();
+ return this->Impl->SpecificGroup.c_str();
}
-void cmCTest::SetSpecificTrack(const char* track)
+void cmCTest::SetSpecificGroup(const char* group)
{
- if (!track) {
- this->Impl->SpecificTrack.clear();
+ if (!group) {
+ this->Impl->SpecificGroup.clear();
return;
}
- this->Impl->SpecificTrack = track;
+ this->Impl->SpecificGroup = group;
}
void cmCTest::SetFailover(bool failover)
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 7f66378..7fe3455 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -404,9 +404,9 @@ public:
std::vector<std::string>& GetInitialCommandLineArguments();
- /** Set the track to submit to */
- void SetSpecificTrack(const char* track);
- const char* GetSpecificTrack();
+ /** Set the group to submit to */
+ void SetSpecificGroup(const char* group);
+ const char* GetSpecificGroup();
void SetFailover(bool failover);
bool GetFailover() const;
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 67ff94b..cf28cdb 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -541,8 +541,7 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
// make sure we only use unix style paths
if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
if (e.Value.find(';') != std::string::npos) {
- std::vector<std::string> paths;
- cmExpandList(e.Value, paths);
+ std::vector<std::string> paths = cmExpandedList(e.Value);
const char* sep = "";
e.Value = "";
for (std::string& i : paths) {
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 073a0cd..b368b3a 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -88,9 +88,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
return nullptr;
}
if (this->FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0) {
- std::ostringstream ostr;
- ostr << this->FileLine;
- return this->AddString(ostr.str());
+ return this->AddString(std::to_string(this->FileLine));
}
const char* value = this->Makefile->GetDefinition(var);
if (!value) {
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index ead16d2..702b743 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -78,6 +78,7 @@
#include "cmTargetCompileOptionsCommand.h"
#include "cmTargetIncludeDirectoriesCommand.h"
#include "cmTargetLinkLibrariesCommand.h"
+#include "cmTargetPrecompileHeadersCommand.h"
#include "cmTargetSourcesCommand.h"
#include "cmTryCompileCommand.h"
#include "cmTryRunCommand.h"
@@ -208,8 +209,7 @@ void GetScriptingCommands(cmState* state)
"build_name", cmBuildNameCommand, cmPolicies::CMP0036,
"The build_name command should not be called; see CMP0036.");
state->AddDisallowedCommand(
- "use_mangled_mesa", cm::make_unique<cmUseMangledMesaCommand>(),
- cmPolicies::CMP0030,
+ "use_mangled_mesa", cmUseMangledMesaCommand, cmPolicies::CMP0030,
"The use_mangled_mesa command should not be called; see CMP0030.");
#endif
@@ -277,6 +277,9 @@ void GetProjectCommands(cmState* state)
state->AddBuiltinCommand("try_compile",
cm::make_unique<cmTryCompileCommand>());
state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>());
+ state->AddBuiltinCommand(
+ "target_precompile_headers",
+ cm::make_unique<cmTargetPrecompileHeadersCommand>());
#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("add_compile_definitions",
@@ -310,29 +313,24 @@ void GetProjectCommands(cmState* state)
cm::make_unique<cmSourceGroupCommand>());
state->AddDisallowedCommand(
- "export_library_dependencies",
- cm::make_unique<cmExportLibraryDependenciesCommand>(), cmPolicies::CMP0033,
+ "export_library_dependencies", cmExportLibraryDependenciesCommand,
+ cmPolicies::CMP0033,
"The export_library_dependencies command should not be called; "
"see CMP0033.");
state->AddDisallowedCommand(
- "load_command", cm::make_unique<cmLoadCommandCommand>(),
- cmPolicies::CMP0031,
+ "load_command", cmLoadCommandCommand, cmPolicies::CMP0031,
"The load_command command should not be called; see CMP0031.");
state->AddDisallowedCommand(
- "output_required_files", cm::make_unique<cmOutputRequiredFilesCommand>(),
- cmPolicies::CMP0032,
+ "output_required_files", cmOutputRequiredFilesCommand, cmPolicies::CMP0032,
"The output_required_files command should not be called; see CMP0032.");
state->AddDisallowedCommand(
- "subdir_depends", cm::make_unique<cmSubdirDependsCommand>(),
- cmPolicies::CMP0029,
+ "subdir_depends", cmSubdirDependsCommand, cmPolicies::CMP0029,
"The subdir_depends command should not be called; see CMP0029.");
state->AddDisallowedCommand(
- "utility_source", cm::make_unique<cmUtilitySourceCommand>(),
- cmPolicies::CMP0034,
+ "utility_source", cmUtilitySourceCommand, cmPolicies::CMP0034,
"The utility_source command should not be called; see CMP0034.");
state->AddDisallowedCommand(
- "variable_requires", cm::make_unique<cmVariableRequiresCommand>(),
- cmPolicies::CMP0035,
+ "variable_requires", cmVariableRequiresCommand, cmPolicies::CMP0035,
"The variable_requires command should not be called; see CMP0035.");
#endif
}
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index c4b0c05..a39425c 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -436,8 +436,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
// This is called to add the dependencies named by
// <item>_LIB_DEPENDS. The variable contains a semicolon-separated
// list. The list contains link-type;item pairs and just items.
- std::vector<std::string> deplist;
- cmExpandList(value, deplist);
+ std::vector<std::string> deplist = cmExpandedList(value);
// Look for entries meant for this configuration.
std::vector<cmLinkItem> actual_libs;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 0ff0c3a..880d5c0 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -541,8 +541,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// linker language.
std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES");
if (const char* libs = this->Makefile->GetDefinition(libVar)) {
- std::vector<std::string> libsVec;
- cmExpandList(libs, libsVec);
+ std::vector<std::string> libsVec = cmExpandedList(libs);
for (std::string const& i : libsVec) {
if (!cmContains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
@@ -554,8 +553,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// implied by the linker language.
std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES");
if (const char* dirs = this->Makefile->GetDefinition(dirVar)) {
- std::vector<std::string> dirsVec;
- cmExpandList(dirs, dirsVec);
+ std::vector<std::string> dirsVec = cmExpandedList(dirs);
this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
}
}
@@ -795,16 +793,14 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
LinkUnknown);
if (const char* linkSuffixes =
mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
- std::vector<std::string> linkSuffixVec;
- cmExpandList(linkSuffixes, linkSuffixVec);
+ std::vector<std::string> linkSuffixVec = cmExpandedList(linkSuffixes);
for (std::string const& i : linkSuffixVec) {
this->AddLinkExtension(i.c_str(), LinkUnknown);
}
}
if (const char* sharedSuffixes =
mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
- std::vector<std::string> sharedSuffixVec;
- cmExpandList(sharedSuffixes, sharedSuffixVec);
+ std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes);
for (std::string const& i : sharedSuffixVec) {
this->AddLinkExtension(i.c_str(), LinkShared);
}
@@ -1640,8 +1636,7 @@ static void cmCLI_ExpandListUnique(const char* str,
std::vector<std::string>& out,
std::set<std::string>& emitted)
{
- std::vector<std::string> tmp;
- cmExpandList(str, tmp);
+ std::vector<std::string> tmp = cmExpandedList(str);
for (std::string const& i : tmp) {
if (emitted.insert(i).second) {
out.push_back(i);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index d72f561..21df278 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -668,8 +668,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
def2 = this->Makefile.GetDefinition(argP2->GetValue());
if (def2) {
- std::vector<std::string> list;
- cmExpandList(def2, list, true);
+ std::vector<std::string> list = cmExpandedList(def2, true);
result = cmContains(list, def);
}
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index f696b95..3687056 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -674,8 +674,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
if (const char* varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
- std::vector<std::string> varList;
- cmExpandList(varListStr, varList);
+ std::vector<std::string> varList = cmExpandedList(varListStr);
vars.insert(varList.begin(), varList.end());
}
diff --git a/Source/cmDisallowedCommand.cxx b/Source/cmDisallowedCommand.cxx
deleted file mode 100644
index aa1f90b..0000000
--- a/Source/cmDisallowedCommand.cxx
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmDisallowedCommand.h"
-
-#include "cmMakefile.h"
-#include "cmMessageType.h"
-
-class cmExecutionStatus;
-
-bool cmDisallowedCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
-{
- switch (this->Makefile->GetPolicyStatus(this->Policy)) {
- case cmPolicies::WARN:
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
- cmPolicies::GetPolicyWarning(this->Policy));
- break;
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Message);
- return true;
- }
-
- this->Command->SetExecutionStatus(this->GetExecutionStatus());
- return this->Command->InitialPass(args, status);
-}
diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h
deleted file mode 100644
index e07f255..0000000
--- a/Source/cmDisallowedCommand.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmDisallowedCommand_h
-#define cmDisallowedCommand_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-#include "cmPolicies.h"
-
-class cmExecutionStatus;
-
-class cmDisallowedCommand : public cmCommand
-{
-public:
- cmDisallowedCommand(std::unique_ptr<cmCommand> command,
- cmPolicies::PolicyID policy, const char* message)
- : Command(std::move(command))
- , Policy(policy)
- , Message(message)
- {
- }
-
- ~cmDisallowedCommand() override = default;
-
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmDisallowedCommand>(this->Command->Clone(),
- this->Policy, this->Message);
- }
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- std::unique_ptr<cmCommand> Command;
- cmPolicies::PolicyID Policy;
- const char* Message;
-};
-
-#endif
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index f8ce592..561e830 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -143,8 +143,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
}
} else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
std::string includes = property.second;
- std::vector<std::string> includeList;
- cmExpandList(includes, includeList);
+ std::vector<std::string> includeList = cmExpandedList(includes);
os << "LOCAL_EXPORT_C_INCLUDES := ";
std::string end;
for (std::string const& i : includeList) {
@@ -154,8 +153,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
os << "\n";
} else if (property.first == "INTERFACE_LINK_OPTIONS") {
os << "LOCAL_EXPORT_LDFLAGS := ";
- std::vector<std::string> linkFlagsList;
- cmExpandList(property.second, linkFlagsList);
+ std::vector<std::string> linkFlagsList =
+ cmExpandedList(property.second);
os << cmJoin(linkFlagsList, " ") << "\n";
} else {
os << "# " << property.first << " " << (property.second) << "\n";
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 8a1a305..9f0396b 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -91,6 +91,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gte,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 96733f2..70f98bf 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -499,8 +499,7 @@ void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
if (!p) {
return;
}
- std::vector<std::string> content;
- cmExpandList(p, content);
+ std::vector<std::string> content = cmExpandedList(p);
ifaceProperties.insert(content.begin(), content.end());
}
@@ -843,9 +842,7 @@ void cmExportFileGenerator::SetImportDetailProperties(
if (iface->Multiplicity > 0) {
std::string prop =
cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
- std::ostringstream m;
- m << iface->Multiplicity;
- properties[prop] = m.str();
+ properties[prop] = std::to_string(iface->Multiplicity);
}
}
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 81237db..bab394a 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -8,6 +8,7 @@
#include "cm_memory.hxx"
+#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -18,8 +19,6 @@
#include "cmTargetLinkLibraryType.h"
#include "cmake.h"
-class cmExecutionStatus;
-
static void FinalAction(cmMakefile& makefile, std::string const& filename,
bool append)
{
@@ -140,19 +139,20 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename,
fout << "endif()\n";
}
-bool cmExportLibraryDependenciesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string const& filename = args[0];
bool const append = args.size() > 1 && args[1] == "APPEND";
- this->Makefile->AddFinalAction([filename, append](cmMakefile& makefile) {
- FinalAction(makefile, filename, append);
- });
+ status.GetMakefile().AddFinalAction(
+ [filename, append](cmMakefile& makefile) {
+ FinalAction(makefile, filename, append);
+ });
return true;
}
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index 4817162..230c906 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmExportLibraryDependenciesCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmExportLibraryDependenciesCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index f77fd3a..5631d60 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -103,8 +103,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
- std::vector<std::string> depends;
- cmExpandList(evalResult, depends);
+ std::vector<std::string> depends = cmExpandedList(evalResult);
for (std::string const& li : depends) {
cmGeneratorTarget* tgt =
target->GetLocalGenerator()->FindGeneratorTargetToUse(li);
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index d8a1a49..487d0de 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -365,7 +365,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// check whether it is a C/C++/CUDA implementation file
bool isCFile = false;
- std::string lang = s->GetLanguage();
+ std::string lang = s->GetOrDetermineLanguage();
if (lang == "C" || lang == "CXX" || lang == "CUDA") {
std::string const& srcext = s->GetExtension();
isCFile = cm->IsSourceExtension(srcext);
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 5ff638d..6c94aae 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -415,8 +415,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
if (const char* extraNaturesProp =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
- std::vector<std::string> extraNatures;
- cmExpandList(extraNaturesProp, extraNatures);
+ std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp);
for (std::string const& n : extraNatures) {
xml.Element("nature", n);
}
@@ -797,8 +796,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS");
if (this->CEnabled && cDefs) {
// Expand the list.
- std::vector<std::string> defs;
- cmExpandList(cDefs, defs, true);
+ std::vector<std::string> defs = cmExpandedList(cDefs, true);
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
@@ -830,8 +828,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS");
if (this->CXXEnabled && cxxDefs) {
// Expand the list.
- std::vector<std::string> defs;
- cmExpandList(cxxDefs, defs, true);
+ std::vector<std::string> defs = cmExpandedList(cxxDefs, true);
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
@@ -881,16 +878,14 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
if (this->CEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs;
- cmExpandList(systemIncludeDirs, dirs);
+ std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
this->AppendIncludeDirectories(xml, dirs, emmited);
}
compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
if (this->CXXEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs;
- cmExpandList(systemIncludeDirs, dirs);
+ std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
this->AppendIncludeDirectories(xml, dirs, emmited);
}
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 36d9afd..6f4472b 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -134,8 +134,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile(
// End of build_systems
fout << "\n\t]";
std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- std::vector<std::string> tokens;
- cmExpandList(this->EnvSettings, tokens);
+ std::vector<std::string> tokens = cmExpandedList(this->EnvSettings);
if (!this->EnvSettings.empty()) {
fout << ",";
@@ -343,7 +342,7 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* gtgt)
{
std::string flags;
- std::string language = source->GetLanguage();
+ std::string language = source->GetOrDetermineLanguage();
if (language.empty()) {
language = "C";
}
@@ -378,7 +377,7 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
{
std::set<std::string> defines;
cmMakefile* makefile = lg->GetMakefile();
- const std::string& language = source->GetLanguage();
+ const std::string& language = source->GetOrDetermineLanguage();
const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
language);
@@ -411,7 +410,7 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes(
{
std::vector<std::string> includes;
cmMakefile* makefile = lg->GetMakefile();
- const std::string& language = source->GetLanguage();
+ const std::string& language = source->GetOrDetermineLanguage();
const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
language);
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index e4b7670..08db7c7 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -837,7 +837,7 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
{
CompileData fd;
- fd.Language = sf->GetLanguage();
+ fd.Language = sf->GetOrDetermineLanguage();
if (fd.Language.empty()) {
return fd;
}
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 3156c95..e00e726 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -173,8 +173,8 @@ bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode)
const char* default_dir_install_permissions = this->Makefile->GetDefinition(
"CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (default_dir_install_permissions && *default_dir_install_permissions) {
- std::vector<std::string> items;
- cmExpandList(default_dir_install_permissions, items);
+ std::vector<std::string> items =
+ cmExpandedList(default_dir_install_permissions);
for (const auto& arg : items) {
if (!this->CheckPermissions(arg, **mode)) {
this->Status.SetError(
@@ -446,9 +446,8 @@ bool cmFileCopier::Install(const std::string& fromFile,
const std::string& toFile)
{
if (fromFile.empty()) {
- std::ostringstream e;
- e << "INSTALL encountered an empty string input file name.";
- this->Status.SetError(e.str());
+ this->Status.SetError(
+ "INSTALL encountered an empty string input file name.");
return false;
}
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 191d7bb..cdc5f63 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -145,7 +145,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
// look for old style
// FIND_*(VAR name path1 path2 ...)
- if (!newStyle) {
+ if (!newStyle && !this->Names.empty()) {
// All the short-hand arguments have been recorded as names.
std::vector<std::string> shortArgs = this->Names;
this->Names.clear(); // clear out any values in Names
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index e8f03d7..9420541 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -62,9 +62,7 @@ bool cmFunctionHelperCommand::operator()(
this->Policies);
// set the value of argc
- std::ostringstream strStream;
- strStream << expandedArgs.size();
- makefile.AddDefinition("ARGC", strStream.str());
+ makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size()));
makefile.MarkVariableAsUsed("ARGC");
// set the values for ARGV0 ARGV1 ...
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 6d7d6ef..b72a40f 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -29,7 +29,8 @@ class cmGeneratorTarget;
SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \
SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \
SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES) \
- SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS)
+ SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) \
+ SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS)
#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 9a4e13e..667f4a0 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -375,8 +375,7 @@ static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode
"$<REMOVE_DUPLICATES:...> expression requires one parameter");
}
- std::vector<std::string> values;
- cmExpandList(parameters.front(), values, true);
+ std::vector<std::string> values = cmExpandedList(parameters.front(), true);
auto valuesEnd = cmRemoveDuplicates(values);
auto valuesBegin = values.cbegin();
@@ -684,10 +683,10 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
if (cmsysString_strcasecmp(param.c_str(), compilerId.c_str()) == 0) {
switch (context->LG->GetPolicyStatus(cmPolicies::CMP0044)) {
case cmPolicies::WARN: {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0044);
context->LG->GetCMakeInstance()->IssueMessage(
- MessageType::AUTHOR_WARNING, e.str(), context->Backtrace);
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0044),
+ context->Backtrace);
CM_FALLTHROUGH;
}
case cmPolicies::OLD:
@@ -939,8 +938,7 @@ static const struct JoinNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> list;
- cmExpandList(parameters.front(), list);
+ std::vector<std::string> list = cmExpandedList(parameters.front());
return cmJoin(list, parameters[1]);
}
} joinNode;
@@ -2209,8 +2207,7 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> listIn;
- cmExpandList(parameters.front(), listIn);
+ std::vector<std::string> listIn = cmExpandedList(parameters.front());
if (listIn.empty()) {
reportError(context, content->GetOriginalExpression(),
"\"\" is not an absolute path.");
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2e9a11a..cc37232 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -21,6 +21,7 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
@@ -278,6 +279,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
, DebugCompileDefinitionsDone(false)
, DebugLinkOptionsDone(false)
, DebugLinkDirectoriesDone(false)
+ , DebugPrecompileHeadersDone(false)
, DebugSourcesDone(false)
, LinkImplementationLanguageIsContextDependent(true)
, UtilityItemsDone(false)
@@ -312,6 +314,10 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
t->GetLinkDirectoriesBacktraces(),
this->LinkDirectoriesEntries);
+ CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(),
+ t->GetPrecompileHeadersBacktraces(),
+ this->PrecompileHeadersEntries);
+
CreatePropertyGeneratorExpressions(t->GetSourceEntries(),
t->GetSourceBacktraces(),
this->SourceEntries, true);
@@ -327,6 +333,7 @@ cmGeneratorTarget::~cmGeneratorTarget()
cmDeleteAll(this->CompileDefinitionsEntries);
cmDeleteAll(this->LinkOptionsEntries);
cmDeleteAll(this->LinkDirectoriesEntries);
+ cmDeleteAll(this->PrecompileHeadersEntries);
cmDeleteAll(this->SourceEntries);
cmDeleteAll(this->LinkInformation);
}
@@ -1405,8 +1412,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmStringRange sourceEntries = this->Target->GetSourceEntries();
for (std::string const& entry : sourceEntries) {
- std::vector<std::string> items;
- cmExpandList(entry, items);
+ std::vector<std::string> items = cmExpandedList(entry);
for (std::string const& item : items) {
if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") &&
item.back() == '>') {
@@ -1594,7 +1600,7 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
kind = SourceKindHeader;
} else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
kind = SourceKindExternalObject;
- } else if (!sf->GetLanguage().empty()) {
+ } else if (!sf->GetOrDetermineLanguage().empty()) {
kind = SourceKindObjectSource;
} else if (ext == "def") {
kind = SourceKindModuleDefinition;
@@ -2674,8 +2680,7 @@ void cmTargetTraceDependencies::Trace()
// Queue dependencies added explicitly by the user.
if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDeps;
- cmExpandList(additionalDeps, objDeps);
+ std::vector<std::string> objDeps = cmExpandedList(additionalDeps);
for (std::string& objDep : objDeps) {
if (cmSystemTools::FileIsFullPath(objDep)) {
objDep = cmSystemTools::CollapseFullPath(objDep);
@@ -3289,10 +3294,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
if (configProp) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) {
case cmPolicies::WARN: {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
- this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING,
- e.str());
+ this->LocalGenerator->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0043));
CM_FALLTHROUGH;
}
case cmPolicies::OLD: {
@@ -3315,6 +3319,152 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
return list;
}
+std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
+ const std::string& config, const std::string& language) const
+{
+ std::unordered_set<std::string> uniqueOptions;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
+ nullptr, nullptr);
+
+ std::vector<std::string> debugProperties;
+ const char* debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp) {
+ cmExpandList(debugProp, debugProperties);
+ }
+
+ bool debugDefines = !this->DebugPrecompileHeadersDone &&
+ std::find(debugProperties.begin(), debugProperties.end(),
+ "PRECOMPILE_HEADERS") != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
+ this->DebugPrecompileHeadersDone = true;
+ }
+
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->PrecompileHeadersEntries);
+
+ AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
+ &dagChecker, entries);
+
+ std::vector<BT<std::string>> list;
+ processOptions(this, entries, list, uniqueOptions, debugDefines,
+ "precompile headers", OptionsParse::None);
+
+ return list;
+}
+
+std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
+ const std::string& language) const
+{
+ if (language != "C" && language != "CXX") {
+ return std::string();
+ }
+ if (this->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
+ return std::string();
+ }
+ const auto inserted =
+ this->PchHeaders.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ const std::vector<BT<std::string>> headers =
+ this->GetPrecompileHeaders(config, language);
+ if (headers.empty()) {
+ return std::string();
+ }
+ std::string& filename = inserted.first->second;
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ filename =
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), "/");
+ } else {
+ // For GCC we need to have the header file .h[xx]
+ // next to the .h[xx].gch file
+ filename = this->ObjectDirectory;
+ }
+
+ filename = cmStrCat(filename, "CMakeFiles/", this->GetName(),
+ ".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx"));
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
+ auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE");
+
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ this->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+ if (pchPrologue) {
+ file << pchPrologue << "\n";
+ }
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n";
+ }
+ if (language == "CXX") {
+ file << "#ifdef __cplusplus\n";
+ }
+ for (auto const& header_bt : headers) {
+ if (header_bt.Value.empty()) {
+ continue;
+ }
+ if (header_bt.Value[0] == '<' || header_bt.Value[0] == '"') {
+ file << "#include " << header_bt.Value << "\n";
+ } else {
+ file << "#include \"" << header_bt.Value << "\"\n";
+ }
+ }
+ if (language == "CXX") {
+ file << "#endif // __cplusplus\n";
+ }
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n";
+ }
+ if (pchEpilogue) {
+ file << pchEpilogue << "\n";
+ }
+ }
+ cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
+ cmSystemTools::RemoveFile(filename_tmp);
+ }
+ return inserted.first->second;
+}
+
+std::string cmGeneratorTarget::GetPchSource(const std::string& config,
+ const std::string& language) const
+{
+ if (language != "C" && language != "CXX") {
+ return std::string();
+ }
+ const auto inserted =
+ this->PchSources.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ const std::string pchHeader = this->GetPchHeader(config, language);
+ if (pchHeader.empty()) {
+ return std::string();
+ }
+ std::string& filename = inserted.first->second;
+ filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", this->GetName(), ".dir/cmake_pch");
+
+ // For GCC the source extension will be tranformed into .h[xx].gch
+ if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ filename += ((language == "C") ? ".h.c" : ".hxx.cxx");
+ } else {
+ filename += ((language == "C") ? ".c" : ".cxx");
+ }
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ cmGeneratedFileStream file(filename_tmp);
+ file << "/* generated by CMake */\n";
+ }
+ cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
+ cmSystemTools::RemoveFile(filename_tmp);
+ }
+ return inserted.first->second;
+}
+
void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
@@ -3363,8 +3513,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_LINKER_WRAPPER_FLAG"));
- std::vector<std::string> wrapperFlag;
- cmExpandList(wrapper, wrapperFlag);
+ std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP"));
bool concatFlagAndArgs = true;
@@ -3485,8 +3634,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<EvaluatedTargetPropertyEntry> entries;
if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
- std::vector<std::string> options;
- cmExpandList(linkOptions, options);
+ std::vector<std::string> options = cmExpandedList(linkOptions);
for (const auto& option : options) {
std::unique_ptr<TargetPropertyEntry> entry(
CreateTargetPropertyEntry(option));
@@ -3640,8 +3788,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
std::vector<EvaluatedTargetPropertyEntry> entries;
if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
- std::vector<std::string> depends;
- cmExpandList(linkDepends, depends);
+ std::vector<std::string> depends = cmExpandedList(linkDepends);
for (const auto& depend : depends) {
std::unique_ptr<TargetPropertyEntry> entry(
CreateTargetPropertyEntry(depend));
@@ -4184,8 +4331,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process public headers to mark the source files.
if (const char* files = this->GetProperty("PUBLIC_HEADER")) {
- std::vector<std::string> relFiles;
- cmExpandList(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4198,8 +4344,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process private headers after public headers so that they take
// precedence if a file is listed in both.
if (const char* files = this->GetProperty("PRIVATE_HEADER")) {
- std::vector<std::string> relFiles;
- cmExpandList(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4211,8 +4356,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Mark sources listed as resources.
if (const char* files = this->GetProperty("RESOURCE")) {
- std::vector<std::string> relFiles;
- cmExpandList(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4354,8 +4498,7 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
return;
}
- std::vector<std::string> props;
- cmExpandList(prop, props);
+ std::vector<std::string> props = cmExpandedList(prop);
std::string pdir =
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
@@ -5709,8 +5852,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, usage_requirements_only, iface.Libraries,
iface.HadHeadSensitiveCondition);
- std::vector<std::string> deps;
- cmExpandList(info->SharedDeps, deps);
+ std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
}
@@ -5993,8 +6135,7 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026(
// behavior of CMP0024 and CMP0026 only.
cmStringRange rng = this->Target->GetSourceEntries();
for (std::string const& entry : rng) {
- std::vector<std::string> files;
- cmExpandList(entry, files);
+ std::vector<std::string> files = cmExpandedList(entry);
for (std::string const& li : files) {
if (cmHasLiteralPrefix(li, "$<TARGET_OBJECTS:") && li.back() == '>') {
std::string objLibName = li.substr(17, li.size() - 18);
@@ -6067,7 +6208,7 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
std::vector<cmSourceFile*> sourceFiles;
this->GetSourceFiles(sourceFiles, config);
for (cmSourceFile* src : sourceFiles) {
- const std::string& lang = src->GetLanguage();
+ const std::string& lang = src->GetOrDetermineLanguage();
if (!lang.empty()) {
languages.insert(lang);
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 3874738..4701071 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -455,6 +455,14 @@ public:
std::vector<BT<std::string>> GetLinkDepends(
std::string const& config, std::string const& language) const;
+ std::vector<BT<std::string>> GetPrecompileHeaders(
+ const std::string& config, const std::string& language) const;
+
+ std::string GetPchHeader(const std::string& config,
+ const std::string& language) const;
+ std::string GetPchSource(const std::string& config,
+ const std::string& language) const;
+
bool IsSystemIncludeDirectory(const std::string& dir,
const std::string& config,
const std::string& language) const;
@@ -867,8 +875,11 @@ private:
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
std::vector<TargetPropertyEntry*> LinkOptionsEntries;
std::vector<TargetPropertyEntry*> LinkDirectoriesEntries;
+ std::vector<TargetPropertyEntry*> PrecompileHeadersEntries;
std::vector<TargetPropertyEntry*> SourceEntries;
mutable std::set<std::string> LinkImplicitNullProperties;
+ mutable std::map<std::string, std::string> PchHeaders;
+ mutable std::map<std::string, std::string> PchSources;
void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config,
@@ -922,6 +933,7 @@ private:
mutable bool DebugCompileDefinitionsDone;
mutable bool DebugLinkOptionsDone;
mutable bool DebugLinkDirectoriesDone;
+ mutable bool DebugPrecompileHeadersDone;
mutable bool DebugSourcesDone;
mutable bool LinkImplementationLanguageIsContextDependent;
mutable bool UtilityItemsDone;
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index a16076d..5c1c8a5 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -24,10 +24,6 @@ bool cmGetSourceFilePropertyCommand::InitialPass(
sf = this->Makefile->CreateSource(file);
}
if (sf) {
- if (args[2] == "LANGUAGE") {
- this->Makefile->AddDefinition(var, sf->GetLanguage());
- return true;
- }
const char* prop = nullptr;
if (!args[2].empty()) {
prop = sf->GetPropertyForUser(args[2]);
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 26fc226..e7b20ed 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -465,8 +465,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty(
{
const char* prop = sf->GetProperty(propName);
if (prop) {
- std::vector<std::string> list;
- cmExpandList(prop, list);
+ std::vector<std::string> list = cmExpandedList(prop);
for (auto& p : list) {
fout << " " << propFlag << p << std::endl;
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index e145ad4..4342e9f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -884,12 +884,9 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(
cmMakefile* mf, std::string const& lang) const
{
std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID";
- const char* compilerId = mf->GetDefinition(compilerIdVar);
- if (!compilerId) {
- return;
- }
+ std::string const compilerId = mf->GetSafeDefinition(compilerIdVar);
- if (strcmp(compilerId, "AppleClang") == 0) {
+ if (compilerId == "AppleClang") {
switch (mf->GetPolicyStatus(cmPolicies::CMP0025)) {
case cmPolicies::WARN:
if (!this->CMakeInstance->GetIsInTryCompile() &&
@@ -919,7 +916,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(
}
}
- if (strcmp(compilerId, "QCC") == 0) {
+ if (compilerId == "QCC") {
switch (mf->GetPolicyStatus(cmPolicies::CMP0047)) {
case cmPolicies::WARN:
if (!this->CMakeInstance->GetIsInTryCompile() &&
@@ -955,7 +952,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(
}
}
- if (strcmp(compilerId, "XLClang") == 0) {
+ if (compilerId == "XLClang") {
switch (mf->GetPolicyStatus(cmPolicies::CMP0089)) {
case cmPolicies::WARN:
if (!this->CMakeInstance->GetIsInTryCompile() &&
@@ -1110,8 +1107,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
std::string ignoreExtensionsVar =
std::string("CMAKE_") + std::string(l) + std::string("_IGNORE_EXTENSIONS");
std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar);
- std::vector<std::string> extensionList;
- cmExpandList(ignoreExts, extensionList);
+ std::vector<std::string> extensionList = cmExpandedList(ignoreExts);
for (std::string const& i : extensionList) {
this->IgnoreExtensions[i] = true;
}
@@ -1123,8 +1119,7 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
std::string extensionsVar = std::string("CMAKE_") + std::string(l) +
std::string("_SOURCE_FILE_EXTENSIONS");
const std::string& exts = mf->GetSafeDefinition(extensionsVar);
- std::vector<std::string> extensionList;
- cmExpandList(exts, extensionList);
+ std::vector<std::string> extensionList = cmExpandedList(exts);
for (std::string const& i : extensionList) {
this->ExtensionToLanguage[i] = l;
}
@@ -1581,8 +1576,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
"CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES";
std::string const& standardIncludesStr =
mf->GetSafeDefinition(standardIncludesVar);
- std::vector<std::string> standardIncludesVec;
- cmExpandList(standardIncludesStr, standardIncludesVec);
+ std::vector<std::string> standardIncludesVec =
+ cmExpandedList(standardIncludesStr);
standardIncludesSet.insert(standardIncludesVec.begin(),
standardIncludesVec.end());
}
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 25d678f..0b45f4b 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -610,8 +610,8 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
char const* ghsGpjMacros =
this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
if (nullptr != ghsGpjMacros) {
- std::vector<std::string> expandedList;
- cmExpandList(std::string(ghsGpjMacros), expandedList);
+ std::vector<std::string> expandedList =
+ cmExpandedList(std::string(ghsGpjMacros));
for (std::string const& arg : expandedList) {
fout << "macro " << arg << std::endl;
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 258e300..26ceedd 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -511,8 +511,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
extensibilityAddInsOverridden = true;
}
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
- std::vector<std::string> keyValuePairs;
- cmExpandList(root->GetMakefile()->GetProperty(it), keyValuePairs);
+ std::vector<std::string> keyValuePairs =
+ cmExpandedList(root->GetMakefile()->GetProperty(it));
for (std::string const& itPair : keyValuePairs) {
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index bb6ad16..6e0b804 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -555,9 +555,9 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
if (ERROR_SUCCESS == result) {
// Iterate the subkeys and look for the values of interest in each subkey:
wchar_t subkeyname[256];
- DWORD cch_subkeyname = sizeof(subkeyname) * sizeof(subkeyname[0]);
+ DWORD cch_subkeyname = cm::size(subkeyname);
wchar_t keyclass[256];
- DWORD cch_keyclass = sizeof(keyclass) * sizeof(keyclass[0]);
+ DWORD cch_keyclass = cm::size(keyclass);
FILETIME lastWriteTime;
lastWriteTime.dwHighDateTime = 0;
lastWriteTime.dwLowDateTime = 0;
@@ -571,8 +571,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
if (ERROR_SUCCESS == result) {
DWORD valueType = REG_SZ;
wchar_t data1[256];
- DWORD cch_data1 = sizeof(data1) * sizeof(data1[0]);
- RegQueryValueExW(hsubkey, L"Path", 0, &valueType, (LPBYTE)&data1[0],
+ DWORD cch_data1 = sizeof(data1);
+ RegQueryValueExW(hsubkey, L"Path", 0, &valueType, (LPBYTE)data1,
&cch_data1);
DWORD data2 = 0;
@@ -620,8 +620,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
}
++index;
- cch_subkeyname = sizeof(subkeyname) * sizeof(subkeyname[0]);
- cch_keyclass = sizeof(keyclass) * sizeof(keyclass[0]);
+ cch_subkeyname = cm::size(subkeyname);
+ cch_keyclass = cm::size(keyclass);
lastWriteTime.dwHighDateTime = 0;
lastWriteTime.dwLowDateTime = 0;
}
@@ -636,9 +636,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
// follow the expected naming scheme. Expected naming scheme is that
// the subkeys of OtherProjects7 is 0 to n-1, so it's ok to use "n"
// as the name of the next subkey.
- std::ostringstream ossNext;
- ossNext << index;
- nextAvailableSubKeyName = ossNext.str();
+ nextAvailableSubKeyName = std::to_string(index);
keyname = regKeyBase + "\\RecordingProject7";
hkey = NULL;
@@ -648,9 +646,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
if (ERROR_SUCCESS == result) {
DWORD valueType = REG_SZ;
wchar_t data1[256];
- DWORD cch_data1 = sizeof(data1) * sizeof(data1[0]);
- RegQueryValueExW(hkey, L"Path", 0, &valueType, (LPBYTE)&data1[0],
- &cch_data1);
+ DWORD cch_data1 = sizeof(data1);
+ RegQueryValueExW(hkey, L"Path", 0, &valueType, (LPBYTE)data1, &cch_data1);
DWORD data2 = 0;
DWORD cch_data2 = sizeof(data2);
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index cbab329..e4cd73f 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -110,6 +110,13 @@ public:
bool IsIncludeExternalMSProjectSupported() const override { return true; }
+ /** Get encoding used by generator for generated source files
+ */
+ codecvt::Encoding GetMakefileEncoding() const override
+ {
+ return codecvt::ANSI;
+ }
+
class TargetSet : public std::set<cmGeneratorTarget const*>
{
};
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index a8f27d6..427ab44 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -875,8 +875,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
- std::vector<std::string> attributes;
- cmExpandList(extraFileAttributes, attributes);
+ std::vector<std::string> attributes = cmExpandedList(extraFileAttributes);
// Store the attributes.
for (const auto& attribute : attributes) {
@@ -2375,6 +2374,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
this->CreateString(vso.str()));
}
+
+ // Precompile Headers
+ std::string pchHeader = gtgt->GetPchHeader(configName, llang);
+ if (!pchHeader.empty()) {
+ buildSettings->AddAttribute("GCC_PREFIX_HEADER",
+ this->CreateString(pchHeader));
+ buildSettings->AddAttribute("GCC_PRECOMPILE_PREFIX_HEADER",
+ this->CreateString("YES"));
+ }
+
// put this last so it can override existing settings
// Convert "XCODE_ATTRIBUTE_*" properties directly.
{
@@ -2830,6 +2839,8 @@ bool cmGlobalXCodeGenerator::CreateGroups(
continue;
}
+ generator->AddPchDependencies(gtgt, "");
+
auto addSourceToGroup = [this, mf, gtgt,
&sourceGroups](std::string const& source) {
cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
@@ -3568,8 +3579,7 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
}
// Expand the list of definitions.
- std::vector<std::string> defines;
- cmExpandList(defines_list, defines);
+ std::vector<std::string> defines = cmExpandedList(defines_list);
// Store the definitions in the string.
this->AppendDefines(defs, defines, dflag);
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index c5b5522..9b58f61 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -235,8 +235,8 @@ void cmGraphVizWriter::ReadSettings(
this->TargetsToIgnoreRegex.clear();
if (!ignoreTargetsRegexes.empty()) {
- std::vector<std::string> ignoreTargetsRegExVector;
- cmExpandList(ignoreTargetsRegexes, ignoreTargetsRegExVector);
+ std::vector<std::string> ignoreTargetsRegExVector =
+ cmExpandedList(ignoreTargetsRegexes);
for (std::string const& currentRegexString : ignoreTargetsRegExVector) {
cmsys::RegularExpression currentRegex;
if (!currentRegex.compile(currentRegexString)) {
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 8b428a9..9a78c49 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -368,10 +368,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
!objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() ||
!bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() ||
!publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) {
- std::ostringstream e;
- e << "TARGETS given TYPE option. The TYPE option may only be specified in "
- " install(FILES) and install(DIRECTORIES).";
- this->SetError(e.str());
+ this->SetError(
+ "TARGETS given TYPE option. The TYPE option may only be specified in "
+ " install(FILES) and install(DIRECTORIES).");
return false;
}
@@ -670,8 +669,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
const char* files = target.GetProperty("PRIVATE_HEADER");
if ((files) && (*files)) {
- std::vector<std::string> relFiles;
- cmExpandList(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
std::vector<std::string> absFiles;
if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
return false;
@@ -685,8 +683,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
files = target.GetProperty("PUBLIC_HEADER");
if ((files) && (*files)) {
- std::vector<std::string> relFiles;
- cmExpandList(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
std::vector<std::string> absFiles;
if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
return false;
@@ -700,8 +697,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
files = target.GetProperty("RESOURCE");
if ((files) && (*files)) {
- std::vector<std::string> relFiles;
- cmExpandList(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
std::vector<std::string> absFiles;
if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
return false;
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index b8eed13..4948b01 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -264,7 +264,7 @@ static Json::Value DumpSourceFilesList(
std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
for (cmSourceFile* file : files) {
LanguageData fileData;
- fileData.Language = file->GetLanguage();
+ fileData.Language = file->GetOrDetermineLanguage();
if (!fileData.Language.empty()) {
const LanguageData& ld = languageDataMap.at(fileData.Language);
cmLocalGenerator* lg = target->GetLocalGenerator();
diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx
index d5cc621..b68dbbd 100644
--- a/Source/cmLDConfigLDConfigTool.cxx
+++ b/Source/cmLDConfigLDConfigTool.cxx
@@ -33,8 +33,7 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
}
}
- std::vector<std::string> ldConfigCommand;
- cmExpandList(ldConfigPath, ldConfigCommand);
+ std::vector<std::string> ldConfigCommand = cmExpandedList(ldConfigPath);
ldConfigCommand.emplace_back("-v");
ldConfigCommand.emplace_back("-N"); // Don't rebuild the cache.
ldConfigCommand.emplace_back("-X"); // Don't update links.
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index fe77b33..91dea58 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -16,6 +16,7 @@
#include <vector>
#include "cm_memory.hxx"
+#include "cm_static_string_view.hxx"
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
@@ -26,121 +27,16 @@
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
namespace {
-bool HandleLengthCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleGetCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleAppendCommand(std::vector<std::string> const& args,
- cmMakefile& makefile);
-bool HandlePrependCommand(std::vector<std::string> const& args,
- cmMakefile& makefile);
-bool HandlePopBackCommand(std::vector<std::string> const& args,
- cmMakefile& makefile);
-bool HandlePopFrontCommand(std::vector<std::string> const& args,
- cmMakefile& makefile);
-bool HandleFindCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleInsertCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleJoinCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleRemoveAtCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleRemoveItemCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleTransformCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleSortCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleSublistCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleReverseCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleFilterCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
+
bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
std::string const& listName,
std::vector<std::string>& varArgsExpanded,
cmExecutionStatus& status);
-bool GetList(std::vector<std::string>& list, const std::string& var,
- const cmMakefile& makefile);
-bool GetListString(std::string& listString, const std::string& var,
- const cmMakefile& makefile);
-}
-
-bool cmListCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
-{
- if (args.size() < 2) {
- status.SetError("must be called with at least two arguments.");
- return false;
- }
-
- const std::string& subCommand = args[0];
- if (subCommand == "LENGTH") {
- return HandleLengthCommand(args, status);
- }
- if (subCommand == "GET") {
- return HandleGetCommand(args, status);
- }
- if (subCommand == "APPEND") {
- return HandleAppendCommand(args, status.GetMakefile());
- }
- if (subCommand == "PREPEND") {
- return HandlePrependCommand(args, status.GetMakefile());
- }
- if (subCommand == "POP_BACK") {
- return HandlePopBackCommand(args, status.GetMakefile());
- }
- if (subCommand == "POP_FRONT") {
- return HandlePopFrontCommand(args, status.GetMakefile());
- }
- if (subCommand == "FIND") {
- return HandleFindCommand(args, status);
- }
- if (subCommand == "INSERT") {
- return HandleInsertCommand(args, status);
- }
- if (subCommand == "JOIN") {
- return HandleJoinCommand(args, status);
- }
- if (subCommand == "REMOVE_AT") {
- return HandleRemoveAtCommand(args, status);
- }
- if (subCommand == "REMOVE_ITEM") {
- return HandleRemoveItemCommand(args, status);
- }
- if (subCommand == "REMOVE_DUPLICATES") {
- return HandleRemoveDuplicatesCommand(args, status);
- }
- if (subCommand == "TRANSFORM") {
- return HandleTransformCommand(args, status);
- }
- if (subCommand == "SORT") {
- return HandleSortCommand(args, status);
- }
- if (subCommand == "SUBLIST") {
- return HandleSublistCommand(args, status);
- }
- if (subCommand == "REVERSE") {
- return HandleReverseCommand(args, status);
- }
- if (subCommand == "FILTER") {
- return HandleFilterCommand(args, status);
- }
-
- std::string e = "does not recognize sub-command " + subCommand;
- status.SetError(e);
- return false;
-}
-
-namespace {
bool GetListString(std::string& listString, const std::string& var,
const cmMakefile& makefile)
{
@@ -275,7 +171,7 @@ bool HandleGetCommand(std::vector<std::string> const& args,
}
bool HandleAppendCommand(std::vector<std::string> const& args,
- cmMakefile& makefile)
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
@@ -284,6 +180,7 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
return true;
}
+ cmMakefile& makefile = status.GetMakefile();
std::string const& listName = args[1];
// expand the variable
std::string listString;
@@ -300,7 +197,7 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
}
bool HandlePrependCommand(std::vector<std::string> const& args,
- cmMakefile& makefile)
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
@@ -309,6 +206,7 @@ bool HandlePrependCommand(std::vector<std::string> const& args,
return true;
}
+ cmMakefile& makefile = status.GetMakefile();
std::string const& listName = args[1];
// expand the variable
std::string listString;
@@ -326,10 +224,11 @@ bool HandlePrependCommand(std::vector<std::string> const& args,
}
bool HandlePopBackCommand(std::vector<std::string> const& args,
- cmMakefile& makefile)
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
+ cmMakefile& makefile = status.GetMakefile();
auto ai = args.cbegin();
++ai; // Skip subcommand name
std::string const& listName = *ai++;
@@ -373,10 +272,11 @@ bool HandlePopBackCommand(std::vector<std::string> const& args,
}
bool HandlePopFrontCommand(std::vector<std::string> const& args,
- cmMakefile& makefile)
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
+ cmMakefile& makefile = status.GetMakefile();
auto ai = args.cbegin();
++ai; // Skip subcommand name
std::string const& listName = *ai++;
@@ -440,9 +340,9 @@ bool HandleFindCommand(std::vector<std::string> const& args,
std::vector<std::string>::iterator it =
std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]);
if (it != varArgsExpanded.end()) {
- std::ostringstream indexStream;
- indexStream << std::distance(varArgsExpanded.begin(), it);
- status.GetMakefile().AddDefinition(variableName, indexStream.str());
+ status.GetMakefile().AddDefinition(
+ variableName,
+ std::to_string(std::distance(varArgsExpanded.begin(), it)));
return true;
}
@@ -1564,4 +1464,36 @@ bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
status.GetMakefile().AddDefinition(listName, value);
return true;
}
+
+} // namespace
+
+bool cmListCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 2) {
+ status.SetError("must be called with at least two arguments.");
+ return false;
+ }
+
+ static cmSubcommandTable const subcommand{
+ { "LENGTH"_s, HandleLengthCommand },
+ { "GET"_s, HandleGetCommand },
+ { "APPEND"_s, HandleAppendCommand },
+ { "PREPEND"_s, HandlePrependCommand },
+ { "POP_BACK"_s, HandlePopBackCommand },
+ { "POP_FRONT"_s, HandlePopFrontCommand },
+ { "FIND"_s, HandleFindCommand },
+ { "INSERT"_s, HandleInsertCommand },
+ { "JOIN"_s, HandleJoinCommand },
+ { "REMOVE_AT"_s, HandleRemoveAtCommand },
+ { "REMOVE_ITEM"_s, HandleRemoveItemCommand },
+ { "REMOVE_DUPLICATES"_s, HandleRemoveDuplicatesCommand },
+ { "TRANSFORM"_s, HandleTransformCommand },
+ { "SORT"_s, HandleSortCommand },
+ { "SUBLIST"_s, HandleSublistCommand },
+ { "REVERSE"_s, HandleReverseCommand },
+ { "FILTER"_s, HandleFilterCommand },
+ };
+
+ return subcommand(args[0], args, status);
}
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 7ef475a..ff3ecd9 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -483,8 +483,7 @@ std::vector<BT<std::string>> ExpandListWithBacktrace(
std::string const& list, cmListFileBacktrace const& bt)
{
std::vector<BT<std::string>> result;
- std::vector<std::string> tmp;
- cmExpandList(list, tmp);
+ std::vector<std::string> tmp = cmExpandedList(list);
result.reserve(tmp.size());
for (std::string& i : tmp) {
result.emplace_back(std::move(i), bt);
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 180e65b..f650eb1 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -14,14 +14,14 @@
#include "cmCPluginAPI.cxx"
#include "cmCPluginAPI.h"
+#include "cmCommand.h"
#include "cmDynamicLoader.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
@@ -175,8 +175,8 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
} // namespace
// cmLoadCommandCommand
-bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmLoadCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
return true;
@@ -185,13 +185,13 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
// Construct a variable to report what file was loaded, if any.
// Start by removing the definition in case of failure.
std::string reportVar = cmStrCat("CMAKE_LOADED_COMMAND_", args[0]);
- this->Makefile->RemoveDefinition(reportVar);
+ status.GetMakefile().RemoveDefinition(reportVar);
// the file must exist
std::string moduleName = cmStrCat(
- this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX"), "cm",
- args[0],
- this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX"));
+ status.GetMakefile().GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX"),
+ "cm", args[0],
+ status.GetMakefile().GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX"));
// search for the file
std::vector<std::string> path;
@@ -209,7 +209,7 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
if (fullPath.empty()) {
std::ostringstream e;
e << "Attempt to load command failed from file \"" << moduleName << "\"";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -224,12 +224,12 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
err += " Additional error info is:\n";
err += error;
}
- this->SetError(err);
+ status.SetError(err);
return false;
}
// Report what file was loaded for this command.
- this->Makefile->AddDefinition(reportVar, fullPath);
+ status.GetMakefile().AddDefinition(reportVar, fullPath);
// find the init function
std::string initFuncName = args[0] + "Init";
@@ -243,12 +243,12 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
// if the symbol is found call it to set the name on the
// function blocker
if (initFunction) {
- this->Makefile->GetState()->AddScriptedCommand(
+ status.GetMakefile().GetState()->AddScriptedCommand(
args[0],
cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
return true;
}
- this->SetError("Attempt to load command failed. "
- "No init function found.");
+ status.SetError("Attempt to load command failed. "
+ "No init function found.");
return false;
}
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index d81cefb..f5fd754 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmLoadCommandCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmLoadCommandCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmLoadCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 1827a42..7177694 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
+#include "cmSourceFileLocationKind.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
@@ -37,6 +38,7 @@
#include <algorithm>
#include <assert.h>
+#include <functional>
#include <initializer_list>
#include <iterator>
#include <memory>
@@ -311,8 +313,7 @@ void cmLocalGenerator::GenerateTestFiles()
const char* testIncludeFiles =
this->Makefile->GetProperty("TEST_INCLUDE_FILES");
if (testIncludeFiles) {
- std::vector<std::string> includesList;
- cmExpandList(testIncludeFiles, includesList);
+ std::vector<std::string> includesList = cmExpandedList(testIncludeFiles);
for (std::string const& i : includesList) {
fout << "include(\"" << i << "\")" << std::endl;
}
@@ -902,8 +903,7 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags,
ge.Parse(jmcExprGen);
std::string isJMCEnabled = cge->Evaluate(this, config);
if (cmIsOn(isJMCEnabled)) {
- std::vector<std::string> optVec;
- cmExpandList(jmc, optVec);
+ std::vector<std::string> optVec = cmExpandedList(jmc);
this->AppendCompileOptions(flags, optVec);
}
}
@@ -1566,6 +1566,17 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
config);
+ if (lang == "Swift") {
+ if (const char* v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
+ if (cmSystemTools::VersionCompare(
+ cmSystemTools::OP_GREATER_EQUAL,
+ this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"),
+ "4.2")) {
+ this->AppendFlags(flags, "-swift-version " + std::string(v));
+ }
+ }
+ }
+
// Add MSVC runtime library flags. This is activated by the presence
// of a default selection whether or not it is overridden by a property.
const char* msvcRuntimeLibraryDefault =
@@ -1769,8 +1780,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
"CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION";
if (const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag)) {
- std::vector<std::string> optVec;
- cmExpandList(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -1798,8 +1808,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
"does not know the compile flags to use to enable it.";
this->IssueMessage(MessageType::FATAL_ERROR, e.str());
} else {
- std::vector<std::string> optVec;
- cmExpandList(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -1859,8 +1868,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
std::string const& opt =
target->Target->GetMakefile()->GetRequiredDefinition(option_flag);
- std::vector<std::string> optVec;
- cmExpandList(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -1876,8 +1884,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
if (const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag)) {
- std::vector<std::string> optVec;
- cmExpandList(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -2072,8 +2079,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC"));
}
if (!picFlags.empty()) {
- std::vector<std::string> options;
- cmExpandList(picFlags, options);
+ std::vector<std::string> options = cmExpandedList(picFlags);
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -2120,6 +2126,82 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags,
this->AppendFlags(flags, this->EscapeForShell(rawFlag));
}
+void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target,
+ const std::string& config)
+{
+ const std::string lang = target->GetLinkerLanguage(config);
+ const std::string buildType = cmSystemTools::UpperCase(config);
+ const std::string pchSource = target->GetPchSource(config, lang);
+ const std::string pchHeader = target->GetPchHeader(config, lang);
+
+ if (pchSource.empty() || pchHeader.empty()) {
+ return;
+ }
+
+ const std::string createOptVar =
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_CREATE_PCH");
+ std::string createOptionList =
+ this->Makefile->GetSafeDefinition(createOptVar);
+
+ const std::string useOptVar =
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_USE_PCH");
+ std::string useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
+
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+
+ if (createOptionList.empty() || useOptionList.empty() ||
+ pchExtension.empty()) {
+ return;
+ }
+
+ auto pch_sf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
+ std::string pchFile = pchHeader;
+
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ // Exclude the pch files from linking
+ if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ cmSystemTools::ReplaceString(pchFile, (lang == "C" ? ".h" : ".hxx"),
+ pchExtension);
+ pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+ } else {
+ pchFile += pchExtension;
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ }
+
+ target->AddSource(pchSource, true);
+
+ for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) {
+ cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader);
+ cmSystemTools::ReplaceString(str, "<PCH_FILE>", pchFile);
+ }
+ }
+
+ pch_sf->SetProperty("COMPILE_OPTIONS", createOptionList.c_str());
+
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, buildType);
+ for (cmSourceFile* sf : sources) {
+ if (pch_sf == sf || sf->GetLanguage() != lang) {
+ continue;
+ }
+
+ if (sf->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ sf->SetProperty("COMPILE_DEFINITIONS",
+ "CMAKE_SKIP_PRECOMPILE_HEADERS");
+ }
+ continue;
+ }
+
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ sf->SetProperty("OBJECT_DEPENDS", pchFile.c_str());
+ sf->SetProperty("COMPILE_OPTIONS", useOptionList.c_str());
+ }
+ }
+}
+
void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& config,
@@ -2144,8 +2226,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
return;
}
- std::vector<std::string> flagsList;
- cmExpandList(rawFlagsList, flagsList);
+ std::vector<std::string> flagsList = cmExpandedList(rawFlagsList);
for (std::string const& o : flagsList) {
this->AppendFlagEscape(flags, o);
}
@@ -2180,8 +2261,7 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
return;
}
- std::vector<std::string> flagsList;
- cmExpandList(pieFlags, flagsList);
+ std::vector<std::string> flagsList = cmExpandedList(pieFlags);
for (const auto& flag : flagsList) {
this->AppendFlagEscape(flags, flag);
}
@@ -2197,8 +2277,7 @@ void cmLocalGenerator::AppendCompileOptions(std::string& options,
}
// Expand the list of options.
- std::vector<std::string> options_vec;
- cmExpandList(options_list, options_vec);
+ std::vector<std::string> options_vec = cmExpandedList(options_list);
this->AppendCompileOptions(options, options_vec, regex);
}
@@ -2232,8 +2311,7 @@ void cmLocalGenerator::AppendIncludeDirectories(
}
// Expand the list of includes.
- std::vector<std::string> includes_vec;
- cmExpandList(includes_list, includes_vec);
+ std::vector<std::string> includes_vec = cmExpandedList(includes_list);
this->AppendIncludeDirectories(includes, includes_vec, sourceFile);
}
@@ -2360,8 +2438,7 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags,
const char* optionList = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature));
if (optionList != nullptr) {
- std::vector<std::string> options;
- cmExpandList(optionList, options);
+ std::vector<std::string> options = cmExpandedList(optionList);
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -2717,6 +2794,11 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
}
}
+ const char* pchExtension = source.GetProperty("PCH_EXTENSION");
+ if (pchExtension) {
+ customOutputExtension = pchExtension;
+ }
+
// Remove the source extension if it is to be replaced.
if (replaceExt || customOutputExtension) {
keptSourceExtension = false;
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 455e491..f63fe0f 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -124,6 +124,8 @@ public:
virtual void AppendFlags(std::string& flags, const char* newFlags) const;
virtual void AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const;
+ void AddPchDependencies(cmGeneratorTarget* target,
+ const std::string& config);
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 1be219c..e28b876 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -221,8 +221,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
- std::vector<std::string> pools;
- cmExpandList(jobpools, pools);
+ std::vector<std::string> pools = cmExpandedList(jobpools);
for (std::string const& pool : pools) {
const std::string::size_type eq = pool.find('=');
unsigned int jobs;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c301b1a..106e506 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1455,8 +1455,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
this->WriteDisclaimer(internalRuleFileStream);
// for each language we need to scan, scan it
- std::vector<std::string> langs;
- cmExpandList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"), langs);
+ std::vector<std::string> langs =
+ cmExpandedList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"));
for (std::string const& lang : langs) {
// construct the checker
// Create the scanner for this language
@@ -1500,8 +1500,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
}
// Convert the string to a list and preserve empty entries.
- std::vector<std::string> pairs;
- cmExpandList(pairs_string, pairs, true);
+ std::vector<std::string> pairs = cmExpandedList(pairs_string, true);
for (std::vector<std::string>::const_iterator i = pairs.begin();
i != pairs.end() && (i + 1) != pairs.end();) {
const std::string& depender = *i++;
@@ -1727,8 +1726,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
if (!infoDef) {
return;
}
- std::vector<std::string> files;
- cmExpandList(infoDef, files);
+ std::vector<std::string> files = cmExpandedList(infoDef);
// Each depend information file corresponds to a target. Clear the
// dependencies for that target.
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index bbee705..795cee4 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1320,6 +1320,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
const std::string& libName,
cmGeneratorTarget* target)
{
+ this->AddPchDependencies(target, "");
+
std::vector<std::string> configs;
this->Makefile->GetConfigurations(configs);
@@ -1492,8 +1494,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// Check for extra object-file dependencies.
if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depends;
- cmExpandList(deps, depends);
+ std::vector<std::string> depends = cmExpandedList(deps);
const char* sep = "";
for (std::vector<std::string>::iterator j = depends.begin();
j != depends.end(); ++j) {
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 92ea9aa..201cc13 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMacroCommand.h"
-#include <sstream>
#include <stdio.h>
#include <utility>
@@ -64,9 +63,7 @@ bool cmMacroHelperCommand::operator()(
this->Policies);
// set the value of argc
- std::ostringstream argcDefStream;
- argcDefStream << expandedArgs.size();
- std::string argcDef = argcDefStream.str();
+ std::string argcDef = std::to_string(expandedArgs.size());
std::vector<std::string>::const_iterator eit =
expandedArgs.begin() + (this->Args.size() - 1);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 78351c1..f101cdc 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1352,8 +1352,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
if (remove) {
if (const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
- std::vector<std::string> defs;
- cmExpandList(cdefs, defs);
+ std::vector<std::string> defs = cmExpandedList(cdefs);
// Recompose the list without the definition.
std::vector<std::string>::const_iterator defEnd =
@@ -1953,8 +1952,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
}
if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs;
- cmExpandList(linkLibsProp, linkLibs);
+ std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
for (std::vector<std::string>::iterator j = linkLibs.begin();
j != linkLibs.end(); ++j) {
@@ -2281,8 +2279,7 @@ void cmMakefile::ExpandVariablesCMP0019()
}
if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs;
- cmExpandList(linkLibsProp, linkLibs);
+ std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
for (std::vector<std::string>::iterator l = linkLibs.begin();
l != linkLibs.end(); ++l) {
@@ -2813,9 +2810,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
switch (var.domain) {
case NORMAL:
if (filename && lookup == lineVar) {
- std::ostringstream ostr;
- ostr << line;
- varresult = ostr.str();
+ varresult = std::to_string(line);
} else {
value = this->GetDefinition(lookup);
}
@@ -3200,8 +3195,7 @@ bool cmMakefile::ExpandArguments(
if (i.Delim == cmListFileArgument::Quoted) {
outArgs.emplace_back(value, true);
} else {
- std::vector<std::string> stringArgs;
- cmExpandList(value, stringArgs);
+ std::vector<std::string> stringArgs = cmExpandedList(value);
for (std::string const& stringArg : stringArgs) {
outArgs.emplace_back(stringArg, false);
}
@@ -3248,9 +3242,7 @@ void cmMakefile::SetScriptModeFile(std::string const& scriptfile)
void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
{
- std::ostringstream strStream;
- strStream << args.size();
- this->AddDefinition("CMAKE_ARGC", strStream.str());
+ this->AddDefinition("CMAKE_ARGC", std::to_string(args.size()));
// this->MarkVariableAsUsed("CMAKE_ARGC");
for (unsigned int t = 0; t < args.size(); ++t) {
@@ -3558,8 +3550,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
// Always search in CMAKE_MODULE_PATH:
const char* cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH");
if (cmakeModulePath) {
- std::vector<std::string> modulePath;
- cmExpandList(cmakeModulePath, modulePath);
+ std::vector<std::string> modulePath = cmExpandedList(cmakeModulePath);
// Look through the possible module directories.
for (std::string itempl : modulePath) {
@@ -4374,8 +4365,7 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
return false;
}
- std::vector<std::string> availableFeatures;
- cmExpandList(features, availableFeatures);
+ std::vector<std::string> availableFeatures = cmExpandedList(features);
if (!cmContains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
@@ -4498,10 +4488,10 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
const char* defaultCStandard =
this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
if (!defaultCStandard) {
- std::ostringstream e;
- e << "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
- "not fully configured for this compiler.";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ this->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler.");
// Return true so the caller does not try to lookup the default standard.
return true;
}
@@ -4582,10 +4572,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
const char* defaultCxxStandard =
this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
if (!defaultCxxStandard) {
- std::ostringstream e;
- e << "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
- "not fully configured for this compiler.";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ this->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler.");
// Return true so the caller does not try to lookup the default standard.
return true;
}
@@ -4643,32 +4633,27 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
{
if (const char* propCxx98 =
this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propCxx98, props);
+ std::vector<std::string> props = cmExpandedList(propCxx98);
needCxx98 = cmContains(props, feature);
}
if (const char* propCxx11 =
this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propCxx11, props);
+ std::vector<std::string> props = cmExpandedList(propCxx11);
needCxx11 = cmContains(props, feature);
}
if (const char* propCxx14 =
this->GetDefinition("CMAKE_CXX14_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propCxx14, props);
+ std::vector<std::string> props = cmExpandedList(propCxx14);
needCxx14 = cmContains(props, feature);
}
if (const char* propCxx17 =
this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propCxx17, props);
+ std::vector<std::string> props = cmExpandedList(propCxx17);
needCxx17 = cmContains(props, feature);
}
if (const char* propCxx20 =
this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propCxx20, props);
+ std::vector<std::string> props = cmExpandedList(propCxx20);
needCxx20 = cmContains(props, feature);
}
}
@@ -4767,20 +4752,17 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature,
{
if (const char* propC90 =
this->GetDefinition("CMAKE_C90_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propC90, props);
+ std::vector<std::string> props = cmExpandedList(propC90);
needC90 = cmContains(props, feature);
}
if (const char* propC99 =
this->GetDefinition("CMAKE_C99_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propC99, props);
+ std::vector<std::string> props = cmExpandedList(propC99);
needC99 = cmContains(props, feature);
}
if (const char* propC11 =
this->GetDefinition("CMAKE_C11_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmExpandList(propC11, props);
+ std::vector<std::string> props = cmExpandedList(propC11);
needC11 = cmContains(props, feature);
}
}
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 7bc05b1..bebd5c4 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -40,6 +40,8 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
this->OSXBundleGenerator =
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+
+ this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
}
cmMakefileExecutableTargetGenerator::~cmMakefileExecutableTargetGenerator() =
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 252279f..4244402 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -42,6 +42,8 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
this->OSXBundleGenerator =
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+
+ this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
}
cmMakefileLibraryTargetGenerator::~cmMakefileLibraryTargetGenerator() =
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 5477e48..90d8ea9 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -130,10 +130,10 @@ void cmMakefileTargetGenerator::CreateRuleFile()
this->BuildFileStream =
new cmGeneratedFileStream(this->BuildFileNameFull, false,
this->GlobalGenerator->GetMakefileEncoding());
- this->BuildFileStream->SetCopyIfDifferent(true);
if (!this->BuildFileStream) {
return;
}
+ this->BuildFileStream->SetCopyIfDifferent(true);
this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream);
if (this->GlobalGenerator->AllowDeleteOnError()) {
std::vector<std::string> no_depends;
@@ -239,10 +239,15 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->GeneratorTarget->GetExtraSources(extraSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
extraSources, this->MacOSXContentGenerator);
+ const char* pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
this->GeneratorTarget->GetExternalObjects(externalObjects, config);
for (cmSourceFile const* sf : externalObjects) {
- this->ExternalObjects.push_back(sf->GetFullPath());
+ auto const& objectFileName = sf->GetFullPath();
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ this->ExternalObjects.push_back(objectFileName);
+ }
}
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources, config);
@@ -299,10 +304,10 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->FlagFileStream =
new cmGeneratedFileStream(this->FlagFileNameFull, false,
this->GlobalGenerator->GetMakefileEncoding());
- this->FlagFileStream->SetCopyIfDifferent(true);
if (!this->FlagFileStream) {
return;
}
+ this->FlagFileStream->SetCopyIfDifferent(true);
this->LocalGenerator->WriteDisclaimer(*this->FlagFileStream);
// Include the flags for the target.
@@ -767,8 +772,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCommands.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args;
- cmExpandList(compilerLauncher, args, true);
+ std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -840,8 +844,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
cmStrCat("CMAKE_", lang, "_CREATE_PREPROCESSED_SOURCE");
if (const char* preprocessRule =
this->Makefile->GetDefinition(preprocessRuleVar)) {
- std::vector<std::string> preprocessCommands;
- cmExpandList(preprocessRule, preprocessCommands);
+ std::vector<std::string> preprocessCommands =
+ cmExpandedList(preprocessRule);
std::string shellObjI = this->LocalGenerator->ConvertToOutputFormat(
objI, cmOutputConverter::SHELL);
@@ -885,8 +889,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
cmStrCat("CMAKE_", lang, "_CREATE_ASSEMBLY_SOURCE");
if (const char* assemblyRule =
this->Makefile->GetDefinition(assemblyRuleVar)) {
- std::vector<std::string> assemblyCommands;
- cmExpandList(assemblyRule, assemblyCommands);
+ std::vector<std::string> assemblyCommands =
+ cmExpandedList(assemblyRule);
std::string shellObjS = this->LocalGenerator->ConvertToOutputFormat(
objS, cmOutputConverter::SHELL);
@@ -1013,10 +1017,10 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
this->InfoFileNameFull =
this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
this->InfoFileStream = new cmGeneratedFileStream(this->InfoFileNameFull);
- this->InfoFileStream->SetCopyIfDifferent(true);
- if (!*this->InfoFileStream) {
+ if (!this->InfoFileStream) {
return;
}
+ this->InfoFileStream->SetCopyIfDifferent(true);
this->LocalGenerator->WriteDependLanguageInfo(*this->InfoFileStream,
this->GeneratorTarget);
@@ -1239,7 +1243,14 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
if (!lineContinue) {
lineContinue = "\\";
}
+
+ const char* pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
+
for (std::string const& obj : this->Objects) {
+ if (cmSystemTools::StringEndsWith(obj, pchExtension)) {
+ continue;
+ }
*this->BuildFileStream << " " << lineContinue << "\n";
*this->BuildFileStream
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
@@ -1332,10 +1343,16 @@ private:
void cmMakefileTargetGenerator::WriteObjectsStrings(
std::vector<std::string>& objStrings, std::string::size_type limit)
{
+ const char* pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
+
cmMakefileTargetGeneratorObjectStrings helper(
objStrings, this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit);
for (std::string const& obj : this->Objects) {
+ if (cmSystemTools::StringEndsWith(obj, pchExtension)) {
+ continue;
+ }
helper.Feed(obj);
}
for (std::string const& obj : this->ExternalObjects) {
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 8ed6be5..556191f 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -25,6 +25,8 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
this->OSXBundleGenerator =
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+
+ this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
}
cmMakefileUtilityTargetGenerator::~cmMakefileUtilityTargetGenerator() =
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 3f33312..39b40b8 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -70,8 +70,8 @@ bool cmMessageCommand(std::vector<std::string> const& args,
fatal = true;
type = MessageType::DEPRECATION_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if ((!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") ||
- status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED"))) {
+ } else if (!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") ||
+ status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED")) {
type = MessageType::DEPRECATION_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 2841245..0e3aa3a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -59,6 +59,8 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
this->OSXBundleGenerator =
cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+
+ GetLocalGenerator()->AddPchDependencies(target, this->GetConfigName());
}
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
@@ -87,6 +89,7 @@ void cmNinjaNormalTargetGenerator::Generate()
this->WriteLinkStatement();
}
+ // Find ADDITIONAL_CLEAN_FILES
this->AdditionalCleanFiles();
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 7b91bd4..29e8b74 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -725,8 +725,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCmds.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args;
- cmExpandList(compilerLauncher, args, true);
+ std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -791,10 +790,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
extraSources, this->MacOSXContentGenerator.get());
}
{
+ const char* pchExtension =
+ GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+
std::vector<cmSourceFile const*> externalObjects;
this->GeneratorTarget->GetExternalObjects(externalObjects, config);
for (cmSourceFile const* sf : externalObjects) {
- this->Objects.push_back(this->GetSourceFilePath(sf));
+ const auto objectFileName = this->GetSourceFilePath(sf);
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ this->Objects.push_back(objectFileName);
+ }
}
}
@@ -956,8 +961,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
objBuild.Outputs.push_back(objectFileName);
- // Add this object to the list of object files.
- this->Objects.push_back(objectFileName);
+ const char* pchExtension =
+ this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ // Add this object to the list of object files.
+ this->Objects.push_back(objectFileName);
+ }
objBuild.ExplicitDeps.push_back(sourceFileName);
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 83a9beb..eea4c93 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -136,6 +136,9 @@ void cmNinjaUtilityTargetGenerator::Generate()
gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
}
+ // Find ADDITIONAL_CLEAN_FILES
+ this->AdditionalCleanFiles();
+
// Add an alias for the logical target name regardless of what directory
// contains it. Skip this for GLOBAL_TARGET because they are meant to
// be per-directory and have one at the top-level anyway.
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index 38e86e3..3d8ebc3 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -5,9 +5,12 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include <map>
+#include <set>
+#include <stdio.h>
#include <utility>
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
@@ -15,8 +18,7 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
+namespace {
/** \class cmDependInformation
* \brief Store dependency information for a single source file.
*
@@ -122,8 +124,7 @@ public:
std::string incDirs = cmGeneratorExpression::Preprocess(
incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- std::vector<std::string> includes;
- cmExpandList(incDirs, includes);
+ std::vector<std::string> includes = cmExpandedList(incDirs);
for (std::string& path : includes) {
this->Makefile->ExpandVariablesInString(path);
@@ -453,43 +454,47 @@ protected:
DirectoryToFileToPathMapType DirectoryToFileToPathMap;
};
+void ListDependencies(cmDependInformation const* info, FILE* fout,
+ std::set<cmDependInformation const*>* visited);
+}
+
// cmOutputRequiredFilesCommand
-bool cmOutputRequiredFilesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// store the arg for final pass
- this->File = args[0];
- this->OutputFile = args[1];
+ const std::string& file = args[0];
+ const std::string& outputFile = args[1];
// compute the list of files
cmLBDepend md;
- md.SetMakefile(this->Makefile);
- md.AddSearchPath(this->Makefile->GetCurrentSourceDirectory());
+ md.SetMakefile(&status.GetMakefile());
+ md.AddSearchPath(status.GetMakefile().GetCurrentSourceDirectory());
// find the depends for a file
- const cmDependInformation* info = md.FindDependencies(this->File.c_str());
+ const cmDependInformation* info = md.FindDependencies(file.c_str());
if (info) {
// write them out
- FILE* fout = cmsys::SystemTools::Fopen(this->OutputFile, "w");
+ FILE* fout = cmsys::SystemTools::Fopen(outputFile, "w");
if (!fout) {
- this->SetError(cmStrCat("Can not open output file: ", this->OutputFile));
+ status.SetError(cmStrCat("Can not open output file: ", outputFile));
return false;
}
std::set<cmDependInformation const*> visited;
- this->ListDependencies(info, fout, &visited);
+ ListDependencies(info, fout, &visited);
fclose(fout);
}
return true;
}
-void cmOutputRequiredFilesCommand::ListDependencies(
- cmDependInformation const* info, FILE* fout,
- std::set<cmDependInformation const*>* visited)
+namespace {
+void ListDependencies(cmDependInformation const* info, FILE* fout,
+ std::set<cmDependInformation const*>* visited)
{
// add info to the visited set
visited->insert(info);
@@ -504,7 +509,8 @@ void cmOutputRequiredFilesCommand::ListDependencies(
fprintf(fout, "%s\n", d->FullPath.c_str());
}
}
- this->ListDependencies(d, fout, visited);
+ ListDependencies(d, fout, visited);
}
}
}
+}
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index faffabd..4c11894 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -5,34 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <set>
-#include <stdio.h>
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
-class cmDependInformation;
class cmExecutionStatus;
-class cmOutputRequiredFilesCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmOutputRequiredFilesCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- void ListDependencies(cmDependInformation const* info, FILE* fout,
- std::set<cmDependInformation const*>* visited);
-
-private:
- std::string File;
- std::string OutputFile;
-};
+bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 2ca3c57..aad9f74 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -159,8 +159,7 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args,
};
// the second argument is a (cmake) list of options without argument
- std::vector<std::string> list;
- cmExpandList(*argIter++, list);
+ std::vector<std::string> list = cmExpandedList(*argIter++);
parser.Bind(list, options, duplicateKey);
// the third argument is a (cmake) list of single argument options
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 9d29e5c..d890f8e 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -12,6 +12,7 @@
#include <algorithm>
#include <array>
+#include <initializer_list>
#include <sstream>
#include <utility>
@@ -21,7 +22,7 @@
/// @arg valueOpts list of options that accept a value
void MergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
- std::vector<std::string> const& valueOpts, bool isQt5)
+ std::initializer_list<cm::string_view> valueOpts, bool isQt5)
{
typedef std::vector<std::string>::iterator Iter;
typedef std::vector<std::string>::const_iterator CIter;
@@ -75,102 +76,74 @@ void MergeOptions(std::vector<std::string>& baseOpts,
unsigned int const cmQtAutoGen::ParallelMax = 64;
std::string const cmQtAutoGen::ListSep = "<<<S>>>";
-std::string const& cmQtAutoGen::GeneratorName(GenT genType)
+cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
{
- static const std::string AutoGen("AutoGen");
- static const std::string AutoMoc("AutoMoc");
- static const std::string AutoUic("AutoUic");
- static const std::string AutoRcc("AutoRcc");
-
switch (genType) {
case GenT::GEN:
- return AutoGen;
+ return "AutoGen";
case GenT::MOC:
- return AutoMoc;
+ return "AutoMoc";
case GenT::UIC:
- return AutoUic;
+ return "AutoUic";
case GenT::RCC:
- return AutoRcc;
+ return "AutoRcc";
}
- return AutoGen;
+ return "AutoGen";
}
-std::string const& cmQtAutoGen::GeneratorNameUpper(GenT genType)
+cm::string_view cmQtAutoGen::GeneratorNameUpper(GenT genType)
{
- static const std::string AUTOGEN("AUTOGEN");
- static const std::string AUTOMOC("AUTOMOC");
- static const std::string AUTOUIC("AUTOUIC");
- static const std::string AUTORCC("AUTORCC");
-
switch (genType) {
case GenT::GEN:
- return AUTOGEN;
+ return "AUTOGEN";
case GenT::MOC:
- return AUTOMOC;
+ return "AUTOMOC";
case GenT::UIC:
- return AUTOUIC;
+ return "AUTOUIC";
case GenT::RCC:
- return AUTORCC;
+ return "AUTORCC";
}
- return AUTOGEN;
+ return "AUTOGEN";
}
std::string cmQtAutoGen::Tools(bool moc, bool uic, bool rcc)
{
- std::string res;
- std::vector<std::string> lst;
+ std::array<cm::string_view, 3> lst;
+ decltype(lst)::size_type num = 0;
if (moc) {
- lst.emplace_back("AUTOMOC");
+ lst.at(num++) = "AUTOMOC";
}
if (uic) {
- lst.emplace_back("AUTOUIC");
+ lst.at(num++) = "AUTOUIC";
}
if (rcc) {
- lst.emplace_back("AUTORCC");
+ lst.at(num++) = "AUTORCC";
}
- switch (lst.size()) {
+ switch (num) {
case 1:
- res += lst.at(0);
- break;
+ return std::string(lst[0]);
case 2:
- res += lst.at(0);
- res += " and ";
- res += lst.at(1);
- break;
+ return cmStrCat(lst[0], " and ", lst[1]);
case 3:
- res += lst.at(0);
- res += ", ";
- res += lst.at(1);
- res += " and ";
- res += lst.at(2);
- break;
+ return cmStrCat(lst[0], ", ", lst[1], " and ", lst[2]);
default:
break;
}
- return res;
+ return std::string();
}
-std::string cmQtAutoGen::Quoted(std::string const& text)
+std::string cmQtAutoGen::Quoted(cm::string_view text)
{
- const std::array<std::pair<const char*, const char*>, 9> replaces = {
- { { "\\", "\\\\" },
- { "\"", "\\\"" },
- { "\a", "\\a" },
- { "\b", "\\b" },
- { "\f", "\\f" },
- { "\n", "\\n" },
- { "\r", "\\r" },
- { "\t", "\\t" },
- { "\v", "\\v" } }
- };
+ static std::initializer_list<std::pair<const char*, const char*>> const
+ replacements = { { "\\", "\\\\" }, { "\"", "\\\"" }, { "\a", "\\a" },
+ { "\b", "\\b" }, { "\f", "\\f" }, { "\n", "\\n" },
+ { "\r", "\\r" }, { "\t", "\\t" }, { "\v", "\\v" } };
- std::string res = text;
- for (auto const& pair : replaces) {
+ std::string res(text);
+ for (auto const& pair : replacements) {
cmSystemTools::ReplaceString(res, pair.first, pair.second);
}
- res = '"' + res;
- res += '"';
- return res;
+ return cmStrCat('"', res, '"');
}
std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
@@ -191,37 +164,31 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
return res;
}
-std::string cmQtAutoGen::SubDirPrefix(std::string const& filename)
+std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename)
{
- std::string::size_type slash_pos = filename.rfind('/');
- if (slash_pos == std::string::npos) {
+ auto slashPos = filename.rfind('/');
+ if (slashPos == cm::string_view::npos) {
return std::string();
}
- return filename.substr(0, slash_pos + 1);
+ return std::string(filename.substr(0, slashPos + 1));
}
-std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename,
- std::string const& suffix)
+std::string cmQtAutoGen::AppendFilenameSuffix(cm::string_view filename,
+ cm::string_view suffix)
{
- std::string res;
- auto pos = filename.rfind('.');
- if (pos != std::string::npos) {
- const auto it_dot = filename.begin() + pos;
- res.assign(filename.begin(), it_dot);
- res.append(suffix);
- res.append(it_dot, filename.end());
- } else {
- res = filename;
- res.append(suffix);
+ auto dotPos = filename.rfind('.');
+ if (dotPos == cm::string_view::npos) {
+ return cmStrCat(filename, suffix);
}
- return res;
+ return cmStrCat(filename.substr(0, dotPos), suffix,
+ filename.substr(dotPos, filename.size() - dotPos));
}
void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
bool isQt5)
{
- static std::vector<std::string> const valueOpts = {
+ static std::initializer_list<cm::string_view> const valueOpts = {
"tr", "translate", "postfix", "generator",
"include", // Since Qt 5.3
"g"
@@ -233,9 +200,9 @@ void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
bool isQt5)
{
- static std::vector<std::string> const valueOpts = { "name", "root",
- "compress",
- "threshold" };
+ static std::initializer_list<cm::string_view> const valueOpts = {
+ "name", "root", "compress", "threshold"
+ };
MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
}
@@ -349,9 +316,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
// Log command
if (verbose) {
- std::string msg =
- cmStrCat("Running command:\n", QuotedCommand(cmd), '\n');
- cmSystemTools::Stdout(msg);
+ cmSystemTools::Stdout(
+ cmStrCat("Running command:\n", QuotedCommand(cmd), '\n'));
}
result = cmSystemTools::RunSingleCommand(
@@ -362,12 +328,10 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
error =
cmStrCat("The rcc list process failed for ", Quoted(qrcFile), '\n');
if (!rccStdOut.empty()) {
- error += rccStdOut;
- error += "\n";
+ error += cmStrCat(rccStdOut, '\n');
}
if (!rccStdErr.empty()) {
- error += rccStdErr;
- error += "\n";
+ error += cmStrCat(rccStdErr, '\n');
}
return false;
}
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index 619fff1..939ceb3 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -5,6 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cm_string_view.hxx"
+
#include <memory>
#include <string>
#include <vector>
@@ -66,24 +68,24 @@ public:
public:
/// @brief Returns the generator name
- static std::string const& GeneratorName(GenT genType);
+ static cm::string_view GeneratorName(GenT genType);
/// @brief Returns the generator name in upper case
- static std::string const& GeneratorNameUpper(GenT genType);
+ static cm::string_view GeneratorNameUpper(GenT genType);
/// @brief Returns a string with the requested tool names
static std::string Tools(bool moc, bool uic, bool rcc);
/// @brief Returns the string escaped and enclosed in quotes
- static std::string Quoted(std::string const& text);
+ static std::string Quoted(cm::string_view text);
static std::string QuotedCommand(std::vector<std::string> const& command);
/// @brief Returns the parent directory of the file with a "/" suffix
- static std::string SubDirPrefix(std::string const& filename);
+ static std::string SubDirPrefix(cm::string_view filename);
/// @brief Appends the suffix to the filename before the last dot
- static std::string AppendFilenameSuffix(std::string const& filename,
- std::string const& suffix);
+ static std::string AppendFilenameSuffix(cm::string_view filename,
+ cm::string_view suffix);
/// @brief Merges newOpts into baseOpts
static void UicMergeOptions(std::vector<std::string>& baseOpts,
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 6718466..bd96c08 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -29,8 +29,8 @@
#include "cmsys/SystemInformation.hxx"
#include <algorithm>
-#include <array>
#include <deque>
+#include <initializer_list>
#include <map>
#include <set>
#include <string>
@@ -381,8 +381,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
std::string const deps =
this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
- std::vector<std::string> extraDeps;
- cmExpandList(deps, extraDeps);
+ std::vector<std::string> extraDeps = cmExpandedList(deps);
for (std::string const& depName : extraDeps) {
// Allow target and file dependencies
auto* depTarget = makefile->FindTargetToUse(depName);
@@ -397,13 +396,13 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// CMAKE_AUTOMOC_RELAXED_MODE deprecation warning
if (this->Moc.Enabled) {
- if (cmIsOn(makefile->GetDefinition("CMAKE_AUTOMOC_RELAXED_MODE"))) {
- std::string msg =
+ if (makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) {
+ makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
cmStrCat("AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is "
"deprecated an will be removed in the future. Consider "
"disabling it and converting the target ",
- this->Target->GetName(), " to regular mode.");
- makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
+ this->Target->GetName(), " to regular mode."));
}
}
}
@@ -697,7 +696,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::vector<MUFileHandle> extraHeaders;
extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2);
// Header search suffixes and extensions
- std::array<std::string, 2> const suffixes{ { "", "_p" } };
+ static std::initializer_list<cm::string_view> const suffixes{ "", "_p" };
auto const& exts = cm->GetHeaderExtensions();
// Scan through sources
for (auto const& pair : this->AutogenTarget.Sources) {
@@ -709,7 +708,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath),
cmSystemTools::GetFilenameWithoutLastExtension(srcPath));
for (auto const& suffix : suffixes) {
- std::string const suffixedPath = basePath + suffix;
+ std::string const suffixedPath = cmStrCat(basePath, suffix);
for (auto const& ext : exts) {
std::string fullPath = cmStrCat(suffixedPath, '.', ext);
@@ -796,8 +795,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS);
if (!uicOpts.empty()) {
this->Uic.FileFiles.push_back(std::move(realPath));
- std::vector<std::string> optsVec;
- cmExpandList(uicOpts, optsVec);
+ std::vector<std::string> optsVec = cmExpandedList(uicOpts);
this->Uic.FileOptions.push_back(std::move(optsVec));
}
} else {
@@ -816,33 +814,31 @@ bool cmQtAutoGenInitializer::InitScanFiles()
this->AutogenTarget.DependFiles.insert(muf->RealPath);
}
} else if (this->CMP0071Warn) {
- std::string msg =
- cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n');
- std::string property;
+ cm::string_view property;
if (this->Moc.Enabled && this->Uic.Enabled) {
- property = kw.SKIP_AUTOGEN;
+ property = "SKIP_AUTOGEN";
} else if (this->Moc.Enabled) {
- property = kw.SKIP_AUTOMOC;
+ property = "SKIP_AUTOMOC";
} else if (this->Uic.Enabled) {
- property = kw.SKIP_AUTOUIC;
+ property = "SKIP_AUTOUIC";
}
- msg += "For compatibility, CMake is excluding the GENERATED source "
- "file(s):\n";
+ std::string files;
for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
- msg += " ";
- msg += Quoted(muf->RealPath);
- msg += '\n';
+ files += cmStrCat(" ", Quoted(muf->RealPath), '\n');
}
- msg += "from processing by ";
- msg += cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false);
- msg += ". If any of the files should be processed, set CMP0071 to NEW. "
- "If any of the files should not be processed, "
- "explicitly exclude them by setting the source file property ";
- msg += property;
- msg += ":\n set_property(SOURCE file.h PROPERTY ";
- msg += property;
- msg += " ON)\n";
- makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
+ makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n',
+ "For compatibility, CMake is excluding the GENERATED source "
+ "file(s):\n",
+ files, "from processing by ",
+ cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false),
+ ". If any of the files should be processed, set CMP0071 to NEW. "
+ "If any of the files should not be processed, "
+ "explicitly exclude them by setting the source file property ",
+ property, ":\n set_property(SOURCE file.h PROPERTY ", property,
+ " ON)\n"));
}
}
@@ -850,9 +846,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!this->Rcc.Qrcs.empty()) {
const bool modernQt = (this->QtVersion.Major >= 5);
// Target rcc options
- std::vector<std::string> optionsTarget;
- cmExpandList(this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS),
- optionsTarget);
+ std::vector<std::string> optionsTarget =
+ cmExpandedList(this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS));
// Check if file name is unique
for (Qrc& qrc : this->Rcc.Qrcs) {
@@ -870,20 +865,16 @@ bool cmQtAutoGenInitializer::InitScanFiles()
for (Qrc& qrc : this->Rcc.Qrcs) {
qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile);
// RCC output file name
- qrc.RccFile = cmStrCat(this->Dir.Build + "/", qrc.PathChecksum,
- "/qrc_", qrc.QrcName, ".cpp");
+ qrc.RccFile = cmStrCat(this->Dir.Build, '/', qrc.PathChecksum, "/qrc_",
+ qrc.QrcName, ".cpp");
{
- std::string base = cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName);
- if (!qrc.Unique) {
- base += qrc.PathChecksum;
- }
-
+ cm::string_view const baseSuffix =
+ qrc.Unique ? cm::string_view() : cm::string_view(qrc.PathChecksum);
+ std::string const base =
+ cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName, baseSuffix);
qrc.LockFile = cmStrCat(base, ".lock");
-
qrc.InfoFile = cmStrCat(base, "Info.cmake");
-
qrc.SettingsFile = cmStrCat(base, "Settings.txt");
-
if (this->MultiConfig) {
for (std::string const& cfg : this->ConfigsList) {
qrc.ConfigSettingsFile[cfg] =
@@ -903,7 +894,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Replace '-' with '_'. The former is not valid for symbol names.
std::replace(name.begin(), name.end(), '-', '_');
if (!qrc.Unique) {
- name += cmStrCat("_", qrc.PathChecksum);
+ name += cmStrCat('_', qrc.PathChecksum);
}
std::vector<std::string> nameOpts;
nameOpts.emplace_back("-name");
@@ -1134,8 +1125,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
{
ccName = cmStrCat(this->Target->GetName(), "_arcc_", qrc.QrcName);
if (!qrc.Unique) {
- ccName += "_";
- ccName += qrc.PathChecksum;
+ ccName += cmStrCat('_', qrc.PathChecksum);
}
cmTarget* autoRccTarget = makefile->AddUtilityCommand(
@@ -1277,7 +1267,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
if (muf->MocIt || muf->UicIt) {
headers.emplace_back(muf->RealPath);
headersFlags.emplace_back(
- cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u"));
+ cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
}
}
}
@@ -1286,19 +1276,17 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
cmFilePathChecksum const fpathCheckSum(makefile);
std::unordered_set<std::string> emitted;
for (std::string const& hdr : headers) {
- std::string basePath =
+ std::string const basePath =
cmStrCat(fpathCheckSum.getPart(hdr), "/moc_",
cmSystemTools::GetFilenameWithoutLastExtension(hdr));
- for (int ii = 1; ii != 1024; ++ii) {
- std::string path = basePath;
- if (ii > 1) {
- path += cmStrCat("_", ii);
- }
- path += ".cpp";
+ std::string suffix;
+ for (int ii = 0; ii != 1024; ++ii) {
+ std::string path = cmStrCat(basePath, suffix, ".cpp");
if (emitted.emplace(path).second) {
headersBuildPaths.emplace_back(std::move(path));
break;
}
+ suffix = cmStrCat('_', ii + 1);
}
}
}
@@ -1332,7 +1320,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
if (muf->MocIt || muf->UicIt) {
sources.emplace_back(muf->RealPath);
sourcesFlags.emplace_back(
- cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u"));
+ cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
}
}
}
@@ -1457,7 +1445,7 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
}
bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
- std::string const& genNameUpper)
+ cm::string_view genNameUpper)
{
cmMakefile* makefile = this->Target->Target->GetMakefile();
cmSourceGroup* sourceGroup = nullptr;
@@ -1467,13 +1455,14 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
std::string groupName;
{
// Prefer generator specific source group name
- std::array<std::string, 2> props{ { genNameUpper + "_SOURCE_GROUP",
- "AUTOGEN_SOURCE_GROUP" } };
- for (std::string& prop : props) {
+ std::initializer_list<std::string> const props{
+ cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP"
+ };
+ for (std::string const& prop : props) {
const char* propName = makefile->GetState()->GetGlobalProperty(prop);
if ((propName != nullptr) && (*propName != '\0')) {
groupName = propName;
- property = std::move(prop);
+ property = prop;
break;
}
}
@@ -1515,11 +1504,16 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
cmGeneratorTarget const* target)
{
// Qt version variable prefixes
- static std::array<std::string, 3> const prefixes{ { "Qt6Core", "Qt5Core",
- "QT" } };
+ static std::initializer_list<
+ std::pair<cm::string_view, cm::string_view>> const keys{
+ { "Qt6Core_VERSION_MAJOR", "Qt6Core_VERSION_MINOR" },
+ { "Qt5Core_VERSION_MAJOR", "Qt5Core_VERSION_MINOR" },
+ { "QT_VERSION_MAJOR", "QT_VERSION_MINOR" },
+ };
std::vector<cmQtAutoGen::IntegerVersion> result;
- result.reserve(prefixes.size() * 2);
+ result.reserve(keys.size() * 2);
+
// Adds a version to the result (nullptr safe)
auto addVersion = [&result](const char* major, const char* minor) {
cmQtAutoGen::IntegerVersion ver(CharPtrToUInt(major),
@@ -1528,18 +1522,19 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
result.emplace_back(ver);
}
};
+
cmMakefile* makefile = target->Target->GetMakefile();
// Read versions from variables
- for (const std::string& prefix : prefixes) {
- addVersion(makefile->GetDefinition(prefix + "_VERSION_MAJOR"),
- makefile->GetDefinition(prefix + "_VERSION_MINOR"));
+ for (auto const& keyPair : keys) {
+ addVersion(makefile->GetDefinition(std::string(keyPair.first)),
+ makefile->GetDefinition(std::string(keyPair.second)));
}
// Read versions from directory properties
- for (const std::string& prefix : prefixes) {
- addVersion(makefile->GetProperty(prefix + "_VERSION_MAJOR"),
- makefile->GetProperty(prefix + "_VERSION_MINOR"));
+ for (auto const& keyPair : keys) {
+ addVersion(makefile->GetProperty(std::string(keyPair.first)),
+ makefile->GetProperty(std::string(keyPair.second)));
}
return result;
@@ -1583,7 +1578,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Custom executable
{
- std::string const prop = genVars.GenNameUpper + "_EXECUTABLE";
+ std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
std::string const val = this->Target->Target->GetSafeProperty(prop);
if (!val.empty()) {
// Evaluate generator expression
@@ -1610,15 +1605,15 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Find executable target
{
// Find executable target name
- std::string targetName;
+ cm::string_view prefix;
if (this->QtVersion.Major == 4) {
- targetName = "Qt4::";
+ prefix = "Qt4::";
} else if (this->QtVersion.Major == 5) {
- targetName = "Qt5::";
+ prefix = "Qt5::";
} else if (this->QtVersion.Major == 6) {
- targetName = "Qt6::";
+ prefix = "Qt6::";
}
- targetName += executable;
+ std::string const targetName = cmStrCat(prefix, executable);
// Find target
cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 7d72cad..65666a6 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -63,7 +63,7 @@ public:
bool Enabled = false;
// Generator type/name
GenT Gen;
- std::string const& GenNameUpper;
+ cm::string_view GenNameUpper;
// Executable
std::string ExecutableTargetName;
cmGeneratorTarget* ExecutableTarget = nullptr;
@@ -145,7 +145,7 @@ private:
bool AddGeneratedSource(std::string const& filename, GenVarsT const& genVars,
bool prepend = false);
bool AddToSourceGroup(std::string const& fileName,
- std::string const& genNameUpper);
+ cm::string_view genNameUpper);
void AddCleanFile(std::string const& fileName);
bool GetQtExecutable(GenVarsT& genVars, const std::string& executable,
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 90361a9..3bcc1c9 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -58,18 +58,16 @@ void cmQtAutoGenerator::Logger::SetColorOutput(bool value)
ColorOutput_ = value;
}
-std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title)
+std::string cmQtAutoGenerator::Logger::HeadLine(cm::string_view title)
{
- return cmStrCat(title, "\n", std::string(title.size(), '-'), "\n");
+ return cmStrCat(title, '\n', std::string(title.size(), '-'), '\n');
}
void cmQtAutoGenerator::Logger::Info(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
- std::string msg = cmStrCat(GeneratorName(genType), ": ", message);
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
+ std::string msg = cmStrCat(GeneratorName(genType), ": ", message,
+ cmHasSuffix(message, '\n') ? "" : "\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stdout(msg);
@@ -77,23 +75,18 @@ void cmQtAutoGenerator::Logger::Info(GenT genType,
}
void cmQtAutoGenerator::Logger::Warning(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
std::string msg;
if (message.find('\n') == std::string::npos) {
// Single line message
- msg += GeneratorName(genType);
- msg += " warning: ";
+ msg = cmStrCat(GeneratorName(genType), " warning: ", message,
+ cmHasSuffix(message, '\n') ? "\n" : "\n\n");
} else {
// Multi line message
- msg += HeadLine(GeneratorName(genType) + " warning");
- }
- // Message
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
+ msg = cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " warning")),
+ message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
}
- msg.push_back('\n');
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stdout(msg);
@@ -101,22 +94,18 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType,
}
void cmQtAutoGenerator::Logger::WarningFile(GenT genType,
- std::string const& filename,
- std::string const& message) const
+ cm::string_view filename,
+ cm::string_view message) const
{
- Warning(genType, cmStrCat(" ", Quoted(filename), "\n", message));
+ Warning(genType, cmStrCat(" ", Quoted(filename), '\n', message));
}
void cmQtAutoGenerator::Logger::Error(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
- std::string msg = HeadLine(GeneratorName(genType) + " error");
- // Message
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
+ std::string msg =
+ cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " error")), message,
+ cmHasSuffix(message, '\n') ? "\n" : "\n\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stderr(msg);
@@ -124,36 +113,22 @@ void cmQtAutoGenerator::Logger::Error(GenT genType,
}
void cmQtAutoGenerator::Logger::ErrorFile(GenT genType,
- std::string const& filename,
- std::string const& message) const
+ cm::string_view filename,
+ cm::string_view message) const
{
Error(genType, cmStrCat(" ", Quoted(filename), '\n', message));
}
void cmQtAutoGenerator::Logger::ErrorCommand(
- GenT genType, std::string const& message,
+ GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
- std::string msg;
- msg.push_back('\n');
- msg += HeadLine(GeneratorName(genType) + " subprocess error");
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
- msg += HeadLine("Command");
- msg += QuotedCommand(command);
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
- msg += HeadLine("Output");
- msg += output;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
+ std::string msg = cmStrCat(
+ '\n', HeadLine(cmStrCat(GeneratorName(genType), " subprocess error")),
+ message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
+ msg += cmStrCat(HeadLine("Command"), QuotedCommand(command), "\n\n");
+ msg += cmStrCat(HeadLine("Output"), output,
+ cmHasSuffix(output, '\n') ? "\n" : "\n\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stderr(msg);
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index ff4c4c9..4b8b0b7 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -7,6 +7,7 @@
#include "cmFileTime.h"
#include "cmQtAutoGen.h"
+#include "cm_string_view.hxx"
#include <mutex>
#include <string>
@@ -41,21 +42,21 @@ public:
bool ColorOutput() const { return this->ColorOutput_; }
void SetColorOutput(bool value);
// -- Log info
- void Info(GenT genType, std::string const& message) const;
+ void Info(GenT genType, cm::string_view message) const;
// -- Log warning
- void Warning(GenT genType, std::string const& message) const;
- void WarningFile(GenT genType, std::string const& filename,
- std::string const& message) const;
+ void Warning(GenT genType, cm::string_view message) const;
+ void WarningFile(GenT genType, cm::string_view filename,
+ cm::string_view message) const;
// -- Log error
- void Error(GenT genType, std::string const& message) const;
- void ErrorFile(GenT genType, std::string const& filename,
- std::string const& message) const;
- void ErrorCommand(GenT genType, std::string const& message,
+ void Error(GenT genType, cm::string_view message) const;
+ void ErrorFile(GenT genType, cm::string_view filename,
+ cm::string_view message) const;
+ void ErrorCommand(GenT genType, cm::string_view message,
std::vector<std::string> const& command,
std::string const& output) const;
private:
- static std::string HeadLine(std::string const& title);
+ static std::string HeadLine(cm::string_view title);
private:
mutable std::mutex Mutex_;
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index a82dd3a..84359f2 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -3,10 +3,9 @@
#include "cmQtAutoMocUic.h"
#include <algorithm>
-#include <array>
+#include <initializer_list>
#include <list>
#include <set>
-#include <sstream>
#include <utility>
#include "cm_memory.hxx"
@@ -233,22 +232,21 @@ bool cmQtAutoMocUic::UicSettingsT::skipped(std::string const& fileName) const
}
void cmQtAutoMocUic::JobT::LogError(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
Gen()->AbortError();
Gen()->Log().Error(genType, message);
}
-void cmQtAutoMocUic::JobT::LogFileError(GenT genType,
- std::string const& filename,
- std::string const& message) const
+void cmQtAutoMocUic::JobT::LogFileError(GenT genType, cm::string_view filename,
+ cm::string_view message) const
{
Gen()->AbortError();
Gen()->Log().ErrorFile(genType, filename, message);
}
void cmQtAutoMocUic::JobT::LogCommandError(
- GenT genType, std::string const& message,
+ GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
Gen()->AbortError();
@@ -262,16 +260,14 @@ bool cmQtAutoMocUic::JobT::RunProcess(GenT genType,
{
// Log command
if (Log().Verbose()) {
- std::string msg;
- if ((infoMessage != nullptr) && !infoMessage->empty()) {
- msg = *infoMessage;
- if (msg.back() != '\n') {
- msg += '\n';
- }
+ cm::string_view info;
+ if (infoMessage != nullptr) {
+ info = *infoMessage;
}
- msg += QuotedCommand(command);
- msg += '\n';
- Log().Info(genType, msg);
+ Log().Info(genType,
+ cmStrCat(info,
+ info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
+ QuotedCommand(command), '\n'));
}
return cmWorkerPool::JobT::RunProcess(result, command,
BaseConst().AutogenBuildDir);
@@ -302,10 +298,11 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
}
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
- std::string msg =
- cmStrCat("The content generation command for ",
- Quoted(predefsFileRel), " failed.\n", result.ErrorMessage);
- LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
+ LogCommandError(GenT::MOC,
+ cmStrCat("The content generation command for ",
+ Quoted(predefsFileRel), " failed.\n",
+ result.ErrorMessage),
+ cmd, result.StdOut);
return;
}
}
@@ -313,9 +310,8 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
// (Re)write predefs file only on demand
if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
- std::string msg =
- cmStrCat("Writing ", Quoted(predefsFileRel), " failed.");
- LogFileError(GenT::MOC, predefsFileAbs, msg);
+ LogFileError(GenT::MOC, predefsFileAbs,
+ cmStrCat("Writing ", Quoted(predefsFileRel), " failed."));
return;
}
} else {
@@ -324,9 +320,9 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel));
}
if (!cmSystemTools::Touch(predefsFileAbs, false)) {
- std::string msg =
- cmStrCat("Touching ", Quoted(predefsFileAbs), " failed.");
- LogFileError(GenT::MOC, predefsFileAbs, msg);
+ LogFileError(
+ GenT::MOC, predefsFileAbs,
+ cmStrCat("Touching ", Quoted(predefsFileAbs), " failed."));
return;
}
}
@@ -654,14 +650,12 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
// Check if this source needs to be moc processed but doesn't.
if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
!(relaxedMode && sourceIncludesMocUnderscore)) {
- {
- std::string emsg =
- cmStrCat("The file contains a ", Quoted(parseData.Macro),
- " macro, but does not include ", Quoted(sourceBase + ".moc"),
- "!\nConsider to\n - add #include \"", sourceBase,
- ".moc\"\n - enable SKIP_AUTOMOC for this file");
- LogFileError(GenT::MOC, sourceFile.FileName, emsg);
- }
+ LogFileError(GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file contains a ", Quoted(parseData.Macro),
+ " macro, but does not include ",
+ Quoted(sourceBase + ".moc"),
+ "!\nConsider to\n - add #include \"", sourceBase,
+ ".moc\"\n - enable SKIP_AUTOMOC for this file"));
return false;
}
@@ -670,14 +664,12 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
std::string const headerBase = incKey.Dir + incKey.Base;
SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
if (!header) {
- {
- std::string msg =
- cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
- ",\nbut the header could not be found "
- "in the following locations\n",
- MocMessageTestHeaders(headerBase));
- LogFileError(GenT::MOC, sourceFile.FileName, msg);
- }
+ LogFileError(GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file includes the moc file ",
+ Quoted(incKey.Key),
+ ",\nbut the header could not be found "
+ "in the following locations\n",
+ MocMessageTestHeaders(headerBase)));
return false;
}
// The include might be handled differently in relaxed mode
@@ -688,18 +680,19 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
// be generated from <BASE>.cpp instead of <BASE>.h, because otherwise
// it won't build. But warn, since this is not how it is supposed to be
// used. This is for KDE4 compatibility.
- {
- // Issue a warning
- std::string msg = cmStrCat(
- "The file contains a ", Quoted(parseData.Macro),
- " macro, but does not include ", Quoted(sourceBase + ".moc"),
- ".\nInstead it includes ", Quoted(incKey.Key),
- ".\nRunning moc on the source\n ", Quoted(sourceFile.FileName),
- "!\nBetter include ", Quoted(sourceBase + ".moc"),
- " for compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
- }
+
+ // Issue a warning
+ Log().WarningFile(
+ GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file contains a ", Quoted(parseData.Macro),
+ " macro, but does not include ", Quoted(sourceBase + ".moc"),
+ ".\nInstead it includes ", Quoted(incKey.Key),
+ ".\nRunning moc on the source\n ",
+ Quoted(sourceFile.FileName), "!\nBetter include ",
+ Quoted(sourceBase + ".moc"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
+
// Create mapping
if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
return false;
@@ -735,13 +728,13 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
std::string const headerBase = incKey.Dir + incKey.Base;
SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
if (!header) {
- std::string msg =
+ LogFileError(
+ GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
",\nwhich seems to be the moc file from a different source "
"file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header"
"could not be found in the following locations\n",
- MocMessageTestHeaders(headerBase));
- LogFileError(GenT::MOC, sourceFile.FileName, msg);
+ MocMessageTestHeaders(headerBase)));
return false;
}
// Check if header is skipped
@@ -750,23 +743,25 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
}
// Issue a warning
if (ownMoc && parseData.Macro.empty()) {
- std::string msg = cmStrCat(
- "The file includes the moc file ", Quoted(incKey.Key),
- ", but does not contain a\n", MocConst().MacrosString(),
- " macro.\nRunning moc on the header\n ", Quoted(header->FileName),
- "!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"),
- " for a compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
+ Log().WarningFile(
+ GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
+ ", but does not contain a\n", MocConst().MacrosString(),
+ " macro.\nRunning moc on the header\n ",
+ Quoted(header->FileName), "!\nBetter include ",
+ Quoted("moc_" + incKey.Base + ".cpp"),
+ " for a compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
} else {
- std::string msg = cmStrCat(
- "The file includes the moc file ", Quoted(incKey.Key),
- " instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
- ".\nRunning moc on the header\n ", Quoted(header->FileName),
- "!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"),
- " for compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
+ Log().WarningFile(
+ GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
+ " instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
+ ".\nRunning moc on the header\n ",
+ Quoted(header->FileName), "!\nBetter include ",
+ Quoted("moc_" + incKey.Base + ".cpp"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
}
// Create mapping
if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
@@ -780,20 +775,22 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
bool const ownMoc = (incKey.Base == sourceBase);
if (!ownMoc) {
// Don't allow <BASE>.moc include other than own in regular mode
- std::string msg = cmStrCat(
- "The file includes the moc file ", Quoted(incKey.Key),
- ",\nwhich seems to be the moc file from a different "
- "source file.\nThis is not supported. Include ",
- Quoted(sourceBase + ".moc"), " to run moc on this source file.");
- LogFileError(GenT::MOC, sourceFile.FileName, msg);
+ LogFileError(
+ GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
+ ",\nwhich seems to be the moc file from a different "
+ "source file.\nThis is not supported. Include ",
+ Quoted(sourceBase + ".moc"),
+ " to run moc on this source file."));
return false;
}
// Accept but issue a warning if moc isn't required
if (parseData.Macro.empty()) {
- std::string msg = cmStrCat(
- "The file includes the moc file ", Quoted(incKey.Key),
- ", but does not contain a ", MocConst().MacrosString(), " macro.");
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
+ Log().WarningFile(GenT::MOC, sourceFile.FileName,
+ cmStrCat("The file includes the moc file ",
+ Quoted(incKey.Key),
+ ", but does not contain a ",
+ MocConst().MacrosString(), " macro."));
}
// Create mapping
if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
@@ -864,19 +861,16 @@ cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader(
}
std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders(
- std::string const& fileBase) const
+ cm::string_view fileBase) const
{
- std::ostringstream res;
- {
- std::string exts =
- cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","),
- '}'); // Compose result string
- res << " " << fileBase << exts << '\n';
- for (std::string const& path : MocConst().IncludePaths) {
- res << " " << path << '/' << fileBase << exts << '\n';
- }
+ std::string const exts =
+ cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), '}');
+ // Compose result string
+ std::string res = cmStrCat(" ", fileBase, exts, '\n');
+ for (std::string const& path : MocConst().IncludePaths) {
+ res += cmStrCat(" ", path, '/', fileBase, exts, '\n');
}
- return res.str();
+ return res;
}
bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
@@ -888,26 +882,24 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
if (handle) {
// Check if the output file would be generated from different source files
if (handle->SourceFile != sourceFileHandle) {
- std::string msg = cmStrCat("The source files\n ",
- Quoted(includerFileHandle->FileName), '\n');
+ std::string files =
+ cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
- }
- msg += "contain the same include string ";
- msg += Quoted(includeString);
- msg += ", but\nthe moc file would be generated from different "
- "source files\n ";
- msg += Quoted(sourceFileHandle->FileName);
- msg += " and\n ";
- msg += Quoted(handle->SourceFile->FileName);
- msg += ".\nConsider to\n"
- " - not include the \"moc_<NAME>.cpp\" file\n"
- " - add a directory prefix to a \"<NAME>.moc\" include "
- "(e.g \"sub/<NAME>.moc\")\n"
- " - rename the source file(s)\n";
- LogError(GenT::MOC, msg);
+ files += cmStrCat(" ", Quoted(item->FileName), '\n');
+ }
+ LogError(
+ GenT::MOC,
+ cmStrCat("The source files\n", files,
+ "contain the same include string ", Quoted(includeString),
+ ", but\nthe moc file would be generated from different "
+ "source files\n ",
+ Quoted(sourceFileHandle->FileName), " and\n ",
+ Quoted(handle->SourceFile->FileName),
+ ".\nConsider to\n"
+ " - not include the \"moc_<NAME>.cpp\" file\n"
+ " - add a directory prefix to a \"<NAME>.moc\" include "
+ "(e.g \"sub/<NAME>.moc\")\n"
+ " - rename the source file(s)\n"));
return false;
}
@@ -921,7 +913,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
handle->SourceFile = std::move(sourceFileHandle);
- handle->OutputFile += Gen()->AbsoluteIncludePath(includeString);
+ handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
// Register mapping in sources/headers map
MocRegisterMapping(handle, sourceIsHeader);
@@ -957,7 +949,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEval(SourceFileMapT const& fileMap)
}
bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
- SourceFileHandleT sourceFileHandle)
+ SourceFileHandleT const& sourceFileHandle)
{
SourceFileT const& sourceFile = *sourceFileHandle;
auto const& Include = sourceFile.ParseData->Uic.Include;
@@ -975,7 +967,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
}
// Register mapping
if (!UicRegisterMapping(incKey.Key, std::move(uiFileHandle),
- std::move(sourceFileHandle))) {
+ sourceFileHandle)) {
return false;
}
}
@@ -993,26 +985,25 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
MappingHandleT const& handle = it->second;
if (handle->SourceFile != uiFileHandle) {
// The output file already gets generated - from a different .ui file!
- std::string msg = cmStrCat("The source files\n ",
- Quoted(includerFileHandle->FileName), '\n');
+ std::string files =
+ cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
- }
- msg += "contain the same include string ";
- msg += Quoted(includeString);
- msg += ", but\nthe uic file would be generated from different "
- "user interface files\n ";
- msg += Quoted(uiFileHandle->FileName);
- msg += " and\n ";
- msg += Quoted(handle->SourceFile->FileName);
- msg += ".\nConsider to\n"
- " - add a directory prefix to a \"ui_<NAME>.h\" include "
- "(e.g \"sub/ui_<NAME>.h\")\n"
- " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
- "include(s)\n";
- LogError(GenT::UIC, msg);
+ files += cmStrCat(" ", Quoted(item->FileName), '\n');
+ }
+ LogError(
+ GenT::UIC,
+ cmStrCat(
+ "The source files\n", files, "contain the same include string ",
+ Quoted(includeString),
+ ", but\nthe uic file would be generated from different "
+ "user interface files\n ",
+ Quoted(uiFileHandle->FileName), " and\n ",
+ Quoted(handle->SourceFile->FileName),
+ ".\nConsider to\n"
+ " - add a directory prefix to a \"ui_<NAME>.h\" include "
+ "(e.g \"sub/ui_<NAME>.h\")\n"
+ " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
+ "include(s)\n"));
return false;
}
// Add includer file to existing mapping
@@ -1023,7 +1014,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
handle->SourceFile = std::move(uiFileHandle);
- handle->OutputFile += Gen()->AbsoluteIncludePath(includeString);
+ handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
// Register mapping
Includes.emplace(includeString, std::move(handle));
}
@@ -1080,16 +1071,15 @@ cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi(
// Log error
{
- std::string msg =
- cmStrCat("The file includes the uic file ", Quoted(incKey.Key),
- ",\nbut the user interface file ", Quoted(searchFileName),
- "\ncould not be found in the following locations\n");
+ std::string files;
for (std::string const& testFile : testFiles) {
- msg += " ";
- msg += Quoted(testFile);
- msg += '\n';
+ files += cmStrCat(" ", Quoted(testFile), '\n');
}
- LogFileError(GenT::UIC, sourceFile, msg);
+ LogFileError(
+ GenT::UIC, sourceFile,
+ cmStrCat("The file includes the uic file ", Quoted(incKey.Key),
+ ",\nbut the user interface file ", Quoted(searchFileName),
+ "\ncould not be found in the following locations\n", files));
}
return SourceFileHandleT();
@@ -1257,9 +1247,7 @@ cmQtAutoMocUic::JobGenerateT::MocFindDependency(
}
// Search in include directories
for (std::string const& includePath : MocConst().IncludePaths) {
- ResPair res{ includePath, {} };
- res.first += '/';
- res.first += includeString;
+ ResPair res{ cmStrCat(includePath, '/', includeString), {} };
if (res.second.Load(res.first)) {
return res;
}
@@ -1366,21 +1354,19 @@ void cmQtAutoMocUic::JobMocT::Process()
}
} else {
// Moc command failed
- std::string msg =
- cmStrCat("The moc process failed to compile\n ", Quoted(sourceFile),
- "\ninto\n ", Quoted(outputFile));
- if (Mapping->IncluderFiles.empty()) {
- msg += ".\n";
- } else {
- msg += "\nincluded by\n";
+ std::string includers;
+ if (!Mapping->IncluderFiles.empty()) {
+ includers = "included by\n";
for (auto const& item : Mapping->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
+ includers += cmStrCat(" ", Quoted(item->FileName), '\n');
}
}
- msg += result.ErrorMessage;
- LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
+ LogCommandError(GenT::MOC,
+ cmStrCat("The moc process failed to compile\n ",
+ Quoted(sourceFile), "\ninto\n ",
+ Quoted(outputFile), '\n', includers,
+ result.ErrorMessage),
+ cmd, result.StdOut);
}
}
@@ -1414,16 +1400,16 @@ void cmQtAutoMocUic::JobUicT::Process()
}
} else {
// Uic command failed
- std::string msg =
- cmStrCat("The uic process failed to compile\n ", Quoted(sourceFile),
- "\ninto\n ", Quoted(outputFile), "\nincluded by\n");
+ std::string includers;
for (auto const& item : Mapping->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
+ includers += cmStrCat(" ", Quoted(item->FileName), '\n');
}
- msg += result.ErrorMessage;
- LogCommandError(GenT::UIC, msg, cmd, result.StdOut);
+ LogCommandError(GenT::UIC,
+ cmStrCat("The uic process failed to compile\n ",
+ Quoted(sourceFile), "\ninto\n ",
+ Quoted(outputFile), "\nincluded by\n", includers,
+ result.ErrorMessage),
+ cmd, result.StdOut);
}
}
@@ -1436,19 +1422,14 @@ void cmQtAutoMocUic::JobMocsCompilationT::Process()
if (MocEval().CompFiles.empty()) {
// Placeholder content
content += "// No files found that require moc or the moc files are "
- "included\n";
- content += "enum some_compilers { need_more_than_nothing };\n";
+ "included\n"
+ "enum some_compilers { need_more_than_nothing };\n";
} else {
// Valid content
- char const clampB = BaseConst().MultiConfig ? '<' : '"';
- char const clampE = BaseConst().MultiConfig ? '>' : '"';
- for (std::string const& mocfile : MocEval().CompFiles) {
- content += "#include ";
- content += clampB;
- content += mocfile;
- content += clampE;
- content += '\n';
- }
+ const bool mc = BaseConst().MultiConfig;
+ cm::string_view const wrapFront = mc ? "#include <" : "#include \"";
+ cm::string_view const wrapBack = mc ? ">\n" : "\"\n";
+ content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, "");
}
std::string const& compAbs = MocConst().CompFileAbs;
@@ -1484,22 +1465,21 @@ cmQtAutoMocUic::~cmQtAutoMocUic() = default;
bool cmQtAutoMocUic::Init(cmMakefile* makefile)
{
// Utility lambdas
- auto InfoGet = [makefile](const char* key) {
- return makefile->GetSafeDefinition(key);
+ auto InfoGet = [makefile](cm::string_view key) {
+ return makefile->GetSafeDefinition(std::string(key));
};
- auto InfoGetBool = [makefile](const char* key) {
- return makefile->IsOn(key);
+ auto InfoGetBool = [makefile](cm::string_view key) {
+ return makefile->IsOn(std::string(key));
};
- auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmExpandList(makefile->GetSafeDefinition(key), list);
- return list;
+ auto InfoGetList =
+ [makefile](cm::string_view key) -> std::vector<std::string> {
+ return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
};
auto InfoGetLists =
- [makefile](const char* key) -> std::vector<std::vector<std::string>> {
+ [makefile](cm::string_view key) -> std::vector<std::vector<std::string>> {
std::vector<std::vector<std::string>> lists;
{
- std::string const value = makefile->GetSafeDefinition(key);
+ std::string const value = makefile->GetSafeDefinition(std::string(key));
std::string::size_type pos = 0;
while (pos < value.size()) {
std::string::size_type next = value.find(ListSep, pos);
@@ -1517,39 +1497,30 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
}
return lists;
};
- auto InfoGetConfig = [makefile, this](const char* key) -> std::string {
- const char* valueConf = nullptr;
- {
- std::string keyConf = cmStrCat(key, '_', InfoConfig());
- valueConf = makefile->GetDefinition(keyConf);
- }
- if (valueConf == nullptr) {
- return makefile->GetSafeDefinition(key);
+ auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
+ if (const char* valueConf =
+ makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
+ return std::string(valueConf);
}
- return std::string(valueConf);
+ return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetConfigList =
- [&InfoGetConfig](const char* key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmExpandList(InfoGetConfig(key), list);
- return list;
+ [&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
+ return cmExpandedList(InfoGetConfig(key));
};
- auto LogInfoError = [this](std::string const& msg) -> bool {
- std::ostringstream err;
- err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
- this->Log().Error(GenT::GEN, err.str());
+ auto LogInfoError = [this](cm::string_view msg) -> bool {
+ this->Log().Error(GenT::GEN,
+ cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
return false;
};
- auto MatchSizes = [&LogInfoError](const char* keyA, const char* keyB,
+ auto MatchSizes = [&LogInfoError](cm::string_view keyA, cm::string_view keyB,
std::size_t sizeA,
std::size_t sizeB) -> bool {
if (sizeA == sizeB) {
return true;
}
- std::ostringstream err;
- err << "Lists sizes mismatch " << keyA << '(' << sizeA << ") " << keyB
- << '(' << sizeB << ')';
- return LogInfoError(err.str());
+ return LogInfoError(cmStrCat("Lists sizes mismatch ", keyA, '(', sizeA,
+ ") ", keyB, '(', sizeB, ')'));
};
// -- Read info file
@@ -1591,10 +1562,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
return LogInfoError("CMake executable file name missing.");
}
if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
- std::string error =
- cmStrCat("The CMake executable ", Quoted(BaseConst_.CMakeExecutable),
- " does not exist.");
- return LogInfoError(error);
+ return LogInfoError(cmStrCat("The CMake executable ",
+ Quoted(BaseConst_.CMakeExecutable),
+ " does not exist."));
}
BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
if (BaseConst_.ParseCacheFile.empty()) {
@@ -1621,10 +1591,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
MocConst_.Enabled = true;
// Load the executable file time
if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
- std::string error =
- cmStrCat("The moc executable ", Quoted(MocConst_.Executable),
- " does not exist.");
- return LogInfoError(error);
+ return LogInfoError(cmStrCat("The moc executable ",
+ Quoted(MocConst_.Executable),
+ " does not exist."));
}
for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
MocConst_.SkipList.insert(std::move(sfl));
@@ -1640,12 +1609,11 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
{
auto addFilter = [this, &LogInfoError](std::string const& key,
std::string const& exp) -> bool {
- auto filterErr = [&LogInfoError, &key, &exp](const char* err) -> bool {
- std::ostringstream ferr;
- ferr << "AUTOMOC_DEPEND_FILTERS: " << err << '\n';
- ferr << " Key: " << Quoted(key) << '\n';
- ferr << " Exp: " << Quoted(exp) << '\n';
- return LogInfoError(ferr.str());
+ auto filterErr = [&LogInfoError, &key,
+ &exp](cm::string_view err) -> bool {
+ return LogInfoError(cmStrCat("AUTOMOC_DEPEND_FILTERS: ", err, '\n',
+ " Key: ", Quoted(key), '\n',
+ " Exp: ", Quoted(exp), '\n'));
};
if (key.empty()) {
return filterErr("Key is empty");
@@ -1689,10 +1657,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
UicConst_.Enabled = true;
// Load the executable file time
if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
- std::string error =
- cmStrCat("The uic executable ", Quoted(UicConst_.Executable),
- " does not exist.");
- return LogInfoError(error);
+ return LogInfoError(cmStrCat("The uic executable ",
+ Quoted(UicConst_.Executable),
+ " does not exist."));
}
for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
UicConst_.SkipList.insert(std::move(sfl));
@@ -1700,8 +1667,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
{
- const char* keyFiles = "AM_UIC_OPTIONS_FILES";
- const char* keyOpts = "AM_UIC_OPTIONS_OPTIONS";
+ cm::string_view const keyFiles = "AM_UIC_OPTIONS_FILES";
+ cm::string_view const keyOpts = "AM_UIC_OPTIONS_OPTIONS";
auto sources = InfoGetList(keyFiles);
auto options = InfoGetLists(keyOpts);
if (!MatchSizes(keyFiles, keyOpts, sources.size(), options.size())) {
@@ -1743,8 +1710,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Headers
{
// Get file lists
- const char* keyFiles = "AM_HEADERS";
- const char* keyFlags = "AM_HEADERS_FLAGS";
+ cm::string_view const keyFiles = "AM_HEADERS";
+ cm::string_view const keyFlags = "AM_HEADERS_FLAGS";
std::vector<std::string> files = InfoGetList(keyFiles);
std::vector<std::string> flags = InfoGetList(keyFlags);
std::vector<std::string> builds;
@@ -1752,7 +1719,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
return false;
}
if (MocConst().Enabled) {
- const char* keyPaths = "AM_HEADERS_BUILD_PATHS";
+ cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS";
builds = InfoGetList(keyPaths);
if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) {
return false;
@@ -1779,8 +1746,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Sources
{
- const char* keyFiles = "AM_SOURCES";
- const char* keyFlags = "AM_SOURCES_FLAGS";
+ cm::string_view const keyFiles = "AM_SOURCES";
+ cm::string_view const keyFlags = "AM_SOURCES_FLAGS";
std::vector<std::string> files = InfoGetList(keyFiles);
std::vector<std::string> flags = InfoGetList(keyFlags);
if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
@@ -1808,12 +1775,12 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Moc predefs file
if (!MocConst_.PredefsCmd.empty()) {
- MocConst_.PredefsFileRel = "moc_predefs";
if (BaseConst_.MultiConfig) {
- MocConst_.PredefsFileRel += '_';
- MocConst_.PredefsFileRel += InfoConfig();
+ MocConst_.PredefsFileRel =
+ cmStrCat("moc_predefs_", InfoConfig(), ".h");
+ } else {
+ MocConst_.PredefsFileRel = "moc_predefs.h";
}
- MocConst_.PredefsFileRel += ".h";
MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel);
}
@@ -1826,14 +1793,14 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
MocConst_.IncludePaths.reserve(includes.size());
// Append project directories only
{
- std::array<std::string const*, 2> const movePaths = {
- { &BaseConst().ProjectBinaryDir, &BaseConst().ProjectSourceDir }
+ std::initializer_list<cm::string_view> const movePaths = {
+ BaseConst().ProjectBinaryDir, BaseConst().ProjectSourceDir
};
- for (std::string const* ppath : movePaths) {
+ for (cm::string_view const& ppath : movePaths) {
std::list<std::string>::iterator it = includes.begin();
while (it != includes.end()) {
std::string const& path = *it;
- if (cmHasPrefix(path, *ppath)) {
+ if (cmHasPrefix(path, ppath)) {
MocConst_.IncludePaths.push_back(path);
it = includes.erase(it);
} else {
@@ -1945,22 +1912,19 @@ void cmQtAutoMocUic::SettingsFileRead()
// Compose current settings strings
{
cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
- std::string const sep(";");
- auto cha = [&cryptoHash, &sep](std::string const& value) {
+ auto cha = [&cryptoHash](cm::string_view value) {
cryptoHash.Append(value);
- cryptoHash.Append(sep);
+ cryptoHash.Append(";");
};
if (MocConst_.Enabled) {
cryptoHash.Initialize();
cha(MocConst().Executable);
- for (auto const& value : MocConst().AllOptions) {
- cha(value);
- }
+ std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(),
+ cha);
cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE");
- for (auto const& value : MocConst().PredefsCmd) {
- cha(value);
- }
+ std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(),
+ cha);
for (auto const& filter : MocConst().DependFilters) {
cha(filter.Key);
}
@@ -1973,14 +1937,11 @@ void cmQtAutoMocUic::SettingsFileRead()
if (UicConst().Enabled) {
cryptoHash.Initialize();
cha(UicConst().Executable);
- for (auto const& value : UicConst().TargetOptions) {
- cha(value);
- }
+ std::for_each(UicConst().TargetOptions.begin(),
+ UicConst().TargetOptions.end(), cha);
for (const auto& item : UicConst().Options) {
cha(item.first);
- for (auto const& svalue : item.second) {
- cha(svalue);
- }
+ std::for_each(item.second.begin(), item.second.end(), cha);
}
SettingsStringUic_ = cryptoHash.FinalizeHex();
}
@@ -2028,13 +1989,10 @@ bool cmQtAutoMocUic::SettingsFileWrite()
// Compose settings file content
std::string content;
{
- auto SettingAppend = [&content](const char* key,
- std::string const& value) {
+ auto SettingAppend = [&content](cm::string_view key,
+ cm::string_view value) {
if (!value.empty()) {
- content += key;
- content += ':';
- content += value;
- content += '\n';
+ content += cmStrCat(key, ':', value, '\n');
}
};
SettingAppend("moc", SettingsStringMoc_);
@@ -2055,7 +2013,7 @@ bool cmQtAutoMocUic::SettingsFileWrite()
void cmQtAutoMocUic::ParseCacheRead()
{
- const char* reason = nullptr;
+ cm::string_view reason;
// Don't read the cache if it is invalid
if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) {
reason = "Refreshing parse cache because it doesn't exist.";
@@ -2067,7 +2025,7 @@ void cmQtAutoMocUic::ParseCacheRead()
"Refreshing parse cache because it is older than the CMake executable.";
}
- if (reason != nullptr) {
+ if (!reason.empty()) {
// Don't read but refresh the complete parse cache
if (Log().Verbose()) {
Log().Info(GenT::GEN, reason);
@@ -2116,19 +2074,13 @@ void cmQtAutoMocUic::Abort(bool error)
}
std::string cmQtAutoMocUic::AbsoluteBuildPath(
- std::string const& relativePath) const
+ cm::string_view relativePath) const
{
- std::string res(BaseConst().AutogenBuildDir);
- res += '/';
- res += relativePath;
- return res;
+ return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath);
}
std::string cmQtAutoMocUic::AbsoluteIncludePath(
- std::string const& relativePath) const
+ cm::string_view relativePath) const
{
- std::string res(BaseConst().AutogenIncludeDir);
- res += '/';
- res += relativePath;
- return res;
+ return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath);
}
diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h
index dc18328..f676c57 100644
--- a/Source/cmQtAutoMocUic.h
+++ b/Source/cmQtAutoMocUic.h
@@ -9,6 +9,7 @@
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmWorkerPool.h"
+#include "cm_string_view.hxx"
#include "cmsys/RegularExpression.hxx"
#include <atomic>
@@ -333,10 +334,10 @@ public:
UicEvalT& UicEval() const { return Gen()->UicEval(); }
// -- Error logging with automatic abort
- void LogError(GenT genType, std::string const& message) const;
- void LogFileError(GenT genType, std::string const& filename,
- std::string const& message) const;
- void LogCommandError(GenT genType, std::string const& message,
+ void LogError(GenT genType, cm::string_view message) const;
+ void LogFileError(GenT genType, cm::string_view filename,
+ cm::string_view message) const;
+ void LogCommandError(GenT genType, cm::string_view message,
std::vector<std::string> const& command,
std::string const& output) const;
@@ -429,7 +430,7 @@ public:
SourceFileHandleT MocFindIncludedHeader(
std::string const& includerDir, std::string const& includeBase) const;
SourceFileHandleT MocFindHeader(std::string const& basePath) const;
- std::string MocMessageTestHeaders(std::string const& fileBase) const;
+ std::string MocMessageTestHeaders(cm::string_view fileBase) const;
bool MocRegisterIncluded(std::string const& includeString,
SourceFileHandleT includerFileHandle,
SourceFileHandleT sourceFileHandle,
@@ -439,7 +440,7 @@ public:
// -- Uic
bool UicEval(SourceFileMapT const& fileMap);
- bool UicEvalFile(SourceFileHandleT sourceFileHandle);
+ bool UicEvalFile(SourceFileHandleT const& sourceFileHandle);
SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile,
std::string const& sourceDir,
IncludeKeyT const& incKey) const;
@@ -531,8 +532,8 @@ public:
void AbortSuccess() { Abort(false); }
// -- Utility
- std::string AbsoluteBuildPath(std::string const& relativePath) const;
- std::string AbsoluteIncludePath(std::string const& relativePath) const;
+ std::string AbsoluteBuildPath(cm::string_view relativePath) const;
+ std::string AbsoluteIncludePath(cm::string_view relativePath) const;
template <class JOBTYPE>
void CreateParseJobs(SourceFileMapT const& sourceMap);
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index f15634c..e931346 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -1,9 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoRcc.h"
-#include "cmQtAutoGen.h"
-
-#include <sstream>
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
@@ -11,10 +8,12 @@
#include "cmFileLockResult.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmQtAutoGen.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cm_string_view.hxx"
-// -- Class methods
+#include <algorithm>
cmQtAutoRcc::cmQtAutoRcc() = default;
@@ -23,37 +22,27 @@ cmQtAutoRcc::~cmQtAutoRcc() = default;
bool cmQtAutoRcc::Init(cmMakefile* makefile)
{
// -- Utility lambdas
- auto InfoGet = [makefile](std::string const& key) {
- return makefile->GetSafeDefinition(key);
+ auto InfoGet = [makefile](cm::string_view key) {
+ return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetList =
- [makefile](std::string const& key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmExpandList(makefile->GetSafeDefinition(key), list);
- return list;
+ [makefile](cm::string_view key) -> std::vector<std::string> {
+ return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
};
- auto InfoGetConfig = [makefile,
- this](std::string const& key) -> std::string {
- const char* valueConf = nullptr;
- {
- std::string keyConf = cmStrCat(key, '_', InfoConfig());
- valueConf = makefile->GetDefinition(keyConf);
+ auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
+ if (const char* valueConf =
+ makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
+ return std::string(valueConf);
}
- if (valueConf == nullptr) {
- return makefile->GetSafeDefinition(key);
- }
- return std::string(valueConf);
+ return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetConfigList =
- [&InfoGetConfig](std::string const& key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmExpandList(InfoGetConfig(key), list);
- return list;
+ [&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
+ return cmExpandedList(InfoGetConfig(key));
};
- auto LogInfoError = [this](std::string const& msg) -> bool {
- std::ostringstream err;
- err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
- this->Log().Error(GenT::RCC, err.str());
+ auto LogInfoError = [this](cm::string_view msg) -> bool {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
return false;
};
@@ -80,9 +69,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
// - Rcc executable
RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
if (!RccExecutableTime_.Load(RccExecutable_)) {
- std::string error = cmStrCat("The rcc executable ", Quoted(RccExecutable_),
- " does not exist.");
- return LogInfoError(error);
+ return LogInfoError(cmStrCat("The rcc executable ", Quoted(RccExecutable_),
+ " does not exist."));
}
RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
@@ -170,25 +158,27 @@ bool cmQtAutoRcc::Process()
std::string cmQtAutoRcc::MultiConfigOutput() const
{
- static std::string const suffix = "_CMAKE_";
- std::string res = cmStrCat(RccPathChecksum_, '/',
- AppendFilenameSuffix(RccFileName_, suffix));
- return res;
+ return cmStrCat(RccPathChecksum_, '/',
+ AppendFilenameSuffix(RccFileName_, "_CMAKE_"));
}
bool cmQtAutoRcc::SettingsFileRead()
{
// Compose current settings strings
{
- cmCryptoHash crypt(cmCryptoHash::AlgoSHA256);
- std::string const sep(" ~~~ ");
- {
- std::string str =
- cmStrCat(RccExecutable_, sep, cmJoin(RccListOptions_, ";"), sep,
- QrcFile_, sep, RccPathChecksum_, sep, RccFileName_, sep,
- cmJoin(Options_, ";"), sep, cmJoin(Inputs_, ";"), sep);
- SettingsString_ = crypt.HashString(str);
- }
+ cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
+ auto cha = [&cryptoHash](cm::string_view value) {
+ cryptoHash.Append(value);
+ cryptoHash.Append(";");
+ };
+ cha(RccExecutable_);
+ std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha);
+ cha(QrcFile_);
+ cha(RccPathChecksum_);
+ cha(RccFileName_);
+ std::for_each(Options_.begin(), Options_.end(), cha);
+ std::for_each(Inputs_.begin(), Inputs_.end(), cha);
+ SettingsString_ = cryptoHash.FinalizeHex();
}
// Make sure the settings file exists
@@ -273,10 +263,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
{
// Test if the rcc input file exists
if (!QrcFileTime_.Load(QrcFile_)) {
- std::string error;
- error =
- cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist");
- Log().ErrorFile(GenT::RCC, QrcFile_, error);
+ Log().ErrorFile(
+ GenT::RCC, QrcFile_,
+ cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist"));
return false;
}
@@ -343,10 +332,9 @@ bool cmQtAutoRcc::TestResources(bool& generate)
// Check if the resource file exists
cmFileTime fileTime;
if (!fileTime.Load(resFile)) {
- std::string error;
- error = cmStrCat("Could not find the resource file\n ", Quoted(resFile),
- '\n');
- Log().ErrorFile(GenT::RCC, QrcFile_, error);
+ Log().ErrorFile(GenT::RCC, QrcFile_,
+ cmStrCat("Could not find the resource file\n ",
+ Quoted(resFile), '\n'));
return false;
}
// Check if the resource file is newer than the rcc output file
@@ -368,10 +356,9 @@ bool cmQtAutoRcc::TestInfoFile()
// Test if the rcc output file is older than the info file
if (RccFileTime_.Older(InfoFileTime())) {
if (Log().Verbose()) {
- std::string reason =
- cmStrCat("Touching ", Quoted(RccFileOutput_),
- " because it is older than ", Quoted(InfoFile()));
- Log().Info(GenT::RCC, reason);
+ Log().Info(GenT::RCC,
+ cmStrCat("Touching ", Quoted(RccFileOutput_),
+ " because it is older than ", Quoted(InfoFile())));
}
// Touch build file
if (!cmSystemTools::Touch(RccFileOutput_, false)) {
@@ -403,13 +390,9 @@ bool cmQtAutoRcc::GenerateRcc()
// Log reason and command
if (Log().Verbose()) {
- std::string msg = Reason;
- if (!msg.empty() && (msg.back() != '\n')) {
- msg += '\n';
- }
- msg += QuotedCommand(cmd);
- msg += '\n';
- Log().Info(GenT::RCC, msg);
+ Log().Info(GenT::RCC,
+ cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n",
+ QuotedCommand(cmd), '\n'));
}
std::string rccStdOut;
@@ -420,12 +403,11 @@ bool cmQtAutoRcc::GenerateRcc()
cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
if (!result || (retVal != 0)) {
// rcc process failed
- {
- std::string err =
- cmStrCat("The rcc process failed to compile\n ", Quoted(QrcFile_),
- "\ninto\n ", Quoted(RccFileOutput_));
- Log().ErrorCommand(GenT::RCC, err, cmd, rccStdOut + rccStdErr);
- }
+ Log().ErrorCommand(GenT::RCC,
+ cmStrCat("The rcc process failed to compile\n ",
+ Quoted(QrcFile_), "\ninto\n ",
+ Quoted(RccFileOutput_)),
+ cmd, rccStdOut + rccStdErr);
cmSystemTools::RemoveFile(RccFileOutput_);
return false;
}
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index affff54..d15ce57 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -78,8 +78,7 @@ void cmSearchPath::AddCMakePath(const std::string& variable)
// Get a path from a CMake variable.
if (const char* value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded;
- cmExpandList(value, expanded);
+ std::vector<std::string> expanded = cmExpandedList(value);
for (std::string const& p : expanded) {
this->AddPathInternal(
@@ -103,8 +102,7 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
// Get a path from a CMake variable.
if (const char* value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded;
- cmExpandList(value, expanded);
+ std::vector<std::string> expanded = cmExpandedList(value);
this->AddPrefixPaths(
expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str());
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index a6d2807..5d738d5 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -45,11 +45,13 @@ std::string cmSourceFile::GetObjectLibrary() const
return this->ObjectLibrary;
}
-std::string cmSourceFile::GetLanguage()
+std::string const& cmSourceFile::GetOrDetermineLanguage()
{
// If the language was set explicitly by the user then use it.
if (const char* lang = this->GetProperty(propLANGUAGE)) {
- return lang;
+ // Assign to member in order to return a reference.
+ this->Language = lang;
+ return this->Language;
}
// Perform computation needed to get the language if necessary.
@@ -72,8 +74,8 @@ std::string cmSourceFile::GetLanguage()
}
}
- // Now try to determine the language.
- return static_cast<cmSourceFile const*>(this)->GetLanguage();
+ // Use the language determined from the file extension.
+ return this->Language;
}
std::string cmSourceFile::GetLanguage() const
@@ -83,13 +85,8 @@ std::string cmSourceFile::GetLanguage() const
return lang;
}
- // If the language was determined from the source file extension use it.
- if (!this->Language.empty()) {
- return this->Language;
- }
-
- // The language is not known.
- return "";
+ // Use the language determined from the file extension.
+ return this->Language;
}
cmSourceFileLocation const& cmSourceFile::GetLocation() const
@@ -275,6 +272,13 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
this->GetFullPath();
}
+ // Similarly, LANGUAGE can be determined by the file extension
+ // if it is requested by the user.
+ if (prop == propLANGUAGE) {
+ // The c_str pointer is valid until `this->Language` is modified.
+ return this->GetOrDetermineLanguage().c_str();
+ }
+
// Perform the normal property lookup.
return this->GetProperty(prop);
}
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index edad4c7..ccd5b62 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -88,7 +88,7 @@ public:
/**
* Get the language of the compiler to use for this source file.
*/
- std::string GetLanguage();
+ std::string const& GetOrDetermineLanguage();
std::string GetLanguage() const;
/**
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index b6f1808..902287c 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -14,7 +14,6 @@
#include "cmCacheManager.h"
#include "cmCommand.h"
#include "cmDefinitions.h"
-#include "cmDisallowedCommand.h"
#include "cmExecutionStatus.h"
#include "cmGlobVerificationManager.h"
#include "cmListFileCache.h"
@@ -485,16 +484,6 @@ void cmState::AddDisallowedCommand(std::string const& name,
});
}
-void cmState::AddDisallowedCommand(std::string const& name,
- std::unique_ptr<cmCommand> command,
- cmPolicies::PolicyID policy,
- const char* message)
-{
- this->AddBuiltinCommand(
- name,
- cm::make_unique<cmDisallowedCommand>(std::move(command), policy, message));
-}
-
void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
{
this->AddBuiltinCommand(
diff --git a/Source/cmState.h b/Source/cmState.h
index 937ab61..a7ca015 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -159,9 +159,6 @@ public:
void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
void AddDisallowedCommand(std::string const& name, BuiltinCommand command,
cmPolicies::PolicyID policy, const char* message);
- void AddDisallowedCommand(std::string const& name,
- std::unique_ptr<cmCommand> command,
- cmPolicies::PolicyID policy, const char* message);
void AddUnexpectedCommand(std::string const& name, const char* error);
void AddScriptedCommand(std::string const& name, Command command);
void RemoveBuiltinCommand(std::string const& name);
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 849a566..9a2de9d 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -13,6 +13,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include "cm_static_string_view.hxx"
+
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmExecutionStatus.h"
@@ -22,150 +24,23 @@
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmUuid.h"
namespace {
-bool HandleConfigureCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleAsciiCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleRegexCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
+
bool RegexMatch(std::vector<std::string> const& args,
cmExecutionStatus& status);
bool RegexMatchAll(std::vector<std::string> const& args,
cmExecutionStatus& status);
bool RegexReplace(std::vector<std::string> const& args,
cmExecutionStatus& status);
-bool HandleHashCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
- bool toUpper, cmExecutionStatus& status);
-bool HandleCompareCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleReplaceCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleLengthCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleSubstringCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleAppendCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandlePrependCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleConcatCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleJoinCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleStripCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleRepeatCommand(std::vector<std::string> const& args,
- cmMakefile& makefile);
-bool HandleRandomCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleFindCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleTimestampCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleGenexStripCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
-bool HandleUuidCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status);
bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
size_t varIdx, cmMakefile& makefile);
-}
-
-bool cmStringCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
-{
- if (args.empty()) {
- status.SetError("must be called with at least one argument.");
- return false;
- }
-
- const std::string& subCommand = args[0];
- if (subCommand == "REGEX") {
- return HandleRegexCommand(args, status);
- }
- if (subCommand == "REPLACE") {
- return HandleReplaceCommand(args, status);
- }
- if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
- subCommand == "SHA256" || subCommand == "SHA384" ||
- subCommand == "SHA512" || subCommand == "SHA3_224" ||
- subCommand == "SHA3_256" || subCommand == "SHA3_384" ||
- subCommand == "SHA3_512") {
- return HandleHashCommand(args, status);
- }
- if (subCommand == "TOLOWER") {
- return HandleToUpperLowerCommand(args, false, status);
- }
- if (subCommand == "TOUPPER") {
- return HandleToUpperLowerCommand(args, true, status);
- }
- if (subCommand == "COMPARE") {
- return HandleCompareCommand(args, status);
- }
- if (subCommand == "ASCII") {
- return HandleAsciiCommand(args, status);
- }
- if (subCommand == "CONFIGURE") {
- return HandleConfigureCommand(args, status);
- }
- if (subCommand == "LENGTH") {
- return HandleLengthCommand(args, status);
- }
- if (subCommand == "APPEND") {
- return HandleAppendCommand(args, status);
- }
- if (subCommand == "PREPEND") {
- return HandlePrependCommand(args, status);
- }
- if (subCommand == "CONCAT") {
- return HandleConcatCommand(args, status);
- }
- if (subCommand == "JOIN") {
- return HandleJoinCommand(args, status);
- }
- if (subCommand == "SUBSTRING") {
- return HandleSubstringCommand(args, status);
- }
- if (subCommand == "STRIP") {
- return HandleStripCommand(args, status);
- }
- if (subCommand == "REPEAT") {
- return HandleRepeatCommand(args, status.GetMakefile());
- }
- if (subCommand == "RANDOM") {
- return HandleRandomCommand(args, status);
- }
- if (subCommand == "FIND") {
- return HandleFindCommand(args, status);
- }
- if (subCommand == "TIMESTAMP") {
- return HandleTimestampCommand(args, status);
- }
- if (subCommand == "MAKE_C_IDENTIFIER") {
- return HandleMakeCIdentifierCommand(args, status);
- }
- if (subCommand == "GENEX_STRIP") {
- return HandleGenexStripCommand(args, status);
- }
- if (subCommand == "UUID") {
- return HandleUuidCommand(args, status);
- }
-
- std::string e = "does not recognize sub-command " + subCommand;
- status.SetError(e);
- return false;
-}
-namespace {
bool HandleHashCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -214,6 +89,18 @@ bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
return true;
}
+bool HandleToUpperCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleToUpperLowerCommand(args, true, status);
+}
+
+bool HandleToLowerCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleToUpperLowerCommand(args, false, status);
+}
+
bool HandleAsciiCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -784,8 +671,10 @@ bool HandleStripCommand(std::vector<std::string> const& args,
}
bool HandleRepeatCommand(std::vector<std::string> const& args,
- cmMakefile& makefile)
+ cmExecutionStatus& status)
{
+ cmMakefile& makefile = status.GetMakefile();
+
// `string(REPEAT "<str>" <times> OUTPUT_VARIABLE)`
enum ArgPos : std::size_t
{
@@ -1032,4 +921,50 @@ bool HandleUuidCommand(std::vector<std::string> const& args,
return false;
#endif
}
+
+} // namespace
+
+bool cmStringCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.empty()) {
+ status.SetError("must be called with at least one argument.");
+ return false;
+ }
+
+ static cmSubcommandTable const subcommand{
+ { "REGEX"_s, HandleRegexCommand },
+ { "REPLACE"_s, HandleReplaceCommand },
+ { "MD5"_s, HandleHashCommand },
+ { "SHA1"_s, HandleHashCommand },
+ { "SHA224"_s, HandleHashCommand },
+ { "SHA256"_s, HandleHashCommand },
+ { "SHA384"_s, HandleHashCommand },
+ { "SHA512"_s, HandleHashCommand },
+ { "SHA3_224"_s, HandleHashCommand },
+ { "SHA3_256"_s, HandleHashCommand },
+ { "SHA3_384"_s, HandleHashCommand },
+ { "SHA3_512"_s, HandleHashCommand },
+ { "TOLOWER"_s, HandleToLowerCommand },
+ { "TOUPPER"_s, HandleToUpperCommand },
+ { "COMPARE"_s, HandleCompareCommand },
+ { "ASCII"_s, HandleAsciiCommand },
+ { "CONFIGURE"_s, HandleConfigureCommand },
+ { "LENGTH"_s, HandleLengthCommand },
+ { "APPEND"_s, HandleAppendCommand },
+ { "PREPEND"_s, HandlePrependCommand },
+ { "CONCAT"_s, HandleConcatCommand },
+ { "JOIN"_s, HandleJoinCommand },
+ { "SUBSTRING"_s, HandleSubstringCommand },
+ { "STRIP"_s, HandleStripCommand },
+ { "REPEAT"_s, HandleRepeatCommand },
+ { "RANDOM"_s, HandleRandomCommand },
+ { "FIND"_s, HandleFindCommand },
+ { "TIMESTAMP"_s, HandleTimestampCommand },
+ { "MAKE_C_IDENTIFIER"_s, HandleMakeCIdentifierCommand },
+ { "GENEX_STRIP"_s, HandleGenexStripCommand },
+ { "UUID"_s, HandleUuidCommand },
+ };
+
+ return subcommand(args[0], args, status);
}
diff --git a/Source/cmSubdirDependsCommand.cxx b/Source/cmSubdirDependsCommand.cxx
index 0bb2c0a..496c60d 100644
--- a/Source/cmSubdirDependsCommand.cxx
+++ b/Source/cmSubdirDependsCommand.cxx
@@ -4,8 +4,8 @@
class cmExecutionStatus;
-bool cmSubdirDependsCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&)
+bool cmSubdirDependsCommand(std::vector<std::string> const&,
+ cmExecutionStatus&)
{
return true;
}
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index 64c28b9..bf99bd1 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmSubdirDependsCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmSubdirDependsCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmSubdirDependsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bc1b9de..2a09b43 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -88,8 +88,7 @@ const char* cmTargetPropertyComputer::GetSources<cmTarget>(
std::ostringstream ss;
const char* sep = "";
for (std::string const& entry : entries) {
- std::vector<std::string> files;
- cmExpandList(entry, files);
+ std::vector<std::string> files = cmExpandedList(entry);
for (std::string const& file : files) {
if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
file.back() == '>') {
@@ -191,6 +190,8 @@ public:
std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
std::vector<std::string> CompileDefinitionsEntries;
std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
+ std::vector<std::string> PrecompileHeadersEntries;
+ std::vector<cmListFileBacktrace> PrecompileHeadersBacktraces;
std::vector<std::string> SourceEntries;
std::vector<cmListFileBacktrace> SourceBacktraces;
std::vector<std::string> LinkOptionsEntries;
@@ -347,8 +348,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("FOLDER");
+ initProp("Swift_LANGUAGE_VERSION");
initProp("Swift_MODULE_DIRECTORY");
initProp("VS_JUST_MY_CODE_DEBUGGING");
+ initProp("DISABLE_PRECOMPILE_HEADERS");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_GENERATE_SCHEME");
@@ -499,8 +502,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (globals) {
const std::string genName = mf->GetGlobalGenerator()->GetName();
if (cmHasLiteralPrefix(genName, "Visual Studio")) {
- std::vector<std::string> props;
- cmExpandList(globals, props);
+ std::vector<std::string> props = cmExpandedList(globals);
const std::string vsGlobal = "VS_GLOBAL_";
for (const std::string& i : props) {
// split NAME=VALUE
@@ -742,8 +744,7 @@ public:
bool operator()(std::string const& entry)
{
- std::vector<std::string> files;
- cmExpandList(entry, files);
+ std::vector<std::string> files = cmExpandedList(entry);
std::vector<cmSourceFileLocation> locations;
locations.reserve(files.size());
std::transform(files.begin(), files.end(), std::back_inserter(locations),
@@ -1020,6 +1021,16 @@ cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
return cmMakeRange(impl->CompileDefinitionsBacktraces);
}
+cmStringRange cmTarget::GetPrecompileHeadersEntries() const
+{
+ return cmMakeRange(impl->PrecompileHeadersEntries);
+}
+
+cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const
+{
+ return cmMakeRange(impl->PrecompileHeadersBacktraces);
+}
+
cmStringRange cmTarget::GetSourceEntries() const
{
return cmMakeRange(impl->SourceEntries);
@@ -1071,6 +1082,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
MAKE_STATIC_PROP(COMPILE_FEATURES);
MAKE_STATIC_PROP(COMPILE_OPTIONS);
+ MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
MAKE_STATIC_PROP(CUDA_PTX_COMPILATION);
MAKE_STATIC_PROP(EXPORT_NAME);
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
@@ -1084,21 +1096,19 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
MAKE_STATIC_PROP(TYPE);
#undef MAKE_STATIC_PROP
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
- std::ostringstream e;
- e << "MANUALLY_ADDED_DEPENDENCIES property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "MANUALLY_ADDED_DEPENDENCIES property is read-only\n");
return;
}
if (prop == propNAME) {
- std::ostringstream e;
- e << "NAME property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "NAME property is read-only\n");
return;
}
if (prop == propTYPE) {
- std::ostringstream e;
- e << "TYPE property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "TYPE property is read-only\n");
return;
}
if (prop == propEXPORT_NAME && this->IsImported()) {
@@ -1171,6 +1181,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
+ } else if (prop == propPRECOMPILE_HEADERS) {
+ impl->PrecompileHeadersEntries.clear();
+ impl->PrecompileHeadersBacktraces.clear();
+ if (value) {
+ impl->PrecompileHeadersEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
+ impl->PrecompileHeadersBacktraces.push_back(lfbt);
+ }
} else if (prop == propLINK_LIBRARIES) {
impl->LinkImplementationPropertyEntries.clear();
impl->LinkImplementationPropertyBacktraces.clear();
@@ -1225,9 +1243,8 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
return;
}
if (prop == "NAME") {
- std::ostringstream e;
- e << "NAME property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "NAME property is read-only\n");
return;
}
if (prop == "EXPORT_NAME" && this->IsImported()) {
@@ -1288,6 +1305,12 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
+ } else if (prop == "PRECOMPILE_HEADERS") {
+ if (value && *value) {
+ impl->PrecompileHeadersEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
+ impl->PrecompileHeadersBacktraces.push_back(lfbt);
+ }
} else if (prop == "LINK_LIBRARIES") {
if (value && *value) {
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
@@ -1399,6 +1422,13 @@ void cmTarget::InsertLinkDirectory(std::string const& entry,
impl->LinkDirectoriesBacktraces.insert(btPosition, bt);
}
+void cmTarget::InsertPrecompileHeader(std::string const& entry,
+ cmListFileBacktrace const& bt)
+{
+ impl->PrecompileHeadersEntries.push_back(entry);
+ impl->PrecompileHeadersBacktraces.push_back(bt);
+}
+
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
const char* value,
cmMakefile* context,
@@ -1519,6 +1549,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
MAKE_STATIC_PROP(LINK_OPTIONS);
MAKE_STATIC_PROP(LINK_DIRECTORIES);
+ MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
MAKE_STATIC_PROP(IMPORTED);
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
@@ -1534,6 +1565,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
propCOMPILE_FEATURES,
propCOMPILE_OPTIONS,
propCOMPILE_DEFINITIONS,
+ propPRECOMPILE_HEADERS,
propLINK_OPTIONS,
propLINK_DIRECTORIES,
propIMPORTED,
@@ -1622,6 +1654,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const
output = cmJoin(impl->Utilities, ";");
return output.c_str();
}
+ if (prop == propPRECOMPILE_HEADERS) {
+ if (impl->PrecompileHeadersEntries.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output = cmJoin(impl->PrecompileHeadersEntries, ";");
+ return output.c_str();
+ }
if (prop == propIMPORTED) {
return this->IsImported() ? "TRUE" : "FALSE";
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2b75879..783c278 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -216,6 +216,8 @@ public:
cmListFileBacktrace const& bt, bool before = false);
void InsertLinkDirectory(std::string const& entry,
cmListFileBacktrace const& bt, bool before = false);
+ void InsertPrecompileHeader(std::string const& entry,
+ cmListFileBacktrace const& bt);
void AppendBuildInterfaceIncludes();
@@ -237,6 +239,9 @@ public:
cmStringRange GetCompileDefinitionsEntries() const;
cmBacktraceRange GetCompileDefinitionsBacktraces() const;
+ cmStringRange GetPrecompileHeadersEntries() const;
+ cmBacktraceRange GetPrecompileHeadersBacktraces() const;
+
cmStringRange GetSourceEntries() const;
cmBacktraceRange GetSourceBacktraces() const;
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
new file mode 100644
index 0000000..30cf1be
--- /dev/null
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -0,0 +1,36 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmTargetPrecompileHeadersCommand.h"
+
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
+#include "cmTarget.h"
+
+bool cmTargetPrecompileHeadersCommand::InitialPass(
+ std::vector<std::string> const& args, cmExecutionStatus&)
+{
+ return this->HandleArguments(args, "PRECOMPILE_HEADERS");
+}
+
+void cmTargetPrecompileHeadersCommand::HandleMissingTarget(
+ const std::string& name)
+{
+ const std::string e =
+ cmStrCat("Cannot specify precompile headers for target \"", name,
+ "\" which is not built by this project.");
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+}
+
+std::string cmTargetPrecompileHeadersCommand::Join(
+ const std::vector<std::string>& content)
+{
+ return cmJoin(content, ";");
+}
+
+bool cmTargetPrecompileHeadersCommand::HandleDirectContent(
+ cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
+{
+ tgt->AppendProperty("PRECOMPILE_HEADERS", this->Join(content).c_str());
+ return true;
+}
diff --git a/Source/cmTargetPrecompileHeadersCommand.h b/Source/cmTargetPrecompileHeadersCommand.h
new file mode 100644
index 0000000..1ddf2af
--- /dev/null
+++ b/Source/cmTargetPrecompileHeadersCommand.h
@@ -0,0 +1,41 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmTargetPrecompileHeadersCommand_h
+#define cmTargetPrecompileHeadersCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
+
+#include "cmTargetPropCommandBase.h"
+
+class cmExecutionStatus;
+class cmTarget;
+
+class cmTargetPrecompileHeadersCommand : public cmTargetPropCommandBase
+{
+public:
+ std::unique_ptr<cmCommand> Clone() override
+ {
+ return cm::make_unique<cmTargetPrecompileHeadersCommand>();
+ }
+
+ bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) override;
+
+private:
+ void HandleMissingTarget(const std::string& name) override;
+
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool system) override;
+
+ std::string Join(const std::vector<std::string>& content) override;
+};
+
+#endif
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 75cb413..333d4d5 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -102,8 +102,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Prepend with the emulator when cross compiling if required.
const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
if (emulator != nullptr && *emulator) {
- std::vector<std::string> emulatorWithArgs;
- cmExpandList(emulator, emulatorWithArgs);
+ std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 9e32226..a9be729 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -168,9 +168,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
return std::string();
}
- std::ostringstream ss;
- ss << static_cast<long int>(difftime(timeT, unixEpoch));
- return ss.str();
+ return std::to_string(static_cast<long int>(difftime(timeT, unixEpoch)));
}
default: {
return formatString;
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 1c892c7..24d0f0f 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -170,8 +170,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
const std::string& emulator =
this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
if (!emulator.empty()) {
- std::vector<std::string> emulatorWithArgs;
- cmExpandList(emulator, emulatorWithArgs);
+ std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
finalCommand +=
cmSystemTools::ConvertToRunCommandPath(emulatorWithArgs[0]);
finalCommand += " ";
diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx
index 3d83760..cfc00e8 100644
--- a/Source/cmUseMangledMesaCommand.cxx
+++ b/Source/cmUseMangledMesaCommand.cxx
@@ -5,26 +5,30 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cmExecutionStatus.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+namespace {
+void CopyAndFullPathMesaHeader(const std::string& source,
+ const std::string& outdir);
+}
-bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmUseMangledMesaCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// expected two arguments:
// argument one: the full path to gl_mangle.h
// argument two : directory for output of edited headers
if (args.size() != 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
const std::string& inputDir = args[0];
std::string glh = cmStrCat(inputDir, "/gl.h");
if (!cmSystemTools::FileExists(glh)) {
std::string e = cmStrCat("Bad path to Mesa, could not find: ", glh, ' ');
- this->SetError(e);
+ status.SetError(e);
return false;
}
const std::string& destDir = args[1];
@@ -37,14 +41,15 @@ bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args,
cmSystemTools::MakeDirectory(destDir);
for (std::string const& f : files) {
std::string path = cmStrCat(inputDir, '/', f);
- this->CopyAndFullPathMesaHeader(path, destDir);
+ CopyAndFullPathMesaHeader(path, destDir);
}
return true;
}
-void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader(
- const std::string& source, const std::string& outdir)
+namespace {
+void CopyAndFullPathMesaHeader(const std::string& source,
+ const std::string& outdir)
{
std::string dir;
std::string file;
@@ -96,3 +101,4 @@ void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader(
cmSystemTools::CopyFileIfDifferent(tempOutputFile, outFile);
cmSystemTools::RemoveFile(tempOutputFile);
}
+}
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index 1c01596..215e4a3 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -8,25 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmUseMangledMesaCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmUseMangledMesaCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- void CopyAndFullPathMesaHeader(const std::string& source,
- const std::string& outdir);
-};
+bool cmUseMangledMesaCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index d255b67..25fe4ad 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -4,20 +4,19 @@
#include <string.h>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmUtilitySourceCommand
-bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmUtilitySourceCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -25,15 +24,15 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// The first argument is the cache entry name.
std::string const& cacheEntry = *arg++;
- const char* cacheValue = this->Makefile->GetDefinition(cacheEntry);
+ const char* cacheValue = status.GetMakefile().GetDefinition(cacheEntry);
// If it exists already and appears up to date then we are done. If
// the string contains "(IntDir)" but that is not the
// CMAKE_CFG_INTDIR setting then the value is out of date.
std::string const& intDir =
- this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
+ status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR");
bool haveCacheValue = false;
- if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING")) {
+ if (status.GetMakefile().IsOn("CMAKE_CROSSCOMPILING")) {
haveCacheValue = (cacheValue != nullptr);
if (!haveCacheValue) {
std::string msg = cmStrCat(
@@ -44,7 +43,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
cmSystemTools::Message(msg, "Warning");
}
} else {
- cmState* state = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
haveCacheValue = (cacheValue &&
(strstr(cacheValue, "(IntDir)") == nullptr ||
(intDir == "$(IntDir)")) &&
@@ -63,7 +62,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// The third argument specifies the relative directory of the source
// of the utility.
std::string const& relativeSource = *arg++;
- std::string utilitySource = this->Makefile->GetCurrentSourceDirectory();
+ std::string utilitySource = status.GetMakefile().GetCurrentSourceDirectory();
utilitySource = utilitySource + "/" + relativeSource;
// If the directory doesn't exist, the source has not been included.
@@ -81,11 +80,12 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// The source exists.
const std::string& cmakeCFGout =
- this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
- std::string utilityDirectory = this->Makefile->GetCurrentBinaryDirectory();
+ status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR");
+ std::string utilityDirectory =
+ status.GetMakefile().GetCurrentBinaryDirectory();
std::string exePath;
- if (this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
- exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
+ if (status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
+ exePath = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH");
}
if (!exePath.empty()) {
utilityDirectory = exePath;
@@ -95,21 +95,22 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// Construct the cache entry for the executable's location.
std::string utilityExecutable = utilityDirectory + "/" + cmakeCFGout + "/" +
- utilityName + this->Makefile->GetDefinition("CMAKE_EXECUTABLE_SUFFIX");
+ utilityName +
+ status.GetMakefile().GetDefinition("CMAKE_EXECUTABLE_SUFFIX");
// make sure we remove any /./ in the name
cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
// Enter the value into the cache.
- this->Makefile->AddCacheDefinition(cacheEntry, utilityExecutable.c_str(),
- "Path to an internal program.",
- cmStateEnums::FILEPATH);
+ status.GetMakefile().AddCacheDefinition(
+ cacheEntry, utilityExecutable.c_str(), "Path to an internal program.",
+ cmStateEnums::FILEPATH);
// add a value into the cache that maps from the
// full path to the name of the project
cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
- this->Makefile->AddCacheDefinition(utilityExecutable, utilityName.c_str(),
- "Executable to project name.",
- cmStateEnums::INTERNAL);
+ status.GetMakefile().AddCacheDefinition(
+ utilityExecutable, utilityName.c_str(), "Executable to project name.",
+ cmStateEnums::INTERNAL);
return true;
}
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index cef7fed..934d539 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmUtilitySourceCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmUtilitySourceCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmUtilitySourceCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 1bda54a..ad46c75 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -74,26 +74,8 @@ class SmartBSTR
{
public:
SmartBSTR() { str = NULL; }
- SmartBSTR(const SmartBSTR& src)
- {
- if (src.str != NULL) {
- str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str));
- } else {
- str = ::SysAllocStringByteLen(NULL, 0);
- }
- }
- SmartBSTR& operator=(const SmartBSTR& src)
- {
- if (str != src.str) {
- ::SysFreeString(str);
- if (src.str != NULL) {
- str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str));
- } else {
- str = ::SysAllocStringByteLen(NULL, 0);
- }
- }
- return *this;
- }
+ SmartBSTR(const SmartBSTR& src) = delete;
+ SmartBSTR& operator=(const SmartBSTR& src) = delete;
operator BSTR() const { return str; }
BSTR* operator&() throw() { return &str; }
~SmartBSTR() throw() { ::SysFreeString(str); }
diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx
index c44eeca..6b93c63 100644
--- a/Source/cmVariableRequiresCommand.cxx
+++ b/Source/cmVariableRequiresCommand.cxx
@@ -2,33 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableRequiresCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmLibraryCommand
-bool cmVariableRequiresCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmVariableRequiresCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string const& testVariable = args[0];
- if (!this->Makefile->IsOn(testVariable)) {
+ if (!status.GetMakefile().IsOn(testVariable)) {
return true;
}
std::string const& resultVariable = args[1];
bool requirementsMet = true;
std::string notSet;
bool hasAdvanced = false;
- cmState* state = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
for (unsigned int i = 2; i < args.size(); ++i) {
- if (!this->Makefile->IsOn(args[i])) {
+ if (!status.GetMakefile().IsOn(args[i])) {
requirementsMet = false;
notSet += args[i];
notSet += "\n";
@@ -38,12 +37,12 @@ bool cmVariableRequiresCommand::InitialPass(
}
}
}
- const char* reqVar = this->Makefile->GetDefinition(resultVariable);
+ const char* reqVar = status.GetMakefile().GetDefinition(resultVariable);
// if reqVar is unset, then set it to requirementsMet
// if reqVar is set to true, but requirementsMet is false , then
// set reqVar to false.
- if (!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar))) {
- this->Makefile->AddDefinitionBool(resultVariable, requirementsMet);
+ if (!reqVar || (!requirementsMet && status.GetMakefile().IsOn(reqVar))) {
+ status.GetMakefile().AddDefinitionBool(resultVariable, requirementsMet);
}
if (!requirementsMet) {
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index 38e7490..fb0520e 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmVariableRequiresCommand : public cmCommand
-{
-public:
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmVariableRequiresCommand>();
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmVariableRequiresCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index c5cf9a7..b4f05c7 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -249,6 +249,8 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
this->Makefile->GetCurrentBinaryDirectory());
+
+ this->LocalGenerator->AddPchDependencies(target, "");
}
cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -851,8 +853,8 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
const char* imports =
this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
if (imports) {
- std::vector<std::string> argsSplit;
- cmExpandList(std::string(imports), argsSplit, false);
+ std::vector<std::string> argsSplit =
+ cmExpandedList(std::string(imports), false);
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -1115,7 +1117,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
std::string configType;
if (const char* vsConfigurationType =
this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
- configType = vsConfigurationType;
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(vsConfigurationType);
+ configType = cge->Evaluate(this->LocalGenerator, c);
} else {
switch (this->GeneratorTarget->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
@@ -2145,6 +2150,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
this->OutputSourceSpecificFlags(e2, si.Source);
}
+ if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
+ e2.Element("PrecompiledHeader", "NotUsing");
+ }
if (!exclude_configs.empty()) {
this->WriteExcludeFromBuild(e2, exclude_configs);
}
@@ -2626,6 +2634,13 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->IPOEnabledConfigurations.insert(configName);
}
+ // Precompile Headers
+ std::string pchHeader =
+ this->GeneratorTarget->GetPchHeader(configName, linkLanguage);
+ if (this->MSTools && vcxproj == this->ProjectType && pchHeader.empty()) {
+ clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+ }
+
// Get preprocessor definitions for this directory.
std::string defineFlags = this->Makefile->GetDefineFlags();
if (this->MSTools) {
@@ -2641,7 +2656,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
// replace this setting with "true" below.
clOptions.AddFlag("UseFullPaths", "false");
}
- clOptions.AddFlag("PrecompiledHeader", "NotUsing");
clOptions.AddFlag("AssemblerListingLocation", "$(IntDir)");
}
}
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index 0b3962e..a1c64ed 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -214,8 +214,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (const char* argList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
- std::vector<std::string> arguments;
- cmExpandList(argList, arguments);
+ std::vector<std::string> arguments = cmExpandedList(argList);
if (!arguments.empty()) {
xout.StartElement("CommandLineArguments");
@@ -235,8 +234,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (const char* envList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
- std::vector<std::string> envs;
- cmExpandList(envList, envs);
+ std::vector<std::string> envs = cmExpandedList(envList);
if (!envs.empty()) {
xout.StartElement("EnvironmentVariables");
diff --git a/Source/cm_optional.hxx b/Source/cm_optional.hxx
new file mode 100644
index 0000000..295571d
--- /dev/null
+++ b/Source/cm_optional.hxx
@@ -0,0 +1,343 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cm_optional_hxx
+#define cm_optional_hxx
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+# define CMake_HAVE_CXX_OPTIONAL
+#endif
+
+#if defined(CMake_HAVE_CXX_OPTIONAL)
+# include <optional>
+#else
+# include "cm_utility.hxx"
+# include <memory>
+# include <utility>
+#endif
+
+namespace cm {
+
+#if defined(CMake_HAVE_CXX_OPTIONAL)
+
+using std::nullopt_t;
+using std::nullopt;
+using std::optional;
+using std::bad_optional_access;
+using std::make_optional;
+
+#else
+
+class bad_optional_access : public std::exception
+{
+ using std::exception::exception;
+};
+
+struct nullopt_t
+{
+ explicit constexpr nullopt_t(int) {}
+};
+
+constexpr nullopt_t nullopt{ 0 };
+
+template <typename T>
+class optional
+{
+public:
+ using value_type = T;
+
+ optional() noexcept = default;
+ optional(nullopt_t) noexcept;
+ optional(const optional& other);
+ optional(optional&& other) noexcept;
+
+ template <typename... Args>
+ explicit optional(cm::in_place_t, Args&&... args);
+
+ template <
+ typename U = T,
+ typename = typename std::enable_if<
+ std::is_constructible<T, U&&>::value &&
+ !std::is_same<typename std::decay<U>::type, cm::in_place_t>::value &&
+ !std::is_same<typename std::decay<U>::type,
+ cm::optional<T>>::value>::type>
+ optional(U&& v);
+
+ ~optional();
+
+ optional& operator=(nullopt_t) noexcept;
+ optional& operator=(const optional& other);
+ optional& operator=(optional&& other) noexcept;
+
+ template <
+ typename U = T,
+ typename = typename std::enable_if<
+ !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
+ std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value &&
+ (!std::is_scalar<T>::value ||
+ !std::is_same<typename std::decay<U>::type, T>::value)>::type>
+ optional& operator=(U&& v);
+
+ const T* operator->() const;
+ T* operator->();
+ const T& operator*() const&;
+ T& operator*() &;
+ const T&& operator*() const&&;
+ T&& operator*() &&;
+
+ explicit operator bool() const noexcept;
+ bool has_value() const noexcept;
+
+ T& value() &;
+ const T& value() const&;
+
+ T&& value() &&;
+ const T&& value() const&&;
+
+ template <typename U>
+ T value_or(U&& default_value) const&;
+
+ template <typename U>
+ T value_or(U&& default_value) &&;
+
+ void swap(optional& other) noexcept;
+ void reset() noexcept;
+
+ template <typename... Args>
+ T& emplace(Args&&... args);
+
+private:
+ bool _has_value = false;
+ std::allocator<T> _allocator;
+ union _mem_union
+ {
+ T value;
+
+ // Explicit constructor and destructor is required to make this work
+ _mem_union() noexcept {}
+ ~_mem_union() noexcept {}
+ } _mem;
+};
+
+template <typename T>
+optional<typename std::decay<T>::type> make_optional(T&& value)
+{
+ return optional<typename std::decay<T>::type>(std::forward<T>(value));
+}
+
+template <typename T, class... Args>
+optional<T> make_optional(Args&&... args)
+{
+ return optional<T>(in_place, std::forward<Args>(args)...);
+}
+
+template <typename T>
+optional<T>::optional(nullopt_t) noexcept
+{
+}
+
+template <typename T>
+optional<T>::optional(const optional& other)
+{
+ *this = other;
+}
+
+template <typename T>
+optional<T>::optional(optional&& other) noexcept
+{
+ *this = std::move(other);
+}
+
+template <typename T>
+template <typename... Args>
+optional<T>::optional(cm::in_place_t, Args&&... args)
+{
+ this->emplace(std::forward<Args>(args)...);
+}
+
+template <typename T>
+template <typename U, typename>
+optional<T>::optional(U&& v)
+{
+ this->emplace(std::forward<U>(v));
+}
+
+template <typename T>
+optional<T>::~optional()
+{
+ this->reset();
+}
+
+template <typename T>
+optional<T>& optional<T>::operator=(nullopt_t) noexcept
+{
+ this->reset();
+ return *this;
+}
+
+template <typename T>
+optional<T>& optional<T>::operator=(const optional& other)
+{
+ if (other.has_value()) {
+ if (this->has_value()) {
+ this->value() = *other;
+ } else {
+ this->emplace(*other);
+ }
+ } else {
+ this->reset();
+ }
+ return *this;
+}
+
+template <typename T>
+optional<T>& optional<T>::operator=(optional&& other) noexcept
+{
+ if (other.has_value()) {
+ if (this->has_value()) {
+ this->value() = std::move(*other);
+ } else {
+ this->emplace(std::move(*other));
+ }
+ } else {
+ this->reset();
+ }
+ return *this;
+}
+
+template <typename T>
+template <typename U, typename>
+optional<T>& optional<T>::operator=(U&& v)
+{
+ if (this->has_value()) {
+ this->value() = v;
+ } else {
+ this->emplace(std::forward<U>(v));
+ }
+ return *this;
+}
+
+template <typename T>
+const T* optional<T>::operator->() const
+{
+ return &**this;
+}
+
+template <typename T>
+T* optional<T>::operator->()
+{
+ return &**this;
+}
+
+template <typename T>
+const T& optional<T>::operator*() const&
+{
+ return this->_mem.value;
+}
+
+template <typename T>
+T& optional<T>::operator*() &
+{
+ return this->_mem.value;
+}
+
+template <typename T>
+const T&& optional<T>::operator*() const&&
+{
+ return std::move(**this);
+}
+
+template <typename T>
+T&& optional<T>::operator*() &&
+{
+ return std::move(**this);
+}
+
+template <typename T>
+bool optional<T>::has_value() const noexcept
+{
+ return this->_has_value;
+}
+
+template <typename T>
+optional<T>::operator bool() const noexcept
+{
+ return this->has_value();
+}
+
+template <typename T>
+T& optional<T>::value() &
+{
+ if (!this->has_value()) {
+ throw cm::bad_optional_access{};
+ }
+ return **this;
+}
+
+template <typename T>
+const T& optional<T>::value() const&
+{
+ if (!this->has_value()) {
+ throw cm::bad_optional_access{};
+ }
+ return **this;
+}
+
+template <typename T>
+template <typename U>
+T optional<T>::value_or(U&& default_value) const&
+{
+ return bool(*this) ? **this : static_cast<T>(std::forward<U>(default_value));
+}
+
+template <typename T>
+template <typename U>
+T optional<T>::value_or(U&& default_value) &&
+{
+ return bool(*this) ? std::move(**this)
+ : static_cast<T>(std::forward<U>(default_value));
+}
+
+template <typename T>
+void optional<T>::swap(optional& other) noexcept
+{
+ if (this->has_value()) {
+ if (other.has_value()) {
+ using std::swap;
+ swap(**this, *other);
+ } else {
+ other.emplace(std::move(**this));
+ this->reset();
+ }
+ } else if (other.has_value()) {
+ this->emplace(std::move(*other));
+ other.reset();
+ }
+}
+
+template <typename T>
+void optional<T>::reset() noexcept
+{
+ if (this->has_value()) {
+ this->_has_value = false;
+ std::allocator_traits<std::allocator<T>>::destroy(this->_allocator,
+ &**this);
+ }
+}
+
+template <typename T>
+template <typename... Args>
+T& optional<T>::emplace(Args&&... args)
+{
+ this->reset();
+ std::allocator_traits<std::allocator<T>>::construct(
+ this->_allocator, &**this, std::forward<Args>(args)...);
+ this->_has_value = true;
+ return this->value();
+}
+
+#endif
+}
+
+#endif
diff --git a/Source/cm_utility.hxx b/Source/cm_utility.hxx
new file mode 100644
index 0000000..99d7f8b
--- /dev/null
+++ b/Source/cm_utility.hxx
@@ -0,0 +1,35 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cm_utility_hxx
+#define cm_utility_hxx
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+# define CMake_HAVE_CXX_IN_PLACE
+#endif
+
+#if defined(CMake_HAVE_CXX_IN_PLACE)
+# include <utility>
+#endif
+
+namespace cm {
+
+#if defined(CMake_HAVE_CXX_IN_PLACE)
+
+using std::in_place_t;
+using std::in_place;
+
+#else
+
+struct in_place_t
+{
+ explicit in_place_t() = default;
+};
+
+constexpr in_place_t in_place{};
+
+#endif
+}
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a5c8d46..1746082 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -431,6 +431,11 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
// Register fake project commands that hint misuse in script mode.
GetProjectCommandsInScriptMode(this->GetState());
+ // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
+ // set to $PWD for -P mode.
+ this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeOutputDirectory(
+ cmSystemTools::GetCurrentWorkingDirectory());
this->ReadListFile(args, path);
} else if (arg.find("--find-package", 0) == 0) {
findPackageMode = true;
@@ -460,15 +465,9 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
// read in the list file to fill the cache
if (!path.empty()) {
this->CurrentSnapshot = this->State->Reset();
- std::string homeDir = this->GetHomeDirectory();
- std::string homeOutputDir = this->GetHomeOutputDirectory();
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
cmStateSnapshot snapshot = this->GetCurrentSnapshot();
- snapshot.GetDirectory().SetCurrentBinary(
- cmSystemTools::GetCurrentWorkingDirectory());
- snapshot.GetDirectory().SetCurrentSource(
- cmSystemTools::GetCurrentWorkingDirectory());
+ snapshot.GetDirectory().SetCurrentBinary(this->GetHomeOutputDirectory());
+ snapshot.GetDirectory().SetCurrentSource(this->GetHomeDirectory());
snapshot.SetDefaultDefinitions();
cmMakefile mf(gg, snapshot);
if (this->GetWorkingMode() != NORMAL_MODE) {
@@ -481,8 +480,6 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
if (!mf.ReadListFile(path)) {
cmSystemTools::Error("Error processing file: " + path);
}
- this->SetHomeDirectory(homeDir);
- this->SetHomeOutputDirectory(homeOutputDir);
}
// free generic one if generated
@@ -531,8 +528,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
}
} else if (mode == "COMPILE") {
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
- std::vector<std::string> includeDirs;
- cmExpandList(includes, includeDirs);
+ std::vector<std::string> includeDirs = cmExpandedList(includes);
gg->CreateGenerationObjects();
cmLocalGenerator* lg = gg->LocalGenerators[0];
@@ -548,8 +544,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
tgt->SetProperty("LINKER_LANGUAGE", language.c_str());
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
- std::vector<std::string> libList;
- cmExpandList(libs, libList);
+ std::vector<std::string> libList = cmExpandedList(libs);
for (std::string const& lib : libList) {
tgt->AddLinkLibrary(*mf, lib, GENERAL_LibraryType);
}
@@ -1264,8 +1259,7 @@ struct SaveCacheEntry
int cmake::HandleDeleteCacheVariables(const std::string& var)
{
- std::vector<std::string> argsSplit;
- cmExpandList(std::string(var), argsSplit, true);
+ std::vector<std::string> argsSplit = cmExpandedList(std::string(var), true);
// erase the property to avoid infinite recursion
this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
if (this->State->GetIsInTryCompile()) {
@@ -2106,9 +2100,7 @@ int cmake::CheckBuildSystem()
// If no file is provided for the check, we have to rerun.
if (this->CheckBuildSystemArgument.empty()) {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake no build system arguments\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout("Re-run cmake no build system arguments\n");
}
return 1;
}
@@ -2191,10 +2183,8 @@ int cmake::CheckBuildSystem()
if (depends.empty() || outputs.empty()) {
// Not enough information was provided to do the test. Just rerun.
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
- "or CMAKE_MAKEFILE_OUTPUTS :\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout("Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
+ "or CMAKE_MAKEFILE_OUTPUTS :\n");
}
return 1;
}
@@ -2210,9 +2200,8 @@ int cmake::CheckBuildSystem()
}
} else {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake: build system dependency is missing\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ "Re-run cmake: build system dependency is missing\n");
}
return 1;
}
@@ -2229,9 +2218,8 @@ int cmake::CheckBuildSystem()
}
} else {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake: build system output is missing\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ "Re-run cmake: build system output is missing\n");
}
return 1;
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 0832e2f..2be8bae 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -172,8 +172,7 @@ static int HandleIWYU(const std::string& runCmd,
{
// Construct the iwyu command line by taking what was given
// and adding all the arguments we give to the compiler.
- std::vector<std::string> iwyu_cmd;
- cmExpandList(runCmd, iwyu_cmd, true);
+ std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
cmAppend(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
// Run the iwyu command line. Capture its stderr and hide its stdout.
// Ignore its return code because the tool always returns non-zero.
@@ -262,8 +261,7 @@ static int HandleCppLint(const std::string& runCmd,
const std::vector<std::string>&)
{
// Construct the cpplint command line.
- std::vector<std::string> cpplint_cmd;
- cmExpandList(runCmd, cpplint_cmd, true);
+ std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
cpplint_cmd.push_back(sourceFile);
// Run the cpplint command line. Capture its output.
@@ -291,8 +289,7 @@ static int HandleCppCheck(const std::string& runCmd,
const std::vector<std::string>& orig_cmd)
{
// Construct the cpplint command line.
- std::vector<std::string> cppcheck_cmd;
- cmExpandList(runCmd, cppcheck_cmd, true);
+ std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
// extract all the -D, -U, and -I options from the compile line
for (auto const& opt : orig_cmd) {
if (opt.size() > 2) {
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 77a84fd..a69ba15 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -83,7 +83,9 @@ static const char* cmDocumentationOptions[][2] = {
{ "-T <action>, --test-action <action>",
"Sets the dashboard action to "
"perform" },
- { "--track <track>", "Specify the track to submit dashboard to" },
+ { "--group <group>",
+ "Specify what build group on the dashboard you'd like to "
+ "submit results to." },
{ "-S <script>, --script <script>",
"Execute a dashboard for a "
"configuration" },
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index cd4dbc8..204810e 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -9,6 +9,7 @@ set(CMakeLib_TESTS
testGeneratedFileStream.cxx
testRST.cxx
testRange.cxx
+ testOptional.cxx
testString.cxx
testStringAlgorithms.cxx
testSystemTools.cxx
diff --git a/Tests/CMakeLib/testOptional.cxx b/Tests/CMakeLib/testOptional.cxx
new file mode 100644
index 0000000..a5e30fb
--- /dev/null
+++ b/Tests/CMakeLib/testOptional.cxx
@@ -0,0 +1,690 @@
+#include "cm_optional.hxx"
+#include "cm_utility.hxx"
+
+#include <iostream>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+class EventLogger;
+
+class Event
+{
+public:
+ enum EventType
+ {
+ DEFAULT_CONSTRUCT,
+ COPY_CONSTRUCT,
+ MOVE_CONSTRUCT,
+ VALUE_CONSTRUCT,
+
+ DESTRUCT,
+
+ COPY_ASSIGN,
+ MOVE_ASSIGN,
+ VALUE_ASSIGN,
+
+ REFERENCE,
+ CONST_REFERENCE,
+ RVALUE_REFERENCE,
+ CONST_RVALUE_REFERENCE,
+
+ SWAP,
+ };
+
+ EventType Type;
+ const EventLogger* Logger1;
+ const EventLogger* Logger2;
+ int Value;
+
+ bool operator==(const Event& other) const;
+ bool operator!=(const Event& other) const;
+};
+
+bool Event::operator==(const Event& other) const
+{
+ return this->Type == other.Type && this->Logger1 == other.Logger1 &&
+ this->Logger2 == other.Logger2 && this->Value == other.Value;
+}
+
+bool Event::operator!=(const Event& other) const
+{
+ return !(*this == other);
+}
+
+static std::vector<Event> events;
+
+class EventLogger
+{
+public:
+ EventLogger();
+ EventLogger(const EventLogger& other);
+ EventLogger(EventLogger&& other);
+ EventLogger(int value);
+
+ ~EventLogger();
+
+ EventLogger& operator=(const EventLogger& other);
+ EventLogger& operator=(EventLogger&& other);
+ EventLogger& operator=(int value);
+
+ void Reference() &;
+ void Reference() const&;
+ void Reference() &&;
+ void Reference() const&&;
+
+ int Value = 0;
+};
+
+// Certain builds of GCC generate false -Wmaybe-uninitialized warnings when
+// doing a release build with the system version of std::optional. These
+// warnings do not manifest when using our own cm::optional implementation.
+// Silence these false warnings.
+#if defined(__GNUC__) && !defined(__clang__)
+# define BEGIN_IGNORE_UNINITIALIZED \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define END_IGNORE_UNINITIALIZED _Pragma("GCC diagnostic pop")
+#else
+# define BEGIN_IGNORE_UNINITIALIZED
+# define END_IGNORE_UNINITIALIZED
+#endif
+
+void swap(EventLogger& e1, EventLogger& e2)
+{
+ BEGIN_IGNORE_UNINITIALIZED
+ events.push_back({ Event::SWAP, &e1, &e2, e2.Value });
+ END_IGNORE_UNINITIALIZED
+ auto tmp = e1.Value;
+ e1.Value = e2.Value;
+ e2.Value = tmp;
+}
+
+EventLogger::EventLogger()
+ : Value(0)
+{
+ events.push_back({ Event::DEFAULT_CONSTRUCT, this, nullptr, 0 });
+}
+
+EventLogger::EventLogger(const EventLogger& other)
+ : Value(other.Value)
+{
+ events.push_back({ Event::COPY_CONSTRUCT, this, &other, other.Value });
+}
+
+BEGIN_IGNORE_UNINITIALIZED
+EventLogger::EventLogger(EventLogger&& other)
+ : Value(other.Value)
+{
+ events.push_back({ Event::MOVE_CONSTRUCT, this, &other, other.Value });
+}
+END_IGNORE_UNINITIALIZED
+
+EventLogger::EventLogger(int value)
+ : Value(value)
+{
+ events.push_back({ Event::VALUE_CONSTRUCT, this, nullptr, value });
+}
+
+EventLogger::~EventLogger()
+{
+ BEGIN_IGNORE_UNINITIALIZED
+ events.push_back({ Event::DESTRUCT, this, nullptr, this->Value });
+ END_IGNORE_UNINITIALIZED
+}
+
+EventLogger& EventLogger::operator=(const EventLogger& other)
+{
+ events.push_back({ Event::COPY_ASSIGN, this, &other, other.Value });
+ this->Value = other.Value;
+ return *this;
+}
+
+EventLogger& EventLogger::operator=(EventLogger&& other)
+{
+ events.push_back({ Event::MOVE_ASSIGN, this, &other, other.Value });
+ this->Value = other.Value;
+ return *this;
+}
+
+EventLogger& EventLogger::operator=(int value)
+{
+ events.push_back({ Event::VALUE_ASSIGN, this, nullptr, value });
+ this->Value = value;
+ return *this;
+}
+
+void EventLogger::Reference() &
+{
+ events.push_back({ Event::REFERENCE, this, nullptr, this->Value });
+}
+
+void EventLogger::Reference() const&
+{
+ events.push_back({ Event::CONST_REFERENCE, this, nullptr, this->Value });
+}
+
+void EventLogger::Reference() &&
+{
+ events.push_back({ Event::RVALUE_REFERENCE, this, nullptr, this->Value });
+}
+
+void EventLogger::Reference() const&&
+{
+ events.push_back(
+ { Event::CONST_RVALUE_REFERENCE, this, nullptr, this->Value });
+}
+
+static bool testDefaultConstruct(std::vector<Event>& expected)
+{
+ const cm::optional<EventLogger> o{};
+
+ expected = {};
+ return true;
+}
+
+static bool testNulloptConstruct(std::vector<Event>& expected)
+{
+ const cm::optional<EventLogger> o{ cm::nullopt };
+
+ expected = {};
+ return true;
+}
+
+static bool testValueConstruct(std::vector<Event>& expected)
+{
+ const cm::optional<EventLogger> o{ 4 };
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
+ { Event::DESTRUCT, &*o, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testInPlaceConstruct(std::vector<Event>& expected)
+{
+ const cm::optional<EventLogger> o1{ cm::in_place, 4 };
+ const cm::optional<EventLogger> o2{ cm::in_place_t{}, 4 };
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 4 },
+ { Event::DESTRUCT, &*o2, nullptr, 4 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testCopyConstruct(std::vector<Event>& expected)
+{
+ const cm::optional<EventLogger> o1{ 4 };
+ const cm::optional<EventLogger> o2{ o1 };
+ const cm::optional<EventLogger> o3{};
+ const cm::optional<EventLogger> o4{ o3 };
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::COPY_CONSTRUCT, &*o2, &o1.value(), 4 },
+ { Event::DESTRUCT, &*o2, nullptr, 4 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testMoveConstruct(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o1{ 4 };
+ const cm::optional<EventLogger> o2{ std::move(o1) };
+ cm::optional<EventLogger> o3{};
+ const cm::optional<EventLogger> o4{ std::move(o3) };
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::MOVE_CONSTRUCT, &*o2, &o1.value(), 4 },
+ { Event::DESTRUCT, &*o2, nullptr, 4 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testNulloptAssign(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o1{ 4 };
+ o1 = cm::nullopt;
+ cm::optional<EventLogger> o2{};
+ o2 = cm::nullopt;
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testCopyAssign(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o1{};
+ const cm::optional<EventLogger> o2{ 4 };
+ o1 = o2;
+ const cm::optional<EventLogger> o3{ 5 };
+ o1 = o3;
+ const cm::optional<EventLogger> o4{};
+ o1 = o4;
+ o1 = o4; // Intentionally duplicated to test assigning an empty optional to
+ // an empty optional
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 4 },
+ { Event::COPY_CONSTRUCT, &*o1, &*o2, 4 },
+ { Event::VALUE_CONSTRUCT, &*o3, nullptr, 5 },
+ { Event::COPY_ASSIGN, &*o1, &*o3, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 5 },
+ { Event::DESTRUCT, &o3.value(), nullptr, 5 },
+ { Event::DESTRUCT, &o2.value(), nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testMoveAssign(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o1{};
+ cm::optional<EventLogger> o2{ 4 };
+ o1 = std::move(o2);
+ cm::optional<EventLogger> o3{ 5 };
+ o1 = std::move(o3);
+ cm::optional<EventLogger> o4{};
+ o1 = std::move(o4);
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 4 },
+ { Event::MOVE_CONSTRUCT, &*o1, &*o2, 4 },
+ { Event::VALUE_CONSTRUCT, &*o3, nullptr, 5 },
+ { Event::MOVE_ASSIGN, &*o1, &*o3, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 5 },
+ { Event::DESTRUCT, &*o3, nullptr, 5 },
+ { Event::DESTRUCT, &*o2, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testPointer(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o1{ 4 };
+ const cm::optional<EventLogger> o2{ 5 };
+
+ o1->Reference();
+ o2->Reference();
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
+ { Event::REFERENCE, &*o1, nullptr, 4 },
+ { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return true;
+}
+
+#if !__GNUC__ || __GNUC__ > 4
+# define ALLOW_CONST_RVALUE
+#endif
+
+static bool testDereference(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o1{ 4 };
+ const cm::optional<EventLogger> o2{ 5 };
+
+ (*o1).Reference();
+ (*o2).Reference();
+ (*std::move(o1)).Reference();
+#ifdef ALLOW_CONST_RVALUE
+ (*std::move(o2)).Reference(); // Broken in GCC 4.9.0. Sigh...
+#endif
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
+ { Event::REFERENCE, &*o1, nullptr, 4 },
+ { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
+ { Event::RVALUE_REFERENCE, &*o1, nullptr, 4 },
+#ifdef ALLOW_CONST_RVALUE
+ { Event::CONST_RVALUE_REFERENCE, &*o2, nullptr, 5 },
+#endif
+ { Event::DESTRUCT, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testHasValue(std::vector<Event>& expected)
+{
+ bool retval = true;
+
+ const cm::optional<EventLogger> o1{ 4 };
+ const cm::optional<EventLogger> o2{};
+
+ if (!o1.has_value()) {
+ std::cout << "o1 should have a value" << std::endl;
+ retval = false;
+ }
+
+ if (!o1) {
+ std::cout << "(bool)o1 should be true" << std::endl;
+ retval = false;
+ }
+
+ if (o2.has_value()) {
+ std::cout << "o2 should not have a value" << std::endl;
+ retval = false;
+ }
+
+ if (o2) {
+ std::cout << "(bool)o2 should be false" << std::endl;
+ retval = false;
+ }
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return retval;
+}
+
+static bool testValue(std::vector<Event>& expected)
+{
+ bool retval = true;
+
+ cm::optional<EventLogger> o1{ 4 };
+ const cm::optional<EventLogger> o2{ 5 };
+ cm::optional<EventLogger> o3{};
+ const cm::optional<EventLogger> o4{};
+
+ o1.value().Reference();
+ o2.value().Reference();
+
+ bool thrown = false;
+ try {
+ (void)o3.value();
+ } catch (cm::bad_optional_access&) {
+ thrown = true;
+ }
+ if (!thrown) {
+ std::cout << "o3.value() did not throw" << std::endl;
+ retval = false;
+ }
+
+ thrown = false;
+ try {
+ (void)o4.value();
+ } catch (cm::bad_optional_access&) {
+ thrown = true;
+ }
+ if (!thrown) {
+ std::cout << "o4.value() did not throw" << std::endl;
+ retval = false;
+ }
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
+ { Event::REFERENCE, &*o1, nullptr, 4 },
+ { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ };
+ return retval;
+}
+
+static bool testValueOr()
+{
+ bool retval = true;
+
+ const cm::optional<EventLogger> o1{ 4 };
+ cm::optional<EventLogger> o2{ 5 };
+ const cm::optional<EventLogger> o3{};
+ cm::optional<EventLogger> o4{};
+
+ EventLogger e1{ 6 };
+ EventLogger e2{ 7 };
+ EventLogger e3{ 8 };
+ EventLogger e4{ 9 };
+
+ EventLogger r1 = o1.value_or(e1);
+ if (r1.Value != 4) {
+ std::cout << "r1.Value should be 4" << std::endl;
+ retval = false;
+ }
+ EventLogger r2 = std::move(o2).value_or(e2);
+ if (r2.Value != 5) {
+ std::cout << "r2.Value should be 5" << std::endl;
+ retval = false;
+ }
+ EventLogger r3 = o3.value_or(e3);
+ if (r3.Value != 8) {
+ std::cout << "r3.Value should be 8" << std::endl;
+ retval = false;
+ }
+ EventLogger r4 = std::move(o4).value_or(e4);
+ if (r4.Value != 9) {
+ std::cout << "r4.Value should be 9" << std::endl;
+ retval = false;
+ }
+
+ return retval;
+}
+
+static bool testSwap(std::vector<Event>& expected)
+{
+ bool retval = true;
+
+ cm::optional<EventLogger> o1{ 4 };
+ cm::optional<EventLogger> o2{};
+
+ o1.swap(o2);
+
+ if (o1.has_value()) {
+ std::cout << "o1 should not have value" << std::endl;
+ retval = false;
+ }
+ if (!o2.has_value()) {
+ std::cout << "o2 should have value" << std::endl;
+ retval = false;
+ }
+ if (o2.value().Value != 4) {
+ std::cout << "value of o2 should be 4" << std::endl;
+ retval = false;
+ }
+
+ o1.swap(o2);
+
+ if (!o1.has_value()) {
+ std::cout << "o1 should have value" << std::endl;
+ retval = false;
+ }
+ if (o1.value().Value != 4) {
+ std::cout << "value of o1 should be 4" << std::endl;
+ retval = false;
+ }
+ if (o2.has_value()) {
+ std::cout << "o2 should not have value" << std::endl;
+ retval = false;
+ }
+
+ o2.emplace(5);
+ o1.swap(o2);
+
+ if (!o1.has_value()) {
+ std::cout << "o1 should have value" << std::endl;
+ retval = false;
+ }
+ if (o1.value().Value != 5) {
+ std::cout << "value of o1 should be 5" << std::endl;
+ retval = false;
+ }
+ if (!o2.has_value()) {
+ std::cout << "o2 should not have value" << std::endl;
+ retval = false;
+ }
+ if (o2.value().Value != 4) {
+ std::cout << "value of o2 should be 4" << std::endl;
+ retval = false;
+ }
+
+ o1.reset();
+ o2.reset();
+ o1.swap(o2);
+
+ if (o1.has_value()) {
+ std::cout << "o1 should not have value" << std::endl;
+ retval = false;
+ }
+ if (o2.has_value()) {
+ std::cout << "o2 should not have value" << std::endl;
+ retval = false;
+ }
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
+ { Event::MOVE_CONSTRUCT, &*o2, &*o1, 4 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ { Event::MOVE_CONSTRUCT, &*o1, &*o2, 4 },
+ { Event::DESTRUCT, &*o2, nullptr, 4 },
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
+ { Event::SWAP, &*o1, &*o2, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 5 },
+ { Event::DESTRUCT, &*o2, nullptr, 4 },
+ };
+ return retval;
+}
+
+static bool testReset(std::vector<Event>& expected)
+{
+ bool retval = true;
+
+ cm::optional<EventLogger> o{ 4 };
+
+ o.reset();
+
+ if (o.has_value()) {
+ std::cout << "o should not have value" << std::endl;
+ retval = false;
+ }
+
+ o.reset();
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
+ { Event::DESTRUCT, &*o, nullptr, 4 },
+ };
+ return retval;
+}
+
+static bool testEmplace(std::vector<Event>& expected)
+{
+ cm::optional<EventLogger> o{ 4 };
+
+ o.emplace(5);
+ o.reset();
+ o.emplace();
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
+ { Event::DESTRUCT, &*o, nullptr, 4 },
+ { Event::VALUE_CONSTRUCT, &*o, nullptr, 5 },
+ { Event::DESTRUCT, &*o, nullptr, 5 },
+ { Event::DEFAULT_CONSTRUCT, &*o, nullptr, 0 },
+ { Event::DESTRUCT, &*o, nullptr, 0 },
+ };
+ return true;
+}
+
+static bool testMakeOptional(std::vector<Event>& expected)
+{
+ EventLogger e{ 4 };
+ cm::optional<EventLogger> o1 = cm::make_optional<EventLogger>(e);
+ cm::optional<EventLogger> o2 = cm::make_optional<EventLogger>(5);
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &e, nullptr, 4 },
+ { Event::COPY_CONSTRUCT, &*o1, &e, 4 },
+ { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o2, nullptr, 5 },
+ { Event::DESTRUCT, &*o1, nullptr, 4 },
+ { Event::DESTRUCT, &e, nullptr, 4 },
+ };
+ return true;
+}
+
+static bool testMemoryRange(std::vector<Event>& expected)
+{
+ bool retval = true;
+
+ cm::optional<EventLogger> o{ 4 };
+
+ auto* ostart = &o;
+ auto* oend = ostart + 1;
+ auto* estart = &o.value();
+ auto* eend = estart + 1;
+
+ if (static_cast<void*>(estart) < static_cast<void*>(ostart) ||
+ static_cast<void*>(eend) > static_cast<void*>(oend)) {
+ std::cout << "value is not within memory range of optional" << std::endl;
+ retval = false;
+ }
+
+ expected = {
+ { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
+ { Event::DESTRUCT, &*o, nullptr, 4 },
+ };
+ return retval;
+}
+
+int testOptional(int /*unused*/, char* /*unused*/ [])
+{
+ int retval = 0;
+
+#define DO_EVENT_TEST(name) \
+ do { \
+ events.clear(); \
+ std::vector<Event> expected; \
+ if (!name(expected)) { \
+ std::cout << "in " #name << std::endl; \
+ retval = 1; \
+ } else if (expected != events) { \
+ std::cout << #name " did not produce expected events" << std::endl; \
+ retval = 1; \
+ } \
+ } while (0)
+
+#define DO_TEST(name) \
+ do { \
+ if (!name()) { \
+ std::cout << "in " #name << std::endl; \
+ retval = 1; \
+ } \
+ } while (0)
+
+ DO_EVENT_TEST(testDefaultConstruct);
+ DO_EVENT_TEST(testNulloptConstruct);
+ DO_EVENT_TEST(testValueConstruct);
+ DO_EVENT_TEST(testInPlaceConstruct);
+ DO_EVENT_TEST(testCopyConstruct);
+ DO_EVENT_TEST(testMoveConstruct);
+ DO_EVENT_TEST(testNulloptAssign);
+ DO_EVENT_TEST(testCopyAssign);
+ DO_EVENT_TEST(testMoveAssign);
+ DO_EVENT_TEST(testPointer);
+ DO_EVENT_TEST(testDereference);
+ DO_EVENT_TEST(testHasValue);
+ DO_EVENT_TEST(testValue);
+ DO_TEST(testValueOr);
+ DO_EVENT_TEST(testSwap);
+ DO_EVENT_TEST(testReset);
+ DO_EVENT_TEST(testEmplace);
+ DO_EVENT_TEST(testMakeOptional);
+ DO_EVENT_TEST(testMemoryRange);
+
+ return retval;
+}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 34858b8..02e28d4 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -780,8 +780,6 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
win64_release.cmake)
ADD_NIGHTLY_BUILD_TEST(CMakeNightlyOSX
osx_release.cmake)
- ADD_NIGHTLY_BUILD_TEST(CMakeNightlyLinux64
- linux64_release.cmake)
set_property(TEST CMakeNightlyWin64 PROPERTY DEPENDS CMakeNightlyWin32)
endif()
@@ -2619,16 +2617,18 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
PASS_REGULAR_EXPRESSION "Could not find executable"
FAIL_REGULAR_EXPRESSION "SegFault")
- configure_file(
- "${CMake_SOURCE_DIR}/Tests/CTestTestUpload/test.cmake.in"
- "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake"
- @ONLY ESCAPE_QUOTES)
- add_test(CTestTestUpload ${CMAKE_CTEST_COMMAND}
- -S "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake" -V
- --output-log "${CMake_BINARY_DIR}/Tests/CTestTestUpload/testOut.log"
- )
- set_tests_properties(CTestTestUpload PROPERTIES
- PASS_REGULAR_EXPRESSION "Upload\\.xml")
+ if(NOT CMake_TEST_NO_NETWORK)
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestUpload/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ add_test(CTestTestUpload ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestUpload/testOut.log"
+ )
+ set_tests_properties(CTestTestUpload PROPERTIES
+ PASS_REGULAR_EXPRESSION "Upload\\.xml")
+ endif()
configure_file(
"${CMake_SOURCE_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake.in"
diff --git a/Tests/COnly/CMakeLists.txt b/Tests/COnly/CMakeLists.txt
index 3037f13..20615fe 100644
--- a/Tests/COnly/CMakeLists.txt
+++ b/Tests/COnly/CMakeLists.txt
@@ -13,11 +13,5 @@ if(MSVC_VERSION AND NOT CMAKE_C_COMPILER_ID STREQUAL Clang OR "x${CMAKE_C_COMPIL
endif()
string(ASCII 35 32 67 77 97 107 101 ASCII_STRING)
message(STATUS "String: ${ASCII_STRING}")
-get_source_file_property(LANG conly.c LANGUAGE)
-if("${LANG}" STREQUAL "C")
- message("Language is C")
-else()
- message(FATAL_ERROR "Bad language for file conly.c")
-endif()
add_library(testCModule MODULE testCModule.c)
diff --git a/Tests/MakeClean/ToClean/CMakeLists.txt b/Tests/MakeClean/ToClean/CMakeLists.txt
index 6f16d12..a05c38b 100644
--- a/Tests/MakeClean/ToClean/CMakeLists.txt
+++ b/Tests/MakeClean/ToClean/CMakeLists.txt
@@ -15,42 +15,45 @@ function(writeCleanFile FILENAME)
file(WRITE "${FILENAME}" ${CLEAN_FILE_CONTENT})
endfunction()
+set(DUMMY_CONTENT_FILE ${CSD}/toclean.cxx)
+
# Build a simple project whose compiled objects should be cleaned.
add_executable(toclean toclean.cxx)
-addCleanFile("${CBD}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
+addCleanFile(
+ "${CBD}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
-# Create a post build custom command that copies the toclean output executable
+# Create a post build custom command that copies a dummy file
# to a custom location
-function(addToCleanPostBuildCopy FILENAME)
- add_custom_command(TARGET toclean POST_BUILD
+function(addPostBuildFile TARGET FILENAME)
+ add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND}
- ARGS -E copy $<TARGET_FILE:toclean> ${FILENAME})
+ ARGS -E copy ${DUMMY_CONTENT_FILE} ${FILENAME})
endfunction()
# Create a custom command whose output should be cleaned.
set(CustomCommandFile "${CBD}/CustomCommandFile.txt")
add_custom_command(OUTPUT ${CustomCommandFile}
- DEPENDS ${CSD}/toclean.cxx
+ DEPENDS ${DUMMY_CONTENT_FILE}
COMMAND ${CMAKE_COMMAND}
- ARGS -E copy ${CSD}/toclean.cxx ${CustomCommandFile})
-add_custom_target(generate ALL DEPENDS ${CustomCommandFile})
+ ARGS -E copy ${DUMMY_CONTENT_FILE} ${CustomCommandFile})
+add_custom_target(customTarget ALL DEPENDS ${CustomCommandFile})
addCleanFile(${CustomCommandFile})
### Tests ADDITIONAL_MAKE_CLEAN_FILES directory property
if("${CMAKE_GENERATOR}" MATCHES "Makefile")
# Create a file that must be registered for cleaning.
- set(MakeDirPropFile "${CBD}/MakeDirPropFile.txt")
- writeCleanFile("${MakeDirPropFile}")
- set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MakeDirPropFile}")
- addCleanFile(${MakeDirPropFile})
+ set(MakeDirPropFileAbs "${CBD}/MakeDirPropFile.txt")
+ writeCleanFile("${MakeDirPropFileAbs}")
+ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MakeDirPropFileAbs}")
+ addCleanFile(${MakeDirPropFileAbs})
# Create a custom command whose output should be cleaned, but whose name
# is not known until generate-time
set(MakeDirPropExpFileRel "MakeDirProp_copy${CMAKE_EXECUTABLE_SUFFIX}")
- set(MakeDirPropExpFile "$<TARGET_FILE_DIR:toclean>/${MakeDirPropExpFileRel}")
- addToCleanPostBuildCopy("${MakeDirPropExpFile}")
- set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${MakeDirPropExpFile})
+ set(MakeDirPropExpFileAbs "$<TARGET_FILE_DIR:toclean>/${MakeDirPropExpFileRel}")
+ addPostBuildFile(toclean "${MakeDirPropExpFileAbs}")
+ set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${MakeDirPropExpFileAbs})
addCleanFile("${CBD}/${MakeDirPropExpFileRel}")
endif()
@@ -72,34 +75,43 @@ addCleanFile("${DirPropFileAbs}")
# Create a custom command whose output should be cleaned, but whose name
# is not known until generate-time
set(DirPropExpFileRel "DirProp_copy${CMAKE_EXECUTABLE_SUFFIX}")
-set(DirPropExpFile "$<TARGET_FILE_DIR:toclean>/${DirPropExpFileRel}")
-addToCleanPostBuildCopy("${DirPropExpFile}")
-set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropExpFile})
+set(DirPropExpFileAbs "$<TARGET_FILE_DIR:toclean>/${DirPropExpFileRel}")
+addPostBuildFile(toclean "${DirPropExpFileAbs}")
+set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropExpFileAbs})
addCleanFile("${CBD}/${DirPropExpFileRel}")
### Tests ADDITIONAL_CLEAN_FILES target property
-# Register a file path relative to the build directory
-set(TgtPropFileRel "TargetPropFileRel.txt")
-writeCleanFile("${CBD}/${TgtPropFileRel}")
-set_target_properties(toclean PROPERTIES ADDITIONAL_CLEAN_FILES ${TgtPropFileRel})
-addCleanFile("${CBD}/${TgtPropFileRel}")
-
-# Register an absolute file path
-set(TgtPropFileAbs "${CBD}/TargetPropFileAbs.txt")
-writeCleanFile("${TgtPropFileAbs}")
-set_property(TARGET toclean APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropFileAbs})
-addCleanFile("${TgtPropFileAbs}")
-
-# Create a custom command whose output should be cleaned, but whose name
-# is not known until generate-time
-set(TgtPropExpFileRel "TgtProp_copy${CMAKE_EXECUTABLE_SUFFIX}")
-set(TgtPropExpFile "$<TARGET_FILE_DIR:toclean>/${TgtPropExpFileRel}")
-addToCleanPostBuildCopy("${TgtPropExpFile}")
-set_property(TARGET toclean APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropExpFile})
-addCleanFile("${CBD}/${TgtPropExpFileRel}")
+function(test_target_property TARGET)
+ # Register a file path relative to the build directory
+ set(TgtPropFileRel "${TARGET}_TargetPropFileRel.txt")
+ writeCleanFile("${CBD}/${TgtPropFileRel}")
+ set_target_properties(${TARGET} PROPERTIES ADDITIONAL_CLEAN_FILES ${TgtPropFileRel})
+ addCleanFile("${CBD}/${TgtPropFileRel}")
+
+ # Register an absolute file path
+ set(TgtPropFileAbs "${CBD}/${TARGET}_TargetPropFileAbs.txt")
+ writeCleanFile("${TgtPropFileAbs}")
+ set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropFileAbs})
+ addCleanFile("${TgtPropFileAbs}")
+
+ # Create a custom command whose output should be cleaned, but whose name
+ # is not known until generate-time
+ set(TgtPropExpFileRel "${TARGET}_TargetPropGenExp.txt")
+ set(TgtPropExpFileAbs "$<TARGET_FILE_DIR:toclean>/${TgtPropExpFileRel}")
+ addPostBuildFile(${TARGET} "${TgtPropExpFileAbs}")
+ set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropExpFileAbs})
+ addCleanFile("${CBD}/${TgtPropExpFileRel}")
+endfunction()
+# Test target property for various target types
+add_executable(acf_exec toclean.cxx)
+test_target_property(acf_exec)
+add_library(acf_lib toclean.cxx)
+test_target_property(acf_lib)
+add_custom_target(acf_custom ALL DEPENDS ${CustomCommandFile})
+test_target_property(acf_custom)
# Process subdirectory without targets
add_subdirectory(EmptySubDir)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 5a4a109..48eebcc 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -249,7 +249,8 @@ add_RunCMake_test(export)
add_RunCMake_test(cmake_minimum_required)
add_RunCMake_test(cmake_parse_arguments)
add_RunCMake_test(continue)
-add_RunCMake_test(ctest_build)
+add_executable(color_warning color_warning.c)
+add_RunCMake_test(ctest_build -DCOLOR_WARNING=$<TARGET_FILE:color_warning>)
add_RunCMake_test(ctest_cmake_error)
add_RunCMake_test(ctest_configure)
if(COVERAGE_COMMAND)
@@ -573,3 +574,5 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|9[0-9])")
endif()
add_RunCMake_test("CTestCommandExpandLists")
+
+add_RunCMake_test(PrecompileHeaders)
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir-stderr.txt b/Tests/RunCMake/CommandLine/C_buildsrcdir-stderr.txt
new file mode 100644
index 0000000..0d8f72e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir-stderr.txt
@@ -0,0 +1,8 @@
+initial-cache.txt: CMAKE_SOURCE_DIR: .*/C_buildsrcdir/src
+initial-cache.txt: CMAKE_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+PreLoad.cmake: CMAKE_SOURCE_DIR: .*/C_buildsrcdir/src
+PreLoad.cmake: CMAKE_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+CMakeLists.txt: INITIAL_SOURCE_DIR: .*/C_buildsrcdir/src
+CMakeLists.txt: INITIAL_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+CMakeLists.txt: PRELOAD_SOURCE_DIR: .*/C_buildsrcdir/src
+CMakeLists.txt: PRELOAD_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir-stdout.txt b/Tests/RunCMake/CommandLine/C_buildsrcdir-stdout.txt
new file mode 100644
index 0000000..c69b11e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir-stdout.txt
@@ -0,0 +1,2 @@
+loading initial cache file .*/C_buildsrcdir/initial-cache.txt
+.*
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir.cmake b/Tests/RunCMake/CommandLine/C_buildsrcdir.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir.cmake
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt b/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
new file mode 100644
index 0000000..adc125b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
@@ -0,0 +1,6 @@
+# Used to verify that the values match what is passed via -S and -B, and are retained in cache.
+set(INITIAL_SOURCE_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "defined in initial.cmake")
+set(INITIAL_BINARY_DIR "${CMAKE_BINARY_DIR}" CACHE PATH "defined in initial.cmake")
+
+message("initial-cache.txt: CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
+message("initial-cache.txt: CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir/src/CMakeLists.txt b/Tests/RunCMake/CommandLine/C_buildsrcdir/src/CMakeLists.txt
new file mode 100644
index 0000000..4893fe7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir/src/CMakeLists.txt
@@ -0,0 +1,6 @@
+project(C_buildsrcdir)
+
+message("CMakeLists.txt: INITIAL_SOURCE_DIR: ${INITIAL_SOURCE_DIR}")
+message("CMakeLists.txt: INITIAL_BINARY_DIR: ${INITIAL_BINARY_DIR}")
+message("CMakeLists.txt: PRELOAD_SOURCE_DIR: ${PRELOAD_SOURCE_DIR}")
+message("CMakeLists.txt: PRELOAD_BINARY_DIR: ${PRELOAD_BINARY_DIR}")
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir/src/PreLoad.cmake b/Tests/RunCMake/CommandLine/C_buildsrcdir/src/PreLoad.cmake
new file mode 100644
index 0000000..5199219
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir/src/PreLoad.cmake
@@ -0,0 +1,6 @@
+# Used to verify that the values match what is passed via -S and -B, and are retained in cache.
+message("PreLoad.cmake: CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
+message("PreLoad.cmake: CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
+
+set(PRELOAD_BINARY_DIR "${CMAKE_BINARY_DIR}" CACHE PATH "value of cmake_binary_dir during preload")
+set(PRELOAD_SOURCE_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "value of cmake_source_dir during preload")
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index dd49423..71a3843 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -391,6 +391,13 @@ run_cmake_command(E_sleep-one-tenth ${CMAKE_COMMAND} -E sleep 0.1)
run_cmake_command(P_directory ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR})
run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake)
+# Documented to return the same result as above even if -S and -B are set to something else.
+# Tests the values of CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_SOURCE_DIR.
+run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake -S something_else -B something_else_1)
+
+# CMAKE_BINARY_DIR should be determined by -B if specified, and CMAKE_SOURCE_DIR determined by -S if specified.
+run_cmake_with_options(C_buildsrcdir -B DummyBuildDir -S ${RunCMake_SOURCE_DIR}/C_buildsrcdir/src -C ${RunCMake_SOURCE_DIR}/C_buildsrcdir/initial-cache.txt)
+
set(RunCMake_TEST_OPTIONS
"-DFOO=-DBAR:BOOL=BAZ")
diff --git a/Tests/RunCMake/PrecompileHeaders/CMakeLists.txt b/Tests/RunCMake/PrecompileHeaders/CMakeLists.txt
new file mode 100644
index 0000000..7dbf32e
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.15.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake b/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
new file mode 100644
index 0000000..fa37c2c
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
@@ -0,0 +1,17 @@
+if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/CMakeFiles/foo.dir/cmake_pch.h")
+ set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/CMakeFiles/foobar.dir/cmake_pch.h")
+else()
+ set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
+ set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
+endif()
+
+if (NOT EXISTS ${foo_pch_header})
+ set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
+ return()
+endif()
+
+if (EXISTS ${foobar_pch_header})
+ set(RunCMake_TEST_FAILED "Generated foobar pch header ${foobar_pch_header} should not exist")
+ return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake b/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake
new file mode 100644
index 0000000..ee47980
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.15)
+project(DisabledPch C)
+
+add_library(foo foo.c)
+target_include_directories(foo PUBLIC include)
+target_precompile_headers(foo PUBLIC
+ foo.h
+ <stdio.h>
+ \"string.h\"
+)
+
+add_executable(foobar foobar.c)
+target_link_libraries(foobar foo)
+set_target_properties(foobar PROPERTIES DISABLE_PRECOMPILE_HEADERS ON)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
new file mode 100644
index 0000000..cbd6ede
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
@@ -0,0 +1,36 @@
+if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/CMakeFiles/foo.dir/cmake_pch.h")
+ set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/CMakeFiles/foobar.dir/cmake_pch.h")
+else()
+ set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
+ set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
+endif()
+
+if (NOT EXISTS ${foo_pch_header})
+ set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
+ return()
+endif()
+
+if (NOT EXISTS ${foobar_pch_header})
+ set(RunCMake_TEST_FAILED "Generated foobar pch header ${foobar_pch_header} does not exist")
+ return()
+endif()
+
+file(STRINGS ${foo_pch_header} foo_pch_header_strings)
+
+if (NOT "#include \"foo.h\"" IN_LIST foo_pch_header_strings OR
+ NOT "#include <stdio.h>" IN_LIST foo_pch_header_strings OR
+ NOT "#include \"string.h\"" IN_LIST foo_pch_header_strings)
+ set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} has bad content")
+ return()
+endif()
+
+file(STRINGS ${foobar_pch_header} foobar_pch_header_strings)
+
+if (NOT "#include \"foo.h\"" IN_LIST foobar_pch_header_strings OR
+ NOT "#include <stdio.h>" IN_LIST foobar_pch_header_strings OR
+ NOT "#include \"string.h\"" IN_LIST foobar_pch_header_strings OR
+ NOT "#include \"bar.h\"" IN_LIST foobar_pch_header_strings)
+ set(RunCMake_TEST_FAILED "Generated foobar pch header ${foobar_pch_header} has bad content")
+ return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake b/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake
new file mode 100644
index 0000000..9041b09
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.15)
+project(PchInterface C)
+
+add_library(foo foo.c)
+target_include_directories(foo PUBLIC include)
+target_precompile_headers(foo PUBLIC
+ foo.h
+ <stdio.h>
+ \"string.h\"
+)
+
+add_library(bar INTERFACE)
+target_include_directories(bar INTERFACE include)
+target_precompile_headers(bar INTERFACE bar.h)
+
+add_executable(foobar foobar.c)
+target_link_libraries(foobar foo bar)
+
+enable_testing()
+add_test(NAME foobar COMMAND foobar)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
new file mode 100644
index 0000000..fd82607
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
@@ -0,0 +1,12 @@
+if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/CMakeFiles/main.dir/cmake_pch.hxx")
+else()
+ set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/cmake_pch.hxx")
+endif()
+
+file(STRINGS ${main_pch_header} main_pch_header_strings)
+string(REGEX MATCH "#pragma warning\\(push, 0\\).*#include.*pch.h.*#pragma warning\\(pop\\)" matched_code ${main_pch_header_strings})
+if(NOT matched_code)
+ set(RunCMake_TEST_FAILED "Generated pch file doesn't include expected prologue and epilogue code")
+ return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue.cmake b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue.cmake
new file mode 100644
index 0000000..3e27620
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue.cmake
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(PchPrologueEpilogue)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_PCH_PROLOGUE "#pragma warning(push, 0)")
+set(CMAKE_PCH_EPILOGUE "#pragma warning(pop)")
+
+add_executable(main main.cpp)
+target_precompile_headers(main PRIVATE pch.h)
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
new file mode 100644
index 0000000..fffcc47
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+cmake_policy(SET CMP0057 NEW)
+include(RunCMake)
+
+function(run_test name)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+ run_cmake(${name})
+ # Precompiled headers are not supported with multiple architectures.
+ if(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
+ endif()
+endfunction()
+
+run_cmake(DisabledPch)
+run_test(PchInterface)
+run_cmake(PchPrologueEpilogue)
+run_test(SkipPrecompileHeaders)
diff --git a/Tests/RunCMake/PrecompileHeaders/SkipPrecompileHeaders.cmake b/Tests/RunCMake/PrecompileHeaders/SkipPrecompileHeaders.cmake
new file mode 100644
index 0000000..49efbfb
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/SkipPrecompileHeaders.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(SkipPrecompileHeaders)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(pch-test main.cpp non-pch.cpp)
+target_precompile_headers(pch-test PRIVATE pch.h)
+
+set_source_files_properties(non-pch.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
+
+enable_testing()
+add_test(NAME pch-test COMMAND pch-test)
diff --git a/Tests/RunCMake/PrecompileHeaders/foo.c b/Tests/RunCMake/PrecompileHeaders/foo.c
new file mode 100644
index 0000000..974a248
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/foo.c
@@ -0,0 +1,6 @@
+#include "foo.h"
+
+int foo()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/PrecompileHeaders/foobar.c b/Tests/RunCMake/PrecompileHeaders/foobar.c
new file mode 100644
index 0000000..6dbf8ce
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/foobar.c
@@ -0,0 +1,7 @@
+#include "bar.h"
+#include "foo.h"
+
+int main()
+{
+ return foo() + bar();
+}
diff --git a/Tests/RunCMake/PrecompileHeaders/include/bar.h b/Tests/RunCMake/PrecompileHeaders/include/bar.h
new file mode 100644
index 0000000..5feb983
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/include/bar.h
@@ -0,0 +1,9 @@
+#ifndef bar_h
+#define bar_h
+
+static int bar()
+{
+ return 0;
+}
+
+#endif
diff --git a/Tests/RunCMake/PrecompileHeaders/include/foo.h b/Tests/RunCMake/PrecompileHeaders/include/foo.h
new file mode 100644
index 0000000..4a49474
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/include/foo.h
@@ -0,0 +1,6 @@
+#ifndef foo_h
+#define foo_h
+
+extern int foo();
+
+#endif
diff --git a/Tests/RunCMake/PrecompileHeaders/main.cpp b/Tests/RunCMake/PrecompileHeaders/main.cpp
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/PrecompileHeaders/non-pch.cpp b/Tests/RunCMake/PrecompileHeaders/non-pch.cpp
new file mode 100644
index 0000000..df5a79f
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/non-pch.cpp
@@ -0,0 +1,3 @@
+#ifdef PCH_INCLUDED
+# error "PCH must not be included into this file!"
+#endif
diff --git a/Tests/RunCMake/PrecompileHeaders/pch.h b/Tests/RunCMake/PrecompileHeaders/pch.h
new file mode 100644
index 0000000..81b6d9e
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/pch.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define PCH_INCLUDED 1
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 5ca069a..72154e7 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -25,6 +25,7 @@ run_cmake(VsProjectImport)
run_cmake(VsPackageReferences)
run_cmake(VsDpiAware)
run_cmake(VsDpiAwareBadParam)
+run_cmake(VsPrecompileHeaders)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
run_cmake(VsJustMyCode)
diff --git a/Tests/RunCMake/VS10Project/VsConfigurationType-check.cmake b/Tests/RunCMake/VS10Project/VsConfigurationType-check.cmake
index 4690970..bbd34da 100644
--- a/Tests/RunCMake/VS10Project/VsConfigurationType-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsConfigurationType-check.cmake
@@ -9,7 +9,7 @@ file(STRINGS "${vcProjectFile}" lines)
foreach(line IN LISTS lines)
if(line MATCHES "^ *<ConfigurationType>(.*)</ConfigurationType>$")
set(propertyFound TRUE)
- set(expectedValue "MyValue")
+ set(expectedValue "MyValue foo")
set(actualValue ${CMAKE_MATCH_1})
if(NOT (${actualValue} STREQUAL ${expectedValue}))
set(RunCMake_TEST_FAILED "ConfigurationType \"${actualValue}\" differs from expected value \"${expectedValue}\".")
diff --git a/Tests/RunCMake/VS10Project/VsConfigurationType.cmake b/Tests/RunCMake/VS10Project/VsConfigurationType.cmake
index a73dfe8..a2f544a 100644
--- a/Tests/RunCMake/VS10Project/VsConfigurationType.cmake
+++ b/Tests/RunCMake/VS10Project/VsConfigurationType.cmake
@@ -1,3 +1,3 @@
enable_language(CXX)
add_library(foo foo.cpp)
-set_target_properties(foo PROPERTIES VS_CONFIGURATION_TYPE "MyValue")
+set_target_properties(foo PROPERTIES VS_CONFIGURATION_TYPE "MyValue $<TARGET_PROPERTY:foo,NAME>")
diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
new file mode 100644
index 0000000..82ca421
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
@@ -0,0 +1,69 @@
+set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx")
+set(pch_source "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.cxx")
+
+file(TO_NATIVE_PATH "${pch_source}" pch_source_win)
+
+if(NOT EXISTS "${pch_header}")
+ set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.")
+ return()
+endif()
+if(NOT EXISTS "${pch_source}")
+ set(RunCMake_TEST_FAILED "Generated PCH header ${pch_source} does not exist.")
+ return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+ set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+ return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+ if (line MATCHES "<PrecompiledHeader.*>Use</PrecompiledHeader>")
+ set(have_pch_use ON)
+ endif()
+
+ if (line MATCHES "<PrecompiledHeader.*>Create</PrecompiledHeader>")
+ set(have_pch_create ON)
+ endif()
+
+ if (line MATCHES "<PrecompiledHeaderFile.*>${pch_header}</PrecompiledHeaderFile>")
+ set(have_pch_header ON)
+ endif()
+
+ if (line MATCHES "<ForcedIncludeFiles.*>${pch_header}</ForcedIncludeFiles>")
+ set(have_force_pch_header ON)
+ endif()
+
+ string(FIND "${line}" "<ClCompile Include=\"${pch_source_win}\">" find_pos)
+ if (NOT find_pos EQUAL "-1")
+ set(have_pch_source_compile ON)
+ endif()
+endforeach()
+
+if (NOT have_pch_use)
+ set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeader>Use</PrecompiledHeader> block.")
+ return()
+endif()
+
+if (NOT have_pch_create)
+ set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeader>Create</PrecompiledHeader> block.")
+ return()
+endif()
+
+if (NOT have_pch_header)
+ set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeaderFile>${pch_header}</PrecompiledHeaderFile> block.")
+ return()
+endif()
+
+if (NOT have_force_pch_header)
+ set(RunCMake_TEST_FAILED "Generated project should have the <ForcedIncludeFiles>${pch_header}</ForcedIncludeFiles> block.")
+ return()
+endif()
+
+if (NOT have_pch_source_compile)
+ set(RunCMake_TEST_FAILED "Generated project should have the <ClCompile Include=\"${pch_source_win}\"> block.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeaders.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeaders.cmake
new file mode 100644
index 0000000..6d208c9
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsPrecompileHeaders.cmake
@@ -0,0 +1,4 @@
+project(VsPrecompileHeaders CXX)
+
+add_library(tgt SHARED empty.cxx)
+target_precompile_headers(tgt PRIVATE stdafx.h)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 191f56d..1dfa8b2 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -12,6 +12,7 @@ run_cmake(XcodeObjectNeedsQuote)
run_cmake(XcodeOptimizationFlags)
run_cmake(XcodePreserveNonOptimizationFlags)
run_cmake(XcodePreserveObjcFlag)
+run_cmake(XcodePrecompileHeaders)
if (NOT XCODE_VERSION VERSION_LESS 6)
run_cmake(XcodePlatformFrameworks)
endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
index ef772ea..8c0b470 100644
--- a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
@@ -5,6 +5,7 @@ enable_language(C)
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
index f6c00b1..c221033 100644
--- a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
@@ -11,6 +11,7 @@ if(NOT IOS)
endif()
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
index ec11dbb..172f2e8 100644
--- a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
@@ -7,6 +7,7 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 9)
endif()
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
add_library(foo SHARED foo.cpp)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake
index 58e96b4..038a890 100644
--- a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake
@@ -7,6 +7,7 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 9)
endif()
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
add_library(foo SHARED foo.cpp)
diff --git a/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
new file mode 100644
index 0000000..aa3eafc
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
@@ -0,0 +1,35 @@
+set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx")
+
+if(NOT EXISTS "${pch_header}")
+ set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.")
+ return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/XcodePrecompileHeaders.xcodeproj/project.pbxproj")
+if (NOT EXISTS "${tgt_project}")
+ set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+ return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+ if (line MATCHES "GCC_PRECOMPILE_PREFIX_HEADER = YES;")
+ set(have_pch_prefix ON)
+ endif()
+
+ string(FIND "${line}" "GCC_PREFIX_HEADER = \"${pch_header}\";" find_pos)
+ if (NOT find_pos EQUAL "-1")
+ set(have_pch_header ON)
+ endif()
+endforeach()
+
+if (NOT have_pch_prefix)
+ set(RunCMake_TEST_FAILED "Generated project should have the GCC_PRECOMPILE_PREFIX_HEADER = YES; line.")
+ return()
+endif()
+
+if (NOT have_pch_header)
+ set(RunCMake_TEST_FAILED "Generated project should have the GCC_PREFIX_HEADER = \"${pch_header}\"; line.")
+ return()
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders.cmake b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders.cmake
new file mode 100644
index 0000000..f86bcf4
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders.cmake
@@ -0,0 +1,4 @@
+project(XcodePrecompileHeaders CXX)
+
+add_library(tgt foo.cpp)
+target_precompile_headers(tgt PRIVATE stdafx.h)
diff --git a/Tests/RunCMake/color_warning.c b/Tests/RunCMake/color_warning.c
new file mode 100644
index 0000000..831abd9
--- /dev/null
+++ b/Tests/RunCMake/color_warning.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+int main(void)
+{
+ printf(
+ "/tmp/hello.c:3:2: \033[35mwarning:\033[0m Hello, World! [-W#warnings]\n");
+ return 0;
+}
diff --git a/Tests/RunCMake/ctest_build/IgnoreColor-stdout.txt b/Tests/RunCMake/ctest_build/IgnoreColor-stdout.txt
new file mode 100644
index 0000000..cd1720f
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/IgnoreColor-stdout.txt
@@ -0,0 +1,2 @@
+ 0 Compiler errors
+ 1 Compiler warnings
diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
index 1092d2a..b2e562a 100644
--- a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
@@ -1,6 +1,8 @@
include(RunCTest)
set(CASE_CTEST_BUILD_ARGS "")
+set(RunCMake_USE_LAUNCHERS TRUE)
+set(RunCMake_USE_CUSTOM_BUILD_COMMAND FALSE)
function(run_ctest_build CASE_NAME)
set(CASE_CTEST_BUILD_ARGS "${ARGN}")
@@ -45,3 +47,9 @@ function(run_BuildChangeId)
run_ctest(BuildChangeId)
endfunction()
run_BuildChangeId()
+
+set(RunCMake_USE_LAUNCHERS FALSE)
+set(RunCMake_USE_CUSTOM_BUILD_COMMAND TRUE)
+set(RunCMake_BUILD_COMMAND "${COLOR_WARNING}")
+run_ctest(IgnoreColor)
+unset(RunCMake_BUILD_COMMAND)
diff --git a/Tests/RunCMake/ctest_build/test.cmake.in b/Tests/RunCMake/ctest_build/test.cmake.in
index 6f15ec9..9f7fa13 100644
--- a/Tests/RunCMake/ctest_build/test.cmake.in
+++ b/Tests/RunCMake/ctest_build/test.cmake.in
@@ -9,7 +9,10 @@ set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_USE_LAUNCHERS TRUE)
+set(CTEST_USE_LAUNCHERS "@RunCMake_USE_LAUNCHERS@")
+if (@RunCMake_USE_CUSTOM_BUILD_COMMAND@)
+ set(CTEST_BUILD_COMMAND "\"@RunCMake_BUILD_COMMAND@\"")
+endif()
set(ctest_build_args "@CASE_CTEST_BUILD_ARGS@")
ctest_start(Experimental)
diff --git a/Tests/RunCMake/ctest_start/AppendDifferentGroup-stderr.txt b/Tests/RunCMake/ctest_start/AppendDifferentGroup-stderr.txt
new file mode 100644
index 0000000..9e493a6
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/AppendDifferentGroup-stderr.txt
@@ -0,0 +1 @@
+^Group given in TAG does not match group given in ctest_start\(\)$
diff --git a/Tests/RunCMake/ctest_start/AppendDifferentGroup-stdout.txt b/Tests/RunCMake/ctest_start/AppendDifferentGroup-stdout.txt
new file mode 100644
index 0000000..5f83653
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/AppendDifferentGroup-stdout.txt
@@ -0,0 +1,8 @@
+Run dashboard with to-be-determined model
+ Source directory: .*/Tests/RunCMake/ctest_start/AppendDifferentGroup
+ Build directory: .*/Tests/RunCMake/ctest_start/AppendDifferentGroup-build
+ Group: ExperimentalDifferent
+ Site: test-site
+ Build name: test-build-name
+ Use existing tag: 19551112-2204 - ExperimentalDifferent
+ Use ExperimentalDifferent tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/AppendDifferentTrack-stderr.txt b/Tests/RunCMake/ctest_start/AppendDifferentTrack-stderr.txt
index 0d6d19d..9e493a6 100644
--- a/Tests/RunCMake/ctest_start/AppendDifferentTrack-stderr.txt
+++ b/Tests/RunCMake/ctest_start/AppendDifferentTrack-stderr.txt
@@ -1 +1 @@
-^Track given in TAG does not match track given in ctest_start\(\)$
+^Group given in TAG does not match group given in ctest_start\(\)$
diff --git a/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt b/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt
index 25085ef..022e2ec 100644
--- a/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt
+++ b/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt
@@ -1,7 +1,7 @@
Run dashboard with to-be-determined model
Source directory: .*/Tests/RunCMake/ctest_start/AppendDifferentTrack
Build directory: .*/Tests/RunCMake/ctest_start/AppendDifferentTrack-build
- Track: ExperimentalDifferent
+ Group: ExperimentalDifferent
Site: test-site
Build name: test-build-name
Use existing tag: 19551112-2204 - ExperimentalDifferent
diff --git a/Tests/RunCMake/ctest_start/MissingGroupArg-result.txt b/Tests/RunCMake/ctest_start/MissingGroupArg-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/MissingGroupArg-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_start/MissingGroupArg-stderr.txt b/Tests/RunCMake/ctest_start/MissingGroupArg-stderr.txt
new file mode 100644
index 0000000..e0480f6
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/MissingGroupArg-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error at .*/Tests/RunCMake/ctest_start/MissingGroupArg/test\.cmake:[0-9]+ \(ctest_start\):
+ ctest_start GROUP argument missing group name$
diff --git a/Tests/RunCMake/ctest_start/MissingGroupArgAppend-result.txt b/Tests/RunCMake/ctest_start/MissingGroupArgAppend-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/MissingGroupArgAppend-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_start/MissingGroupArgAppend-stderr.txt b/Tests/RunCMake/ctest_start/MissingGroupArgAppend-stderr.txt
new file mode 100644
index 0000000..8ae53ff
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/MissingGroupArgAppend-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error at .*/Tests/RunCMake/ctest_start/MissingGroupArgAppend/test\.cmake:[0-9]+ \(ctest_start\):
+ ctest_start GROUP argument missing group name$
diff --git a/Tests/RunCMake/ctest_start/MissingGroupArgQuiet-result.txt b/Tests/RunCMake/ctest_start/MissingGroupArgQuiet-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/MissingGroupArgQuiet-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_start/MissingGroupArgQuiet-stderr.txt b/Tests/RunCMake/ctest_start/MissingGroupArgQuiet-stderr.txt
new file mode 100644
index 0000000..c4f8900
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/MissingGroupArgQuiet-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error at .*/Tests/RunCMake/ctest_start/MissingGroupArgQuiet/test\.cmake:[0-9]+ \(ctest_start\):
+ ctest_start GROUP argument missing group name$
diff --git a/Tests/RunCMake/ctest_start/MissingTrackArg-stderr.txt b/Tests/RunCMake/ctest_start/MissingTrackArg-stderr.txt
index 7b42bc9..2a72a83 100644
--- a/Tests/RunCMake/ctest_start/MissingTrackArg-stderr.txt
+++ b/Tests/RunCMake/ctest_start/MissingTrackArg-stderr.txt
@@ -1,2 +1,2 @@
^CMake Error at .*/Tests/RunCMake/ctest_start/MissingTrackArg/test\.cmake:[0-9]+ \(ctest_start\):
- ctest_start TRACK argument missing track name$
+ ctest_start TRACK argument missing group name$
diff --git a/Tests/RunCMake/ctest_start/MissingTrackArgAppend-stderr.txt b/Tests/RunCMake/ctest_start/MissingTrackArgAppend-stderr.txt
index 695bfad..7ff82ab 100644
--- a/Tests/RunCMake/ctest_start/MissingTrackArgAppend-stderr.txt
+++ b/Tests/RunCMake/ctest_start/MissingTrackArgAppend-stderr.txt
@@ -1,2 +1,2 @@
^CMake Error at .*/Tests/RunCMake/ctest_start/MissingTrackArgAppend/test\.cmake:[0-9]+ \(ctest_start\):
- ctest_start TRACK argument missing track name$
+ ctest_start TRACK argument missing group name$
diff --git a/Tests/RunCMake/ctest_start/MissingTrackArgQuiet-stderr.txt b/Tests/RunCMake/ctest_start/MissingTrackArgQuiet-stderr.txt
index 9438522..c23b1bf 100644
--- a/Tests/RunCMake/ctest_start/MissingTrackArgQuiet-stderr.txt
+++ b/Tests/RunCMake/ctest_start/MissingTrackArgQuiet-stderr.txt
@@ -1,2 +1,2 @@
^CMake Error at .*/Tests/RunCMake/ctest_start/MissingTrackArgQuiet/test\.cmake:[0-9]+ \(ctest_start\):
- ctest_start TRACK argument missing track name$
+ ctest_start TRACK argument missing group name$
diff --git a/Tests/RunCMake/ctest_start/NoAppendDifferentGroup-stdout.txt b/Tests/RunCMake/ctest_start/NoAppendDifferentGroup-stdout.txt
new file mode 100644
index 0000000..13a3883
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/NoAppendDifferentGroup-stdout.txt
@@ -0,0 +1,7 @@
+Run dashboard with model Experimental
+ Source directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentGroup
+ Build directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentGroup-build
+ Group: ExperimentalDifferent
+ Site: test-site
+ Build name: test-build-name
+ Use ExperimentalDifferent tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt b/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt
index 20a29be..c511e0d 100644
--- a/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt
+++ b/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt
@@ -1,7 +1,7 @@
Run dashboard with model Experimental
Source directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack
Build directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-build
- Track: ExperimentalDifferent
+ Group: ExperimentalDifferent
Site: test-site
Build name: test-build-name
Use ExperimentalDifferent tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
index 905ad00..da85b39 100644
--- a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
@@ -26,18 +26,24 @@ run_ctest_start(WriteModelToTagExperimental Experimental QUIET)
run_ctest_start(WriteModelToTagContinuous Continuous QUIET)
run_ctest_start(WriteModelToTagNightly Nightly QUIET)
run_ctest_start(WriteModelToTagNoMatchingTrack Continuous TRACK SomeWeirdTrackName QUIET)
+run_ctest_start(WriteModelToTagNoMatchingGroup Continuous GROUP SomeWeirdTrackName QUIET)
run_ctest_start(AppendSameModel Continuous APPEND)
run_ctest_start(AppendDifferentModel Experimental APPEND)
run_ctest_start(AppendNoModel APPEND)
run_ctest_start(AppendDifferentTrack TRACK ExperimentalDifferent APPEND)
+run_ctest_start(AppendDifferentGroup GROUP ExperimentalDifferent APPEND)
run_ctest_start(NoAppendDifferentTrack Experimental TRACK ExperimentalDifferent)
+run_ctest_start(NoAppendDifferentGroup Experimental GROUP ExperimentalDifferent)
run_ctest_start(AppendNoMatchingTrack Continuous APPEND)
run_ctest_start(AppendOldContinuous Continuous APPEND)
run_ctest_start(AppendOldNoModel APPEND)
run_ctest_start(NoModel QUIET)
run_ctest_start(MissingTrackArg Experimental TRACK)
+run_ctest_start(MissingGroupArg Experimental GROUP)
run_ctest_start(MissingTrackArgAppend Experimental TRACK APPEND)
+run_ctest_start(MissingGroupArgAppend Experimental GROUP APPEND)
run_ctest_start(MissingTrackArgQuiet Experimental TRACK QUIET)
+run_ctest_start(MissingGroupArgQuiet Experimental GROUP QUIET)
run_ctest_start(TooManyArgs Experimental
${RunCMake_BINARY_DIR}/TooManyArgs-build
${RunCMake_BINARY_DIR}/TooManyArgs-build
diff --git a/Tests/RunCMake/ctest_start/WriteModelToTagNoMatchingGroup-check.cmake b/Tests/RunCMake/ctest_start/WriteModelToTagNoMatchingGroup-check.cmake
new file mode 100644
index 0000000..bd2862d
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/WriteModelToTagNoMatchingGroup-check.cmake
@@ -0,0 +1 @@
+check_tag_contents("^[0-9-]+\nSomeWeirdTrackName\nContinuous\n$")
diff --git a/Tests/RunCMake/find_path/EmptyOldStyle-stdout.txt b/Tests/RunCMake/find_path/EmptyOldStyle-stdout.txt
new file mode 100644
index 0000000..8f21eb8
--- /dev/null
+++ b/Tests/RunCMake/find_path/EmptyOldStyle-stdout.txt
@@ -0,0 +1 @@
+-- VAR-NOTFOUND
diff --git a/Tests/RunCMake/find_path/EmptyOldStyle.cmake b/Tests/RunCMake/find_path/EmptyOldStyle.cmake
new file mode 100644
index 0000000..d78bb65
--- /dev/null
+++ b/Tests/RunCMake/find_path/EmptyOldStyle.cmake
@@ -0,0 +1,2 @@
+find_path(VAR ONLY_CMAKE_FIND_ROOT_PATH)
+message(STATUS "${VAR}")
diff --git a/Tests/RunCMake/find_path/RunCMakeTest.cmake b/Tests/RunCMake/find_path/RunCMakeTest.cmake
index 8b5b5b7..ed55f51 100644
--- a/Tests/RunCMake/find_path/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_path/RunCMakeTest.cmake
@@ -1,5 +1,6 @@
include(RunCMake)
+run_cmake(EmptyOldStyle)
run_cmake(FromPATHEnv)
run_cmake(PrefixInPATH)
diff --git a/Tests/SourceFileProperty/CMakeLists.txt b/Tests/SourceFileProperty/CMakeLists.txt
index 1b6506d..5e55f7b 100644
--- a/Tests/SourceFileProperty/CMakeLists.txt
+++ b/Tests/SourceFileProperty/CMakeLists.txt
@@ -1,19 +1,27 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.1)
project(SourceFileProperty C)
-set(sources)
-
if (EXISTS icasetest.c)
# If a file exists by this name, use it.
set_source_files_properties(icasetest.c
PROPERTIES
- COMPILE_FLAGS -DNEEDED_TO_WORK)
+ COMPILE_DEFINITIONS NEEDED_TO_WORK)
else ()
# Work on case-sensitive file systems as well.
set_source_files_properties(main.c
PROPERTIES
- COMPILE_FLAGS -DNO_NEED_TO_CALL)
+ COMPILE_DEFINITIONS NO_NEED_TO_CALL)
endif ()
-list(APPEND sources ICaseTest.c)
-add_executable(SourceFileProperty main.c ${sources})
+add_executable(SourceFileProperty main.c)
+target_sources(SourceFileProperty PRIVATE ICaseTest.c)
+
+get_source_file_property(LANG_MAIN main.c LANGUAGE)
+if(NOT "${LANG_MAIN}" STREQUAL "C")
+ message(FATAL_ERROR "Bad language for file main.c")
+endif()
+
+get_property(LANG_TEST SOURCE ICaseTest.c PROPERTY LANGUAGE)
+if (NOT "${LANG_TEST}" STREQUAL "C")
+ message(FATAL_ERROR "Bad language for file ICaseTest.c")
+endif ()
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index f52caed..5bf13f3 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.1...3.15 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 9fff442..78026fa 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -23,6 +23,7 @@
# HACK: check whether this can be removed with next iwyu release.
{ include: [ "<bits/shared_ptr.h>", private, "<memory>", public ] },
{ include: [ "<bits/std_function.h>", private, "<functional>", public ] },
+ { include: [ "<bits/refwrap.h>", private, "<functional>", public ] },
{ include: [ "<bits/stdint-intn.h>", private, "<stdint.h>", public ] },
{ include: [ "<bits/stdint-uintn.h>", private, "<stdint.h>", public ] },
{ include: [ "<bits/time.h>", private, "<time.h>", public ] },
@@ -73,6 +74,7 @@
# Use '-Xiwyu -v7' 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<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 ] },
diff --git a/Utilities/Release/README b/Utilities/Release/README
deleted file mode 100644
index 11de1c3..0000000
--- a/Utilities/Release/README
+++ /dev/null
@@ -1,18 +0,0 @@
-To create a cmake release, make sure the "release" tag is pointing to the
-expected git commit:
-
-https://cmake.org/gitweb?p=cmake.git;a=shortlog;h=refs/heads/release
-
-Then as kitware@hythloth, using an up-to-date CMake:
-
- cd ~/CMakeReleases/cmake/Utilities/Release
- mkdir 283rc1
- cd 283rc1
- ~/CMakeReleases/build/bin/cmake -DCMAKE_CREATE_VERSION=release -P ../create-cmake-release.cmake
- ./create-release.sh
-
-
-create-cmake-release.cmake: script to run to create release sh scripts
-Add or remove machines in create-cmake-release.cmake.
-
-machine_release.cmake : config files for each machine
diff --git a/Utilities/Release/README.rst b/Utilities/Release/README.rst
new file mode 100644
index 0000000..e7f0eb3
--- /dev/null
+++ b/Utilities/Release/README.rst
@@ -0,0 +1,84 @@
+CMake Release Utilities
+***********************
+
+This directory contains scripts used to package CMake itself for distribution
+on ``cmake.org``. See also the `CMake Source Code Guide`_.
+
+.. _`CMake Source Code Guide`: ../../Help/dev/source.rst
+
+Docker
+------
+
+The ``linux/<arch>/`` directories contain Docker specifications that anyone
+may use to produce Linux binaries for CMake:
+
+* ``linux/<arch>/base/Dockerfile``:
+ Produces a base image with a build environment for portable CMake binaries.
+ This image is published in the `kitware/cmake Docker Hub Repository`_
+ with tag ``build-linux-<arch>-base-<date>``.
+
+* ``linux/<arch>/deps/Dockerfile``:
+ Produces an image with custom-built dependencies for portable CMake binaries.
+ This image is published in the `kitware/cmake Docker Hub Repository`_
+ with tag ``build-linux-<arch>-deps-<date>``.
+
+* ``linux/<arch>/Dockerfile``:
+ Produce an image containing a portable CMake binary package for Linux.
+ Build this image using the CMake source directory as the build context.
+ The resulting image will have an ``/out`` directory containing the package.
+ For example:
+
+ .. code-block:: console
+
+ $ docker build --tag=cmake:build --network none \
+ -f cmake-src/Utilities/Release/linux/$arch/Dockerfile cmake-src
+ $ docker container create --name cmake-build cmake:build
+ $ docker cp cmake-build:/out .
+ $ ls out/cmake-*-Linux-$arch.tar.gz
+
+* ``linux/<arch>/test/Dockerfile``:
+ Produces a base image with a test environment for packaged CMake binaries.
+ For example, build the test base image:
+
+ .. code-block:: console
+
+ $ docker build --tag=cmake:test-base \
+ cmake-src/Utilities/Release/linux/$arch/test
+
+ Then create a local ``test/Dockerfile`` to prepare an image with both the
+ CMake source tree and the above-built package::
+
+ FROM cmake:test-base
+ COPY cmake-src /opt/cmake/src/cmake
+ ADD out/cmake-<ver>-Linux-<arch>.tar.gz /opt/
+ ENV PATH=/opt/cmake-<ver>-Linux-<arch>/bin:$PATH
+
+ Build the test image and run it to drive testing:
+
+ .. code-block:: console
+
+ $ docker build --tag cmake:test --network none -f test/Dockerfile .
+ $ docker run --network none cmake:test bash test-make.bash
+ $ docker run --network none cmake:test bash test-ninja.bash
+
+.. _`kitware/cmake Docker Hub Repository`: https://hub.docker.com/r/kitware/cmake
+
+Scripts for Kitware
+-------------------
+
+Kitware uses the following scripts to produce binaries for ``cmake.org``.
+They work only on specific machines Kitware uses for such builds.
+
+* ``create-cmake-release.cmake``:
+ Run ``cmake -DCMAKE_CREATE_VERSION=$ver -P ../create-cmake-release.cmake``
+ to generate ``create-$ver-*.sh`` release scripts. It also displays
+ instructions to run them.
+
+* ``*_release.cmake``:
+ Platform-specific settings used in corresponding scripts generated above.
+
+* ``release_cmake.cmake``:
+ Code shared by all ``*_release.cmake`` scripts.
+
+* ``release_cmake.sh.in``:
+ Template for script that runs on the actual build machines.
diff --git a/Utilities/Release/WiX/CustomAction/CMakeLists.txt b/Utilities/Release/WiX/CustomAction/CMakeLists.txt
index 7efd01e..9d89dd8 100644
--- a/Utilities/Release/WiX/CustomAction/CMakeLists.txt
+++ b/Utilities/Release/WiX/CustomAction/CMakeLists.txt
@@ -1,9 +1,15 @@
-foreach(CONFIG DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
- string(REPLACE "/MD" "/MT"
- "CMAKE_CXX_FLAGS_${CONFIG}"
- "${CMAKE_CXX_FLAGS_${CONFIG}}"
- )
-endforeach()
+if(MSVC)
+ if(NOT CMAKE_VERSION VERSION_LESS 3.15)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+ else()
+ foreach(CONFIG DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
+ string(REPLACE "/MD" "/MT"
+ "CMAKE_CXX_FLAGS_${CONFIG}"
+ "${CMAKE_CXX_FLAGS_${CONFIG}}"
+ )
+ endforeach()
+ endif()
+endif()
add_library(CMakeWiXCustomActions MODULE
detect_nsis_overwrite.cpp
diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake
index 0622ad8..17a2151 100644
--- a/Utilities/Release/create-cmake-release.cmake
+++ b/Utilities/Release/create-cmake-release.cmake
@@ -45,14 +45,12 @@ echo 'Failed to create \${name}.tar.gz'
endfunction()
write_docs_shell_script("create-${CMAKE_CREATE_VERSION}-docs.sh")
-write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-linux64.sh" linux64_release) # Linux x86_64
write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-macos.sh" osx_release ) # macOS x86_64
write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-win64.sh" win64_release ) # Windows x64
write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-win32.sh" win32_release ) # Windows x86
message("Build docs first and then build for each platform:
./create-${CMAKE_CREATE_VERSION}-docs.sh &&
- ./create-${CMAKE_CREATE_VERSION}-linux64.sh &&
./create-${CMAKE_CREATE_VERSION}-macos.sh &&
./create-${CMAKE_CREATE_VERSION}-win64.sh &&
./create-${CMAKE_CREATE_VERSION}-win32.sh &&
diff --git a/Utilities/Release/linux/x86_64/Dockerfile b/Utilities/Release/linux/x86_64/Dockerfile
new file mode 100644
index 0000000..f3ba69c
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/Dockerfile
@@ -0,0 +1,35 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Produce an image containing a portable CMake binary package for Linux/x86_64.
+# Build using the CMake source directory as the build context.
+# The resulting image will have an '/out' directory containing the package.
+
+ARG FROM_IMAGE_NAME=kitware/cmake:build-linux-x86_64-deps-2019-08-09
+ARG FROM_IMAGE_DIGEST=@sha256:630c320b26a67fc584e0bc98314f1fb0cb0abc764348bb2613ef07437f7101f9
+ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+FROM $FROM_IMAGE
+
+COPY . /opt/cmake/src/cmake
+
+ARG TEST=true
+
+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 \
+ && export LANG=en_US.UTF-8 \
+ && set -x \
+ && ../cmake/bootstrap --parallel=$(nproc) --docdir=doc/cmake \
+ && nice make -j $(nproc) \
+ && if $TEST; then \
+ # Run tests that require the full build tree.
+ bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)'; \
+ fi \
+ && bin/cpack -G TGZ \
+ && set +x \
+ && mkdir /out \
+ && mv cmake-*-Linux-x86_64.tar.gz /out \
+ && :
diff --git a/Utilities/Release/linux/x86_64/base/Dockerfile b/Utilities/Release/linux/x86_64/base/Dockerfile
new file mode 100644
index 0000000..dfc7df8
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/base/Dockerfile
@@ -0,0 +1,30 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# 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=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+FROM $FROM_IMAGE
+
+RUN : \
+ && yum install -y centos-release-scl \
+ && yum install -y \
+ ca-certificates \
+ curl \
+ devtoolset-6-gcc \
+ devtoolset-6-gcc-c++ \
+ fontconfig-devel \
+ freetype-devel \
+ git \
+ libX11-devel \
+ libxcb-devel \
+ make \
+ patch \
+ perl \
+ rh-python36-python-pip \
+ xz \
+ && yum clean all \
+ && :
diff --git a/Utilities/Release/linux/x86_64/cache.txt b/Utilities/Release/linux/x86_64/cache.txt
new file mode 100644
index 0000000..a2864e9
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/cache.txt
@@ -0,0 +1,44 @@
+CMAKE_BUILD_TYPE:STRING=Release
+
+CMAKE_C_STANDARD:STRING=11
+CMAKE_CXX_STANDARD:STRING=14
+
+# Require only older APIs where possible.
+CMAKE_C_FLAGS:STRING=-D_POSIX_C_SOURCE=199506L -D_POSIX_SOURCE=1 -D_SVID_SOURCE=1 -D_BSD_SOURCE=1
+
+# Link C++ library statically.
+CMAKE_EXE_LINKER_FLAGS:STRING=-static-libstdc++ -static-libgcc
+
+# Enable ssl support in curl
+CMAKE_USE_OPENSSL:BOOL=ON
+OPENSSL_CRYPTO_LIBRARY:STRING=/opt/openssl/lib/libcrypto.a;-pthread
+OPENSSL_INCLUDE_DIR:PATH=/opt/openssl/include
+OPENSSL_SSL_LIBRARY:FILEPATH=/opt/openssl/lib/libssl.a
+
+# Enable ccmake
+BUILD_CursesDialog:BOOL=ON
+CURSES_FORM_LIBRARY:FILEPATH=/opt/ncurses/lib/libform.a
+CURSES_INCLUDE_PATH:PATH=/opt/ncurses/include
+CURSES_NCURSES_LIBRARY:FILEPATH=/opt/ncurses/lib/libncurses.a
+
+# Enable cmake-gui with static qt plugins
+BUILD_QtDialog:BOOL=TRUE
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
+CMAKE_PREFIX_PATH:STRING=/opt/qt
+CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES:STRING=/opt/qt/plugins/platforms/libqxcb.a;/opt/qt/lib/libQt5XcbQpa.a;/opt/qt/lib/libQt5ServiceSupport.a;/opt/qt/lib/libQt5EdidSupport.a;/opt/qt/lib/libQt5EventDispatcherSupport.a;/opt/qt/lib/libQt5FontDatabaseSupport.a;/opt/qt/lib/libQt5ThemeSupport.a;/opt/qt/lib/libxcb-static.a;-lxcb;-lfontconfig;-lfreetype
+
+# Build documentation.
+SPHINX_EXECUTABLE:FILEPATH=/opt/rh/rh-python36/root/usr/bin/sphinx-build
+SPHINX_HTML:BOOL=ON
+SPHINX_MAN:BOOL=ON
+SPHINX_QTHELP:BOOL=ON
+QCOLLECTIONGENERATOR_EXECUTABLE:PATH=/opt/qt/bin/qhelpgenerator
+
+# We bootstrap as part of the build so skip its test.
+CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
+
+# Skip Qt5 tests because our Qt is static.
+CMake_TEST_Qt5:BOOL=FALSE
+
+# CPack package file name component for this platform.
+CPACK_SYSTEM_NAME:STRING=Linux-x86_64
diff --git a/Utilities/Release/linux/x86_64/deps/Dockerfile b/Utilities/Release/linux/x86_64/deps/Dockerfile
new file mode 100644
index 0000000..db5551c
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/deps/Dockerfile
@@ -0,0 +1,142 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# 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=$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/
+RUN : \
+ && mkdir -p /opt/qt/src/qt-build \
+ && cd /opt/qt/src \
+ && curl -OL https://download.qt.io/archive/qt/5.12/5.12.0/single/qt-everywhere-src-5.12.0.tar.xz \
+ && 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 \
+ && ../qt-everywhere-src-5.12.0/configure \
+ -prefix /opt/qt \
+ -static \
+ -release \
+ -c++std c++11 \
+ -opensource -confirm-license \
+ -gui \
+ -widgets \
+ -xcb \
+ -fontconfig \
+ -sql-sqlite \
+ -qt-doubleconversion \
+ -qt-libjpeg \
+ -qt-libpng \
+ -qt-pcre \
+ -qt-sqlite \
+ -qt-xcb \
+ -qt-xkbcommon \
+ -qt-zlib \
+ -system-freetype \
+ -no-accessibility \
+ -no-compile-examples \
+ -no-cups \
+ -no-dbus \
+ -no-directfb \
+ -no-egl \
+ -no-eglfs \
+ -no-evdev \
+ -no-gbm \
+ -no-gif \
+ -no-glib \
+ -no-gtk \
+ -no-harfbuzz \
+ -no-iconv \
+ -no-icu \
+ -no-journald \
+ -no-kms \
+ -no-libinput \
+ -no-libproxy \
+ -no-linuxfb \
+ -no-ltcg \
+ -no-mirclient \
+ -no-mtdev \
+ -no-opengl \
+ -no-openssl \
+ -no-pch \
+ -no-sql-mysql \
+ -no-sql-psql \
+ -no-sql-sqlite2 \
+ -no-syslog \
+ -no-system-proxies \
+ -no-tslib \
+ -no-use-gold-linker \
+ -skip declarative \
+ -skip multimedia \
+ -skip qtcanvas3d \
+ -skip qtconnectivity \
+ -skip qtdeclarative \
+ -skip qtlocation \
+ -skip qtmultimedia \
+ -skip qtsensors \
+ -skip qtserialport \
+ -skip qtsvg \
+ -skip qtwayland \
+ -skip qtwebchannel \
+ -skip qtwebengine \
+ -skip qtwebsockets \
+ -skip qtwinextras \
+ -skip qtxmlpatterns \
+ -nomake examples \
+ -nomake tests \
+ && make install -j $(nproc) \
+ && cd /opt/qt \
+ && patch -p1 -i src/qt-install.patch \
+ && cd /opt \
+ && rm -rf /opt/qt/src \
+ && :
+
+# Curses
+RUN : \
+ && mkdir -p /opt/ncurses/src/ncurses-build \
+ && cd /opt/ncurses/src \
+ && curl -O https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz \
+ && 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 \
+ && ../ncurses-6.1/configure \
+ --prefix=/opt/ncurses \
+ --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo \
+ --with-default-terminfo-dir=/usr/share/terminfo \
+ --without-shared \
+ && make -j $(nproc) \
+ && make install.libs install.includes \
+ && cd /opt \
+ && rm -rf /opt/ncurses/src \
+ && :
+
+# OpenSSL
+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.1c.tar.gz \
+ && sha512sum openssl-1.1.1c.tar.gz | grep -q 8e2c5cc11c120efbb7d7850980cb6eaa782d29b4996b3f3378d37613c1679f852d7cc08a90d62e78fcec3439f06bdbee70064579a8c2adaffd91532a97f646ff \
+ && tar xzf openssl-1.1.1c.tar.gz \
+ && cd openssl-1.1.1c \
+ && patch -p1 -i ../openssl-source.patch \
+ && source /opt/rh/devtoolset-6/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 \
+ && rm -rf /opt/openssl/src \
+ && :
diff --git a/Utilities/Release/linux/x86_64/deps/openssl-source.patch b/Utilities/Release/linux/x86_64/deps/openssl-source.patch
new file mode 100644
index 0000000..c81fe2f
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/deps/openssl-source.patch
@@ -0,0 +1,12 @@
+# enable pthread APIs disabled by our _POSIX_SOURCE definitions
+--- openssl-source/crypto/threads_pthread.c.orig
++++ openssl-source/crypto/threads_pthread.c
+@@ -6,6 +6,8 @@
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
++#undef _POSIX_C_SOURCE
++#undef _POSIX_SOURCE
+
+ #include <openssl/crypto.h>
+ #include "internal/cryptlib.h"
diff --git a/Utilities/Release/linux/x86_64/deps/qt-install.patch b/Utilities/Release/linux/x86_64/deps/qt-install.patch
new file mode 100644
index 0000000..792aefd
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/deps/qt-install.patch
@@ -0,0 +1,24 @@
+# Add Qt Core dependencies missing from static Qt build.
+--- qt-install/lib/cmake/Qt5Core/Qt5CoreConfig.cmake.orig
++++ qt-install/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
+@@ -111,7 +111,7 @@
+ list(REMOVE_DUPLICATES Qt5Core_COMPILE_DEFINITIONS)
+ list(REMOVE_DUPLICATES Qt5Core_EXECUTABLE_COMPILE_FLAGS)
+
+- set(_Qt5Core_LIB_DEPENDENCIES "")
++ set(_Qt5Core_LIB_DEPENDENCIES "${_qt5Core_install_prefix}/lib/libqtpcre2.a")
+
+
+ add_library(Qt5::Core STATIC IMPORTED)
+# Add Qt Gui dependencies missing from static Qt build.
+--- qt-install/lib/cmake/Qt5Gui/Qt5GuiConfig.cmake.orig
++++ qt-install/lib/cmake/Qt5Gui/Qt5GuiConfig.cmake
+@@ -111,7 +111,7 @@
+ list(REMOVE_DUPLICATES Qt5Gui_COMPILE_DEFINITIONS)
+ list(REMOVE_DUPLICATES Qt5Gui_EXECUTABLE_COMPILE_FLAGS)
+
+- set(_Qt5Gui_LIB_DEPENDENCIES "Qt5::Core")
++ set(_Qt5Gui_LIB_DEPENDENCIES "Qt5::Core;${_qt5Gui_install_prefix}/lib/libqtlibpng.a")
+
+
+ add_library(Qt5::Gui STATIC IMPORTED)
diff --git a/Utilities/Release/linux/x86_64/test/Dockerfile b/Utilities/Release/linux/x86_64/test/Dockerfile
new file mode 100644
index 0000000..6629156
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/test/Dockerfile
@@ -0,0 +1,26 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# 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=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+FROM $FROM_IMAGE
+
+RUN : \
+ && apt-get update \
+ && apt-get install -y \
+ dpkg \
+ file \
+ gcc \
+ g++ \
+ gfortran \
+ qt5-default \
+ make \
+ ninja-build \
+ && apt-get clean \
+ && :
+
+COPY test-make.bash test-ninja.bash /
diff --git a/Utilities/Release/linux/x86_64/test/cache-ninja.txt b/Utilities/Release/linux/x86_64/test/cache-ninja.txt
new file mode 100644
index 0000000..b00370e
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/test/cache-ninja.txt
@@ -0,0 +1,4 @@
+CMAKE_Fortran_COMPILER:STRING=
+CMake_TEST_IPO_WORKS_C:BOOL=ON
+CMake_TEST_IPO_WORKS_CXX:BOOL=ON
+CMake_TEST_Qt5:BOOL=ON
diff --git a/Utilities/Release/linux/x86_64/test/test-make.bash b/Utilities/Release/linux/x86_64/test/test-make.bash
new file mode 100644
index 0000000..10d30c3
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/test/test-make.bash
@@ -0,0 +1,17 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+set -e
+set -x
+mkdir -p /opt/cmake/src/cmake-make
+cd /opt/cmake/src/cmake-make
+echo >CMakeCache.txt '
+CMake_TEST_IPO_WORKS_C:BOOL=ON
+CMake_TEST_IPO_WORKS_CXX:BOOL=ON
+CMake_TEST_IPO_WORKS_Fortran:BOOL=ON
+CMake_TEST_NO_NETWORK:BOOL=ON
+CMake_TEST_Qt5:BOOL=ON
+'
+cmake ../cmake -DCMake_TEST_HOST_CMAKE=1 -G "Unix Makefiles"
+make -j $(nproc)
+ctest --output-on-failure -j $(nproc)
diff --git a/Utilities/Release/linux/x86_64/test/test-ninja.bash b/Utilities/Release/linux/x86_64/test/test-ninja.bash
new file mode 100644
index 0000000..fe39e2e
--- /dev/null
+++ b/Utilities/Release/linux/x86_64/test/test-ninja.bash
@@ -0,0 +1,17 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+set -e
+set -x
+mkdir -p /opt/cmake/src/cmake-ninja
+cd /opt/cmake/src/cmake-ninja
+echo >CMakeCache.txt '
+CMAKE_Fortran_COMPILER:STRING=
+CMake_TEST_IPO_WORKS_C:BOOL=ON
+CMake_TEST_IPO_WORKS_CXX:BOOL=ON
+CMake_TEST_NO_NETWORK:BOOL=ON
+CMake_TEST_Qt5:BOOL=ON
+'
+cmake ../cmake -DCMake_TEST_HOST_CMAKE=1 -G "Ninja"
+ninja
+ctest --output-on-failure -j $(nproc)
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
deleted file mode 100644
index 958ed25..0000000
--- a/Utilities/Release/linux64_release.cmake
+++ /dev/null
@@ -1,53 +0,0 @@
-set(PROCESSORS 4)
-set(BOOTSTRAP_ARGS "--docdir=doc/cmake")
-set(HOST linux64)
-set(MAKE_PROGRAM "make")
-set(CPACK_BINARY_GENERATORS "STGZ TGZ")
-set(CC /opt/gcc-8.2.0/bin/gcc)
-set(CXX /opt/gcc-8.2.0/bin/g++)
-set(CFLAGS "")
-set(CXXFLAGS "")
-set(qt_prefix "/home/kitware/qt-5.7.0")
-set(qt_xcb_libs
- ${qt_prefix}/plugins/platforms/libqxcb.a
- ${qt_prefix}/lib/libQt5XcbQpa.a
- ${qt_prefix}/lib/libQt5PlatformSupport.a
- ${qt_prefix}/lib/libxcb-static.a
- -lX11-xcb
- -lX11
- -lxcb
- -lfontconfig
- -lfreetype
- )
-set(INITIAL_CACHE "
-CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_C_STANDARD:STRING=11
-CMAKE_CXX_STANDARD:STRING=14
-CMAKE_C_FLAGS:STRING=-D_POSIX_C_SOURCE=199506L -D_POSIX_SOURCE=1 -D_SVID_SOURCE=1 -D_BSD_SOURCE=1
-CMAKE_EXE_LINKER_FLAGS:STRING=-static-libstdc++ -static-libgcc
-CURSES_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libncurses.a
-CURSES_INCLUDE_PATH:PATH=/home/kitware/ncurses-5.9/include
-FORM_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libform.a
-CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:STRING=/home/kitware/openssl-1.1.1/lib/libcrypto.a;-pthread
-OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.1.1/include
-OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.1.1/lib/libssl.a
-PYTHON_EXECUTABLE:FILEPATH=/usr/bin/python3
-CPACK_SYSTEM_NAME:STRING=Linux-x86_64
-BUILD_CursesDialog:BOOL=ON
-BUILD_QtDialog:BOOL=TRUE
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
-CMAKE_PREFIX_PATH:STRING=${qt_prefix}
-CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES:STRING=${qt_xcb_libs}
-")
-set(ENV [[
-export CMAKE_PREFIX_PATH=/opt/binutils-2.31
-]])
-set(SIGN "")
-
-# Exclude Qt5 tests because our Qt5 is static.
-set(EXTRA_CTEST_ARGS "-E Qt5")
-
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/osx_release.cmake b/Utilities/Release/osx_release.cmake
index ac35872..5ef3003 100644
--- a/Utilities/Release/osx_release.cmake
+++ b/Utilities/Release/osx_release.cmake
@@ -5,7 +5,7 @@ set(HOST dragnipur)
set(MAKE_PROGRAM "make")
set(MAKE "${MAKE_PROGRAM} -j5")
set(CPACK_BINARY_GENERATORS "DragNDrop TGZ")
-set(CPACK_SOURCE_GENERATORS "TGZ TZ")
+set(CPACK_SOURCE_GENERATORS "")
set(CPACK_DMG_FORMAT "UDBZ") #build using bzip2 for smaller package size
set(CC clang)
set(CXX clang++)
diff --git a/Utilities/Release/win32_release.cmake b/Utilities/Release/win32_release.cmake
index 468e5f4..14e5cba 100644
--- a/Utilities/Release/win32_release.cmake
+++ b/Utilities/Release/win32_release.cmake
@@ -5,7 +5,7 @@ set(PROCESSORS 16)
set(HOST win32)
set(RUN_LAUNCHER ~/rel/run)
set(CPACK_BINARY_GENERATORS "WIX ZIP")
-set(CPACK_SOURCE_GENERATORS "ZIP")
+set(CPACK_SOURCE_GENERATORS "")
set(MAKE_PROGRAM "ninja")
set(MAKE "${MAKE_PROGRAM} -j16")
set(qt_prefix "c:/Qt/5.12.1/msvc2017-32-w7-mt")
@@ -28,8 +28,7 @@ CMAKE_Fortran_COMPILER:FILEPATH=FALSE
CMAKE_GENERATOR:INTERNAL=Ninja
BUILD_QtDialog:BOOL=TRUE
CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
-CMAKE_C_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
-CMAKE_CXX_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
+CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x86 -subsystem:console,6.01
CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES:STRING=${qt_win_libs}
CMAKE_PREFIX_PATH:STRING=${qt_prefix}
diff --git a/Utilities/Release/win64_release.cmake b/Utilities/Release/win64_release.cmake
index 5a93ce6..149d378 100644
--- a/Utilities/Release/win64_release.cmake
+++ b/Utilities/Release/win64_release.cmake
@@ -28,8 +28,7 @@ CMAKE_Fortran_COMPILER:FILEPATH=FALSE
CMAKE_GENERATOR:INTERNAL=Ninja
BUILD_QtDialog:BOOL=TRUE
CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
-CMAKE_C_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
-CMAKE_CXX_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
+CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x64 -subsystem:console,6.01
CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES:STRING=${qt_win_libs}
CMAKE_PREFIX_PATH:STRING=${qt_prefix}
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 736a7c0..17c5018 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.1...3.15 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/bootstrap b/bootstrap
index eaccfc8..9504250 100755
--- a/bootstrap
+++ b/bootstrap
@@ -297,7 +297,6 @@ CMAKE_CXX_SOURCES="\
cmDefinitions \
cmDepends \
cmDependsC \
- cmDisallowedCommand \
cmDocumentationFormatter \
cmEnableLanguageCommand \
cmEnableTestingCommand \
@@ -436,6 +435,7 @@ CMAKE_CXX_SOURCES="\
cmTargetCompileOptionsCommand \
cmTargetIncludeDirectoriesCommand \
cmTargetLinkLibrariesCommand \
+ cmTargetPrecompileHeadersCommand \
cmTargetPropCommandBase \
cmTargetPropertyComputer \
cmTargetSourcesCommand \
@@ -1147,6 +1147,20 @@ int check_cxx14()
}
#endif
+#if __cplusplus >= 201703L
+#include <optional>
+int check_cxx17()
+{
+ std::optional<int> oi = 0;
+ return oi.value();
+}
+#else
+int check_cxx17()
+{
+ return 0;
+}
+#endif
+
class Class
{
public:
@@ -1157,7 +1171,7 @@ private:
int main()
{
auto const c = std::unique_ptr<Class>(new Class);
- std::cout << c->Get() << check_cxx14() << std::endl;
+ std::cout << c->Get() << check_cxx14() << check_cxx17() << std::endl;
return 0;
}
' > "${TMPFILE}.cxx"