diff options
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) @@ -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" |