diff options
651 files changed, 8814 insertions, 8128 deletions
diff --git a/.clang-tidy b/.clang-tidy index cfca64e..a520679 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,16 +7,10 @@ bugprone-*,\ -bugprone-too-small-loop-variable,\ google-readability-casting,\ misc-*,\ --misc-incorrect-roundings,\ --misc-macro-parentheses,\ --misc-misplaced-widening-cast,\ -misc-non-private-member-variables-in-classes,\ -misc-static-assert,\ modernize-*,\ -modernize-avoid-c-arrays,\ --modernize-deprecated-headers,\ --modernize-return-braced-init-list,\ --modernize-use-auto,\ -modernize-use-nodiscard,\ -modernize-use-noexcept,\ -modernize-use-transparent-functors,\ @@ -24,7 +18,6 @@ performance-*,\ readability-*,\ -readability-function-size,\ -readability-identifier-naming,\ --readability-implicit-bool-cast,\ -readability-implicit-bool-conversion,\ -readability-inconsistent-declaration-parameter-name,\ -readability-magic-numbers,\ @@ -38,4 +31,6 @@ CheckOptions: value: '1' - key: modernize-use-equals-default.IgnoreMacros value: '0' + - key: modernize-use-auto.MinTypeNameLength + value: '80' ... diff --git a/CMakeLists.txt b/CMakeLists.txt index 21e8c46..da99a6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,11 +368,24 @@ macro (CMAKE_BUILD_UTILITIES) # Setup third-party libraries. # Everything in the tree should be able to include files from the # Utilities directory. + if (CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # using -isystem option generate error "template with C linkage" + include_directories("${CMake_SOURCE_DIR}/Utilities/std") + else() + include_directories(SYSTEM "${CMake_SOURCE_DIR}/Utilities/std") + endif() + include_directories( ${CMake_BINARY_DIR}/Utilities ${CMake_SOURCE_DIR}/Utilities ) + #--------------------------------------------------------------------- + # Build CMake std library for CMake and CTest. + set(CMAKE_STD_LIBRARY cmstd) + add_subdirectory(Utilities/std) + CMAKE_SET_TARGET_FOLDER(cmstd "Utilities/std") + # check for the use of system libraries versus builtin ones # (a macro defined in this file) CMAKE_HANDLE_SYSTEM_LIBRARIES() diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index ed321fc..ab2a023 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -68,9 +68,6 @@ The options are: order-only dependencies to ensure the byproducts will be available before their dependents build. - The ``BYPRODUCTS`` option is ignored on non-Ninja generators - except to mark byproducts ``GENERATED``. - ``COMMAND`` Specify the command-line(s) to execute at build time. If more than one ``COMMAND`` is specified they will be executed in order, @@ -111,6 +108,9 @@ The options are: an ``OUTPUT`` of another custom command in the same directory (``CMakeLists.txt`` file) CMake automatically brings the other custom command into the target in which this command is built. + A target-level dependency is added if any dependency is listed as + ``BYPRODUCTS`` of a target or any of its build events in the same + directory to ensure the byproducts will be available. If ``DEPENDS`` is not specified the command will run whenever the ``OUTPUT`` is missing; if the command does not actually create the ``OUTPUT`` then the rule will always run. diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst index 08b9516..e74960c 100644 --- a/Help/command/add_custom_target.rst +++ b/Help/command/add_custom_target.rst @@ -49,9 +49,6 @@ The options are: order-only dependencies to ensure the byproducts will be available before their dependents build. - The ``BYPRODUCTS`` option is ignored on non-Ninja generators - except to mark byproducts ``GENERATED``. - ``COMMAND`` Specify the command-line(s) to execute at build time. If more than one ``COMMAND`` is specified they will be executed in order, @@ -86,6 +83,9 @@ The options are: :command:`add_custom_command` command calls in the same directory (``CMakeLists.txt`` file). They will be brought up to date when the target is built. + A target-level dependency is added if any dependency is a byproduct + of a target or any of its build events in the same directory to ensure + the byproducts will be available before this target is built. Use the :command:`add_dependencies` command to add dependencies on other targets. diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst index 3e28265..3a32f41 100644 --- a/Help/command/target_precompile_headers.rst +++ b/Help/command/target_precompile_headers.rst @@ -9,9 +9,23 @@ Add a list of header files to precompile. <INTERFACE|PUBLIC|PRIVATE> [header1...] [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...]) + target_precompile_headers(<target> REUSE_FROM <other_target>) + Adds header files to :prop_tgt:`PRECOMPILE_HEADERS` or :prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` target properties. +The second signature will reuse an already precompiled header file artefact +from another target. This is done by setting the +:prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` to ``<other_target>`` value. +The ``<other_target>`` will become a dependency of ``<target>``. + +.. note:: + + The second signature will require the same set of compiler options, + compiler flags, compiler definitions for both ``<target>``, and + ``<other_target>``. Compilers (e.g. GCC) will issue a warning if the + precompiled header file cannot be used (``-Winvalid-pch``). + 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. @@ -34,17 +48,32 @@ 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. +Usage +^^^^^ + .. code-block:: cmake target_precompile_headers(<target> PUBLIC - "project_header.h" + project_header.h PRIVATE + [["other_header.h"]] <unordered_map> ) -Header files will be double quoted if they are not specified with double -quotes or angle brackets. +The list of header files is used to generate a header file named +``cmake_pch.h|xx`` which is used to generate the precompiled header file +(``.pch``, ``.gch``, ``.pchi``) artifact. The ``cmake_pch.h|xx`` header +file will be force included (``-include`` for GCC, ``/FI`` for MSVC) to +all source files, so sources do not need to have ``#include "pch.h"``. + +Header file names specified with angle brackets (e.g. ``<unordered_map>``) or +explicit double quotes (escaped for the :manual:`cmake-language(7)`, +e.g. ``[["other_header.h"]]``) will be treated as is, and include directories +must be available for the compiler to find them. Other header file names +(e.g. ``project_header.h``) are interpreted as being relative to the current +source directory (e.g. :variable:`CMAKE_CURRENT_SOURCE_DIR`) and will be +included by absolute path. See Also ^^^^^^^^ diff --git a/Help/cpack_gen/wix.rst b/Help/cpack_gen/wix.rst index dde4943..7fb5a12 100644 --- a/Help/cpack_gen/wix.rst +++ b/Help/cpack_gen/wix.rst @@ -95,6 +95,10 @@ Windows using WiX. If this variable is not set, it will be initialized with CPACK_PACKAGE_NAME + If this variable is set to ``.``, then application shortcuts will be + created directly in the start menu and the uninstaller shortcut will be + omitted. + .. variable:: CPACK_WIX_CULTURES Language(s) of the installer diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 19afb7d..8f8cb33 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -134,6 +134,7 @@ Properties on Targets /prop_tgt/AUTOMOC_EXECUTABLE /prop_tgt/AUTOMOC_MACRO_NAMES /prop_tgt/AUTOMOC_MOC_OPTIONS + /prop_tgt/AUTOMOC_PATH_PREFIX /prop_tgt/AUTOMOC /prop_tgt/AUTOUIC /prop_tgt/AUTOUIC_EXECUTABLE @@ -298,6 +299,7 @@ Properties on Targets /prop_tgt/PDB_OUTPUT_DIRECTORY /prop_tgt/POSITION_INDEPENDENT_CODE /prop_tgt/PRECOMPILE_HEADERS + /prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM /prop_tgt/PREFIX /prop_tgt/PRIVATE_HEADER /prop_tgt/PROJECT_LABEL diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 2d473d8..def63e4 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -342,6 +342,7 @@ Variables that Control the Build /variable/CMAKE_AUTOMOC_DEPEND_FILTERS /variable/CMAKE_AUTOMOC_MACRO_NAMES /variable/CMAKE_AUTOMOC_MOC_OPTIONS + /variable/CMAKE_AUTOMOC_PATH_PREFIX /variable/CMAKE_AUTORCC /variable/CMAKE_AUTORCC_OPTIONS /variable/CMAKE_AUTOUIC diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 2576cde..754f14b 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -473,6 +473,12 @@ Available commands are: directory and it must exist. ``copy_if_different`` does follow symlinks. +``create_symlink <old> <new>`` + Create a symbolic link ``<new>`` naming ``<old>``. + + .. note:: + Path to where ``<new>`` symbolic link will be created has to exist beforehand. + ``echo [<string>...]`` Displays arguments as text. @@ -485,6 +491,9 @@ Available commands are: ``environment`` Display the current environment variables. +``false`` + Do nothing, with an exit code of 1. + ``make_directory <dir>...`` Create ``<dir>`` directories. If necessary, create parent directories too. If a directory already exists it will be @@ -602,18 +611,9 @@ Available commands are: Touch a file if it exists but do not create it. If a file does not exist it will be silently ignored. -``create_symlink <old> <new>`` - Create a symbolic link ``<new>`` naming ``<old>``. - -.. note:: - Path to where ``<new>`` symbolic link will be created has to exist beforehand. - ``true`` Do nothing, with an exit code of 0. -``false`` - Do nothing, with an exit code of 1. - Windows-specific Command-Line Tools ----------------------------------- diff --git a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst new file mode 100644 index 0000000..e2ebb3f --- /dev/null +++ b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst @@ -0,0 +1,32 @@ +AUTOMOC_PATH_PREFIX +------------------- + +When this property is ``ON``, CMake will generate the ``-p`` path prefix +option for ``moc`` on :prop_tgt:`AUTOMOC` enabled Qt targets. + +To generate the path prefix, CMake tests if the header compiled by ``moc`` +is in any of the target +:command:`include directories <target_include_directories>`. If so, CMake will +compute the relative path accordingly. If the header is not in the +:command:`include directories <target_include_directories>`, CMake will omit +the ``-p`` path prefix option. ``moc`` usually generates a +relative include path in that case. + +:prop_tgt:`AUTOMOC_PATH_PREFIX` is initialized from the variable +:variable:`CMAKE_AUTOMOC_PATH_PREFIX`, which is ``ON`` by default. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. + +Reproducible builds +^^^^^^^^^^^^^^^^^^^ + +For reproducible builds is is recommended to keep headers that are ``moc`` +compiled in one of the target +:command:`include directories <target_include_directories>` and set +:prop_tgt:`AUTOMOC_PATH_PREFIX` to ``ON`` (which is the default). This ensures +that + +- ``moc`` output files are identical on different build setups, +- ``moc`` output files will compile correctly when the source and/or + build directory is a symbolic link. diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst new file mode 100644 index 0000000..d740303 --- /dev/null +++ b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst @@ -0,0 +1,7 @@ +PRECOMPILE_HEADERS_REUSE_FROM +----------------------------- + +Target from which to reuse the precomipled headers build artifact. + +See the second signature of :command:`target_precompile_headers` command +for more detailed information. diff --git a/Help/release/dev/FindGnuTLS-target.rst b/Help/release/dev/FindGnuTLS-target.rst new file mode 100644 index 0000000..671a7b7 --- /dev/null +++ b/Help/release/dev/FindGnuTLS-target.rst @@ -0,0 +1,4 @@ +FindGnuTLS-target +----------------- + +* The :module:`FindGnuTLS` module now provides an imported target. diff --git a/Help/release/dev/automoc_path_prefix.rst b/Help/release/dev/automoc_path_prefix.rst new file mode 100644 index 0000000..bee1b32 --- /dev/null +++ b/Help/release/dev/automoc_path_prefix.rst @@ -0,0 +1,13 @@ +automoc_path_prefix +------------------- + +* When using :prop_tgt:`AUTOMOC`, CMake now generates the ``-p`` path prefix + option for ``moc``. This ensures that ``moc`` output files are identical + on different build setups (given, that the headers compiled by ``moc`` are + in an :command:`include directory <target_include_directories>`). + Also it ensures that ``moc`` output files will compile correctly when the + source and/or build directory is a symbolic link. + + The ``moc`` path prefix generation behavior can be configured by setting + the new :variable:`CMAKE_AUTOMOC_PATH_PREFIX` variable and/or + :prop_tgt:`AUTOMOC_PATH_PREFIX` target property. diff --git a/Help/release/dev/windows-auto-export-incremental-build.rst b/Help/release/dev/windows-auto-export-incremental-build.rst new file mode 100644 index 0000000..3126329 --- /dev/null +++ b/Help/release/dev/windows-auto-export-incremental-build.rst @@ -0,0 +1,6 @@ +windows-auto-export-incremental-build +------------------------------------- + +* On Windows, existing auto generated exports are now only updated if the + modified time stamp of the exports is not newer than any modified time stamp + of the input files. diff --git a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst new file mode 100644 index 0000000..dca0b06 --- /dev/null +++ b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst @@ -0,0 +1,11 @@ +CMAKE_AUTOMOC_PATH_PREFIX +------------------------- + +Whether to generate the ``-p`` path prefix option for ``moc`` on +:prop_tgt:`AUTOMOC` enabled Qt targets. + +This variable is used to initialize the :prop_tgt:`AUTOMOC_PATH_PREFIX` +property on all the targets. See that target property for additional +information. + +The default value is ``ON``. diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst index 77e1ea9..f4a33e2 100644 --- a/Help/variable/MSVC_TOOLSET_VERSION.rst +++ b/Help/variable/MSVC_TOOLSET_VERSION.rst @@ -14,6 +14,7 @@ Known toolset version numbers are:: 120 = VS 2013 (12.0) 140 = VS 2015 (14.0) 141 = VS 2017 (15.0) + 142 = VS 2019 (16.0) Compiler versions newer than those known to CMake will be reported as the latest known toolset version. diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 01f9dae..781b48c 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -134,7 +134,7 @@ else() endif() if(CMAKE_PLATFORM_HAS_INSTALLNAME) - find_program(CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + find_program(CMAKE_INSTALL_NAME_TOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) if(NOT CMAKE_INSTALL_NAME_TOOL) message(FATAL_ERROR "Could not find install_name_tool, please check your installation.") diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index ddfc7bd..77d8cfd 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -26,6 +26,7 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) +set(CMAKE_AUTOMOC_PATH_PREFIX ON) set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE") # basically all general purpose OSs support shared libs diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index 542a6fe..95465ce 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -174,6 +174,9 @@ # elif defined(__ICC430__) # define ARCHITECTURE_ID "MSP430" +# elif defined(__ICCV850__) +# define ARCHITECTURE_ID "V850" + # else /* unknown architecture */ # define ARCHITECTURE_ID "" # endif diff --git a/Modules/Compiler/IAR-ASM.cmake b/Modules/Compiler/IAR-ASM.cmake index 437678e..413d9e2 100644 --- a/Modules/Compiler/IAR-ASM.cmake +++ b/Modules/Compiler/IAR-ASM.cmake @@ -37,6 +37,11 @@ elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430") __compiler_iar_xlink(ASM) set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s43;asm;msa) +elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850") + set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") + __compiler_iar_xlink(ASM) + set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS r85;asm;msa) + else() message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID not detected. This should be automatic.") endif() diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake index e03ce3f..9ad1ba0 100644 --- a/Modules/Compiler/IAR-C.cmake +++ b/Modules/Compiler/IAR-C.cmake @@ -60,6 +60,11 @@ elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430") __compiler_check_default_language_standard(C 1.10 90 5.10 99) set(CMAKE_C_OUTPUT_EXTENSION ".r43") +elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850") + __compiler_iar_xlink(C) + __compiler_check_default_language_standard(C 1.10 90 4.10 99) + set(CMAKE_C_OUTPUT_EXTENSION ".r85") + else() message(FATAL_ERROR "CMAKE_C_COMPILER_ARCHITECTURE_ID not detected. This should be automatic.") endif() diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake index e8f1142..549d242 100644 --- a/Modules/Compiler/IAR-CXX.cmake +++ b/Modules/Compiler/IAR-CXX.cmake @@ -68,6 +68,10 @@ elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430") __compiler_check_default_language_standard(CXX 5.10 98) set(CMAKE_CXX_OUTPUT_EXTENSION ".r43") +elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850") + __compiler_iar_xlink(CXX) + __compiler_check_default_language_standard(CXX 1.10 98) + set(CMAKE_C_OUTPUT_EXTENSION ".r85") else() message(FATAL_ERROR "CMAKE_CXX_COMPILER_ARCHITECTURE_ID not detected. This should be automatic." ) endif() diff --git a/Modules/Compiler/IAR-DetermineCompiler.cmake b/Modules/Compiler/IAR-DetermineCompiler.cmake index 57ca1c9..7e17778 100644 --- a/Modules/Compiler/IAR-DetermineCompiler.cmake +++ b/Modules/Compiler/IAR-DetermineCompiler.cmake @@ -31,7 +31,7 @@ set(_compiler_id_version_compute " # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(((__VER__) / 1000) % 1000) # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@((__VER__) % 1000) # define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__IAR_SYSTEMS_ICC__) -# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__)) +# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__)) # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@((__VER__) / 100) # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@((__VER__) - (((__VER__) / 100)*100)) # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__SUBVERSION__) diff --git a/Modules/Compiler/IAR-FindBinUtils.cmake b/Modules/Compiler/IAR-FindBinUtils.cmake index b7d4664..6258cf3 100644 --- a/Modules/Compiler/IAR-FindBinUtils.cmake +++ b/Modules/Compiler/IAR-FindBinUtils.cmake @@ -45,7 +45,8 @@ set(CMAKE_IAR_LINKER \"${CMAKE_IAR_LINKER}\") ") elseif("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR" OR - "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430") + "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430" OR + "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "V850") # Find the "xlink" linker and "xar" archiver: find_program(CMAKE_IAR_LINKER xlink HINTS ${__iar_hints} diff --git a/Modules/FindGnuTLS.cmake b/Modules/FindGnuTLS.cmake index 123a0f5..819f000 100644 --- a/Modules/FindGnuTLS.cmake +++ b/Modules/FindGnuTLS.cmake @@ -7,16 +7,25 @@ FindGnuTLS Find the GNU Transport Layer Security library (gnutls) - - -Once done this will define - -:: - - GNUTLS_FOUND - System has gnutls - GNUTLS_INCLUDE_DIR - The gnutls include directory - GNUTLS_LIBRARIES - The libraries needed to use gnutls - GNUTLS_DEFINITIONS - Compiler switches required for using gnutls +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``GnuTLS::GnuTLS``, if +gnutls has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +``GNUTLS_FOUND`` + System has gnutls +``GNUTLS_INCLUDE_DIR`` + The gnutls include directory +``GNUTLS_LIBRARIES`` + The libraries needed to use gnutls +``GNUTLS_DEFINITIONS`` + Compiler switches required for using gnutls +``GNUTLS_VERSION`` + version of gnutls. #]=======================================================================] # Note that this doesn't try to find the gnutls-extra package. @@ -34,6 +43,8 @@ if (NOT WIN32) find_package(PkgConfig QUIET) PKG_CHECK_MODULES(PC_GNUTLS QUIET gnutls) set(GNUTLS_DEFINITIONS ${PC_GNUTLS_CFLAGS_OTHER}) + set(GNUTLS_VERSION ${PC_GNUTLS_VERSION}) + # keep for backward compatibility set(GNUTLS_VERSION_STRING ${PC_GNUTLS_VERSION}) endif () @@ -59,4 +70,13 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GnuTLS if(GNUTLS_FOUND) set(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY}) set(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR}) + + if(NOT TARGET GnuTLS::GnuTLS) + add_library(GnuTLS::GnuTLS UNKNOWN IMPORTED) + set_target_properties(GnuTLS::GnuTLS PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${GNUTLS_INCLUDE_DIRS}" + INTERFACE_COMPILE_DEFINITIONS "${GNUTLS_DEFINITIONS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${GNUTLS_LIBRARIES}") + endif() endif() diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index 5f947fe..33ceab7 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -35,10 +35,14 @@ This module will set the following variables in your project: The OpenSSL include directory. ``OPENSSL_CRYPTO_LIBRARY`` The OpenSSL crypto library. +``OPENSSL_CRYPTO_LIBRARIES`` + The OpenSSL crypto library and its dependencies. ``OPENSSL_SSL_LIBRARY`` The OpenSSL SSL library. +``OPENSSL_SSL_LIBRARIES`` + The OpenSSL SSL library and its dependencies. ``OPENSSL_LIBRARIES`` - All OpenSSL libraries. + All OpenSSL libraries and their dependencies. ``OPENSSL_VERSION`` This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``). @@ -50,6 +54,32 @@ Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries. Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib. #]=======================================================================] +macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library) + if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND + (("${ssl_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") OR + ("${crypto_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$"))) + set(_OpenSSL_has_dependencies TRUE) + find_package(Threads) + else() + set(_OpenSSL_has_dependencies FALSE) + endif() +endmacro() + +function(_OpenSSL_add_dependencies libraries_var library) + if(CMAKE_THREAD_LIBS_INIT) + list(APPEND ${libraries_var} ${CMAKE_THREAD_LIBS_INIT}) + endif() + list(APPEND ${libraries_var} ${CMAKE_DL_LIBS}) + set(${libraries_var} ${${libraries_var}} PARENT_SCOPE) +endfunction() + +function(_OpenSSL_target_add_dependencies target) + if(_OpenSSL_has_dependencies) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads ) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} ) + endif() +endfunction() + if (UNIX) find_package(PkgConfig QUIET) pkg_check_modules(_OPENSSL QUIET openssl) @@ -306,10 +336,15 @@ else() mark_as_advanced(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY) - # compat defines - set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) - set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) +endif() +# compat defines +set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) +set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) +_OpenSSL_test_and_find_dependencies("${OPENSSL_SSL_LIBRARY}" "${OPENSSL_CRYPTO_LIBRARY}") +if(_OpenSSL_has_dependencies) + _OpenSSL_add_dependencies( OPENSSL_SSL_LIBRARIES "${OPENSSL_SSL_LIBRARY}" ) + _OpenSSL_add_dependencies( OPENSSL_CRYPTO_LIBRARIES "${OPENSSL_CRYPTO_LIBRARY}" ) endif() function(from_hex HEX DEC) @@ -379,7 +414,8 @@ if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") endif () endif () -set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ) +set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} ) +list(REMOVE_DUPLICATES OPENSSL_LIBRARIES) foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS) if(_comp STREQUAL "Crypto") @@ -451,6 +487,7 @@ if(OPENSSL_FOUND) IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}") endif() + _OpenSSL_target_add_dependencies(OpenSSL::Crypto) endif() if(NOT TARGET OpenSSL::SSL AND @@ -484,6 +521,7 @@ if(OPENSSL_FOUND) set_target_properties(OpenSSL::SSL PROPERTIES INTERFACE_LINK_LIBRARIES OpenSSL::Crypto) endif() + _OpenSSL_target_add_dependencies(OpenSSL::SSL) endif() endif() diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index 4c9af91..5162a44 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -214,7 +214,11 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path) NAMES ${_pkg_search} ${_find_opts}) mark_as_advanced(pkgcfg_lib_${_prefix}_${_pkg_search}) - list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}") + if(pkgcfg_lib_${_prefix}_${_pkg_search}) + list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}") + else() + list(APPEND _libs ${_pkg_search}) + endif() endforeach() set(${_prefix}_LINK_LIBRARIES "${_libs}" PARENT_SCOPE) diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake index b0c91b2..d39fe33 100644 --- a/Modules/FindThreads.cmake +++ b/Modules/FindThreads.cmake @@ -77,7 +77,7 @@ macro(_check_threads_lib LIBNAME FUNCNAME VARNAME) if(NOT Threads_FOUND) CHECK_LIBRARY_EXISTS(${LIBNAME} ${FUNCNAME} "" ${VARNAME}) if(${VARNAME}) - set(CMAKE_THREAD_LIBS_INIT "-l${LIBNAME}") + set(CMAKE_THREAD_LIBS_INIT "${LIBNAME}") set(CMAKE_HAVE_THREADS_LIBRARY 1) set(Threads_FOUND TRUE) endif() @@ -88,7 +88,7 @@ endmacro() # Do NOT even think about using it outside of this file! macro(_check_pthreads_flag) if(NOT Threads_FOUND) - # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread + # If we did not find a thread library look for -pthread compiler option. if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG) message(STATUS "Check if compiler accepts -pthread") if(CMAKE_C_COMPILER_LOADED) @@ -164,7 +164,7 @@ if(CMAKE_HAVE_PTHREAD_H) _check_threads_lib(pthreads pthread_create CMAKE_HAVE_PTHREADS_CREATE) _check_threads_lib(pthread pthread_create CMAKE_HAVE_PTHREAD_CREATE) if(CMAKE_SYSTEM_NAME MATCHES "SunOS") - # On sun also check for -lthread + # On sun also check for thread library with thr_create _check_threads_lib(thread thr_create CMAKE_HAVE_THR_CREATE) endif() endif() @@ -195,7 +195,7 @@ if(CMAKE_USE_PTHREADS_INIT) # are available. CHECK_LIBRARY_EXISTS(cma pthread_attr_create "" CMAKE_HAVE_HP_CMA) if(CMAKE_HAVE_HP_CMA) - set(CMAKE_THREAD_LIBS_INIT "-lcma") + set(CMAKE_THREAD_LIBS_INIT "cma") set(CMAKE_HP_PTHREADS_INIT 1) set(Threads_FOUND TRUE) endif() diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 6ddcaa3..34f5d03 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -333,10 +333,17 @@ macro(__windows_compiler_msvc lang) set(CMAKE_LINK_PCH ON) if(MSVC_VERSION GREATER_EQUAL 1910) # VS 2017 or greater - set(CMAKE_PCH_PROLOGUE "#pragma system_header") + if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang") + set(CMAKE_PCH_PROLOGUE "#pragma system_header") + else() + set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + endif() + endif() + if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang") + set(CMAKE_PCH_COPY_COMPILE_PDB ON) 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>) + set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /Fp<PCH_FILE> /FI<PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /Fp<PCH_FILE> /FI<PCH_HEADER>) if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index decb39a..8ed7b2f 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -191,6 +191,8 @@ set(SRCS cmCustomCommand.h cmCustomCommandGenerator.cxx cmCustomCommandGenerator.h + cmCustomCommandLines.cxx + cmCustomCommandLines.h cmDefinitions.cxx cmDefinitions.h cmDepends.cxx @@ -224,8 +226,6 @@ set(SRCS cmExportTryCompileFileGenerator.cxx cmExportSet.h cmExportSet.cxx - cmExportSetMap.h - cmExportSetMap.cxx cmExternalMakefileProjectGenerator.cxx cmExternalMakefileProjectGenerator.h cmExtraCodeBlocksGenerator.cxx @@ -437,9 +437,6 @@ set(SRCS cmXMLWriter.h cmake.cxx cmake.h - cm_string_view.cxx - cm_string_view.hxx - cm_static_string_view.hxx cmCommand.cxx cmCommand.h @@ -681,13 +678,13 @@ set(SRCS cmWriteFileCommand.cxx cmWriteFileCommand.h + cm_static_string_view.hxx cm_get_date.h cm_get_date.c cm_utf8.h cm_utf8.c cm_codecvt.hxx cm_codecvt.cxx - cm_thread.hxx cmDuration.h cmDuration.cxx @@ -853,6 +850,7 @@ endforeach() # create a library used by the command line and the GUI add_library(CMakeLib ${SRCS}) target_link_libraries(CMakeLib cmsys + ${CMAKE_STD_LIBRARY} ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES} ${CMAKE_TAR_LIBRARIES} ${CMAKE_CURL_LIBRARIES} diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index fd605fa..d24c2c0 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 20190908) +set(CMake_VERSION_PATCH 20190925) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index d1ffcef..94530c1 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -77,8 +77,7 @@ int cmCPackIFWGenerator::PackageFiles() if (!this->OnlineOnly && !this->DownloadedPackages.empty()) { ifwCmd.emplace_back("-i"); - std::set<cmCPackIFWPackage*>::iterator it = - this->DownloadedPackages.begin(); + auto it = this->DownloadedPackages.begin(); ifwArg = (*it)->Name; ++it; while (it != this->DownloadedPackages.end()) { @@ -137,8 +136,7 @@ int cmCPackIFWGenerator::PackageFiles() if (!this->Installer.Resources.empty()) { ifwCmd.emplace_back("-r"); - std::vector<std::string>::iterator it = - this->Installer.Resources.begin(); + auto it = this->Installer.Resources.begin(); std::string path = this->toplevel + "/resources/"; ifwArg = path + *it; ++it; @@ -180,8 +178,7 @@ int cmCPackIFWGenerator::PackageFiles() } else if (!this->DownloadedPackages.empty() && !this->Installer.RemoteRepositories.empty()) { ifwCmd.emplace_back("-e"); - std::set<cmCPackIFWPackage*>::iterator it = - this->DownloadedPackages.begin(); + auto it = this->DownloadedPackages.begin(); ifwArg = (*it)->Name; ++it; while (it != this->DownloadedPackages.end()) { @@ -193,14 +190,13 @@ int cmCPackIFWGenerator::PackageFiles() ifwCmd.emplace_back("-i"); ifwArg.clear(); // Binary - std::set<cmCPackIFWPackage*>::iterator bit = - this->BinaryPackages.begin(); + auto bit = this->BinaryPackages.begin(); while (bit != this->BinaryPackages.end()) { ifwArg += (*bit)->Name + ","; ++bit; } // Depend - DependenceMap::iterator it = this->DependentPackages.begin(); + auto it = this->DependentPackages.begin(); ifwArg += it->second.Name; ++it; while (it != this->DependentPackages.end()) { @@ -410,7 +406,7 @@ std::string cmCPackIFWGenerator::GetComponentInstallDirNameSuffix( cmCPackComponent* cmCPackIFWGenerator::GetComponent( const std::string& projectName, const std::string& componentName) { - ComponentsMap::iterator cit = this->Components.find(componentName); + auto cit = this->Components.find(componentName); if (cit != this->Components.end()) { return &(cit->second); } @@ -422,7 +418,7 @@ cmCPackComponent* cmCPackIFWGenerator::GetComponent( } std::string name = this->GetComponentPackageName(component); - PackagesMap::iterator pit = this->Packages.find(name); + auto pit = this->Packages.find(name); if (pit != this->Packages.end()) { return component; } @@ -462,7 +458,7 @@ cmCPackComponentGroup* cmCPackIFWGenerator::GetComponentGroup( } std::string name = this->GetGroupPackageName(group); - PackagesMap::iterator pit = this->Packages.find(name); + auto pit = this->Packages.find(name); if (pit != this->Packages.end()) { return group; } @@ -593,23 +589,21 @@ std::string cmCPackIFWGenerator::GetComponentPackageName( cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage( cmCPackComponentGroup* group) const { - std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit = - this->GroupPackages.find(group); + auto pit = this->GroupPackages.find(group); return pit != this->GroupPackages.end() ? pit->second : nullptr; } cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage( cmCPackComponent* component) const { - std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit = - this->ComponentPackages.find(component); + auto pit = this->ComponentPackages.find(component); return pit != this->ComponentPackages.end() ? pit->second : nullptr; } cmCPackIFWRepository* cmCPackIFWGenerator::GetRepository( const std::string& repositoryName) { - RepositoriesMap::iterator rit = this->Repositories.find(repositoryName); + auto rit = this->Repositories.find(repositoryName); if (rit != this->Repositories.end()) { return &(rit->second); } diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index b4bfea7..2393279 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -13,8 +13,8 @@ #include "cmXMLParser.h" #include "cmXMLWriter.h" +#include <cstddef> #include <sstream> -#include <stddef.h> #include <utility> cmCPackIFWInstaller::cmCPackIFWInstaller() = default; diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index fb75145..9f2a443 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -13,9 +13,9 @@ #include "cmTimestamp.h" #include "cmXMLWriter.h" +#include <cstddef> #include <map> #include <sstream> -#include <stddef.h> #include <utility> //---------------------------------------------------------- CompareStruct --- @@ -620,7 +620,7 @@ void cmCPackIFWPackage::GeneratePackageFile() // Write dependencies if (!compDepSet.empty()) { std::ostringstream dependencies; - std::set<DependenceStruct>::iterator it = compDepSet.begin(); + auto it = compDepSet.begin(); dependencies << it->NameWithCompare(); ++it; while (it != compDepSet.end()) { @@ -638,7 +638,7 @@ void cmCPackIFWPackage::GeneratePackageFile() // Write automatic dependency on if (!compAutoDepSet.empty()) { std::ostringstream dependencies; - std::set<DependenceStruct>::iterator it = compAutoDepSet.begin(); + auto it = compAutoDepSet.begin(); dependencies << it->NameWithCompare(); ++it; while (it != compAutoDepSet.end()) { @@ -674,7 +674,7 @@ void cmCPackIFWPackage::GeneratePackageFile() // Replaces if (!this->Replaces.empty()) { std::ostringstream replaces; - std::vector<std::string>::iterator it = this->Replaces.begin(); + auto it = this->Replaces.begin(); replaces << *it; ++it; while (it != this->Replaces.end()) { diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx index 8042167..82ddbdb 100644 --- a/Source/CPack/IFW/cmCPackIFWRepository.cxx +++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx @@ -8,7 +8,7 @@ #include "cmXMLParser.h" #include "cmXMLWriter.h" -#include <stddef.h> +#include <cstddef> cmCPackIFWRepository::cmCPackIFWRepository() : Update(cmCPackIFWRepository::None) diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx index 00d272c..b8f12fd 100644 --- a/Source/CPack/OSXScriptLauncher.cxx +++ b/Source/CPack/OSXScriptLauncher.cxx @@ -3,8 +3,9 @@ #include "cmsys/FStream.hxx" #include "cmsys/Process.h" #include "cmsys/SystemTools.hxx" + +#include <cstddef> #include <iostream> -#include <stddef.h> #include <string> #include <vector> diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index b0b2df2..683f275 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -11,8 +11,9 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUuid.h" -#include "cm_string_view.hxx" + #include <algorithm> +#include <cm/string_view> #include "cmWIXDirectoriesSourceWriter.h" #include "cmWIXFeaturesSourceWriter.h" @@ -537,9 +538,16 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() } } - bool emitUninstallShortcut = - emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) != - emittedShortcutTypes.end(); + bool emitUninstallShortcut = true; + const char* cpackWixProgramMenuFolder = + GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); + if (cpackWixProgramMenuFolder && + cm::string_view(cpackWixProgramMenuFolder) == ".") { + emitUninstallShortcut = false; + } else if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) == + emittedShortcutTypes.end()) { + emitUninstallShortcut = false; + } if (!CreateShortcuts(std::string(), "ProductFeature", globalShortcuts, emitUninstallShortcut, fileDefinitions, @@ -733,9 +741,16 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType( { std::string directoryId; switch (type) { - case cmWIXShortcuts::START_MENU: - directoryId = "PROGRAM_MENU_FOLDER"; - break; + case cmWIXShortcuts::START_MENU: { + const char* cpackWixProgramMenuFolder = + GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); + if (cpackWixProgramMenuFolder && + cm::string_view(cpackWixProgramMenuFolder) == ".") { + directoryId = "ProgramMenuFolder"; + } else { + directoryId = "PROGRAM_MENU_FOLDER"; + } + } break; case cmWIXShortcuts::DESKTOP: directoryId = "DesktopFolder"; break; @@ -789,8 +804,13 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType( fileDefinitions); if (type == cmWIXShortcuts::START_MENU) { - fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" + - idSuffix); + const char* cpackWixProgramMenuFolder = + GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); + if (cpackWixProgramMenuFolder && + cm::string_view(cpackWixProgramMenuFolder) != ".") { + fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" + + idSuffix); + } } if (emitUninstallShortcut) { diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx index 975dffb..0a83ca2 100644 --- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx @@ -14,10 +14,12 @@ void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder( BeginElement("Directory"); AddAttribute("Id", "ProgramMenuFolder"); - BeginElement("Directory"); - AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - AddAttribute("Name", startMenuFolder); - EndElement("Directory"); + if (startMenuFolder != ".") { + BeginElement("Directory"); + AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + AddAttribute("Name", startMenuFolder); + EndElement("Directory"); + } EndElement("Directory"); } diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx index dd3caf9..7705d83 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx @@ -9,10 +9,10 @@ #include "cmSystemTools.h" #include "cmUuid.h" -#include "cm_sys_stat.h" - #include "cmCMakeToWixPath.h" +#include "cm_sys_stat.h" + cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger, std::string const& filename, GuidType componentGuidType) diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index cefbc90..4f299f7 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -10,13 +10,15 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cm_sys_stat.h" #include "cmsys/Glob.hxx" + +#include "cm_sys_stat.h" + +#include <cstring> #include <map> #include <ostream> #include <set> -#include <string.h> #include <utility> namespace { diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index ca06b81..bedbfa8 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -12,9 +12,9 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include <cstdlib> #include <iomanip> #include <map> -#include <stdlib.h> #include <CoreFoundation/CoreFoundation.h> diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx index 5dc6ace..05e5c21 100644 --- a/Source/CPack/cmCPackExternalGenerator.cxx +++ b/Source/CPack/cmCPackExternalGenerator.cxx @@ -17,7 +17,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> int cmCPackExternalGenerator::InitializeInternal() { diff --git a/Source/CPack/cmCPackExternalGenerator.h b/Source/CPack/cmCPackExternalGenerator.h index 176d6a9..b77e45b 100644 --- a/Source/CPack/cmCPackExternalGenerator.h +++ b/Source/CPack/cmCPackExternalGenerator.h @@ -4,6 +4,7 @@ #define cmCPackExternalGenerator_h #include "cmCPackGenerator.h" + #include "cm_sys_stat.h" #include <memory> diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index fc00b09..33026c1 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -10,9 +10,10 @@ #include <string> #include <vector> +#include "cm_sys_stat.h" + #include "cmCPackComponentGroup.h" #include "cmSystemTools.h" -#include "cm_sys_stat.h" class cmCPackLog; class cmGlobalGenerator; diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 4d41049..79e344b 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -6,7 +6,6 @@ #include <utility> #include "IFW/cmCPackIFWGenerator.h" -#include "cmAlgorithms.h" #ifdef HAVE_FREEBSD_PKG # include "cmCPackFreeBSDGenerator.h" #endif @@ -138,34 +137,21 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() #endif } -cmCPackGeneratorFactory::~cmCPackGeneratorFactory() -{ - cmDeleteAll(this->Generators); -} - -cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator( +std::unique_ptr<cmCPackGenerator> cmCPackGeneratorFactory::NewGenerator( const std::string& name) { - cmCPackGenerator* gen = this->NewGeneratorInternal(name); + auto it = this->GeneratorCreators.find(name); + if (it == this->GeneratorCreators.end()) { + return nullptr; + } + std::unique_ptr<cmCPackGenerator> gen(it->second()); if (!gen) { return nullptr; } - this->Generators.push_back(gen); gen->SetLogger(this->Logger); return gen; } -cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal( - const std::string& name) -{ - cmCPackGeneratorFactory::t_GeneratorCreatorsMap::iterator it = - this->GeneratorCreators.find(name); - if (it == this->GeneratorCreators.end()) { - return nullptr; - } - return (it->second)(); -} - void cmCPackGeneratorFactory::RegisterGenerator( const std::string& name, const char* generatorDescription, CreateGeneratorCall* createGenerator) diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h index da2eb8d..62b7484 100644 --- a/Source/CPack/cmCPackGeneratorFactory.h +++ b/Source/CPack/cmCPackGeneratorFactory.h @@ -6,8 +6,8 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <map> +#include <memory> #include <string> -#include <vector> class cmCPackGenerator; class cmCPackLog; @@ -20,14 +20,9 @@ class cmCPackGeneratorFactory { public: cmCPackGeneratorFactory(); - ~cmCPackGeneratorFactory(); - - cmCPackGeneratorFactory(const cmCPackGeneratorFactory&) = delete; - cmCPackGeneratorFactory& operator=(const cmCPackGeneratorFactory&) = delete; //! Get the generator - cmCPackGenerator* NewGenerator(const std::string& name); - void DeleteGenerator(cmCPackGenerator* gen); + std::unique_ptr<cmCPackGenerator> NewGenerator(const std::string& name); using CreateGeneratorCall = cmCPackGenerator*(); @@ -44,9 +39,6 @@ public: } private: - cmCPackGenerator* NewGeneratorInternal(const std::string& name); - std::vector<cmCPackGenerator*> Generators; - using t_GeneratorCreatorsMap = std::map<std::string, CreateGeneratorCall*>; t_GeneratorCreatorsMap GeneratorCreators; DescriptionsMap GeneratorDescriptions; diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 8098edf..3f53186 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -14,10 +14,10 @@ #include "cmsys/Directory.hxx" #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include <cstdlib> +#include <cstring> #include <map> #include <sstream> -#include <stdlib.h> -#include <string.h> #include <utility> /* NSIS uses different command line syntax on Windows and others */ diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 992299a..cd65694 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -4,13 +4,14 @@ #include <sstream> +#include "cm_sys_stat.h" + #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cm_sys_stat.h" cmCPackOSXX11Generator::cmCPackOSXX11Generator() = default; diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index 5dc36ab..7be6a7d 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -4,11 +4,11 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" -#include <assert.h> +#include <cassert> +#include <cstdio> +#include <cstdlib> #include <map> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #include <string> #include "cmCPackComponentGroup.h" diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx index 800af28..dae268c 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.cxx +++ b/Source/CPack/cmCPackProductBuildGenerator.cxx @@ -2,9 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackProductBuildGenerator.h" +#include <cstddef> #include <map> #include <sstream> -#include <stddef.h> #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 0f621cc..0c1cecf 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -3,7 +3,7 @@ #include "cmCPackRPMGenerator.h" #include <algorithm> -#include <ctype.h> +#include <cctype> #include <map> #include <ostream> #include <utility> @@ -184,8 +184,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) // The default behavior is to have one package by component group // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. if (!ignoreGroup) { - std::map<std::string, cmCPackComponentGroup>::iterator mainCompGIt = - this->ComponentGroups.end(); + auto mainCompGIt = this->ComponentGroups.end(); std::map<std::string, cmCPackComponentGroup>::iterator compGIt; for (compGIt = this->ComponentGroups.begin(); @@ -206,8 +205,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) retval &= PackageOnePack(initialTopLevel, compGIt->first); } // Handle Orphan components (components not belonging to any groups) - std::map<std::string, cmCPackComponent>::iterator mainCompIt = - this->Components.end(); + auto mainCompIt = this->Components.end(); std::map<std::string, cmCPackComponent>::iterator compIt; for (compIt = this->Components.begin(); compIt != this->Components.end(); ++compIt) { @@ -251,8 +249,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) // CPACK_COMPONENTS_IGNORE_GROUPS is set // We build 1 package per component else { - std::map<std::string, cmCPackComponent>::iterator mainCompIt = - this->Components.end(); + auto mainCompIt = this->Components.end(); std::map<std::string, cmCPackComponent>::iterator compIt; for (compIt = this->Components.begin(); compIt != this->Components.end(); diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index 3092508..eb1e24c 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -3,16 +3,17 @@ #include "cmCPackSTGZGenerator.h" #include "cmsys/FStream.hxx" +#include <cstdio> #include <sstream> -#include <stdio.h> #include <string> #include <vector> +#include "cm_sys_stat.h" + #include "cmArchiveWrite.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmSystemTools.h" -#include "cm_sys_stat.h" cmCPackSTGZGenerator::cmCPackSTGZGenerator() : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", ".sh") diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 08681ec..ce41d40 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -22,10 +22,11 @@ # include "cmsys/ConsoleBuf.hxx" #endif +#include <cstddef> #include <iostream> #include <map> +#include <memory> #include <sstream> -#include <stddef.h> #include <string> #include <utility> #include <vector> @@ -237,7 +238,6 @@ int main(int argc, char const* const* argv) cmCPackGeneratorFactory generators; generators.SetLogger(&log); - cmCPackGenerator* cpackGenerator = nullptr; cmDocumentation doc; doc.addCPackStandardDocSections(); @@ -360,7 +360,8 @@ int main(int argc, char const* const* argv) parsed = 0; } if (parsed) { - cpackGenerator = generators.NewGenerator(gen); + std::unique_ptr<cmCPackGenerator> cpackGenerator = + generators.NewGenerator(gen); if (cpackGenerator) { cpackGenerator->SetTrace(trace); cpackGenerator->SetTraceExpand(traceExpand); diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index 52dc0ac..4ea0c88 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -11,10 +11,10 @@ #include "cm_expat.h" #include "cmsys/RegularExpression.hxx" +#include <cstdlib> #include <list> #include <map> #include <ostream> -#include <stdlib.h> #include <vector> extern "C" int cmBZRXMLParserUnknownEncodingHandler(void* /*unused*/, diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index e7fb4c7..0f79670 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -14,9 +14,9 @@ #include "cmsys/Process.h" #include <chrono> +#include <cstdlib> #include <cstring> #include <ratio> -#include <stdlib.h> cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() { diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index cb22fa6..ce690f9 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -9,24 +9,23 @@ #include "cmMessageType.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cm_static_string_view.hxx" #include "cmake.h" +#include <cstring> #include <sstream> -#include <string.h> class cmExecutionStatus; -cmCTestBuildCommand::cmCTestBuildCommand() +void cmCTestBuildCommand::BindArguments() { - this->GlobalGenerator = nullptr; - this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS"; - this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS"; - this->Arguments[ctb_TARGET] = "TARGET"; - this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION"; - this->Arguments[ctb_FLAGS] = "FLAGS"; - this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME"; - this->Arguments[ctb_LAST] = nullptr; - this->Last = ctb_LAST; + this->cmCTestHandlerCommand::BindArguments(); + this->Bind("NUMBER_ERRORS"_s, this->NumberErrors); + this->Bind("NUMBER_WARNINGS"_s, this->NumberWarnings); + this->Bind("TARGET"_s, this->Target); + this->Bind("CONFIGURATION"_s, this->Configuration); + this->Bind("FLAGS"_s, this->Flags); + this->Bind("PROJECT_NAME"_s, this->ProjectName); } cmCTestBuildCommand::~cmCTestBuildCommand() @@ -60,20 +59,17 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() // const char* ctestBuildConfiguration = this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION"); - const char* cmakeBuildConfiguration = - (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION]) - ? this->Values[ctb_CONFIGURATION] + const char* cmakeBuildConfiguration = !this->Configuration.empty() + ? this->Configuration.c_str() : ((ctestBuildConfiguration && *ctestBuildConfiguration) ? ctestBuildConfiguration : this->CTest->GetConfigType().c_str()); - const char* cmakeBuildAdditionalFlags = - (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS]) - ? this->Values[ctb_FLAGS] + const char* cmakeBuildAdditionalFlags = !this->Flags.empty() + ? this->Flags.c_str() : this->Makefile->GetDefinition("CTEST_BUILD_FLAGS"); - const char* cmakeBuildTarget = - (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET]) - ? this->Values[ctb_TARGET] + const char* cmakeBuildTarget = !this->Target.empty() + ? this->Target.c_str() : this->Makefile->GetDefinition("CTEST_BUILD_TARGET"); if (cmakeGeneratorName && *cmakeGeneratorName) { @@ -153,16 +149,13 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) { bool ret = cmCTestHandlerCommand::InitialPass(args, status); - if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) { + if (!this->NumberErrors.empty()) { this->Makefile->AddDefinition( - this->Values[ctb_NUMBER_ERRORS], - std::to_string(this->Handler->GetTotalErrors())); + this->NumberErrors, std::to_string(this->Handler->GetTotalErrors())); } - if (this->Values[ctb_NUMBER_WARNINGS] && - *this->Values[ctb_NUMBER_WARNINGS]) { + if (!this->NumberWarnings.empty()) { this->Makefile->AddDefinition( - this->Values[ctb_NUMBER_WARNINGS], - std::to_string(this->Handler->GetTotalWarnings())); + this->NumberWarnings, std::to_string(this->Handler->GetTotalWarnings())); } return ret; } diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h index a62c301..791e1f0 100644 --- a/Source/CTest/cmCTestBuildCommand.h +++ b/Source/CTest/cmCTestBuildCommand.h @@ -12,7 +12,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmCTestBuildHandler; class cmCTestGenericHandler; @@ -27,7 +27,6 @@ class cmGlobalGenerator; class cmCTestBuildCommand : public cmCTestHandlerCommand { public: - cmCTestBuildCommand(); ~cmCTestBuildCommand() override; /** @@ -49,23 +48,19 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - cmGlobalGenerator* GlobalGenerator; + cmGlobalGenerator* GlobalGenerator = nullptr; protected: cmCTestBuildHandler* Handler; - enum - { - ctb_BUILD = ct_LAST, - ctb_NUMBER_ERRORS, - ctb_NUMBER_WARNINGS, - ctb_TARGET, - ctb_CONFIGURATION, - ctb_FLAGS, - ctb_PROJECT_NAME, - ctb_LAST - }; - + void BindArguments() override; cmCTestGenericHandler* InitializeHandler() override; + + std::string NumberErrors; + std::string NumberWarnings; + std::string Target; + std::string Configuration; + std::string Flags; + std::string ProjectName; }; #endif diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index e07d7aa..86abb12 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -17,9 +17,9 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" #include "cmsys/Process.h" +#include <cstdlib> +#include <cstring> #include <set> -#include <stdlib.h> -#include <string.h> #include <utility> static const char* cmCTestErrorMatches[] = { diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index b9b90c8..5baeecd 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -7,10 +7,12 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" -#include "cm_string_view.hxx" #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" + +#include <cm/string_view> + #include <utility> cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log) diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 320c184..948b9fb 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -8,25 +8,25 @@ #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cm_static_string_view.hxx" #include "cmake.h" +#include <cstring> #include <sstream> -#include <string.h> #include <vector> -cmCTestConfigureCommand::cmCTestConfigureCommand() +void cmCTestConfigureCommand::BindArguments() { - this->Arguments[ctc_OPTIONS] = "OPTIONS"; - this->Arguments[ctc_LAST] = nullptr; - this->Last = ctc_LAST; + this->cmCTestHandlerCommand::BindArguments(); + this->Bind("OPTIONS"_s, this->Options); } cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() { std::vector<std::string> options; - if (this->Values[ctc_OPTIONS]) { - cmExpandList(this->Values[ctc_OPTIONS], options); + if (!this->Options.empty()) { + cmExpandList(this->Options, options); } if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) { diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h index 4677c83..0bc7848 100644 --- a/Source/CTest/cmCTestConfigureCommand.h +++ b/Source/CTest/cmCTestConfigureCommand.h @@ -11,7 +11,7 @@ #include <string> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> class cmCTestGenericHandler; @@ -23,8 +23,6 @@ class cmCTestGenericHandler; class cmCTestConfigureCommand : public cmCTestHandlerCommand { public: - cmCTestConfigureCommand(); - /** * This is a virtual constructor for the command. */ @@ -42,14 +40,10 @@ public: std::string GetName() const override { return "ctest_configure"; } protected: + void BindArguments() override; cmCTestGenericHandler* InitializeHandler() override; - enum - { - ctc_FIRST = ct_LAST, - ctc_OPTIONS, - ctc_LAST - }; + std::string Options; }; #endif diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx index 07aae76..b66bba7 100644 --- a/Source/CTest/cmCTestCoverageCommand.cxx +++ b/Source/CTest/cmCTestCoverageCommand.cxx @@ -2,14 +2,26 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestCoverageCommand.h" +#include <set> + +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cm_static_string_view.hxx" class cmCTestGenericHandler; -cmCTestCoverageCommand::cmCTestCoverageCommand() +void cmCTestCoverageCommand::BindArguments() +{ + this->cmCTestHandlerCommand::BindArguments(); + this->Bind("LABELS"_s, this->Labels); +} + +void cmCTestCoverageCommand::CheckArguments( + std::vector<std::string> const& keywords) { - this->LabelsMentioned = false; + this->LabelsMentioned = + !this->Labels.empty() || cmContains(keywords, "LABELS"); } cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler() @@ -24,34 +36,10 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler() // If a LABELS option was given, select only files with the labels. if (this->LabelsMentioned) { - handler->SetLabelFilter(this->Labels); + handler->SetLabelFilter( + std::set<std::string>(this->Labels.begin(), this->Labels.end())); } handler->SetQuiet(this->Quiet); return handler; } - -bool cmCTestCoverageCommand::CheckArgumentKeyword(std::string const& arg) -{ - // Look for arguments specific to this command. - if (arg == "LABELS") { - this->ArgumentDoing = ArgumentDoingLabels; - this->LabelsMentioned = true; - return true; - } - - // Look for other arguments. - return this->Superclass::CheckArgumentKeyword(arg); -} - -bool cmCTestCoverageCommand::CheckArgumentValue(std::string const& arg) -{ - // Handle states specific to this command. - if (this->ArgumentDoing == ArgumentDoingLabels) { - this->Labels.insert(arg); - return true; - } - - // Look for other arguments. - return this->Superclass::CheckArgumentValue(arg); -} diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h index 24b96c0..fcffa75 100644 --- a/Source/CTest/cmCTestCoverageCommand.h +++ b/Source/CTest/cmCTestCoverageCommand.h @@ -8,11 +8,11 @@ #include "cmCTestHandlerCommand.h" #include "cmCommand.h" -#include <set> #include <string> #include <utility> +#include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmCTestGenericHandler; @@ -24,8 +24,6 @@ class cmCTestGenericHandler; class cmCTestCoverageCommand : public cmCTestHandlerCommand { public: - cmCTestCoverageCommand(); - /** * This is a virtual constructor for the command. */ @@ -42,22 +40,13 @@ public: */ std::string GetName() const override { return "ctest_coverage"; } - using Superclass = cmCTestHandlerCommand; - protected: + void BindArguments() override; + void CheckArguments(std::vector<std::string> const& keywords) override; cmCTestGenericHandler* InitializeHandler() override; - bool CheckArgumentKeyword(std::string const& arg) override; - bool CheckArgumentValue(std::string const& arg) override; - - enum - { - ArgumentDoingLabels = Superclass::ArgumentDoingLast1, - ArgumentDoingLast2 - }; - bool LabelsMentioned; - std::set<std::string> Labels; + std::vector<std::string> Labels; }; #endif diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 772fa47..4d76387 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -24,12 +24,12 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <chrono> +#include <cstdio> +#include <cstdlib> #include <cstring> #include <iomanip> #include <iterator> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #include <utility> class cmMakefile; @@ -1830,9 +1830,8 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( return 0; } std::map<std::string, std::string> fileMap; - std::vector<std::string>::iterator fp = filesFullPath.begin(); - for (std::vector<std::string>::iterator f = files.begin(); f != files.end(); - ++f, ++fp) { + auto fp = filesFullPath.begin(); + for (auto f = files.begin(); f != files.end(); ++f, ++fp) { fileMap[*f] = *fp; } @@ -1870,7 +1869,7 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( this->StartCoverageLogXML(covLogXML); count++; // move on one } - std::map<std::string, std::string>::iterator i = fileMap.find(file); + auto i = fileMap.find(file); // if the file should be covered write out the header for that file if (i != fileMap.end()) { // we have a new file so count it in the output @@ -2202,7 +2201,7 @@ bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine( int cmCTestCoverageHandler::GetLabelId(std::string const& label) { - LabelIdMapType::iterator i = this->LabelIdMap.find(label); + auto i = this->LabelIdMap.find(label); if (i == this->LabelIdMap.end()) { int n = int(this->Labels.size()); this->Labels.push_back(label); @@ -2273,7 +2272,7 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir) void cmCTestCoverageHandler::WriteXMLLabels(cmXMLWriter& xml, std::string const& source) { - LabelMapType::const_iterator li = this->SourceLabels.find(source); + auto li = this->SourceLabels.find(source); if (li != this->SourceLabels.end() && !li->second.empty()) { xml.StartElement("Labels"); for (auto const& ls : li->second) { @@ -2316,7 +2315,7 @@ bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source) // The source is filtered out if it does not have any labels in // common with the filter set. std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str()); - LabelMapType::const_iterator li = this->SourceLabels.find(shortSrc); + auto li = this->SourceLabels.find(shortSrc); if (li != this->SourceLabels.end()) { return !this->IntersectsFilter(li->second); } diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx index 40f5918..8793260 100644 --- a/Source/CTest/cmCTestCurl.cxx +++ b/Source/CTest/cmCTestCurl.cxx @@ -8,8 +8,8 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include <cstdio> #include <ostream> -#include <stdio.h> cmCTestCurl::cmCTestCurl(cmCTest* ctest) { diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h index 84250cb..4232b9e 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h @@ -12,7 +12,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 3ae464d..9fd3a62 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -4,10 +4,10 @@ #include "cmsys/FStream.hxx" #include "cmsys/Process.h" -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> +#include <cctype> +#include <cstdio> +#include <cstdlib> +#include <ctime> #include <vector> #include "cmCTest.h" diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index d3020b5..cc0b4ed 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -23,8 +23,7 @@ cmCTestGenericHandler::~cmCTestGenericHandler() = default; void cmCTestGenericHandler::SetOption(const std::string& op, const char* value) { if (!value) { - cmCTestGenericHandler::t_StringToString::iterator remit = - this->Options.find(op); + auto remit = this->Options.find(op); if (remit != this->Options.end()) { this->Options.erase(remit); } @@ -39,8 +38,7 @@ void cmCTestGenericHandler::SetPersistentOption(const std::string& op, { this->SetOption(op, value); if (!value) { - cmCTestGenericHandler::t_StringToString::iterator remit = - this->PersistentOptions.find(op); + auto remit = this->PersistentOptions.find(op); if (remit != this->PersistentOptions.end()) { this->PersistentOptions.erase(remit); } @@ -62,8 +60,7 @@ void cmCTestGenericHandler::Initialize() const char* cmCTestGenericHandler::GetOption(const std::string& op) { - cmCTestGenericHandler::t_StringToString::iterator remit = - this->Options.find(op); + auto remit = this->Options.find(op); if (remit == this->Options.end()) { return nullptr; } diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 6add717..3f9ce4e 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -7,30 +7,15 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" +#include "cm_static_string_view.hxx" +#include <algorithm> +#include <cstdlib> #include <cstring> #include <sstream> -#include <stdlib.h> - -cmCTestHandlerCommand::cmCTestHandlerCommand() -{ - const size_t INIT_SIZE = 100; - size_t cc; - this->Arguments.reserve(INIT_SIZE); - for (cc = 0; cc < INIT_SIZE; ++cc) { - this->Arguments.push_back(nullptr); - } - this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE"; - this->Arguments[ct_CAPTURE_CMAKE_ERROR] = "CAPTURE_CMAKE_ERROR"; - this->Arguments[ct_SOURCE] = "SOURCE"; - this->Arguments[ct_BUILD] = "BUILD"; - this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX"; - this->Last = ct_LAST; - this->AppendXML = false; - this->Quiet = false; -} namespace { // class to save and restore the error state for ctest_* commands @@ -90,30 +75,30 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, // save error state and restore it if needed SaveRestoreErrorState errorState; // Allocate space for argument values. - this->Values.clear(); - this->Values.resize(this->Last, nullptr); + this->BindArguments(); // Process input arguments. - this->ArgumentDoing = ArgumentDoingNone; - // look at all arguments and do not short circuit on the first - // bad one so that CAPTURE_CMAKE_ERROR can override setting the - // global error state - bool foundBadArgument = false; - for (std::string const& arg : args) { - // Check this argument. - if (!this->CheckArgumentKeyword(arg) && !this->CheckArgumentValue(arg)) { - std::ostringstream e; - e << "called with unknown argument \"" << arg << "\"."; - this->SetError(e.str()); - foundBadArgument = true; - } - // note bad argument - if (this->ArgumentDoing == ArgumentDoingError) { - foundBadArgument = true; - } + std::vector<std::string> unparsedArguments; + std::vector<std::string> keywordsMissingValue; + std::vector<std::string> parsedKeywords; + this->Parse(args, &unparsedArguments, &keywordsMissingValue, + &parsedKeywords); + this->CheckArguments(keywordsMissingValue); + + std::sort(parsedKeywords.begin(), parsedKeywords.end()); + auto it = std::adjacent_find(parsedKeywords.begin(), parsedKeywords.end()); + if (it != parsedKeywords.end()) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Called with more than one value for ", *it)); + } + + bool const foundBadArgument = !unparsedArguments.empty(); + if (foundBadArgument) { + this->SetError(cmStrCat("called with unknown argument \"", + unparsedArguments.front(), "\".")); } - bool captureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] && - *this->Values[ct_CAPTURE_CMAKE_ERROR]); + bool const captureCMakeError = !this->CaptureCMakeError.empty(); // now that arguments are parsed check to see if there is a // CAPTURE_CMAKE_ERROR specified let the errorState object know. if (captureCMakeError) { @@ -123,8 +108,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, if (foundBadArgument) { // store the cmake error if (captureCMakeError) { - this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], - "-1"); + this->Makefile->AddDefinition(this->CaptureCMakeError, "-1"); std::string const err = this->GetName() + " " + status.GetError(); if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n"); @@ -146,10 +130,9 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, this->CTest->SetConfigType(ctestConfigType); } - if (this->Values[ct_BUILD]) { + if (!this->Build.empty()) { this->CTest->SetCTestConfiguration( - "BuildDirectory", - cmSystemTools::CollapseFullPath(this->Values[ct_BUILD]).c_str(), + "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build).c_str(), this->Quiet); } else { std::string const& bdir = @@ -163,13 +146,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, "CTEST_BINARY_DIRECTORY not set" << std::endl;); } } - if (this->Values[ct_SOURCE]) { + if (!this->Source.empty()) { cmCTestLog(this->CTest, DEBUG, - "Set source directory to: " << this->Values[ct_SOURCE] - << std::endl); + "Set source directory to: " << this->Source << std::endl); this->CTest->SetCTestConfiguration( - "SourceDirectory", - cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(), + "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(), this->Quiet); } else { this->CTest->SetCTestConfiguration( @@ -192,8 +173,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, "Cannot instantiate test handler " << this->GetName() << std::endl); if (captureCMakeError) { - this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], - "-1"); + this->Makefile->AddDefinition(this->CaptureCMakeError, "-1"); std::string const& err = status.GetError(); if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n"); @@ -203,11 +183,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, return false; } - handler->SetAppendXML(this->AppendXML); + handler->SetAppendXML(this->Append); handler->PopulateCustomVectors(this->Makefile); - if (this->Values[ct_SUBMIT_INDEX]) { - handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX])); + if (!this->SubmitIndex.empty()) { + handler->SetSubmitIndex(atoi(this->SubmitIndex.c_str())); } cmWorkingDirectory workdir( this->CTest->GetCTestConfiguration("BuildDirectory")); @@ -216,8 +196,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, this->CTest->GetCTestConfiguration("BuildDirectory") + " : " + std::strerror(workdir.GetLastResult())); if (captureCMakeError) { - this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], - "-1"); + this->Makefile->AddDefinition(this->CaptureCMakeError, "-1"); cmCTestLog(this->CTest, ERROR_MESSAGE, this->GetName() << " " << status.GetError() << "\n"); // return success because failure is recorded in CAPTURE_CMAKE_ERROR @@ -227,9 +206,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]) { - this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], - std::to_string(res)); + if (!this->ReturnValue.empty()) { + this->Makefile->AddDefinition(this->ReturnValue, std::to_string(res)); } this->ProcessAdditionalValues(handler); // log the error message if there was an error @@ -245,8 +223,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, } } // store the captured cmake error state 0 or -1 - this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], - returnString); + this->Makefile->AddDefinition(this->CaptureCMakeError, returnString); } return true; } @@ -255,47 +232,17 @@ void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*) { } -bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg) +void cmCTestHandlerCommand::BindArguments() { - // Look for non-value arguments common to all commands. - if (arg == "APPEND") { - this->ArgumentDoing = ArgumentDoingNone; - this->AppendXML = true; - return true; - } - if (arg == "QUIET") { - this->ArgumentDoing = ArgumentDoingNone; - this->Quiet = true; - return true; - } - - // Check for a keyword in our argument/value table. - for (unsigned int k = 0; k < this->Arguments.size(); ++k) { - if (this->Arguments[k] && arg == this->Arguments[k]) { - this->ArgumentDoing = ArgumentDoingKeyword; - this->ArgumentIndex = k; - return true; - } - } - return false; + this->Bind("APPEND"_s, this->Append); + this->Bind("QUIET"_s, this->Quiet); + this->Bind("RETURN_VALUE"_s, this->ReturnValue); + this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError); + this->Bind("SOURCE"_s, this->Source); + this->Bind("BUILD"_s, this->Build); + this->Bind("SUBMIT_INDEX"_s, this->SubmitIndex); } -bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg) +void cmCTestHandlerCommand::CheckArguments(std::vector<std::string> const&) { - if (this->ArgumentDoing == ArgumentDoingKeyword) { - this->ArgumentDoing = ArgumentDoingNone; - unsigned int k = this->ArgumentIndex; - if (this->Values[k]) { - std::ostringstream e; - e << "Called with more than one value for " << this->Arguments[k]; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); - this->ArgumentDoing = ArgumentDoingError; - return true; - } - this->Values[k] = arg.c_str(); - cmCTestLog(this->CTest, DEBUG, - "Set " << this->Arguments[k] << " to " << arg << "\n"); - return true; - } - return false; } diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h index 79d61f3..5bbc569 100644 --- a/Source/CTest/cmCTestHandlerCommand.h +++ b/Source/CTest/cmCTestHandlerCommand.h @@ -5,9 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmArgumentParser.h" #include "cmCTestCommand.h" -#include <stddef.h> #include <string> #include <vector> @@ -19,11 +19,11 @@ class cmExecutionStatus; * * cmCTestHandlerCommand defineds the command to test the project. */ -class cmCTestHandlerCommand : public cmCTestCommand +class cmCTestHandlerCommand + : public cmCTestCommand + , public cmArgumentParser<void> { public: - cmCTestHandlerCommand(); - /** * The name of the command as specified in CMakeList.txt. */ @@ -36,42 +36,22 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - enum - { - ct_NONE, - ct_RETURN_VALUE, - ct_CAPTURE_CMAKE_ERROR, - ct_BUILD, - ct_SOURCE, - ct_SUBMIT_INDEX, - ct_LAST - }; - protected: virtual cmCTestGenericHandler* InitializeHandler() = 0; virtual void ProcessAdditionalValues(cmCTestGenericHandler* handler); // Command argument handling. - virtual bool CheckArgumentKeyword(std::string const& arg); - virtual bool CheckArgumentValue(std::string const& arg); - enum - { - ArgumentDoingNone, - ArgumentDoingError, - ArgumentDoingKeyword, - ArgumentDoingLast1 - }; - int ArgumentDoing; - unsigned int ArgumentIndex; - - bool AppendXML; - bool Quiet; - - std::string ReturnVariable; - std::vector<const char*> Arguments; - std::vector<const char*> Values; - size_t Last; + virtual void BindArguments(); + virtual void CheckArguments(std::vector<std::string> const& keywords); + + bool Append = false; + bool Quiet = false; + std::string CaptureCMakeError; + std::string ReturnValue; + std::string Build; + std::string Source; + std::string SubmitIndex; }; #define CTEST_COMMAND_APPEND_OPTION_DOCS \ diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index ac52581..ba49c29 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -5,9 +5,9 @@ #include "cmsys/FStream.hxx" #include "cmsys/Process.h" #include "cmsys/RegularExpression.hxx" +#include <cstdlib> +#include <cstring> #include <iostream> -#include <stdlib.h> -#include <string.h> #include "cmCryptoHash.h" #include "cmGeneratedFileStream.h" diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx index 804efa5..abad5fc 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -2,18 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestMemCheckCommand.h" -#include <string> -#include <vector> - #include "cmCTest.h" #include "cmCTestMemCheckHandler.h" #include "cmMakefile.h" +#include "cm_static_string_view.hxx" -cmCTestMemCheckCommand::cmCTestMemCheckCommand() +void cmCTestMemCheckCommand::BindArguments() { - this->Arguments[ctm_DEFECT_COUNT] = "DEFECT_COUNT"; - this->Arguments[ctm_LAST] = nullptr; - this->Last = ctm_LAST; + this->cmCTestTestCommand::BindArguments(); + this->Bind("DEFECT_COUNT"_s, this->DefectCount); } cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() @@ -43,9 +40,9 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() void cmCTestMemCheckCommand::ProcessAdditionalValues( cmCTestGenericHandler* handler) { - if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) { + if (!this->DefectCount.empty()) { this->Makefile->AddDefinition( - this->Values[ctm_DEFECT_COUNT], + this->DefectCount, std::to_string( static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount())); } diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index 837a687..8f4ffb8 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h @@ -5,9 +5,10 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <string> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCTestTestCommand.h" #include "cmCommand.h" @@ -22,8 +23,6 @@ class cmCTestGenericHandler; class cmCTestMemCheckCommand : public cmCTestTestCommand { public: - cmCTestMemCheckCommand(); - /** * This is a virtual constructor for the command. */ @@ -36,15 +35,13 @@ public: } protected: + void BindArguments() override; + cmCTestGenericHandler* InitializeActualHandler() override; void ProcessAdditionalValues(cmCTestGenericHandler* handler) override; - enum - { - ctm_DEFECT_COUNT = ctt_LAST, - ctm_LAST - }; + std::string DefectCount; }; #endif diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 259240f..ba196f0 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -12,9 +12,9 @@ #include "cmsys/Glob.hxx" #include "cmsys/RegularExpression.hxx" #include <chrono> +#include <cstring> #include <iostream> #include <sstream> -#include <string.h> #include <utility> struct CatToErrorType diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index af1980a..f79ba2e 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -25,15 +25,15 @@ #include <algorithm> #include <chrono> +#include <cmath> +#include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <list> -#include <math.h> #include <memory> #include <sstream> #include <stack> -#include <stdlib.h> #include <unordered_map> #include <utility> #include <vector> diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index 9bca7cb..a6aea85 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -12,8 +12,8 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include <ctime> #include <ostream> -#include <time.h> #include <utility> cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log) @@ -146,8 +146,7 @@ private: cmCTestP4::User cmCTestP4::GetUserData(const std::string& username) { - std::map<std::string, cmCTestP4::User>::const_iterator it = - Users.find(username); + auto it = Users.find(username); if (it == Users.end()) { std::vector<char const*> p4_users; diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h index db2ac5e..8199cbc 100644 --- a/Source/CTest/cmCTestReadCustomFilesCommand.h +++ b/Source/CTest/cmCTestReadCustomFilesCommand.h @@ -12,7 +12,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h index 6961f6e..d262a83 100644 --- a/Source/CTest/cmCTestRunScriptCommand.h +++ b/Source/CTest/cmCTestRunScriptCommand.h @@ -12,7 +12,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 23c6b0d..d8a5923 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -13,14 +13,14 @@ #include "cmsys/RegularExpression.hxx" #include <chrono> #include <cstdint> +#include <cstdio> #include <cstring> #include <iomanip> #include <ratio> #include <sstream> -#include <stdio.h> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler) : MultiTestHandler(multiHandler) @@ -571,8 +571,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) void cmCTestRunTest::ComputeArguments() { this->Arguments.clear(); // reset because this might be a rerun - std::vector<std::string>::const_iterator j = - this->TestProperties->Args.begin(); + auto j = this->TestProperties->Args.begin(); ++j; // skip test name // find the test executable if (this->TestHandler->MemCheck) { diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index 6d8077f..6e5b5e7 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -12,10 +12,10 @@ #include "cmXMLWriter.h" #include "cmsys/RegularExpression.hxx" +#include <cstdlib> +#include <cstring> #include <map> #include <ostream> -#include <stdlib.h> -#include <string.h> struct cmCTestSVN::Revision : public cmCTestVC::Revision { @@ -169,7 +169,7 @@ void cmCTestSVN::GuessBase(SVNInfo& svninfo, slash = svninfo.URL.find('/', slash + 1)) { // If the URL suffix is a prefix of at least one path then it is the base. std::string base = cmCTest::DecodeURL(svninfo.URL.substr(slash)); - for (std::vector<Change>::const_iterator ci = changes.begin(); + for (auto ci = changes.begin(); svninfo.Base.empty() && ci != changes.end(); ++ci) { if (cmCTestSVNPathStarts(ci->Path, base)) { svninfo.Base = base; diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 81966dd..c988e3a 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -5,7 +5,7 @@ #include "cmsys/Directory.hxx" #include "cmsys/Process.h" -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCTest.h" #include "cmCTestBuildCommand.h" @@ -34,13 +34,13 @@ #include "cmSystemTools.h" #include "cmake.h" +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <map> #include <memory> #include <ratio> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <utility> #ifdef _WIN32 diff --git a/Source/CTest/cmCTestSleepCommand.cxx b/Source/CTest/cmCTestSleepCommand.cxx index 2752cd3..bc4470c 100644 --- a/Source/CTest/cmCTestSleepCommand.cxx +++ b/Source/CTest/cmCTestSleepCommand.cxx @@ -4,7 +4,7 @@ #include "cmCTestScriptHandler.h" -#include <stdlib.h> +#include <cstdlib> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 7b17081..b98079d 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h @@ -12,7 +12,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index e4a1844..844f2ca 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -8,8 +8,8 @@ #include "cmMakefile.h" #include "cmSystemTools.h" +#include <cstddef> #include <sstream> -#include <stddef.h> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index 7c71f36..598c937 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h @@ -13,7 +13,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmExecutionStatus; diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index d16aac0..706b45a 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -2,33 +2,25 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestSubmitCommand.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestSubmitHandler.h" #include "cmCommand.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cm_static_string_view.hxx" +#include <set> #include <sstream> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> class cmExecutionStatus; -cmCTestSubmitCommand::cmCTestSubmitCommand() -{ - this->PartsMentioned = false; - this->FilesMentioned = false; - this->InternalTest = false; - this->RetryCount = ""; - this->RetryDelay = ""; - this->CDashUpload = false; - this->Arguments[cts_BUILD_ID] = "BUILD_ID"; - this->Last = cts_LAST; -} - /** * This is a virtual constructor for the command. */ @@ -106,13 +98,18 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() // without any of the default parts. // handler->SelectParts(std::set<cmCTest::Part>()); - handler->SelectFiles(this->Files); + handler->SelectFiles( + std::set<std::string>(this->Files.begin(), this->Files.end())); } // If a PARTS option was given, select only the named parts for submission. // if (this->PartsMentioned) { - handler->SelectParts(this->Parts); + auto parts = + cmMakeRange(this->Parts).transform([this](std::string const& arg) { + return this->CTest->GetPartFromName(arg.c_str()); + }); + handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end())); } // Pass along any HTTPHEADER to the handler if this option was given. @@ -140,133 +137,61 @@ bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args, bool ret = this->cmCTestHandlerCommand::InitialPass(args, status); - if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) { - this->Makefile->AddDefinition(this->Values[cts_BUILD_ID], - this->CTest->GetBuildID()); + if (!this->BuildID.empty()) { + this->Makefile->AddDefinition(this->BuildID, this->CTest->GetBuildID()); } return ret; } -bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) +void cmCTestSubmitCommand::BindArguments() { if (this->CDashUpload) { // Arguments specific to the CDASH_UPLOAD signature. - if (arg == "CDASH_UPLOAD") { - this->ArgumentDoing = ArgumentDoingCDashUpload; - return true; - } - - if (arg == "CDASH_UPLOAD_TYPE") { - this->ArgumentDoing = ArgumentDoingCDashUploadType; - return true; - } + this->Bind("CDASH_UPLOAD", this->CDashUploadFile); + this->Bind("CDASH_UPLOAD_TYPE", this->CDashUploadType); } else { // Arguments that cannot be used with CDASH_UPLOAD. - if (arg == "PARTS") { - this->ArgumentDoing = ArgumentDoingParts; - this->PartsMentioned = true; - return true; - } - - if (arg == "FILES") { - this->ArgumentDoing = ArgumentDoingFiles; - this->FilesMentioned = true; - return true; - } + this->Bind("PARTS"_s, this->Parts); + this->Bind("FILES"_s, this->Files); } // Arguments used by both modes. - if (arg == "HTTPHEADER") { - this->ArgumentDoing = ArgumentDoingHttpHeader; - return true; - } - - if (arg == "RETRY_COUNT") { - this->ArgumentDoing = ArgumentDoingRetryCount; - return true; - } - - if (arg == "RETRY_DELAY") { - this->ArgumentDoing = ArgumentDoingRetryDelay; - return true; - } - - if (arg == "SUBMIT_URL") { - this->ArgumentDoing = ArgumentDoingSubmitURL; - return true; - } - - if (arg == "INTERNAL_TEST_CHECKSUM") { - this->InternalTest = true; - return true; - } + this->Bind("BUILD_ID"_s, this->BuildID); + this->Bind("HTTPHEADER"_s, this->HttpHeaders); + this->Bind("RETRY_COUNT"_s, this->RetryCount); + this->Bind("RETRY_DELAY"_s, this->RetryDelay); + this->Bind("SUBMIT_URL"_s, this->SubmitURL); + this->Bind("INTERNAL_TEST_CHECKSUM", this->InternalTest); // Look for other arguments. - return this->Superclass::CheckArgumentKeyword(arg); + this->cmCTestHandlerCommand::BindArguments(); } -bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) +void cmCTestSubmitCommand::CheckArguments( + std::vector<std::string> const& keywords) { - // Handle states specific to this command. - if (this->ArgumentDoing == ArgumentDoingParts) { + this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS"); + this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES"); + + cmEraseIf(this->Parts, [this](std::string const& arg) -> bool { cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str()); - if (p != cmCTest::PartCount) { - this->Parts.insert(p); - } else { + if (p == cmCTest::PartCount) { std::ostringstream e; e << "Part name \"" << arg << "\" is invalid."; this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); - this->ArgumentDoing = ArgumentDoingError; + return true; } - return true; - } + return false; + }); - if (this->ArgumentDoing == ArgumentDoingFiles) { - if (cmSystemTools::FileExists(arg)) { - this->Files.insert(arg); - } else { + cmEraseIf(this->Files, [this](std::string const& arg) -> bool { + if (!cmSystemTools::FileExists(arg)) { std::ostringstream e; e << "File \"" << arg << "\" does not exist. Cannot submit " << "a non-existent file."; this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); - this->ArgumentDoing = ArgumentDoingError; + return true; } - return true; - } - - if (this->ArgumentDoing == ArgumentDoingHttpHeader) { - this->HttpHeaders.push_back(arg); - return true; - } - - if (this->ArgumentDoing == ArgumentDoingRetryCount) { - this->RetryCount = arg; - return true; - } - - if (this->ArgumentDoing == ArgumentDoingRetryDelay) { - this->RetryDelay = arg; - return true; - } - - if (this->ArgumentDoing == ArgumentDoingCDashUpload) { - this->ArgumentDoing = ArgumentDoingNone; - this->CDashUploadFile = arg; - return true; - } - - if (this->ArgumentDoing == ArgumentDoingCDashUploadType) { - this->ArgumentDoing = ArgumentDoingNone; - this->CDashUploadType = arg; - return true; - } - - if (this->ArgumentDoing == ArgumentDoingSubmitURL) { - this->ArgumentDoing = ArgumentDoingNone; - this->SubmitURL = arg; - return true; - } - - // Look for other arguments. - return this->Superclass::CheckArgumentValue(arg); + return false; + }); } diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 8562207..249f844 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -5,11 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmCTest.h" #include "cmCTestHandlerCommand.h" #include <memory> -#include <set> #include <string> #include <vector> @@ -26,7 +24,6 @@ class cmExecutionStatus; class cmCTestSubmitCommand : public cmCTestHandlerCommand { public: - cmCTestSubmitCommand(); std::unique_ptr<cmCommand> Clone() override; bool InitialPass(std::vector<std::string> const& args, @@ -37,45 +34,26 @@ public: */ std::string GetName() const override { return "ctest_submit"; } - using Superclass = cmCTestHandlerCommand; - protected: + void BindArguments() override; + void CheckArguments(std::vector<std::string> const& keywords) override; cmCTestGenericHandler* InitializeHandler() override; - bool CheckArgumentKeyword(std::string const& arg) override; - bool CheckArgumentValue(std::string const& arg) override; - - enum - { - ArgumentDoingParts = Superclass::ArgumentDoingLast1, - ArgumentDoingFiles, - ArgumentDoingRetryDelay, - ArgumentDoingRetryCount, - ArgumentDoingCDashUpload, - ArgumentDoingCDashUploadType, - ArgumentDoingHttpHeader, - ArgumentDoingSubmitURL, - ArgumentDoingLast2 - }; - - enum - { - cts_BUILD_ID = ct_LAST, - cts_LAST - }; + bool CDashUpload = false; + bool FilesMentioned = false; + bool InternalTest = false; + bool PartsMentioned = false; - bool PartsMentioned; - std::set<cmCTest::Part> Parts; - bool FilesMentioned; - bool InternalTest; - std::set<std::string> Files; - std::string RetryCount; - std::string RetryDelay; - bool CDashUpload; + std::string BuildID; std::string CDashUploadFile; std::string CDashUploadType; - std::vector<std::string> HttpHeaders; + std::string RetryCount; + std::string RetryDelay; std::string SubmitURL; + + std::vector<std::string> Files; + std::vector<std::string> HttpHeaders; + std::vector<std::string> Parts; }; #endif diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index f215911..ca7fd2c 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -6,9 +6,9 @@ #include "cm_jsoncpp_reader.h" #include "cm_jsoncpp_value.h" #include <chrono> +#include <cstdio> +#include <cstdlib> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #include "cmAlgorithms.h" #include "cmCTest.h" diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 24de5b4..c277db8 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -8,30 +8,29 @@ #include "cmDuration.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" +#include "cm_static_string_view.hxx" #include <chrono> +#include <cstdlib> #include <sstream> -#include <stdlib.h> -#include <vector> -cmCTestTestCommand::cmCTestTestCommand() +void cmCTestTestCommand::BindArguments() { - this->Arguments[ctt_START] = "START"; - this->Arguments[ctt_END] = "END"; - this->Arguments[ctt_STRIDE] = "STRIDE"; - this->Arguments[ctt_EXCLUDE] = "EXCLUDE"; - this->Arguments[ctt_INCLUDE] = "INCLUDE"; - this->Arguments[ctt_EXCLUDE_LABEL] = "EXCLUDE_LABEL"; - this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL"; - this->Arguments[ctt_EXCLUDE_FIXTURE] = "EXCLUDE_FIXTURE"; - this->Arguments[ctt_EXCLUDE_FIXTURE_SETUP] = "EXCLUDE_FIXTURE_SETUP"; - this->Arguments[ctt_EXCLUDE_FIXTURE_CLEANUP] = "EXCLUDE_FIXTURE_CLEANUP"; - this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL"; - this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM"; - this->Arguments[ctt_STOP_TIME] = "STOP_TIME"; - this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD"; - this->Arguments[ctt_LAST] = nullptr; - this->Last = ctt_LAST; + this->cmCTestHandlerCommand::BindArguments(); + this->Bind("START"_s, this->Start); + this->Bind("END"_s, this->End); + this->Bind("STRIDE"_s, this->Stride); + this->Bind("EXCLUDE"_s, this->Exclude); + this->Bind("INCLUDE"_s, this->Include); + this->Bind("EXCLUDE_LABEL"_s, this->ExcludeLabel); + this->Bind("INCLUDE_LABEL"_s, this->IncludeLabel); + this->Bind("EXCLUDE_FIXTURE"_s, this->ExcludeFixture); + this->Bind("EXCLUDE_FIXTURE_SETUP"_s, this->ExcludeFixtureSetup); + this->Bind("EXCLUDE_FIXTURE_CLEANUP"_s, this->ExcludeFixtureCleanup); + this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel); + this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom); + this->Bind("STOP_TIME"_s, this->StopTime); + this->Bind("TEST_LOAD"_s, this->TestLoad); } cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() @@ -51,57 +50,44 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() } this->CTest->SetTimeOut(timeout); cmCTestGenericHandler* handler = this->InitializeActualHandler(); - if (this->Values[ctt_START] || this->Values[ctt_END] || - this->Values[ctt_STRIDE]) { - std::ostringstream testsToRunString; - if (this->Values[ctt_START]) { - testsToRunString << this->Values[ctt_START]; - } - testsToRunString << ","; - if (this->Values[ctt_END]) { - testsToRunString << this->Values[ctt_END]; - } - testsToRunString << ","; - if (this->Values[ctt_STRIDE]) { - testsToRunString << this->Values[ctt_STRIDE]; - } - handler->SetOption("TestsToRunInformation", - testsToRunString.str().c_str()); + if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) { + handler->SetOption( + "TestsToRunInformation", + cmStrCat(this->Start, ',', this->End, ',', this->Stride).c_str()); } - if (this->Values[ctt_EXCLUDE]) { - handler->SetOption("ExcludeRegularExpression", this->Values[ctt_EXCLUDE]); + if (!this->Exclude.empty()) { + handler->SetOption("ExcludeRegularExpression", this->Exclude.c_str()); } - if (this->Values[ctt_INCLUDE]) { - handler->SetOption("IncludeRegularExpression", this->Values[ctt_INCLUDE]); + if (!this->Include.empty()) { + handler->SetOption("IncludeRegularExpression", this->Include.c_str()); } - if (this->Values[ctt_EXCLUDE_LABEL]) { + if (!this->ExcludeLabel.empty()) { handler->SetOption("ExcludeLabelRegularExpression", - this->Values[ctt_EXCLUDE_LABEL]); + this->ExcludeLabel.c_str()); } - if (this->Values[ctt_INCLUDE_LABEL]) { - handler->SetOption("LabelRegularExpression", - this->Values[ctt_INCLUDE_LABEL]); + if (!this->IncludeLabel.empty()) { + handler->SetOption("LabelRegularExpression", this->IncludeLabel.c_str()); } - if (this->Values[ctt_EXCLUDE_FIXTURE]) { + if (!this->ExcludeFixture.empty()) { handler->SetOption("ExcludeFixtureRegularExpression", - this->Values[ctt_EXCLUDE_FIXTURE]); + this->ExcludeFixture.c_str()); } - if (this->Values[ctt_EXCLUDE_FIXTURE_SETUP]) { + if (!this->ExcludeFixtureSetup.empty()) { handler->SetOption("ExcludeFixtureSetupRegularExpression", - this->Values[ctt_EXCLUDE_FIXTURE_SETUP]); + this->ExcludeFixtureSetup.c_str()); } - if (this->Values[ctt_EXCLUDE_FIXTURE_CLEANUP]) { + if (!this->ExcludeFixtureCleanup.empty()) { handler->SetOption("ExcludeFixtureCleanupRegularExpression", - this->Values[ctt_EXCLUDE_FIXTURE_CLEANUP]); + this->ExcludeFixtureCleanup.c_str()); } - if (this->Values[ctt_PARALLEL_LEVEL]) { - handler->SetOption("ParallelLevel", this->Values[ctt_PARALLEL_LEVEL]); + if (!this->ParallelLevel.empty()) { + handler->SetOption("ParallelLevel", this->ParallelLevel.c_str()); } - if (this->Values[ctt_SCHEDULE_RANDOM]) { - handler->SetOption("ScheduleRandom", this->Values[ctt_SCHEDULE_RANDOM]); + if (!this->ScheduleRandom.empty()) { + handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str()); } - if (this->Values[ctt_STOP_TIME]) { - this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]); + if (!this->StopTime.empty()) { + this->CTest->SetStopTime(this->StopTime); } // Test load is determined by: TEST_LOAD argument, @@ -109,12 +95,12 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() // command line argument... in that order. unsigned long testLoad; const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD"); - if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) { - if (!cmStrToULong(this->Values[ctt_TEST_LOAD], &testLoad)) { + if (!this->TestLoad.empty()) { + if (!cmStrToULong(this->TestLoad.c_str(), &testLoad)) { testLoad = 0; cmCTestLog(this->CTest, WARNING, - "Invalid value for 'TEST_LOAD' : " - << this->Values[ctt_TEST_LOAD] << std::endl); + "Invalid value for 'TEST_LOAD' : " << this->TestLoad + << std::endl); } } else if (ctestTestLoad && *ctestTestLoad) { if (!cmStrToULong(ctestTestLoad, &testLoad)) { diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index d74136c..edd21b7 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -11,7 +11,7 @@ #include <string> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> class cmCTestGenericHandler; @@ -23,8 +23,6 @@ class cmCTestGenericHandler; class cmCTestTestCommand : public cmCTestHandlerCommand { public: - cmCTestTestCommand(); - /** * This is a virtual constructor for the command. */ @@ -42,29 +40,24 @@ public: std::string GetName() const override { return "ctest_test"; } protected: + void BindArguments() override; virtual cmCTestGenericHandler* InitializeActualHandler(); cmCTestGenericHandler* InitializeHandler() override; - enum - { - ctt_BUILD = ct_LAST, - ctt_RETURN_VALUE, - ctt_START, - ctt_END, - ctt_STRIDE, - ctt_EXCLUDE, - ctt_INCLUDE, - ctt_EXCLUDE_LABEL, - ctt_INCLUDE_LABEL, - ctt_EXCLUDE_FIXTURE, - ctt_EXCLUDE_FIXTURE_SETUP, - ctt_EXCLUDE_FIXTURE_CLEANUP, - ctt_PARALLEL_LEVEL, - ctt_SCHEDULE_RANDOM, - ctt_STOP_TIME, - ctt_TEST_LOAD, - ctt_LAST - }; + std::string Start; + std::string End; + std::string Stride; + std::string Exclude; + std::string Include; + std::string ExcludeLabel; + std::string IncludeLabel; + std::string ExcludeFixture; + std::string ExcludeFixtureSetup; + std::string ExcludeFixtureCleanup; + std::string ParallelLevel; + std::string ScheduleRandom; + std::string StopTime; + std::string TestLoad; }; #endif diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index f67b11a..ee0d8c8 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -2,13 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestTestHandler.h" -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestMultiProcessHandler.h" -#include "cmCommand.h" #include "cmDuration.h" +#include "cmExecutionStatus.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -29,47 +29,53 @@ #include <cmsys/Directory.hxx> #include <cmsys/RegularExpression.hxx> #include <cstddef> +#include <cstdio> +#include <cstdlib> #include <cstring> +#include <ctime> #include <functional> #include <iomanip> #include <iterator> #include <set> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> #include <utility> -class cmExecutionStatus; +namespace { -class cmCTestSubdirCommand : public cmCommand +class cmCTestCommand { public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override + cmCTestCommand(cmCTestTestHandler* testHandler) + : TestHandler(testHandler) { - auto c = cm::make_unique<cmCTestSubdirCommand>(); - c->TestHandler = this->TestHandler; - return std::unique_ptr<cmCommand>(std::move(c)); } - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) override; + virtual ~cmCTestCommand() = default; + + bool operator()(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& status) + { + cmMakefile& mf = status.GetMakefile(); + std::vector<std::string> expandedArguments; + if (!mf.ExpandArguments(args, expandedArguments)) { + // There was an error expanding arguments. It was already + // reported, so we can skip this command without error. + return true; + } + return this->InitialPass(expandedArguments, status); + } + + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) = 0; cmCTestTestHandler* TestHandler; }; -bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) +bool cmCTestSubdirCommand(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 cwd = cmSystemTools::GetCurrentWorkingDirectory(); @@ -90,8 +96,8 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, { cmWorkingDirectory workdir(fname); if (workdir.Failed()) { - this->SetError("Failed to change directory to " + fname + " : " + - std::strerror(workdir.GetLastResult())); + status.SetError("Failed to change directory to " + fname + " : " + + std::strerror(workdir.GetLastResult())); return false; } const char* testFilename; @@ -107,45 +113,21 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, } fname += "/"; fname += testFilename; - readit = this->Makefile->ReadDependentFile(fname); + readit = status.GetMakefile().ReadDependentFile(fname); } if (!readit) { - std::string m = cmStrCat("Could not find include file: ", fname); - this->SetError(m); + status.SetError(cmStrCat("Could not find include file: ", fname)); return false; } } return true; } -class cmCTestAddSubdirectoryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - auto c = cm::make_unique<cmCTestAddSubdirectoryCommand>(); - c->TestHandler = this->TestHandler; - return std::unique_ptr<cmCommand>(std::move(c)); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) override; - - cmCTestTestHandler* TestHandler; -}; - -bool cmCTestAddSubdirectoryCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus& /*unused*/) +bool cmCTestAddSubdirectoryCommand(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; } @@ -171,28 +153,19 @@ bool cmCTestAddSubdirectoryCommand::InitialPass( } fname += "/"; fname += testFilename; - readit = this->Makefile->ReadDependentFile(fname); + readit = status.GetMakefile().ReadDependentFile(fname); } if (!readit) { - std::string m = cmStrCat("Could not find include file: ", fname); - this->SetError(m); + status.SetError(cmStrCat("Could not find include file: ", fname)); return false; } return true; } -class cmCTestAddTestCommand : public cmCommand +class cmCTestAddTestCommand : public cmCTestCommand { public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - auto c = cm::make_unique<cmCTestAddTestCommand>(); - c->TestHandler = this->TestHandler; - return std::unique_ptr<cmCommand>(std::move(c)); - } + using cmCTestCommand::cmCTestCommand; /** * This is called when the command is first encountered in @@ -200,32 +173,22 @@ public: */ bool InitialPass(std::vector<std::string> const& /*args*/, cmExecutionStatus& /*unused*/) override; - - cmCTestTestHandler* TestHandler; }; bool cmCTestAddTestCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } return this->TestHandler->AddTest(args); } -class cmCTestSetTestsPropertiesCommand : public cmCommand +class cmCTestSetTestsPropertiesCommand : public cmCTestCommand { public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - auto c = cm::make_unique<cmCTestSetTestsPropertiesCommand>(); - c->TestHandler = this->TestHandler; - return std::unique_ptr<cmCommand>(std::move(c)); - } + using cmCTestCommand::cmCTestCommand; /** * This is called when the command is first encountered in @@ -233,8 +196,6 @@ public: */ bool InitialPass(std::vector<std::string> const& /*args*/, cmExecutionStatus& /*unused*/) override; - - cmCTestTestHandler* TestHandler; }; bool cmCTestSetTestsPropertiesCommand::InitialPass( @@ -243,18 +204,10 @@ bool cmCTestSetTestsPropertiesCommand::InitialPass( return this->TestHandler->SetTestsProperties(args); } -class cmCTestSetDirectoryPropertiesCommand : public cmCommand +class cmCTestSetDirectoryPropertiesCommand : public cmCTestCommand { public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - auto c = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>(); - c->TestHandler = this->TestHandler; - return std::unique_ptr<cmCommand>(std::move(c)); - } + using cmCTestCommand::cmCTestCommand; /** * This is called when the command is first encountered in @@ -262,8 +215,6 @@ public: */ bool InitialPass(std::vector<std::string> const& /*unused*/, cmExecutionStatus& /*unused*/) override; - - cmCTestTestHandler* TestHandler; }; bool cmCTestSetDirectoryPropertiesCommand::InitialPass( @@ -324,6 +275,8 @@ inline int GetNextRealNumber(std::string const& in, double& val, return 0; } +} // namespace + cmCTestTestHandler::cmCTestTestHandler() { this->UseUnion = false; @@ -690,8 +643,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) for (std::string const& l : p.Labels) { // first check to see if the current label is a subproject label bool isSubprojectLabel = false; - std::vector<std::string>::iterator subproject = - std::find(subprojects.begin(), subprojects.end(), l); + auto subproject = std::find(subprojects.begin(), subprojects.end(), l); if (subproject != subprojects.end()) { isSubprojectLabel = true; } @@ -945,8 +897,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const FixtureDependencies fixtureSetups; FixtureDependencies fixtureCleanups; - for (ListOfTests::const_iterator it = this->TestList.begin(); - it != this->TestList.end(); ++it) { + for (auto it = this->TestList.begin(); it != this->TestList.end(); ++it) { const cmCTestTestProperties& p = *it; for (std::string const& deps : p.FixturesSetup) { @@ -1007,8 +958,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const // cleanup tests depend on this test case later. std::pair<FixtureDepsIterator, FixtureDepsIterator> setupRange = fixtureSetups.equal_range(requiredFixtureName); - for (FixtureDepsIterator sIt = setupRange.first; - sIt != setupRange.second; ++sIt) { + for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) { const std::string& setupTestName = sIt->second->Name; tests[i].RequireSuccessDepends.insert(setupTestName); if (!cmContains(tests[i].Depends, setupTestName)) { @@ -1031,8 +981,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const !excludeSetupRegex.find(requiredFixtureName)) { std::pair<FixtureDepsIterator, FixtureDepsIterator> fixtureRange = fixtureSetups.equal_range(requiredFixtureName); - for (FixtureDepsIterator it = fixtureRange.first; - it != fixtureRange.second; ++it) { + for (auto it = fixtureRange.first; it != fixtureRange.second; ++it) { ListOfTests::const_iterator lotIt = it->second; const cmCTestTestProperties& p = *lotIt; @@ -1063,8 +1012,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const !excludeCleanupRegex.find(requiredFixtureName)) { std::pair<FixtureDepsIterator, FixtureDepsIterator> fixtureRange = fixtureCleanups.equal_range(requiredFixtureName); - for (FixtureDepsIterator it = fixtureRange.first; - it != fixtureRange.second; ++it) { + for (auto it = fixtureRange.first; it != fixtureRange.second; ++it) { ListOfTests::const_iterator lotIt = it->second; const cmCTestTestProperties& p = *lotIt; @@ -1112,8 +1060,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const // This cleanup test could be part of the original test list that was // passed in. It is then possible that no other test requires the // fIt fixture, so we have to check for this. - std::map<std::string, std::vector<size_t>>::const_iterator cIt = - fixtureRequirements.find(fixture); + auto cIt = fixtureRequirements.find(fixture); if (cIt != fixtureRequirements.end()) { const std::vector<size_t>& indices = cIt->second; for (size_t index : indices) { @@ -1688,31 +1635,23 @@ void cmCTestTestHandler::GetListOfTests() mf.AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType()); // Add handler for ADD_TEST - auto newCom1 = cm::make_unique<cmCTestAddTestCommand>(); - newCom1->TestHandler = this; - cm.GetState()->AddBuiltinCommand("add_test", std::move(newCom1)); + cm.GetState()->AddBuiltinCommand("add_test", cmCTestAddTestCommand(this)); // Add handler for SUBDIRS - auto newCom2 = cm::make_unique<cmCTestSubdirCommand>(); - newCom2->TestHandler = this; - cm.GetState()->AddBuiltinCommand("subdirs", std::move(newCom2)); + cm.GetState()->AddBuiltinCommand("subdirs", cmCTestSubdirCommand); // Add handler for ADD_SUBDIRECTORY - auto newCom3 = cm::make_unique<cmCTestAddSubdirectoryCommand>(); - newCom3->TestHandler = this; - cm.GetState()->AddBuiltinCommand("add_subdirectory", std::move(newCom3)); + cm.GetState()->AddBuiltinCommand("add_subdirectory", + cmCTestAddSubdirectoryCommand); // Add handler for SET_TESTS_PROPERTIES - auto newCom4 = cm::make_unique<cmCTestSetTestsPropertiesCommand>(); - newCom4->TestHandler = this; - cm.GetState()->AddBuiltinCommand("set_tests_properties", std::move(newCom4)); + cm.GetState()->AddBuiltinCommand("set_tests_properties", + cmCTestSetTestsPropertiesCommand(this)); // Add handler for SET_DIRECTORY_PROPERTIES cm.GetState()->RemoveBuiltinCommand("set_directory_properties"); - auto newCom5 = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>(); - newCom5->TestHandler = this; cm.GetState()->AddBuiltinCommand("set_directory_properties", - std::move(newCom5)); + cmCTestSetDirectoryPropertiesCommand(this)); const char* testFilename; if (cmSystemTools::FileExists("CTestTestfile.cmake")) { @@ -1819,8 +1758,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformation(size_t numTests) std::sort(this->TestsToRun.begin(), this->TestsToRun.end(), std::less<int>()); // remove duplicates - std::vector<int>::iterator new_end = - std::unique(this->TestsToRun.begin(), this->TestsToRun.end()); + auto new_end = std::unique(this->TestsToRun.begin(), this->TestsToRun.end()); this->TestsToRun.erase(new_end, this->TestsToRun.end()); } @@ -2257,8 +2195,7 @@ bool cmCTestTestHandler::SetTestsProperties( // sort the array std::sort(rt.Labels.begin(), rt.Labels.end()); // remove duplicates - std::vector<std::string>::iterator new_end = - std::unique(rt.Labels.begin(), rt.Labels.end()); + auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end()); rt.Labels.erase(new_end, rt.Labels.end()); } if (key == "MEASUREMENT") { @@ -2337,8 +2274,7 @@ bool cmCTestTestHandler::SetDirectoryProperties( // sort the array std::sort(rt.Labels.begin(), rt.Labels.end()); // remove duplicates - std::vector<std::string>::iterator new_end = - std::unique(rt.Labels.begin(), rt.Labels.end()); + auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end()); rt.Labels.erase(new_end, rt.Labels.end()); } } diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 65dc921..673eb9a 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -7,14 +7,11 @@ #include "cmMakefile.h" #include "cmSystemTools.h" -#include <vector> - cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() { - if (this->Values[ct_SOURCE]) { + if (!this->Source.empty()) { this->CTest->SetCTestConfiguration( - "SourceDirectory", - cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(), + "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(), this->Quiet); } else { this->CTest->SetCTestConfiguration( diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h index 55c4b80..a4798a5 100644 --- a/Source/CTest/cmCTestUpdateCommand.h +++ b/Source/CTest/cmCTestUpdateCommand.h @@ -11,7 +11,7 @@ #include <string> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> class cmCTestGenericHandler; @@ -23,8 +23,6 @@ class cmCTestGenericHandler; class cmCTestUpdateCommand : public cmCTestHandlerCommand { public: - cmCTestUpdateCommand() {} - /** * This is a virtual constructor for the command. */ diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index a6a3542..c4cb233 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -20,7 +20,7 @@ #include <chrono> #include <sstream> -#include "cm_memory.hxx" +#include <cm/memory> static const char* cmCTestUpdateHandlerUpdateStrings[] = { "Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4" diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx index 59fbf37..9180821 100644 --- a/Source/CTest/cmCTestUploadCommand.cxx +++ b/Source/CTest/cmCTestUploadCommand.cxx @@ -2,61 +2,45 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestUploadCommand.h" +#include <set> #include <sstream> #include <vector> +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestUploadHandler.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmSystemTools.h" +#include "cm_static_string_view.hxx" -cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler() -{ - cmCTestUploadHandler* handler = this->CTest->GetUploadHandler(); - handler->Initialize(); - handler->SetFiles(this->Files); - handler->SetQuiet(this->Quiet); - return handler; -} - -bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg) +void cmCTestUploadCommand::BindArguments() { - if (arg == "FILES") { - this->ArgumentDoing = ArgumentDoingFiles; - return true; - } - if (arg == "QUIET") { - this->ArgumentDoing = ArgumentDoingNone; - this->Quiet = true; - return true; - } - if (arg == "CAPTURE_CMAKE_ERROR") { - this->ArgumentDoing = ArgumentDoingCaptureCMakeError; - return true; - } - return false; + this->Bind("FILES"_s, this->Files); + this->Bind("QUIET"_s, this->Quiet); + this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError); } -bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg) +void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&) { - if (this->ArgumentDoing == ArgumentDoingCaptureCMakeError) { - this->Values[ct_CAPTURE_CMAKE_ERROR] = arg.c_str(); - return true; - } - if (this->ArgumentDoing == ArgumentDoingFiles) { - if (cmSystemTools::FileExists(arg)) { - this->Files.insert(arg); + cmEraseIf(this->Files, [this](std::string const& arg) -> bool { + if (!cmSystemTools::FileExists(arg)) { + std::ostringstream e; + e << "File \"" << arg << "\" does not exist. Cannot submit " + << "a non-existent file."; + this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return true; } - std::ostringstream e; - e << "File \"" << arg << "\" does not exist. Cannot submit " - << "a non-existent file."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); - this->ArgumentDoing = ArgumentDoingError; return false; - } + }); +} - // Look for other arguments. - return this->Superclass::CheckArgumentValue(arg); +cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler() +{ + cmCTestUploadHandler* handler = this->CTest->GetUploadHandler(); + handler->Initialize(); + handler->SetFiles( + std::set<std::string>(this->Files.begin(), this->Files.end())); + handler->SetQuiet(this->Quiet); + return handler; } diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h index 9e49769..f78f0ec 100644 --- a/Source/CTest/cmCTestUploadCommand.h +++ b/Source/CTest/cmCTestUploadCommand.h @@ -8,11 +8,11 @@ #include "cmCTestHandlerCommand.h" #include "cmCommand.h" -#include <set> #include <string> #include <utility> +#include <vector> -#include "cm_memory.hxx" +#include <cm/memory> class cmCTestGenericHandler; @@ -41,22 +41,12 @@ public: */ std::string GetName() const override { return "ctest_upload"; } - using Superclass = cmCTestHandlerCommand; - protected: + void BindArguments() override; + void CheckArguments(std::vector<std::string> const&) override; cmCTestGenericHandler* InitializeHandler() override; - bool CheckArgumentKeyword(std::string const& arg) override; - bool CheckArgumentValue(std::string const& arg) override; - - enum - { - ArgumentDoingFiles = Superclass::ArgumentDoingLast1, - ArgumentDoingCaptureCMakeError, - ArgumentDoingLast2 - }; - - std::set<std::string> Files; + std::vector<std::string> Files; }; #endif diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index 773886d..00919e5 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -8,9 +8,9 @@ #include "cmXMLWriter.h" #include "cmsys/Process.h" +#include <cstdio> +#include <ctime> #include <sstream> -#include <stdio.h> -#include <time.h> #include <vector> cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log) diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 191100c..8c87700 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -7,8 +7,8 @@ #include "cmSystemTools.h" #include "cmsys/FStream.hxx" -#include <stdio.h> -#include <stdlib.h> +#include <cstdio> +#include <cstdlib> class cmParseBlanketJSCoverage::JSONParser { diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx index cd2bb1a..da48610 100644 --- a/Source/CTest/cmParseCacheCoverage.cxx +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -7,9 +7,9 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" +#include <cstdio> +#include <cstdlib> #include <map> -#include <stdio.h> -#include <stdlib.h> #include <utility> cmParseCacheCoverage::cmParseCacheCoverage( @@ -47,8 +47,7 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles() { // loop over the coverage data computed and remove all files // that only have -1 or 0 for the lines. - cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator ci = - this->Coverage.TotalCoverage.begin(); + auto ci = this->Coverage.TotalCoverage.begin(); while (ci != this->Coverage.TotalCoverage.end()) { cmCTestCoverageHandlerContainer::SingleFileCoverageVector& v = ci->second; bool nothing = true; diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index e4f353b..7c00d00 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -7,8 +7,8 @@ #include "cmXMLParser.h" #include "cmsys/FStream.hxx" -#include <stdlib.h> -#include <string.h> +#include <cstdlib> +#include <cstring> class cmParseCoberturaCoverage::XMLParser : public cmXMLParser { diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx index e8a184a..22c756c 100644 --- a/Source/CTest/cmParseDelphiCoverage.cxx +++ b/Source/CTest/cmParseDelphiCoverage.cxx @@ -6,8 +6,8 @@ #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" -#include <stdio.h> -#include <stdlib.h> +#include <cstdio> +#include <cstdlib> class cmParseDelphiCoverage::HTMLParser { diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 621ca79..1f2181b 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -7,9 +7,9 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" +#include <cstdio> +#include <cstdlib> #include <map> -#include <stdio.h> -#include <stdlib.h> #include <vector> cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont, diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index 6a2d0cc..be6348a 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -9,8 +9,8 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" -#include <stdlib.h> -#include <string.h> +#include <cstdlib> +#include <cstring> class cmParseJacocoCoverage::XMLParser : public cmXMLParser { diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx index afd7dc3..596b72e 100644 --- a/Source/CTest/cmParseMumpsCoverage.cxx +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -123,8 +123,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d) bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine, std::string& filepath) { - std::map<std::string, std::string>::iterator i = - this->RoutineToDirectory.find(routine); + auto i = this->RoutineToDirectory.find(routine); if (i != this->RoutineToDirectory.end()) { filepath = i->second; return true; diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx index 870e222..8f0404d 100644 --- a/Source/CTest/cmParsePHPCoverage.cxx +++ b/Source/CTest/cmParsePHPCoverage.cxx @@ -7,8 +7,8 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" -#include <stdlib.h> -#include <string.h> +#include <cstdlib> +#include <cstring> /* To setup coverage for php. diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 61d2ed3..9c63a59 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -10,8 +10,8 @@ #include "cmStringAlgorithms.h" #include "cmsys/Process.h" +#include <csignal> #include <iostream> -#include <signal.h> #include <string> #if defined(_WIN32) # include "cm_kwiml.h" diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index ce32898..567b4f4 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -11,9 +11,9 @@ #include "cmake.h" #include "cmsys/Encoding.hxx" +#include <csignal> +#include <cstring> #include <iostream> -#include <signal.h> -#include <string.h> #include <string> #include <vector> diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index f450a1c..47fe84c 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -15,7 +15,7 @@ #include "cmSystemTools.h" #include "cmake.h" -#include <assert.h> +#include <cassert> #include <vector> cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx index 95026d5..028cc26 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.cxx +++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx @@ -7,8 +7,8 @@ #include "cmCursesStandardIncludes.h" #include "cmVersion.h" -#include <stdio.h> -#include <string.h> +#include <cstdio> +#include <cstring> inline int ctrl(int z) { diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 1b25716..5f8a19e 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -19,8 +19,8 @@ #include "cmake.h" #include <algorithm> -#include <stdio.h> -#include <string.h> +#include <cstdio> +#include <cstring> #include <utility> inline int ctrl(int z) diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h index d379975..f3194ab 100644 --- a/Source/CursesDialog/cmCursesMainForm.h +++ b/Source/CursesDialog/cmCursesMainForm.h @@ -9,7 +9,7 @@ #include "cmCursesStandardIncludes.h" #include "cmStateTypes.h" -#include <stddef.h> +#include <cstddef> #include <string> #include <vector> diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx index 26724e7..3fc1858 100644 --- a/Source/CursesDialog/cmCursesStringWidget.cxx +++ b/Source/CursesDialog/cmCursesStringWidget.cxx @@ -8,8 +8,8 @@ #include "cmCursesWidget.h" #include "cmStateTypes.h" -#include <stdio.h> -#include <string.h> +#include <cstdio> +#include <cstring> inline int ctrl(int z) { diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 287a482..ad18cfe 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -229,8 +229,8 @@ int main(int argc, char** argv) #if defined(Q_OS_MAC) # include "cm_sys_stat.h" -# include <errno.h> -# include <string.h> +# include <cerrno> +# include <cstring> # include <unistd.h> static bool cmOSXInstall(std::string const& dir, std::string const& tool) { diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index d9a8aff..0f09d7c 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -107,8 +107,7 @@ void StartCompilerSetup::setGenerators( ->GeneratorDefaultPlatform[QString::fromLocal8Bit(gen.name.c_str())] = QString::fromLocal8Bit(gen.defaultPlatform.c_str()); - std::vector<std::string>::const_iterator platformIt = - gen.supportedPlatforms.cbegin(); + auto platformIt = gen.supportedPlatforms.cbegin(); while (platformIt != gen.supportedPlatforms.cend()) { this->GeneratorSupportedPlatforms.insert( diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index d2330e1..35db6a4 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -4,7 +4,6 @@ #include <sstream> #include <unordered_set> -#include <utility> #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" @@ -13,7 +12,6 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -51,7 +49,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, bool uses_terminal = false; bool command_expand_lists = false; std::string implicit_depends_lang; - cmCustomCommand::ImplicitDependsList implicit_depends; + cmImplicitDependsList implicit_depends; // Accumulate one command line at a time. cmCustomCommandLine currentLine; @@ -248,6 +246,8 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, // An implicit dependency starting point is also an // explicit dependency. std::string dep = copy; + // Upfront path conversion is correct because Genex + // are not supported. cmSystemTools::ConvertToUnixSlashes(dep); depends.push_back(dep); @@ -264,9 +264,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, target = copy; break; case doing_depends: { - std::string dep = copy; - cmSystemTools::ConvertToUnixSlashes(dep); - depends.push_back(std::move(dep)); + depends.push_back(copy); } break; case doing_outputs: outputs.push_back(filename); @@ -317,21 +315,15 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, // Check for an append request. if (append) { - // Lookup an existing command. - if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) { - if (cmCustomCommand* cc = sf->GetCustomCommand()) { - cc->AppendCommands(commandLines); - cc->AppendDepends(depends); - cc->AppendImplicitDepends(implicit_depends); - return true; - } + if (mf.AppendCustomCommandToOutput(output[0], depends, implicit_depends, + commandLines)) { + return true; } // No command for this output exists. - std::ostringstream e; - e << "given APPEND option with output\n\"" << output[0] - << "\"\nwhich is not already a custom command output."; - status.SetError(e.str()); + status.SetError( + cmStrCat("given APPEND option with output\n\"", output[0], + "\"\nwhich is not already a custom command output.")); return false; } @@ -351,28 +343,10 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, job_pool, command_expand_lists); } else if (target.empty()) { // Target is empty, use the output. - mf.AddCustomCommandToOutput(output, byproducts, depends, main_dependency, - commandLines, comment, working.c_str(), false, - escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool); - - // Add implicit dependency scanning requests if any were given. - if (!implicit_depends.empty()) { - bool okay = false; - if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) { - if (cmCustomCommand* cc = sf->GetCustomCommand()) { - okay = true; - cc->SetImplicitDepends(implicit_depends); - } - } - if (!okay) { - std::ostringstream e; - e << "could not locate source file with a custom command producing \"" - << output[0] << "\" even though this command tried to create it!"; - status.SetError(e.str()); - return false; - } - } + mf.AddCustomCommandToOutput( + output, byproducts, depends, main_dependency, implicit_depends, + commandLines, comment, working.c_str(), false, escapeOldStyle, + uses_terminal, command_expand_lists, depfile, job_pool); } else if (!byproducts.empty()) { status.SetError("BYPRODUCTS may not be specified with SOURCE signatures"); return false; @@ -432,10 +406,8 @@ bool cmAddCustomCommandCommandCheckOutputs( // Make sure the output file name has no invalid characters. std::string::size_type pos = o.find_first_of("#<>"); if (pos != std::string::npos) { - std::ostringstream msg; - msg << "called with OUTPUT containing a \"" << o[pos] - << "\". This character is not allowed."; - status.SetError(msg.str()); + status.SetError(cmStrCat("called with OUTPUT containing a \"", o[pos], + "\". This character is not allowed.")); return false; } } diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index caea510..9fd1234 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddCustomTargetCommand.h" -#include <sstream> #include <utility> #include "cmCustomCommandLines.h" @@ -29,11 +28,9 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args, // Check the target name. if (targetName.find_first_of("/\\") != std::string::npos) { - std::ostringstream e; - e << "called with invalid target name \"" << targetName - << "\". Target names may not contain a slash. " - << "Use ADD_CUSTOM_COMMAND to generate files."; - status.SetError(e.str()); + status.SetError(cmStrCat("called with invalid target name \"", targetName, + "\". Target names may not contain a slash. " + "Use ADD_CUSTOM_COMMAND to generate files.")); return false; } @@ -127,7 +124,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args, } filename += copy; cmSystemTools::ConvertToUnixSlashes(filename); - byproducts.push_back(filename); + byproducts.push_back(cmSystemTools::CollapseFullPath(filename)); } break; case doing_depends: { std::string dep = copy; @@ -153,10 +150,9 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args, std::string::size_type pos = targetName.find_first_of("#<>"); if (pos != std::string::npos) { - std::ostringstream msg; - msg << "called with target name containing a \"" << targetName[pos] - << "\". This character is not allowed."; - status.SetError(msg.str()); + status.SetError(cmStrCat("called with target name containing a \"", + targetName[pos], + "\". This character is not allowed.")); return false; } diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index 0ddbda8..b1fc893 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -2,12 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddDependenciesCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" bool cmAddDependenciesCommand(std::vector<std::string> const& args, @@ -21,10 +20,10 @@ bool cmAddDependenciesCommand(std::vector<std::string> const& args, cmMakefile& mf = status.GetMakefile(); std::string const& target_name = args[0]; if (mf.IsAlias(target_name)) { - std::ostringstream e; - e << "Cannot add target-level dependencies to alias target \"" - << target_name << "\".\n"; - mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot add target-level dependencies to alias target \"", + target_name, "\".\n")); } if (cmTarget* target = mf.FindTargetToUse(target_name)) { @@ -33,14 +32,17 @@ bool cmAddDependenciesCommand(std::vector<std::string> const& args, target->AddUtility(arg, &mf); } } else { - std::ostringstream e; - e << "Cannot add target-level dependencies to non-existent target \"" - << target_name << "\".\n" - << "The add_dependencies works for top-level logical targets created " - << "by the add_executable, add_library, or add_custom_target commands. " - << "If you want to add file-level dependencies see the DEPENDS option " - << "of the add_custom_target and add_custom_command commands."; - mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat( + "Cannot add target-level dependencies to non-existent " + "target \"", + target_name, + "\".\nThe add_dependencies works for " + "top-level logical targets created by the add_executable, " + "add_library, or add_custom_target commands. If you want to add " + "file-level dependencies see the DEPENDS option of the " + "add_custom_target and add_custom_command commands.")); } return true; diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index f1264d5..e738bc4 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -2,13 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddExecutableCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" bool cmAddExecutableCommand(std::vector<std::string> const& args, @@ -20,7 +19,7 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args, } cmMakefile& mf = status.GetMakefile(); - std::vector<std::string>::const_iterator s = args.begin(); + auto s = args.begin(); std::string const& exename = *s; @@ -99,34 +98,30 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args, std::string const& aliasedName = *s; if (mf.IsAlias(aliasedName)) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" is itself an ALIAS."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", exename, + "\" because target \"", aliasedName, + "\" is itself an ALIAS.")); return false; } cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true); if (!aliasedTarget) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" does not already exist."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", exename, + "\" because target \"", aliasedName, + "\" does not already exist.")); return false; } cmStateEnums::TargetType type = aliasedTarget->GetType(); if (type != cmStateEnums::EXECUTABLE) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" is not an executable."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", exename, + "\" because target \"", aliasedName, + "\" is not an executable.")); return false; } if (aliasedTarget->IsImported() && !aliasedTarget->IsImportedGloballyVisible()) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << exename << "\" because target \"" - << aliasedName << "\" is imported but not globally visible."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", exename, + "\" because target \"", aliasedName, + "\" is imported but not globally visible.")); return false; } mf.AddAlias(exename, aliasedName); @@ -137,10 +132,9 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args, if (importTarget) { // Make sure the target does not already exist. if (mf.FindTargetToUse(exename)) { - std::ostringstream e; - e << "cannot create imported target \"" << exename - << "\" because another target with the same name already exists."; - status.SetError(e.str()); + status.SetError(cmStrCat( + "cannot create imported target \"", exename, + "\" because another target with the same name already exists.")); return false; } diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index c067aea..0439c51 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddLibraryCommand.h" -#include <sstream> - #include "cmAlgorithms.h" #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" @@ -34,7 +32,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, bool importTarget = false; bool importGlobal = false; - std::vector<std::string>::const_iterator s = args.begin(); + auto s = args.begin(); std::string const& libName = *s; @@ -184,20 +182,16 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, std::string const& aliasedName = *s; if (mf.IsAlias(aliasedName)) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << libName << "\" because target \"" - << aliasedName << "\" is itself an ALIAS."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", libName, + "\" because target \"", aliasedName, + "\" is itself an ALIAS.")); return false; } cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true); if (!aliasedTarget) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << libName << "\" because target \"" - << aliasedName - << "\" does not already " - "exist."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", libName, + "\" because target \"", aliasedName, + "\" does not already exist.")); return false; } cmStateEnums::TargetType aliasedType = aliasedTarget->GetType(); @@ -208,18 +202,16 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, aliasedType != cmStateEnums::INTERFACE_LIBRARY && !(aliasedType == cmStateEnums::UNKNOWN_LIBRARY && aliasedTarget->IsImported())) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << libName << "\" because target \"" - << aliasedName << "\" is not a library."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", libName, + "\" because target \"", aliasedName, + "\" is not a library.")); return false; } if (aliasedTarget->IsImported() && !aliasedTarget->IsImportedGloballyVisible()) { - std::ostringstream e; - e << "cannot create ALIAS target \"" << libName << "\" because target \"" - << aliasedName << "\" is imported but not globally visible."; - status.SetError(e.str()); + status.SetError(cmStrCat("cannot create ALIAS target \"", libName, + "\" because target \"", aliasedName, + "\" is imported but not globally visible.")); return false; } mf.AddAlias(libName, aliasedName); @@ -238,12 +230,13 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, if ((type == cmStateEnums::SHARED_LIBRARY || type == cmStateEnums::MODULE_LIBRARY) && !mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) { - std::ostringstream w; - w << "ADD_LIBRARY called with " - << (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE") - << " option but the target platform does not support dynamic linking. " - "Building a STATIC library instead. This may lead to problems."; - mf.IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + mf.IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat( + "ADD_LIBRARY called with ", + (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE"), + " option but the target platform does not support dynamic linking. ", + "Building a STATIC library instead. This may lead to problems.")); type = cmStateEnums::STATIC_LIBRARY; } @@ -266,19 +259,17 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, } if (type == cmStateEnums::INTERFACE_LIBRARY) { if (!cmGeneratorExpression::IsValidTargetName(libName)) { - std::ostringstream e; - e << "Invalid name for IMPORTED INTERFACE library target: " << libName; - status.SetError(e.str()); + status.SetError(cmStrCat( + "Invalid name for IMPORTED INTERFACE library target: ", libName)); return false; } } // Make sure the target does not already exist. if (mf.FindTargetToUse(libName)) { - std::ostringstream e; - e << "cannot create imported target \"" << libName - << "\" because another target with the same name already exists."; - status.SetError(e.str()); + status.SetError(cmStrCat( + "cannot create imported target \"", libName, + "\" because another target with the same name already exists.")); return false; } @@ -309,9 +300,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, if (type == cmStateEnums::INTERFACE_LIBRARY) { if (!cmGeneratorExpression::IsValidTargetName(libName) || libName.find("::") != std::string::npos) { - std::ostringstream e; - e << "Invalid name for INTERFACE library target: " << libName; - status.SetError(e.str()); + status.SetError( + cmStrCat("Invalid name for INTERFACE library target: ", libName)); return false; } diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 17bdc4a..6a1a514 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -2,8 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddSubDirectoryCommand.h" -#include <sstream> -#include <string.h> +#include <cstring> #include "cmExecutionStatus.h" #include "cmMakefile.h" @@ -64,13 +63,13 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args, // error. if (!cmSystemTools::IsSubDirectory(srcPath, mf.GetCurrentSourceDirectory())) { - std::ostringstream e; - e << "not given a binary directory but the given source directory " - << "\"" << srcPath << "\" is not a subdirectory of \"" - << mf.GetCurrentSourceDirectory() << "\". " - << "When specifying an out-of-tree source a binary directory " - << "must be explicitly specified."; - status.SetError(e.str()); + status.SetError( + cmStrCat("not given a binary directory but the given source ", + "directory \"", srcPath, "\" is not a subdirectory of \"", + mf.GetCurrentSourceDirectory(), + "\". When specifying an " + "out-of-tree source a binary directory must be explicitly " + "specified.")); return false; } diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx index 7904bf5..8942113 100644 --- a/Source/cmAddTestCommand.cxx +++ b/Source/cmAddTestCommand.cxx @@ -2,10 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddTestCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmTest.h" #include "cmTestGenerator.h" @@ -38,10 +37,8 @@ bool cmAddTestCommand(std::vector<std::string> const& args, // If the test was already added by a new-style signature do not // allow it to be duplicated. if (!test->GetOldStyle()) { - std::ostringstream e; - e << " given test name \"" << args[0] - << "\" which already exists in this directory."; - status.SetError(e.str()); + status.SetError(cmStrCat(" given test name \"", args[0], + "\" which already exists in this directory.")); return false; } } else { @@ -110,9 +107,7 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args, working_directory = args[i]; doing = DoingNone; } else { - std::ostringstream e; - e << " given unknown argument:\n " << args[i] << "\n"; - status.SetError(e.str()); + status.SetError(cmStrCat(" given unknown argument:\n ", args[i], "\n")); return false; } } @@ -133,10 +128,8 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args, // Require a unique test name within the directory. if (mf.GetTest(name)) { - std::ostringstream e; - e << " given test NAME \"" << name - << "\" which already exists in this directory."; - status.SetError(e.str()); + status.SetError(cmStrCat(" given test NAME \"", name, + "\" which already exists in this directory.")); return false; } diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx index a6d89aa..33768a9 100644 --- a/Source/cmAffinity.cxx +++ b/Source/cmAffinity.cxx @@ -13,7 +13,7 @@ # 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 +# include <cstring> // IWYU pragma: keep # if defined(__FreeBSD__) # include <pthread_np.h> # include <sys/cpuset.h> diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 6775f9d..06ea9f6 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -165,14 +165,14 @@ typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem) { typename InputRange::const_iterator remIt = rem.begin(); typename InputRange::const_iterator remEnd = rem.end(); - const typename Range::iterator rangeEnd = r.end(); + const auto rangeEnd = r.end(); if (remIt == remEnd) { return rangeEnd; } - typename Range::iterator writer = r.begin(); + auto writer = r.begin(); std::advance(writer, *remIt); - typename Range::iterator pivot = writer; + auto pivot = writer; typename InputRange::value_type prevRem = *remIt; ++remIt; size_t count = 1; @@ -238,81 +238,4 @@ typename Range::const_iterator cmFindNot(Range const& r, T const& t) return std::find_if(r.begin(), r.end(), [&t](T const& i) { return i != t; }); } -template <class Iter> -std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it) -{ - return std::reverse_iterator<Iter>(it); -} - -namespace cm { - -#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L - -using std::size; - -#else - -// std::size backport from C++17. -template <class C> -# if !defined(_MSC_VER) || _MSC_VER >= 1900 -constexpr -# endif - auto - size(C const& c) -> decltype(c.size()) -{ - return c.size(); -} - -template <typename T, size_t N> -# if !defined(_MSC_VER) || _MSC_VER >= 1900 -constexpr -# endif - std::size_t - size(const T (&)[N]) throw() -{ - return N; -} - -#endif - -template <typename T> -int isize(const T& t) -{ - return static_cast<int>(cm::size(t)); -} - -#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L - -using std::cbegin; -using std::cend; - -#else - -// std::c{begin,end} backport from C++14 -template <class C> -# if defined(_MSC_VER) && _MSC_VER < 1900 -auto cbegin(C const& c) -# else -constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c))) -# endif - -> decltype(std::begin(c)) -{ - return std::begin(c); -} - -template <class C> -# if defined(_MSC_VER) && _MSC_VER < 1900 -auto cend(C const& c) -# else -constexpr auto cend(C const& c) noexcept(noexcept(std::end(c))) -# endif - -> decltype(std::end(c)) -{ - return std::end(c); -} - -#endif - -} // namespace cm - #endif diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index a6c25e1..c45edaf 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -11,10 +11,10 @@ #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" +#include <cstring> +#include <ctime> #include <iostream> #include <sstream> -#include <string.h> -#include <time.h> #ifndef __LA_SSIZE_T # define __LA_SSIZE_T la_ssize_t diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index e90a603..e791761 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -5,8 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cstddef> #include <iosfwd> -#include <stddef.h> #include <string> #if defined(CMAKE_BOOTSTRAP) diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx index 751d117..4c87177 100644 --- a/Source/cmArgumentParser.cxx +++ b/Source/cmArgumentParser.cxx @@ -61,10 +61,14 @@ void Instance::Bind(MultiStringList& val) void Instance::Consume(cm::string_view arg, void* result, std::vector<std::string>* unparsedArguments, - std::vector<std::string>* keywordsMissingValue) + std::vector<std::string>* keywordsMissingValue, + std::vector<std::string>* parsedKeywords) { auto const it = this->Bindings.Find(arg); if (it != this->Bindings.end()) { + if (parsedKeywords != nullptr) { + parsedKeywords->emplace_back(arg); + } it->second(*this, result); if (this->ExpectValue && keywordsMissingValue != nullptr) { keywordsMissingValue->emplace_back(arg); diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h index 6cfe946..9be2488 100644 --- a/Source/cmArgumentParser.h +++ b/Source/cmArgumentParser.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" +#include <cm/string_view> #include <cassert> #include <functional> @@ -45,7 +45,8 @@ public: void Consume(cm::string_view arg, void* result, std::vector<std::string>* unparsedArguments, - std::vector<std::string>* keywordsMissingValue); + std::vector<std::string>* keywordsMissingValue, + std::vector<std::string>* parsedKeywords); private: ActionMap const& Bindings; @@ -79,21 +80,25 @@ public: template <typename Range> void Parse(Result& result, Range const& args, std::vector<std::string>* unparsedArguments = nullptr, - std::vector<std::string>* keywordsMissingValue = nullptr) const + std::vector<std::string>* keywordsMissingValue = nullptr, + std::vector<std::string>* parsedKeywords = nullptr) const { ArgumentParser::Instance instance(this->Bindings); for (cm::string_view arg : args) { - instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue); + instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue, + parsedKeywords); } } template <typename Range> Result Parse(Range const& args, std::vector<std::string>* unparsedArguments = nullptr, - std::vector<std::string>* keywordsMissingValue = nullptr) const + std::vector<std::string>* keywordsMissingValue = nullptr, + std::vector<std::string>* parsedKeywords = nullptr) const { Result result; - this->Parse(result, args, unparsedArguments, keywordsMissingValue); + this->Parse(result, args, unparsedArguments, keywordsMissingValue, + parsedKeywords); return result; } @@ -116,11 +121,13 @@ public: template <typename Range> void Parse(Range const& args, std::vector<std::string>* unparsedArguments = nullptr, - std::vector<std::string>* keywordsMissingValue = nullptr) const + std::vector<std::string>* keywordsMissingValue = nullptr, + std::vector<std::string>* parsedKeywords = nullptr) const { ArgumentParser::Instance instance(this->Bindings); for (cm::string_view arg : args) { - instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue); + instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue, + parsedKeywords); } } diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index 7bf19d0..111bc41 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -4,7 +4,7 @@ #include "cmsys/Directory.hxx" #include <algorithm> -#include <stddef.h> +#include <cstddef> #include <utility> #include "cmExecutionStatus.h" diff --git a/Source/cmBase32.h b/Source/cmBase32.h index c6758d4..d85198d 100644 --- a/Source/cmBase32.h +++ b/Source/cmBase32.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stddef.h> +#include <cstddef> #include <string> /** \class cmBase32Encoder diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx index 6316a29..a1125a9 100644 --- a/Source/cmBinUtilsLinuxELFLinker.cxx +++ b/Source/cmBinUtilsLinuxELFLinker.cxx @@ -15,7 +15,7 @@ #include <sstream> -#include "cm_memory.hxx" +#include <cm/memory> static std::string ReplaceOrigin(const std::string& rpath, const std::string& origin) diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx index 7ff8584..b1f718b 100644 --- a/Source/cmBinUtilsMacOSMachOLinker.cxx +++ b/Source/cmBinUtilsMacOSMachOLinker.cxx @@ -12,7 +12,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> cmBinUtilsMacOSMachOLinker::cmBinUtilsMacOSMachOLinker( cmRuntimeDependencyArchive* archive) diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx index 5a9ad66..bfafaeb 100644 --- a/Source/cmBinUtilsWindowsPELinker.cxx +++ b/Source/cmBinUtilsWindowsPELinker.cxx @@ -12,7 +12,7 @@ #include <sstream> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #ifdef _WIN32 # include <windows.h> diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index e9e1d49..49c9439 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -2,32 +2,21 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmBuildCommand.h" -#include <sstream> - +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -bool cmBuildCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) -{ - // Support the legacy signature of the command: - // - if (2 == args.size()) { - return this->TwoArgsSignature(args); - } - - return this->MainSignature(args); -} +namespace { -bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) +bool MainSignature(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("requires at least one argument naming a CMake variable"); + status.SetError("requires at least one argument naming a CMake variable"); return false; } @@ -63,9 +52,7 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) doing = DoingNone; target = args[i]; } else { - std::ostringstream e; - e << "unknown argument \"" << args[i] << "\""; - this->SetError(e.str()); + status.SetError(cmStrCat("unknown argument \"", args[i], "\"")); return false; } } @@ -82,30 +69,32 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) configuration = "Release"; } + cmMakefile& mf = status.GetMakefile(); if (!project_name.empty()) { - this->Makefile->IssueMessage( - MessageType::AUTHOR_WARNING, - "Ignoring PROJECT_NAME option because it has no effect."); + mf.IssueMessage(MessageType::AUTHOR_WARNING, + "Ignoring PROJECT_NAME option because it has no effect."); } - std::string makecommand = - this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand( - target, configuration, "", this->Makefile->IgnoreErrorsCMP0061()); + std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand( + target, configuration, "", mf.IgnoreErrorsCMP0061()); - this->Makefile->AddDefinition(variable, makecommand); + mf.AddDefinition(variable, makecommand); return true; } -bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args) +bool TwoArgsSignature(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with less than two arguments"); + status.SetError("called with less than two arguments"); return false; } + cmMakefile& mf = status.GetMakefile(); + std::string const& define = args[0]; - const char* cacheValue = this->Makefile->GetDefinition(define); + const char* cacheValue = mf.GetDefinition(define); std::string configType; if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) || @@ -113,16 +102,28 @@ bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args) configType = "Release"; } - std::string makecommand = - this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand( - "", configType, "", this->Makefile->IgnoreErrorsCMP0061()); + std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand( + "", configType, "", mf.IgnoreErrorsCMP0061()); if (cacheValue) { return true; } - this->Makefile->AddCacheDefinition(define, makecommand.c_str(), - "Command used to build entire project " - "from the command line.", - cmStateEnums::STRING); + mf.AddCacheDefinition(define, makecommand.c_str(), + "Command used to build entire project " + "from the command line.", + cmStateEnums::STRING); return true; } + +} // namespace + +bool cmBuildCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + // Support the legacy signature of the command: + if (args.size() == 2) { + return TwoArgsSignature(args, status); + } + + return MainSignature(args, status); +} diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h index d373103..45aa71d 100644 --- a/Source/cmBuildCommand.h +++ b/Source/cmBuildCommand.h @@ -8,47 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmBuildCommand - * \brief build_command command - * - * cmBuildCommand implements the build_command CMake command - */ -class cmBuildCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmBuildCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - - /** - * The primary command signature with optional, KEYWORD-based args. - */ - virtual bool MainSignature(std::vector<std::string> const& args); - - /** - * Legacy "exactly 2 args required" signature. - */ - virtual bool TwoArgsSignature(std::vector<std::string> const& args); - -private: - bool IgnoreErrors() const; -}; +bool cmBuildCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 974b984..c3f6f40 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeHostSystemInformationCommand.h" -#include <stddef.h> +#include <cstddef> #include "cmExecutionStatus.h" #include "cmMakefile.h" diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index f93c266..1b03873 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -2,8 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeMinimumRequired.h" +#include <cstdio> #include <sstream> -#include <stdio.h> #include "cmExecutionStatus.h" #include "cmMakefile.h" diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx index 9b1aea9..b7f08d2 100644 --- a/Source/cmCMakePolicyCommand.cxx +++ b/Source/cmCMakePolicyCommand.cxx @@ -2,14 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakePolicyCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" namespace { bool HandleSetMode(std::vector<std::string> const& args, @@ -60,9 +59,7 @@ bool cmCMakePolicyCommand(std::vector<std::string> const& args, return HandleGetWarningMode(args, status); } - std::ostringstream e; - e << "given unknown first argument \"" << args[0] << "\""; - status.SetError(e.str()); + status.SetError(cmStrCat("given unknown first argument \"", args[0], "\"")); return false; } @@ -82,9 +79,8 @@ bool HandleSetMode(std::vector<std::string> const& args, } else if (args[2] == "NEW") { policyStatus = cmPolicies::NEW; } else { - std::ostringstream e; - e << "SET given unrecognized policy status \"" << args[2] << "\""; - status.SetError(e.str()); + status.SetError( + cmStrCat("SET given unrecognized policy status \"", args[2], "\"")); return false; } @@ -128,10 +124,9 @@ bool HandleGetMode(std::vector<std::string> const& args, // Lookup the policy number. cmPolicies::PolicyID pid; if (!cmPolicies::GetPolicyID(id.c_str(), pid)) { - std::ostringstream e; - e << "GET given policy \"" << id << "\" which is not known to this " - << "version of CMake."; - status.SetError(e.str()); + status.SetError( + cmStrCat("GET given policy \"", id, + "\" which is not known to this version of CMake.")); return false; } @@ -155,12 +150,14 @@ bool HandleGetMode(std::vector<std::string> const& args, case cmPolicies::REQUIRED_ALWAYS: // The policy is required to be set before anything needs it. { - std::ostringstream e; - e << cmPolicies::GetRequiredPolicyError(pid) << "\n" - << "The call to cmake_policy(GET " << id << " ...) at which this " - << "error appears requests the policy, and this version of CMake " - << "requires that the policy be set to NEW before it is checked."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat( + cmPolicies::GetRequiredPolicyError(pid), "\n", + "The call to cmake_policy(GET ", id, + " ...) at which this " + "error appears requests the policy, and this version of CMake ", + "requires that the policy be set to NEW before it is checked.")); } } @@ -188,10 +185,9 @@ bool HandleVersionMode(std::vector<std::string> const& args, : std::string(); if (dd != std::string::npos && (version_min.empty() || version_max.empty())) { - std::ostringstream e; - e << "VERSION \"" << version_string - << R"(" does not have a version on both sides of "...".)"; - status.SetError(e.str()); + status.SetError( + cmStrCat("VERSION \"", version_string, + R"(" does not have a version on both sides of "...".)")); return false; } @@ -215,10 +211,9 @@ bool HandleGetWarningMode(std::vector<std::string> const& args, // Lookup the policy number. cmPolicies::PolicyID pid; if (!cmPolicies::GetPolicyID(id.c_str(), pid)) { - std::ostringstream e; - e << "GET_WARNING given policy \"" << id - << "\" which is not known to this version of CMake."; - status.SetError(e.str()); + status.SetError( + cmStrCat("GET_WARNING given policy \"", id, + "\" which is not known to this version of CMake.")); return false; } diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index e814d67..1eaf48b 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -14,7 +14,7 @@ #include "cmState.h" #include "cmVersion.h" -#include <stdlib.h> +#include <cstdlib> #ifdef __QNX__ # include <malloc.h> /* for malloc/free on QNX */ @@ -531,7 +531,7 @@ void CCONV* cmGetSource(void* arg, const char* name) cmMakefile* mf = static_cast<cmMakefile*>(arg); if (cmSourceFile* rsf = mf->GetSource(name)) { // Lookup the proxy source file object for this source. - cmCPluginAPISourceFileMap::iterator i = cmCPluginAPISourceFiles.find(rsf); + auto i = cmCPluginAPISourceFiles.find(rsf); if (i == cmCPluginAPISourceFiles.end()) { // Create a proxy source file object for this source. cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile; @@ -561,7 +561,7 @@ void* CCONV cmAddSource(void* arg, void* arg2) // Create the real cmSourceFile instance and copy over saved information. cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath); - rsf->GetProperties() = osf->Properties; + rsf->SetProperties(osf->Properties); for (std::string const& d : osf->Depends) { rsf->AddDepend(d); } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index f51ed0b..1031f40 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -11,16 +11,16 @@ #include "cmsys/Process.h" #include "cmsys/SystemInformation.hxx" #include <algorithm> +#include <cctype> #include <chrono> -#include <ctype.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> #include <iostream> #include <map> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <string> -#include <time.h> #include <utility> #include <vector> #if defined(_WIN32) @@ -29,7 +29,7 @@ # include <unistd.h> // IWYU pragma: keep #endif -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmCTestBuildAndTestHandler.h" @@ -1483,8 +1483,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects() // sort the array std::sort(subprojects.begin(), subprojects.end()); // remove duplicates - std::vector<std::string>::iterator new_end = - std::unique(subprojects.begin(), subprojects.end()); + auto new_end = std::unique(subprojects.begin(), subprojects.end()); subprojects.erase(new_end, subprojects.end()); return subprojects; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 41dac85..9b11653 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -9,11 +9,11 @@ #include "cmProcessOutput.h" #include <chrono> +#include <ctime> #include <map> #include <memory> #include <sstream> #include <string> -#include <time.h> #include <vector> class cmCTestBuildHandler; diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index cf28cdb..0888a5e 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -5,9 +5,9 @@ #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" #include <algorithm> +#include <cstdio> +#include <cstring> #include <sstream> -#include <stdio.h> -#include <string.h> #include <string> #include "cmGeneratedFileStream.h" @@ -480,7 +480,7 @@ void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout, void cmCacheManager::RemoveCacheEntry(const std::string& key) { - CacheEntryMap::iterator i = this->Cache.find(key); + auto i = this->Cache.find(key); if (i != this->Cache.end()) { this->Cache.erase(i); } @@ -489,7 +489,7 @@ void cmCacheManager::RemoveCacheEntry(const std::string& key) cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry( const std::string& key) { - CacheEntryMap::iterator i = this->Cache.find(key); + auto i = this->Cache.find(key); if (i != this->Cache.end()) { return &i->second; } @@ -498,13 +498,13 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry( cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key) { - return CacheIterator(*this, key); + return { *this, key }; } const std::string* cmCacheManager::GetInitializedCacheValue( const std::string& key) const { - CacheEntryMap::const_iterator i = this->Cache.find(key); + auto i = this->Cache.find(key); if (i != this->Cache.end() && i->second.Initialized) { return &i->second.Value; } diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index a988bd8..faa60c5 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -94,7 +94,7 @@ public: }; //! return an iterator to iterate through the cache map - cmCacheManager::CacheIterator NewIterator() { return CacheIterator(*this); } + cmCacheManager::CacheIterator NewIterator() { return { *this }; } //! Load a cache for given makefile. Loads from path/CMakeCache.txt. bool LoadCache(const std::string& path, bool internal, diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index b368b3a..e35fba5 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -8,9 +8,9 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include <cstring> #include <iostream> #include <sstream> -#include <string.h> int cmCommandArgument_yyparse(yyscan_t yyscanner); // diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 702b743..88d17f1 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -1,7 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommands.h" #include "cmPolicies.h" @@ -125,14 +125,11 @@ void GetScriptingCommands(cmState* state) state->AddBuiltinCommand("exec_program", cmExecProgramCommand); state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand); state->AddBuiltinCommand("file", cmFileCommand); - state->AddBuiltinCommand("find_file", cm::make_unique<cmFindFileCommand>()); - state->AddBuiltinCommand("find_library", - cm::make_unique<cmFindLibraryCommand>()); - state->AddBuiltinCommand("find_package", - cm::make_unique<cmFindPackageCommand>()); - state->AddBuiltinCommand("find_path", cm::make_unique<cmFindPathCommand>()); - state->AddBuiltinCommand("find_program", - cm::make_unique<cmFindProgramCommand>()); + state->AddBuiltinCommand("find_file", cmFindFile); + state->AddBuiltinCommand("find_library", cmFindLibrary); + state->AddBuiltinCommand("find_package", cmFindPackage); + state->AddBuiltinCommand("find_path", cmFindPath); + state->AddBuiltinCommand("find_program", cmFindProgram); state->AddBuiltinCommand("foreach", cmForEachCommand); state->AddBuiltinCommand("function", cmFunctionCommand); state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand); @@ -225,41 +222,30 @@ void GetProjectCommands(cmState* state) state->AddBuiltinCommand("add_library", cmAddLibraryCommand); state->AddBuiltinCommand("add_subdirectory", cmAddSubDirectoryCommand); state->AddBuiltinCommand("add_test", cmAddTestCommand); - state->AddBuiltinCommand("build_command", cm::make_unique<cmBuildCommand>()); - state->AddBuiltinCommand("create_test_sourcelist", - cm::make_unique<cmCreateTestSourceList>()); - state->AddBuiltinCommand("define_property", - cm::make_unique<cmDefinePropertyCommand>()); - state->AddBuiltinCommand("enable_language", - cm::make_unique<cmEnableLanguageCommand>()); + state->AddBuiltinCommand("build_command", cmBuildCommand); + state->AddBuiltinCommand("create_test_sourcelist", cmCreateTestSourceList); + state->AddBuiltinCommand("define_property", cmDefinePropertyCommand); + state->AddBuiltinCommand("enable_language", cmEnableLanguageCommand); state->AddBuiltinCommand("enable_testing", cmEnableTestingCommand); state->AddBuiltinCommand("get_source_file_property", - cm::make_unique<cmGetSourceFilePropertyCommand>()); - state->AddBuiltinCommand("get_target_property", - cm::make_unique<cmGetTargetPropertyCommand>()); - state->AddBuiltinCommand("get_test_property", - cm::make_unique<cmGetTestPropertyCommand>()); - state->AddBuiltinCommand("include_directories", - cm::make_unique<cmIncludeDirectoryCommand>()); - state->AddBuiltinCommand( - "include_regular_expression", - cm::make_unique<cmIncludeRegularExpressionCommand>()); - state->AddBuiltinCommand("install", cm::make_unique<cmInstallCommand>()); - state->AddBuiltinCommand("install_files", - cm::make_unique<cmInstallFilesCommand>()); - state->AddBuiltinCommand("install_targets", - cm::make_unique<cmInstallTargetsCommand>()); - state->AddBuiltinCommand("link_directories", - cm::make_unique<cmLinkDirectoriesCommand>()); - state->AddBuiltinCommand("project", cm::make_unique<cmProjectCommand>()); - state->AddBuiltinCommand( - "set_source_files_properties", - cm::make_unique<cmSetSourceFilesPropertiesCommand>()); + cmGetSourceFilePropertyCommand); + state->AddBuiltinCommand("get_target_property", cmGetTargetPropertyCommand); + state->AddBuiltinCommand("get_test_property", cmGetTestPropertyCommand); + state->AddBuiltinCommand("include_directories", cmIncludeDirectoryCommand); + state->AddBuiltinCommand("include_regular_expression", + cmIncludeRegularExpressionCommand); + state->AddBuiltinCommand("install", cmInstallCommand); + state->AddBuiltinCommand("install_files", cmInstallFilesCommand); + state->AddBuiltinCommand("install_targets", cmInstallTargetsCommand); + state->AddBuiltinCommand("link_directories", cmLinkDirectoriesCommand); + state->AddBuiltinCommand("project", cmProjectCommand); + state->AddBuiltinCommand("set_source_files_properties", + cmSetSourceFilesPropertiesCommand); state->AddBuiltinCommand("set_target_properties", - cm::make_unique<cmSetTargetPropertiesCommand>()); + cmSetTargetPropertiesCommand); state->AddBuiltinCommand("set_tests_properties", - cm::make_unique<cmSetTestsPropertiesCommand>()); - state->AddBuiltinCommand("subdirs", cm::make_unique<cmSubdirCommand>()); + cmSetTestsPropertiesCommand); + state->AddBuiltinCommand("subdirs", cmSubdirCommand); state->AddBuiltinCommand( "target_compile_definitions", cm::make_unique<cmTargetCompileDefinitionsCommand>()); @@ -271,7 +257,7 @@ void GetProjectCommands(cmState* state) "target_include_directories", cm::make_unique<cmTargetIncludeDirectoriesCommand>()); state->AddBuiltinCommand("target_link_libraries", - cm::make_unique<cmTargetLinkLibrariesCommand>()); + cmTargetLinkLibrariesCommand); state->AddBuiltinCommand("target_sources", cm::make_unique<cmTargetSourcesCommand>()); state->AddBuiltinCommand("try_compile", @@ -287,30 +273,22 @@ void GetProjectCommands(cmState* state) state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand); state->AddBuiltinCommand("aux_source_directory", cmAuxSourceDirectoryCommand); - state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>()); - state->AddBuiltinCommand("fltk_wrap_ui", - cm::make_unique<cmFLTKWrapUICommand>()); - state->AddBuiltinCommand( - "include_external_msproject", - cm::make_unique<cmIncludeExternalMSProjectCommand>()); - state->AddBuiltinCommand("install_programs", - cm::make_unique<cmInstallProgramsCommand>()); + state->AddBuiltinCommand("export", cmExportCommand); + state->AddBuiltinCommand("fltk_wrap_ui", cmFLTKWrapUICommand); + state->AddBuiltinCommand("include_external_msproject", + cmIncludeExternalMSProjectCommand); + state->AddBuiltinCommand("install_programs", cmInstallProgramsCommand); state->AddBuiltinCommand("add_link_options", cmAddLinkOptionsCommand); - state->AddBuiltinCommand("link_libraries", - cm::make_unique<cmLinkLibrariesCommand>()); + state->AddBuiltinCommand("link_libraries", cmLinkLibrariesCommand); state->AddBuiltinCommand("target_link_options", cm::make_unique<cmTargetLinkOptionsCommand>()); state->AddBuiltinCommand("target_link_directories", cm::make_unique<cmTargetLinkDirectoriesCommand>()); - state->AddBuiltinCommand("load_cache", - cm::make_unique<cmLoadCacheCommand>()); - state->AddBuiltinCommand("qt_wrap_cpp", - cm::make_unique<cmQTWrapCPPCommand>()); - state->AddBuiltinCommand("qt_wrap_ui", cm::make_unique<cmQTWrapUICommand>()); - state->AddBuiltinCommand("remove_definitions", - cm::make_unique<cmRemoveDefinitionsCommand>()); - state->AddBuiltinCommand("source_group", - cm::make_unique<cmSourceGroupCommand>()); + state->AddBuiltinCommand("load_cache", cmLoadCacheCommand); + state->AddBuiltinCommand("qt_wrap_cpp", cmQTWrapCPPCommand); + state->AddBuiltinCommand("qt_wrap_ui", cmQTWrapUICommand); + state->AddBuiltinCommand("remove_definitions", cmRemoveDefinitionsCommand); + state->AddBuiltinCommand("source_group", cmSourceGroupCommand); state->AddDisallowedCommand( "export_library_dependencies", cmExportLibraryDependenciesCommand, diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 54443f2..19a096b 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -96,7 +96,7 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags( std::string cmCommonTargetGenerator::GetFlags(const std::string& l) { - ByLanguageMap::iterator i = this->FlagsByLanguage.find(l); + auto i = this->FlagsByLanguage.find(l); if (i == this->FlagsByLanguage.end()) { std::string flags; @@ -111,7 +111,7 @@ std::string cmCommonTargetGenerator::GetFlags(const std::string& l) std::string cmCommonTargetGenerator::GetDefines(const std::string& l) { - ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); + auto i = this->DefinesByLanguage.find(l); if (i == this->DefinesByLanguage.end()) { std::set<std::string> defines; this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, @@ -128,7 +128,7 @@ std::string cmCommonTargetGenerator::GetDefines(const std::string& l) std::string cmCommonTargetGenerator::GetIncludes(std::string const& l) { - ByLanguageMap::iterator i = this->IncludesByLanguage.find(l); + auto i = this->IncludesByLanguage.find(l); if (i == this->IncludesByLanguage.end()) { std::string includes; this->AddIncludeFlags(includes, l); @@ -171,6 +171,7 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) { return compilePdbPath; } + compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName()); if (compilePdbPath.empty()) { diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx index 113463f..655e4ac 100644 --- a/Source/cmComputeComponentGraph.cxx +++ b/Source/cmComputeComponentGraph.cxx @@ -4,7 +4,7 @@ #include <algorithm> -#include <assert.h> +#include <cassert> cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input) : InputGraph(input) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index a39425c..ab4371a 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmComputeLinkDepends.h" -#include "cmAlgorithms.h" #include "cmComputeComponentGraph.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -16,14 +15,14 @@ #include "cmake.h" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstdio> +#include <cstring> #include <iterator> #include <sstream> -#include <stdio.h> -#include <string.h> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> /* @@ -201,10 +200,7 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target, this->CCG = nullptr; } -cmComputeLinkDepends::~cmComputeLinkDepends() -{ - cmDeleteAll(this->InferredDependSets); -} +cmComputeLinkDepends::~cmComputeLinkDepends() = default; void cmComputeLinkDepends::SetOldLinkDirMode(bool b) { @@ -283,10 +279,9 @@ std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry( { std::map<cmLinkItem, int>::value_type index_entry( item, static_cast<int>(this->EntryList.size())); - std::map<cmLinkItem, int>::iterator lei = - this->LinkEntryIndex.insert(index_entry).first; + auto lei = this->LinkEntryIndex.insert(index_entry).first; this->EntryList.emplace_back(); - this->InferredDependSets.push_back(nullptr); + this->InferredDependSets.emplace_back(); this->EntryConstraintGraph.emplace_back(); return lei; } @@ -294,7 +289,7 @@ std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry( int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) { // Check if the item entry has already been added. - std::map<cmLinkItem, int>::iterator lei = this->LinkEntryIndex.find(item); + auto lei = this->LinkEntryIndex.find(item); if (lei != this->LinkEntryIndex.end()) { // Yes. We do not need to follow the item's dependencies again. return lei->second; @@ -326,7 +321,7 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) this->BFSQueue.push(qe); } else if (!entry.IsFlag) { // The item dependencies are not known. We need to infer them. - this->InferredDependSets[index] = new DependSetList; + this->InferredDependSets[index].Initialized = true; } } @@ -394,8 +389,7 @@ void cmComputeLinkDepends::QueueSharedDependencies( void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) { // Check if the target already has an entry. - std::map<cmLinkItem, int>::iterator lei = - this->LinkEntryIndex.find(dep.Item); + auto lei = this->LinkEntryIndex.find(dep.Item); if (lei == this->LinkEntryIndex.end()) { // Allocate a spot for the item entry. lei = this->AllocateLinkEntry(dep.Item); @@ -540,7 +534,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, } // If this item needs to have dependencies inferred, do so. - if (this->InferredDependSets[dependee_index]) { + if (this->InferredDependSets[dependee_index].Initialized) { // Make sure an entry exists to hold the set for the item. dependSets[dependee_index]; } @@ -548,7 +542,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, // Store the inferred dependency sets discovered for this list. for (auto const& dependSet : dependSets) { - this->InferredDependSets[dependSet.first]->push_back(dependSet.second); + this->InferredDependSets[dependSet.first].push_back(dependSet.second); } } @@ -575,14 +569,14 @@ void cmComputeLinkDepends::InferDependencies() depender_index < this->InferredDependSets.size(); ++depender_index) { // Skip items for which dependencies do not need to be inferred or // for which the inferred dependency sets are empty. - DependSetList* sets = this->InferredDependSets[depender_index]; - if (!sets || sets->empty()) { + DependSetList& sets = this->InferredDependSets[depender_index]; + if (!sets.Initialized || sets.empty()) { continue; } // Intersect the sets for this item. - DependSet common = sets->front(); - for (DependSet const& i : cmMakeRange(*sets).advance(1)) { + DependSet common = sets.front(); + for (DependSet const& i : cmMakeRange(sets).advance(1)) { DependSet intersection; std::set_intersection(common.begin(), common.end(), i.begin(), i.end(), std::inserter(intersection, intersection.begin())); @@ -719,8 +713,7 @@ void cmComputeLinkDepends::VisitEntry(int index) // This entry has now been seen. Update its component. bool completed = false; int component = this->CCG->GetComponentMap()[index]; - std::map<int, PendingComponent>::iterator mi = - this->PendingComponents.find(this->ComponentOrder[component]); + auto mi = this->PendingComponents.find(this->ComponentOrder[component]); if (mi != this->PendingComponents.end()) { // The entry is in an already pending component. PendingComponent& pc = mi->second; diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index f0ac771..203cc68 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -106,8 +106,9 @@ private: }; struct DependSetList : public std::vector<DependSet> { + bool Initialized = false; }; - std::vector<DependSetList*> InferredDependSets; + std::vector<DependSetList> InferredDependSets; void InferDependencies(); // Ordering constraint graph adjacency list. diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index dd8d246..832f38e 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -6,6 +6,7 @@ #include "cmComputeLinkDepends.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -20,9 +21,9 @@ #include "cmake.h" #include <algorithm> -#include <ctype.h> +#include <cctype> +#include <cstring> #include <sstream> -#include <string.h> #include <utility> //#define CM_COMPUTE_LINK_INFO_DEBUG @@ -406,6 +407,18 @@ cmComputeLinkInformation::~cmComputeLinkInformation() delete this->OrderDependentRPath; } +void cmComputeLinkInformation::AppendValues( + std::string& result, std::vector<BT<std::string>>& values) +{ + for (BT<std::string>& p : values) { + if (result.empty()) { + result.append(" "); + } + + result.append(p.Value); + } +} + cmComputeLinkInformation::ItemVector const& cmComputeLinkInformation::GetItems() const { @@ -418,6 +431,28 @@ std::vector<std::string> const& cmComputeLinkInformation::GetDirectories() return this->OrderLinkerSearchPath->GetOrderedDirectories(); } +std::vector<BT<std::string>> +cmComputeLinkInformation::GetDirectoriesWithBacktraces() +{ + std::vector<BT<std::string>> directoriesWithBacktraces; + + std::vector<BT<std::string>> targetLinkDirectores = + this->Target->GetLinkDirectories(this->Config, this->LinkLanguage); + + const std::vector<std::string>& orderedDirectories = this->GetDirectories(); + for (const std::string& dir : orderedDirectories) { + auto result = + std::find(targetLinkDirectores.begin(), targetLinkDirectores.end(), dir); + if (result != targetLinkDirectores.end()) { + directoriesWithBacktraces.emplace_back(std::move(*result)); + } else { + directoriesWithBacktraces.emplace_back(dir); + } + } + + return directoriesWithBacktraces; +} + std::string cmComputeLinkInformation::GetRPathLinkString() const { // If there is no separate linker runtime search flag (-rpath-link) @@ -1332,8 +1367,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item, std::string const& file) { // Do not depend on things that do not exist. - std::vector<std::string>::iterator i = - std::find(this->Depends.begin(), this->Depends.end(), item); + auto i = std::find(this->Depends.begin(), this->Depends.end(), item); if (i != this->Depends.end()) { this->Depends.erase(i); } diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 0f71381..d3345d9 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -17,6 +17,8 @@ class cmGlobalGenerator; class cmMakefile; class cmOrderDirectories; class cmake; +template <typename T> +class BT; /** \class cmComputeLinkInformation * \brief Compute link information for a target in one configuration. @@ -43,8 +45,10 @@ public: cmGeneratorTarget const* Target = nullptr; }; using ItemVector = std::vector<Item>; + void AppendValues(std::string& result, std::vector<BT<std::string>>& values); ItemVector const& GetItems() const; std::vector<std::string> const& GetDirectories() const; + std::vector<BT<std::string>> GetDirectoriesWithBacktraces(); std::vector<std::string> const& GetDepends() const; std::vector<std::string> const& GetFrameworkPaths() const; std::string GetLinkLanguage() const { return this->LinkLanguage; } @@ -66,6 +70,8 @@ public: std::string GetConfig() const { return this->Config; } + const cmGeneratorTarget* GetTarget() { return this->Target; } + private: void AddItem(std::string const& item, const cmGeneratorTarget* tgt); void AddSharedDepItem(std::string const& item, cmGeneratorTarget const* tgt); diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 6bf2f2d..239fcdf 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -20,9 +20,9 @@ #include "cmTargetDepend.h" #include "cmake.h" -#include <assert.h> +#include <cassert> +#include <cstdio> #include <sstream> -#include <stdio.h> #include <utility> /* @@ -140,8 +140,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t, { // Lookup the index for this target. All targets should be known by // this point. - std::map<cmGeneratorTarget const*, int>::const_iterator tii = - this->TargetIndex.find(t); + auto tii = this->TargetIndex.find(t); assert(tii != this->TargetIndex.end()); int i = tii->second; @@ -149,7 +148,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t, EdgeList const& nl = this->FinalGraph[i]; for (cmGraphEdge const& ni : nl) { cmGeneratorTarget const* dep = this->Targets[ni]; - cmTargetDependSet::iterator di = deps.insert(dep).first; + auto di = deps.insert(dep).first; di->SetType(ni.IsStrong()); di->SetBacktrace(ni.GetBacktrace()); } @@ -368,8 +367,7 @@ void cmComputeTargetDepends::AddTargetDepend( } else { // Lookup the index for this target. All targets should be known by // this point. - std::map<cmGeneratorTarget const*, int>::const_iterator tii = - this->TargetIndex.find(dependee); + auto tii = this->TargetIndex.find(dependee); assert(tii != this->TargetIndex.end()); int dependee_index = tii->second; diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 21df278..3ddd8ca 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -3,11 +3,11 @@ #include "cmConditionEvaluator.h" #include "cmsys/RegularExpression.hxx" +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <functional> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <utility> #include "cmAlgorithms.h" @@ -367,7 +367,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs, int reducible; do { reducible = 0; - cmArgumentList::iterator arg = newArgs.begin(); + auto arg = newArgs.begin(); while (arg != newArgs.end()) { if (IsKeyword(keyParenL, *arg)) { // search for the closing paren for this opening one @@ -393,7 +393,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs, std::vector<cmExpandedCommandArgument> newArgs2; // copy to the list structure - cmArgumentList::iterator argP1 = arg; + auto argP1 = arg; argP1++; cmAppend(newArgs2, argP1, argClose); newArgs2.pop_back(); @@ -424,7 +424,7 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&, int reducible; do { reducible = 0; - cmArgumentList::iterator arg = newArgs.begin(); + auto arg = newArgs.begin(); cmArgumentList::iterator argP1; cmArgumentList::iterator argP2; while (arg != newArgs.end()) { @@ -524,7 +524,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs, const char* def2; do { reducible = 0; - cmArgumentList::iterator arg = newArgs.begin(); + auto arg = newArgs.begin(); cmArgumentList::iterator argP1; cmArgumentList::iterator argP2; while (arg != newArgs.end()) { @@ -700,7 +700,7 @@ bool cmConditionEvaluator::HandleLevel3(cmArgumentList& newArgs, int reducible; do { reducible = 0; - cmArgumentList::iterator arg = newArgs.begin(); + auto arg = newArgs.begin(); cmArgumentList::iterator argP1; cmArgumentList::iterator argP2; while (arg != newArgs.end()) { @@ -728,7 +728,7 @@ bool cmConditionEvaluator::HandleLevel4(cmArgumentList& newArgs, bool rhs; do { reducible = 0; - cmArgumentList::iterator arg = newArgs.begin(); + auto arg = newArgs.begin(); cmArgumentList::iterator argP1; cmArgumentList::iterator argP2; while (arg != newArgs.end()) { diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index 7e37f32..8767386 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmConfigureFileCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -26,13 +24,9 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args, // If the input location is a directory, error out. if (cmSystemTools::FileIsDirectory(inputFile)) { - std::ostringstream e; - /* clang-format off */ - e << "input location\n" - << " " << inputFile << "\n" - << "is a directory but a file was expected."; - /* clang-format on */ - status.SetError(e.str()); + status.SetError(cmStrCat("input location\n ", inputFile, + "\n" + "is a directory but a file was expected.")); return false; } diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 3687056..12050b3 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -3,10 +3,10 @@ #include "cmCoreTryCompile.h" #include "cmsys/Directory.hxx" +#include <cstdio> +#include <cstring> #include <set> #include <sstream> -#include <stdio.h> -#include <string.h> #include <utility> #include "cmExportTryCompileFileGenerator.h" diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx index 4a1825f..9d492ba 100644 --- a/Source/cmCreateTestSourceList.cxx +++ b/Source/cmCreateTestSourceList.cxx @@ -4,23 +4,21 @@ #include <algorithm> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -// cmCreateTestSourceList -bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmCreateTestSourceList(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("called with wrong number of arguments."); + status.SetError("called with wrong number of arguments."); return false; } - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); std::string extraInclude; std::string function; std::vector<std::string> tests; @@ -29,14 +27,14 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, if (*i == "EXTRA_INCLUDE") { ++i; if (i == args.end()) { - this->SetError("incorrect arguments to EXTRA_INCLUDE"); + status.SetError("incorrect arguments to EXTRA_INCLUDE"); return false; } extraInclude = cmStrCat("#include \"", *i, "\"\n"); } else if (*i == "FUNCTION") { ++i; if (i == args.end()) { - this->SetError("incorrect arguments to FUNCTION"); + status.SetError("incorrect arguments to FUNCTION"); return false; } function = cmStrCat(*i, "(&ac, &av);\n"); @@ -54,12 +52,12 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, // Name of the test driver // make sure they specified an extension if (cmSystemTools::GetFilenameExtension(*i).size() < 2) { - this->SetError( + status.SetError( "You must specify a file extension for the test driver file."); return false; } - std::string driver = - cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', *i); + cmMakefile& mf = status.GetMakefile(); + std::string driver = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', *i); ++i; std::string configFile = cmSystemTools::GetCMakeRoot(); @@ -67,7 +65,7 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, configFile += "/Templates/TestDriver.cxx.in"; // Create the test driver file - std::vector<std::string>::const_iterator testsBegin = i; + auto testsBegin = i; std::vector<std::string> tests_func_name; // The rest of the arguments consist of a list of test source files. @@ -121,35 +119,32 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, numTests++; } if (!extraInclude.empty()) { - this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES", - extraInclude); + mf.AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES", extraInclude); } if (!function.empty()) { - this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function); + mf.AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function); } - this->Makefile->AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", - forwardDeclareCode); - this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", - functionMapCode); + mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode); + mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode); bool res = true; - if (!this->Makefile->ConfigureFile(configFile, driver, false, true, false)) { + if (!mf.ConfigureFile(configFile, driver, false, true, false)) { res = false; } // Construct the source list. std::string sourceListValue; { - cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver); + cmSourceFile* sf = mf.GetOrCreateSource(driver); sf->SetProperty("ABSTRACT", "0"); sourceListValue = args[1]; } for (i = testsBegin; i != tests.end(); ++i) { - cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i); + cmSourceFile* sf = mf.GetOrCreateSource(*i); sf->SetProperty("ABSTRACT", "0"); sourceListValue += ";"; sourceListValue += *i; } - this->Makefile->AddDefinition(sourceList, sourceListValue); + mf.AddDefinition(sourceList, sourceListValue); return res; } diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h index 5aa6af4..19503f4 100644 --- a/Source/cmCreateTestSourceList.h +++ b/Source/cmCreateTestSourceList.h @@ -8,34 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmCreateTestSourceList - * \brief Test driver generation command - * - */ - -class cmCreateTestSourceList : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmCreateTestSourceList>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmCreateTestSourceList(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index f9f9581..ff683ad 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -6,7 +6,7 @@ #include "cm_rhash.h" #include "cmsys/FStream.hxx" -#include "cm_memory.hxx" +#include <cm/memory> static unsigned int const cmCryptoHashAlgoToId[] = { /* clang-format needs this comment to break after the opening brace */ diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h index 681f5cc..05552bd 100644 --- a/Source/cmCryptoHash.h +++ b/Source/cmCryptoHash.h @@ -5,10 +5,10 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cm_string_view.hxx" +#include <cm/string_view> +#include <cstddef> #include <memory> -#include <stddef.h> #include <string> #include <vector> diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 7402eeb..fc6718d 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -88,18 +88,17 @@ cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const return this->Backtrace; } -cmCustomCommand::ImplicitDependsList const& -cmCustomCommand::GetImplicitDepends() const +cmImplicitDependsList const& cmCustomCommand::GetImplicitDepends() const { return this->ImplicitDepends; } -void cmCustomCommand::SetImplicitDepends(ImplicitDependsList const& l) +void cmCustomCommand::SetImplicitDepends(cmImplicitDependsList const& l) { this->ImplicitDepends = l; } -void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l) +void cmCustomCommand::AppendImplicitDepends(cmImplicitDependsList const& l) { cmAppend(this->ImplicitDepends, l); } diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index 102b178..bb5a0ed 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -14,6 +14,11 @@ class cmMakefile; +class cmImplicitDependsList + : public std::vector<std::pair<std::string, std::string>> +{ +}; + /** \class cmCustomCommand * \brief A class to encapsulate a custom command * @@ -68,13 +73,9 @@ public: /** Backtrace of the command that created this custom command. */ cmListFileBacktrace const& GetBacktrace() const; - using ImplicitDependsPair = std::pair<std::string, std::string>; - class ImplicitDependsList : public std::vector<ImplicitDependsPair> - { - }; - void SetImplicitDepends(ImplicitDependsList const&); - void AppendImplicitDepends(ImplicitDependsList const&); - ImplicitDependsList const& GetImplicitDepends() const; + void SetImplicitDepends(cmImplicitDependsList const&); + void AppendImplicitDepends(cmImplicitDependsList const&); + cmImplicitDependsList const& GetImplicitDepends() const; /** Set/Get whether this custom command should be given access to the real console (if possible). */ @@ -99,7 +100,7 @@ private: std::vector<std::string> Depends; cmCustomCommandLines CommandLines; cmListFileBacktrace Backtrace; - ImplicitDependsList ImplicitDepends; + cmImplicitDependsList ImplicitDepends; std::string Comment; std::string WorkingDirectory; std::string Depfile; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 82cc037..7f3e052 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -13,10 +13,30 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include <cstddef> #include <memory> -#include <stddef.h> #include <utility> +namespace { +void AppendPaths(const std::vector<std::string>& inputs, + cmGeneratorExpression const& ge, cmLocalGenerator* lg, + std::string const& config, std::vector<std::string>& output) +{ + for (std::string const& in : inputs) { + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(in); + std::vector<std::string> result = + cmExpandedList(cge->Evaluate(lg, config)); + for (std::string& it : result) { + cmSystemTools::ConvertToUnixSlashes(it); + if (cmSystemTools::FileIsFullPath(it)) { + it = cmSystemTools::CollapseFullPath(it); + } + } + cmAppend(output, result); + } +} +} + cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg) @@ -25,15 +45,15 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, , LG(lg) , OldStyle(cc.GetEscapeOldStyle()) , MakeVars(cc.GetEscapeAllowMakeVars()) - , GE(new cmGeneratorExpression(cc.GetBacktrace())) , EmulatorsWithArguments(cc.GetCommandLines().size()) { + cmGeneratorExpression ge(cc.GetBacktrace()); + const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines(); for (cmCustomCommandLine const& cmdline : cmdlines) { cmCustomCommandLine argv; for (std::string const& clarg : cmdline) { - std::unique_ptr<cmCompiledGeneratorExpression> cge = - this->GE->Parse(clarg); + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg); std::string parsed_arg = cge->Evaluate(this->LG, this->Config); if (this->CC.GetCommandExpandLists()) { cmAppend(argv, cmExpandedList(parsed_arg)); @@ -46,29 +66,20 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, // lists on an empty command may have left this empty. // FIXME: Should we define behavior for removing empty commands? if (argv.empty()) { - argv.push_back(std::string()); + argv.emplace_back(); } this->CommandLines.push_back(std::move(argv)); } - std::vector<std::string> depends = this->CC.GetDepends(); - for (std::string const& d : depends) { - std::unique_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(d); - std::vector<std::string> result = - cmExpandedList(cge->Evaluate(this->LG, this->Config)); - for (std::string& it : result) { - if (cmSystemTools::FileIsFullPath(it)) { - it = cmSystemTools::CollapseFullPath(it); - } - } - cmAppend(this->Depends, result); - } + AppendPaths(cc.GetByproducts(), ge, this->LG, this->Config, + this->Byproducts); + AppendPaths(cc.GetDepends(), ge, this->LG, this->Config, this->Depends); const std::string& workingdirectory = this->CC.GetWorkingDirectory(); if (!workingdirectory.empty()) { std::unique_ptr<cmCompiledGeneratorExpression> cge = - this->GE->Parse(workingdirectory); + ge.Parse(workingdirectory); this->WorkingDirectory = cge->Evaluate(this->LG, this->Config); // Convert working directory to a full path. if (!this->WorkingDirectory.empty()) { @@ -81,11 +92,6 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, this->FillEmulatorsWithArguments(); } -cmCustomCommandGenerator::~cmCustomCommandGenerator() -{ - delete this->GE; -} - unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const { return static_cast<unsigned int>(this->CC.GetCommandLines().size()); @@ -238,7 +244,7 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const { - return this->CC.GetByproducts(); + return this->Byproducts; } std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index 766f4b8..50f292e 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -10,7 +10,6 @@ #include <vector> class cmCustomCommand; -class cmGeneratorExpression; class cmLocalGenerator; class cmCustomCommandGenerator @@ -20,9 +19,9 @@ class cmCustomCommandGenerator cmLocalGenerator* LG; bool OldStyle; bool MakeVars; - cmGeneratorExpression* GE; cmCustomCommandLines CommandLines; std::vector<std::vector<std::string>> EmulatorsWithArguments; + std::vector<std::string> Byproducts; std::vector<std::string> Depends; std::string WorkingDirectory; @@ -33,7 +32,6 @@ class cmCustomCommandGenerator public: cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg); - ~cmCustomCommandGenerator(); cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete; cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) = delete; diff --git a/Source/cmCustomCommandLines.cxx b/Source/cmCustomCommandLines.cxx new file mode 100644 index 0000000..37ad75b --- /dev/null +++ b/Source/cmCustomCommandLines.cxx @@ -0,0 +1,22 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCustomCommandLines.h" + +cmCustomCommandLine cmMakeCommandLine( + std::initializer_list<cm::string_view> ilist) +{ + cmCustomCommandLine commandLine; + commandLine.reserve(ilist.size()); + for (cm::string_view cmd : ilist) { + commandLine.emplace_back(cmd); + } + return commandLine; +} + +cmCustomCommandLines cmMakeSingleCommandLine( + std::initializer_list<cm::string_view> ilist) +{ + cmCustomCommandLines commandLines; + commandLines.push_back(cmMakeCommandLine(ilist)); + return commandLines; +} diff --git a/Source/cmCustomCommandLines.h b/Source/cmCustomCommandLines.h index 35a15ba..ead5792 100644 --- a/Source/cmCustomCommandLines.h +++ b/Source/cmCustomCommandLines.h @@ -5,25 +5,28 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <initializer_list> #include <string> #include <vector> +#include <cm/string_view> // IWYU pragma: keep + /** Data structure to represent a single command line. */ class cmCustomCommandLine : public std::vector<std::string> { -public: - using Superclass = std::vector<std::string>; - using iterator = Superclass::iterator; - using const_iterator = Superclass::const_iterator; }; /** Data structure to represent a list of command lines. */ class cmCustomCommandLines : public std::vector<cmCustomCommandLine> { -public: - using Superclass = std::vector<cmCustomCommandLine>; - using iterator = Superclass::iterator; - using const_iterator = Superclass::const_iterator; }; +/** Return a command line from a list of command line parts. */ +cmCustomCommandLine cmMakeCommandLine( + std::initializer_list<cm::string_view> ilist); + +/** Return a command line vector with a single command line. */ +cmCustomCommandLines cmMakeSingleCommandLine( + std::initializer_list<cm::string_view> ilist); + #endif diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx index 86a83da..f4e4fda 100644 --- a/Source/cmDefinePropertyCommand.cxx +++ b/Source/cmDefinePropertyCommand.cxx @@ -2,19 +2,17 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmDefinePropertyCommand.h" -#include <sstream> - +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmProperty.h" #include "cmState.h" +#include "cmStringAlgorithms.h" -class cmExecutionStatus; - -bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmDefinePropertyCommand(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; } @@ -37,17 +35,17 @@ bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args, } else if (scope_arg == "CACHED_VARIABLE") { scope = cmProperty::CACHED_VARIABLE; } else { - std::ostringstream e; - e << "given invalid scope " << scope_arg << ". " - << "Valid scopes are " - << "GLOBAL, DIRECTORY, TARGET, SOURCE, " - << "TEST, VARIABLE, CACHED_VARIABLE."; - this->SetError(e.str()); + status.SetError(cmStrCat("given invalid scope ", scope_arg, + ". Valid scopes are GLOBAL, DIRECTORY, TARGET, " + "SOURCE, TEST, VARIABLE, CACHED_VARIABLE.")); return false; } // Parse remaining arguments. bool inherited = false; + std::string PropertyName; + std::string BriefDocs; + std::string FullDocs; enum Doing { DoingNone, @@ -68,39 +66,36 @@ bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args, inherited = true; } else if (doing == DoingProperty) { doing = DoingNone; - this->PropertyName = args[i]; + PropertyName = args[i]; } else if (doing == DoingBrief) { - this->BriefDocs += args[i]; + BriefDocs += args[i]; } else if (doing == DoingFull) { - this->FullDocs += args[i]; + FullDocs += args[i]; } else { - std::ostringstream e; - e << "given invalid argument \"" << args[i] << "\"."; - this->SetError(e.str()); + status.SetError(cmStrCat("given invalid argument \"", args[i], "\".")); return false; } } // Make sure a property name was found. - if (this->PropertyName.empty()) { - this->SetError("not given a PROPERTY <name> argument."); + if (PropertyName.empty()) { + status.SetError("not given a PROPERTY <name> argument."); return false; } // Make sure documentation was given. - if (this->BriefDocs.empty()) { - this->SetError("not given a BRIEF_DOCS <brief-doc> argument."); + if (BriefDocs.empty()) { + status.SetError("not given a BRIEF_DOCS <brief-doc> argument."); return false; } - if (this->FullDocs.empty()) { - this->SetError("not given a FULL_DOCS <full-doc> argument."); + if (FullDocs.empty()) { + status.SetError("not given a FULL_DOCS <full-doc> argument."); return false; } // Actually define the property. - this->Makefile->GetState()->DefineProperty( - this->PropertyName, scope, this->BriefDocs.c_str(), this->FullDocs.c_str(), - inherited); + status.GetMakefile().GetState()->DefineProperty( + PropertyName, scope, BriefDocs.c_str(), FullDocs.c_str(), inherited); return true; } diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h index 36f97df..60dd76a 100644 --- a/Source/cmDefinePropertyCommand.h +++ b/Source/cmDefinePropertyCommand.h @@ -8,31 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmDefinePropertyCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmDefinePropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - std::string PropertyName; - std::string BriefDocs; - std::string FullDocs; -}; +bool cmDefinePropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index e688890..32f47b0 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -2,9 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmDefinitions.h" -#include "cm_string_view.hxx" +#include <cm/string_view> -#include <assert.h> +#include <cassert> #include <functional> #include <unordered_set> #include <utility> diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index 008821d..72e88b5 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -5,11 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cm_string_view.hxx" - #include "cmLinkedTree.h" + #include "cmString.hxx" +#include <cm/string_view> + #include <functional> #include <string> #include <unordered_map> diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 06a442b..e8f6faf 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -33,8 +33,7 @@ bool cmDepends::Write(std::ostream& makeDepends, std::ostream& internalDepends) cmMakefile* mf = this->LocalGenerator->GetMakefile(); cmExpandList(mf->GetSafeDefinition(srcLang), pairs); } - for (std::vector<std::string>::iterator si = pairs.begin(); - si != pairs.end();) { + for (auto si = pairs.begin(); si != pairs.end();) { // Get the source and object file. std::string const& src = *si++; if (si == pairs.end()) { diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index 0f9f166..012a0b1 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -5,7 +5,6 @@ #include "cmsys/FStream.hxx" #include <utility> -#include "cmAlgorithms.h" #include "cmFileTime.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" @@ -67,7 +66,6 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir, cmDependsC::~cmDependsC() { this->WriteCacheFile(); - cmDeleteAll(this->FileCache); } bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, @@ -172,9 +170,9 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, // Check whether this file is already in the cache auto fileIt = this->FileCache.find(fullName); if (fileIt != this->FileCache.end()) { - fileIt->second->Used = true; + fileIt->second.Used = true; dependencies.insert(fullName); - for (UnscannedEntry const& inc : fileIt->second->UnscannedEntries) { + for (UnscannedEntry const& inc : fileIt->second.UnscannedEntries) { if (this->Encountered.find(inc.FileName) == this->Encountered.end()) { this->Encountered.insert(inc.FileName); @@ -260,8 +258,7 @@ void cmDependsC::ReadCacheFile() if (res && newer) // cache is newer than the parsed file { - cacheEntry = new cmIncludeLines; - this->FileCache[line] = cacheEntry; + cacheEntry = &this->FileCache[line]; } // file doesn't exist, check that the regular expressions // haven't changed @@ -313,10 +310,10 @@ void cmDependsC::WriteCacheFile() const cacheOut << this->IncludeRegexTransformString << "\n\n"; for (auto const& fileIt : this->FileCache) { - if (fileIt.second->Used) { + if (fileIt.second.Used) { cacheOut << fileIt.first << std::endl; - for (UnscannedEntry const& inc : fileIt.second->UnscannedEntries) { + for (UnscannedEntry const& inc : fileIt.second.UnscannedEntries) { cacheOut << inc.FileName << std::endl; if (inc.QuotedLocation.empty()) { cacheOut << "-" << std::endl; @@ -332,9 +329,8 @@ void cmDependsC::WriteCacheFile() const void cmDependsC::Scan(std::istream& is, const std::string& directory, const std::string& fullName) { - cmIncludeLines* newCacheEntry = new cmIncludeLines; - newCacheEntry->Used = true; - this->FileCache[fullName] = newCacheEntry; + cmIncludeLines& newCacheEntry = this->FileCache[fullName]; + newCacheEntry.Used = true; // Read one line at a time. std::string line; @@ -370,7 +366,7 @@ void cmDependsC::Scan(std::istream& is, const std::string& directory, // This kind of problem will be fixed when a more // preprocessor-like implementation of this scanner is created. if (this->IncludeRegexScan.find(entry.FileName)) { - newCacheEntry->UnscannedEntries.push_back(entry); + newCacheEntry.UnscannedEntries.push_back(entry); if (this->Encountered.find(entry.FileName) == this->Encountered.end()) { this->Encountered.insert(entry.FileName); @@ -438,8 +434,7 @@ void cmDependsC::TransformLine(std::string& line) if (!this->IncludeRegexTransform.find(line)) { return; } - TransformRulesType::const_iterator tri = - this->TransformRules.find(this->IncludeRegexTransform.match(3)); + auto tri = this->TransformRules.find(this->IncludeRegexTransform.match(3)); if (tri == this->TransformRules.end()) { return; } diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h index cbdc276..7d732d9 100644 --- a/Source/cmDependsC.h +++ b/Source/cmDependsC.h @@ -84,7 +84,7 @@ protected: std::set<std::string> Encountered; std::queue<UnscannedEntry> Unscanned; - std::map<std::string, cmIncludeLines*> FileCache; + std::map<std::string, cmIncludeLines> FileCache; std::map<std::string, std::string> HeaderLocationCache; std::string CacheFileName; diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index c30e0bf..de919f1 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -3,10 +3,10 @@ #include "cmDependsFortran.h" #include "cmsys/FStream.hxx" -#include <assert.h> +#include <cassert> +#include <cstdlib> #include <iostream> #include <map> -#include <stdlib.h> #include <utility> #include "cmFortranParser.h" /* Interface to parser object. */ @@ -56,8 +56,7 @@ public: cmFortranSourceInfo& CreateObjectInfo(const std::string& obj, const std::string& src) { - std::map<std::string, cmFortranSourceInfo>::iterator i = - this->ObjectInfo.find(obj); + auto i = this->ObjectInfo.find(obj); if (i == this->ObjectInfo.end()) { std::map<std::string, cmFortranSourceInfo>::value_type entry( obj, cmFortranSourceInfo()); @@ -303,9 +302,7 @@ void cmDependsFortran::ConsiderModule(const std::string& name, const std::string& stampDir) { // Locate each required module. - using TargetRequiresMap = cmDependsFortranInternals::TargetRequiresMap; - TargetRequiresMap::iterator required = - this->Internal->TargetRequires.find(name); + auto required = this->Internal->TargetRequires.find(name); if (required != this->Internal->TargetRequires.end() && required->second.empty()) { // The module is provided by a CMake target. It will have a stamp file. @@ -321,8 +318,6 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::ostream& makeDepends, std::ostream& internalDepends) { - using TargetRequiresMap = cmDependsFortranInternals::TargetRequiresMap; - // Get the source file for this object. std::string const& src = info.Source; @@ -350,8 +345,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, // The object file should depend on timestamped files for the // modules it uses. - TargetRequiresMap::const_iterator required = - this->Internal->TargetRequires.find(i); + auto required = this->Internal->TargetRequires.find(i); if (required == this->Internal->TargetRequires.end()) { abort(); } diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx index 12d875d..18b49b8 100644 --- a/Source/cmDependsJavaParserHelper.cxx +++ b/Source/cmDependsJavaParserHelper.cxx @@ -5,12 +5,12 @@ #include "cmDependsJavaLexer.h" #include "cmSystemTools.h" -#include "cm_string_view.hxx" #include "cmsys/FStream.hxx" +#include <cm/string_view> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <iostream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <utility> int cmDependsJava_yyparse(yyscan_t yyscanner); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index d4628fa..d1f3a83 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -11,8 +11,8 @@ #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" #include <algorithm> -#include <ctype.h> -#include <string.h> +#include <cctype> +#include <cstring> #include <utility> static const char* cmDocumentationStandardOptions[][2] = { diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index 3e7f989..be6756a 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx @@ -5,9 +5,9 @@ #include "cmDocumentationEntry.h" #include "cmDocumentationSection.h" +#include <cstring> #include <iomanip> #include <ostream> -#include <string.h> #include <string> #include <vector> diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx index 0549cf9..0b72a94 100644 --- a/Source/cmDynamicLoader.cxx +++ b/Source/cmDynamicLoader.cxx @@ -39,8 +39,7 @@ void cmDynamicLoaderCache::CacheFile(const char* path, bool cmDynamicLoaderCache::GetCacheFile(const char* path, cmsys::DynamicLoader::LibraryHandle& p) { - std::map<std::string, cmsys::DynamicLoader::LibraryHandle>::iterator it = - this->CacheMap.find(path); + auto it = this->CacheMap.find(path); if (it != this->CacheMap.end()) { p = it->second; return true; @@ -50,8 +49,7 @@ bool cmDynamicLoaderCache::GetCacheFile(const char* path, bool cmDynamicLoaderCache::FlushCache(const char* path) { - std::map<std::string, cmsys::DynamicLoader::LibraryHandle>::iterator it = - this->CacheMap.find(path); + auto it = this->CacheMap.find(path); bool ret = false; if (it != this->CacheMap.end()) { cmsys::DynamicLoader::CloseLibrary(it->second); diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 648a900..06b5511 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -4,12 +4,12 @@ #include "cmAlgorithms.h" #include "cm_kwiml.h" -#include "cm_memory.hxx" #include "cmsys/FStream.hxx" +#include <cm/memory> +#include <cstddef> #include <map> #include <memory> #include <sstream> -#include <stddef.h> #include <utility> #include <vector> @@ -585,8 +585,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( unsigned int tag) { // Short-circuit if already checked. - std::map<unsigned int, StringEntry>::iterator dssi = - this->DynamicSectionStrings.find(tag); + auto dssi = this->DynamicSectionStrings.find(tag); if (dssi != this->DynamicSectionStrings.end()) { if (dssi->second.Position > 0) { return &dssi->second; @@ -614,8 +613,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link]; // Look for the requested entry. - for (typename std::vector<ELF_Dyn>::iterator di = - this->DynamicSectionEntries.begin(); + for (auto di = this->DynamicSectionEntries.begin(); di != this->DynamicSectionEntries.end(); ++di) { ELF_Dyn& dyn = *di; if (static_cast<tagtype>(dyn.d_tag) == static_cast<tagtype>(tag)) { diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx index ddd26de..59522c0 100644 --- a/Source/cmEnableLanguageCommand.cxx +++ b/Source/cmEnableLanguageCommand.cxx @@ -2,20 +2,19 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmEnableLanguageCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -// cmEnableLanguageCommand -bool cmEnableLanguageCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmEnableLanguageCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - bool optional = false; - std::vector<std::string> languages; if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } + + bool optional = false; + std::vector<std::string> languages; for (std::string const& it : args) { if (it == "OPTIONAL") { optional = true; @@ -24,6 +23,6 @@ bool cmEnableLanguageCommand::InitialPass(std::vector<std::string> const& args, } } - this->Makefile->EnableLanguage(languages, optional); + status.GetMakefile().EnableLanguage(languages, optional); return true; } diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h index dc43e34..1f8c4ce 100644 --- a/Source/cmEnableLanguageCommand.h +++ b/Source/cmEnableLanguageCommand.h @@ -8,37 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmEnableLanguageCommand - * \brief Specify the name for this build project. - * - * cmEnableLanguageCommand is used to specify a name for this build project. - * It is defined once per set of CMakeList.txt files (including - * all subdirectories). Currently it just sets the name of the workspace - * file for Microsoft Visual C++ - */ -class cmEnableLanguageCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmEnableLanguageCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmEnableLanguageCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 74e9c55..207b6fd 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -3,7 +3,7 @@ #include "cmExecProgramCommand.h" #include "cmsys/Process.h" -#include <stdio.h> +#include <cstdio> #include "cmExecutionStatus.h" #include "cmMakefile.h" diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index acf2a83..12364c8 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -6,10 +6,10 @@ #include "cmsys/Process.h" #include <algorithm> -#include <ctype.h> /* isspace */ +#include <cctype> /* isspace */ +#include <cstdio> #include <iostream> #include <memory> -#include <stdio.h> #include <vector> #include "cmAlgorithms.h" diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 9f0396b..c751966 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -17,6 +17,7 @@ #include "cmake.h" #include <map> +#include <memory> #include <set> #include <sstream> #include <utility> @@ -283,7 +284,8 @@ void cmExportBuildFileGenerator::GetTargets( std::vector<std::string>& targets) const { if (this->ExportSet) { - for (cmTargetExport* te : *this->ExportSet->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->ExportSet->GetTargetExports()) { targets.push_back(te->TargetName); } return; @@ -311,7 +313,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg, } } - return std::make_pair(exportFiles, ns); + return { exportFiles, ns }; } void cmExportBuildFileGenerator::ComplainAboutMissingTarget( diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 4046f91..79af6e9 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -11,9 +11,10 @@ #include "cmAlgorithms.h" #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmExportBuildAndroidMKGenerator.h" #include "cmExportBuildFileGenerator.h" -#include "cmExportSetMap.h" +#include "cmExportSet.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -23,24 +24,31 @@ #include "cmSystemTools.h" #include "cmTarget.h" -class cmExportSet; -class cmExecutionStatus; - #if defined(__HAIKU__) # include <FindDirectory.h> # include <StorageDefs.h> #endif -bool cmExportCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +#if defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> +#endif + +static bool HandlePackage(std::vector<std::string> const& args, + cmExecutionStatus& status); + +static void StorePackageRegistry(cmMakefile& mf, std::string const& package, + const char* content, const char* hash); + +bool cmExportCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with too few arguments"); + status.SetError("called with too few arguments"); return false; } if (args[0] == "PACKAGE") { - return this->HandlePackage(args); + return HandlePackage(args, status); } struct Arguments @@ -73,7 +81,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, parser.Parse(args, &unknownArgs, &keywordsMissingValue); if (!unknownArgs.empty()) { - this->SetError("Unknown argument: \"" + unknownArgs.front() + "\"."); + status.SetError("Unknown argument: \"" + unknownArgs.front() + "\"."); return false; } @@ -85,7 +93,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } if (arguments.Filename.empty() && fname.empty()) { if (args[0] != "EXPORT") { - this->SetError("FILE <filename> option missing."); + status.SetError("FILE <filename> option missing."); return false; } fname = arguments.ExportSetName + ".cmake"; @@ -96,64 +104,66 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "FILE option given filename \"" << arguments.Filename << "\" which does not have an extension of \".cmake\".\n"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } fname = arguments.Filename; } + cmMakefile& mf = status.GetMakefile(); + // Get the file to write. if (cmSystemTools::FileIsFullPath(fname)) { - if (!this->Makefile->CanIWriteThisFile(fname)) { + if (!mf.CanIWriteThisFile(fname)) { std::ostringstream e; e << "FILE option given filename \"" << fname << "\" which is in the source tree.\n"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } else { // Interpret relative paths with respect to the current build dir. - std::string dir = this->Makefile->GetCurrentBinaryDirectory(); + std::string const& dir = mf.GetCurrentBinaryDirectory(); fname = dir + "/" + fname; } std::vector<std::string> targets; - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = mf.GetGlobalGenerator(); - cmExportSet* ExportSet = nullptr; + cmExportSet* exportSet = nullptr; if (args[0] == "EXPORT") { cmExportSetMap& setMap = gg->GetExportSets(); auto const it = setMap.find(arguments.ExportSetName); if (it == setMap.end()) { std::ostringstream e; e << "Export set \"" << arguments.ExportSetName << "\" not found."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - ExportSet = it->second; + exportSet = &it->second; } else if (!arguments.Targets.empty() || cmContains(keywordsMissingValue, "TARGETS")) { for (std::string const& currentTarget : arguments.Targets) { - if (this->Makefile->IsAlias(currentTarget)) { + if (mf.IsAlias(currentTarget)) { std::ostringstream e; e << "given ALIAS target \"" << currentTarget << "\" which may not be exported."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } if (cmTarget* target = gg->FindTarget(currentTarget)) { if (target->GetType() == cmStateEnums::UTILITY) { - this->SetError("given custom target \"" + currentTarget + - "\" which may not be exported."); + status.SetError("given custom target \"" + currentTarget + + "\" which may not be exported."); return false; } } else { std::ostringstream e; e << "given target \"" << currentTarget << "\" which is not built by this project."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } targets.push_back(currentTarget); @@ -166,7 +176,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } } } else { - this->SetError("EXPORT or TARGETS specifier missing."); + status.SetError("EXPORT or TARGETS specifier missing."); return false; } @@ -180,24 +190,24 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, ebfg->SetExportFile(fname.c_str()); ebfg->SetNamespace(arguments.Namespace); ebfg->SetAppendMode(arguments.Append); - if (ExportSet != nullptr) { - ebfg->SetExportSet(ExportSet); + if (exportSet != nullptr) { + ebfg->SetExportSet(exportSet); } else { ebfg->SetTargets(targets); } - this->Makefile->AddExportBuildFileGenerator(ebfg); + mf.AddExportBuildFileGenerator(ebfg); ebfg->SetExportOld(arguments.ExportOld); // Compute the set of configurations exported. std::vector<std::string> configurationTypes; - this->Makefile->GetConfigurations(configurationTypes); + mf.GetConfigurations(configurationTypes); if (configurationTypes.empty()) { configurationTypes.emplace_back(); } for (std::string const& ct : configurationTypes) { ebfg->AddConfiguration(ct); } - if (ExportSet != nullptr) { + if (exportSet != nullptr) { gg->AddBuildExportExportSet(ebfg); } else { gg->AddBuildExportSet(ebfg); @@ -206,7 +216,8 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, return true; } -bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) +static bool HandlePackage(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Parse PACKAGE mode arguments. enum Doing @@ -223,14 +234,14 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) } else { std::ostringstream e; e << "PACKAGE given unknown argument: " << args[i]; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } // Verify the package name. if (package.empty()) { - this->SetError("PACKAGE must be given a package name."); + status.SetError("PACKAGE must be given a package name."); return false; } const char* packageExpr = "^[A-Za-z0-9_.-]+$"; @@ -239,16 +250,18 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) std::ostringstream e; e << "PACKAGE given invalid package name \"" << package << "\". " << "Package names must match \"" << packageExpr << "\"."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } + cmMakefile& mf = status.GetMakefile(); + // CMP0090 decides both the default and what variable changes it. - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0090)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0090)) { case cmPolicies::WARN: case cmPolicies::OLD: // Default is to export, but can be disabled. - if (this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) { + if (mf.IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) { return true; } break; @@ -256,7 +269,7 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: // Default is to not export, but can be enabled. - if (!this->Makefile->IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) { + if (!mf.IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) { return true; } break; @@ -265,22 +278,17 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) // We store the current build directory in the registry as a value // named by a hash of its own content. This is deterministic and is // unique with high probability. - const std::string& outDir = this->Makefile->GetCurrentBinaryDirectory(); + const std::string& outDir = mf.GetCurrentBinaryDirectory(); std::string hash = cmSystemTools::ComputeStringMD5(outDir); -#if defined(_WIN32) && !defined(__CYGWIN__) - this->StorePackageRegistryWin(package, outDir.c_str(), hash.c_str()); -#else - this->StorePackageRegistryDir(package, outDir.c_str(), hash.c_str()); -#endif + StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str()); return true; } #if defined(_WIN32) && !defined(__CYGWIN__) -# include <windows.h> -void cmExportCommand::ReportRegistryError(std::string const& msg, - std::string const& key, long err) +static void ReportRegistryError(cmMakefile& mf, std::string const& msg, + std::string const& key, long err) { std::ostringstream e; e << msg << "\n" @@ -292,12 +300,11 @@ void cmExportCommand::ReportRegistryError(std::string const& msg, e << "Windows reported:\n" << " " << cmsys::Encoding::ToNarrow(winmsg); } - this->Makefile->IssueMessage(MessageType::WARNING, e.str()); + mf.IssueMessage(MessageType::WARNING, e.str()); } -void cmExportCommand::StorePackageRegistryWin(std::string const& package, - const char* content, - const char* hash) +static void StorePackageRegistry(cmMakefile& mf, std::string const& package, + const char* content, const char* hash) { std::string key = cmStrCat("Software\\Kitware\\CMake\\Packages\\", package); HKEY hKey; @@ -305,7 +312,7 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package, RegCreateKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(key).c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, 0); if (err != ERROR_SUCCESS) { - this->ReportRegistryError("Cannot create/open registry key", key, err); + ReportRegistryError(mf, "Cannot create/open registry key", key, err); return; } @@ -318,14 +325,13 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package, if (err != ERROR_SUCCESS) { std::ostringstream msg; msg << "Cannot set registry value \"" << hash << "\" under key"; - this->ReportRegistryError(msg.str(), key, err); + ReportRegistryError(mf, msg.str(), key, err); return; } } #else -void cmExportCommand::StorePackageRegistryDir(std::string const& package, - const char* content, - const char* hash) +static void StorePackageRegistry(cmMakefile& mf, std::string const& package, + const char* content, const char* hash) { # if defined(__HAIKU__) char dir[B_PATH_NAME_LENGTH]; @@ -357,7 +363,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package, << " " << fname << "\n" << cmSystemTools::GetLastSystemError() << "\n"; /* clang-format on */ - this->Makefile->IssueMessage(MessageType::WARNING, e.str()); + mf.IssueMessage(MessageType::WARNING, e.str()); } } } diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h index 50463af..9655628 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -8,38 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmExportCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmExportCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool HandlePackage(std::vector<std::string> const& args); - void StorePackageRegistryWin(std::string const& package, const char* content, - const char* hash); - void StorePackageRegistryDir(std::string const& package, const char* content, - const char* hash); - void ReportRegistryError(std::string const& msg, std::string const& key, - long err); -}; +bool cmExportCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 70f98bf..e142560 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -19,12 +19,12 @@ #include "cmTargetExport.h" #include "cmsys/FStream.hxx" -#include <assert.h> +#include <cassert> +#include <cstring> #include <sstream> -#include <string.h> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> static std::string cmExportFileGeneratorEscape(std::string const& str) { @@ -380,7 +380,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( this->ReplaceInstallPrefix(dirs); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs); std::string exportDirs = - cge->Evaluate(target->GetLocalGenerator(), "", false, target); + cge->Evaluate(target->GetLocalGenerator(), "", target); if (cge->GetHadContextSensitiveCondition()) { cmLocalGenerator* lg = target->GetLocalGenerator(); @@ -1185,7 +1185,7 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode( << targetName << " "; for (std::string const& li : importedLocations) { - ImportPropertyMap::const_iterator pi = properties.find(li); + auto pi = properties.find(li); if (pi != properties.end()) { os << cmExportFileGeneratorEscape(pi->second) << " "; } diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx index 1b536c9..2d732c1 100644 --- a/Source/cmExportInstallAndroidMKGenerator.cxx +++ b/Source/cmExportInstallAndroidMKGenerator.cxx @@ -2,8 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportInstallAndroidMKGenerator.h" +#include <cstddef> +#include <memory> #include <ostream> -#include <stddef.h> #include "cmExportBuildAndroidMKGenerator.h" #include "cmExportSet.h" @@ -35,7 +36,8 @@ void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode( } os << "_IMPORT_PREFIX := " << "$(LOCAL_PATH)" << path << "\n\n"; - for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->IEGen->GetExportSet()->GetTargetExports()) { // Collect import properties for this target. if (te->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { continue; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index e7f301e..0009b3a 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -3,7 +3,6 @@ #include "cmExportInstallFileGenerator.h" #include "cmExportSet.h" -#include "cmExportSetMap.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" @@ -19,6 +18,7 @@ #include "cmTarget.h" #include "cmTargetExport.h" +#include <memory> #include <sstream> #include <utility> @@ -40,12 +40,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { std::string expectedTargets; std::string sep; - for (cmTargetExport* te : - *this->IEGen->GetExportSet()->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->IEGen->GetExportSet()->GetTargetExports()) { expectedTargets += sep + this->Namespace + te->Target->GetExportName(); sep = " "; if (this->ExportedTargets.insert(te->Target).second) { - allTargets.push_back(te); + allTargets.push_back(te.get()); } else { std::ostringstream e; e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName() @@ -314,9 +314,11 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig( std::vector<std::string>& missingTargets) { // Add each target in the set to the export. - for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->IEGen->GetExportSet()->GetTargetExports()) { // Collect import properties for this target. - if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) { + if (this->GetExportTargetType(te.get()) == + cmStateEnums::INTERFACE_LIBRARY) { continue; } @@ -474,12 +476,10 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, const cmExportSetMap& exportSets = gg->GetExportSets(); for (auto const& expIt : exportSets) { - const cmExportSet* exportSet = expIt.second; - std::vector<cmTargetExport*> const* targets = - exportSet->GetTargetExports(); + const cmExportSet& exportSet = expIt.second; bool containsTarget = false; - for (cmTargetExport* target : *targets) { + for (auto const& target : exportSet.GetTargetExports()) { if (name == target->TargetName) { containsTarget = true; break; @@ -488,7 +488,7 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, if (containsTarget) { std::vector<cmInstallExportGenerator const*> const* installs = - exportSet->GetInstallations(); + exportSet.GetInstallations(); for (cmInstallExportGenerator const* install : *installs) { exportFiles.push_back(install->GetDestinationFile()); ns = install->GetNamespace(); @@ -496,7 +496,7 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, } } - return std::make_pair(exportFiles, ns); + return { exportFiles, ns }; } void cmExportInstallFileGenerator::ComplainAboutMissingTarget( diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx index bab394a..fd2401e 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -6,7 +6,7 @@ #include <map> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmExecutionStatus.h" #include "cmGeneratedFileStream.h" diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index a6fa186..a20aa9a 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx @@ -2,28 +2,43 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportSet.h" -#include "cmAlgorithms.h" +#include <tuple> +#include <utility> + #include "cmLocalGenerator.h" #include "cmTargetExport.h" -cmExportSet::~cmExportSet() +cmExportSet::cmExportSet(std::string name) + : Name(std::move(name)) { - cmDeleteAll(this->TargetExports); } +cmExportSet::~cmExportSet() = default; + void cmExportSet::Compute(cmLocalGenerator* lg) { - for (cmTargetExport* tgtExport : this->TargetExports) { + for (std::unique_ptr<cmTargetExport>& tgtExport : this->TargetExports) { tgtExport->Target = lg->FindGeneratorTargetToUse(tgtExport->TargetName); } } -void cmExportSet::AddTargetExport(cmTargetExport* te) +void cmExportSet::AddTargetExport(std::unique_ptr<cmTargetExport> te) { - this->TargetExports.push_back(te); + this->TargetExports.emplace_back(std::move(te)); } void cmExportSet::AddInstallation(cmInstallExportGenerator const* installation) { this->Installations.push_back(installation); } + +cmExportSet& cmExportSetMap::operator[](const std::string& name) +{ + auto it = this->find(name); + if (it == this->end()) // Export set not found + { + auto tup_name = std::make_tuple(name); + it = this->emplace(std::piecewise_construct, tup_name, tup_name).first; + } + return it->second; +} diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h index d654c12..f0d921f 100644 --- a/Source/cmExportSet.h +++ b/Source/cmExportSet.h @@ -5,8 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <map> +#include <memory> #include <string> -#include <utility> #include <vector> class cmInstallExportGenerator; @@ -18,10 +19,7 @@ class cmExportSet { public: /// Construct an empty export set named \a name - cmExportSet(std::string name) - : Name(std::move(name)) - { - } + cmExportSet(std::string name); /// Destructor ~cmExportSet(); @@ -30,15 +28,15 @@ public: void Compute(cmLocalGenerator* lg); - void AddTargetExport(cmTargetExport* tgt); + void AddTargetExport(std::unique_ptr<cmTargetExport> tgt); void AddInstallation(cmInstallExportGenerator const* installation); std::string const& GetName() const { return this->Name; } - std::vector<cmTargetExport*> const* GetTargetExports() const + std::vector<std::unique_ptr<cmTargetExport>> const& GetTargetExports() const { - return &this->TargetExports; + return this->TargetExports; } std::vector<cmInstallExportGenerator const*> const* GetInstallations() const @@ -47,9 +45,21 @@ public: } private: - std::vector<cmTargetExport*> TargetExports; + std::vector<std::unique_ptr<cmTargetExport>> TargetExports; std::string Name; std::vector<cmInstallExportGenerator const*> Installations; }; +/// A name -> cmExportSet map with overloaded operator[]. +class cmExportSetMap : public std::map<std::string, cmExportSet> +{ +public: + /** \brief Overloaded operator[]. + * + * The operator is overloaded because cmExportSet has no default constructor: + * we do not want unnamed export sets. + */ + cmExportSet& operator[](const std::string& name); +}; + #endif diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx deleted file mode 100644 index 293e80c..0000000 --- a/Source/cmExportSetMap.cxx +++ /dev/null @@ -1,31 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmExportSetMap.h" - -#include "cmAlgorithms.h" -#include "cmExportSet.h" - -#include <utility> - -cmExportSet* cmExportSetMap::operator[](const std::string& name) -{ - std::map<std::string, cmExportSet*>::iterator it = this->find(name); - if (it == this->end()) // Export set not found - { - it = this->insert(std::make_pair(name, new cmExportSet(name))).first; - } - return it->second; -} - -void cmExportSetMap::clear() -{ - cmDeleteAll(*this); - this->derived::clear(); -} - -cmExportSetMap::cmExportSetMap() = default; - -cmExportSetMap::~cmExportSetMap() -{ - this->clear(); -} diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h deleted file mode 100644 index 0ef07ef..0000000 --- a/Source/cmExportSetMap.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmExportSetMap_h -#define cmExportSetMap_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <map> -#include <string> - -class cmExportSet; - -/// A name -> cmExportSet map with overloaded operator[]. -class cmExportSetMap : public std::map<std::string, cmExportSet*> -{ - using derived = std::map<std::string, cmExportSet*>; - -public: - /** \brief Overloaded operator[]. - * - * The operator is overloaded because cmExportSet has no default constructor: - * we do not want unnamed export sets. - */ - cmExportSet* operator[](const std::string& name); - - void clear(); - - cmExportSetMap(); - - /// Overloaded destructor deletes all member export sets. - ~cmExportSetMap(); - - cmExportSetMap(const cmExportSetMap&) = delete; - cmExportSetMap& operator=(const cmExportSetMap&) = delete; -}; - -#endif diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 5631d60..4027d4b 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -74,9 +74,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets( cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator()); - std::string result = - cge->Evaluate(tgt->GetLocalGenerator(), this->Config, false, &gDummyHead, - tgt, &dagChecker, language); + std::string result = cge->Evaluate(tgt->GetLocalGenerator(), this->Config, + &gDummyHead, &dagChecker, tgt, language); const std::set<cmGeneratorTarget const*>& allTargets = cge->GetAllTargetsSeen(); diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 5a9c54c..5a5d959 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -573,8 +573,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget( cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs)); } - std::vector<std::string>::const_iterator end = - cmRemoveDuplicates(allIncludeDirs); + auto end = cmRemoveDuplicates(allIncludeDirs); for (std::string const& str : cmMakeRange(allIncludeDirs.cbegin(), end)) { xml.StartElement("Add"); diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 0956729..e74ad0c 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -15,10 +15,10 @@ #include "cmake.h" #include "cmsys/SystemInformation.hxx" +#include <cstring> #include <map> #include <set> #include <sstream> -#include <string.h> #include <utility> cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator() @@ -307,7 +307,7 @@ void cmExtraCodeLiteGenerator::FindMatchingHeaderfiles( for (std::string const& ext : headerExts) { std::string hname = cmStrCat(headerBasename, '.', ext); // if it's already in the set, don't check if it exists on disk - std::set<std::string>::const_iterator headerIt = otherFiles.find(hname); + auto headerIt = otherFiles.find(hname); if (headerIt != otherFiles.end()) { break; } diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 43f1e12..ca612b5 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -4,10 +4,10 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstdio> #include <map> #include <sstream> -#include <stdio.h> #include <utility> #include "cmGeneratedFileStream.h" @@ -800,7 +800,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const // the list must contain only definition-value pairs: if ((defs.size() % 2) == 0) { - std::vector<std::string>::const_iterator di = defs.begin(); + auto di = defs.begin(); while (di != defs.end()) { std::string def = *di; ++di; @@ -832,7 +832,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const // the list must contain only definition-value pairs: if ((defs.size() % 2) == 0) { - std::vector<std::string>::const_iterator di = defs.begin(); + auto di = defs.begin(); while (di != defs.end()) { std::string def = *di; ++di; diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 7ac73cf..b3d869e 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -12,9 +12,9 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include <cstring> #include <ostream> #include <set> -#include <string.h> #include <vector> cmExtraKateGenerator::cmExtraKateGenerator() = default; diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 52ba968..f041821 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -3,9 +3,9 @@ #include "cmExtraSublimeTextGenerator.h" #include "cmsys/RegularExpression.hxx" +#include <cstring> #include <set> #include <sstream> -#include <string.h> #include <utility> #include "cmGeneratedFileStream.h" @@ -242,7 +242,7 @@ void cmExtraSublimeTextGenerator::AppendTarget( target->GetSourceFiles(sourceFiles, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); for (cmSourceFile* sourceFile : sourceFiles) { - MapSourceFileFlags::iterator sourceFileFlagsIter = + auto sourceFileFlagsIter = sourceFileFlags.find(sourceFile->ResolveFullPath()); if (sourceFileFlagsIter == sourceFileFlags.end()) { sourceFileFlagsIter = diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index ea9e672..11844e4 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -2,16 +2,16 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFLTKWrapUICommand.h" -#include <stddef.h> +#include <cstddef> #include "cmCustomCommandLines.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; class cmTarget; static void FinalAction(cmMakefile& makefile, std::string const& name) @@ -30,39 +30,40 @@ static void FinalAction(cmMakefile& makefile, std::string const& name) } } -// cmFLTKWrapUICommand -bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmFLTKWrapUICommand(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; } + cmMakefile& mf = status.GetMakefile(); + // what is the current source dir - std::string cdir = this->Makefile->GetCurrentSourceDirectory(); + std::string cdir = mf.GetCurrentSourceDirectory(); std::string const& fluid_exe = - this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE"); + mf.GetRequiredDefinition("FLTK_FLUID_EXECUTABLE"); // Target that will use the generated files std::string const& target = args[0]; // get the list of GUI files from which .cxx and .h will be generated - std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory(); + std::string outputDirectory = mf.GetCurrentBinaryDirectory(); { // Some of the generated files are *.h so the directory "GUI" // where they are created have to be added to the include path std::vector<std::string> outputDirectories; outputDirectories.push_back(outputDirectory); - this->Makefile->AddIncludeDirectories(outputDirectories); + mf.AddIncludeDirectories(outputDirectories); } // List of produced files. std::vector<cmSourceFile*> generatedSourcesClasses; for (std::string const& arg : cmMakeRange(args).advance(1)) { - cmSourceFile* curr = this->Makefile->GetSource(arg); + cmSourceFile* curr = mf.GetSource(arg); // if we should use the source GUI // to generate .cxx and .h files if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) { @@ -76,29 +77,26 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, depends.push_back(fluid_exe); std::string cxxres = cmStrCat(outName, ".cxx"); - cmCustomCommandLine commandLine; - commandLine.push_back(fluid_exe); - commandLine.push_back("-c"); // instructs Fluid to run in command line - commandLine.push_back("-h"); // optionally rename .h files - commandLine.push_back(hname); - commandLine.push_back("-o"); // optionally rename .cxx files - commandLine.push_back(cxxres); - commandLine.push_back(origname); // name of the GUI fluid file - cmCustomCommandLines commandLines; - commandLines.push_back(commandLine); + cmCustomCommandLines commandLines = cmMakeSingleCommandLine({ + fluid_exe, + "-c", // instructs Fluid to run in command line + "-h", // optionally rename .h files + hname, + "-o", // optionally rename .cxx files + cxxres, + origname // name of the GUI fluid file + }); // Add command for generating the .h and .cxx files std::string no_main_dependency; const char* no_comment = nullptr; const char* no_working_dir = nullptr; - this->Makefile->AddCustomCommandToOutput( - cxxres, depends, no_main_dependency, commandLines, no_comment, - no_working_dir); - this->Makefile->AddCustomCommandToOutput( - hname, depends, no_main_dependency, commandLines, no_comment, - no_working_dir); - - cmSourceFile* sf = this->Makefile->GetSource(cxxres); + mf.AddCustomCommandToOutput(cxxres, depends, no_main_dependency, + commandLines, no_comment, no_working_dir); + mf.AddCustomCommandToOutput(hname, depends, no_main_dependency, + commandLines, no_comment, no_working_dir); + + cmSourceFile* sf = mf.GetSource(cxxres); sf->AddDepend(hname); sf->AddDepend(origname); generatedSourcesClasses.push_back(sf); @@ -116,9 +114,9 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, } std::string const varName = target + "_FLTK_UI_SRCS"; - this->Makefile->AddDefinition(varName, sourceListValue); + mf.AddDefinition(varName, sourceListValue); - this->Makefile->AddFinalAction( + mf.AddFinalAction( [target](cmMakefile& makefile) { FinalAction(makefile, target); }); return true; } diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h index ea8d401..bb56dbd 100644 --- a/Source/cmFLTKWrapUICommand.h +++ b/Source/cmFLTKWrapUICommand.h @@ -8,35 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmFLTKWrapUICommand - * \brief Create .h and .cxx files rules for FLTK user interfaces files - * - * cmFLTKWrapUICommand is used to create wrappers for FLTK classes into - * normal C++ - */ -class cmFLTKWrapUICommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFLTKWrapUICommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmFLTKWrapUICommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmFSPermissions.h b/Source/cmFSPermissions.h index 7a6e708..fef72e6 100644 --- a/Source/cmFSPermissions.h +++ b/Source/cmFSPermissions.h @@ -5,10 +5,10 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cm_sys_stat.h" - #include <string> +#include "cm_sys_stat.h" + namespace cmFSPermissions { // Table of permissions flags. diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 3ac769c..96ea071 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -802,9 +802,13 @@ void Target::ProcessLanguage(std::string const& lang) { // FIXME: Add flags from end section of ExpandRuleVariable, // which may need to be factored out. - std::string flags; - lg->GetTargetCompileFlags(this->GT, this->Config, lang, flags); - cd.Flags.emplace_back(std::move(flags), JBTIndex()); + std::vector<BT<std::string>> flags = + lg->GetTargetCompileFlags(this->GT, this->Config, lang); + + cd.Flags.reserve(flags.size()); + for (const BT<std::string>& f : flags) { + cd.Flags.emplace_back(this->ToJBT(f)); + } } std::set<BT<std::string>> defines = lg->GetTargetDefines(this->GT, this->Config, lang); @@ -823,8 +827,7 @@ void Target::ProcessLanguage(std::string const& lang) Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si) { - std::unordered_map<cmSourceGroup const*, Json::ArrayIndex>::iterator i = - this->SourceGroupsMap.find(sg); + auto i = this->SourceGroupsMap.find(sg); if (i == this->SourceGroupsMap.end()) { auto sgIndex = static_cast<Json::ArrayIndex>(this->SourceGroups.size()); i = this->SourceGroupsMap.emplace(sg, sgIndex).first; @@ -1264,10 +1267,10 @@ Json::Value Target::DumpLinkCommandFragments() Json::Value linkFragments = Json::arrayValue; std::string linkLanguageFlags; - std::string linkFlags; + std::vector<BT<std::string>> linkFlags; std::string frameworkPath; - std::string linkPath; - std::string linkLibs; + std::vector<BT<std::string>> linkPath; + std::vector<BT<std::string>> linkLibs; cmLocalGenerator* lg = this->GT->GetLocalGenerator(); cmLinkLineComputer linkLineComputer(lg, lg->GetStateSnapshot().GetDirectory()); @@ -1275,10 +1278,7 @@ Json::Value Target::DumpLinkCommandFragments() linkLanguageFlags, linkFlags, frameworkPath, linkPath, this->GT); linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags); - linkFlags = cmTrimWhitespace(linkFlags); frameworkPath = cmTrimWhitespace(frameworkPath); - linkPath = cmTrimWhitespace(linkPath); - linkLibs = cmTrimWhitespace(linkLibs); if (!linkLanguageFlags.empty()) { linkFragments.append( @@ -1286,8 +1286,11 @@ Json::Value Target::DumpLinkCommandFragments() } if (!linkFlags.empty()) { - linkFragments.append( - this->DumpCommandFragment(std::move(linkFlags), "flags")); + for (BT<std::string> frag : linkFlags) { + frag.Value = cmTrimWhitespace(frag.Value); + linkFragments.append( + this->DumpCommandFragment(this->ToJBT(frag), "flags")); + } } if (!frameworkPath.empty()) { @@ -1296,13 +1299,19 @@ Json::Value Target::DumpLinkCommandFragments() } if (!linkPath.empty()) { - linkFragments.append( - this->DumpCommandFragment(std::move(linkPath), "libraryPath")); + for (BT<std::string> frag : linkPath) { + frag.Value = cmTrimWhitespace(frag.Value); + linkFragments.append( + this->DumpCommandFragment(this->ToJBT(frag), "libraryPath")); + } } if (!linkLibs.empty()) { - linkFragments.append( - this->DumpCommandFragment(std::move(linkLibs), "libraries")); + for (BT<std::string> frag : linkLibs) { + frag.Value = cmTrimWhitespace(frag.Value); + linkFragments.append( + this->DumpCommandFragment(this->ToJBT(frag), "libraries")); + } } return linkFragments; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 36a7dc3..c7a0e55 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -9,18 +9,20 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cctype> #include <cmath> -#include <ctype.h> +#include <cstdio> +#include <cstdlib> #include <map> #include <set> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> + +#include "cm_sys_stat.h" #include "cmAlgorithms.h" #include "cmArgumentParser.h" @@ -44,7 +46,6 @@ #include "cmSubcommandTable.h" #include "cmSystemTools.h" #include "cmTimestamp.h" -#include "cm_sys_stat.h" #include "cmake.h" #if !defined(CMAKE_BOOTSTRAP) @@ -91,7 +92,7 @@ std::string fix_file_url_windows(const std::string& url) bool HandleWriteImpl(std::vector<std::string> const& args, bool append, cmExecutionStatus& status) { - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); i++; // Get rid of subcommand @@ -274,9 +275,8 @@ bool HandleHashCommand(std::vector<std::string> const& args, { #if !defined(CMAKE_BOOTSTRAP) if (args.size() != 3) { - std::ostringstream e; - e << args[0] << " requires a file name and output variable"; - status.SetError(e.str()); + status.SetError( + cmStrCat(args[0], " requires a file name and output variable")); return false; } @@ -287,16 +287,12 @@ bool HandleHashCommand(std::vector<std::string> const& args, status.GetMakefile().AddDefinition(args[2], out); return true; } - std::ostringstream e; - e << args[0] << " failed to read file \"" << args[1] - << "\": " << cmSystemTools::GetLastSystemError(); - status.SetError(e.str()); + status.SetError(cmStrCat(args[0], " failed to read file \"", args[1], + "\": ", cmSystemTools::GetLastSystemError())); } return false; #else - std::ostringstream e; - e << args[0] << " not available during bootstrap"; - status.SetError(e.str()); + status.SetError(cmStrCat(args[0], " not available during bootstrap")); return false; #endif } @@ -376,30 +372,24 @@ bool HandleStringsCommand(std::vector<std::string> const& args, } else if (arg_mode == arg_limit_input) { if (sscanf(args[i].c_str(), "%d", &limit_input) != 1 || limit_input < 0) { - std::ostringstream e; - e << "STRINGS option LIMIT_INPUT value \"" << args[i] - << "\" is not an unsigned integer."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option LIMIT_INPUT value \"", + args[i], "\" is not an unsigned integer.")); return false; } arg_mode = arg_none; } else if (arg_mode == arg_limit_output) { if (sscanf(args[i].c_str(), "%d", &limit_output) != 1 || limit_output < 0) { - std::ostringstream e; - e << "STRINGS option LIMIT_OUTPUT value \"" << args[i] - << "\" is not an unsigned integer."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option LIMIT_OUTPUT value \"", + args[i], "\" is not an unsigned integer.")); return false; } arg_mode = arg_none; } else if (arg_mode == arg_limit_count) { int count; if (sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0) { - std::ostringstream e; - e << "STRINGS option LIMIT_COUNT value \"" << args[i] - << "\" is not an unsigned integer."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option LIMIT_COUNT value \"", + args[i], "\" is not an unsigned integer.")); return false; } limit_count = count; @@ -407,10 +397,8 @@ bool HandleStringsCommand(std::vector<std::string> const& args, } else if (arg_mode == arg_length_minimum) { int len; if (sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0) { - std::ostringstream e; - e << "STRINGS option LENGTH_MINIMUM value \"" << args[i] - << "\" is not an unsigned integer."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option LENGTH_MINIMUM value \"", + args[i], "\" is not an unsigned integer.")); return false; } minlen = len; @@ -418,20 +406,16 @@ bool HandleStringsCommand(std::vector<std::string> const& args, } else if (arg_mode == arg_length_maximum) { int len; if (sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0) { - std::ostringstream e; - e << "STRINGS option LENGTH_MAXIMUM value \"" << args[i] - << "\" is not an unsigned integer."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option LENGTH_MAXIMUM value \"", + args[i], "\" is not an unsigned integer.")); return false; } maxlen = len; arg_mode = arg_none; } else if (arg_mode == arg_regex) { if (!regex.compile(args[i])) { - std::ostringstream e; - e << "STRINGS option REGEX value \"" << args[i] - << "\" could not be compiled."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option REGEX value \"", args[i], + "\" could not be compiled.")); return false; } have_regex = true; @@ -448,16 +432,14 @@ bool HandleStringsCommand(std::vector<std::string> const& args, } else if (args[i] == "UTF-32BE") { encoding = encoding_utf32be; } else { - std::ostringstream e; - e << "STRINGS option ENCODING \"" << args[i] << "\" not recognized."; - status.SetError(e.str()); + status.SetError(cmStrCat("STRINGS option ENCODING \"", args[i], + "\" not recognized.")); return false; } arg_mode = arg_none; } else { - std::ostringstream e; - e << "STRINGS given unknown argument \"" << args[i] << "\""; - status.SetError(e.str()); + status.SetError( + cmStrCat("STRINGS given unknown argument \"", args[i], "\"")); return false; } } @@ -479,9 +461,8 @@ bool HandleStringsCommand(std::vector<std::string> const& args, cmsys::ifstream fin(fileName.c_str()); #endif if (!fin) { - std::ostringstream e; - e << "STRINGS file \"" << fileName << "\" cannot be read."; - status.SetError(e.str()); + status.SetError( + cmStrCat("STRINGS file \"", fileName, "\" cannot be read.")); return false; } @@ -663,7 +644,7 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse, // File commands has at least one argument assert(args.size() > 1); - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); i++; // Get rid of subcommand @@ -963,9 +944,7 @@ bool HandleDifferentCommand(std::vector<std::string> const& args, file_rhs = args[i].c_str(); doing = DoingNone; } else { - std::ostringstream e; - e << "DIFFERENT given unknown argument " << args[i]; - status.SetError(e.str()); + status.SetError(cmStrCat("DIFFERENT given unknown argument ", args[i])); return false; } } @@ -1027,9 +1006,8 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args, newRPath = args[i].c_str(); doing = DoingNone; } else { - std::ostringstream e; - e << "RPATH_CHANGE given unknown argument " << args[i]; - status.SetError(e.str()); + status.SetError( + cmStrCat("RPATH_CHANGE given unknown argument ", args[i])); return false; } } @@ -1046,9 +1024,8 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args, return false; } if (!cmSystemTools::FileExists(file, true)) { - std::ostringstream e; - e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist."; - status.SetError(e.str()); + status.SetError( + cmStrCat("RPATH_CHANGE given FILE \"", file, "\" that does not exist.")); return false; } bool success = true; @@ -1058,15 +1035,9 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args, if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, removeEnvironmentRPath, &emsg, &changed)) { - std::ostringstream e; - /* clang-format off */ - e << "RPATH_CHANGE could not write new RPATH:\n" - << " " << newRPath << "\n" - << "to the file:\n" - << " " << file << "\n" - << emsg; - /* clang-format on */ - status.SetError(e.str()); + status.SetError(cmStrCat("RPATH_CHANGE could not write new RPATH:\n ", + newRPath, "\nto the file:\n ", file, "\n", + emsg)); success = false; } if (success) { @@ -1098,9 +1069,8 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args, file = args[i]; doing = DoingNone; } else { - std::ostringstream e; - e << "RPATH_REMOVE given unknown argument " << args[i]; - status.SetError(e.str()); + status.SetError( + cmStrCat("RPATH_REMOVE given unknown argument ", args[i])); return false; } } @@ -1109,9 +1079,8 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args, return false; } if (!cmSystemTools::FileExists(file, true)) { - std::ostringstream e; - e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist."; - status.SetError(e.str()); + status.SetError( + cmStrCat("RPATH_REMOVE given FILE \"", file, "\" that does not exist.")); return false; } bool success = true; @@ -1119,13 +1088,9 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args, std::string emsg; bool removed; if (!cmSystemTools::RemoveRPath(file, &emsg, &removed)) { - std::ostringstream e; - /* clang-format off */ - e << "RPATH_REMOVE could not remove RPATH from file:\n" - << " " << file << "\n" - << emsg; - /* clang-format on */ - status.SetError(e.str()); + status.SetError( + cmStrCat("RPATH_REMOVE could not remove RPATH from file: \n ", file, + "\n", emsg)); success = false; } if (success) { @@ -1164,9 +1129,8 @@ bool HandleRPathCheckCommand(std::vector<std::string> const& args, rpath = args[i].c_str(); doing = DoingNone; } else { - std::ostringstream e; - e << "RPATH_CHECK given unknown argument " << args[i]; - status.SetError(e.str()); + status.SetError( + cmStrCat("RPATH_CHECK given unknown argument ", args[i])); return false; } } @@ -1215,9 +1179,8 @@ bool HandleReadElfCommand(std::vector<std::string> const& args, Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2)); if (!cmSystemTools::FileExists(fileNameArg, true)) { - std::ostringstream e; - e << "READ_ELF given FILE \"" << fileNameArg << "\" that does not exist."; - status.SetError(e.str()); + status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg, + "\" that does not exist.")); return false; } @@ -1311,15 +1274,8 @@ bool HandleRename(std::vector<std::string> const& args, if (!cmSystemTools::RenameFile(oldname, newname)) { std::string err = cmSystemTools::GetLastSystemError(); - std::ostringstream e; - /* clang-format off */ - e << "RENAME failed to rename\n" - << " " << oldname << "\n" - << "to\n" - << " " << newname << "\n" - << "because: " << err << "\n"; - /* clang-format on */ - status.SetError(e.str()); + status.SetError(cmStrCat("RENAME failed to rename\n ", oldname, + "\nto\n ", newname, "\nbecause: ", err, "\n")); return false; } return true; @@ -1494,10 +1450,8 @@ public: bool updated = (OldPercentage != this->CurrentPercentage); if (updated) { - std::ostringstream oss; - oss << "[" << this->Text << " " << this->CurrentPercentage - << "% complete]"; - status = oss.str(); + status = + cmStrCat("[", this->Text, " ", this->CurrentPercentage, "% complete]"); } return updated; @@ -1585,7 +1539,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { #if !defined(CMAKE_BOOTSTRAP) - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); if (args.size() < 3) { status.SetError("DOWNLOAD must be called with at least three arguments."); return false; @@ -1743,9 +1697,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, msg = cmStrCat("returning early; file already exists with expected ", hashMatchMSG, '"'); if (!statusVar.empty()) { - std::ostringstream result; - result << 0 << ";\"" << msg; - status.GetMakefile().AddDefinition(statusVar, result.str()); + status.GetMakefile().AddDefinition(statusVar, cmStrCat(0, ";\"", msg)); } return true; } @@ -1891,10 +1843,9 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, ::curl_easy_cleanup(curl); if (!statusVar.empty()) { - std::ostringstream result; - result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res) - << "\""; - status.GetMakefile().AddDefinition(statusVar, result.str()); + status.GetMakefile().AddDefinition( + statusVar, + cmStrCat(static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\"")); } ::curl_global_cleanup(); @@ -1914,14 +1865,6 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, } if (expectedHash != actualHash) { - std::ostringstream oss; - oss << "DOWNLOAD HASH mismatch" << std::endl - << " for file: [" << file << "]" << std::endl - << " expected hash: [" << expectedHash << "]" << std::endl - << " actual hash: [" << actualHash << "]" << std::endl - << " status: [" << static_cast<int>(res) << ";\"" - << ::curl_easy_strerror(res) << "\"]" << std::endl; - if (!statusVar.empty() && res == 0) { status.GetMakefile().AddDefinition(statusVar, "1;HASH mismatch: " @@ -1930,7 +1873,19 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, " actual: " + actualHash); } - status.SetError(oss.str()); + status.SetError(cmStrCat("DOWNLOAD HASH mismatch\n" + " for file: [", + file, + "]\n" + " expected hash: [", + expectedHash, + "]\n" + " actual hash: [", + actualHash, + "]\n" + " status: [", + static_cast<int>(res), ";\"", + ::curl_easy_strerror(res), "\"]\n")); return false; } } @@ -1955,7 +1910,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, status.SetError("UPLOAD must be called with at least three arguments."); return false; } - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); ++i; std::string filename = *i; ++i; @@ -2180,10 +2135,9 @@ bool HandleUploadCommand(std::vector<std::string> const& args, ::curl_easy_cleanup(curl); if (!statusVar.empty()) { - std::ostringstream result; - result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res) - << "\""; - status.GetMakefile().AddDefinition(statusVar, result.str()); + status.GetMakefile().AddDefinition( + statusVar, + cmStrCat(static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\"")); } ::curl_global_cleanup(); @@ -2322,9 +2276,9 @@ bool HandleLockCommand(std::vector<std::string> const& args, } else if (args[i] == "PROCESS") { guard = GUARD_PROCESS; } else { - std::ostringstream e; - e << merr << ", but got:\n \"" << args[i] << "\"."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat(merr, ", but got:\n \"", args[i], "\".")); return false; } @@ -2346,17 +2300,18 @@ bool HandleLockCommand(std::vector<std::string> const& args, } long scanned; if (!cmStrToLong(args[i], &scanned) || scanned < 0) { - std::ostringstream e; - e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("TIMEOUT value \"", args[i], + "\" is not an unsigned integer.")); return false; } timeout = static_cast<unsigned long>(scanned); } else { - std::ostringstream e; - e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n"; - e << "but got: \"" << args[i] << "\"."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or ", + "TIMEOUT\nbut got: \"", args[i], "\".")); return false; } } @@ -2375,18 +2330,19 @@ bool HandleLockCommand(std::vector<std::string> const& args, // Create file and directories if needed std::string parentDir = cmSystemTools::GetParentDirectory(path); if (!cmSystemTools::MakeDirectory(parentDir)) { - std::ostringstream e; - e << "directory\n \"" << parentDir << "\"\ncreation failed "; - e << "(check permissions)."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("directory\n \"", parentDir, + "\"\ncreation failed (check permissions).")); cmSystemTools::SetFatalErrorOccured(); return false; } FILE* file = cmsys::SystemTools::Fopen(path, "w"); if (!file) { - std::ostringstream e; - e << "file\n \"" << path << "\"\ncreation failed (check permissions)."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("file\n \"", path, + "\"\ncreation failed (check permissions).")); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -2419,9 +2375,9 @@ bool HandleLockCommand(std::vector<std::string> const& args, const std::string result = fileLockResult.GetOutputMessage(); if (resultVariable.empty() && !fileLockResult.IsOk()) { - std::ostringstream e; - e << "error locking file\n \"" << path << "\"\n" << result << "."; - status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("error locking file\n \"", path, "\"\n", result, ".")); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -2485,9 +2441,8 @@ bool HandleSizeCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { if (args.size() != 3) { - std::ostringstream e; - e << args[0] << " requires a file name and output variable"; - status.SetError(e.str()); + status.SetError( + cmStrCat(args[0], " requires a file name and output variable")); return false; } @@ -2498,9 +2453,8 @@ bool HandleSizeCommand(std::vector<std::string> const& args, const std::string& outputVariable = args[argsIndex++]; if (!cmSystemTools::FileExists(filename, true)) { - std::ostringstream e; - e << "SIZE requested of path that is not readable:\n " << filename; - status.SetError(e.str()); + status.SetError( + cmStrCat("SIZE requested of path that is not readable:\n ", filename)); return false; } @@ -2514,9 +2468,8 @@ bool HandleReadSymlinkCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { if (args.size() != 3) { - std::ostringstream e; - e << args[0] << " requires a file name and output variable"; - status.SetError(e.str()); + status.SetError( + cmStrCat(args[0], " requires a file name and output variable")); return false; } @@ -2525,10 +2478,8 @@ bool HandleReadSymlinkCommand(std::vector<std::string> const& args, std::string result; if (!cmSystemTools::ReadSymlink(filename, result)) { - std::ostringstream e; - e << "READ_SYMLINK requested of path that is not a symlink:\n " - << filename; - status.SetError(e.str()); + status.SetError(cmStrCat( + "READ_SYMLINK requested of path that is not a symlink:\n ", filename)); return false; } @@ -2655,10 +2606,9 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, std::string platform = status.GetMakefile().GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME"); if (!supportedPlatforms.count(platform)) { - std::ostringstream e; - e << "GET_RUNTIME_DEPENDENCIES is not supported on system \"" << platform - << "\""; - status.SetError(e.str()); + status.SetError( + cmStrCat("GET_RUNTIME_DEPENDENCIES is not supported on system \"", + platform, "\"")); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -2718,17 +2668,13 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, &keywordsMissingValues); auto argIt = unrecognizedArguments.begin(); if (argIt != unrecognizedArguments.end()) { - std::ostringstream e; - e << "Unrecognized argument: \"" << *argIt << "\""; - status.SetError(e.str()); + status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\"")); cmSystemTools::SetFatalErrorOccured(); return false; } argIt = keywordsMissingValues.begin(); if (argIt != keywordsMissingValues.end()) { - std::ostringstream e; - e << "Keyword missing value: " << *argIt; - status.SetError(e.str()); + status.SetError(cmStrCat("Keyword missing value: ", *argIt)); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -2792,9 +2738,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, } else { auto it = archive.GetUnresolvedPaths().begin(); assert(it != archive.GetUnresolvedPaths().end()); - std::ostringstream e; - e << "Could not resolve file " << *it; - status.SetError(e.str()); + status.SetError(cmStrCat("Could not resolve file ", *it)); cmSystemTools::SetFatalErrorOccured(); return false; } diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index e00e726..5b9c85a 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -16,8 +16,8 @@ # include "cmsys/FStream.hxx" #endif +#include <cstring> #include <sstream> -#include <string.h> using namespace cmFSPermissions; diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h index 263a365..8fc481c 100644 --- a/Source/cmFileCopier.h +++ b/Source/cmFileCopier.h @@ -6,9 +6,10 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmFileTimeCache.h" -#include "cm_sys_stat.h" #include "cmsys/RegularExpression.hxx" +#include "cm_sys_stat.h" + #include <string> #include <vector> diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx index 1e472da..d380798 100644 --- a/Source/cmFileLock.cxx +++ b/Source/cmFileLock.cxx @@ -3,7 +3,7 @@ #include "cmFileLock.h" #include "cmFileLockResult.h" -#include <assert.h> +#include <cassert> // Common implementation diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx index d700a79..8db2db2 100644 --- a/Source/cmFileLockPool.cxx +++ b/Source/cmFileLockPool.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileLockPool.h" -#include <assert.h> +#include <cassert> #include "cmAlgorithms.h" #include "cmFileLock.h" diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx index 9ca5d8a..9d5a6c6 100644 --- a/Source/cmFileLockResult.cxx +++ b/Source/cmFileLockResult.cxx @@ -2,13 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileLockResult.h" -#include <errno.h> -#include <string.h> +#include <cerrno> +#include <cstring> #define WINMSG_BUF_LEN (1024) cmFileLockResult cmFileLockResult::MakeOk() { - return cmFileLockResult(OK, 0); + return { OK, 0 }; } cmFileLockResult cmFileLockResult::MakeSystem() @@ -18,27 +18,27 @@ cmFileLockResult cmFileLockResult::MakeSystem() #else const Error lastError = errno; #endif - return cmFileLockResult(SYSTEM, lastError); + return { SYSTEM, lastError }; } cmFileLockResult cmFileLockResult::MakeTimeout() { - return cmFileLockResult(TIMEOUT, 0); + return { TIMEOUT, 0 }; } cmFileLockResult cmFileLockResult::MakeAlreadyLocked() { - return cmFileLockResult(ALREADY_LOCKED, 0); + return { ALREADY_LOCKED, 0 }; } cmFileLockResult cmFileLockResult::MakeInternal() { - return cmFileLockResult(INTERNAL, 0); + return { INTERNAL, 0 }; } cmFileLockResult cmFileLockResult::MakeNoFunction() { - return cmFileLockResult(NO_FUNCTION, 0); + return { NO_FUNCTION, 0 }; } bool cmFileLockResult::IsOk() const diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx index 1bf5013..7393823 100644 --- a/Source/cmFileLockUnix.cxx +++ b/Source/cmFileLockUnix.cxx @@ -3,9 +3,9 @@ #include "cmFileLock.h" #include "cmSystemTools.h" -#include <errno.h> // errno +#include <cerrno> // errno +#include <cstdio> // SEEK_SET #include <fcntl.h> -#include <stdio.h> // SEEK_SET #include <unistd.h> cmFileLock::cmFileLock() = default; diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx index 56ee739..7fcced2 100644 --- a/Source/cmFileMonitor.cxx +++ b/Source/cmFileMonitor.cxx @@ -6,7 +6,7 @@ #include "cmsys/SystemTools.hxx" #include <cassert> -#include <stddef.h> +#include <cstddef> #include <unordered_map> #include <utility> diff --git a/Source/cmFilePathChecksum.h b/Source/cmFilePathChecksum.h index 30881ce..b7d5cd2 100644 --- a/Source/cmFilePathChecksum.h +++ b/Source/cmFilePathChecksum.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <array> -#include <stddef.h> +#include <cstddef> #include <string> #include <utility> diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx index 253457f..f92c0ff 100644 --- a/Source/cmFileTime.cxx +++ b/Source/cmFileTime.cxx @@ -2,8 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileTime.h" +#include <ctime> #include <string> -#include <time.h> // Use a platform-specific API to get file times efficiently. #if !defined(_WIN32) || defined(__CYGWIN__) diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx index 3824e9b..54ac4ed 100644 --- a/Source/cmFileTimes.cxx +++ b/Source/cmFileTimes.cxx @@ -2,11 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileTimes.h" -#include "cm_sys_stat.h" - #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> + +#include "cm_sys_stat.h" #if defined(_WIN32) # include "cmSystemTools.h" diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index cdc5f63..7d74118 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -2,10 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFindBase.h" +#include <cstddef> #include <deque> #include <iostream> #include <map> -#include <stddef.h> #include "cmAlgorithms.h" #include "cmMakefile.h" @@ -16,7 +16,10 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -cmFindBase::cmFindBase() +class cmExecutionStatus; + +cmFindBase::cmFindBase(cmExecutionStatus& status) + : cmFindCommon(status) { this->AlreadyInCache = false; this->AlreadyInCacheWithoutMetaInfo = false; diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index 88b5b6c..f75db5f 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -10,6 +10,8 @@ #include "cmFindCommon.h" +class cmExecutionStatus; + /** \class cmFindBase * \brief Base class for most FIND_XXX commands. * @@ -19,7 +21,9 @@ class cmFindBase : public cmFindCommon { public: - cmFindBase(); + cmFindBase(cmExecutionStatus& status); + virtual ~cmFindBase() = default; + /** * This is called when the command is first encountered in * the CMakeLists.txt file. diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 9425f99..badec55 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -4,10 +4,11 @@ #include <algorithm> #include <array> -#include <string.h> +#include <cstring> #include <utility> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -24,7 +25,9 @@ cmFindCommon::PathLabel cmFindCommon::PathLabel::SystemEnvironment( cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeSystem("CMAKE_SYSTEM"); cmFindCommon::PathLabel cmFindCommon::PathLabel::Guess("GUESS"); -cmFindCommon::cmFindCommon() +cmFindCommon::cmFindCommon(cmExecutionStatus& status) + : Makefile(&status.GetMakefile()) + , Status(status) { this->FindRootPathMode = RootPathModeBoth; this->NoDefaultPath = false; @@ -51,7 +54,10 @@ cmFindCommon::cmFindCommon() this->InitializeSearchPathGroups(); } -cmFindCommon::~cmFindCommon() = default; +void cmFindCommon::SetError(std::string const& e) +{ + this->Status.SetError(e); +} void cmFindCommon::InitializeSearchPathGroups() { diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index d95eeb1..8177eac 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -10,10 +10,12 @@ #include <string> #include <vector> -#include "cmCommand.h" #include "cmPathLabel.h" #include "cmSearchPath.h" +class cmExecutionStatus; +class cmMakefile; + /** \class cmFindCommon * \brief Base class for FIND_XXX implementations. * @@ -21,11 +23,12 @@ * cmFindProgramCommand, cmFindPathCommand, cmFindLibraryCommand, * cmFindFileCommand, and cmFindPackageCommand. */ -class cmFindCommon : public cmCommand +class cmFindCommon { public: - cmFindCommon(); - ~cmFindCommon() override; + cmFindCommon(cmExecutionStatus& status); + + void SetError(std::string const& e); protected: friend class cmSearchPath; @@ -127,6 +130,9 @@ protected: bool SearchAppBundleFirst; bool SearchAppBundleOnly; bool SearchAppBundleLast; + + cmMakefile* Makefile; + cmExecutionStatus& Status; }; #endif diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx index 9840c4f..29a2bc4 100644 --- a/Source/cmFindFileCommand.cxx +++ b/Source/cmFindFileCommand.cxx @@ -2,7 +2,16 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFindFileCommand.h" -cmFindFileCommand::cmFindFileCommand() +class cmExecutionStatus; + +cmFindFileCommand::cmFindFileCommand(cmExecutionStatus& status) + : cmFindPathCommand(status) { this->IncludeFileInPath = true; } + +bool cmFindFile(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return cmFindFileCommand(status).InitialPass(args); +} diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h index 152b505..7dc6e55 100644 --- a/Source/cmFindFileCommand.h +++ b/Source/cmFindFileCommand.h @@ -5,11 +5,13 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cm_memory.hxx" +#include <string> +#include <vector> -#include "cmCommand.h" #include "cmFindPathCommand.h" +class cmExecutionStatus; + /** \class cmFindFileCommand * \brief Define a command to search for an executable program. * @@ -21,14 +23,10 @@ class cmFindFileCommand : public cmFindPathCommand { public: - cmFindFileCommand(); - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFindFileCommand>(); - } + cmFindFileCommand(cmExecutionStatus& status); }; +bool cmFindFile(std::vector<std::string> const& args, + cmExecutionStatus& status); + #endif diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 92c64c8..011e8aa 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -4,9 +4,9 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include <cstdio> +#include <cstring> #include <set> -#include <stdio.h> -#include <string.h> #include <utility> #include "cmGlobalGenerator.h" @@ -18,15 +18,15 @@ class cmExecutionStatus; -cmFindLibraryCommand::cmFindLibraryCommand() +cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status) + : cmFindBase(status) { this->EnvironmentPath = "LIB"; this->NamesPerDirAllowed = true; } // cmFindLibraryCommand -bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn, - cmExecutionStatus&) +bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn) { this->VariableDocumentation = "Path to a library."; this->CMakePathName = "LIBRARY"; @@ -490,3 +490,9 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName() // No framework found. return ""; } + +bool cmFindLibrary(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return cmFindLibraryCommand(status).InitialPass(args); +} diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index af17d60..b2f71b3 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -8,9 +8,6 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" #include "cmFindBase.h" class cmExecutionStatus; @@ -25,21 +22,9 @@ class cmExecutionStatus; class cmFindLibraryCommand : public cmFindBase { public: - cmFindLibraryCommand(); - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFindLibraryCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; + cmFindLibraryCommand(cmExecutionStatus& status); + + bool InitialPass(std::vector<std::string> const& args); protected: void AddArchitecturePaths(const char* suffix); @@ -57,4 +42,7 @@ private: std::string FindFrameworkLibraryDirsPerName(); }; +bool cmFindLibrary(std::vector<std::string> const& args, + cmExecutionStatus& status); + #endif diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 9132760..17e9869 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -9,16 +9,16 @@ #include "cmsys/RegularExpression.hxx" #include "cmsys/String.h" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstdio> +#include <cstring> #include <deque> #include <functional> #include <iterator> #include <sstream> -#include <stdio.h> -#include <string.h> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmMakefile.h" @@ -85,7 +85,8 @@ void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin, // else do not sort } -cmFindPackageCommand::cmFindPackageCommand() +cmFindPackageCommand::cmFindPackageCommand(cmExecutionStatus& status) + : cmFindCommon(status) { this->CMakePathName = "PACKAGE"; this->Quiet = false; @@ -143,8 +144,7 @@ void cmFindPackageCommand::AppendSearchPathGroups() std::make_pair(PathLabel::SystemRegistry, cmSearchPath(this))); } -bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) { if (args.empty()) { this->SetError("called with incorrect number of arguments"); @@ -348,11 +348,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, } else if (doing == DoingConfigs) { if (args[i].find_first_of(":/\\") != std::string::npos || cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake") { - std::ostringstream e; - e << "given CONFIGS option followed by invalid file name \"" << args[i] - << "\". The names given must be file names without " - << "a path and with a \".cmake\" extension."; - this->SetError(e.str()); + this->SetError(cmStrCat( + "given CONFIGS option followed by invalid file name \"", args[i], + "\". The names given must be file names without " + "a path and with a \".cmake\" extension.")); return false; } this->Configs.push_back(args[i]); @@ -360,9 +359,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, haveVersion = true; this->Version = args[i]; } else { - std::ostringstream e; - e << "called with invalid argument \"" << args[i] << "\""; - this->SetError(e.str()); + this->SetError( + cmStrCat("called with invalid argument \"", args[i], "\"")); return false; } } @@ -372,10 +370,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, optionalComponents.begin(), optionalComponents.end(), std::back_inserter(doubledComponents)); if (!doubledComponents.empty()) { - std::ostringstream e; - e << "called with components that are both required and optional:\n"; - e << cmWrap(" ", doubledComponents, "", "\n") << "\n"; - this->SetError(e.str()); + this->SetError( + cmStrCat("called with components that are both required and " + "optional:\n", + cmWrap(" ", doubledComponents, "", "\n"), "\n")); return false; } @@ -459,11 +457,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name); if (this->Makefile->IsOn(disableFindPackageVar)) { if (this->Required) { - std::ostringstream e; - e << "for module " << this->Name << " called with REQUIRED, but " - << disableFindPackageVar - << " is enabled. A REQUIRED package cannot be disabled."; - this->SetError(e.str()); + this->SetError( + cmStrCat("for module ", this->Name, " called with REQUIRED, but ", + disableFindPackageVar, + " is enabled. A REQUIRED package cannot be disabled.")); return false; } @@ -701,9 +698,9 @@ bool cmFindPackageCommand::FindModule(bool& found) this->Makefile->GetPolicyStatus(it->second); switch (status) { case cmPolicies::WARN: { - std::ostringstream e; - e << cmPolicies::GetPolicyWarning(it->second) << "\n"; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + this->Makefile->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat(cmPolicies::GetPolicyWarning(it->second), "\n")); CM_FALLTHROUGH; } case cmPolicies::OLD: @@ -847,8 +844,7 @@ bool cmFindPackageCommand::HandlePackageMode( // If there are files in ConsideredConfigs, it means that FooConfig.cmake // have been found, but they didn't have appropriate versions. else if (!this->ConsideredConfigs.empty()) { - std::vector<ConfigFileInfo>::const_iterator duplicate_end = - cmRemoveDuplicates(this->ConsideredConfigs); + auto duplicate_end = cmRemoveDuplicates(this->ConsideredConfigs); e << "Could not find a configuration file for package \"" << this->Name << "\" that " << (this->VersionExact ? "exactly matches" : "is compatible with") @@ -935,10 +931,10 @@ bool cmFindPackageCommand::HandlePackageMode( } // output result if in config mode but not in quiet mode else if (!this->Quiet) { - std::ostringstream aw; - aw << "Could NOT find " << this->Name << " (missing: " << this->Name - << "_DIR)"; - this->Makefile->DisplayStatus(aw.str(), -1); + this->Makefile->DisplayStatus(cmStrCat("Could NOT find ", this->Name, + " (missing: ", this->Name, + "_DIR)"), + -1); } } @@ -1080,7 +1076,7 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) std::string tmp = foundProp; cmExpandList(tmp, foundContents, false); - std::vector<std::string>::iterator nameIt = + auto nameIt = std::find(foundContents.begin(), foundContents.end(), this->Name); if (nameIt != foundContents.end()) { foundContents.erase(nameIt); @@ -1094,7 +1090,7 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) std::string tmp = notFoundProp; cmExpandList(tmp, notFoundContents, false); - std::vector<std::string>::iterator nameIt = + auto nameIt = std::find(notFoundContents.begin(), notFoundContents.end(), this->Name); if (nameIt != notFoundContents.end()) { notFoundContents.erase(nameIt); @@ -1199,8 +1195,7 @@ void cmFindPackageCommand::FillPrefixesPackageRoot() cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot]; // Add the PACKAGE_ROOT_PATH from each enclosing find_package call. - for (std::deque<std::vector<std::string>>::const_reverse_iterator pkgPaths = - this->Makefile->FindPackageRootPathStack.rbegin(); + for (auto pkgPaths = this->Makefile->FindPackageRootPathStack.rbegin(); pkgPaths != this->Makefile->FindPackageRootPathStack.rend(); ++pkgPaths) { for (std::string const& path : *pkgPaths) { @@ -2282,3 +2277,9 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in) } // TODO: Debug cmsys::Glob double slash problem. + +bool cmFindPackage(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return cmFindPackageCommand(status).InitialPass(args); +} diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index d57b38a..78b4985 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -3,9 +3,7 @@ #ifndef cmFindPackageCommand_h #define cmFindPackageCommand_h -#include "cmCommand.h" #include "cmConfigure.h" // IWYU pragma: keep -#include "cmPolicies.h" #include "cm_kwiml.h" #include <cstddef> @@ -15,7 +13,8 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include "cmFindCommon.h" +#include "cmPolicies.h" // IWYU insists we should forward-declare instead of including <functional>, // but we cannot forward-declare reliably because some C++ standard libraries @@ -28,8 +27,6 @@ namespace std { /* clang-format on */ #endif -#include "cmFindCommon.h" - class cmExecutionStatus; class cmSearchPath; @@ -62,22 +59,9 @@ public: std::vector<std::string>::iterator end, SortOrderType order, SortDirectionType dir); - cmFindPackageCommand(); + cmFindPackageCommand(cmExecutionStatus& status); - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFindPackageCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; + bool InitialPass(std::vector<std::string> const& args); private: class PathLabel : public cmFindCommon::PathLabel @@ -246,4 +230,7 @@ struct hash<cmFindPackageCommand::ConfigFileInfo> }; } +bool cmFindPackage(std::vector<std::string> const& args, + cmExecutionStatus& status); + #endif diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 41f5e51..f5e2631 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -11,15 +11,15 @@ class cmExecutionStatus; -cmFindPathCommand::cmFindPathCommand() +cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status) + : cmFindBase(status) { this->EnvironmentPath = "INCLUDE"; this->IncludeFileInPath = false; } // cmFindPathCommand -bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn, - cmExecutionStatus&) +bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn) { this->VariableDocumentation = "Path to a file."; this->CMakePathName = "INCLUDE"; @@ -145,3 +145,9 @@ std::string cmFindPathCommand::FindFrameworkHeader() } return ""; } + +bool cmFindPath(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return cmFindPathCommand(status).InitialPass(args); +} diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h index 89e2cef..8d1ea8b 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -8,9 +8,6 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" #include "cmFindBase.h" class cmExecutionStatus; @@ -25,21 +22,9 @@ class cmExecutionStatus; class cmFindPathCommand : public cmFindBase { public: - cmFindPathCommand(); - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFindPathCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; + cmFindPathCommand(cmExecutionStatus& status); + + bool InitialPass(std::vector<std::string> const& args); bool IncludeFileInPath; @@ -51,4 +36,7 @@ private: std::string FindFrameworkHeader(); }; +bool cmFindPath(std::vector<std::string> const& args, + cmExecutionStatus& status); + #endif diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index a2db65c..e0a3fbf 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -88,14 +88,14 @@ struct cmFindProgramHelper } }; -cmFindProgramCommand::cmFindProgramCommand() +cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status) + : cmFindBase(status) { this->NamesPerDirAllowed = true; } // cmFindProgramCommand -bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn, - cmExecutionStatus&) +bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn) { this->VariableDocumentation = "Path to a program."; this->CMakePathName = "PROGRAM"; @@ -270,3 +270,9 @@ std::string cmFindProgramCommand::GetBundleExecutable( return executable; } + +bool cmFindProgram(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return cmFindProgramCommand(status).InitialPass(args); +} diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h index 40e455e..043b43c 100644 --- a/Source/cmFindProgramCommand.h +++ b/Source/cmFindProgramCommand.h @@ -8,9 +8,6 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" #include "cmFindBase.h" class cmExecutionStatus; @@ -26,21 +23,9 @@ class cmExecutionStatus; class cmFindProgramCommand : public cmFindBase { public: - cmFindProgramCommand(); - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFindProgramCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; + cmFindProgramCommand(cmExecutionStatus& status); + + bool InitialPass(std::vector<std::string> const& args); private: std::string FindProgram(); @@ -51,4 +36,7 @@ private: std::string GetBundleExecutable(std::string const& bundlePath); }; +bool cmFindProgram(std::vector<std::string> const& args, + cmExecutionStatus& status); + #endif diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index f0633aa..44392ba 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -2,14 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmForEachCommand.h" -#include <sstream> -#include <stdio.h> -#include <stdlib.h> +#include <cstdio> +#include <cstdlib> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/string_view> + #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" #include "cmExecutionStatus.h" #include "cmFunctionBlocker.h" @@ -146,10 +146,9 @@ bool cmForEachCommand(std::vector<std::string> const& args, } if ((start > stop && step > 0) || (start < stop && step < 0) || step == 0) { - std::ostringstream str; - str << "called with incorrect range specification: start "; - str << start << ", stop " << stop << ", step " << step; - status.SetError(str.str()); + status.SetError( + cmStrCat("called with incorrect range specification: start ", start, + ", stop ", stop, ", step ", step)); return false; } std::vector<std::string> range; @@ -204,10 +203,9 @@ bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile) cmExpandList(value, fb->Args, true); } } else { - std::ostringstream e; - e << "Unknown argument:\n" - << " " << args[i] << "\n"; - makefile.IssueMessage(MessageType::FATAL_ERROR, e.str()); + makefile.IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Unknown argument:\n", " ", args[i], "\n")); return true; } } diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h index 825876c..6f97b42 100644 --- a/Source/cmFortranParser.h +++ b/Source/cmFortranParser.h @@ -12,7 +12,7 @@ # include <vector> #endif -#include <stddef.h> /* size_t */ +#include <cstddef> /* size_t */ /* Forward declare parser object type. */ using cmFortranParser = struct cmFortranParser_s; diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx index ad377de..b983b4d 100644 --- a/Source/cmFortranParserImpl.cxx +++ b/Source/cmFortranParserImpl.cxx @@ -5,10 +5,10 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <assert.h> +#include <cassert> +#include <cstdio> #include <set> #include <stack> -#include <stdio.h> #include <string> #include <utility> #include <vector> diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index 87bdccd..59bb892 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -7,7 +7,7 @@ #include <vector> -#include "cm_string_view.hxx" +#include <cm/string_view> #include "cmListFileCache.h" diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 9420541..b3ddfe0 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -5,9 +5,10 @@ #include <sstream> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/string_view> + #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" #include "cmAlgorithms.h" #include "cmExecutionStatus.h" @@ -80,8 +81,7 @@ bool cmFunctionHelperCommand::operator()( // define ARGV and ARGN std::string argvDef = cmJoin(expandedArgs, ";"); - std::vector<std::string>::const_iterator eit = - expandedArgs.begin() + (this->Args.size() - 1); + auto eit = expandedArgs.begin() + (this->Args.size() - 1); std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";"); makefile.AddDefinition("ARGV", argvDef); makefile.MarkVariableAsUsed("ARGV"); diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 7475e9f..2af04b6 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -2,8 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGeneratedFileStream.h" -#include <stdio.h> +#include <cstdio> +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #if !defined(CMAKE_BOOTSTRAP) @@ -149,7 +150,7 @@ bool cmGeneratedFileStreamBase::Close() // The destination is to be replaced. Rename the temporary to the // destination atomically. if (this->Compress) { - std::string gzname = this->TempName + ".temp.gz"; + std::string gzname = cmStrCat(this->TempName, ".temp.gz"); if (this->CompressFile(this->TempName, gzname)) { this->RenameFile(gzname, resname); } diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 32eb3cd..1f31069 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -6,7 +6,6 @@ #include <memory> #include <utility> -#include "assert.h" #include "cmAlgorithms.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionDAGChecker.h" @@ -15,46 +14,63 @@ #include "cmGeneratorExpressionParser.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include <cassert> cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace) : Backtrace(std::move(backtrace)) { } +cmGeneratorExpression::~cmGeneratorExpression() = default; + std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse( - std::string const& input) + std::string input) const { return std::unique_ptr<cmCompiledGeneratorExpression>( - new cmCompiledGeneratorExpression(this->Backtrace, input)); + new cmCompiledGeneratorExpression(this->Backtrace, std::move(input))); } std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse( - const char* input) + const char* input) const { return this->Parse(std::string(input ? input : "")); } -cmGeneratorExpression::~cmGeneratorExpression() = default; - -const std::string& cmCompiledGeneratorExpression::Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet, - const cmGeneratorTarget* headTarget, +std::string cmGeneratorExpression::Evaluate( + std::string input, cmLocalGenerator* lg, const std::string& config, + cmGeneratorTarget const* headTarget, cmGeneratorExpressionDAGChecker* dagChecker, - std::string const& language) const + cmGeneratorTarget const* currentTarget, std::string const& language) { - return this->Evaluate(lg, config, quiet, headTarget, headTarget, dagChecker, + if (Find(input) != std::string::npos) { + cmCompiledGeneratorExpression cge(cmListFileBacktrace(), std::move(input)); + return cge.Evaluate(lg, config, headTarget, dagChecker, currentTarget, language); + } + return input; +} + +std::string cmGeneratorExpression::Evaluate( + const char* input, cmLocalGenerator* lg, const std::string& config, + cmGeneratorTarget const* headTarget, + cmGeneratorExpressionDAGChecker* dagChecker, + cmGeneratorTarget const* currentTarget, std::string const& language) +{ + return input ? Evaluate(std::string(input), lg, config, headTarget, + dagChecker, currentTarget, language) + : ""; } const std::string& cmCompiledGeneratorExpression::Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet, - const cmGeneratorTarget* headTarget, const cmGeneratorTarget* currentTarget, + cmLocalGenerator* lg, const std::string& config, + const cmGeneratorTarget* headTarget, cmGeneratorExpressionDAGChecker* dagChecker, - std::string const& language) const + const cmGeneratorTarget* currentTarget, std::string const& language) const { cmGeneratorExpressionContext context( - lg, config, quiet, headTarget, currentTarget ? currentTarget : headTarget, - this->EvaluateForBuildsystem, this->Backtrace, language); + lg, config, this->Quiet, headTarget, + currentTarget ? currentTarget : headTarget, this->EvaluateForBuildsystem, + this->Backtrace, language); return this->EvaluateWithContext(context, dagChecker); } @@ -97,9 +113,10 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( cmListFileBacktrace backtrace, std::string input) : Backtrace(std::move(backtrace)) , Input(std::move(input)) + , EvaluateForBuildsystem(false) + , Quiet(false) , HadContextSensitiveCondition(false) , HadHeadSensitiveCondition(false) - , EvaluateForBuildsystem(false) { cmGeneratorExpressionLexer l; std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input); @@ -370,19 +387,17 @@ bool cmGeneratorExpression::IsValidTargetName(const std::string& input) void cmCompiledGeneratorExpression::GetMaxLanguageStandard( const cmGeneratorTarget* tgt, std::map<std::string, std::string>& mapping) { - using MapType = - std::map<cmGeneratorTarget const*, std::map<std::string, std::string>>; - MapType::const_iterator it = this->MaxLanguageStandard.find(tgt); + auto it = this->MaxLanguageStandard.find(tgt); if (it != this->MaxLanguageStandard.end()) { mapping = it->second; } } const std::string& cmGeneratorExpressionInterpreter::Evaluate( - const char* expression, const std::string& property) + std::string expression, const std::string& property) { this->CompiledGeneratorExpression = - this->GeneratorExpression.Parse(expression); + this->GeneratorExpression.Parse(std::move(expression)); // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS cmGeneratorExpressionDAGChecker dagChecker( @@ -391,6 +406,12 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate( nullptr); return this->CompiledGeneratorExpression->Evaluate( - this->LocalGenerator, this->Config, false, this->HeadTarget, &dagChecker, + this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr, this->Language); } + +const std::string& cmGeneratorExpressionInterpreter::Evaluate( + const char* expression, const std::string& property) +{ + return this->Evaluate(std::string(expression ? expression : ""), property); +} diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index ef76651..de5c705 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -41,8 +41,22 @@ public: cmGeneratorExpression& operator=(cmGeneratorExpression const&) = delete; std::unique_ptr<cmCompiledGeneratorExpression> Parse( - std::string const& input); - std::unique_ptr<cmCompiledGeneratorExpression> Parse(const char* input); + std::string input) const; + std::unique_ptr<cmCompiledGeneratorExpression> Parse( + const char* input) const; + + static std::string Evaluate( + std::string input, cmLocalGenerator* lg, const std::string& config, + cmGeneratorTarget const* headTarget = nullptr, + cmGeneratorExpressionDAGChecker* dagChecker = nullptr, + cmGeneratorTarget const* currentTarget = nullptr, + std::string const& language = std::string()); + static std::string Evaluate( + const char* input, cmLocalGenerator* lg, const std::string& config, + cmGeneratorTarget const* headTarget = nullptr, + cmGeneratorExpressionDAGChecker* dagChecker = nullptr, + cmGeneratorTarget const* currentTarget = nullptr, + std::string const& language = std::string()); enum PreprocessContext { @@ -87,15 +101,10 @@ public: cmCompiledGeneratorExpression const&) = delete; const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet = false, + cmLocalGenerator* lg, const std::string& config, cmGeneratorTarget const* headTarget = nullptr, - cmGeneratorTarget const* currentTarget = nullptr, cmGeneratorExpressionDAGChecker* dagChecker = nullptr, - std::string const& language = std::string()) const; - const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet, - cmGeneratorTarget const* headTarget, - cmGeneratorExpressionDAGChecker* dagChecker, + cmGeneratorTarget const* currentTarget = nullptr, std::string const& language = std::string()) const; /** Get set of targets found during evaluations. */ @@ -135,6 +144,8 @@ public: this->EvaluateForBuildsystem = eval; } + void SetQuiet(bool quiet) { this->Quiet = quiet; } + void GetMaxLanguageStandard(cmGeneratorTarget const* tgt, std::map<std::string, std::string>& mapping); @@ -152,6 +163,8 @@ private: std::vector<cmGeneratorExpressionEvaluator*> Evaluators; const std::string Input; bool NeedsEvaluation; + bool EvaluateForBuildsystem; + bool Quiet; mutable std::set<cmGeneratorTarget*> DependTargets; mutable std::set<cmGeneratorTarget const*> AllTargetsSeen; @@ -163,7 +176,6 @@ private: mutable bool HadContextSensitiveCondition; mutable bool HadHeadSensitiveCondition; mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets; - bool EvaluateForBuildsystem; }; class cmGeneratorExpressionInterpreter @@ -172,11 +184,11 @@ public: cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator, std::string config, cmGeneratorTarget const* headTarget, - std::string lang = std::string()) + std::string language = std::string()) : LocalGenerator(localGenerator) , Config(std::move(config)) , HeadTarget(headTarget) - , Language(std::move(lang)) + , Language(std::move(language)) { } @@ -185,13 +197,10 @@ public: cmGeneratorExpressionInterpreter& operator=( cmGeneratorExpressionInterpreter const&) = delete; + const std::string& Evaluate(std::string expression, + const std::string& property); const std::string& Evaluate(const char* expression, const std::string& property); - const std::string& Evaluate(const std::string& expression, - const std::string& property) - { - return this->Evaluate(expression.c_str(), property); - } protected: cmGeneratorExpression GeneratorExpression; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index df2227f..76f2905 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -10,8 +10,8 @@ #include "cmStringAlgorithms.h" #include "cmake.h" +#include <cstring> #include <sstream> -#include <string.h> #include <utility> cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( @@ -59,8 +59,7 @@ void cmGeneratorExpressionDAGChecker::Initialize() TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(*) #undef TEST_TRANSITIVE_PROPERTY_METHOD { - std::map<cmGeneratorTarget const*, std::set<std::string>>::const_iterator - it = top->Seen.find(this->Target); + auto it = top->Seen.find(this->Target); if (it != top->Seen.end()) { const std::set<std::string>& propSet = it->second; if (propSet.find(this->Property) != propSet.end()) { diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 11c2dcc..aa2c1a6 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -37,8 +37,8 @@ void cmGeneratorExpressionEvaluationFile::Generate( { std::string rawCondition = this->Condition->GetInput(); if (!rawCondition.empty()) { - std::string condResult = this->Condition->Evaluate( - lg, config, false, nullptr, nullptr, nullptr, lang); + std::string condResult = + this->Condition->Evaluate(lg, config, nullptr, nullptr, nullptr, lang); if (condResult == "0") { return; } @@ -54,9 +54,9 @@ void cmGeneratorExpressionEvaluationFile::Generate( } std::string outputFileName = this->OutputFileExpr->Evaluate( - lg, config, false, nullptr, nullptr, nullptr, lang); - const std::string& outputContent = inputExpression->Evaluate( - lg, config, false, nullptr, nullptr, nullptr, lang); + lg, config, nullptr, nullptr, nullptr, lang); + const std::string& outputContent = + inputExpression->Evaluate(lg, config, nullptr, nullptr, nullptr, lang); if (cmSystemTools::FileIsFullPath(outputFileName)) { outputFileName = cmSystemTools::CollapseFullPath(outputFileName); @@ -64,8 +64,7 @@ void cmGeneratorExpressionEvaluationFile::Generate( outputFileName = this->FixRelativePath(outputFileName, PathForOutput, lg); } - std::map<std::string, std::string>::iterator it = - outputFiles.find(outputFileName); + auto it = outputFiles.find(outputFileName); if (it != outputFiles.end()) { if (it->second == outputContent) { @@ -101,8 +100,8 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile( gg->GetEnabledLanguages(enabledLanguages); for (std::string const& le : enabledLanguages) { - std::string name = this->OutputFileExpr->Evaluate( - lg, config, false, nullptr, nullptr, nullptr, le); + std::string name = this->OutputFileExpr->Evaluate(lg, config, nullptr, + nullptr, nullptr, le); cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource( name, false, cmSourceFileLocationKind::Known); // Tell TraceDependencies that the file is not expected to exist diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index 06ebeac..c3bc4c8 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -10,9 +10,10 @@ #include <string> #include <vector> +#include "cm_sys_stat.h" + #include "cmGeneratorExpression.h" #include "cmPolicies.h" -#include "cm_sys_stat.h" class cmLocalGenerator; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 7442018..c1343b2 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -30,9 +30,7 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent( { std::string result; - const std::vector< - std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend = - this->ParamChildren.end(); + const auto pend = this->ParamChildren.end(); for (; pit != pend; ++pit) { for (cmGeneratorExpressionEvaluator* pExprEval : *pit) { if (node->RequiresLiteralInput()) { @@ -116,11 +114,8 @@ std::string GeneratorExpressionContent::EvaluateParameters( { const int numExpected = node->NumExpectedParameters(); { - std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator - pit = this->ParamChildren.begin(); - const std::vector< - std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend = - this->ParamChildren.end(); + auto pit = this->ParamChildren.begin(); + const auto pend = this->ParamChildren.end(); const bool acceptsArbitraryContent = node->AcceptsArbitraryContentParameter(); int counter = 1; diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 4530152..b10bb5b 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stddef.h> +#include <cstddef> #include <string> #include <utility> #include <vector> diff --git a/Source/cmGeneratorExpressionLexer.h b/Source/cmGeneratorExpressionLexer.h index bf24308..9e01948 100644 --- a/Source/cmGeneratorExpressionLexer.h +++ b/Source/cmGeneratorExpressionLexer.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stddef.h> +#include <cstddef> #include <string> #include <vector> diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 89b6c1c..641cbaf 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -29,30 +29,32 @@ #include "cmsys/RegularExpression.hxx" #include "cmsys/String.h" +#include <cm/iterator> + #include <algorithm> -#include <assert.h> -#include <errno.h> -#include <iterator> +#include <cassert> +#include <cerrno> +#include <cstdlib> +#include <cstring> #include <map> #include <memory> #include <set> #include <sstream> -#include <stdlib.h> -#include <string.h> #include <utility> std::string cmGeneratorExpressionNode::EvaluateDependentExpression( std::string const& prop, cmLocalGenerator* lg, cmGeneratorExpressionContext* context, cmGeneratorTarget const* headTarget, - cmGeneratorTarget const* currentTarget, - cmGeneratorExpressionDAGChecker* dagChecker) + cmGeneratorExpressionDAGChecker* dagChecker, + cmGeneratorTarget const* currentTarget) { cmGeneratorExpression ge(context->Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem); + cge->SetQuiet(context->Quiet); std::string result = - cge->Evaluate(lg, context->Config, context->Quiet, headTarget, - currentTarget, dagChecker, context->Language); + cge->Evaluate(lg, context->Config, headTarget, dagChecker, currentTarget, + context->Language); if (cge->GetHadContextSensitiveCondition()) { context->HadContextSensitiveCondition = true; } @@ -476,13 +478,13 @@ protected: } return this->EvaluateDependentExpression( - expression, context->LG, context, context->HeadTarget, - context->CurrentTarget, &dagChecker); + expression, context->LG, context, context->HeadTarget, &dagChecker, + context->CurrentTarget); } return this->EvaluateDependentExpression( - expression, context->LG, context, context->HeadTarget, - context->CurrentTarget, dagCheckerParent); + expression, context->LG, context, context->HeadTarget, dagCheckerParent, + context->CurrentTarget); } }; @@ -1330,7 +1332,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (!interfacePropertyName.empty()) { result = this->EvaluateDependentExpression(result, context->LG, context, - target, target, &dagChecker); + target, &dagChecker, target); std::string linkedTargetsContent = getLinkedTargetsContent( target, interfacePropertyName, context, &dagChecker); if (!linkedTargetsContent.empty()) { diff --git a/Source/cmGeneratorExpressionNode.h b/Source/cmGeneratorExpressionNode.h index 7a36924..13e8484 100644 --- a/Source/cmGeneratorExpressionNode.h +++ b/Source/cmGeneratorExpressionNode.h @@ -43,8 +43,8 @@ struct cmGeneratorExpressionNode static std::string EvaluateDependentExpression( std::string const& prop, cmLocalGenerator* lg, cmGeneratorExpressionContext* context, const cmGeneratorTarget* headTarget, - const cmGeneratorTarget* currentTarget, - cmGeneratorExpressionDAGChecker* dagChecker); + cmGeneratorExpressionDAGChecker* dagChecker, + const cmGeneratorTarget* currentTarget); static const cmGeneratorExpressionNode* GetNode( const std::string& identifier); diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index e7effca..a0b685e 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -5,8 +5,8 @@ #include "cmAlgorithms.h" #include "cmGeneratorExpressionEvaluator.h" -#include <assert.h> -#include <stddef.h> +#include <cassert> +#include <cstddef> #include <utility> cmGeneratorExpressionParser::cmGeneratorExpressionParser( @@ -66,8 +66,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( unsigned int nestedLevel = this->NestingLevel; ++this->NestingLevel; - std::vector<cmGeneratorExpressionToken>::const_iterator startToken = - this->it - 1; + auto startToken = this->it - 1; std::vector<cmGeneratorExpressionEvaluator*> identifier; while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression && @@ -174,13 +173,9 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( if (!parameters.empty()) { extendText(result, colonToken); - using EvaluatorVector = std::vector<cmGeneratorExpressionEvaluator*>; - using TokenVector = std::vector<cmGeneratorExpressionToken>; - std::vector<EvaluatorVector>::const_iterator pit = parameters.begin(); - const std::vector<EvaluatorVector>::const_iterator pend = - parameters.end(); - std::vector<TokenVector::const_iterator>::const_iterator commaIt = - commaTokens.begin(); + auto pit = parameters.begin(); + const auto pend = parameters.end(); + auto commaIt = commaTokens.begin(); assert(parameters.size() > commaTokens.size()); for (; pit != pend; ++pit, ++commaIt) { if (!pit->empty() && !emptyParamTermination) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b4706a3..07578cc 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4,19 +4,21 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cerrno> #include <cstddef> -#include <errno.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <iterator> #include <memory> #include <queue> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <unordered_set> #include <utility> +#include <cm/string_view> + #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommand.h" @@ -35,13 +37,13 @@ #include "cmRange.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" +#include "cmSourceFileLocationKind.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmTargetPropertyComputer.h" -#include "cm_string_view.hxx" #include "cmake.h" class cmMessenger; @@ -82,16 +84,10 @@ public: virtual ~TargetPropertyEntry() = default; virtual const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet = false, - cmGeneratorTarget const* headTarget = nullptr, - cmGeneratorTarget const* currentTarget = nullptr, - cmGeneratorExpressionDAGChecker* dagChecker = nullptr, - std::string const& language = std::string()) const = 0; - virtual const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet, + cmLocalGenerator* lg, const std::string& config, cmGeneratorTarget const* headTarget, cmGeneratorExpressionDAGChecker* dagChecker, - std::string const& language = std::string()) const = 0; + std::string const& language) const = 0; virtual cmListFileBacktrace GetBacktrace() const = 0; virtual std::string const& GetInput() const = 0; @@ -111,23 +107,12 @@ public: { } - const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet = false, - cmGeneratorTarget const* headTarget = nullptr, - cmGeneratorTarget const* currentTarget = nullptr, - cmGeneratorExpressionDAGChecker* dagChecker = nullptr, - std::string const& language = std::string()) const override - { - return this->ge->Evaluate(lg, config, quiet, headTarget, currentTarget, - dagChecker, language); - } - const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, bool quiet, - cmGeneratorTarget const* headTarget, - cmGeneratorExpressionDAGChecker* dagChecker, - std::string const& language = std::string()) const override + const std::string& Evaluate(cmLocalGenerator* lg, const std::string& config, + cmGeneratorTarget const* headTarget, + cmGeneratorExpressionDAGChecker* dagChecker, + std::string const& language) const override { - return this->ge->Evaluate(lg, config, quiet, headTarget, dagChecker, + return this->ge->Evaluate(lg, config, headTarget, dagChecker, nullptr, language); } @@ -159,15 +144,7 @@ public: { } - const std::string& Evaluate(cmLocalGenerator*, const std::string&, bool, - cmGeneratorTarget const*, - cmGeneratorTarget const*, - cmGeneratorExpressionDAGChecker*, - std::string const&) const override - { - return this->PropertyValue; - } - const std::string& Evaluate(cmLocalGenerator*, const std::string&, bool, + const std::string& Evaluate(cmLocalGenerator*, const std::string&, cmGeneratorTarget const*, cmGeneratorExpressionDAGChecker*, std::string const&) const override @@ -196,7 +173,7 @@ cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry( return new TargetPropertyEntryGenex(std::move(cge)); } - return new TargetPropertyEntryString(propertyValue, backtrace); + return new TargetPropertyEntryString(propertyValue, std::move(backtrace)); } void CreatePropertyGeneratorExpressions( @@ -204,9 +181,8 @@ void CreatePropertyGeneratorExpressions( std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items, bool evaluateForBuildsystem = false) { - std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin(); - for (std::vector<std::string>::const_iterator it = entries.begin(); - it != entries.end(); ++it, ++btIt) { + auto btIt = backtraces.begin(); + for (auto it = entries.begin(); it != entries.end(); ++it, ++btIt) { items.push_back( CreateTargetPropertyEntry(*it, *btIt, evaluateForBuildsystem)); } @@ -244,7 +220,7 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( cmGeneratorTarget::TargetPropertyEntry* entry) { EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace()); - cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config, false, + cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config, thisTarget, dagChecker, lang), ee.Values); if (entry->GetHadContextSensitiveCondition()) { @@ -471,8 +447,7 @@ std::string cmGeneratorTarget::GetOutputName( { // Lookup/compute/cache the output name for this configuration. OutputNameKey key(config, artifact); - cmGeneratorTarget::OutputNameMapType::iterator i = - this->OutputNameMap.find(key); + auto i = this->OutputNameMap.find(key); if (i == this->OutputNameMap.end()) { // Add empty name in map to detect potential recursion. OutputNameMapType::value_type entry(key, ""); @@ -512,9 +487,8 @@ std::string cmGeneratorTarget::GetOutputName( } // Now evaluate genex and update the previously-prepared map entry. - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName); - i->second = cge->Evaluate(this->LocalGenerator, config); + i->second = + cmGeneratorExpression::Evaluate(outName, this->LocalGenerator, config); } else if (i->second.empty()) { // An empty map entry indicates we have been called recursively // from the above block. @@ -716,7 +690,7 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src, std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends( cmSourceFile const* sf) const { - SourceEntriesType::const_iterator i = this->SourceDepends.find(sf); + auto i = this->SourceDepends.find(sf); if (i != this->SourceDepends.end()) { return &i->second.Depends; } @@ -734,9 +708,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg, { if (const char* dirs = depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) { - cmGeneratorExpression ge; - cmExpandList(ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, - depTgt, dagChecker, language), + cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget, + dagChecker, depTgt, language), result); } if (!depTgt->IsImported() || excludeImported) { @@ -745,9 +718,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg, if (const char* dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) { - cmGeneratorExpression ge; - cmExpandList(ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, - depTgt, dagChecker, language), + cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget, + dagChecker, depTgt, language), result); } } @@ -925,8 +897,7 @@ void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf) bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const { const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping(); - std::set<cmSourceFile const*>::const_iterator it = - this->ExplicitObjectName.find(file); + auto it = this->ExplicitObjectName.find(file); return it != this->ExplicitObjectName.end(); } @@ -1108,8 +1079,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory( } using IncludeCacheType = std::map<std::string, std::vector<std::string>>; - IncludeCacheType::const_iterator iter = - this->SystemIncludesCache.find(config_upper); + auto iter = this->SystemIncludesCache.find(config_upper); if (iter == this->SystemIncludesCache.end()) { cmGeneratorExpressionDAGChecker dagChecker( @@ -1119,9 +1089,9 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory( std::vector<std::string> result; for (std::string const& it : this->Target->GetSystemIncludeDirectories()) { - cmGeneratorExpression ge; - cmExpandList(ge.Parse(it)->Evaluate(this->LocalGenerator, config, false, - this, &dagChecker, language), + cmExpandList(cmGeneratorExpression::Evaluate(it, this->LocalGenerator, + config, this, &dagChecker, + nullptr, language), result); } @@ -1227,7 +1197,7 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( if (const char* p = this->GetProperty(prop)) { result = cmGeneratorExpressionNode::EvaluateDependentExpression( - p, context->LG, context, headTarget, this, &dagChecker); + p, context->LG, context, headTarget, &dagChecker, this); } if (cmLinkInterfaceLibraries const* iface = @@ -1317,7 +1287,7 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget, EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); cmExpandList(cge->Evaluate(headTarget->GetLocalGenerator(), config, - false, headTarget, dagChecker), + headTarget, dagChecker), ee.Values); if (cge->GetHadContextSensitiveCondition()) { ee.ContextDependent = true; @@ -1456,11 +1426,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources); // Collect TARGET_OBJECTS of direct object link-dependencies. - std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries; - AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); + bool contextDependentObjects = false; std::vector<std::string>::size_type numFilesBefore2 = files.size(); - bool contextDependentObjects = - processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources); + if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) { + std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries; + AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); + contextDependentObjects = processSources(this, linkObjectsEntries, files, + uniqueSrcs, debugSources); + } if (!contextDependentDirectSources && !(contextDependentInterfaceSources && numFilesBefore < files.size()) && @@ -1548,7 +1521,7 @@ cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources( // Lookup any existing link implementation for this configuration. std::string const key = cmSystemTools::UpperCase(config); - KindedSourcesMapType::iterator it = this->KindedSourcesMap.find(key); + auto it = this->KindedSourcesMap.find(key); if (it != this->KindedSourcesMap.end()) { if (!it->second.Initialized) { std::ostringstream e; @@ -1680,8 +1653,7 @@ void cmGeneratorTarget::ComputeAllConfigSources() const for (size_t ci = 0; ci < configs.size(); ++ci) { KindedSources const& sources = this->GetKindedSources(configs[ci]); for (SourceAndKind const& src : sources.Sources) { - std::map<cmSourceFile const*, size_t>::iterator mi = - index.find(src.Source.Value); + auto mi = index.find(src.Source.Value); if (mi == index.end()) { AllConfigSource acs; acs.Source = src.Source.Value; @@ -2292,7 +2264,7 @@ cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure( const std::string& config) const { std::string key(cmSystemTools::UpperCase(config)); - LinkClosureMapType::iterator i = this->LinkClosureMap.find(key); + auto i = this->LinkClosureMap.find(key); if (i == this->LinkClosureMap.end()) { LinkClosure lc; this->ComputeLinkClosure(config, lc); @@ -2474,8 +2446,7 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo( if (!config.empty()) { config_upper = cmSystemTools::UpperCase(config); } - CompileInfoMapType::const_iterator i = - this->CompileInfoMap.find(config_upper); + auto i = this->CompileInfoMap.find(config_upper); if (i == this->CompileInfoMap.end()) { CompileInfo info; this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir); @@ -2500,8 +2471,7 @@ cmGeneratorTarget::GetModuleDefinitionInfo(std::string const& config) const if (!config.empty()) { config_upper = cmSystemTools::UpperCase(config); } - ModuleDefinitionInfoMapType::const_iterator i = - this->ModuleDefinitionInfoMap.find(config_upper); + auto i = this->ModuleDefinitionInfoMap.find(config_upper); if (i == this->ModuleDefinitionInfoMap.end()) { ModuleDefinitionInfo info; this->ComputeModuleDefinitionInfo(config, info); @@ -2545,12 +2515,11 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result, if (!prop) { return; } - cmGeneratorExpression ge; cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr, nullptr); - cmExpandList(ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, - this, &dagChecker), + cmExpandList(cmGeneratorExpression::Evaluate(prop, this->LocalGenerator, + config, this, &dagChecker), result); } @@ -2606,7 +2575,7 @@ private: SourceEntry* CurrentEntry; std::queue<cmSourceFile*> SourceQueue; std::set<cmSourceFile*> SourcesQueued; - using NameMapType = std::map<std::string, cmSourceFile*>; + using NameMapType = std::map<std::string, cmSourcesWithOutput>; NameMapType NameMap; std::vector<std::string> NewSources; @@ -2712,19 +2681,30 @@ void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf) void cmTargetTraceDependencies::FollowName(std::string const& name) { - NameMapType::iterator i = this->NameMap.find(name); - if (i == this->NameMap.end()) { + // Use lower bound with key comparison to not repeat the search for the + // insert position if the name could not be found (which is the common case). + auto i = this->NameMap.lower_bound(name); + if (i == this->NameMap.end() || i->first != name) { // Check if we know how to generate this file. - cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name); - NameMapType::value_type entry(name, sf); - i = this->NameMap.insert(entry).first; - } - if (cmSourceFile* sf = i->second) { - // Record the dependency we just followed. - if (this->CurrentEntry) { - this->CurrentEntry->Depends.push_back(sf); + cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name); + i = this->NameMap.emplace_hint(i, name, sources); + } + if (cmTarget* t = i->second.Target) { + // The name is a byproduct of a utility target or a PRE_BUILD, PRE_LINK, or + // POST_BUILD command. + this->GeneratorTarget->Target->AddUtility(t->GetName()); + } + if (cmSourceFile* sf = i->second.Source) { + // For now only follow the dependency if the source file is not a + // byproduct. Semantics of byproducts in a non-Ninja context will have to + // be defined first. + if (!i->second.SourceIsByproduct) { + // Record the dependency we just followed. + if (this->CurrentEntry) { + this->CurrentEntry->Depends.push_back(sf); + } + this->QueueSource(sf); } - this->QueueSource(sf); } } @@ -2809,7 +2789,8 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc) // Check for target references in generator expressions. for (std::string const& cl : cCmdLine) { const std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cl); - cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), "", true); + cge->SetQuiet(true); + cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), ""); std::set<cmGeneratorTarget*> geTargets = cge->GetTargets(); targets.insert(geTargets.begin(), geTargets.end()); } @@ -3367,58 +3348,67 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, } std::string& filename = inserted.first->second; + const cmGeneratorTarget* generatorTarget = this; + const char* pchReuseFrom = + generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); + if (pchReuseFrom) { + generatorTarget = + this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom); + } + if (this->GetGlobalGenerator()->IsMultiConfig()) { - filename = - cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), "/"); + filename = cmStrCat( + generatorTarget->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 = generatorTarget->ObjectDirectory; } - filename = cmStrCat(filename, "CMakeFiles/", this->GetName(), + filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx")); const std::string filename_tmp = cmStrCat(filename, ".tmp"); - { + if (!pchReuseFrom) { 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; + { + cmGeneratedFileStream file( + filename_tmp, false, + this->GetGlobalGenerator()->GetMakefileEncoding()); + file << "/* generated by CMake */\n\n"; + if (pchPrologue) { + file << pchPrologue << "\n"; } - if (header_bt.Value[0] == '<' || header_bt.Value[0] == '"') { - file << "#include " << header_bt.Value << "\n"; - } else { - file << "#include \"" << header_bt.Value << "\"\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"; } } - if (language == "CXX") { - file << "#endif // __cplusplus\n"; - } - if (this->GetGlobalGenerator()->IsXcode()) { - file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n"; - } - if (pchEpilogue) { - file << pchEpilogue << "\n"; - } + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } - cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); - cmSystemTools::RemoveFile(filename_tmp); } return inserted.first->second; } @@ -3437,8 +3427,18 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config, return std::string(); } std::string& filename = inserted.first->second; - filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), - "/CMakeFiles/", this->GetName(), ".dir/cmake_pch"); + + const cmGeneratorTarget* generatorTarget = this; + const char* pchReuseFrom = + generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); + if (pchReuseFrom) { + generatorTarget = + this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom); + } + + filename = + cmStrCat(generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(), + "/CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch"); // For GCC the source extension will be tranformed into .h[xx].gch if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) { @@ -3446,13 +3446,40 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config, } else { filename += ((language == "C") ? ".c" : ".cxx"); } + const std::string filename_tmp = cmStrCat(filename, ".tmp"); - { - cmGeneratedFileStream file(filename_tmp); - file << "/* generated by CMake */\n"; + if (!pchReuseFrom) { + { + cmGeneratedFileStream file(filename_tmp); + file << "/* generated by CMake */\n"; + } + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } - cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); - cmSystemTools::RemoveFile(filename_tmp); + } + return inserted.first->second; +} + +std::string cmGeneratorTarget::GetPchFileObject(const std::string& config, + const std::string& language) +{ + if (language != "C" && language != "CXX") { + return std::string(); + } + const auto inserted = + this->PchObjectFiles.insert(std::make_pair(language + config, "")); + if (inserted.second) { + const std::string pchSource = this->GetPchSource(config, language); + if (pchSource.empty()) { + return std::string(); + } + std::string& filename = inserted.first->second; + + this->AddSource(pchSource, true); + + auto pchSf = this->Makefile->GetOrCreateSource( + pchSource, false, cmSourceFileLocationKind::Known); + + filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf)); } return inserted.first->second; } @@ -3694,7 +3721,7 @@ void processLinkDirectories(cmGeneratorTarget const* tgt, // in case projects set the LINK_DIRECTORIES property directly. cmSystemTools::ConvertToUnixSlashes(entryDirectory); if (uniqueDirectories.insert(entryDirectory).second) { - directories.emplace_back(entryDirectory); + directories.emplace_back(entryDirectory, entry.Backtrace); if (debugDirectories) { usedDirectories += " * " + entryDirectory + "\n"; } @@ -4260,8 +4287,7 @@ void cmGeneratorTarget::GetTargetObjectNames( for (cmSourceFile const* src : objectSources) { // Find the object file name corresponding to this source file. - std::map<cmSourceFile const*, std::string>::const_iterator map_it = - mapping.find(src); + auto map_it = mapping.find(src); // It must exist because we populated the mapping just above. assert(!map_it->second.empty()); objects.push_back(map_it->second); @@ -4285,8 +4311,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const { struct SourceFileFlags flags; this->ConstructSourceFileFlags(); - std::map<cmSourceFile const*, SourceFileFlags>::iterator si = - this->SourceFlagsMap.find(sf); + auto si = this->SourceFlagsMap.find(sf); if (si != this->SourceFlagsMap.end()) { flags = si->second; } else { @@ -4620,7 +4645,7 @@ void cmGeneratorTarget::CheckPropertyCompatibility( if (!prop.empty()) { // Use a sorted std::vector to keep the error message sorted. std::vector<std::string> props; - std::set<std::string>::const_iterator i = emittedBools.find(prop); + auto i = emittedBools.find(prop); if (i != emittedBools.end()) { props.push_back(strBool); } @@ -4778,21 +4803,21 @@ template <> std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType /*unused*/) { - return std::make_pair(lhs == rhs, lhs); + return { lhs == rhs, lhs }; } std::pair<bool, const char*> consistentStringProperty(const char* lhs, const char* rhs) { const bool b = strcmp(lhs, rhs) == 0; - return std::make_pair(b, b ? lhs : nullptr); + return { b, b ? lhs : nullptr }; } std::pair<bool, std::string> consistentStringProperty(const std::string& lhs, const std::string& rhs) { const bool b = lhs == rhs; - return std::make_pair(b, b ? lhs : valueAsString(nullptr)); + return { b, b ? lhs : valueAsString(nullptr) }; } std::pair<bool, const char*> consistentNumberProperty(const char* lhs, @@ -4801,22 +4826,21 @@ std::pair<bool, const char*> consistentNumberProperty(const char* lhs, { char* pEnd; - const char* const null_ptr = nullptr; - long lnum = strtol(lhs, &pEnd, 0); if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) { - return std::pair<bool, const char*>(false, null_ptr); + return { false, nullptr }; } long rnum = strtol(rhs, &pEnd, 0); if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) { - return std::pair<bool, const char*>(false, null_ptr); + return { false, nullptr }; } if (t == NumberMaxType) { - return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs); + return { true, std::max(lnum, rnum) == lnum ? lhs : rhs }; } - return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs); + + return { true, std::min(lnum, rnum) == lnum ? lhs : rhs }; } template <> @@ -4825,21 +4849,19 @@ std::pair<bool, const char*> consistentProperty(const char* lhs, CompatibleType t) { if (!lhs && !rhs) { - return std::make_pair(true, lhs); + return { true, lhs }; } if (!lhs) { - return std::make_pair(true, rhs); + return { true, rhs }; } if (!rhs) { - return std::make_pair(true, lhs); + return { true, lhs }; } - const char* const null_ptr = nullptr; - switch (t) { case BoolType: { bool same = cmIsOn(lhs) == cmIsOn(rhs); - return std::make_pair(same, same ? lhs : nullptr); + return { same, same ? lhs : nullptr }; } case StringType: return consistentStringProperty(lhs, rhs); @@ -4848,7 +4870,7 @@ std::pair<bool, const char*> consistentProperty(const char* lhs, return consistentNumberProperty(lhs, rhs, t); } assert(false && "Unreachable!"); - return std::pair<bool, const char*>(false, null_ptr); + return { false, nullptr }; } std::pair<bool, std::string> consistentProperty(const std::string& lhs, @@ -4858,31 +4880,31 @@ std::pair<bool, std::string> consistentProperty(const std::string& lhs, const std::string null_ptr = valueAsString(nullptr); if (lhs == null_ptr && rhs == null_ptr) { - return std::make_pair(true, lhs); + return { true, lhs }; } if (lhs == null_ptr) { - return std::make_pair(true, rhs); + return { true, rhs }; } if (rhs == null_ptr) { - return std::make_pair(true, lhs); + return { true, lhs }; } switch (t) { case BoolType: { bool same = cmIsOn(lhs) == cmIsOn(rhs); - return std::make_pair(same, same ? lhs : null_ptr); + return { same, same ? lhs : null_ptr }; } case StringType: return consistentStringProperty(lhs, rhs); case NumberMinType: case NumberMaxType: { auto value = consistentNumberProperty(lhs.c_str(), rhs.c_str(), t); - return std::make_pair( - value.first, value.first ? std::string(value.second) : null_ptr); + return { value.first, + value.first ? std::string(value.second) : null_ptr }; } } assert(false && "Unreachable!"); - return std::pair<bool, std::string>(false, null_ptr); + return { false, null_ptr }; } template <typename PropertyType> @@ -5068,7 +5090,7 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation( { // Lookup any existing information for this configuration. std::string key(cmSystemTools::UpperCase(config)); - cmTargetLinkInformationMap::iterator i = this->LinkInformation.find(key); + auto i = this->LinkInformation.find(key); if (i == this->LinkInformation.end()) { // Compute information for this configuration. cmComputeLinkInformation* info = @@ -5264,9 +5286,9 @@ void cmGeneratorTarget::ExpandLinkItems( } std::vector<std::string> libs; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); - cmExpandList(cge->Evaluate(this->LocalGenerator, config, false, headTarget, - this, &dagChecker), - libs); + cmExpandList( + cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this), + libs); this->LookupLinkItems(libs, cge->GetBacktrace(), items); hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); } @@ -5469,7 +5491,7 @@ cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo( if (!config.empty()) { config_upper = cmSystemTools::UpperCase(config); } - OutputInfoMapType::iterator i = this->OutputInfoMap.find(config_upper); + auto i = this->OutputInfoMap.find(config_upper); if (i == this->OutputInfoMap.end()) { // Add empty info in map to detect potential recursion. OutputInfo info; @@ -5529,18 +5551,15 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, // Select an output directory. if (const char* config_outdir = this->GetProperty(configProp)) { // Use the user-specified per-configuration output directory. - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(config_outdir); - out = cge->Evaluate(this->LocalGenerator, config); + out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator, + config); // Skip per-configuration subdirectory. conf.clear(); } else if (const char* outdir = this->GetProperty(propertyName)) { // Use the user-specified output directory. - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outdir); - out = cge->Evaluate(this->LocalGenerator, config); + out = + cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config); // Skip per-configuration subdirectory if the value contained a // generator expression. @@ -5608,18 +5627,15 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind, // Select an output directory. if (const char* config_outdir = this->GetProperty(configProp)) { // Use the user-specified per-configuration output directory. - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(config_outdir); - out = cge->Evaluate(this->LocalGenerator, config); + out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator, + config); // Skip per-configuration subdirectory. conf.clear(); } else if (const char* outdir = this->GetProperty(propertyName)) { // Use the user-specified output directory. - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outdir); - out = cge->Evaluate(this->LocalGenerator, config); + out = + cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config); // Skip per-configuration subdirectory if the value contained a // generator expression. @@ -5674,8 +5690,7 @@ bool cmGeneratorTarget::GetRPATH(const std::string& config, return false; } - cmGeneratorExpression ge; - rpath = ge.Parse(value)->Evaluate(this->LocalGenerator, config); + rpath = cmGeneratorExpression::Evaluate(value, this->LocalGenerator, config); return true; } @@ -5868,7 +5883,7 @@ cmGeneratorTarget::ImportInfo const* cmGeneratorTarget::GetImportInfo( config_upper = "NOCONFIG"; } - ImportInfoMapType::const_iterator i = this->ImportInfoMap.find(config_upper); + auto i = this->ImportInfoMap.find(config_upper); if (i == this->ImportInfoMap.end()) { ImportInfo info; this->ComputeImportInfo(config_upper, info); @@ -6072,7 +6087,7 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles( std::vector<std::string> const& configs = this->Makefile->GetGeneratorConfigs(); - std::vector<std::string>::const_iterator it = configs.begin(); + auto it = configs.begin(); const std::string& firstConfig = *it; this->GetSourceFilesWithoutObjectLibraries(files, firstConfig); @@ -6336,7 +6351,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( cmGeneratorExpression ge(*btIt); std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le); std::string const& evaluated = - cge->Evaluate(this->LocalGenerator, config, false, head, &dagChecker); + cge->Evaluate(this->LocalGenerator, config, head, &dagChecker); cmExpandList(evaluated, llibs); if (cge->GetHadHeadSensitiveCondition()) { impl.HadHeadSensitiveCondition = true; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 9eb2ecf..6c36c4b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -10,9 +10,9 @@ #include "cmPolicies.h" #include "cmStateTypes.h" +#include <cstddef> #include <map> #include <set> -#include <stddef.h> #include <string> #include <unordered_map> #include <utility> @@ -462,6 +462,8 @@ public: const std::string& language) const; std::string GetPchSource(const std::string& config, const std::string& language) const; + std::string GetPchFileObject(const std::string& config, + const std::string& language); bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config, @@ -880,6 +882,7 @@ private: mutable std::set<std::string> LinkImplicitNullProperties; mutable std::map<std::string, std::string> PchHeaders; mutable std::map<std::string, std::string> PchSources; + mutable std::map<std::string, std::string> PchObjectFiles; void ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index d078a7a..64438d5 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -24,7 +24,7 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args, return false; } - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); std::string const& variable = *i; ++i; diff --git a/Source/cmGetPipes.cxx b/Source/cmGetPipes.cxx index ad323f7..79f90fd 100644 --- a/Source/cmGetPipes.cxx +++ b/Source/cmGetPipes.cxx @@ -28,7 +28,7 @@ int cmGetPipes(int* fds) return 0; } #else -# include <errno.h> +# include <cerrno> # include <unistd.h> int cmGetPipes(int* fds) diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index e8e87e7..947d893 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGetPropertyCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmInstalledFile.h" @@ -99,11 +97,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, } else if (args[1] == "INSTALL") { scope = cmProperty::INSTALL; } else { - std::ostringstream e; - e << "given invalid scope " << args[1] << ". " - << "Valid scopes are " - << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."; - status.SetError(e.str()); + status.SetError(cmStrCat( + "given invalid scope ", args[1], + ". " + "Valid scopes are " + "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.")); return false; } @@ -138,9 +136,7 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, doing = DoingNone; propertyName = args[i]; } else { - std::ostringstream e; - e << "given invalid argument \"" << args[i] << "\"."; - status.SetError(e.str()); + status.SetError(cmStrCat("given invalid argument \"", args[i], "\".")); return false; } } @@ -331,10 +327,8 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, } return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr); } - std::ostringstream e; - e << "could not find TARGET " << name - << ". Perhaps it has not yet been created."; - status.SetError(e.str()); + status.SetError(cmStrCat("could not find TARGET ", name, + ". Perhaps it has not yet been created.")); return false; } @@ -352,9 +346,8 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, return StoreResult(infoType, status.GetMakefile(), variable, sf->GetPropertyForUser(propertyName)); } - std::ostringstream e; - e << "given SOURCE name that could not be found or created: " << name; - status.SetError(e.str()); + status.SetError( + cmStrCat("given SOURCE name that could not be found or created: ", name)); return false; } @@ -374,9 +367,7 @@ bool HandleTestMode(cmExecutionStatus& status, const std::string& name, } // If not found it is an error. - std::ostringstream e; - e << "given TEST name that does not exist: " << name; - status.SetError(e.str()); + status.SetError(cmStrCat("given TEST name that does not exist: ", name)); return false; } @@ -431,9 +422,8 @@ bool HandleInstallMode(cmExecutionStatus& status, const std::string& name, return StoreResult(infoType, status.GetMakefile(), variable, isSet ? value.c_str() : nullptr); } - std::ostringstream e; - e << "given INSTALL name that could not be found or created: " << name; - status.SetError(e.str()); + status.SetError( + cmStrCat("given INSTALL name that could not be found or created: ", name)); return false; } } diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 5c1c8a5..eefdc6c 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -2,26 +2,25 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGetSourceFilePropertyCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSourceFile.h" -class cmExecutionStatus; - -// cmSetSourceFilePropertyCommand -bool cmGetSourceFilePropertyCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmGetSourceFilePropertyCommand(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& var = args[0]; std::string const& file = args[1]; - cmSourceFile* sf = this->Makefile->GetSource(file); + cmMakefile& mf = status.GetMakefile(); + cmSourceFile* sf = mf.GetSource(file); // for the location we must create a source file first if (!sf && args[2] == "LOCATION") { - sf = this->Makefile->CreateSource(file); + sf = mf.CreateSource(file); } if (sf) { const char* prop = nullptr; @@ -29,11 +28,11 @@ bool cmGetSourceFilePropertyCommand::InitialPass( prop = sf->GetPropertyForUser(args[2]); } if (prop) { - this->Makefile->AddDefinition(var, prop); + mf.AddDefinition(var, prop); return true; } } - this->Makefile->AddDefinition(var, "NOTFOUND"); + mf.AddDefinition(var, "NOTFOUND"); return true; } diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h index 387a7f4..f0c319b 100644 --- a/Source/cmGetSourceFilePropertyCommand.h +++ b/Source/cmGetSourceFilePropertyCommand.h @@ -8,26 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetSourceFilePropertyCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetSourceFilePropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 07aaf02..7f5df9c 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -11,32 +12,31 @@ #include "cmTarget.h" #include "cmTargetPropertyComputer.h" -class cmExecutionStatus; class cmMessenger; -// cmSetTargetPropertyCommand -bool cmGetTargetPropertyCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmGetTargetPropertyCommand(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& var = args[0]; std::string const& targetName = args[1]; std::string prop; bool prop_exists = false; + cmMakefile& mf = status.GetMakefile(); - if (cmTarget* tgt = this->Makefile->FindTargetToUse(targetName)) { + if (cmTarget* tgt = mf.FindTargetToUse(targetName)) { if (args[2] == "ALIASED_TARGET") { - if (this->Makefile->IsAlias(targetName)) { + if (mf.IsAlias(targetName)) { prop = tgt->GetName(); prop_exists = true; } } else if (!args[2].empty()) { const char* prop_cstr = nullptr; - cmListFileBacktrace bt = this->Makefile->GetBacktrace(); - cmMessenger* messenger = this->Makefile->GetMessenger(); + cmListFileBacktrace bt = mf.GetBacktrace(); + cmMessenger* messenger = mf.GetMessenger(); if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2], messenger, bt)) { prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt); @@ -53,7 +53,7 @@ bool cmGetTargetPropertyCommand::InitialPass( bool issueMessage = false; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0045)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0045)) { case cmPolicies::WARN: issueMessage = true; e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0045) << "\n"; @@ -68,16 +68,16 @@ bool cmGetTargetPropertyCommand::InitialPass( if (issueMessage) { e << "get_target_property() called with non-existent target \"" << targetName << "\"."; - this->Makefile->IssueMessage(messageType, e.str()); + mf.IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } } } if (prop_exists) { - this->Makefile->AddDefinition(var, prop); + mf.AddDefinition(var, prop); return true; } - this->Makefile->AddDefinition(var, var + "-NOTFOUND"); + mf.AddDefinition(var, var + "-NOTFOUND"); return true; } diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h index 1a53195..c13078f 100644 --- a/Source/cmGetTargetPropertyCommand.h +++ b/Source/cmGetTargetPropertyCommand.h @@ -8,26 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetTargetPropertyCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetTargetPropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmGetTargetPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx index 0b0d6eb..cf8c1d5 100644 --- a/Source/cmGetTestPropertyCommand.cxx +++ b/Source/cmGetTestPropertyCommand.cxx @@ -2,33 +2,32 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGetTestPropertyCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmTest.h" -class cmExecutionStatus; - -// cmGetTestPropertyCommand -bool cmGetTestPropertyCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmGetTestPropertyCommand(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& testName = args[0]; std::string const& var = args[2]; - cmTest* test = this->Makefile->GetTest(testName); + cmMakefile& mf = status.GetMakefile(); + cmTest* test = mf.GetTest(testName); if (test) { const char* prop = nullptr; if (!args[1].empty()) { prop = test->GetProperty(args[1]); } if (prop) { - this->Makefile->AddDefinition(var, prop); + mf.AddDefinition(var, prop); return true; } } - this->Makefile->AddDefinition(var, "NOTFOUND"); + mf.AddDefinition(var, "NOTFOUND"); return true; } diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h index a53a7f7..30beb8f 100644 --- a/Source/cmGetTestPropertyCommand.h +++ b/Source/cmGetTestPropertyCommand.h @@ -8,26 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetTestPropertyCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetTestPropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmGetTestPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 658f65d..09ed76d 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -177,8 +177,7 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout, void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config, const std::string& language) { - std::map<std::string, std::string>::iterator i = - this->FlagsByLanguage.find(language); + auto i = this->FlagsByLanguage.find(language); if (i == this->FlagsByLanguage.end()) { std::string flags; const char* lang = language.c_str(); @@ -209,8 +208,7 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config, std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language, std::string const& config) { - std::map<std::string, std::string>::iterator i = - this->DefinesByLanguage.find(language); + auto i = this->DefinesByLanguage.find(language); if (i == this->DefinesByLanguage.end()) { std::set<std::string> defines; const char* lang = language.c_str(); @@ -232,8 +230,7 @@ void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout, std::string const&, const std::string& language) { - std::map<std::string, std::string>::iterator flagsByLangI = - this->FlagsByLanguage.find(language); + auto flagsByLangI = this->FlagsByLanguage.find(language); if (flagsByLangI != this->FlagsByLanguage.end()) { if (!flagsByLangI->second.empty()) { std::vector<std::string> ghsCompFlags = diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 9479424..2273c50 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -5,13 +5,13 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstdio> +#include <cstdlib> #include <cstring> #include <initializer_list> #include <iterator> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #if defined(_WIN32) && !defined(__CYGWIN__) # include <windows.h> diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index d67c725..3075c1a 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -17,7 +17,7 @@ #include "cmAlgorithms.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" -#include "cmExportSetMap.h" +#include "cmExportSet.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -555,8 +555,6 @@ protected: cmTarget* FindTargetImpl(std::string const& name) const; cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const; - cmGeneratorTarget* FindImportedGeneratorTargetImpl( - std::string const& name) const; const char* GetPredefinedTargetsFolder(); diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 0b45f4b..236554f 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -18,9 +18,9 @@ #include "cmake.h" #include <algorithm> +#include <cstring> #include <map> #include <ostream> -#include <string.h> #include <utility> const char* cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj"; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 062eccb..7bba874 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -7,12 +7,12 @@ #include "cm_jsoncpp_writer.h" #include "cmsys/FStream.hxx" #include <algorithm> -#include <ctype.h> +#include <cctype> +#include <cstdio> #include <iterator> #include <sstream> -#include <stdio.h> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmDocumentationEntry.h" diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index f6d5998..7aa231e 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -228,7 +228,7 @@ public: return this->GG->ConvertToNinjaPath(path); } }; - MapToNinjaPathImpl MapToNinjaPath() { return MapToNinjaPathImpl(this); } + MapToNinjaPathImpl MapToNinjaPath() { return { this }; } // -- Additional clean files void AddAdditionalCleanFile(std::string fileName); diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 22c304e..0b211b8 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -7,7 +7,7 @@ #include <sstream> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmDocumentationEntry.h" @@ -291,8 +291,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // Sort the list and remove duplicates. std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>()); #if !defined(__VMS) // The Compaq STL on VMS crashes, so accept duplicates. - std::vector<std::string>::iterator new_end = - std::unique(lfiles.begin(), lfiles.end()); + auto new_end = std::unique(lfiles.begin(), lfiles.end()); lfiles.erase(new_end, lfiles.end()); #endif diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 264de54..6a39509 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -5,10 +5,10 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cstddef> #include <iosfwd> #include <map> #include <set> -#include <stddef.h> #include <string> #include <vector> diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index b355775..7faafba 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -11,10 +11,11 @@ #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmUuid.h" -#include "cm_string_view.hxx" #include "cmake.h" #include "cmsys/Encoding.hxx" +#include <cm/string_view> + #include <assert.h> #include <vector> #include <windows.h> @@ -662,10 +663,8 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( for (std::string const& i : configs) { const char* propertyValue = target->Target->GetMakefile()->GetDefinition(propertyName); - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(propertyValue); - if (cmIsOn(cge->Evaluate(target->GetLocalGenerator(), i))) { + if (cmIsOn(cmGeneratorExpression::Evaluate( + propertyValue, target->GetLocalGenerator(), i))) { activeConfigs.insert(i); } } diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 5e60108..f25d2e2 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGlobalVisualStudio8Generator.h" +#include "cmCustomCommand.h" +#include "cmCustomCommandLines.h" #include "cmDocumentationEntry.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" @@ -145,12 +147,8 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Add a custom prebuild target to run the VerifyGlobs script. cmake* cm = this->GetCMakeInstance(); if (cm->DoWriteGlobVerifyTarget()) { - cmCustomCommandLine verifyCommandLine; - verifyCommandLine.push_back(cmSystemTools::GetCMakeCommand()); - verifyCommandLine.push_back("-P"); - verifyCommandLine.push_back(cm->GetGlobVerifyScript()); - cmCustomCommandLines verifyCommandLines; - verifyCommandLines.push_back(verifyCommandLine); + cmCustomCommandLines verifyCommandLines = cmMakeSingleCommandLine( + { cmSystemTools::GetCMakeCommand(), "-P", cm->GetGlobVerifyScript() }); std::vector<std::string> byproducts; byproducts.push_back(cm->GetGlobVerifyStamp()); @@ -172,30 +170,25 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() listFiles.erase(new_end, listFiles.end()); // Create a rule to re-run CMake. - cmCustomCommandLine commandLine; - commandLine.push_back(cmSystemTools::GetCMakeCommand()); std::string argS = cmStrCat("-S", lg->GetSourceDirectory()); - commandLine.push_back(argS); std::string argB = cmStrCat("-B", lg->GetBinaryDirectory()); - commandLine.push_back(argB); - commandLine.push_back("--check-stamp-list"); - commandLine.push_back(stampList.c_str()); - commandLine.push_back("--vs-solution-file"); std::string const sln = lg->GetBinaryDirectory() + "/" + lg->GetProjectName() + ".sln"; - commandLine.push_back(sln); - cmCustomCommandLines commandLines; - commandLines.push_back(commandLine); + cmCustomCommandLines commandLines = cmMakeSingleCommandLine( + { cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list", + stampList, "--vs-solution-file", sln }); // Add the rule. Note that we cannot use the CMakeLists.txt // file as the main dependency because it would get // overwritten by the CreateVCProjBuildRule. // (this could be avoided with per-target source files) - std::string no_main_dependency; std::vector<std::string> no_byproducts; + std::string no_main_dependency; + cmImplicitDependsList no_implicit_depends; if (cmSourceFile* file = mf->AddCustomCommandToOutput( - stamps, no_byproducts, listFiles, no_main_dependency, commandLines, - "Checking Build System", no_working_directory, true, false)) { + stamps, no_byproducts, listFiles, no_main_dependency, + no_implicit_depends, commandLines, "Checking Build System", + no_working_directory, true, false)) { gt->AddSource(file->ResolveFullPath()); } else { cmSystemTools::Error("Error adding rule for " + stamps[0]); @@ -291,11 +284,9 @@ bool cmGlobalVisualStudio8Generator::DeployInhibited( cmGeneratorTarget const& target, const char* config) const { bool rVal = false; - if (const char* propStr = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propStr); - std::string prop = cge->Evaluate(target.LocalGenerator, config); - rVal = cmIsOn(prop); + if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) { + rVal = cmIsOn( + cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config)); } return rVal; } diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 6e0b804..108a44f 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -10,9 +10,11 @@ #include <shellapi.h> #include <windows.h> -#include "cmAlgorithms.h" +#include <cm/iterator> + #include "cmCallVisualStudioMacro.h" #include "cmCustomCommand.h" +#include "cmCustomCommandLines.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmLocalVisualStudioGenerator.h" @@ -899,18 +901,11 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( gt->LocalGenerator->ComputeObjectFilenames(mapping, gt); std::string obj_dir = gt->ObjectDirectory; std::string cmakeCommand = cmSystemTools::GetCMakeCommand(); - cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand); - cmCustomCommandLine cmdl; - cmdl.push_back(cmakeCommand); - cmdl.push_back("-E"); - cmdl.push_back("__create_def"); - cmdl.push_back(mdi->DefFile); std::string obj_dir_expanded = obj_dir; cmSystemTools::ReplaceString(obj_dir_expanded, this->GetCMakeCFGIntDir(), configName.c_str()); cmSystemTools::MakeDirectory(obj_dir_expanded); std::string const objs_file = obj_dir_expanded + "/objects.txt"; - cmdl.push_back(objs_file); cmGeneratedFileStream fout(objs_file.c_str()); if (!fout) { cmSystemTools::Error("could not open " + objs_file); @@ -948,8 +943,8 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( fout << i->GetFullPath() << "\n"; } - cmCustomCommandLines commandLines; - commandLines.push_back(cmdl); + cmCustomCommandLines commandLines = cmMakeSingleCommandLine( + { cmakeCommand, "-E", "__create_def", mdi->DefFile, objs_file }); cmCustomCommand command(gt->Target->GetMakefile(), outputs, empty, empty, commandLines, "Auto build dll exports", "."); commands.push_back(command); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 10f822f..2c3d3ad 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -3,18 +3,19 @@ #include "cmGlobalXCodeGenerator.h" #include "cmsys/RegularExpression.hxx" -#include <assert.h> +#include <cassert> +#include <cstdio> +#include <cstring> #include <iomanip> #include <sstream> -#include <stdio.h> -#include <string.h> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" +#include "cmCustomCommandLines.h" #include "cmDocumentationEntry.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" @@ -500,22 +501,18 @@ void cmGlobalXCodeGenerator::AddExtraTargets( const char* no_working_directory = nullptr; std::vector<std::string> no_depends; cmTarget* allbuild = mf->AddUtilityCommand( - "ALL_BUILD", cmMakefile::TargetOrigin::Generator, true, no_depends, - no_working_directory, "echo", "Build all projects"); + "ALL_BUILD", cmMakefile::TargetOrigin::Generator, true, + no_working_directory, no_depends, + cmMakeSingleCommandLine({ "echo", "Build all projects" })); cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root); root->AddGeneratorTarget(allBuildGt); // Add XCODE depend helper std::string dir = root->GetCurrentBinaryDirectory(); - cmCustomCommandLine makeHelper; - makeHelper.push_back("make"); - makeHelper.push_back("-C"); - makeHelper.push_back(dir); - makeHelper.push_back("-f"); - makeHelper.push_back(this->CurrentXCodeHackMakefile); - makeHelper.push_back("OBJDIR=$(OBJDIR)"); - makeHelper.push_back(""); // placeholder, see below + cmCustomCommandLines commandLines = cmMakeSingleCommandLine( + { "make", "-C", dir, "-f", this->CurrentXCodeHackMakefile, + "OBJDIR=$(OBJDIR)", /* placeholder, see below */ "" }); // Add ZERO_CHECK bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION"); @@ -530,7 +527,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( cmSystemTools::ReplaceString(file, "\\ ", " "); cmTarget* check = mf->AddUtilityCommand( CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmMakefile::TargetOrigin::Generator, - true, no_depends, no_working_directory, "make", "-f", file.c_str()); + true, no_working_directory, no_depends, + cmMakeSingleCommandLine({ "make", "-f", file })); cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root); root->AddGeneratorTarget(checkGt); @@ -555,10 +553,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( // this will make sure that when the next target is built // things are up-to-date if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - makeHelper.back() = // fill placeholder + commandLines.front().back() = // fill placeholder this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)"); - cmCustomCommandLines commandLines; - commandLines.push_back(makeHelper); std::vector<std::string> no_byproducts; gen->GetMakefile()->AddCustomCommandToTarget( target->GetName(), no_byproducts, no_depends, commandLines, @@ -582,10 +578,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( } // sort the array - std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>()); - std::vector<std::string>::iterator new_end = - std::unique(lfiles.begin(), lfiles.end()); - lfiles.erase(new_end, lfiles.end()); + std::sort(lfiles.begin(), lfiles.end()); + lfiles.erase(std::unique(lfiles.begin(), lfiles.end()), lfiles.end()); cmake* cm = this->GetCMakeInstance(); if (cm->DoWriteGlobVerifyTarget()) { @@ -1254,7 +1248,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - for (auto keySources : bundleFiles) { + for (auto const& keySources : bundleFiles) { cmXCodeObject* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); @@ -1302,7 +1296,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - for (auto keySources : bundleFiles) { + for (auto const& keySources : bundleFiles) { cmXCodeObject* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); @@ -1433,7 +1427,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase( void cmGlobalXCodeGenerator::CreateCustomCommands( cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, - std::vector<cmXCodeObject*> contentBuildPhases, + std::vector<cmXCodeObject*> const& contentBuildPhases, cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt) { std::vector<cmCustomCommand> const& prebuild = gtgt->GetPreBuildCommands(); @@ -1442,19 +1436,14 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( if (gtgt->GetType() == cmStateEnums::SHARED_LIBRARY && !gtgt->IsFrameworkOnApple()) { - cmCustomCommandLines cmd; - cmd.resize(1); - cmd[0].push_back(cmSystemTools::GetCMakeCommand()); - cmd[0].push_back("-E"); - cmd[0].push_back("cmake_symlink_library"); std::string str_file = cmStrCat("$<TARGET_FILE:", gtgt->GetName(), '>'); std::string str_so_file = cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>'); std::string str_link_file = cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>'); - cmd[0].push_back(str_file); - cmd[0].push_back(str_so_file); - cmd[0].push_back(str_link_file); + cmCustomCommandLines cmd = cmMakeSingleCommandLine( + { cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library", + str_file, str_so_file, str_link_file }); cmCustomCommand command(this->CurrentMakefile, std::vector<std::string>(), std::vector<std::string>(), @@ -2392,10 +2381,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, std::string attribute = prop.substr(16); this->FilterConfigurationAttribute(configName, attribute); if (!attribute.empty()) { - cmGeneratorExpression ge; - std::string processed = - ge.Parse(gtgt->GetProperty(prop)) - ->Evaluate(this->CurrentLocalGenerator, configName); + std::string processed = cmGeneratorExpression::Evaluate( + gtgt->GetProperty(prop), this->CurrentLocalGenerator, configName); buildSettings->AddAttribute(attribute, this->CreateString(processed)); } @@ -2629,8 +2616,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget( return nullptr; } - std::map<cmGeneratorTarget const*, cmXCodeObject*>::const_iterator const i = - this->XCodeObjectMap.find(t); + auto const i = this->XCodeObjectMap.find(t); if (i == this->XCodeObjectMap.end()) { return nullptr; } @@ -2910,8 +2896,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( } target += gtgt->GetName(); s = cmStrCat(target, '/', sg->GetFullName()); - std::map<std::string, cmXCodeObject*>::iterator it = - this->GroupNameMap.find(s); + auto it = this->GroupNameMap.find(s); if (it != this->GroupNameMap.end()) { return it->second; } @@ -2956,8 +2941,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( std::string curr_folder = cmStrCat(target, '/'); for (auto const& folder : cmTokenize(sg->GetFullName(), "\\")) { curr_folder += folder; - std::map<std::string, cmXCodeObject*>::iterator i_folder = - this->GroupNameMap.find(curr_folder); + auto const i_folder = this->GroupNameMap.find(curr_folder); // Create new folder if (i_folder == this->GroupNameMap.end()) { cmXCodeObject* group = this->CreatePBXGroup(tgroup, folder); @@ -3132,10 +3116,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( std::string attribute = var.substr(22); this->FilterConfigurationAttribute(config.first, attribute); if (!attribute.empty()) { - cmGeneratorExpression ge; - std::string processed = - ge.Parse(this->CurrentMakefile->GetDefinition(var)) - ->Evaluate(this->CurrentLocalGenerator, config.first); + std::string processed = cmGeneratorExpression::Evaluate( + this->CurrentMakefile->GetDefinition(var), + this->CurrentLocalGenerator, config.first); buildSettingsForCfg->AddAttribute(attribute, this->CreateString(processed)); } @@ -3269,8 +3252,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget( std::string trel = this->ConvertToRelativeForMake(tfull); // Add this target to the post-build phases of its dependencies. - std::map<std::string, cmXCodeObject::StringVec>::const_iterator y = - target->GetDependTargets().find(configName); + auto const y = target->GetDependTargets().find(configName); if (y != target->GetDependTargets().end()) { for (auto const& deptgt : y->second) { makefileStream << this->PostBuildMakeTarget(deptgt, configName) @@ -3290,8 +3272,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget( makefileStream << trel << ":"; // List dependencies if any exist. - std::map<std::string, cmXCodeObject::StringVec>::const_iterator x = - target->GetDependLibraries().find(configName); + auto const x = target->GetDependLibraries().find(configName); if (x != target->GetDependLibraries().end()) { for (auto const& deplib : x->second) { std::string file = this->ConvertToRelativeForMake(deplib); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 71446f9..af905d0 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -122,13 +122,11 @@ private: std::string RelativeToSource(const std::string& p); std::string RelativeToBinary(const std::string& p); std::string ConvertToRelativeForMake(std::string const& p); - void CreateCustomCommands(cmXCodeObject* buildPhases, - cmXCodeObject* sourceBuildPhase, - cmXCodeObject* headerBuildPhase, - cmXCodeObject* resourceBuildPhase, - std::vector<cmXCodeObject*> contentBuildPhases, - cmXCodeObject* frameworkBuildPhase, - cmGeneratorTarget* gtgt); + void CreateCustomCommands( + cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, + cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, + std::vector<cmXCodeObject*> const& contentBuildPhases, + cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt); std::string ComputeInfoPListLocation(cmGeneratorTarget* target); diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 9b58f61..e0d545d 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -368,8 +368,7 @@ void cmGraphVizWriter::WriteConnections( const std::string& targetName, std::set<std::string>& insertedNodes, std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const { - std::map<std::string, const cmGeneratorTarget*>::const_iterator targetPtrIt = - this->TargetPtrs.find(targetName); + auto targetPtrIt = this->TargetPtrs.find(targetName); if (targetPtrIt == this->TargetPtrs.end()) // not found at all { @@ -390,8 +389,7 @@ void cmGraphVizWriter::WriteConnections( for (auto const& llit : ll) { const std::string& libName = llit.first; - std::map<std::string, std::string>::const_iterator libNameIt = - this->TargetNamesNodes.find(libName); + auto libNameIt = this->TargetNamesNodes.find(libName); // can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used if (libNameIt == this->TargetNamesNodes.end()) { @@ -419,8 +417,7 @@ void cmGraphVizWriter::WriteDependerConnections( const std::string& targetName, std::set<std::string>& insertedNodes, std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const { - std::map<std::string, const cmGeneratorTarget*>::const_iterator targetPtrIt = - this->TargetPtrs.find(targetName); + auto targetPtrIt = this->TargetPtrs.find(targetName); if (targetPtrIt == this->TargetPtrs.end()) // not found at all { @@ -454,8 +451,7 @@ void cmGraphVizWriter::WriteDependerConnections( for (auto const& llit : ll) { if (llit.first == targetName) { // So this target links against targetName. - std::map<std::string, std::string>::const_iterator dependerNodeNameIt = - this->TargetNamesNodes.find(tptr.first); + auto dependerNodeNameIt = this->TargetNamesNodes.find(tptr.first); if (dependerNodeNameIt != this->TargetNamesNodes.end()) { std::string connectionName = @@ -487,8 +483,7 @@ void cmGraphVizWriter::WriteNode(const std::string& targetName, { if (insertedNodes.find(targetName) == insertedNodes.end()) { insertedNodes.insert(targetName); - std::map<std::string, std::string>::const_iterator nameIt = - this->TargetNamesNodes.find(targetName); + auto nameIt = this->TargetNamesNodes.find(targetName); str << " \"" << nameIt->second << "\" [ label=\"" << targetName << "\" shape=\"" << getShapeForTarget(target) << "\"];" << std::endl; @@ -556,8 +551,7 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt) } } - std::map<std::string, const cmGeneratorTarget*>::const_iterator tarIt = - this->TargetPtrs.find(libName); + auto tarIt = this->TargetPtrs.find(libName); if (tarIt == this->TargetPtrs.end()) { std::ostringstream ostr; ostr << this->GraphNodePrefix << cnt++; diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx index 190f2e3..2fa4b55 100644 --- a/Source/cmHexFileConverter.cxx +++ b/Source/cmHexFileConverter.cxx @@ -2,9 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmHexFileConverter.h" -#include <ctype.h> -#include <stdio.h> -#include <string.h> +#include <cctype> +#include <cstdio> +#include <cstring> #include "cmSystemTools.h" diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index f719041..b36d96b 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -2,9 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmIfCommand.h" -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/string_view> + #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index 876bd95..170aea1 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -7,24 +7,28 @@ #include <utility> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +static void GetIncludes(cmMakefile& mf, const std::string& arg, + std::vector<std::string>& incs); +static void NormalizeInclude(cmMakefile& mf, std::string& inc); -// cmIncludeDirectoryCommand -bool cmIncludeDirectoryCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmIncludeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; } - std::vector<std::string>::const_iterator i = args.begin(); + cmMakefile& mf = status.GetMakefile(); - bool before = this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE"); + auto i = args.begin(); + + bool before = mf.IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE"); bool system = false; if ((*i) == "BEFORE") { @@ -45,13 +49,13 @@ bool cmIncludeDirectoryCommand::InitialPass( continue; } if (i->empty()) { - this->SetError("given empty-string as include directory."); + status.SetError("given empty-string as include directory."); return false; } std::vector<std::string> includes; - this->GetIncludes(*i, includes); + GetIncludes(mf, *i, includes); if (before) { cmAppend(beforeIncludes, includes); @@ -64,9 +68,9 @@ bool cmIncludeDirectoryCommand::InitialPass( } std::reverse(beforeIncludes.begin(), beforeIncludes.end()); - this->Makefile->AddIncludeDirectories(afterIncludes); - this->Makefile->AddIncludeDirectories(beforeIncludes, before); - this->Makefile->AddSystemIncludeDirectories(systemIncludes); + mf.AddIncludeDirectories(afterIncludes); + mf.AddIncludeDirectories(beforeIncludes, before); + mf.AddSystemIncludeDirectories(systemIncludes); return true; } @@ -83,8 +87,8 @@ bool cmIncludeDirectoryCommand::InitialPass( // output from a program and passing it into a command the cleanup doesn't // always happen // -void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg, - std::vector<std::string>& incs) +static void GetIncludes(cmMakefile& mf, const std::string& arg, + std::vector<std::string>& incs) { // break apart any line feed arguments std::string::size_type pos = 0; @@ -92,7 +96,7 @@ void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg, while ((pos = arg.find('\n', lastPos)) != std::string::npos) { if (pos) { std::string inc = arg.substr(lastPos, pos); - this->NormalizeInclude(inc); + NormalizeInclude(mf, inc); if (!inc.empty()) { incs.push_back(std::move(inc)); } @@ -100,13 +104,13 @@ void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg, lastPos = pos + 1; } std::string inc = arg.substr(lastPos); - this->NormalizeInclude(inc); + NormalizeInclude(mf, inc); if (!inc.empty()) { incs.push_back(std::move(inc)); } } -void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc) +static void NormalizeInclude(cmMakefile& mf, std::string& inc) { std::string::size_type b = inc.find_first_not_of(" \r"); std::string::size_type e = inc.find_last_not_of(" \r"); @@ -119,13 +123,9 @@ void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc) if (!cmIsOff(inc)) { cmSystemTools::ConvertToUnixSlashes(inc); - - if (!cmSystemTools::FileIsFullPath(inc)) { - if (!cmGeneratorExpression::StartsWithGeneratorExpression(inc)) { - std::string tmp = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', inc); - inc = tmp; - } + if (!cmSystemTools::FileIsFullPath(inc) && + !cmGeneratorExpression::StartsWithGeneratorExpression(inc)) { + inc = cmStrCat(mf.GetCurrentSourceDirectory(), '/', inc); } } } diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h index 4df94eb..66caff7 100644 --- a/Source/cmIncludeDirectoryCommand.h +++ b/Source/cmIncludeDirectoryCommand.h @@ -8,40 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmIncludeDirectoryCommand - * \brief Add include directories to the build. - * - * cmIncludeDirectoryCommand is used to specify directory locations - * to search for included files. - */ -class cmIncludeDirectoryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmIncludeDirectoryCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - // used internally - void GetIncludes(const std::string& arg, std::vector<std::string>& incs); - void NormalizeInclude(std::string& inc); -}; +bool cmIncludeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx index 93134ad..fa1e8bc 100644 --- a/Source/cmIncludeExternalMSProjectCommand.cxx +++ b/Source/cmIncludeExternalMSProjectCommand.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmIncludeExternalMSProjectCommand.h" +#include "cmExecutionStatus.h" + #ifdef _WIN32 # include "cmGlobalGenerator.h" # include "cmMakefile.h" @@ -11,22 +13,20 @@ # include "cmake.h" #endif -class cmExecutionStatus; - -// cmIncludeExternalMSProjectCommand -bool cmIncludeExternalMSProjectCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("INCLUDE_EXTERNAL_MSPROJECT called with incorrect " - "number of arguments"); + status.SetError("INCLUDE_EXTERNAL_MSPROJECT called with incorrect " + "number of arguments"); return false; } + // only compile this for win32 to avoid coverage errors #ifdef _WIN32 - if (this->Makefile->GetDefinition("WIN32") || - this->Makefile->GetGlobalGenerator() - ->IsIncludeExternalMSProjectSupported()) { + cmMakefile& mf = status.GetMakefile(); + if (mf.GetDefinition("WIN32") || + mf.GetGlobalGenerator()->IsIncludeExternalMSProjectSupported()) { enum Doing { DoingNone, @@ -77,15 +77,15 @@ bool cmIncludeExternalMSProjectCommand::InitialPass( if (!customGuid.empty()) { std::string guidVariable = utility_name + "_GUID_CMAKE"; - this->Makefile->GetCMakeInstance()->AddCacheEntry( - guidVariable.c_str(), customGuid.c_str(), "Stored GUID", - cmStateEnums::INTERNAL); + mf.GetCMakeInstance()->AddCacheEntry(guidVariable.c_str(), + customGuid.c_str(), "Stored GUID", + cmStateEnums::INTERNAL); } // Create a target instance for this utility. - cmTarget* target = this->Makefile->AddNewTarget(cmStateEnums::UTILITY, - utility_name.c_str()); - if (this->Makefile->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + cmTarget* target = + mf.AddNewTarget(cmStateEnums::UTILITY, utility_name.c_str()); + if (mf.GetPropertyAsBool("EXCLUDE_FROM_ALL")) { target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h index 9f76576..1013c44 100644 --- a/Source/cmIncludeExternalMSProjectCommand.h +++ b/Source/cmIncludeExternalMSProjectCommand.h @@ -8,36 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmIncludeExternalMSProjectCommand - * \brief Specify an external MS project file for inclusion in the workspace. - * - * cmIncludeExternalMSProjectCommand is used to specify an externally - * generated Microsoft project file for inclusion in the default workspace - * generated by CMake. - */ -class cmIncludeExternalMSProjectCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmIncludeExternalMSProjectCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx index 073c95f..655ebd6 100644 --- a/Source/cmIncludeRegularExpressionCommand.cxx +++ b/Source/cmIncludeRegularExpressionCommand.cxx @@ -2,22 +2,22 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmIncludeRegularExpressionCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -// cmIncludeRegularExpressionCommand -bool cmIncludeRegularExpressionCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmIncludeRegularExpressionCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if ((args.empty()) || (args.size() > 2)) { - this->SetError("called with incorrect number of arguments"); + if (args.empty() || args.size() > 2) { + status.SetError("called with incorrect number of arguments"); return false; } - this->Makefile->SetIncludeRegularExpression(args[0].c_str()); + + cmMakefile& mf = status.GetMakefile(); + mf.SetIncludeRegularExpression(args[0].c_str()); if (args.size() > 1) { - this->Makefile->SetComplainRegularExpression(args[1]); + mf.SetComplainRegularExpression(args[1]); } return true; diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h index 1723c8b..ca152b0 100644 --- a/Source/cmIncludeRegularExpressionCommand.h +++ b/Source/cmIncludeRegularExpressionCommand.h @@ -8,35 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmIncludeRegularExpressionCommand - * \brief Set the regular expression for following #includes. - * - * cmIncludeRegularExpressionCommand is used to specify the regular expression - * that determines whether to follow a #include file in dependency checking. - */ -class cmIncludeRegularExpressionCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmIncludeRegularExpressionCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmIncludeRegularExpressionCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 9a78c49..27d0dfb 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -4,14 +4,15 @@ #include "cm_static_string_view.hxx" #include "cmsys/Glob.hxx" +#include <cm/memory> +#include <cstddef> #include <set> #include <sstream> -#include <stddef.h> #include <utility> #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmExportSet.h" -#include "cmExportSetMap.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallCommandArguments.h" @@ -27,13 +28,61 @@ #include "cmPolicies.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmSubcommandTable.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" -class cmExecutionStatus; +namespace { -static cmInstallTargetGenerator* CreateInstallTargetGenerator( +class Helper +{ +public: + Helper(cmExecutionStatus& status) + : Status(status) + , Makefile(&status.GetMakefile()) + { + this->DefaultComponentName = this->Makefile->GetSafeDefinition( + "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + if (this->DefaultComponentName.empty()) { + this->DefaultComponentName = "Unspecified"; + } + } + + void SetError(std::string const& err) { this->Status.SetError(err); } + + bool MakeFilesFullPath(const char* modeName, + const std::vector<std::string>& relFiles, + std::vector<std::string>& absFiles); + bool CheckCMP0006(bool& failure); + + std::string GetDestination(const cmInstallCommandArguments* args, + const std::string& varName, + const std::string& guess); + std::string GetRuntimeDestination(const cmInstallCommandArguments* args); + std::string GetSbinDestination(const cmInstallCommandArguments* args); + std::string GetArchiveDestination(const cmInstallCommandArguments* args); + std::string GetLibraryDestination(const cmInstallCommandArguments* args); + std::string GetIncludeDestination(const cmInstallCommandArguments* args); + std::string GetSysconfDestination(const cmInstallCommandArguments* args); + std::string GetSharedStateDestination(const cmInstallCommandArguments* args); + std::string GetLocalStateDestination(const cmInstallCommandArguments* args); + std::string GetRunStateDestination(const cmInstallCommandArguments* args); + std::string GetDataRootDestination(const cmInstallCommandArguments* args); + std::string GetDataDestination(const cmInstallCommandArguments* args); + std::string GetInfoDestination(const cmInstallCommandArguments* args); + std::string GetLocaleDestination(const cmInstallCommandArguments* args); + std::string GetManDestination(const cmInstallCommandArguments* args); + std::string GetDocDestination(const cmInstallCommandArguments* args); + std::string GetDestinationForType(const cmInstallCommandArguments* args, + const std::string& type); + + cmExecutionStatus& Status; + cmMakefile* Makefile; + std::string DefaultComponentName; +}; + +cmInstallTargetGenerator* CreateInstallTargetGenerator( cmTarget& target, const cmInstallCommandArguments& args, bool impLib, cmListFileBacktrace const& backtrace, const std::string& destination, bool forceOpt = false, bool namelink = false) @@ -52,7 +101,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator( return g; } -static cmInstallTargetGenerator* CreateInstallTargetGenerator( +cmInstallTargetGenerator* CreateInstallTargetGenerator( cmTarget& target, const cmInstallCommandArguments& args, bool impLib, cmListFileBacktrace const& backtrace, bool forceOpt = false, bool namelink = false) @@ -62,7 +111,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator( namelink); } -static cmInstallFilesGenerator* CreateInstallFilesGenerator( +cmInstallFilesGenerator* CreateInstallFilesGenerator( cmMakefile* mf, const std::vector<std::string>& absFiles, const cmInstallCommandArguments& args, bool programs, const std::string& destination) @@ -75,7 +124,7 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator( args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional()); } -static cmInstallFilesGenerator* CreateInstallFilesGenerator( +cmInstallFilesGenerator* CreateInstallFilesGenerator( cmMakefile* mf, const std::vector<std::string>& absFiles, const cmInstallCommandArguments& args, bool programs) { @@ -83,68 +132,18 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator( args.GetDestination()); } -static const std::set<std::string> allowedTypes{ +std::set<std::string> const allowedTypes{ "BIN", "SBIN", "LIB", "INCLUDE", "SYSCONF", "SHAREDSTATE", "LOCALSTATE", "RUNSTATE", "DATA", "INFO", "LOCALE", "MAN", "DOC", }; -// cmInstallCommand -bool cmInstallCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool HandleScriptMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { - // Allow calling with no arguments so that arguments may be built up - // using a variable that may be left empty. - if (args.empty()) { - return true; - } - - // Enable the install target. - this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - - this->DefaultComponentName = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); - if (this->DefaultComponentName.empty()) { - this->DefaultComponentName = "Unspecified"; - } + Helper helper(status); - std::string const& mode = args[0]; - - // Switch among the command modes. - if (mode == "SCRIPT") { - return this->HandleScriptMode(args); - } - if (mode == "CODE") { - return this->HandleScriptMode(args); - } - if (mode == "TARGETS") { - return this->HandleTargetsMode(args); - } - if (mode == "FILES") { - return this->HandleFilesMode(args); - } - if (mode == "PROGRAMS") { - return this->HandleFilesMode(args); - } - if (mode == "DIRECTORY") { - return this->HandleDirectoryMode(args); - } - if (mode == "EXPORT") { - return this->HandleExportMode(args); - } - if (mode == "EXPORT_ANDROID_MK") { - return this->HandleExportAndroidMKMode(args); - } - - // Unknown mode. - std::string e = cmStrCat("called with unknown mode ", args[0]); - this->SetError(e); - return false; -} - -bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) -{ - std::string component = this->DefaultComponentName; + std::string component = helper.DefaultComponentName; int componentCount = 0; bool doing_script = false; bool doing_code = false; @@ -164,9 +163,9 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) } if (componentCount > 1) { - this->SetError("given more than one COMPONENT for the SCRIPT or CODE " - "signature of the INSTALL command. " - "Use multiple INSTALL commands with one COMPONENT each."); + status.SetError("given more than one COMPONENT for the SCRIPT or CODE " + "signature of the INSTALL command. " + "Use multiple INSTALL commands with one COMPONENT each."); return false; } @@ -188,40 +187,43 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) std::string script = arg; if (!cmSystemTools::FileIsFullPath(script)) { script = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', arg); + cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', arg); } if (cmSystemTools::FileIsDirectory(script)) { - this->SetError("given a directory as value of SCRIPT argument."); + status.SetError("given a directory as value of SCRIPT argument."); return false; } - this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator( + helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator( script.c_str(), false, component.c_str(), exclude_from_all)); } else if (doing_code) { doing_code = false; std::string const& code = arg; - this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator( + helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator( code.c_str(), true, component.c_str(), exclude_from_all)); } } if (doing_script) { - this->SetError("given no value for SCRIPT argument."); + status.SetError("given no value for SCRIPT argument."); return false; } if (doing_code) { - this->SetError("given no value for CODE argument."); + status.SetError("given no value for CODE argument."); return false; } // Tell the global generator about any installation component names // specified. - this->Makefile->GetGlobalGenerator()->AddInstallComponent(component); + helper.Makefile->GetGlobalGenerator()->AddInstallComponent(component); return true; } -bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) +bool HandleTargetsMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + // This is the TARGETS mode. std::vector<cmTarget*> targets; @@ -261,21 +263,21 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) std::vector<std::string> targetList; std::string exports; std::vector<std::string> unknownArgs; - cmInstallCommandArguments genericArgs(this->DefaultComponentName); + cmInstallCommandArguments genericArgs(helper.DefaultComponentName); genericArgs.Bind("TARGETS"_s, targetList); genericArgs.Bind("EXPORT"_s, exports); genericArgs.Parse(genericArgVector, &unknownArgs); bool success = genericArgs.Finalize(); - cmInstallCommandArguments archiveArgs(this->DefaultComponentName); - cmInstallCommandArguments libraryArgs(this->DefaultComponentName); - cmInstallCommandArguments runtimeArgs(this->DefaultComponentName); - cmInstallCommandArguments objectArgs(this->DefaultComponentName); - cmInstallCommandArguments frameworkArgs(this->DefaultComponentName); - cmInstallCommandArguments bundleArgs(this->DefaultComponentName); - cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName); - cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName); - cmInstallCommandArguments resourceArgs(this->DefaultComponentName); + cmInstallCommandArguments archiveArgs(helper.DefaultComponentName); + cmInstallCommandArguments libraryArgs(helper.DefaultComponentName); + cmInstallCommandArguments runtimeArgs(helper.DefaultComponentName); + cmInstallCommandArguments objectArgs(helper.DefaultComponentName); + cmInstallCommandArguments frameworkArgs(helper.DefaultComponentName); + cmInstallCommandArguments bundleArgs(helper.DefaultComponentName); + cmInstallCommandArguments privateHeaderArgs(helper.DefaultComponentName); + cmInstallCommandArguments publicHeaderArgs(helper.DefaultComponentName); + cmInstallCommandArguments resourceArgs(helper.DefaultComponentName); cmInstallCommandIncludesArgument includesArgs; // now parse the args for specific parts of the target (e.g. LIBRARY, @@ -293,9 +295,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - std::ostringstream e; - e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given unknown argument \"", unknownArgs[0], "\".")); return false; } @@ -330,7 +331,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() || publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) { - this->SetError( + status.SetError( "TARGETS given NAMELINK_ONLY option not in LIBRARY group. " "The NAMELINK_ONLY option may be specified only following LIBRARY."); return false; @@ -339,7 +340,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() || publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) { - this->SetError( + status.SetError( "TARGETS given NAMELINK_SKIP option not in LIBRARY group. " "The NAMELINK_SKIP option may be specified only following LIBRARY."); return false; @@ -352,15 +353,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) privateHeaderArgs.HasNamelinkComponent() || publicHeaderArgs.HasNamelinkComponent() || resourceArgs.HasNamelinkComponent()) { - this->SetError( + status.SetError( "TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. " "The NAMELINK_COMPONENT option may be specified only following " "LIBRARY."); return false; } if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) { - this->SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. " - "At most one of these two options may be specified."); + status.SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. " + "At most one of these two options may be specified."); return false; } if (!genericArgs.GetType().empty() || !archiveArgs.GetType().empty() || @@ -368,7 +369,7 @@ 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()) { - this->SetError( + status.SetError( "TARGETS given TYPE option. The TYPE option may only be specified in " " install(FILES) and install(DIRECTORIES)."); return false; @@ -390,18 +391,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) for (std::string const& tgt : targetList) { - if (this->Makefile->IsAlias(tgt)) { - std::ostringstream e; - e << "TARGETS given target \"" << tgt << "\" which is an alias."; - this->SetError(e.str()); + if (helper.Makefile->IsAlias(tgt)) { + status.SetError( + cmStrCat("TARGETS given target \"", tgt, "\" which is an alias.")); return false; } // Lookup this target in the current directory. - cmTarget* target = this->Makefile->FindLocalNonAliasTarget(tgt); + cmTarget* target = helper.Makefile->FindLocalNonAliasTarget(tgt); if (!target) { // If no local target has been found, find it in the global scope. cmTarget* const global_target = - this->Makefile->GetGlobalGenerator()->FindTarget(tgt, true); + helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true); if (global_target && !global_target->IsImported()) { target = global_target; } @@ -414,19 +414,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) target->GetType() != cmStateEnums::MODULE_LIBRARY && target->GetType() != cmStateEnums::OBJECT_LIBRARY && target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "TARGETS given target \"" << tgt - << "\" which is not an executable, library, or module."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given target \"", tgt, + "\" which is not an executable, library, or module.")); return false; } // Store the target in the list to be installed. targets.push_back(target); } else { // Did not find the target. - std::ostringstream e; - e << "TARGETS given target \"" << tgt << "\" which does not exist."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given target \"", tgt, "\" which does not exist.")); return false; } } @@ -477,20 +475,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (!archiveArgs.GetDestination().empty()) { // The import library uses the ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, true, this->Makefile->GetBacktrace()); + target, archiveArgs, true, helper.Makefile->GetBacktrace()); } if (!runtimeArgs.GetDestination().empty()) { // The DLL uses the RUNTIME properties. runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace()); + target, runtimeArgs, false, helper.Makefile->GetBacktrace()); } if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) { archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, true, this->Makefile->GetBacktrace(), - this->GetArchiveDestination(nullptr)); + target, archiveArgs, true, helper.Makefile->GetBacktrace(), + helper.GetArchiveDestination(nullptr)); runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace(), - this->GetRuntimeDestination(nullptr)); + target, runtimeArgs, false, helper.Makefile->GetBacktrace(), + helper.GetRuntimeDestination(nullptr)); } } else { // This is a non-DLL platform. @@ -505,28 +503,27 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) { frameworkGenerator = CreateInstallTargetGenerator( - target, frameworkArgs, false, this->Makefile->GetBacktrace()); + target, frameworkArgs, false, helper.Makefile->GetBacktrace()); } else { - std::ostringstream e; - e << "TARGETS given no FRAMEWORK DESTINATION for shared library " - "FRAMEWORK target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given no FRAMEWORK DESTINATION for shared " + "library FRAMEWORK target \"", + target.GetName(), "\".")); return false; } } else { // The shared library uses the LIBRARY properties. if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) { libraryGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace(), - this->GetLibraryDestination(&libraryArgs)); + target, libraryArgs, false, helper.Makefile->GetBacktrace(), + helper.GetLibraryDestination(&libraryArgs)); libraryGenerator->SetNamelinkMode( cmInstallTargetGenerator::NamelinkModeSkip); } if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) { namelinkGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace(), - this->GetLibraryDestination(&libraryArgs), false, true); + target, libraryArgs, false, helper.Makefile->GetBacktrace(), + helper.GetLibraryDestination(&libraryArgs), false, true); namelinkGenerator->SetNamelinkMode( cmInstallTargetGenerator::NamelinkModeOnly); } @@ -547,35 +544,34 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) { frameworkGenerator = CreateInstallTargetGenerator( - target, frameworkArgs, false, this->Makefile->GetBacktrace()); + target, frameworkArgs, false, helper.Makefile->GetBacktrace()); } else { - std::ostringstream e; - e << "TARGETS given no FRAMEWORK DESTINATION for static library " - "FRAMEWORK target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given no FRAMEWORK DESTINATION for static " + "library FRAMEWORK target \"", + target.GetName(), "\".")); return false; } } else { // Static libraries use ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, false, this->Makefile->GetBacktrace(), - this->GetArchiveDestination(&archiveArgs)); + target, archiveArgs, false, helper.Makefile->GetBacktrace(), + helper.GetArchiveDestination(&archiveArgs)); } } break; case cmStateEnums::MODULE_LIBRARY: { // Modules use LIBRARY properties. if (!libraryArgs.GetDestination().empty()) { libraryGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace()); + target, libraryArgs, false, helper.Makefile->GetBacktrace()); libraryGenerator->SetNamelinkMode(namelinkMode); namelinkOnly = (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); } else { - std::ostringstream e; - e << "TARGETS given no LIBRARY DESTINATION for module target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given no LIBRARY DESTINATION for module " + "target \"", + target.GetName(), "\".")); return false; } } break; @@ -584,17 +580,16 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (!objectArgs.GetDestination().empty()) { // Verify that we know where the objects are to install them. std::string reason; - if (!this->Makefile->GetGlobalGenerator() + if (!helper.Makefile->GetGlobalGenerator() ->HasKnownObjectFileLocation(&reason)) { - std::ostringstream e; - e << "TARGETS given OBJECT library \"" << target.GetName() - << "\" whose objects may not be installed" << reason << "."; - this->SetError(e.str()); + status.SetError( + cmStrCat("TARGETS given OBJECT library \"", target.GetName(), + "\" whose objects may not be installed", reason, ".")); return false; } objectGenerator = CreateInstallTargetGenerator( - target, objectArgs, false, this->Makefile->GetBacktrace()); + target, objectArgs, false, helper.Makefile->GetBacktrace()); } else { // Installing an OBJECT library without a destination transforms // it to an INTERFACE library. It installs no files but can be @@ -606,31 +601,29 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Application bundles use the BUNDLE properties. if (!bundleArgs.GetDestination().empty()) { bundleGenerator = CreateInstallTargetGenerator( - target, bundleArgs, false, this->Makefile->GetBacktrace()); + target, bundleArgs, false, helper.Makefile->GetBacktrace()); } else if (!runtimeArgs.GetDestination().empty()) { bool failure = false; - if (this->CheckCMP0006(failure)) { + if (helper.CheckCMP0006(failure)) { // For CMake 2.4 compatibility fallback to the RUNTIME // properties. bundleGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace()); + target, runtimeArgs, false, helper.Makefile->GetBacktrace()); } else if (failure) { return false; } } if (!bundleGenerator) { - std::ostringstream e; - e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE " - "executable target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); + status.SetError(cmStrCat("TARGETS given no BUNDLE DESTINATION for " + "MACOSX_BUNDLE executable target \"", + target.GetName(), "\".")); return false; } } else { // Executables use the RUNTIME properties. runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace(), - this->GetRuntimeDestination(&runtimeArgs)); + target, runtimeArgs, false, helper.Makefile->GetBacktrace(), + helper.GetRuntimeDestination(&runtimeArgs)); } // On DLL platforms an executable may also have an import @@ -641,7 +634,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) target.IsExecutableWithExports()) { // The import library uses the ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, true, this->Makefile->GetBacktrace(), true); + target, archiveArgs, true, helper.Makefile->GetBacktrace(), true); } } break; case cmStateEnums::INTERFACE_LIBRARY: @@ -671,47 +664,47 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if ((files) && (*files)) { std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) { + if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) { return false; } // Create the files install generator. privateHeaderGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, privateHeaderArgs, false, - this->GetIncludeDestination(&privateHeaderArgs)); + helper.Makefile, absFiles, privateHeaderArgs, false, + helper.GetIncludeDestination(&privateHeaderArgs)); } files = target.GetProperty("PUBLIC_HEADER"); if ((files) && (*files)) { std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) { + if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) { return false; } // Create the files install generator. publicHeaderGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, publicHeaderArgs, false, - this->GetIncludeDestination(&publicHeaderArgs)); + helper.Makefile, absFiles, publicHeaderArgs, false, + helper.GetIncludeDestination(&publicHeaderArgs)); } files = target.GetProperty("RESOURCE"); if ((files) && (*files)) { std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) { + if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) { return false; } // Create the files install generator. if (!resourceArgs.GetDestination().empty()) { resourceGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, resourceArgs, false); + helper.Makefile, absFiles, resourceArgs, false); } else { - std::ostringstream e; - e << "INSTALL TARGETS - target " << target.GetName() << " has " - << "RESOURCE files but no RESOURCE DESTINATION."; - cmSystemTools::Message(e.str(), "Warning"); + cmSystemTools::Message( + cmStrCat("INSTALL TARGETS - target ", target.GetName(), + " has RESOURCE files but no RESOURCE DESTINATION."), + "Warning"); } } } @@ -730,21 +723,21 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) installsPublicHeader || publicHeaderGenerator != nullptr; installsResource = installsResource || resourceGenerator; - this->Makefile->AddInstallGenerator(archiveGenerator); - this->Makefile->AddInstallGenerator(libraryGenerator); - this->Makefile->AddInstallGenerator(namelinkGenerator); - this->Makefile->AddInstallGenerator(runtimeGenerator); - this->Makefile->AddInstallGenerator(objectGenerator); - this->Makefile->AddInstallGenerator(frameworkGenerator); - this->Makefile->AddInstallGenerator(bundleGenerator); - this->Makefile->AddInstallGenerator(privateHeaderGenerator); - this->Makefile->AddInstallGenerator(publicHeaderGenerator); - this->Makefile->AddInstallGenerator(resourceGenerator); + helper.Makefile->AddInstallGenerator(archiveGenerator); + helper.Makefile->AddInstallGenerator(libraryGenerator); + helper.Makefile->AddInstallGenerator(namelinkGenerator); + helper.Makefile->AddInstallGenerator(runtimeGenerator); + helper.Makefile->AddInstallGenerator(objectGenerator); + helper.Makefile->AddInstallGenerator(frameworkGenerator); + helper.Makefile->AddInstallGenerator(bundleGenerator); + helper.Makefile->AddInstallGenerator(privateHeaderGenerator); + helper.Makefile->AddInstallGenerator(publicHeaderGenerator); + helper.Makefile->AddInstallGenerator(resourceGenerator); // Add this install rule to an export if one was specified and // this is not a namelink-only rule. if (!exports.empty() && !namelinkOnly) { - cmTargetExport* te = new cmTargetExport; + auto te = cm::make_unique<cmTargetExport>(); te->TargetName = target.GetName(); te->ArchiveGenerator = archiveGenerator; te->BundleGenerator = bundleGenerator; @@ -753,66 +746,69 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) te->LibraryGenerator = libraryGenerator; te->RuntimeGenerator = runtimeGenerator; te->ObjectsGenerator = objectGenerator; - this->Makefile->GetGlobalGenerator() - ->GetExportSets()[exports] - ->AddTargetExport(te); - te->InterfaceIncludeDirectories = cmJoin(includesArgs.GetIncludeDirs(), ";"); + + helper.Makefile->GetGlobalGenerator() + ->GetExportSets()[exports] + .AddTargetExport(std::move(te)); } } // Tell the global generator about any installation component names // specified if (installsArchive) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( archiveArgs.GetComponent()); } if (installsLibrary) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( libraryArgs.GetComponent()); } if (installsNamelink) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( libraryArgs.GetNamelinkComponent()); } if (installsRuntime) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( runtimeArgs.GetComponent()); } if (installsObject) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( objectArgs.GetComponent()); } if (installsFramework) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( frameworkArgs.GetComponent()); } if (installsBundle) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( bundleArgs.GetComponent()); } if (installsPrivateHeader) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( privateHeaderArgs.GetComponent()); } if (installsPublicHeader) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( publicHeaderArgs.GetComponent()); } if (installsResource) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( resourceArgs.GetComponent()); } return true; } -bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) +bool HandleFilesMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + // This is the FILES mode. bool programs = (args[0] == "PROGRAMS"); - cmInstallCommandArguments ica(this->DefaultComponentName); + cmInstallCommandArguments ica(helper.DefaultComponentName); std::vector<std::string> files; ica.Bind(programs ? "PROGRAMS"_s : "FILES"_s, files); std::vector<std::string> unknownArgs; @@ -820,17 +816,15 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - std::ostringstream e; - e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\".")); return false; } std::string type = ica.GetType(); if (!type.empty() && allowedTypes.count(type) == 0) { - std::ostringstream e; - e << args[0] << " given non-type \"" << type << "\" with TYPE argument."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given non-type \"", type, "\" with TYPE argument.")); return false; } @@ -843,28 +837,27 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if (!ica.GetRename().empty() && filesVector.size() > 1) { // The rename option works only with one file. - std::ostringstream e; - e << args[0] << " given RENAME option with more than one file."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given RENAME option with more than one file.")); return false; } std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) { + if (!helper.MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) { return false; } - cmPolicies::PolicyStatus status = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0062); + cmPolicies::PolicyStatus policyStatus = + helper.Makefile->GetPolicyStatus(cmPolicies::CMP0062); - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = helper.Makefile->GetGlobalGenerator(); for (std::string const& file : filesVector) { if (gg->IsExportedTargetsFile(file)) { const char* modal = nullptr; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (status) { + switch (policyStatus) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0062) << "\n"; modal = "should"; @@ -884,7 +877,7 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) << " not be installed with the " "install() command. Use the install(EXPORT) mechanism " "instead. See the cmake-packages(7) manual for more.\n"; - this->Makefile->IssueMessage(messageType, e.str()); + helper.Makefile->IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -897,38 +890,36 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) } if (!type.empty() && !ica.GetDestination().empty()) { - std::ostringstream e; - e << args[0] - << " given both TYPE and DESTINATION arguments. You may only specify " - "one."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], + " given both TYPE and DESTINATION arguments. " + "You may only specify one.")); return false; } - std::string destination = this->GetDestinationForType(&ica, type); + std::string destination = helper.GetDestinationForType(&ica, type); if (destination.empty()) { // A destination is required. - std::ostringstream e; - e << args[0] << " given no DESTINATION!"; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } // Create the files install generator. - this->Makefile->AddInstallGenerator(CreateInstallFilesGenerator( - this->Makefile, absFiles, ica, programs, destination)); + helper.Makefile->AddInstallGenerator(CreateInstallFilesGenerator( + helper.Makefile, absFiles, ica, programs, destination)); // Tell the global generator about any installation component names // specified. - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( ica.GetComponent()); return true; } -bool cmInstallCommand::HandleDirectoryMode( - std::vector<std::string> const& args) +bool HandleDirectoryMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + enum Doing { DoingNone, @@ -953,16 +944,14 @@ bool cmInstallCommand::HandleDirectoryMode( std::string permissions_file; std::string permissions_dir; std::vector<std::string> configurations; - std::string component = this->DefaultComponentName; + std::string component = helper.DefaultComponentName; std::string literal_args; std::string type; for (unsigned int i = 1; i < args.size(); ++i) { if (args[i] == "DESTINATION") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -970,10 +959,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingDestination; } else if (args[i] == "TYPE") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -981,10 +968,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingType; } else if (args[i] == "OPTIONAL") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -993,10 +978,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (args[i] == "MESSAGE_NEVER") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1014,20 +997,16 @@ bool cmInstallCommand::HandleDirectoryMode( } else if (args[i] == "EXCLUDE") { // Add this property to the current match rule. if (!in_match_mode || doing == DoingPattern || doing == DoingRegex) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" before a PATTERN or REGEX is given."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" before a PATTERN or REGEX is given.")); return false; } literal_args += " EXCLUDE"; doing = DoingNone; } else if (args[i] == "PERMISSIONS") { if (!in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" before a PATTERN or REGEX is given."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" before a PATTERN or REGEX is given.")); return false; } @@ -1036,10 +1015,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingPermsMatch; } else if (args[i] == "FILE_PERMISSIONS") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1047,10 +1024,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingPermsFile; } else if (args[i] == "DIRECTORY_PERMISSIONS") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1058,10 +1033,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingPermsDir; } else if (args[i] == "USE_SOURCE_PERMISSIONS") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1070,10 +1043,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (args[i] == "FILES_MATCHING") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1082,10 +1053,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (args[i] == "CONFIGURATIONS") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1093,10 +1062,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingConfigurations; } else if (args[i] == "COMPONENT") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1104,10 +1071,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingComponent; } else if (args[i] == "EXCLUDE_FROM_ALL") { if (in_match_mode) { - std::ostringstream e; - e << args[0] << " does not allow \"" << args[i] - << "\" after PATTERN or REGEX."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } exclude_from_all = true; @@ -1118,16 +1083,14 @@ bool cmInstallCommand::HandleDirectoryMode( std::string::size_type gpos = cmGeneratorExpression::Find(dir); if (gpos != 0 && !cmSystemTools::FileIsFullPath(dir)) { dir = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', args[i]); + cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', args[i]); } // Make sure the name is a directory. if (cmSystemTools::FileExists(dir) && !cmSystemTools::FileIsDirectory(dir)) { - std::ostringstream e; - e << args[0] << " given non-directory \"" << args[i] - << "\" to install."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given non-directory \"", args[i], + "\" to install.")); return false; } @@ -1140,10 +1103,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (doing == DoingType) { if (allowedTypes.count(args[i]) == 0) { - std::ostringstream e; - e << args[0] << " given non-type \"" << args[i] - << "\" with TYPE argument."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given non-type \"", args[i], + "\" with TYPE argument.")); return false; } @@ -1179,36 +1140,30 @@ bool cmInstallCommand::HandleDirectoryMode( // Check the requested permission. if (!cmInstallCommandArguments::CheckPermissions(args[i], permissions_file)) { - std::ostringstream e; - e << args[0] << " given invalid file permission \"" << args[i] - << "\"."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given invalid file permission \"", + args[i], "\".")); return false; } } else if (doing == DoingPermsDir) { // Check the requested permission. if (!cmInstallCommandArguments::CheckPermissions(args[i], permissions_dir)) { - std::ostringstream e; - e << args[0] << " given invalid directory permission \"" << args[i] - << "\"."; - this->SetError(e.str()); + status.SetError(cmStrCat( + args[0], " given invalid directory permission \"", args[i], "\".")); return false; } } else if (doing == DoingPermsMatch) { // Check the requested permission. if (!cmInstallCommandArguments::CheckPermissions(args[i], literal_args)) { - std::ostringstream e; - e << args[0] << " given invalid permission \"" << args[i] << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given invalid permission \"", args[i], "\".")); return false; } } else { // Unknown argument. - std::ostringstream e; - e << args[0] << " given unknown argument \"" << args[i] << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given unknown argument \"", args[i], "\".")); return false; } } @@ -1226,44 +1181,42 @@ bool cmInstallCommand::HandleDirectoryMode( if (!destination) { if (type.empty()) { // A destination is required. - std::ostringstream e; - e << args[0] << " given no DESTINATION!"; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } - destinationStr = this->GetDestinationForType(nullptr, type); + destinationStr = helper.GetDestinationForType(nullptr, type); destination = destinationStr.c_str(); } else if (!type.empty()) { - std::ostringstream e; - e << args[0] - << " given both TYPE and DESTINATION arguments. You may only specify " - "one."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], + " given both TYPE and DESTINATION " + "arguments. You may only specify one.")); return false; } cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never); + cmInstallGenerator::SelectMessageLevel(helper.Makefile, message_never); // Create the directory install generator. - this->Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator( + helper.Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator( dirs, destination, permissions_file.c_str(), permissions_dir.c_str(), configurations, component.c_str(), message, exclude_from_all, literal_args.c_str(), optional)); // Tell the global generator about any installation component names // specified. - this->Makefile->GetGlobalGenerator()->AddInstallComponent(component); + helper.Makefile->GetGlobalGenerator()->AddInstallComponent(component); return true; } -bool cmInstallCommand::HandleExportAndroidMKMode( - std::vector<std::string> const& args) +bool HandleExportAndroidMKMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { #ifndef CMAKE_BOOTSTRAP + Helper helper(status); + // This is the EXPORT mode. - cmInstallCommandArguments ica(this->DefaultComponentName); + cmInstallCommandArguments ica(helper.DefaultComponentName); std::string exp; std::string name_space; @@ -1280,9 +1233,8 @@ bool cmInstallCommand::HandleExportAndroidMKMode( if (!unknownArgs.empty()) { // Unknown argument. - std::ostringstream e; - e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\".")); return false; } @@ -1293,39 +1245,35 @@ bool cmInstallCommand::HandleExportAndroidMKMode( // Make sure there is a destination. if (ica.GetDestination().empty()) { // A destination is required. - std::ostringstream e; - e << args[0] << " given no DESTINATION!"; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } // Check the file name. std::string fname = filename; if (fname.find_first_of(":/\\") != std::string::npos) { - std::ostringstream e; - e << args[0] << " given invalid export file name \"" << fname << "\". " - << "The FILE argument may not contain a path. " - << "Specify the path in the DESTINATION argument."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given invalid export file name \"", + fname, + "\". The FILE argument may not contain a path. " + "Specify the path in the DESTINATION argument.")); return false; } // Check the file extension. if (!fname.empty() && cmSystemTools::GetFilenameLastExtension(fname) != ".mk") { - std::ostringstream e; - e << args[0] << " given invalid export file name \"" << fname << "\". " - << "The FILE argument must specify a name ending in \".mk\"."; - this->SetError(e.str()); + status.SetError(cmStrCat( + args[0], " given invalid export file name \"", fname, + R"(". The FILE argument must specify a name ending in ".mk".)")); return false; } if (fname.find_first_of(":/\\") != std::string::npos) { - std::ostringstream e; - e << args[0] << " given export name \"" << exp << "\". " - << "This name cannot be safely converted to a file name. " - << "Specify a different export name or use the FILE option to set " - << "a file name explicitly."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given export name \"", exp, + "\". " + "This name cannot be safely converted to a file name. " + "Specify a different export name or use the FILE option to set " + "a file name explicitly.")); return false; } // Use the default name @@ -1333,32 +1281,35 @@ bool cmInstallCommand::HandleExportAndroidMKMode( fname = "Android.mk"; } - cmExportSet* exportSet = - this->Makefile->GetGlobalGenerator()->GetExportSets()[exp]; + cmExportSet& exportSet = + helper.Makefile->GetGlobalGenerator()->GetExportSets()[exp]; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); + cmInstallGenerator::SelectMessageLevel(helper.Makefile); // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), + &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), message, ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld, true); - this->Makefile->AddInstallGenerator(exportGenerator); + helper.Makefile->AddInstallGenerator(exportGenerator); return true; #else static_cast<void>(args); - this->SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake"); + status.SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake"); return false; #endif } -bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) +bool HandleExportMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + // This is the EXPORT mode. - cmInstallCommandArguments ica(this->DefaultComponentName); + cmInstallCommandArguments ica(helper.DefaultComponentName); std::string exp; std::string name_space; @@ -1375,9 +1326,8 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - std::ostringstream e; - e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\".")); return false; } @@ -1388,30 +1338,28 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) // Make sure there is a destination. if (ica.GetDestination().empty()) { // A destination is required. - std::ostringstream e; - e << args[0] << " given no DESTINATION!"; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } // Check the file name. std::string fname = filename; if (fname.find_first_of(":/\\") != std::string::npos) { - std::ostringstream e; - e << args[0] << " given invalid export file name \"" << fname << "\". " - << "The FILE argument may not contain a path. " - << "Specify the path in the DESTINATION argument."; - this->SetError(e.str()); + status.SetError(cmStrCat(args[0], " given invalid export file name \"", + fname, + "\". " + "The FILE argument may not contain a path. " + "Specify the path in the DESTINATION argument.")); return false; } // Check the file extension. if (!fname.empty() && cmSystemTools::GetFilenameLastExtension(fname) != ".cmake") { - std::ostringstream e; - e << args[0] << " given invalid export file name \"" << fname << "\". " - << "The FILE argument must specify a name ending in \".cmake\"."; - this->SetError(e.str()); + status.SetError( + cmStrCat(args[0], " given invalid export file name \"", fname, + "\". " + "The FILE argument must specify a name ending in \".cmake\".")); return false; } @@ -1420,55 +1368,53 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) fname = cmStrCat(exp, ".cmake"); if (fname.find_first_of(":/\\") != std::string::npos) { - std::ostringstream e; - e << args[0] << " given export name \"" << exp << "\". " - << "This name cannot be safely converted to a file name. " - << "Specify a different export name or use the FILE option to set " - << "a file name explicitly."; - this->SetError(e.str()); + status.SetError(cmStrCat( + args[0], " given export name \"", exp, + "\". " + "This name cannot be safely converted to a file name. " + "Specify a different export name or use the FILE option to set " + "a file name explicitly.")); return false; } } - cmExportSet* exportSet = - this->Makefile->GetGlobalGenerator()->GetExportSets()[exp]; + cmExportSet& exportSet = + helper.Makefile->GetGlobalGenerator()->GetExportSets()[exp]; if (exportOld) { - for (cmTargetExport* te : *exportSet->GetTargetExports()) { + for (auto const& te : exportSet.GetTargetExports()) { cmTarget* tgt = - this->Makefile->GetGlobalGenerator()->FindTarget(te->TargetName); + helper.Makefile->GetGlobalGenerator()->FindTarget(te->TargetName); const bool newCMP0022Behavior = (tgt && tgt->GetPolicyStatusCMP0022() != cmPolicies::WARN && tgt->GetPolicyStatusCMP0022() != cmPolicies::OLD); if (!newCMP0022Behavior) { - std::ostringstream e; - e << "INSTALL(EXPORT) given keyword \"" - << "EXPORT_LINK_INTERFACE_LIBRARIES" - << "\", but target \"" << te->TargetName - << "\" does not have policy CMP0022 set to NEW."; - this->SetError(e.str()); + status.SetError(cmStrCat( + "INSTALL(EXPORT) given keyword \"" + "EXPORT_LINK_INTERFACE_LIBRARIES\", but target \"", + te->TargetName, "\" does not have policy CMP0022 set to NEW.")); return false; } } } cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); + cmInstallGenerator::SelectMessageLevel(helper.Makefile); // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), + &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), message, ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld, false); - this->Makefile->AddInstallGenerator(exportGenerator); + helper.Makefile->AddInstallGenerator(exportGenerator); return true; } -bool cmInstallCommand::MakeFilesFullPath( - const char* modeName, const std::vector<std::string>& relFiles, - std::vector<std::string>& absFiles) +bool Helper::MakeFilesFullPath(const char* modeName, + const std::vector<std::string>& relFiles, + std::vector<std::string>& absFiles) { for (std::string const& relFile : relFiles) { std::string file = relFile; @@ -1480,9 +1426,8 @@ bool cmInstallCommand::MakeFilesFullPath( // Make sure the file is not a directory. if (gpos == std::string::npos && cmSystemTools::FileIsDirectory(file)) { - std::ostringstream e; - e << modeName << " given directory \"" << relFile << "\" to install."; - this->SetError(e.str()); + this->SetError( + cmStrCat(modeName, " given directory \"", relFile, "\" to install.")); return false; } // Store the file for installation. @@ -1491,7 +1436,7 @@ bool cmInstallCommand::MakeFilesFullPath( return true; } -bool cmInstallCommand::CheckCMP0006(bool& failure) +bool Helper::CheckCMP0006(bool& failure) { switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0006)) { case cmPolicies::WARN: @@ -1516,9 +1461,9 @@ bool cmInstallCommand::CheckCMP0006(bool& failure) return false; } -std::string cmInstallCommand::GetDestination( - const cmInstallCommandArguments* args, const std::string& varName, - const std::string& guess) +std::string Helper::GetDestination(const cmInstallCommandArguments* args, + const std::string& varName, + const std::string& guess) { if (args && !args->GetDestination().empty()) { return args->GetDestination(); @@ -1530,55 +1475,54 @@ std::string cmInstallCommand::GetDestination( return guess; } -std::string cmInstallCommand::GetRuntimeDestination( +std::string Helper::GetRuntimeDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_BINDIR", "bin"); } -std::string cmInstallCommand::GetSbinDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetSbinDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_SBINDIR", "sbin"); } -std::string cmInstallCommand::GetArchiveDestination( +std::string Helper::GetArchiveDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); } -std::string cmInstallCommand::GetLibraryDestination( +std::string Helper::GetLibraryDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); } -std::string cmInstallCommand::GetIncludeDestination( +std::string Helper::GetIncludeDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_INCLUDEDIR", "include"); } -std::string cmInstallCommand::GetSysconfDestination( +std::string Helper::GetSysconfDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_SYSCONFDIR", "etc"); } -std::string cmInstallCommand::GetSharedStateDestination( +std::string Helper::GetSharedStateDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_SHAREDSTATEDIR", "com"); } -std::string cmInstallCommand::GetLocalStateDestination( +std::string Helper::GetLocalStateDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LOCALSTATEDIR", "var"); } -std::string cmInstallCommand::GetRunStateDestination( +std::string Helper::GetRunStateDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_RUNSTATEDIR", @@ -1586,49 +1530,44 @@ std::string cmInstallCommand::GetRunStateDestination( "/run"); } -std::string cmInstallCommand::GetDataRootDestination( +std::string Helper::GetDataRootDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_DATAROOTDIR", "share"); } -std::string cmInstallCommand::GetDataDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetDataDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_DATADIR", this->GetDataRootDestination(nullptr)); } -std::string cmInstallCommand::GetInfoDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetInfoDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_INFODIR", this->GetDataRootDestination(nullptr) + "/info"); } -std::string cmInstallCommand::GetLocaleDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetLocaleDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LOCALEDIR", this->GetDataRootDestination(nullptr) + "/locale"); } -std::string cmInstallCommand::GetManDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetManDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_MANDIR", this->GetDataRootDestination(nullptr) + "/man"); } -std::string cmInstallCommand::GetDocDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetDocDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_DOCDIR", this->GetDataRootDestination(nullptr) + "/doc"); } -std::string cmInstallCommand::GetDestinationForType( +std::string Helper::GetDestinationForType( const cmInstallCommandArguments* args, const std::string& type) { if (args && !args->GetDestination().empty()) { @@ -1675,3 +1614,31 @@ std::string cmInstallCommand::GetDestinationForType( } return ""; } + +} // namespace + +bool cmInstallCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + // Allow calling with no arguments so that arguments may be built up + // using a variable that may be left empty. + if (args.empty()) { + return true; + } + + // Enable the install target. + status.GetMakefile().GetGlobalGenerator()->EnableInstallTarget(); + + static cmSubcommandTable const subcommand{ + { "SCRIPT"_s, HandleScriptMode }, + { "CODE"_s, HandleScriptMode }, + { "TARGETS"_s, HandleTargetsMode }, + { "FILES"_s, HandleFilesMode }, + { "PROGRAMS"_s, HandleFilesMode }, + { "DIRECTORY"_s, HandleDirectoryMode }, + { "EXPORT"_s, HandleExportMode }, + { "EXPORT_ANDROID_MK"_s, HandleExportAndroidMKMode }, + }; + + return subcommand(args[0], args, status); +} diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 28bf443..32f00ce 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -8,71 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmInstallCommandArguments; - -/** \class cmInstallCommand - * \brief Specifies where to install some files - * - * cmInstallCommand is a general-purpose interface command for - * specifying install rules. - */ -class cmInstallCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmInstallCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool HandleScriptMode(std::vector<std::string> const& args); - bool HandleTargetsMode(std::vector<std::string> const& args); - bool HandleFilesMode(std::vector<std::string> const& args); - bool HandleDirectoryMode(std::vector<std::string> const& args); - bool HandleExportMode(std::vector<std::string> const& args); - bool HandleExportAndroidMKMode(std::vector<std::string> const& args); - bool MakeFilesFullPath(const char* modeName, - const std::vector<std::string>& relFiles, - std::vector<std::string>& absFiles); - bool CheckCMP0006(bool& failure); - - std::string GetDestination(const cmInstallCommandArguments* args, - const std::string& varName, - const std::string& guess); - std::string GetRuntimeDestination(const cmInstallCommandArguments* args); - std::string GetSbinDestination(const cmInstallCommandArguments* args); - std::string GetArchiveDestination(const cmInstallCommandArguments* args); - std::string GetLibraryDestination(const cmInstallCommandArguments* args); - std::string GetIncludeDestination(const cmInstallCommandArguments* args); - std::string GetSysconfDestination(const cmInstallCommandArguments* args); - std::string GetSharedStateDestination(const cmInstallCommandArguments* args); - std::string GetLocalStateDestination(const cmInstallCommandArguments* args); - std::string GetRunStateDestination(const cmInstallCommandArguments* args); - std::string GetDataRootDestination(const cmInstallCommandArguments* args); - std::string GetDataDestination(const cmInstallCommandArguments* args); - std::string GetInfoDestination(const cmInstallCommandArguments* args); - std::string GetLocaleDestination(const cmInstallCommandArguments* args); - std::string GetManDestination(const cmInstallCommandArguments* args); - std::string GetDocDestination(const cmInstallCommandArguments* args); - std::string GetDestinationForType(const cmInstallCommandArguments* args, - const std::string& type); - std::string DefaultComponentName; -}; +bool cmInstallCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 1d8210c..259c7f7 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -9,8 +9,6 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <memory> - cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( std::vector<std::string> const& dirs, const char* dest, const char* file_permissions, const char* dir_permissions, @@ -64,10 +62,9 @@ void cmInstallDirectoryGenerator::GenerateScriptForConfig( std::ostream& os, const std::string& config, Indent indent) { std::vector<std::string> dirs; - cmGeneratorExpression ge; for (std::string const& d : this->Directories) { - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(d); - cmExpandList(cge->Evaluate(this->LocalGenerator, config), dirs); + cmExpandList( + cmGeneratorExpression::Evaluate(d, this->LocalGenerator, config), dirs); } // Make sure all dirs have absolute paths. @@ -97,6 +94,6 @@ void cmInstallDirectoryGenerator::AddDirectoryInstallRule( std::string cmInstallDirectoryGenerator::GetDestination( std::string const& config) const { - cmGeneratorExpression ge; - return ge.Parse(this->Destination)->Evaluate(this->LocalGenerator, config); + return cmGeneratorExpression::Evaluate(this->Destination, + this->LocalGenerator, config); } diff --git a/Source/cmInstallExportAndroidMKGenerator.cxx b/Source/cmInstallExportAndroidMKGenerator.cxx deleted file mode 100644 index e8de029..0000000 --- a/Source/cmInstallExportAndroidMKGenerator.cxx +++ /dev/null @@ -1,134 +0,0 @@ - -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmInstallExportAndroidMKGenerator.h" - -#include <stdio.h> - -#include "cmExportInstallFileGenerator.h" -#include "cmExportSet.h" -#include "cmGeneratedFileStream.h" -#include "cmGlobalGenerator.h" -#include "cmInstallFilesGenerator.h" -#include "cmInstallTargetGenerator.h" -#include "cmLocalGenerator.h" -#include "cmMakefile.h" -#include "cmMessageType.h" - -cmInstallExportAndroidMKGenerator::cmInstallExportAndroidMKGenerator( - cmExportSet* exportSet, const char* destination, - const char* file_permissions, std::vector<std::string> const& configurations, - const char* component, MessageLevel message, bool exclude_from_all, - const char* filename, const char* name_space, bool exportOld) - : cmInstallExportGenerator(exportSet, destination, file_permissions, - configurations, component, message, - exclude_from_all, filename, name_space, exportOld) -{ -} - -cmInstallExportAndroidMKGenerator::~cmInstallExportAndroidMKGenerator() -{ -} - -bool cmInstallExportAndroidMKGenerator::Compute(cmLocalGenerator* lg) -{ - this->LocalGenerator = lg; - this->ExportSet->Compute(lg); - return true; -} - -void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os) -{ - // Skip empty sets. - if (ExportSet->GetTargetExports()->empty()) { - std::ostringstream e; - e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName() - << "\""; - cmSystemTools::Error(e.str()); - return; - } - - // Create the temporary directory in which to store the files. - this->ComputeTempDir(); - cmSystemTools::MakeDirectory(this->TempDir.c_str()); - - // Construct a temporary location for the file. - this->MainImportFile = cmStrCat(this->TempDir, '/', this->FileName); - - // Generate the import file for this export set. - this->EFGen->SetExportFile(this->MainImportFile.c_str()); - this->EFGen->SetNamespace(this->Namespace); - this->EFGen->SetExportOld(this->ExportOld); - if (this->ConfigurationTypes->empty()) { - if (!this->ConfigurationName.empty()) { - this->EFGen->AddConfiguration(this->ConfigurationName); - } else { - this->EFGen->AddConfiguration(""); - } - } else { - for (std::string const& config : this->ConfigurationTypes) { - this->EFGen->AddConfiguration(config); - } - } - this->EFGen->GenerateImportFile(); - - // Perform the main install script generation. - this->cmInstallGenerator::GenerateScript(os); -} - -void cmInstallExportAndroidMKGenerator::GenerateScriptConfigs( - std::ostream& os, Indent const& indent) -{ - // Create the main install rules first. - this->cmInstallGenerator::GenerateScriptConfigs(os, indent); - - // Now create a configuration-specific install rule for the import - // file of each configuration. - std::vector<std::string> files; - for (auto const& pair : this->EFGen->GetConfigImportFiles()) { - files.push_back(pair.second); - std::string config_test = this->CreateConfigTest(pair.first); - os << indent << "if(" << config_test << ")\n"; - this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files, - false, this->FilePermissions.c_str(), nullptr, - nullptr, nullptr, indent.Next()); - os << indent << "endif()\n"; - files.clear(); - } -} - -void cmInstallExportAndroidMKGenerator::GenerateScriptActions( - std::ostream& os, Indent const& indent) -{ - // Remove old per-configuration export files if the main changes. - std::string installedDir = - cmStrCat("$ENV{DESTDIR}", - this->ConvertToAbsoluteDestination(this->Destination), '/'); - std::string installedFile = cmStrCat(installedDir, this->FileName); - os << indent << "if(EXISTS \"" << installedFile << "\")\n"; - Indent indentN = indent.Next(); - Indent indentNN = indentN.Next(); - Indent indentNNN = indentNN.Next(); - /* clang-format off */ - os << indentN << "file(DIFFERENT EXPORT_FILE_CHANGED FILES\n" - << indentN << " \"" << installedFile << "\"\n" - << indentN << " \"" << this->MainImportFile << "\")\n"; - os << indentN << "if(EXPORT_FILE_CHANGED)\n"; - os << indentNN << "file(GLOB OLD_CONFIG_FILES \"" << installedDir - << this->EFGen->GetConfigImportFileGlob() << "\")\n"; - os << indentNN << "if(OLD_CONFIG_FILES)\n"; - os << indentNNN << "message(STATUS \"Old export file \\\"" << installedFile - << "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n"; - os << indentNNN << "file(REMOVE ${OLD_CONFIG_FILES})\n"; - os << indentNN << "endif()\n"; - os << indentN << "endif()\n"; - os << indent << "endif()\n"; - /* clang-format on */ - - // Install the main export file. - std::vector<std::string> files; - files.push_back(this->MainImportFile); - this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files, - false, this->FilePermissions.c_str(), nullptr, nullptr, - nullptr, indent); -} diff --git a/Source/cmInstallExportAndroidMKGenerator.h b/Source/cmInstallExportAndroidMKGenerator.h deleted file mode 100644 index a92ff27..0000000 --- a/Source/cmInstallExportAndroidMKGenerator.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmInstallExportAndroidMKGenerator_h -#define cmInstallExportAndroidMKGenerator_h - -#include "cmInstallExportGenerator.h" - -class cmExportInstallFileGenerator; -class cmInstallFilesGenerator; -class cmInstallTargetGenerator; -class cmExportSet; -class cmMakefile; - -/** \class cmInstallExportAndroidMKGenerator - * \brief Generate rules for creating an export files. - */ -class cmInstallExportAndroidMKGenerator : public cmInstallExportGenerator -{ -public: - cmInstallExportAndroidMKGenerator( - cmExportSet* exportSet, const char* dest, const char* file_permissions, - const std::vector<std::string>& configurations, const char* component, - MessageLevel message, bool exclude_from_all, const char* filename, - const char* name_space, bool exportOld); - ~cmInstallExportAndroidMKGenerator(); - - bool Compute(cmLocalGenerator* lg) override; - -protected: - virtual void GenerateScript(std::ostream& os); - virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent); - virtual void GenerateScriptActions(std::ostream& os, Indent const& indent); - void GenerateImportFile(cmExportSet const* exportSet); - void GenerateImportFile(const char* config, cmExportSet const* exportSet); -}; - -#endif diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 0b3617b..cba68be 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -123,7 +123,7 @@ size_t cmInstallExportGenerator::GetMaxConfigLength() const void cmInstallExportGenerator::GenerateScript(std::ostream& os) { // Skip empty sets. - if (ExportSet->GetTargetExports()->empty()) { + if (ExportSet->GetTargetExports().empty()) { std::ostringstream e; e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName() << "\""; diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index e680066..3b9268a 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -8,8 +8,8 @@ #include "cmInstallGenerator.h" #include "cmScriptGenerator.h" +#include <cstddef> #include <iosfwd> -#include <stddef.h> #include <string> #include <vector> diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index 11687a8..d623943 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallFilesCommand.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -11,8 +12,6 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - static std::string FindInstallSource(cmMakefile& makefile, const char* name); static void CreateInstallGenerator(cmMakefile& makefile, std::string const& dest, @@ -20,16 +19,18 @@ static void CreateInstallGenerator(cmMakefile& makefile, static void FinalAction(cmMakefile& makefile, std::string const& dest, std::vector<std::string> const& args); -bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmInstallFilesCommand(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; } + cmMakefile& mf = status.GetMakefile(); + // Enable the install target. - this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); + mf.GetGlobalGenerator()->EnableInstallTarget(); std::string const& dest = args[0]; @@ -37,18 +38,18 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, std::vector<std::string> files; for (std::string const& arg : cmMakeRange(args).advance(2)) { // Find the source location for each file listed. - files.push_back(FindInstallSource(*this->Makefile, arg.c_str())); + files.push_back(FindInstallSource(mf, arg.c_str())); } - CreateInstallGenerator(*this->Makefile, dest, files); + CreateInstallGenerator(mf, dest, files); } else { std::vector<std::string> finalArgs(args.begin() + 1, args.end()); - this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) { FinalAction(makefile, dest, finalArgs); }); } - this->Makefile->GetGlobalGenerator()->AddInstallComponent( - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); + mf.GetGlobalGenerator()->AddInstallComponent( + mf.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); return true; } @@ -63,7 +64,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& dest, // two different options if (args.size() > 1) { // now put the files into the list - std::vector<std::string>::const_iterator s = args.begin(); + auto s = args.begin(); ++s; // for each argument, get the files for (; s != args.end(); ++s) { @@ -85,7 +86,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& dest, std::string const& regex = args[0]; cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), regex, files); - std::vector<std::string>::iterator s = files.begin(); + auto s = files.begin(); // for each argument, get the files for (; s != files.end(); ++s) { installFiles.push_back(FindInstallSource(makefile, s->c_str())); diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h index f9b84fd..f4ebbde 100644 --- a/Source/cmInstallFilesCommand.h +++ b/Source/cmInstallFilesCommand.h @@ -8,35 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmInstallFilesCommand - * \brief Specifies where to install some files - * - * cmInstallFilesCommand specifies the relative path where a list of - * files should be installed. - */ -class cmInstallFilesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmInstallFilesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmInstallFilesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index c4048d4..f5b69a5 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -6,8 +6,6 @@ #include "cmInstallType.h" #include "cmStringAlgorithms.h" -#include <memory> - class cmLocalGenerator; cmInstallFilesGenerator::cmInstallFilesGenerator( @@ -51,8 +49,8 @@ bool cmInstallFilesGenerator::Compute(cmLocalGenerator* lg) std::string cmInstallFilesGenerator::GetDestination( std::string const& config) const { - cmGeneratorExpression ge; - return ge.Parse(this->Destination)->Evaluate(this->LocalGenerator, config); + return cmGeneratorExpression::Evaluate(this->Destination, + this->LocalGenerator, config); } void cmInstallFilesGenerator::AddFilesInstallRule( @@ -82,10 +80,9 @@ void cmInstallFilesGenerator::GenerateScriptForConfig( std::ostream& os, const std::string& config, Indent indent) { std::vector<std::string> files; - cmGeneratorExpression ge; for (std::string const& f : this->Files) { - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(f); - cmExpandList(cge->Evaluate(this->LocalGenerator, config), files); + cmExpandList( + cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config), files); } this->AddFilesInstallRule(os, config, indent, files); } diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index 3eca0e0..6bb4409 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallProgramsCommand.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -10,30 +11,29 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - static void FinalAction(cmMakefile& makefile, std::string const& dest, std::vector<std::string> const& args); static std::string FindInstallSource(cmMakefile& makefile, const char* name); -// cmExecutableCommand -bool cmInstallProgramsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmInstallProgramsCommand(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; } + cmMakefile& mf = status.GetMakefile(); + // Enable the install target. - this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); + mf.GetGlobalGenerator()->EnableInstallTarget(); - this->Makefile->GetGlobalGenerator()->AddInstallComponent( - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); + mf.GetGlobalGenerator()->AddInstallComponent( + mf.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); std::string const& dest = args[0]; std::vector<std::string> const finalArgs(args.begin() + 1, args.end()); - this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) { FinalAction(makefile, dest, finalArgs); }); return true; @@ -52,7 +52,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& dest, // two different options if (args.size() > 1 || files_mode) { // for each argument, get the programs - std::vector<std::string>::const_iterator s = args.begin(); + auto s = args.begin(); if (files_mode) { // Skip the FILES argument in files mode. ++s; @@ -67,7 +67,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& dest, cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), args[0], programs); - std::vector<std::string>::iterator s = programs.begin(); + auto s = programs.begin(); // for each argument, get the programs for (; s != programs.end(); ++s) { files.push_back(FindInstallSource(makefile, s->c_str())); diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h index ccd621d..c567f3b 100644 --- a/Source/cmInstallProgramsCommand.h +++ b/Source/cmInstallProgramsCommand.h @@ -8,35 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmInstallProgramsCommand - * \brief Specifies where to install some programs - * - * cmInstallProgramsCommand specifies the relative path where a list of - * programs should be installed. - */ -class cmInstallProgramsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmInstallProgramsCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmInstallProgramsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index b7b7817..ea29455 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallScriptGenerator.h" -#include <memory> #include <ostream> #include <vector> @@ -79,11 +78,9 @@ void cmInstallScriptGenerator::GenerateScriptForConfig( std::ostream& os, const std::string& config, Indent indent) { if (this->AllowGenex) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(this->Script); this->AddScriptInstallRule(os, indent, - cge->Evaluate(this->LocalGenerator, config)); + cmGeneratorExpression::Evaluate( + this->Script, this->LocalGenerator, config)); } else { this->AddScriptInstallRule(os, indent, this->Script); } diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 7bbef35..0cd04cc 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -2,9 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallTargetGenerator.h" -#include <assert.h> +#include <cassert> #include <map> -#include <memory> #include <set> #include <sstream> #include <utility> @@ -375,9 +374,8 @@ void cmInstallTargetGenerator::GetInstallObjectNames( std::string cmInstallTargetGenerator::GetDestination( std::string const& config) const { - cmGeneratorExpression ge; - return ge.Parse(this->Destination) - ->Evaluate(this->Target->GetLocalGenerator(), config); + return cmGeneratorExpression::Evaluate( + this->Destination, this->Target->GetLocalGenerator(), config); } std::string cmInstallTargetGenerator::GetInstallFilename( diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx index ef07e2c..44f23a5 100644 --- a/Source/cmInstallTargetsCommand.cxx +++ b/Source/cmInstallTargetsCommand.cxx @@ -5,54 +5,54 @@ #include <unordered_map> #include <utility> +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmTarget.h" -class cmExecutionStatus; - -// cmExecutableCommand -bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmInstallTargetsCommand(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; } + cmMakefile& mf = status.GetMakefile(); + // Enable the install target. - this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); + mf.GetGlobalGenerator()->EnableInstallTarget(); - cmMakefile::cmTargetMap& tgts = this->Makefile->GetTargets(); - std::vector<std::string>::const_iterator s = args.begin(); + cmMakefile::cmTargetMap& tgts = mf.GetTargets(); + auto s = args.begin(); ++s; std::string runtime_dir = "/bin"; for (; s != args.end(); ++s) { if (*s == "RUNTIME_DIRECTORY") { ++s; if (s == args.end()) { - this->SetError("called with RUNTIME_DIRECTORY but no actual " - "directory"); + status.SetError("called with RUNTIME_DIRECTORY but no actual " + "directory"); return false; } runtime_dir = *s; } else { - cmMakefile::cmTargetMap::iterator ti = tgts.find(*s); + auto ti = tgts.find(*s); if (ti != tgts.end()) { ti->second.SetInstallPath(args[0]); ti->second.SetRuntimeInstallPath(runtime_dir); ti->second.SetHaveInstallRule(true); } else { std::string str = "Cannot find target: \"" + *s + "\" to install."; - this->SetError(str); + status.SetError(str); return false; } } } - this->Makefile->GetGlobalGenerator()->AddInstallComponent( - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); + mf.GetGlobalGenerator()->AddInstallComponent( + mf.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); return true; } diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h index 55e69ba..0c5850c 100644 --- a/Source/cmInstallTargetsCommand.h +++ b/Source/cmInstallTargetsCommand.h @@ -8,36 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmInstallTargetsCommand - * \brief Specifies where to install some targets - * - * cmInstallTargetsCommand specifies the relative path where a list of - * targets should be installed. The targets can be executables or - * libraries. - */ -class cmInstallTargetsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmInstallTargetsCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmInstallTargetsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx index 11f6efb..7d98b90 100644 --- a/Source/cmInstalledFile.cxx +++ b/Source/cmInstalledFile.cxx @@ -74,7 +74,7 @@ bool cmInstalledFile::HasProperty(const std::string& prop) const bool cmInstalledFile::GetProperty(const std::string& prop, std::string& value) const { - PropertyMapType::const_iterator i = this->Properties.find(prop); + auto i = this->Properties.find(prop); if (i == this->Properties.end()) { return false; } diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index 52e28d3..79180cb 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -32,7 +32,6 @@ #include <functional> #include <limits> #include <map> -#include <memory> #include <set> #include <string> #include <unordered_map> @@ -357,10 +356,8 @@ static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo, } // Remove any config specific variables from the output. - cmGeneratorExpression ge; - auto cge = ge.Parse(command); - const std::string& processed = cge->Evaluate(lg, config); - result[kCTEST_COMMAND] = processed; + result[kCTEST_COMMAND] = + cmGeneratorExpression::Evaluate(command, lg, config); // Build up the list of properties that may have been specified Json::Value properties = Json::arrayValue; @@ -369,9 +366,8 @@ static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo, entry[kKEY_KEY] = prop.first; // Remove config variables from the value too. - auto cge_value = ge.Parse(prop.second); - const std::string& processed_value = cge_value->Evaluate(lg, config); - entry[kVALUE_KEY] = processed_value; + entry[kVALUE_KEY] = + cmGeneratorExpression::Evaluate(prop.second, lg, config); properties.append(entry); } result[kPROPERTIES_KEY] = properties; diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index 57b69c8..2914046 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -11,17 +12,18 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +static void AddLinkDir(cmMakefile& mf, std::string const& dir, + std::vector<std::string>& directories); -// cmLinkDirectoriesCommand -bool cmLinkDirectoriesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmLinkDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; } - bool before = this->Makefile->IsOn("CMAKE_LINK_DIRECTORIES_BEFORE"); + cmMakefile& mf = status.GetMakefile(); + bool before = mf.IsOn("CMAKE_LINK_DIRECTORIES_BEFORE"); auto i = args.cbegin(); if ((*i) == "BEFORE") { @@ -34,16 +36,16 @@ bool cmLinkDirectoriesCommand::InitialPass( std::vector<std::string> directories; for (; i != args.cend(); ++i) { - this->AddLinkDir(*i, directories); + AddLinkDir(mf, *i, directories); } - this->Makefile->AddLinkDirectory(cmJoin(directories, ";"), before); + mf.AddLinkDirectory(cmJoin(directories, ";"), before); return true; } -void cmLinkDirectoriesCommand::AddLinkDir( - std::string const& dir, std::vector<std::string>& directories) +static void AddLinkDir(cmMakefile& mf, std::string const& dir, + std::vector<std::string>& directories) { std::string unixPath = dir; cmSystemTools::ConvertToUnixSlashes(unixPath); @@ -56,10 +58,10 @@ void cmLinkDirectoriesCommand::AddLinkDir( << " " << unixPath << "\n" << "as a link directory.\n"; /* clang-format on */ - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0015)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0015)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0015); - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); break; case cmPolicies::OLD: // OLD behavior does not convert @@ -67,7 +69,7 @@ void cmLinkDirectoriesCommand::AddLinkDir( case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0015); - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); CM_FALLTHROUGH; case cmPolicies::NEW: // NEW behavior converts @@ -75,9 +77,7 @@ void cmLinkDirectoriesCommand::AddLinkDir( break; } if (convertToAbsolute) { - std::string tmp = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', unixPath); - unixPath = tmp; + unixPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', unixPath); } } directories.push_back(unixPath); diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h index 1a439de..a7caa5c 100644 --- a/Source/cmLinkDirectoriesCommand.h +++ b/Source/cmLinkDirectoriesCommand.h @@ -8,41 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmLinkDirectoriesCommand - * \brief Define a list of directories containing files to link. - * - * cmLinkDirectoriesCommand is used to specify a list - * of directories containing files to link into executable(s). - * Note that the command supports the use of CMake built-in variables - * such as CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR. - */ -class cmLinkDirectoriesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmLinkDirectoriesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - void AddLinkDir(std::string const& dir, - std::vector<std::string>& directories); -}; +bool cmLinkDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx index 13f6bae..cb63ceb 100644 --- a/Source/cmLinkLibrariesCommand.cxx +++ b/Source/cmLinkLibrariesCommand.cxx @@ -2,39 +2,37 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmLinkLibrariesCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -// cmLinkLibrariesCommand -bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmLinkLibrariesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; } + cmMakefile& mf = status.GetMakefile(); // add libraries, note that there is an optional prefix // of debug and optimized than can be used - for (std::vector<std::string>::const_iterator i = args.begin(); - i != args.end(); ++i) { + for (auto i = args.begin(); i != args.end(); ++i) { if (*i == "debug") { ++i; if (i == args.end()) { - this->SetError("The \"debug\" argument must be followed by " - "a library"); + status.SetError("The \"debug\" argument must be followed by " + "a library"); return false; } - this->Makefile->AppendProperty("LINK_LIBRARIES", "debug"); + mf.AppendProperty("LINK_LIBRARIES", "debug"); } else if (*i == "optimized") { ++i; if (i == args.end()) { - this->SetError("The \"optimized\" argument must be followed by " - "a library"); + status.SetError("The \"optimized\" argument must be followed by " + "a library"); return false; } - this->Makefile->AppendProperty("LINK_LIBRARIES", "optimized"); + mf.AppendProperty("LINK_LIBRARIES", "optimized"); } - this->Makefile->AppendProperty("LINK_LIBRARIES", i->c_str()); + mf.AppendProperty("LINK_LIBRARIES", i->c_str()); } return true; diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h index 484ab0a..3412251 100644 --- a/Source/cmLinkLibrariesCommand.h +++ b/Source/cmLinkLibrariesCommand.h @@ -8,36 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmLinkLibrariesCommand - * \brief Specify a list of libraries to link into executables. - * - * cmLinkLibrariesCommand is used to specify a list of libraries to link - * into executable(s) or shared objects. The names of the libraries - * should be those defined by the LIBRARY(library) command(s). - */ -class cmLinkLibrariesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmLinkLibrariesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmLinkLibrariesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index 91c551f..0dc6236 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -4,10 +4,13 @@ #include "cmLinkLineComputer.h" #include <sstream> +#include <utility> #include <vector> #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" +#include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmOutputConverter.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" @@ -56,6 +59,15 @@ std::string cmLinkLineComputer::ConvertToLinkReference( std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) { std::string linkLibs; + std::vector<BT<std::string>> linkLibsList; + this->ComputeLinkLibs(cli, linkLibsList); + cli.AppendValues(linkLibs, linkLibsList); + return linkLibs; +} + +void cmLinkLineComputer::ComputeLinkLibs( + cmComputeLinkInformation& cli, std::vector<BT<std::string>>& linkLibraries) +{ using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); for (auto const& item : items) { @@ -63,16 +75,33 @@ std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { continue; } + + BT<std::string> linkLib; if (item.IsPath) { - linkLibs += cli.GetLibLinkFileFlag(); - linkLibs += + linkLib.Value += cli.GetLibLinkFileFlag(); + linkLib.Value += this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value)); } else { - linkLibs += item.Value; + linkLib.Value += item.Value; } - linkLibs += " "; + linkLib.Value += " "; + + const cmLinkImplementation* linkImpl = + cli.GetTarget()->GetLinkImplementation(cli.GetConfig()); + + for (const cmLinkImplItem& iter : linkImpl->Libraries) { + if (iter.Target != nullptr && + iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + std::string libPath = iter.Target->GetLocation(cli.GetConfig()); + if (item.Value == libPath) { + linkLib.Backtrace = iter.Backtrace; + break; + } + } + } + + linkLibraries.emplace_back(linkLib); } - return linkLibs; } std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input) @@ -101,8 +130,19 @@ std::string cmLinkLineComputer::ComputeLinkPath( std::string const& libPathTerminator) { std::string linkPath; + std::vector<BT<std::string>> linkPathList; + this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPathList); + cli.AppendValues(linkPath, linkPathList); + return linkPath; +} +void cmLinkLineComputer::ComputeLinkPath( + cmComputeLinkInformation& cli, std::string const& libPathFlag, + std::string const& libPathTerminator, std::vector<BT<std::string>>& linkPath) +{ if (cli.GetLinkLanguage() == "Swift") { + std::string linkPathNoBT; + for (const cmComputeLinkInformation::Item& item : cli.GetItems()) { const cmGeneratorTarget* target = item.Target; if (!target) { @@ -116,20 +156,23 @@ std::string cmLinkLineComputer::ComputeLinkPath( type = cmStateEnums::ImportLibraryArtifact; } - linkPath += cmStrCat(" ", libPathFlag, - item.Target->GetDirectory(cli.GetConfig(), type), - libPathTerminator, " "); + linkPathNoBT += cmStrCat( + " ", libPathFlag, item.Target->GetDirectory(cli.GetConfig(), type), + libPathTerminator, " "); } } - } - for (std::string const& libDir : cli.GetDirectories()) { - linkPath += - cmStrCat(" ", libPathFlag, this->ConvertToOutputForExisting(libDir), - libPathTerminator, " "); + if (!linkPathNoBT.empty()) { + linkPath.emplace_back(std::move(linkPathNoBT)); + } } - return linkPath; + for (BT<std::string> libDir : cli.GetDirectoriesWithBacktraces()) { + libDir.Value = cmStrCat(" ", libPathFlag, + this->ConvertToOutputForExisting(libDir.Value), + libPathTerminator, " "); + linkPath.emplace_back(libDir); + } } std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli) @@ -179,13 +222,30 @@ std::string cmLinkLineComputer::ComputeFrameworkPath( std::string cmLinkLineComputer::ComputeLinkLibraries( cmComputeLinkInformation& cli, std::string const& stdLibString) { - std::ostringstream fout; - fout << this->ComputeRPath(cli); + std::string linkLibraries; + std::vector<BT<std::string>> linkLibrariesList; + this->ComputeLinkLibraries(cli, stdLibString, linkLibrariesList); + cli.AppendValues(linkLibraries, linkLibrariesList); + return linkLibraries; +} + +void cmLinkLineComputer::ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) +{ + std::ostringstream rpathOut; + rpathOut << this->ComputeRPath(cli); + + std::string rpath = rpathOut.str(); + if (!rpath.empty()) { + linkLibraries.emplace_back(std::move(rpath)); + } // Write the library flags to the build rule. - fout << this->ComputeLinkLibs(cli); + this->ComputeLinkLibs(cli, linkLibraries); // Add the linker runtime search path if any. + std::ostringstream fout; std::string rpath_link = cli.GetRPathLinkString(); if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) { fout << cli.GetRPathLinkFlag(); @@ -198,7 +258,10 @@ std::string cmLinkLineComputer::ComputeLinkLibraries( fout << stdLibString << " "; } - return fout.str(); + std::string remainingLibs = fout.str(); + if (!remainingLibs.empty()) { + linkLibraries.emplace_back(remainingLibs); + } } std::string cmLinkLineComputer::GetLinkerLanguage(cmGeneratorTarget* target, diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h index 2355c32..f426976 100644 --- a/Source/cmLinkLineComputer.h +++ b/Source/cmLinkLineComputer.h @@ -7,12 +7,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> #include "cmStateDirectory.h" class cmComputeLinkInformation; class cmGeneratorTarget; class cmOutputConverter; +template <typename T> +class BT; class cmLinkLineComputer { @@ -34,17 +37,28 @@ public: std::string const& libPathFlag, std::string const& libPathTerminator); + void ComputeLinkPath(cmComputeLinkInformation& cli, + std::string const& libPathFlag, + std::string const& libPathTerminator, + std::vector<BT<std::string>>& linkPath); + std::string ComputeFrameworkPath(cmComputeLinkInformation& cli, std::string const& fwSearchFlag); - virtual std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, - std::string const& stdLibString); + std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, + std::string const& stdLibString); + + virtual void ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries); virtual std::string GetLinkerLanguage(cmGeneratorTarget* target, std::string const& config); protected: std::string ComputeLinkLibs(cmComputeLinkInformation& cli); + void ComputeLinkLibs(cmComputeLinkInformation& cli, + std::vector<BT<std::string>>& linkLibraries); std::string ComputeRPath(cmComputeLinkInformation& cli); std::string ConvertToOutputFormat(std::string const& input); diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 9c0e20f..d845652 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -4,13 +4,14 @@ #include "cmLinkLineDeviceComputer.h" #include <set> -#include <sstream> #include <utility> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateDirectory.h" @@ -67,12 +68,10 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( return false; } -std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( - cmComputeLinkInformation& cli, std::string const& stdLibString) +void cmLinkLineDeviceComputer::ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) { - // Write the library flags to the build rule. - std::ostringstream fout; - // Generate the unique set of link items when device linking. // The nvcc device linker is designed so that each static library // with device symbols only needs to be listed once as it doesn't @@ -82,6 +81,9 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); bool skipItemAfterFramework = false; + // Note: + // Any modification of this algorithm should be reflected also in + // cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions for (auto const& item : items) { if (skipItemAfterFramework) { skipItemAfterFramework = false; @@ -91,6 +93,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( if (item.Target) { bool skip = false; switch (item.Target->GetType()) { + case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: case cmStateEnums::INTERFACE_LIBRARY: skip = true; @@ -106,7 +109,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } } - std::string out; + BT<std::string> linkLib; if (item.IsPath) { // nvcc understands absolute paths to libraries ending in '.a' or '.lib'. // These should be passed to nvlink. Other extensions need to be left @@ -114,7 +117,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( // can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'. if (cmHasLiteralSuffix(item.Value, ".a") || cmHasLiteralSuffix(item.Value, ".lib")) { - out += this->ConvertToOutputFormat( + linkLib.Value += this->ConvertToOutputFormat( this->ConvertToLinkReference(item.Value)); } } else if (item.Value == "-framework") { @@ -123,19 +126,33 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( skipItemAfterFramework = true; continue; } else if (cmLinkItemValidForDevice(item.Value)) { - out += item.Value; + linkLib.Value += item.Value; } - if (emitted.insert(out).second) { - fout << out << " "; + if (emitted.insert(linkLib.Value).second) { + linkLib.Value += " "; + + const cmLinkImplementation* linkImpl = + cli.GetTarget()->GetLinkImplementation(cli.GetConfig()); + + for (const cmLinkImplItem& iter : linkImpl->Libraries) { + if (iter.Target != nullptr && + iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + std::string libPath = iter.Target->GetLocation(cli.GetConfig()); + if (item.Value == libPath) { + linkLib.Backtrace = iter.Backtrace; + break; + } + } + } + + linkLibraries.emplace_back(linkLib); } } if (!stdLibString.empty()) { - fout << stdLibString << " "; + linkLibraries.emplace_back(cmStrCat(stdLibString, ' ')); } - - return fout.str(); } std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*, diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h index 0ea5f69..a9b01cd 100644 --- a/Source/cmLinkLineDeviceComputer.h +++ b/Source/cmLinkLineDeviceComputer.h @@ -7,6 +7,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> #include "cmLinkLineComputer.h" @@ -15,6 +16,8 @@ class cmGeneratorTarget; class cmLocalGenerator; class cmOutputConverter; class cmStateDirectory; +template <typename T> +class BT; class cmLinkLineDeviceComputer : public cmLinkLineComputer { @@ -29,8 +32,9 @@ public: bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli); - std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, - std::string const& stdLibString) override; + void ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) override; std::string GetLinkerLanguage(cmGeneratorTarget* target, std::string const& config) override; diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h index 8b91162..c7453ea 100644 --- a/Source/cmLinkedTree.h +++ b/Source/cmLinkedTree.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <assert.h> +#include <cassert> #include <vector> /** diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 57eeedb..7bf35c3 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -4,19 +4,20 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> #include <cstddef> +#include <cstdio> +#include <cstdlib> // required for atoi #include <functional> #include <iterator> #include <set> #include <sstream> #include <stdexcept> -#include <stdio.h> -#include <stdlib.h> // required for atoi #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> + #include "cm_static_string_view.hxx" #include "cmAlgorithms.h" @@ -158,10 +159,8 @@ bool HandleGetCommand(std::vector<std::string> const& args, item = static_cast<int>(nitem) + item; } if (item < 0 || nitem <= static_cast<size_t>(item)) { - std::ostringstream str; - str << "index: " << item << " out of range (-" << nitem << ", " - << nitem - 1 << ")"; - status.SetError(str.str()); + status.SetError(cmStrCat("index: ", item, " out of range (-", nitem, + ", ", nitem - 1, ")")); return false; } value += varArgsExpanded[item]; @@ -338,8 +337,7 @@ bool HandleFindCommand(std::vector<std::string> const& args, return true; } - std::vector<std::string>::iterator it = - std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]); + auto it = std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]); if (it != varArgsExpanded.end()) { status.GetMakefile().AddDefinition( variableName, @@ -367,9 +365,7 @@ bool HandleInsertCommand(std::vector<std::string> const& args, if ((!GetList(varArgsExpanded, listName, status.GetMakefile()) || varArgsExpanded.empty()) && item != 0) { - std::ostringstream str; - str << "index: " << item << " out of range (0, 0)"; - status.SetError(str.str()); + status.SetError(cmStrCat("index: ", item, " out of range (0, 0)")); return false; } @@ -379,10 +375,9 @@ bool HandleInsertCommand(std::vector<std::string> const& args, item = static_cast<int>(nitem) + item; } if (item < 0 || nitem < static_cast<size_t>(item)) { - std::ostringstream str; - str << "index: " << item << " out of range (-" << varArgsExpanded.size() - << ", " << varArgsExpanded.size() << ")"; - status.SetError(str.str()); + status.SetError(cmStrCat("index: ", item, " out of range (-", + varArgsExpanded.size(), ", ", + varArgsExpanded.size(), ")")); return false; } } @@ -399,10 +394,8 @@ bool HandleJoinCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { if (args.size() != 4) { - std::ostringstream error; - error << "sub-command JOIN requires three arguments (" << args.size() - 1 - << " found)."; - status.SetError(error.str()); + status.SetError(cmStrCat("sub-command JOIN requires three arguments (", + args.size() - 1, " found).")); return false; } @@ -441,13 +434,12 @@ bool HandleRemoveItemCommand(std::vector<std::string> const& args, std::vector<std::string> remove(args.begin() + 2, args.end()); std::sort(remove.begin(), remove.end()); - std::vector<std::string>::const_iterator remEnd = - std::unique(remove.begin(), remove.end()); - std::vector<std::string>::const_iterator remBegin = remove.begin(); + auto remEnd = std::unique(remove.begin(), remove.end()); + auto remBegin = remove.begin(); - std::vector<std::string>::const_iterator argsEnd = + auto argsEnd = cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd)); - std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); + auto argsBegin = varArgsExpanded.cbegin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); status.GetMakefile().AddDefinition(listName, value); return true; @@ -491,9 +483,8 @@ bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args, return true; } - std::vector<std::string>::const_iterator argsEnd = - cmRemoveDuplicates(varArgsExpanded); - std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); + auto argsEnd = cmRemoveDuplicates(varArgsExpanded); + auto argsBegin = varArgsExpanded.cbegin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); status.GetMakefile().AddDefinition(listName, value); @@ -599,11 +590,9 @@ protected: index = static_cast<int>(count) + index; } if (index < 0 || count <= static_cast<std::size_t>(index)) { - std::ostringstream str; - str << "sub-command TRANSFORM, selector " << this->Tag - << ", index: " << index << " out of range (-" << count << ", " - << count - 1 << ")."; - throw transform_error(str.str()); + throw transform_error(cmStrCat( + "sub-command TRANSFORM, selector ", this->Tag, ", index: ", index, + " out of range (-", count, ", ", count - 1, ").")); } return index; } @@ -684,17 +673,14 @@ public: makefile->ClearMatches(); if (!this->ReplaceHelper.IsRegularExpressionValid()) { - std::ostringstream error; - error - << "sub-command TRANSFORM, action REPLACE: Failed to compile regex \"" - << arguments[0] << "\"."; - throw transform_error(error.str()); + throw transform_error( + cmStrCat("sub-command TRANSFORM, action REPLACE: Failed to compile " + "regex \"", + arguments[0], "\".")); } if (!this->ReplaceHelper.IsReplaceExpressionValid()) { - std::ostringstream error; - error << "sub-command TRANSFORM, action REPLACE: " - << this->ReplaceHelper.GetError() << "."; - throw transform_error(error.str()); + throw transform_error(cmStrCat("sub-command TRANSFORM, action REPLACE: ", + this->ReplaceHelper.GetError(), ".")); } } @@ -704,10 +690,8 @@ public: std::string output; if (!this->ReplaceHelper.Replace(input, output)) { - std::ostringstream error; - error << "sub-command TRANSFORM, action REPLACE: " - << this->ReplaceHelper.GetError() << "."; - throw transform_error(error.str()); + throw transform_error(cmStrCat("sub-command TRANSFORM, action REPLACE: ", + this->ReplaceHelper.GetError(), ".")); } return output; @@ -842,19 +826,17 @@ bool HandleTransformCommand(std::vector<std::string> const& args, auto descriptor = descriptors.find(args[index]); if (descriptor == descriptors.end()) { - std::ostringstream error; - error << " sub-command TRANSFORM, " << args[index] << " invalid action."; - status.SetError(error.str()); + status.SetError( + cmStrCat(" sub-command TRANSFORM, ", args[index], " invalid action.")); return false; } // Action arguments index += 1; if (args.size() < index + descriptor->Arity) { - std::ostringstream error; - error << "sub-command TRANSFORM, action " << descriptor->Name - << " expects " << descriptor->Arity << " argument(s)."; - status.SetError(error.str()); + status.SetError(cmStrCat("sub-command TRANSFORM, action ", + descriptor->Name, " expects ", descriptor->Arity, + " argument(s).")); return false; } @@ -884,10 +866,10 @@ bool HandleTransformCommand(std::vector<std::string> const& args, while (args.size() > index) { if ((args[index] == REGEX || args[index] == AT || args[index] == FOR) && command.Selector) { - std::ostringstream error; - error << "sub-command TRANSFORM, selector already specified (" - << command.Selector->Tag << ")."; - status.SetError(error.str()); + status.SetError( + cmStrCat("sub-command TRANSFORM, selector already specified (", + command.Selector->Tag, ").")); + return false; } @@ -901,11 +883,10 @@ bool HandleTransformCommand(std::vector<std::string> const& args, command.Selector = cm::make_unique<TransformSelectorRegex>(args[index]); if (!command.Selector->Validate()) { - std::ostringstream error; - error << "sub-command TRANSFORM, selector REGEX failed to compile " - "regex \""; - error << args[index] << "\"."; - status.SetError(error.str()); + status.SetError( + cmStrCat("sub-command TRANSFORM, selector REGEX failed to compile " + "regex \"", + args[index], "\".")); return false; } @@ -1023,11 +1004,9 @@ bool HandleTransformCommand(std::vector<std::string> const& args, continue; } - std::ostringstream error; - error << "sub-command TRANSFORM, '" - << cmJoin(cmMakeRange(args).advance(index), " ") - << "': unexpected argument(s)."; - status.SetError(error.str()); + status.SetError(cmStrCat("sub-command TRANSFORM, '", + cmJoin(cmMakeRange(args).advance(index), " "), + "': unexpected argument(s).")); return false; } @@ -1264,10 +1243,8 @@ bool HandleSublistCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { if (args.size() != 5) { - std::ostringstream error; - error << "sub-command SUBLIST requires four arguments (" << args.size() - 1 - << " found)."; - status.SetError(error.str()); + status.SetError(cmStrCat("sub-command SUBLIST requires four arguments (", + args.size() - 1, " found).")); return false; } @@ -1288,16 +1265,12 @@ bool HandleSublistCommand(std::vector<std::string> const& args, using size_type = decltype(varArgsExpanded)::size_type; if (start < 0 || size_type(start) >= varArgsExpanded.size()) { - std::ostringstream error; - error << "begin index: " << start << " is out of range 0 - " - << varArgsExpanded.size() - 1; - status.SetError(error.str()); + status.SetError(cmStrCat("begin index: ", start, " is out of range 0 - ", + varArgsExpanded.size() - 1)); return false; } if (length < -1) { - std::ostringstream error; - error << "length: " << length << " should be -1 or greater"; - status.SetError(error.str()); + status.SetError(cmStrCat("length: ", length, " should be -1 or greater")); return false; } @@ -1347,23 +1320,20 @@ bool HandleRemoveAtCommand(std::vector<std::string> const& args, item = static_cast<int>(nitem) + item; } if (item < 0 || nitem <= static_cast<size_t>(item)) { - std::ostringstream str; - str << "index: " << item << " out of range (-" << nitem << ", " - << nitem - 1 << ")"; - status.SetError(str.str()); + status.SetError(cmStrCat("index: ", item, " out of range (-", nitem, + ", ", nitem - 1, ")")); return false; } removed.push_back(static_cast<size_t>(item)); } std::sort(removed.begin(), removed.end()); - std::vector<size_t>::const_iterator remEnd = - std::unique(removed.begin(), removed.end()); - std::vector<size_t>::const_iterator remBegin = removed.begin(); + auto remEnd = std::unique(removed.begin(), removed.end()); + auto remBegin = removed.begin(); - std::vector<std::string>::const_iterator argsEnd = + auto argsEnd = cmRemoveIndices(varArgsExpanded, cmMakeRange(remBegin, remEnd)); - std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); + auto argsBegin = varArgsExpanded.cbegin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); status.GetMakefile().AddDefinition(listName, value); @@ -1456,9 +1426,9 @@ bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, return false; } - std::vector<std::string>::iterator argsBegin = varArgsExpanded.begin(); - std::vector<std::string>::iterator argsEnd = varArgsExpanded.end(); - std::vector<std::string>::iterator newArgsEnd = + auto argsBegin = varArgsExpanded.begin(); + auto argsEnd = varArgsExpanded.end(); + auto newArgsEnd = std::remove_if(argsBegin, argsEnd, MatchesRegex(regex, includeMatches)); std::string value = cmJoin(cmMakeRange(argsBegin, newArgsEnd), ";"); diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index ff3ecd9..ab53df6 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -10,7 +10,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <assert.h> +#include <cassert> #include <memory> #include <sstream> #include <utility> @@ -326,6 +326,7 @@ cmListFileBacktrace::cmListFileBacktrace(cmStateSnapshot const& snapshot) { } +/* NOLINTNEXTLINE(performance-unnecessary-value-param) */ cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> parent, cmListFileContext const& lfc) : TopEntry(std::make_shared<Entry const>(std::move(parent), lfc)) diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 5de1a74..9cae827 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -5,9 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cstddef> #include <iosfwd> #include <memory> -#include <stddef.h> #include <string> #include <utility> #include <vector> diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index 3fd7343..cca1633 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -3,24 +3,30 @@ #include "cmLoadCacheCommand.h" #include "cmsys/FStream.hxx" +#include <set> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmake.h" -class cmExecutionStatus; +static bool ReadWithPrefix(std::vector<std::string> const& args, + cmExecutionStatus& status); -// cmLoadCacheCommand -bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +static void CheckLine(cmMakefile& mf, std::string const& prefix, + std::set<std::string> const& variablesToRead, + const char* line); + +bool cmLoadCacheCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with wrong number of arguments."); + status.SetError("called with wrong number of arguments."); } if (args.size() >= 2 && args[1] == "READ_WITH_PREFIX") { - return this->ReadWithPrefix(args); + return ReadWithPrefix(args, status); } // Cache entries to be excluded from the import list. @@ -59,24 +65,26 @@ bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args, } } + cmMakefile& mf = status.GetMakefile(); + // Loop over each build directory listed in the arguments. Each // directory has a cache file. for (std::string const& arg : args) { if ((arg == "EXCLUDE") || (arg == "INCLUDE_INTERNALS")) { break; } - this->Makefile->GetCMakeInstance()->LoadCache(arg, false, excludes, - includes); + mf.GetCMakeInstance()->LoadCache(arg, false, excludes, includes); } return true; } -bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) +static bool ReadWithPrefix(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Make sure we have a prefix. if (args.size() < 3) { - this->SetError("READ_WITH_PREFIX form must specify a prefix."); + status.SetError("READ_WITH_PREFIX form must specify a prefix."); return false; } @@ -84,17 +92,19 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) std::string cacheFile = args[0] + "/CMakeCache.txt"; if (!cmSystemTools::FileExists(cacheFile)) { std::string e = "Cannot load cache file from " + cacheFile; - this->SetError(e); + status.SetError(e); return false; } // Prepare the table of variables to read. - this->Prefix = args[2]; - this->VariablesToRead.insert(args.begin() + 3, args.end()); + std::string const prefix = args[2]; + std::set<std::string> const variablesToRead(args.begin() + 3, args.end()); // Read the cache file. cmsys::ifstream fin(cacheFile.c_str()); + cmMakefile& mf = status.GetMakefile(); + // This is a big hack read loop to overcome a buggy ifstream // implementation on HP-UX. This should work on all platforms even // for small buffer sizes. @@ -123,7 +133,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) } if (i != end) { // Completed a line. - this->CheckLine(line.c_str()); + CheckLine(mf, prefix, variablesToRead, line.c_str()); line.clear(); // Skip the newline character. @@ -134,13 +144,15 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) } if (!line.empty()) { // Partial last line. - this->CheckLine(line.c_str()); + CheckLine(mf, prefix, variablesToRead, line.c_str()); } return true; } -void cmLoadCacheCommand::CheckLine(const char* line) +static void CheckLine(cmMakefile& mf, std::string const& prefix, + std::set<std::string> const& variablesToRead, + const char* line) { // Check one line of the cache file. std::string var; @@ -148,14 +160,14 @@ void cmLoadCacheCommand::CheckLine(const char* line) cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; if (cmake::ParseCacheEntry(line, var, value, type)) { // Found a real entry. See if this one was requested. - if (this->VariablesToRead.find(var) != this->VariablesToRead.end()) { + if (variablesToRead.find(var) != variablesToRead.end()) { // This was requested. Set this variable locally with the given // prefix. - var = this->Prefix + var; + var = prefix + var; if (!value.empty()) { - this->Makefile->AddDefinition(var, value); + mf.AddDefinition(var, value); } else { - this->Makefile->RemoveDefinition(var); + mf.RemoveDefinition(var); } } } diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h index 45e52f0..7cee663 100644 --- a/Source/cmLoadCacheCommand.h +++ b/Source/cmLoadCacheCommand.h @@ -5,45 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmLoadCacheCommand - * \brief load a cache file - * - * cmLoadCacheCommand loads the non internal values of a cache file - */ -class cmLoadCacheCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmLoadCacheCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - std::set<std::string> VariablesToRead; - std::string Prefix; - - bool ReadWithPrefix(std::vector<std::string> const& args); - void CheckLine(const char* line); -}; +bool cmLoadCacheCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index f650eb1..1e02632 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -2,15 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmLoadCommandCommand.h" -#include <signal.h> +#include <csignal> + +#include <cstdio> +#include <cstdlib> +#include <cstring> -#include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCPluginAPI.cxx" #include "cmCPluginAPI.h" @@ -207,9 +207,8 @@ bool cmLoadCommandCommand(std::vector<std::string> const& args, // Try to find the program. std::string fullPath = cmSystemTools::FindFile(moduleName, path); if (fullPath.empty()) { - std::ostringstream e; - e << "Attempt to load command failed from file \"" << moduleName << "\""; - status.SetError(e.str()); + status.SetError(cmStrCat("Attempt to load command failed from file \"", + moduleName, "\"")); return false; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9152e94..93e074d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4,7 +4,9 @@ #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" +#include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" +#include "cmCustomCommandLines.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionEvaluationFile.h" @@ -14,6 +16,7 @@ #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmLinkLineComputer.h" +#include "cmLinkLineDeviceComputer.h" #include "cmMakefile.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -27,7 +30,6 @@ #include "cmTarget.h" #include "cmTestGenerator.h" #include "cmVersion.h" -#include "cm_string_view.hxx" #include "cmake.h" #include "cmsys/RegularExpression.hxx" @@ -36,16 +38,17 @@ # include "cmCryptoHash.h" #endif +#include <cm/string_view> + #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstdio> #include <cstdlib> +#include <cstring> #include <functional> #include <initializer_list> #include <iterator> -#include <memory> #include <sstream> -#include <stdio.h> -#include <string.h> #include <unordered_set> #include <utility> #include <vector> @@ -648,8 +651,7 @@ void cmLocalGenerator::AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt) cmGeneratorTarget* cmLocalGenerator::FindLocalNonAliasGeneratorTarget( const std::string& name) const { - GeneratorTargetMap::const_iterator ti = - this->GeneratorTargetSearchIndex.find(name); + auto ti = this->GeneratorTargetSearchIndex.find(name); if (ti != this->GeneratorTargetSearchIndex.end()) { return ti->second; } @@ -832,29 +834,50 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags, const std::string& lang, const std::string& config) { + std::vector<BT<std::string>> tmpFlags; + this->AddCompileOptions(tmpFlags, target, lang, config); + this->AppendFlags(flags, tmpFlags); +} + +void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, + cmGeneratorTarget* target, + const std::string& lang, + const std::string& config) +{ std::string langFlagRegexVar = std::string("CMAKE_") + lang + "_FLAG_REGEX"; if (const char* langFlagRegexStr = this->Makefile->GetDefinition(langFlagRegexVar)) { // Filter flags acceptable to this language. - std::vector<std::string> opts; if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) { + std::vector<std::string> opts; cmSystemTools::ParseWindowsCommandLine(targetFlags, opts); + // Re-escape these flags since COMPILE_FLAGS were already parsed + // as a command line above. + std::string compileOpts; + this->AppendCompileOptions(compileOpts, opts, langFlagRegexStr); + if (!compileOpts.empty()) { + flags.emplace_back(std::move(compileOpts)); + } } - target->GetCompileOptions(opts, config, lang); - // (Re-)Escape these flags. COMPILE_FLAGS were already parsed - // as a command line above, and COMPILE_OPTIONS are escaped. - this->AppendCompileOptions(flags, opts, langFlagRegexStr); + std::vector<BT<std::string>> targetCompileOpts = + target->GetCompileOptions(config, lang); + // COMPILE_OPTIONS are escaped. + this->AppendCompileOptions(flags, targetCompileOpts, langFlagRegexStr); } else { // Use all flags. if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) { // COMPILE_FLAGS are not escaped for historical reasons. - this->AppendFlags(flags, targetFlags); + std::string compileFlags; + this->AppendFlags(compileFlags, targetFlags); + if (!compileFlags.empty()) { + flags.emplace_back(std::move(compileFlags)); + } } - std::vector<std::string> opts; - target->GetCompileOptions(opts, config, lang); + std::vector<BT<std::string>> targetCompileOpts = + target->GetCompileOptions(config, lang); // COMPILE_OPTIONS are escaped. - this->AppendCompileOptions(flags, opts); + this->AppendCompileOptions(flags, targetCompileOpts); } for (auto const& it : target->GetMaxLanguageStandards()) { @@ -881,7 +904,12 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags, return; } } - this->AddCompilerRequirementFlag(flags, target, lang); + + std::string compReqFlag; + this->AddCompilerRequirementFlag(compReqFlag, target, lang); + if (!compReqFlag.empty()) { + flags.emplace_back(std::move(compReqFlag)); + } // Add compile flag for the MSVC compiler only. cmMakefile* mf = this->GetMakefile(); @@ -896,13 +924,15 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags, // to ON if (char const* jmcExprGen = target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(jmcExprGen); - std::string isJMCEnabled = cge->Evaluate(this, config); + std::string isJMCEnabled = + cmGeneratorExpression::Evaluate(jmcExprGen, this, config); if (cmIsOn(isJMCEnabled)) { std::vector<std::string> optVec = cmExpandedList(jmc); - this->AppendCompileOptions(flags, optVec); + std::string jmcFlags; + this->AppendCompileOptions(jmcFlags, optVec); + if (!jmcFlags.empty()) { + flags.emplace_back(std::move(jmcFlags)); + } } } } @@ -1117,24 +1147,49 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags, std::string const& linkLanguage, cmGeneratorTarget* target) { + std::vector<BT<std::string>> tmpFlags = + this->GetStaticLibraryFlags(config, linkLanguage, target); + this->AppendFlags(flags, tmpFlags); +} + +std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags( + std::string const& config, std::string const& linkLanguage, + cmGeneratorTarget* target) +{ + std::vector<BT<std::string>> flags; if (linkLanguage != "Swift") { + std::string staticLibFlags; this->AppendFlags( - flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS")); + staticLibFlags, + this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS")); if (!config.empty()) { std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config; - this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name)); + this->AppendFlags(staticLibFlags, + this->Makefile->GetSafeDefinition(name)); + } + if (!staticLibFlags.empty()) { + flags.emplace_back(std::move(staticLibFlags)); } } - this->AppendFlags(flags, target->GetSafeProperty("STATIC_LIBRARY_FLAGS")); + + std::string staticLibFlags; + this->AppendFlags(staticLibFlags, + target->GetSafeProperty("STATIC_LIBRARY_FLAGS")); if (!config.empty()) { std::string name = "STATIC_LIBRARY_FLAGS_" + config; - this->AppendFlags(flags, target->GetSafeProperty(name)); + this->AppendFlags(staticLibFlags, target->GetSafeProperty(name)); } - std::vector<std::string> options; - target->GetStaticLibraryLinkOptions(options, config, linkLanguage); + if (!staticLibFlags.empty()) { + flags.emplace_back(std::move(staticLibFlags)); + } + + std::vector<BT<std::string>> staticLibOpts = + target->GetStaticLibraryLinkOptions(config, linkLanguage); // STATIC_LIBRARY_OPTIONS are escaped. - this->AppendCompileOptions(flags, options); + this->AppendCompileOptions(flags, staticLibOpts); + + return flags; } void cmLocalGenerator::GetTargetFlags( @@ -1142,6 +1197,22 @@ void cmLocalGenerator::GetTargetFlags( std::string& linkLibs, std::string& flags, std::string& linkFlags, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target) { + std::vector<BT<std::string>> linkFlagsList; + std::vector<BT<std::string>> linkPathList; + std::vector<BT<std::string>> linkLibsList; + this->GetTargetFlags(linkLineComputer, config, linkLibsList, flags, + linkFlagsList, frameworkPath, linkPathList, target); + this->AppendFlags(linkFlags, linkFlagsList); + this->AppendFlags(linkPath, linkPathList); + this->AppendFlags(linkLibs, linkLibsList); +} + +void cmLocalGenerator::GetTargetFlags( + cmLinkLineComputer* linkLineComputer, const std::string& config, + std::vector<BT<std::string>>& linkLibs, std::string& flags, + std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target) +{ const std::string buildType = cmSystemTools::UpperCase(config); cmComputeLinkInformation* pcli = target->GetLinkInformation(config); const char* libraryLinkVariable = @@ -1152,19 +1223,26 @@ void cmLocalGenerator::GetTargetFlags( switch (target->GetType()) { case cmStateEnums::STATIC_LIBRARY: - this->GetStaticLibraryFlags(linkFlags, buildType, linkLanguage, target); + linkFlags = this->GetStaticLibraryFlags(buildType, linkLanguage, target); + if (pcli && dynamic_cast<cmLinkLineDeviceComputer*>(linkLineComputer)) { + // Compute the required cuda device link libraries when + // resolving cuda device symbols + this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, + frameworkPath, linkPath); + } break; case cmStateEnums::MODULE_LIBRARY: libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS"; CM_FALLTHROUGH; case cmStateEnums::SHARED_LIBRARY: { + std::string sharedLibFlags; if (linkLanguage != "Swift") { - linkFlags = cmStrCat( + sharedLibFlags = cmStrCat( this->Makefile->GetSafeDefinition(libraryLinkVariable), ' '); if (!buildType.empty()) { std::string build = cmStrCat(libraryLinkVariable, '_', buildType); - linkFlags += this->Makefile->GetSafeDefinition(build); - linkFlags += " "; + sharedLibFlags += this->Makefile->GetSafeDefinition(build); + sharedLibFlags += " "; } if (this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") || @@ -1175,10 +1253,10 @@ void cmLocalGenerator::GetTargetFlags( this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); for (cmSourceFile* sf : sources) { if (sf->GetExtension() == "def") { - linkFlags += defFlag; - linkFlags += this->ConvertToOutputFormat( + sharedLibFlags += defFlag; + sharedLibFlags += this->ConvertToOutputFormat( cmSystemTools::CollapseFullPath(sf->ResolveFullPath()), SHELL); - linkFlags += " "; + sharedLibFlags += " "; } } } @@ -1186,36 +1264,40 @@ void cmLocalGenerator::GetTargetFlags( const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { - linkFlags += targetLinkFlags; - linkFlags += " "; + sharedLibFlags += targetLinkFlags; + sharedLibFlags += " "; } if (!buildType.empty()) { targetLinkFlags = target->GetProperty(cmStrCat("LINK_FLAGS_", buildType)); if (targetLinkFlags) { - linkFlags += targetLinkFlags; - linkFlags += " "; + sharedLibFlags += targetLinkFlags; + sharedLibFlags += " "; } } - std::vector<std::string> opts; - target->GetLinkOptions(opts, config, linkLanguage); + if (!sharedLibFlags.empty()) { + linkFlags.emplace_back(std::move(sharedLibFlags)); + } + + std::vector<BT<std::string>> linkOpts = + target->GetLinkOptions(config, linkLanguage); // LINK_OPTIONS are escaped. - this->AppendCompileOptions(linkFlags, opts); + this->AppendCompileOptions(linkFlags, linkOpts); if (pcli) { this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath, linkPath); } } break; case cmStateEnums::EXECUTABLE: { + std::string exeFlags; if (linkLanguage != "Swift") { - linkFlags += - this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS"); - linkFlags += " "; + exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS"); + exeFlags += " "; if (!buildType.empty()) { - linkFlags += this->Makefile->GetSafeDefinition( + exeFlags += this->Makefile->GetSafeDefinition( cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType)); - linkFlags += " "; + exeFlags += " "; } if (linkLanguage.empty()) { cmSystemTools::Error( @@ -1225,19 +1307,19 @@ void cmLocalGenerator::GetTargetFlags( } if (target->GetPropertyAsBool("WIN32_EXECUTABLE")) { - linkFlags += + exeFlags += this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE"); - linkFlags += " "; + exeFlags += " "; } else { - linkFlags += + exeFlags += this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"); - linkFlags += " "; + exeFlags += " "; } if (target->IsExecutableWithExports()) { - linkFlags += this->Makefile->GetSafeDefinition( + exeFlags += this->Makefile->GetSafeDefinition( cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG")); - linkFlags += " "; + exeFlags += " "; } } @@ -1250,43 +1332,52 @@ void cmLocalGenerator::GetTargetFlags( if (cmIsOn(this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage + std::string("_FLAGS"); - linkFlags += this->Makefile->GetSafeDefinition(sFlagVar); - linkFlags += " "; + exeFlags += this->Makefile->GetSafeDefinition(sFlagVar); + exeFlags += " "; } std::string cmp0065Flags = this->GetLinkLibsCMP0065(linkLanguage, *target); if (!cmp0065Flags.empty()) { - linkFlags += cmp0065Flags; - linkFlags += " "; + exeFlags += cmp0065Flags; + exeFlags += " "; } const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { - linkFlags += targetLinkFlags; - linkFlags += " "; + exeFlags += targetLinkFlags; + exeFlags += " "; } if (!buildType.empty()) { targetLinkFlags = target->GetProperty(cmStrCat("LINK_FLAGS_", buildType)); if (targetLinkFlags) { - linkFlags += targetLinkFlags; - linkFlags += " "; + exeFlags += targetLinkFlags; + exeFlags += " "; } } - std::vector<std::string> opts; - target->GetLinkOptions(opts, config, linkLanguage); + if (!exeFlags.empty()) { + linkFlags.emplace_back(std::move(exeFlags)); + } + + std::vector<BT<std::string>> linkOpts = + target->GetLinkOptions(config, linkLanguage); // LINK_OPTIONS are escaped. - this->AppendCompileOptions(linkFlags, opts); + this->AppendCompileOptions(linkFlags, linkOpts); } break; default: break; } - this->AppendPositionIndependentLinkerFlags(linkFlags, target, config, + std::string extraLinkFlags; + this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config, linkLanguage); - this->AppendIPOLinkerFlags(linkFlags, target, config, linkLanguage); + this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage); + + if (!extraLinkFlags.empty()) { + linkFlags.emplace_back(std::move(extraLinkFlags)); + } } void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target, @@ -1294,26 +1385,45 @@ void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target, std::string const& lang, std::string& flags) { + std::vector<BT<std::string>> tmpFlags = + this->GetTargetCompileFlags(target, config, lang); + this->AppendFlags(flags, tmpFlags); +} + +std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags( + cmGeneratorTarget* target, std::string const& config, + std::string const& lang) +{ + std::vector<BT<std::string>> flags; + std::string compileFlags; + cmMakefile* mf = this->GetMakefile(); // Add language-specific flags. - this->AddLanguageFlags(flags, target, lang, config); + this->AddLanguageFlags(compileFlags, target, lang, config); if (target->IsIPOEnabled(lang, config)) { - this->AppendFeatureOptions(flags, lang, "IPO"); + this->AppendFeatureOptions(compileFlags, lang, "IPO"); } - this->AddArchitectureFlags(flags, target, lang, config); + this->AddArchitectureFlags(compileFlags, target, lang, config); if (lang == "Fortran") { - this->AppendFlags(flags, this->GetTargetFortranFlags(target, config)); + this->AppendFlags(compileFlags, + this->GetTargetFortranFlags(target, config)); } - this->AddCMP0018Flags(flags, target, lang, config); - this->AddVisibilityPresetFlags(flags, target, lang); - this->AppendFlags(flags, mf->GetDefineFlags()); - this->AppendFlags(flags, this->GetFrameworkFlags(lang, config, target)); + this->AddCMP0018Flags(compileFlags, target, lang, config); + this->AddVisibilityPresetFlags(compileFlags, target, lang); + this->AppendFlags(compileFlags, mf->GetDefineFlags()); + this->AppendFlags(compileFlags, + this->GetFrameworkFlags(lang, config, target)); + + if (!compileFlags.empty()) { + flags.emplace_back(std::move(compileFlags)); + } this->AddCompileOptions(flags, target, lang, config); + return flags; } static std::string GetFrameworkFlags(const std::string& lang, @@ -1419,6 +1529,19 @@ void cmLocalGenerator::OutputLinkLibraries( std::string& linkLibraries, std::string& frameworkPath, std::string& linkPath) { + std::vector<BT<std::string>> linkLibrariesList; + std::vector<BT<std::string>> linkPathList; + this->OutputLinkLibraries(pcli, linkLineComputer, linkLibrariesList, + frameworkPath, linkPathList); + pcli->AppendValues(linkLibraries, linkLibrariesList); + pcli->AppendValues(linkPath, linkPathList); +} + +void cmLocalGenerator::OutputLinkLibraries( + cmComputeLinkInformation* pcli, cmLinkLineComputer* linkLineComputer, + std::vector<BT<std::string>>& linkLibraries, std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath) +{ cmComputeLinkInformation& cli = *pcli; std::string linkLanguage = cli.GetLinkLanguage(); @@ -1450,10 +1573,9 @@ void cmLocalGenerator::OutputLinkLibraries( cmStrCat("CMAKE_", linkLanguage, "_FRAMEWORK_SEARCH_FLAG")); frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag); - linkPath = - linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator); - - linkLibraries = linkLineComputer->ComputeLinkLibraries(cli, stdLibString); + linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator, + linkPath); + linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries); } std::string cmLocalGenerator::GetLinkLibsCMP0065( @@ -1585,11 +1707,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, if (!msvcRuntimeLibraryValue) { msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault; } - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(msvcRuntimeLibraryValue); - std::string const msvcRuntimeLibrary = - cge->Evaluate(this, config, false, target); + std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate( + msvcRuntimeLibraryValue, this, config, target); if (!msvcRuntimeLibrary.empty()) { if (const char* msvcRuntimeLibraryOptions = this->Makefile->GetDefinition( @@ -1634,8 +1753,7 @@ void cmLocalGenerator::AddLanguageFlagsForLinking( cmGeneratorTarget* cmLocalGenerator::FindGeneratorTargetToUse( const std::string& name) const { - GeneratorTargetMap::const_iterator imported = - this->ImportedGeneratorTargets.find(name); + auto imported = this->ImportedGeneratorTargets.find(name); if (imported != this->ImportedGeneratorTargets.end()) { return imported->second; } @@ -1836,8 +1954,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( std::vector<std::string>& stds = langStdMap[lang]; - std::vector<std::string>::const_iterator stdIt = - std::find(stds.begin(), stds.end(), standard); + auto stdIt = std::find(stds.begin(), stds.end(), standard); if (stdIt == stds.end()) { std::string e = lang + "_STANDARD is set to invalid value '" + standard + "'"; @@ -1846,8 +1963,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( return; } - std::vector<std::string>::const_iterator defaultStdIt = - std::find(stds.begin(), stds.end(), defaultStd); + auto defaultStdIt = std::find(stds.begin(), stds.end(), defaultStd); if (defaultStdIt == stds.end()) { std::string e = "CMAKE_" + lang + "_STANDARD_DEFAULT is set to invalid value '" + std::string(defaultStd) + @@ -2089,12 +2205,11 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags, const std::string& config) { // Add the flags from the variable itself. - std::string flagsVar = var; - this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar)); + this->AppendFlags(flags, this->Makefile->GetSafeDefinition(var)); // Add the flags from the build-type specific variable. if (!config.empty()) { - flagsVar += "_"; - flagsVar += cmSystemTools::UpperCase(config); + const std::string flagsVar = + cmStrCat(var, '_', cmSystemTools::UpperCase(config)); this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar)); } } @@ -2110,6 +2225,14 @@ void cmLocalGenerator::AppendFlags(std::string& flags, } } +void cmLocalGenerator::AppendFlags( + std::string& flags, const std::vector<BT<std::string>>& newFlags) const +{ + for (BT<std::string> const& flag : newFlags) { + this->AppendFlags(flags, flag.Value); + } +} + void cmLocalGenerator::AppendFlagEscape(std::string& flags, const std::string& rawFlag) const { @@ -2145,22 +2268,131 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, return; } + const char* pchReuseFrom = + target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); + auto pch_sf = this->Makefile->GetOrCreateSource( pchSource, false, cmSourceFileLocationKind::Known); std::string pchFile = pchHeader; if (!this->GetGlobalGenerator()->IsXcode()) { + if (!pchReuseFrom) { + target->AddSource(pchSource, true); + } + // 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()); + + auto replaceExtension = [](const std::string& str, + const std::string& ext) -> std::string { + auto dot_pos = str.rfind('.'); + std::string result; + if (dot_pos != std::string::npos) { + result = str.substr(0, dot_pos); + } + result += ext; + return result; + }; + + if (!pchReuseFrom) { + std::string pchSourceObj = target->GetPchFileObject(config, lang); + + pchFile = replaceExtension(pchSourceObj, pchExtension); + pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str()); + } else { + auto reuseTarget = + this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom); + + if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) { + + const std::string pdb_prefix = + this->GetGlobalGenerator()->IsMultiConfig() + ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/") + : ""; + + const std::string target_compile_pdb_dir = + cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), + "/", target->GetName(), ".dir/"); + + const std::string copy_script = + cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake"); + cmGeneratedFileStream file(copy_script); + + file << "# CMake generated file\n"; + for (auto extension : { ".pdb", ".idb" }) { + const std::string from_file = cmStrCat( + reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(), + "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom, + extension); + + const std::string to_dir = cmStrCat( + target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/", + target->GetName(), ".dir/${PDB_PREFIX}"); + + file << "if (EXISTS \"" << from_file << "\")\n"; + file << " file(COPY \"" << from_file << "\"" + << " DESTINATION \"" << to_dir << "\")\n"; + file << "endif()\n"; + } + + cmCustomCommandLines commandLines; + cmCustomCommandLine currentLine; + currentLine.push_back(cmSystemTools::GetCMakeCommand()); + currentLine.push_back(cmStrCat("-DPDB_PREFIX=", pdb_prefix)); + currentLine.push_back("-P"); + currentLine.push_back(copy_script); + commandLines.push_back(std::move(currentLine)); + + const std::string no_main_dependency; + const std::vector<std::string> no_deps; + const char* no_message = ""; + const char* no_current_dir = nullptr; + std::vector<std::string> no_byproducts; + + std::vector<std::string> outputs; + outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix, + pchReuseFrom, ".pdb")); + + if (this->GetGlobalGenerator()->IsMultiConfig()) { + this->Makefile->AddCustomCommandToTarget( + target->GetName(), outputs, no_deps, commandLines, + cmTarget::PRE_BUILD, no_message, no_current_dir); + } else { + cmImplicitDependsList no_implicit_depends; + cmSourceFile* copy_rule = this->Makefile->AddCustomCommandToOutput( + outputs, no_byproducts, no_deps, no_main_dependency, + no_implicit_depends, commandLines, no_message, no_current_dir); + + if (copy_rule) { + target->AddSource(copy_rule->ResolveFullPath()); + } + } + + target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY", + target_compile_pdb_dir.c_str()); + } + + std::string pchSourceObj = reuseTarget->GetPchFileObject(config, lang); + + // Link to the pch object file + target->Target->SetProperty( + "LINK_FLAGS", + this->ConvertToOutputFormat(pchSourceObj, SHELL).c_str()); + + pchFile = replaceExtension(pchSourceObj, pchExtension); + } } else { pchFile += pchExtension; pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str()); } - target->AddSource(pchSource, true); + // Add pchHeader to source files, which will + // be grouped as "Precompile Header File" + auto pchHeader_sf = this->Makefile->GetOrCreateSource( + pchHeader, false, cmSourceFileLocationKind::Known); + std::string err; + pchHeader_sf->ResolveFullPath(&err); + target->AddSource(pchHeader); for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) { cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader); @@ -2186,7 +2418,8 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, } if (!this->GetGlobalGenerator()->IsXcode()) { - sf->SetProperty("OBJECT_DEPENDS", pchFile.c_str()); + sf->AppendProperty("OBJECT_DEPENDS", pchFile.c_str()); + sf->AppendProperty("OBJECT_DEPENDS", pchHeader.c_str()); sf->SetProperty("COMPILE_OPTIONS", useOptionList.c_str()); } } @@ -2275,8 +2508,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target, } } } - cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); - cmSystemTools::RemoveFile(filename_tmp); + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); target->AddSource(filename, true); @@ -2386,6 +2618,30 @@ void cmLocalGenerator::AppendCompileOptions( } } +void cmLocalGenerator::AppendCompileOptions( + std::vector<BT<std::string>>& options, + const std::vector<BT<std::string>>& options_vec, const char* regex) const +{ + if (regex != nullptr) { + // Filter flags upon specified regular expressions. + cmsys::RegularExpression r(regex); + + for (BT<std::string> const& opt : options_vec) { + if (r.find(opt.Value)) { + std::string flag; + this->AppendFlagEscape(flag, opt.Value); + options.emplace_back(std::move(flag), opt.Backtrace); + } + } + } else { + for (BT<std::string> const& opt : options_vec) { + std::string flag; + this->AppendFlagEscape(flag, opt.Value); + options.emplace_back(std::move(flag), opt.Backtrace); + } + } +} + void cmLocalGenerator::AppendIncludeDirectories( std::vector<std::string>& includes, const char* includes_list, const cmSourceFile& sourceFile) const @@ -2714,8 +2970,7 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName( const std::string& sin, std::string const& dir_max) { // Look for an existing mapped name for this object file. - std::map<std::string, std::string>::iterator it = - this->UniqueObjectNamesMap.find(sin); + auto it = this->UniqueObjectNamesMap.find(sin); // If no entry exists create one. if (it == this->UniqueObjectNamesMap.end()) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index e6ba333..512df26 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -121,6 +121,8 @@ public: //! Append flags to a string. virtual void AppendFlags(std::string& flags, const std::string& newFlags) const; + virtual void AppendFlags(std::string& flags, + const std::vector<BT<std::string>>& newFlags) const; virtual void AppendFlagEscape(std::string& flags, const std::string& rawFlag) const; void AddPchDependencies(cmGeneratorTarget* target, @@ -197,6 +199,9 @@ public: void AppendCompileOptions(std::string& options, const std::vector<std::string>& options_vec, const char* regex = nullptr) const; + void AppendCompileOptions(std::vector<BT<std::string>>& options, + const std::vector<BT<std::string>>& options_vec, + const char* regex = nullptr) const; /** * Join a set of defines into a definesString with a space separator. @@ -283,6 +288,9 @@ public: void AddCompileOptions(std::string& flags, cmGeneratorTarget* target, const std::string& lang, const std::string& config); + void AddCompileOptions(std::vector<BT<std::string>>& flags, + cmGeneratorTarget* target, const std::string& lang, + const std::string& config); std::string GetProjectName() const; @@ -363,6 +371,9 @@ public: void GetStaticLibraryFlags(std::string& flags, std::string const& config, std::string const& linkLanguage, cmGeneratorTarget* target); + std::vector<BT<std::string>> GetStaticLibraryFlags( + std::string const& config, std::string const& linkLanguage, + cmGeneratorTarget* target); /** Fill out these strings for the given target. Libraries to link, * flags, and linkflags. */ @@ -371,6 +382,11 @@ public: std::string& flags, std::string& linkFlags, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target); + void GetTargetFlags( + cmLinkLineComputer* linkLineComputer, const std::string& config, + std::vector<BT<std::string>>& linkLibs, std::string& flags, + std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target); void GetTargetDefines(cmGeneratorTarget const* target, std::string const& config, std::string const& lang, std::set<std::string>& defines) const; @@ -380,6 +396,9 @@ public: void GetTargetCompileFlags(cmGeneratorTarget* target, std::string const& config, std::string const& lang, std::string& flags); + std::vector<BT<std::string>> GetTargetCompileFlags(cmGeneratorTarget* target, + std::string const& config, + std::string const& lang); std::string GetFrameworkFlags(std::string const& l, std::string const& config, @@ -410,6 +429,11 @@ protected: cmLinkLineComputer* linkLineComputer, std::string& linkLibraries, std::string& frameworkPath, std::string& linkPath); + void OutputLinkLibraries(cmComputeLinkInformation* pcli, + cmLinkLineComputer* linkLineComputer, + std::vector<BT<std::string>>& linkLibraries, + std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath); // Handle old-style install rules stored in the targets. void GenerateTargetInstallRules( diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index e28b876..82dc943 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -3,11 +3,11 @@ #include "cmLocalNinjaGenerator.h" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstdio> #include <iterator> #include <memory> #include <sstream> -#include <stdio.h> #include <utility> #include "cmCryptoHash.h" @@ -386,8 +386,7 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( } std::ostringstream cmd; - for (std::vector<std::string>::const_iterator li = cmdLines.begin(); - li != cmdLines.end(); ++li) + for (auto li = cmdLines.begin(); li != cmdLines.end(); ++li) #ifdef _WIN32 { if (li != cmdLines.begin()) { @@ -531,8 +530,7 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc, void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements() { for (cmCustomCommand const* customCommand : this->CustomCommands) { - CustomCommandTargetMap::iterator i = - this->CustomCommandTargets.find(customCommand); + auto i = this->CustomCommandTargets.find(customCommand); assert(i != this->CustomCommandTargets.end()); // A custom command may appear on multiple targets. However, some build @@ -544,7 +542,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements() // // FIXME: This won't work in certain obscure scenarios involving indirect // dependencies. - std::set<cmGeneratorTarget*>::iterator j = i->second.begin(); + auto j = i->second.begin(); assert(j != i->second.end()); std::vector<std::string> ccTargetDeps; this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, @@ -610,12 +608,10 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles() this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { std::vector<std::string> cleanFiles; { - cmGeneratorExpression ge; - auto cge = ge.Parse(prop_value); - cmExpandList( - cge->Evaluate(this, - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), - cleanFiles); + cmExpandList(cmGeneratorExpression::Evaluate( + prop_value, this, + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), + cleanFiles); } std::string const& binaryDir = this->GetCurrentBinaryDirectory(); cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator(); diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 08bec70..f64534c 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -93,7 +93,6 @@ private: void WriteProcessedMakefile(std::ostream& os); void WritePools(std::ostream& os); - void WriteCustomCommandRule(); void WriteCustomCommandBuildStatement(cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 320a58b..1d87e93 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -5,11 +5,11 @@ #include "cmsys/FStream.hxx" #include "cmsys/Terminal.h" #include <algorithm> +#include <cstdio> #include <sstream> -#include <stdio.h> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmCustomCommand.h" // IWYU pragma: keep @@ -161,8 +161,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles( continue; } std::vector<cmSourceFile const*> objectSources; - gt->GetObjectSources( - objectSources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); + gt->GetObjectSources(objectSources, this->ConfigName); // Compute full path to object file directory for this target. std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->GetTargetDirectory(gt), '/'); @@ -1084,12 +1083,10 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( // Look for additional files registered for cleaning in this directory. if (const char* prop_value = this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value); - cmExpandList( - cge->Evaluate(this, - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), - cleanFiles); + cmExpandList(cmGeneratorExpression::Evaluate( + prop_value, this, + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), + cleanFiles); } if (cleanFiles.empty()) { return; @@ -1225,8 +1222,7 @@ std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable( // see if the variable has been defined before and return // the modified version of the variable - std::map<std::string, std::string>::iterator i = - this->MakeVariableMap.find(unmodified); + auto i = this->MakeVariableMap.find(unmodified); if (i != this->MakeVariableMap.end()) { return i->second; } @@ -1495,8 +1491,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) // Convert the string to a list and preserve empty entries. std::vector<std::string> pairs = cmExpandedList(pairs_string, true); - for (std::vector<std::string>::const_iterator i = pairs.begin(); - i != pairs.end() && (i + 1) != pairs.end();) { + for (auto i = pairs.begin(); i != pairs.end() && (i + 1) != pairs.end();) { const std::string& depender = *i++; const std::string& dependee = *i++; @@ -1866,9 +1861,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( << "_TARGET_INCLUDE_PATH\n"; std::vector<std::string> includes; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - this->GetIncludeDirectories(includes, target, implicitLang.first, config); + this->GetIncludeDirectories(includes, target, implicitLang.first, + this->ConfigName); std::string binaryDir = this->GetState()->GetBinaryDirectory(); if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) { std::string const& sourceDir = this->GetState()->GetSourceDirectory(); @@ -2019,10 +2013,9 @@ std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath( if (components.size() > 1) { // Now add the rest of the components separated by the proper slash // direction for this platform. - std::vector<std::string>::const_iterator compEnd = std::remove( - components.begin() + 1, components.end() - 1, std::string()); - std::vector<std::string>::const_iterator compStart = - components.begin() + 1; + auto compEnd = std::remove(components.begin() + 1, components.end() - 1, + std::string()); + auto compStart = components.begin() + 1; result += cmJoin(cmMakeRange(compStart, compEnd), slash); // Only the last component can be empty to avoid double slashes. result += slash; diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 745e251..c02c0dc 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -90,6 +90,7 @@ public: // append flags to a string void AppendFlags(std::string& flags, const std::string& newFlags) const override; + using cmLocalCommonGenerator::AppendFlags; // append an echo command enum EchoColor diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 6c7fb2b..026f494 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -92,11 +92,8 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets() for (cmGeneratorTarget* l : tgts) { if (l->GetType() == cmStateEnums::GLOBAL_TARGET) { std::vector<std::string> no_depends; - cmCustomCommandLine force_command; - force_command.push_back("cd"); - force_command.push_back("."); - cmCustomCommandLines force_commands; - force_commands.push_back(force_command); + cmCustomCommandLines force_commands = + cmMakeSingleCommandLine({ "cd", "." }); std::string no_main_dependency; std::string force = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", l->GetName(), "_force"); @@ -246,21 +243,15 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() std::unique(listFiles.begin(), listFiles.end()); listFiles.erase(new_end, listFiles.end()); + std::string argS = cmStrCat("-S", this->GetSourceDirectory()); + std::string argB = cmStrCat("-B", this->GetBinaryDirectory()); std::string stampName = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp"); - cmCustomCommandLine commandLine; - commandLine.push_back(cmSystemTools::GetCMakeCommand()); + cmCustomCommandLines commandLines = + cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB, + "--check-stamp-file", stampName }); std::string comment = cmStrCat("Building Custom Rule ", makefileIn); - std::string args; - args = cmStrCat("-S", this->GetSourceDirectory()); - commandLine.push_back(args); - args = cmStrCat("-B", this->GetBinaryDirectory()); - commandLine.push_back(args); - commandLine.push_back("--check-stamp-file"); - commandLine.push_back(stampName); - cmCustomCommandLines commandLines; - commandLines.push_back(commandLine); - const char* no_working_directory = 0; + const char* no_working_directory = nullptr; std::string fullpathStampName = cmSystemTools::CollapseFullPath(stampName.c_str()); this->Makefile->AddCustomCommandToOutput( diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index f3f2042..cec9c02 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -98,16 +98,11 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target, } // Add a pre-build event to create the directory. - cmCustomCommandLine command; - command.push_back(cmSystemTools::GetCMakeCommand()); - command.push_back("-E"); - command.push_back("make_directory"); - command.push_back(impDir); std::vector<std::string> no_output; std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; - cmCustomCommandLines commands; - commands.push_back(command); + cmCustomCommandLines commands = cmMakeSingleCommandLine( + { cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir }); pcc.reset(new cmCustomCommand(0, no_output, no_byproducts, no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); diff --git a/Source/cmLocale.h b/Source/cmLocale.h index 3580ec8..c44a42d 100644 --- a/Source/cmLocale.h +++ b/Source/cmLocale.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <locale.h> +#include <clocale> #include <string> class cmLocaleRAII diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx index bec3ad8..ee5eb00 100644 --- a/Source/cmMachO.cxx +++ b/Source/cmMachO.cxx @@ -9,7 +9,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> // Include the Mach-O format information system header. #include <mach-o/fat.h> diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 201cc13..ba9947a 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -2,12 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMacroCommand.h" -#include <stdio.h> +#include <cstdio> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/string_view> + #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" #include "cmAlgorithms.h" #include "cmExecutionStatus.h" @@ -65,8 +66,7 @@ bool cmMacroHelperCommand::operator()( // set the value of argc std::string argcDef = std::to_string(expandedArgs.size()); - std::vector<std::string>::const_iterator eit = - expandedArgs.begin() + (this->Args.size() - 1); + auto eit = expandedArgs.begin() + (this->Args.size() - 1); std::string expandedArgn = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";"); std::string expandedArgv = cmJoin(expandedArgs, ";"); std::vector<std::string> variables; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 411add3..34081ed 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -5,16 +5,17 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cctype> +#include <cstdio> +#include <cstdlib> #include <cstring> -#include <ctype.h> -#include <iterator> -#include <memory> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #include <utility> +#include <cm/iterator> +#include <cm/memory> + #include "cmAlgorithms.h" #include "cmCommandArgumentParserHelper.h" #include "cmCustomCommand.h" @@ -102,6 +103,7 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, this->AddSourceGroup("", "^.*$"); this->AddSourceGroup("Source Files", CM_SOURCE_REGEX); this->AddSourceGroup("Header Files", CM_HEADER_REGEX); + this->AddSourceGroup("Precompile Header File", CM_PCH_REGEX); this->AddSourceGroup("CMake Rules", "\\.rule$"); this->AddSourceGroup("Resources", CM_RESOURCE_REGEX); this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); @@ -751,9 +753,8 @@ cmMakefile::GetExportBuildFileGenerators() const void cmMakefile::RemoveExportBuildFileGeneratorCMP0024( cmExportBuildFileGenerator* gen) { - std::vector<cmExportBuildFileGenerator*>::iterator it = - std::find(this->ExportBuildFileGenerators.begin(), - this->ExportBuildFileGenerators.end(), gen); + auto it = std::find(this->ExportBuildFileGenerators.begin(), + this->ExportBuildFileGenerators.end(), gen); if (it != this->ExportBuildFileGenerators.end()) { this->ExportBuildFileGenerators.erase(it); } @@ -820,7 +821,23 @@ void cmMakefile::ConfigureFinalPass() } } -void cmMakefile::AddCustomCommandToTarget( +bool cmMakefile::ValidateCustomCommand( + const cmCustomCommandLines& commandLines) const +{ + // TODO: More strict? + for (cmCustomCommandLine const& cl : commandLines) { + if (!cl.empty() && !cl[0].empty() && cl[0][0] == '"') { + std::ostringstream e; + e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n"; + this->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return false; + } + } + + return true; +} + +cmTarget* cmMakefile::AddCustomCommandToTarget( const std::string& target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, @@ -829,7 +846,7 @@ void cmMakefile::AddCustomCommandToTarget( bool command_expand_lists, ObjectLibraryCommands objLibraryCommands) { // Find the target to which to add the custom command. - cmTargetMap::iterator ti = this->Targets.find(target); + auto ti = this->Targets.find(target); if (ti == this->Targets.end()) { MessageType messageType = MessageType::AUTHOR_WARNING; @@ -860,38 +877,54 @@ void cmMakefile::AddCustomCommandToTarget( e << "No TARGET '" << target << "' has been created in this directory."; } - IssueMessage(messageType, e.str()); + this->IssueMessage(messageType, e.str()); } - return; + return nullptr; } - cmTarget& t = ti->second; + cmTarget* t = &ti->second; if (objLibraryCommands == RejectObjectLibraryCommands && - t.GetType() == cmStateEnums::OBJECT_LIBRARY) { + t->GetType() == cmStateEnums::OBJECT_LIBRARY) { std::ostringstream e; e << "Target \"" << target << "\" is an OBJECT library " "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; this->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return; + return nullptr; } - if (t.GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) { std::ostringstream e; e << "Target \"" << target << "\" is an INTERFACE library " "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; this->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return; + return nullptr; } - // Always create the byproduct sources and mark them generated. - for (std::string const& o : byproducts) { - if (cmSourceFile* out = this->GetOrCreateSource(o, true)) { - out->SetProperty("GENERATED", "1"); - } + // Validate custom commands. + if (!this->ValidateCustomCommand(commandLines)) { + return t; } + // Always create the byproduct sources and mark them generated. + this->CreateGeneratedSources(byproducts); + + this->CommitCustomCommandToTarget( + t, byproducts, depends, commandLines, type, comment, workingDir, + escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists); + + return t; +} + +void cmMakefile::CommitCustomCommandToTarget( + cmTarget* target, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const char* comment, const char* workingDir, bool escapeOldStyle, + bool uses_terminal, const std::string& depfile, const std::string& job_pool, + bool command_expand_lists) +{ // Add the command to the appropriate build step for the target. std::vector<std::string> no_output; cmCustomCommand cc(this, no_output, byproducts, depends, commandLines, @@ -904,21 +937,70 @@ void cmMakefile::AddCustomCommandToTarget( cc.SetJobPool(job_pool); switch (type) { case cmTarget::PRE_BUILD: - t.AddPreBuildCommand(cc); + target->AddPreBuildCommand(cc); break; case cmTarget::PRE_LINK: - t.AddPreLinkCommand(cc); + target->AddPreLinkCommand(cc); break; case cmTarget::POST_BUILD: - t.AddPostBuildCommand(cc); + target->AddPostBuildCommand(cc); break; } + this->UpdateOutputToSourceMap(byproducts, target); +} + +void cmMakefile::UpdateOutputToSourceMap( + std::vector<std::string> const& byproducts, cmTarget* target) +{ + for (std::string const& o : byproducts) { + this->UpdateOutputToSourceMap(o, target); + } +} + +void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct, + cmTarget* target) +{ + SourceEntry entry; + entry.Sources.Target = target; + + auto pr = this->OutputToSource.emplace(byproduct, entry); + if (!pr.second) { + SourceEntry& current = pr.first->second; + // Has the target already been set? + if (!current.Sources.Target) { + current.Sources.Target = target; + } else { + // Multiple custom commands/targets produce the same output (source file + // or target). See also comment in other UpdateOutputToSourceMap + // overload. + // + // TODO: Warn the user about this case. + } + } +} + +cmSourceFile* cmMakefile::AddCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const std::string& main_dependency, const cmCustomCommandLines& commandLines, + const char* comment, const char* workingDir, bool replace, + bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, + const std::string& depfile, const std::string& job_pool) +{ + std::vector<std::string> outputs; + outputs.push_back(output); + std::vector<std::string> no_byproducts; + cmImplicitDependsList no_implicit_depends; + return this->AddCustomCommandToOutput( + outputs, no_byproducts, depends, main_dependency, no_implicit_depends, + commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, + command_expand_lists, depfile, job_pool); } cmSourceFile* cmMakefile::AddCustomCommandToOutput( const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, const std::string& depfile, @@ -930,16 +1012,31 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( return nullptr; } - // Validate custom commands. TODO: More strict? - for (cmCustomCommandLine const& cl : commandLines) { - if (!cl.empty() && !cl[0].empty() && cl[0][0] == '"') { - std::ostringstream e; - e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n"; - this->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return nullptr; - } + // Validate custom commands. + if (!this->ValidateCustomCommand(commandLines)) { + return nullptr; } + // Always create the output sources and mark them generated. + this->CreateGeneratedSources(outputs); + this->CreateGeneratedSources(byproducts); + + return this->CommitCustomCommandToOutput( + outputs, byproducts, depends, main_dependency, implicit_depends, + commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, + command_expand_lists, depfile, job_pool); +} + +cmSourceFile* cmMakefile::CommitCustomCommandToOutput( + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines, const char* comment, + const char* workingDir, bool replace, bool escapeOldStyle, + bool uses_terminal, bool command_expand_lists, const std::string& depfile, + const std::string& job_pool) +{ // Choose a source file on which to store the custom command. cmSourceFile* file = nullptr; if (!commandLines.empty() && !main_dependency.empty()) { @@ -987,20 +1084,6 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( file->SetProperty("__CMAKE_RULE", "1"); } - // Always create the output sources and mark them generated. - for (std::string const& o : outputs) { - if (cmSourceFile* out = - this->GetOrCreateSource(o, true, cmSourceFileLocationKind::Known)) { - out->SetProperty("GENERATED", "1"); - } - } - for (std::string const& o : byproducts) { - if (cmSourceFile* out = - this->GetOrCreateSource(o, true, cmSourceFileLocationKind::Known)) { - out->SetProperty("GENERATED", "1"); - } - } - // Attach the custom command to the file. if (file) { // Construct a complete list of dependencies. @@ -1009,60 +1092,57 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( depends2.push_back(main_dependency); } - cmCustomCommand* cc = new cmCustomCommand( + std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>( this, outputs, byproducts, depends2, commandLines, comment, workingDir); cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); + cc->SetImplicitDepends(implicit_depends); cc->SetUsesTerminal(uses_terminal); cc->SetCommandExpandLists(command_expand_lists); cc->SetDepfile(depfile); cc->SetJobPool(job_pool); - file->SetCustomCommand(cc); - this->UpdateOutputToSourceMap(outputs, file); + file->SetCustomCommand(std::move(cc)); + this->UpdateOutputToSourceMap(outputs, file, false); + this->UpdateOutputToSourceMap(byproducts, file, true); } return file; } void cmMakefile::UpdateOutputToSourceMap( - std::vector<std::string> const& outputs, cmSourceFile* source) + std::vector<std::string> const& outputs, cmSourceFile* source, + bool byproduct) { for (std::string const& o : outputs) { - this->UpdateOutputToSourceMap(o, source); + this->UpdateOutputToSourceMap(o, source, byproduct); } } void cmMakefile::UpdateOutputToSourceMap(std::string const& output, - cmSourceFile* source) -{ - OutputToSourceMap::iterator i = this->OutputToSource.find(output); - if (i != this->OutputToSource.end()) { - // Multiple custom commands produce the same output but may - // be attached to a different source file (MAIN_DEPENDENCY). - // LinearGetSourceFileWithOutput would return the first one, - // so keep the mapping for the first one. - // - // TODO: Warn the user about this case. However, the VS 8 generator - // triggers it for separate generate.stamp rules in ZERO_CHECK and - // individual targets. - return; + cmSourceFile* source, bool byproduct) +{ + SourceEntry entry; + entry.Sources.Source = source; + entry.Sources.SourceIsByproduct = byproduct; + + auto pr = this->OutputToSource.emplace(output, entry); + if (!pr.second) { + SourceEntry& current = pr.first->second; + // Outputs take precedence over byproducts + if (!current.Sources.Source || + (current.Sources.SourceIsByproduct && !byproduct)) { + current.Sources.Source = source; + current.Sources.SourceIsByproduct = false; + } else { + // Multiple custom commands produce the same output but may + // be attached to a different source file (MAIN_DEPENDENCY). + // LinearGetSourceFileWithOutput would return the first one, + // so keep the mapping for the first one. + // + // TODO: Warn the user about this case. However, the VS 8 generator + // triggers it for separate generate.stamp rules in ZERO_CHECK and + // individual targets. + } } - this->OutputToSource[output] = source; -} - -cmSourceFile* cmMakefile::AddCustomCommandToOutput( - const std::string& output, const std::vector<std::string>& depends, - const std::string& main_dependency, const cmCustomCommandLines& commandLines, - const char* comment, const char* workingDir, bool replace, - bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, - const std::string& depfile, const std::string& job_pool) -{ - std::vector<std::string> outputs; - outputs.push_back(output); - std::vector<std::string> no_byproducts; - return this->AddCustomCommandToOutput( - outputs, no_byproducts, depends, main_dependency, commandLines, comment, - workingDir, replace, escapeOldStyle, uses_terminal, command_expand_lists, - depfile, job_pool); } void cmMakefile::AddCustomCommandOldStyle( @@ -1083,73 +1163,88 @@ void cmMakefile::AddCustomCommandOldStyle( return; } - // Each output must get its own copy of this rule. - cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|" - "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" - "hm|hpp|hxx|in|txx|inl)$"); - for (std::string const& oi : outputs) { - // Get the name of this output. - const char* output = oi.c_str(); - cmSourceFile* sf; - - // Choose whether to use a main dependency. - if (sourceFiles.find(source)) { - // The source looks like a real file. Use it as the main dependency. - sf = this->AddCustomCommandToOutput(output, depends, source, - commandLines, comment, nullptr); - } else { - // The source may not be a real file. Do not use a main dependency. - std::string no_main_dependency; - std::vector<std::string> depends2 = depends; - depends2.push_back(source); - sf = this->AddCustomCommandToOutput(output, depends2, no_main_dependency, - commandLines, comment, nullptr); - } + auto ti = this->Targets.find(target); + cmTarget* t = ti != this->Targets.end() ? &ti->second : nullptr; + auto addRuleFileToTarget = [=](cmSourceFile* sf) { // If the rule was added to the source (and not a .rule file), // then add the source to the target to make sure the rule is // included. - if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) { - cmTargetMap::iterator ti = this->Targets.find(target); - if (ti != this->Targets.end()) { - ti->second.AddSource(sf->ResolveFullPath()); + if (!sf->GetPropertyAsBool("__CMAKE_RULE")) { + if (t) { + t->AddSource(sf->ResolveFullPath()); } else { cmSystemTools::Error("Attempt to add a custom rule to a target " "that does not exist yet for target " + target); - return; + } + } + }; + + // Each output must get its own copy of this rule. + cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|" + "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" + "hm|hpp|hxx|in|txx|inl)$"); + + // Choose whether to use a main dependency. + if (sourceFiles.find(source)) { + // The source looks like a real file. Use it as the main dependency. + for (std::string const& output : outputs) { + cmSourceFile* sf = this->AddCustomCommandToOutput( + output, depends, source, commandLines, comment, nullptr); + if (sf) { + addRuleFileToTarget(sf); + } + } + } else { + std::string no_main_dependency; + std::vector<std::string> depends2 = depends; + depends2.push_back(source); + + // The source may not be a real file. Do not use a main dependency. + for (std::string const& output : outputs) { + cmSourceFile* sf = this->AddCustomCommandToOutput( + output, depends2, no_main_dependency, commandLines, comment, nullptr); + if (sf) { + addRuleFileToTarget(sf); } } } } -cmTarget* cmMakefile::AddUtilityCommand( - const std::string& utilityName, TargetOrigin origin, bool excludeFromAll, - const std::vector<std::string>& depends, const char* workingDirectory, - const char* command, const char* arg1, const char* arg2, const char* arg3, - const char* arg4) +bool cmMakefile::AppendCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines) { - // Construct the command line for the custom command. - cmCustomCommandLine commandLine; - commandLine.push_back(command); - if (arg1) { - commandLine.push_back(arg1); - } - if (arg2) { - commandLine.push_back(arg2); - } - if (arg3) { - commandLine.push_back(arg3); + // Check as good as we can if there will be a command for this output. + if (!this->MightHaveCustomCommand(output)) { + return false; } - if (arg4) { - commandLine.push_back(arg4); + + // Validate custom commands. + if (this->ValidateCustomCommand(commandLines)) { + // Add command factory to allow generator expressions in output. + this->CommitAppendCustomCommandToOutput(output, depends, implicit_depends, + commandLines); } - cmCustomCommandLines commandLines; - commandLines.push_back(std::move(commandLine)); - // Call the real signature of this method. - return this->AddUtilityCommand(utilityName, origin, excludeFromAll, - workingDirectory, depends, commandLines); + return true; +} + +void cmMakefile::CommitAppendCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines) +{ + // Lookup an existing command. + if (cmSourceFile* sf = this->GetSourceFileWithOutput(output)) { + if (cmCustomCommand* cc = sf->GetCustomCommand()) { + cc->AppendCommands(commandLines); + cc->AppendDepends(depends); + cc->AppendImplicitDepends(implicit_depends); + } + } } cmTarget* cmMakefile::AddUtilityCommand( @@ -1180,43 +1275,72 @@ cmTarget* cmMakefile::AddUtilityCommand( if (excludeFromAll || this->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } - if (!comment) { - // Use an empty comment to avoid generation of default comment. - comment = ""; + + // Validate custom commands. + if (!this->ValidateCustomCommand(commandLines) || + (commandLines.empty() && depends.empty())) { + return target; } - // Store the custom command in the target. - if (!commandLines.empty() || !depends.empty()) { - std::string force = - cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); - std::vector<std::string> forced; - forced.push_back(force); - std::string no_main_dependency; - bool no_replace = false; - this->AddCustomCommandToOutput( - forced, byproducts, depends, no_main_dependency, commandLines, comment, - workingDirectory, no_replace, escapeOldStyle, uses_terminal, - command_expand_lists, /*depfile=*/"", job_pool); - cmSourceFile* sf = target->AddSourceCMP0049(force); + // Always create the byproduct sources and mark them generated. + this->CreateGeneratedSources(byproducts); + std::string force = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); + this->CreateGeneratedSource(force); + std::string forceCMP0049 = target->GetSourceCMP0049(force); + { + cmSourceFile* sf = nullptr; + if (!forceCMP0049.empty()) { + sf = this->GetOrCreateSource(forceCMP0049, false, + cmSourceFileLocationKind::Known); + } // The output is not actually created so mark it symbolic. if (sf) { sf->SetProperty("SYMBOLIC", "1"); } else { cmSystemTools::Error("Could not get source file entry for " + force); } + } - // Always create the byproduct sources and mark them generated. - for (std::string const& byproduct : byproducts) { - if (cmSourceFile* out = this->GetOrCreateSource( - byproduct, true, cmSourceFileLocationKind::Known)) { - out->SetProperty("GENERATED", "1"); - } - } + if (!comment) { + // Use an empty comment to avoid generation of default comment. + comment = ""; } + + this->CommitUtilityCommand(target, force, forceCMP0049, workingDirectory, + byproducts, depends, commandLines, escapeOldStyle, + comment, uses_terminal, command_expand_lists, + job_pool); + return target; } +void cmMakefile::CommitUtilityCommand( + cmTarget* target, const std::string& force, const std::string& forceCMP0049, + const char* workingDirectory, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, bool escapeOldStyle, + const char* comment, bool uses_terminal, bool command_expand_lists, + const std::string& job_pool) +{ + std::vector<std::string> forced; + forced.push_back(force); + std::string no_main_dependency; + cmImplicitDependsList no_implicit_depends; + bool no_replace = false; + cmSourceFile* sf = this->AddCustomCommandToOutput( + forced, byproducts, depends, no_main_dependency, no_implicit_depends, + commandLines, comment, workingDirectory, no_replace, escapeOldStyle, + uses_terminal, command_expand_lists, /*depfile=*/"", job_pool); + if (!forceCMP0049.empty()) { + target->AddSource(forceCMP0049); + } + if (sf) { + this->UpdateOutputToSourceMap(byproducts, target); + } +} + static void s_AddDefineFlag(std::string const& flag, std::string& dflags) { // remove any \n\r @@ -1355,9 +1479,8 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) std::vector<std::string> defs = cmExpandedList(cdefs); // Recompose the list without the definition. - std::vector<std::string>::const_iterator defEnd = - std::remove(defs.begin(), defs.end(), define); - std::vector<std::string>::const_iterator defBegin = defs.begin(); + auto defEnd = std::remove(defs.begin(), defs.end(), define); + auto defBegin = defs.begin(); std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";"); // Store the new list. @@ -1640,7 +1763,7 @@ void cmMakefile::Configure() std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories; // for each subdir recurse - std::vector<cmMakefile*>::iterator sdi = subdirs.begin(); + auto sdi = subdirs.begin(); for (; sdi != subdirs.end(); ++sdi) { (*sdi)->StateSnapshot.InitializeFromParent_ForSubdirsCommand(); this->ConfigureSubDirectory(*sdi); @@ -1954,8 +2077,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target) if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp); - for (std::vector<std::string>::iterator j = linkLibs.begin(); - j != linkLibs.end(); ++j) { + for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) { std::string libraryName = *j; cmTargetLinkLibraryType libType = GENERAL_LibraryType; if (libraryName == "optimized") { @@ -2024,60 +2146,146 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName, cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type, const std::string& name) { - cmTargetMap::iterator it = + auto it = this->Targets .emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this)) .first; + this->OrderedTargets.push_back(&it->second); this->GetGlobalGenerator()->IndexTarget(&it->second); this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name); return &it->second; } +namespace { +bool AnyOutputMatches(const std::string& name, + const std::vector<std::string>& outputs) +{ + for (std::string const& output : outputs) { + std::string::size_type pos = output.rfind(name); + // If the output matches exactly + if (pos != std::string::npos && pos == output.size() - name.size() && + (pos == 0 || output[pos - 1] == '/')) { + return true; + } + } + return false; +} + +bool AnyTargetCommandOutputMatches( + const std::string& name, const std::vector<cmCustomCommand>& commands) +{ + for (cmCustomCommand const& command : commands) { + if (AnyOutputMatches(name, command.GetByproducts())) { + return true; + } + } + return false; +} +} + +cmTarget* cmMakefile::LinearGetTargetWithOutput(const std::string& name) const +{ + // We go through the ordered vector of targets to get reproducible results + // should multiple names match. + for (cmTarget* t : this->OrderedTargets) { + // Does the output of any command match the source file name? + if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) { + return t; + } + if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) { + return t; + } + if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) { + return t; + } + } + return nullptr; +} + cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput( - const std::string& name) const + const std::string& name, cmSourceOutputKind kind, bool& byproduct) const { - std::string out; + // Outputs take precedence over byproducts. + byproduct = false; + cmSourceFile* fallback = nullptr; - // look through all the source files that have custom commands - // and see if the custom command has the passed source file as an output + // Look through all the source files that have custom commands and see if the + // custom command has the passed source file as an output. for (cmSourceFile* src : this->SourceFiles) { - // does this source file have a custom command? + // Does this source file have a custom command? if (src->GetCustomCommand()) { // Does the output of the custom command match the source file name? - const std::vector<std::string>& outputs = - src->GetCustomCommand()->GetOutputs(); - for (std::string const& output : outputs) { - out = output; - std::string::size_type pos = out.rfind(name); - // If the output matches exactly - if (pos != std::string::npos && pos == out.size() - name.size() && - (pos == 0 || out[pos - 1] == '/')) { - return src; + if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) { + // Return the first matching output. + return src; + } + if (kind == cmSourceOutputKind::OutputOrByproduct) { + if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) { + // Do not return the source yet as there might be a matching output. + fallback = src; } } } } - // otherwise return NULL - return nullptr; + // Did we find a byproduct? + byproduct = fallback != nullptr; + return fallback; } -cmSourceFile* cmMakefile::GetSourceFileWithOutput( +cmSourcesWithOutput cmMakefile::GetSourcesWithOutput( const std::string& name) const { + // Linear search? Also see GetSourceFileWithOutput for detail. + if (!cmSystemTools::FileIsFullPath(name)) { + cmSourcesWithOutput sources; + sources.Target = this->LinearGetTargetWithOutput(name); + sources.Source = this->LinearGetSourceFileWithOutput( + name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct); + return sources; + } + // Otherwise we use an efficient lookup map. + auto o = this->OutputToSource.find(name); + if (o != this->OutputToSource.end()) { + return o->second.Sources; + } + return {}; +} + +cmSourceFile* cmMakefile::GetSourceFileWithOutput( + const std::string& name, cmSourceOutputKind kind) const +{ // If the queried path is not absolute we use the backward compatible // linear-time search for an output with a matching suffix. if (!cmSystemTools::FileIsFullPath(name)) { - return this->LinearGetSourceFileWithOutput(name); + bool byproduct = false; + return this->LinearGetSourceFileWithOutput(name, kind, byproduct); } // Otherwise we use an efficient lookup map. - OutputToSourceMap::const_iterator o = this->OutputToSource.find(name); - if (o != this->OutputToSource.end()) { - return (*o).second; + auto o = this->OutputToSource.find(name); + if (o != this->OutputToSource.end() && + (!o->second.Sources.SourceIsByproduct || + kind == cmSourceOutputKind::OutputOrByproduct)) { + // Source file could also be null pointer for example if we found the + // byproduct of a utility target or a PRE_BUILD, PRE_LINK, or POST_BUILD + // command of a target. + return o->second.Sources.Source; } return nullptr; } +bool cmMakefile::MightHaveCustomCommand(const std::string& name) const +{ + // This will have to be changed for delaying custom command creation, because + // GetSourceFileWithOutput requires the command to be already created. + if (cmSourceFile* sf = this->GetSourceFileWithOutput(name)) { + if (sf->GetCustomCommand()) { + return true; + } + } + return false; +} + #if !defined(CMAKE_BOOTSTRAP) cmSourceGroup* cmMakefile::GetSourceGroup( const std::vector<std::string>& name) const @@ -2188,8 +2396,7 @@ cmSourceGroup* cmMakefile::FindSourceGroup( const std::string& source, std::vector<cmSourceGroup>& groups) const { // First search for a group that lists the file explicitly. - for (std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin(); - sg != groups.rend(); ++sg) { + for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) { cmSourceGroup* result = sg->MatchChildrenFiles(source); if (result) { return result; @@ -2197,8 +2404,7 @@ cmSourceGroup* cmMakefile::FindSourceGroup( } // Now search for a group whose regex matches the file. - for (std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin(); - sg != groups.rend(); ++sg) { + for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) { cmSourceGroup* result = sg->MatchChildrenRegex(source); if (result) { return result; @@ -2281,8 +2487,7 @@ void cmMakefile::ExpandVariablesCMP0019() if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp); - for (std::vector<std::string>::iterator l = linkLibs.begin(); - l != linkLibs.end(); ++l) { + for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) { std::string libName = *l; if (libName == "optimized") { ++l; @@ -3325,6 +3530,22 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName, return this->CreateSource(sourceName, generated, kind); } +void cmMakefile::CreateGeneratedSource(const std::string& output) +{ + if (cmSourceFile* out = this->GetOrCreateSource( + output, true, cmSourceFileLocationKind::Known)) { + out->SetProperty("GENERATED", "1"); + } +} + +void cmMakefile::CreateGeneratedSources( + const std::vector<std::string>& outputs) +{ + for (std::string const& output : outputs) { + this->CreateGeneratedSource(output); + } +} + void cmMakefile::AddTargetObject(std::string const& tgtName, std::string const& objFile) { @@ -3841,7 +4062,7 @@ std::vector<std::string> cmMakefile::GetPropertyKeys() const cmTarget* cmMakefile::FindLocalNonAliasTarget(const std::string& name) const { - cmTargetMap::iterator i = this->Targets.find(name); + auto i = this->Targets.find(name); if (i != this->Targets.end()) { return &i->second; } @@ -3862,8 +4083,7 @@ cmTest* cmMakefile::CreateTest(const std::string& testName) cmTest* cmMakefile::GetTest(const std::string& testName) const { - std::map<std::string, cmTest*>::const_iterator mi = - this->Tests.find(testName); + auto mi = this->Tests.find(testName); if (mi != this->Tests.end()) { return mi->second; } @@ -3908,7 +4128,7 @@ std::string cmMakefile::FormatListFileStack() const std::ostringstream tmp; size_t depth = listFiles.size(); if (depth > 0) { - std::vector<std::string>::const_iterator it = listFiles.end(); + auto it = listFiles.end(); do { if (depth != listFiles.size()) { tmp << "\n "; @@ -3995,7 +4215,7 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name, { // Look for an imported target. These take priority because they // are more local in scope and do not have to be globally unique. - TargetMap::const_iterator imported = this->ImportedTargets.find(name); + auto imported = this->ImportedTargets.find(name); if (imported != this->ImportedTargets.end()) { return imported->second; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 09f53c9..db37477 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -6,18 +6,18 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmsys/RegularExpression.hxx" +#include <cstddef> #include <deque> #include <functional> #include <map> #include <memory> #include <set> #include <stack> -#include <stddef.h> #include <string> #include <unordered_map> #include <vector> -#include "cm_string_view.hxx" +#include <cm/string_view> #include "cmAlgorithms.h" #include "cmListFileCache.h" @@ -42,6 +42,7 @@ class cmExportBuildFileGenerator; class cmFunctionBlocker; class cmGeneratorExpressionEvaluationFile; class cmGlobalGenerator; +class cmImplicitDependsList; class cmInstallGenerator; class cmMessenger; class cmSourceFile; @@ -51,6 +52,24 @@ class cmTestGenerator; class cmVariableWatch; class cmake; +/** Flag if byproducts shall also be considered. */ +enum class cmSourceOutputKind +{ + OutputOnly, + OutputOrByproduct +}; + +/** Target and source file which have a specific output. */ +struct cmSourcesWithOutput +{ + /** Target with byproduct. */ + cmTarget* Target = nullptr; + + /** Source file with output or byproduct. */ + cmSourceFile* Source = nullptr; + bool SourceIsByproduct = false; +}; + /** A type-safe wrapper for a string representing a directory id. */ class cmDirectoryId { @@ -153,7 +172,7 @@ public: }; /** Add a custom command to the build. */ - void AddCustomCommandToTarget( + cmTarget* AddCustomCommandToTarget( const std::string& target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, @@ -162,17 +181,18 @@ public: const std::string& job_pool = "", bool command_expand_lists = false, ObjectLibraryCommands objLibraryCommands = RejectObjectLibraryCommands); cmSourceFile* AddCustomCommandToOutput( - const std::vector<std::string>& outputs, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, + const std::string& output, const std::vector<std::string>& depends, const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, const std::string& depfile = "", const std::string& job_pool = ""); cmSourceFile* AddCustomCommandToOutput( - const std::string& output, const std::vector<std::string>& depends, + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, @@ -183,6 +203,10 @@ public: const std::string& source, const cmCustomCommandLines& commandLines, const char* comment); + bool AppendCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines); /** * Add a define flag to the build. @@ -219,14 +243,6 @@ public: * Add a utility to the build. A utility target is a command that * is run every time the target is built. */ - cmTarget* AddUtilityCommand(const std::string& utilityName, - TargetOrigin origin, bool excludeFromAll, - const std::vector<std::string>& depends, - const char* workingDirectory, - const char* command, const char* arg1 = nullptr, - const char* arg2 = nullptr, - const char* arg3 = nullptr, - const char* arg4 = nullptr); cmTarget* AddUtilityCommand( const std::string& utilityName, TargetOrigin origin, bool excludeFromAll, const char* workingDirectory, const std::vector<std::string>& depends, @@ -687,10 +703,19 @@ public: } /** - * Is there a source file that has the provided source file as an output? - * if so then return it + * Return the target if the provided source name is a byproduct of a utility + * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command. + * Return the source file which has the provided source name as output. */ - cmSourceFile* GetSourceFileWithOutput(const std::string& outName) const; + cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const; + + /** + * Is there a source file that has the provided source name as an output? + * If so then return it. + */ + cmSourceFile* GetSourceFileWithOutput( + const std::string& name, + cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const; //! Add a new cmTest to the list of tests for this makefile. cmTest* CreateTest(const std::string& testName); @@ -914,6 +939,9 @@ protected: mutable cmTargetMap Targets; std::map<std::string, std::string> AliasTargets; + using TargetsVec = std::vector<cmTarget*>; + TargetsVec OrderedTargets; + using SourceFileVec = std::vector<cmSourceFile*>; SourceFileVec SourceFiles; @@ -1030,22 +1058,81 @@ private: bool escapeQuotes, bool noEscapes, bool atOnly, const char* filename, long line, bool replaceAt) const; + + bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const; + + void CommitCustomCommandToTarget( + cmTarget* target, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const char* comment, const char* workingDir, bool escapeOldStyle, + bool uses_terminal, const std::string& depfile, + const std::string& job_pool, bool command_expand_lists); + cmSourceFile* CommitCustomCommandToOutput( + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines, const char* comment, + const char* workingDir, bool replace, bool escapeOldStyle, + bool uses_terminal, bool command_expand_lists, const std::string& depfile, + const std::string& job_pool); + void CommitAppendCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines); + + void CommitUtilityCommand(cmTarget* target, const std::string& force, + const std::string& forceCMP0049, + const char* workingDirectory, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, + bool escapeOldStyle, const char* comment, + bool uses_terminal, bool command_expand_lists, + const std::string& job_pool); + + void CreateGeneratedSource(const std::string& output); + void CreateGeneratedSources(const std::vector<std::string>& outputs); + /** - * Old version of GetSourceFileWithOutput(const std::string&) kept for - * backward-compatibility. It implements a linear search and support - * relative file paths. It is used as a fall back by - * GetSourceFileWithOutput(const std::string&). + * See LinearGetSourceFileWithOutput for background information */ - cmSourceFile* LinearGetSourceFileWithOutput(const std::string& cname) const; + cmTarget* LinearGetTargetWithOutput(const std::string& name) const; + + /** + * Generalized old version of GetSourceFileWithOutput kept for + * backward-compatibility. It implements a linear search and supports + * relative file paths. It is used as a fall back by GetSourceFileWithOutput + * and GetSourcesWithOutput. + */ + cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name, + cmSourceOutputKind kind, + bool& byproduct) const; + + struct SourceEntry + { + cmSourcesWithOutput Sources; + }; // A map for fast output to input look up. - using OutputToSourceMap = std::unordered_map<std::string, cmSourceFile*>; + using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>; OutputToSourceMap OutputToSource; + void UpdateOutputToSourceMap(std::vector<std::string> const& byproducts, + cmTarget* target); + void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target); + void UpdateOutputToSourceMap(std::vector<std::string> const& outputs, - cmSourceFile* source); - void UpdateOutputToSourceMap(std::string const& output, - cmSourceFile* source); + cmSourceFile* source, bool byproduct); + void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source, + bool byproduct); + + /** + * Return if the provided source file might have a custom command. + */ + bool MightHaveCustomCommand(const std::string& name) const; bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature, std::string* error = nullptr) const; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index e44ca7b..91bd47e 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -8,7 +8,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmGeneratedFileStream.h" diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index d603dac..faa0d67 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -2,13 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileLibraryTargetGenerator.h" +#include <cstddef> #include <set> #include <sstream> -#include <stddef.h> #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmGeneratedFileStream.h" @@ -301,19 +301,16 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // Collect up flags to link in needed libraries. std::string linkLibs; - if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) { + std::unique_ptr<cmLinkLineComputer> linkLineComputer( + new cmLinkLineDeviceComputer( + this->LocalGenerator, + this->LocalGenerator->GetStateSnapshot().GetDirectory())); + linkLineComputer->SetForResponse(useResponseFileForLibs); + linkLineComputer->SetUseWatcomQuote(useWatcomQuote); + linkLineComputer->SetRelink(relink); - std::unique_ptr<cmLinkLineComputer> linkLineComputer( - new cmLinkLineDeviceComputer( - this->LocalGenerator, - this->LocalGenerator->GetStateSnapshot().GetDirectory())); - linkLineComputer->SetForResponse(useResponseFileForLibs); - linkLineComputer->SetUseWatcomQuote(useWatcomQuote); - linkLineComputer->SetRelink(relink); - - this->CreateLinkLibs(linkLineComputer.get(), linkLibs, - useResponseFileForLibs, depends); - } + this->CreateLinkLibs(linkLineComputer.get(), linkLibs, + useResponseFileForLibs, depends); // Construct object file lists that may be needed to expand the // rule. @@ -840,7 +837,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } // Create the archive with the first set of objects. - std::vector<std::string>::iterator osi = object_strings.begin(); + auto osi = object_strings.begin(); { vars.Objects = osi->c_str(); for (std::string const& acc : archiveCreateCommands) { diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 1f6986b..d352f8e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -2,9 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileTargetGenerator.h" +#include <cstdio> #include <memory> #include <sstream> -#include <stdio.h> #include <utility> #include "cmAlgorithms.h" @@ -150,18 +150,14 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() { // -- Write the custom commands for this target - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - // Evaluates generator expressions and expands prop_value auto evaluatedFiles = - [this, &config](const char* prop_value) -> std::vector<std::string> { + [this](const char* prop_value) -> std::vector<std::string> { std::vector<std::string> files; - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value); - cmExpandList(cge->Evaluate(this->LocalGenerator, config, false, - this->GeneratorTarget, nullptr, nullptr), - files); + cmExpandList( + cmGeneratorExpression::Evaluate(prop_value, this->LocalGenerator, + this->ConfigName, this->GeneratorTarget), + files); return files; }; @@ -191,7 +187,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // First generate the object rule files. Save a list of all object // files for this target. std::vector<cmSourceFile const*> customCommands; - this->GeneratorTarget->GetCustomCommands(customCommands, config); + this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName); std::string currentBinDir = this->LocalGenerator->GetCurrentBinaryDirectory(); for (cmSourceFile const* sf : customCommands) { @@ -224,7 +220,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->GetPostBuildCommands()); for (const auto& be : buildEventCommands) { - const std::vector<std::string>& byproducts = be.GetByproducts(); + cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator); + const std::vector<std::string>& byproducts = beg.GetByproducts(); for (std::string const& byproduct : byproducts) { this->CleanFiles.insert( this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, @@ -233,17 +230,17 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } std::vector<cmSourceFile const*> headerSources; - this->GeneratorTarget->GetHeaderSources(headerSources, config); + this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( headerSources, this->MacOSXContentGenerator); std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, config); + this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName); 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); + this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName); for (cmSourceFile const* sf : externalObjects) { auto const& objectFileName = sf->GetFullPath(); if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { @@ -251,7 +248,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } std::vector<cmSourceFile const*> objectSources; - this->GeneratorTarget->GetObjectSources(objectSources, config); + this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName); for (cmSourceFile const* sf : objectSources) { // Generate this object file's rule file. this->WriteObjectRuleFiles(*sf); @@ -1610,10 +1607,8 @@ void cmMakefileTargetGenerator::CreateLinkLibs( { std::string frameworkPath; std::string linkPath; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); cmComputeLinkInformation* pcli = - this->GeneratorTarget->GetLinkInformation(config); + this->GeneratorTarget->GetLinkInformation(this->ConfigName); this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath, linkPath); linkLibs = frameworkPath + linkPath + linkLibs; @@ -1706,13 +1701,12 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, bool useResponseFile = this->Makefile->IsOn(responseVar); std::vector<std::string> includes; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, - lang, config); + lang, this->ConfigName); std::string includeFlags = this->LocalGenerator->GetIncludeFlags( - includes, this->GeneratorTarget, lang, false, useResponseFile, config); + includes, this->GeneratorTarget, lang, false, useResponseFile, + this->ConfigName); if (includeFlags.empty()) { return; } diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index d4045b3..47e2665 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -7,7 +7,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx index 83c22aa..4ea3638 100644 --- a/Source/cmMathCommand.cxx +++ b/Source/cmMathCommand.cxx @@ -8,7 +8,7 @@ #include "cmMessageType.h" #include "cm_kwiml.h" -#include <stdio.h> +#include <cstdio> namespace { bool HandleExprCommand(std::vector<std::string> const& args, diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx index 1ff741e..a121332 100644 --- a/Source/cmNewLineStyle.cxx +++ b/Source/cmNewLineStyle.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmNewLineStyle.h" -#include <stddef.h> +#include <cstddef> cmNewLineStyle::cmNewLineStyle() = default; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index bc2506e..bd5abd1 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -3,14 +3,14 @@ #include "cmNinjaNormalTargetGenerator.h" #include <algorithm> -#include <assert.h> +#include <cassert> #include <iterator> #include <map> #include <set> #include <sstream> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmCustomCommand.h" // IWYU pragma: keep diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 90b59e7..613e7aa 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -5,13 +5,13 @@ #include "cm_jsoncpp_value.h" #include "cm_jsoncpp_writer.h" #include <algorithm> -#include <assert.h> +#include <cassert> #include <iterator> #include <map> #include <ostream> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" @@ -777,11 +777,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() << cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) << " target " << this->GetTargetName() << "\n\n"; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); { std::vector<cmSourceFile const*> customCommands; - this->GeneratorTarget->GetCustomCommands(customCommands, config); + this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName); for (cmSourceFile const* sf : customCommands) { cmCustomCommand const* cc = sf->GetCustomCommand(); this->GetLocalGenerator()->AddCustomCommandTarget( @@ -793,13 +791,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() } { std::vector<cmSourceFile const*> headerSources; - this->GeneratorTarget->GetHeaderSources(headerSources, config); + this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( headerSources, this->MacOSXContentGenerator.get()); } { std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, config); + this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( extraSources, this->MacOSXContentGenerator.get()); } @@ -808,7 +806,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; - this->GeneratorTarget->GetExternalObjects(externalObjects, config); + this->GeneratorTarget->GetExternalObjects(externalObjects, + this->ConfigName); for (cmSourceFile const* sf : externalObjects) { const auto objectFileName = this->GetSourceFilePath(sf); if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { @@ -863,7 +862,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() { std::vector<cmSourceFile const*> objectSources; - this->GeneratorTarget->GetObjectSources(objectSources, config); + this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName); for (cmSourceFile const* sf : objectSources) { this->WriteObjectBuildStatement(sf); } @@ -1318,14 +1317,11 @@ void cmNinjaTargetGenerator::AdditionalCleanFiles() this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) { cmLocalNinjaGenerator* lg = this->LocalGenerator; std::vector<std::string> cleanFiles; - { - cmGeneratorExpression ge; - auto cge = ge.Parse(prop_value); - cmExpandList(cge->Evaluate( - lg, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"), - false, this->GeneratorTarget, nullptr, nullptr), - cleanFiles); - } + cmExpandList(cmGeneratorExpression::Evaluate( + prop_value, lg, + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"), + this->GeneratorTarget), + cleanFiles); std::string const& binaryDir = lg->GetCurrentBinaryDirectory(); cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator(); for (std::string const& cleanFile : cleanFiles) { diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index a0a0989..22e59ac 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmOptionCommand.h" -#include <sstream> - #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -74,13 +72,13 @@ bool cmOptionCommand(std::vector<std::string> const& args, const auto* existsAfterSet = status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); if (!existsAfterSet) { - std::ostringstream w; - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077) - << "\n" - "For compatibility with older versions of CMake, option " - "is clearing the normal variable '" - << args[0] << "'."; - status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + status.GetMakefile().IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0077), + "\n" + "For compatibility with older versions of CMake, option " + "is clearing the normal variable '", + args[0], "'.")); } } return true; diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 35ec33e..916a9f7 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -11,7 +11,7 @@ #include "cmake.h" #include <algorithm> -#include <assert.h> +#include <cassert> #include <functional> #include <sstream> #include <vector> @@ -128,7 +128,7 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir, // Check if the file will be built by cmake. std::set<std::string> const& files = (this->GlobalGenerator->GetDirectoryContent(dir, false)); - std::set<std::string>::const_iterator fi = files.find(name); + auto fi = files.find(name); return fi != files.end(); } @@ -186,9 +186,9 @@ bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir) // know the soname just look at all files that start with the // file name. Usually the soname starts with the library name. std::string base = this->FileName; - std::set<std::string>::const_iterator first = files.lower_bound(base); + auto first = files.lower_bound(base); ++base.back(); - std::set<std::string>::const_iterator last = files.upper_bound(base); + auto last = files.upper_bound(base); if (first != last) { return true; } @@ -380,7 +380,7 @@ void cmOrderDirectories::CollectOriginalDirectories() int cmOrderDirectories::AddOriginalDirectory(std::string const& dir) { // Add the runtime directory with a unique index. - std::map<std::string, int>::iterator i = this->DirectoryIndex.find(dir); + auto i = this->DirectoryIndex.find(dir); if (i == this->DirectoryIndex.end()) { std::map<std::string, int>::value_type entry( dir, static_cast<int>(this->OriginalDirectories.size())); @@ -441,8 +441,7 @@ void cmOrderDirectories::FindConflicts() std::sort(cl.begin(), cl.end()); // Make the edge list unique so cycle detection will be reliable. - ConflictList::iterator last = - std::unique(cl.begin(), cl.end(), cmOrderDirectoriesCompare()); + auto last = std::unique(cl.begin(), cl.end(), cmOrderDirectoriesCompare()); cl.erase(last, cl.end()); } @@ -466,14 +465,14 @@ void cmOrderDirectories::FindImplicitConflicts() } // Warn about the conflicts. - std::ostringstream w; - w << "Cannot generate a safe " << this->Purpose << " for target " - << this->Target->GetName() - << " because files in some directories may conflict with " - << " libraries in implicit directories:\n" - << text << "Some of these libraries may not be found correctly."; this->GlobalGenerator->GetCMakeInstance()->IssueMessage( - MessageType::WARNING, w.str(), this->Target->GetBacktrace()); + MessageType::WARNING, + cmStrCat("Cannot generate a safe ", this->Purpose, " for target ", + this->Target->GetName(), + " because files in some directories may " + "conflict with libraries in implicit directories:\n", + text, "Some of these libraries may not be found correctly."), + this->Target->GetBacktrace()); } void cmOrderDirectories::OrderDirectories() @@ -553,8 +552,7 @@ bool cmOrderDirectories::IsSameDirectory(std::string const& l, std::string const& cmOrderDirectories::GetRealPath(std::string const& dir) { - std::map<std::string, std::string>::iterator i = - this->RealPaths.lower_bound(dir); + auto i = this->RealPaths.lower_bound(dir); if (i == this->RealPaths.end() || this->RealPaths.key_comp()(dir, i->first)) { using value_type = std::map<std::string, std::string>::value_type; diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index bf516e3..e602a6d 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -3,8 +3,8 @@ #include "cmOutputConverter.h" #include <algorithm> -#include <assert.h> -#include <ctype.h> +#include <cassert> +#include <cctype> #include <set> #include <vector> diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index 671efe7..c2053c7 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -6,7 +6,8 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmStateSnapshot.h" -#include "cm_string_view.hxx" + +#include <cm/string_view> #include <string> diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index c034fdd..d9a433d 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -4,9 +4,9 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +#include <cstdio> #include <map> #include <set> -#include <stdio.h> #include <utility> #include "cmAlgorithms.h" @@ -367,8 +367,7 @@ protected: std::string fullPath = this->FullPath(file, extraPath); // Try to find the file's instance of cmDependInformation. - DependInformationMapType::const_iterator result = - this->DependInformationMap.find(fullPath); + auto result = this->DependInformationMap.find(fullPath); if (result != this->DependInformationMap.end()) { // Found an instance, return it. return result->second; @@ -398,7 +397,7 @@ protected: if (m != this->DirectoryToFileToPathMap.end()) { FileToPathMapType& map = m->second; - FileToPathMapType::iterator p = map.find(fname); + auto p = map.find(fname); if (p != map.end()) { return p->second; } diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index a4dd70d..c802fb4 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -14,7 +14,7 @@ #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cm_string_view.hxx" +#include <cm/string_view> static std::string EscapeArg(const std::string& arg) { @@ -116,8 +116,8 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args, return false; } - std::vector<std::string>::const_iterator argIter = args.begin(); - std::vector<std::string>::const_iterator argEnd = args.end(); + auto argIter = args.begin(); + auto argEnd = args.end(); bool parseFromArgV = false; unsigned long argvStart = 0; if (*argIter == "PARSE_ARGV") { diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index d33cd32..c8bc56d 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -8,11 +8,11 @@ #include "cmSystemTools.h" #include "cmVersion.h" -#include <assert.h> -#include <ctype.h> +#include <cassert> +#include <cctype> +#include <cstdio> +#include <cstring> #include <sstream> -#include <stdio.h> -#include <string.h> #include <vector> static bool stringToId(const char* input, cmPolicies::PolicyID& pid) diff --git a/Source/cmProcessOutput.h b/Source/cmProcessOutput.h index 400354c..3db47a4 100644 --- a/Source/cmProcessOutput.h +++ b/Source/cmProcessOutput.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stddef.h> +#include <cstddef> #include <string> #include <vector> diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h index c205a8f..7d97e36 100644 --- a/Source/cmProcessTools.h +++ b/Source/cmProcessTools.h @@ -6,8 +6,8 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmProcessOutput.h" +#include <cstring> #include <iosfwd> -#include <string.h> #include <string> /** \class cmProcessTools diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index e74fff6..373e767 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -8,9 +8,9 @@ #include <cstdio> #include <functional> #include <limits> -#include <sstream> #include <utility> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" @@ -18,40 +18,39 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +static bool IncludeByVariable(cmExecutionStatus& status, + const std::string& variable); +static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name, + std::string const& value); -// cmProjectCommand -bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmProjectCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("PROJECT called with incorrect number of arguments"); + status.SetError("PROJECT called with incorrect number of arguments"); return false; } - if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE_BEFORE")) { + cmMakefile& mf = status.GetMakefile(); + if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) { return false; } std::string const& projectName = args[0]; - this->Makefile->SetProjectName(projectName); + mf.SetProjectName(projectName); - this->Makefile->AddCacheDefinition( - projectName + "_BINARY_DIR", - this->Makefile->GetCurrentBinaryDirectory().c_str(), - "Value Computed by CMake", cmStateEnums::STATIC); - this->Makefile->AddCacheDefinition( - projectName + "_SOURCE_DIR", - this->Makefile->GetCurrentSourceDirectory().c_str(), - "Value Computed by CMake", cmStateEnums::STATIC); + mf.AddCacheDefinition(projectName + "_BINARY_DIR", + mf.GetCurrentBinaryDirectory().c_str(), + "Value Computed by CMake", cmStateEnums::STATIC); + mf.AddCacheDefinition(projectName + "_SOURCE_DIR", + mf.GetCurrentSourceDirectory().c_str(), + "Value Computed by CMake", cmStateEnums::STATIC); - this->Makefile->AddDefinition("PROJECT_BINARY_DIR", - this->Makefile->GetCurrentBinaryDirectory()); - this->Makefile->AddDefinition("PROJECT_SOURCE_DIR", - this->Makefile->GetCurrentSourceDirectory()); + mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory()); + mf.AddDefinition("PROJECT_SOURCE_DIR", mf.GetCurrentSourceDirectory()); - this->Makefile->AddDefinition("PROJECT_NAME", projectName); + mf.AddDefinition("PROJECT_NAME", projectName); // Set the CMAKE_PROJECT_NAME variable to be the highest-level // project name in the tree. If there are two project commands @@ -59,12 +58,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, // CMakeLists.txt file, then go with the last one, so that // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build // will work. - if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") || - (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName); - this->Makefile->AddCacheDefinition( - "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake", - cmStateEnums::STATIC); + if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) { + mf.AddDefinition("CMAKE_PROJECT_NAME", projectName); + mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(), + "Value Computed by CMake", cmStateEnums::STATIC); } bool haveVersion = false; @@ -91,9 +88,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, for (size_t i = 1; i < args.size(); ++i) { if (args[i] == "LANGUAGES") { if (haveLanguages) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "LANGUAGES may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "LANGUAGES may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -107,12 +103,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, "the following parameters must be specified after LANGUAGES " "keyword: ", cmJoin(languages, ", "), '.'); - this->Makefile->IssueMessage(MessageType::WARNING, msg); + mf.IssueMessage(MessageType::WARNING, msg); } } else if (args[i] == "VERSION") { if (haveVersion) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "VERSION may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "VERSION may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -121,8 +117,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, missedValueReporter(); } doing = DoingVersion; - missedValueReporter = [this, &resetReporter]() { - this->Makefile->IssueMessage( + missedValueReporter = [&mf, &resetReporter]() { + mf.IssueMessage( MessageType::WARNING, "VERSION keyword not followed by a value or was followed by a " "value that expanded to nothing."); @@ -130,9 +126,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, }; } else if (args[i] == "DESCRIPTION") { if (haveDescription) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "DESCRIPTION may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "DESCRIPTION may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -141,8 +136,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, missedValueReporter(); } doing = DoingDescription; - missedValueReporter = [this, &resetReporter]() { - this->Makefile->IssueMessage( + missedValueReporter = [&mf, &resetReporter]() { + mf.IssueMessage( MessageType::WARNING, "DESCRIPTION keyword not followed by a value or was followed " "by a value that expanded to nothing."); @@ -150,16 +145,15 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, }; } else if (args[i] == "HOMEPAGE_URL") { if (haveHomepage) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "HOMEPAGE_URL may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "HOMEPAGE_URL may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } haveHomepage = true; doing = DoingHomepage; - missedValueReporter = [this, &resetReporter]() { - this->Makefile->IssueMessage( + missedValueReporter = [&mf, &resetReporter]() { + mf.IssueMessage( MessageType::WARNING, "HOMEPAGE_URL keyword not followed by a value or was followed " "by a value that expanded to nothing."); @@ -191,10 +185,9 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages && !languages.empty()) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "project with VERSION, DESCRIPTION or HOMEPAGE_URL must " - "use LANGUAGES before language names."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "project with VERSION, DESCRIPTION or HOMEPAGE_URL must " + "use LANGUAGES before language names."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -203,13 +196,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } cmPolicies::PolicyStatus const cmp0048 = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0048); + mf.GetPolicyStatus(cmPolicies::CMP0048); if (haveVersion) { // Set project VERSION variables to given values if (cmp0048 == cmPolicies::OLD || cmp0048 == cmPolicies::WARN) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "VERSION not allowed unless CMP0048 is set to NEW"); + mf.IssueMessage(MessageType::FATAL_ERROR, + "VERSION not allowed unless CMP0048 is set to NEW"); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -218,13 +210,13 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)"); if (!vx.find(version)) { std::string e = R"(VERSION ")" + version + R"(" format invalid.)"; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); + mf.IssueMessage(MessageType::FATAL_ERROR, e); cmSystemTools::SetFatalErrorOccured(); return true; } cmPolicies::PolicyStatus const cmp0096 = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0096); + mf.GetPolicyStatus(cmPolicies::CMP0096); constexpr std::size_t MAX_VERSION_COMPONENTS = 4u; std::string version_string; @@ -258,34 +250,30 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, std::string vv; vv = projectName + "_VERSION"; - this->Makefile->AddDefinition("PROJECT_VERSION", version_string); - this->Makefile->AddDefinition(vv, version_string); + mf.AddDefinition("PROJECT_VERSION", version_string); + mf.AddDefinition(vv, version_string); vv = projectName + "_VERSION_MAJOR"; - this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", - version_components[0]); - this->Makefile->AddDefinition(vv, version_components[0]); + mf.AddDefinition("PROJECT_VERSION_MAJOR", version_components[0]); + mf.AddDefinition(vv, version_components[0]); vv = projectName + "_VERSION_MINOR"; - this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", - version_components[1]); - this->Makefile->AddDefinition(vv, version_components[1]); + mf.AddDefinition("PROJECT_VERSION_MINOR", version_components[1]); + mf.AddDefinition(vv, version_components[1]); vv = projectName + "_VERSION_PATCH"; - this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", - version_components[2]); - this->Makefile->AddDefinition(vv, version_components[2]); + mf.AddDefinition("PROJECT_VERSION_PATCH", version_components[2]); + mf.AddDefinition(vv, version_components[2]); vv = projectName + "_VERSION_TWEAK"; - this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", - version_components[3]); - this->Makefile->AddDefinition(vv, version_components[3]); + mf.AddDefinition("PROJECT_VERSION_TWEAK", version_components[3]); + mf.AddDefinition(vv, version_components[3]); // Also, try set top level variables - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", version_string.c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", - version_components[0].c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", - version_components[1].c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", - version_components[2].c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", - version_components[3].c_str()); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION", version_string); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_MAJOR", + version_components[0]); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_MINOR", + version_components[1]); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_PATCH", + version_components[2]); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_TWEAK", + version_components[3]); } else if (cmp0048 != cmPolicies::OLD) { // Set project VERSION variables to empty std::vector<std::string> vv = { "PROJECT_VERSION", @@ -298,7 +286,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, projectName + "_VERSION_MINOR", projectName + "_VERSION_PATCH", projectName + "_VERSION_TWEAK" }; - if (this->Makefile->IsRootMakefile()) { + if (mf.IsRootMakefile()) { vv.emplace_back("CMAKE_PROJECT_VERSION"); vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR"); vv.emplace_back("CMAKE_PROJECT_VERSION_MINOR"); @@ -307,7 +295,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } std::string vw; for (std::string const& i : vv) { - const char* const v = this->Makefile->GetDefinition(i); + const char* const v = mf.GetDefinition(i); if (v && *v) { if (cmp0048 == cmPolicies::WARN) { if (!injectedProjectCommand) { @@ -315,51 +303,54 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, vw += i; } } else { - this->Makefile->AddDefinition(i, ""); + mf.AddDefinition(i, ""); } } } if (!vw.empty()) { - std::ostringstream w; - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0048) - << "\nThe following variable(s) would be set to empty:" << vw; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + mf.IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0048), + "\nThe following variable(s) would be set to empty:", vw)); } } - this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description); - this->Makefile->AddDefinition(projectName + "_DESCRIPTION", description); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str()); + mf.AddDefinition("PROJECT_DESCRIPTION", description); + mf.AddDefinition(projectName + "_DESCRIPTION", description); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_DESCRIPTION", description); - this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage); - this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", homepage); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str()); + mf.AddDefinition("PROJECT_HOMEPAGE_URL", homepage); + mf.AddDefinition(projectName + "_HOMEPAGE_URL", homepage); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_HOMEPAGE_URL", homepage); if (languages.empty()) { // if no language is specified do c and c++ languages = { "C", "CXX" }; } - this->Makefile->EnableLanguage(languages, false); + mf.EnableLanguage(languages, false); - if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE")) { + if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE")) { return false; } - if (!this->IncludeByVariable("CMAKE_PROJECT_" + projectName + "_INCLUDE")) { + if (!IncludeByVariable(status, + "CMAKE_PROJECT_" + projectName + "_INCLUDE")) { return false; } return true; } -bool cmProjectCommand::IncludeByVariable(const std::string& variable) +static bool IncludeByVariable(cmExecutionStatus& status, + const std::string& variable) { - const char* const include = this->Makefile->GetDefinition(variable); + cmMakefile& mf = status.GetMakefile(); + const char* const include = mf.GetDefinition(variable); if (!include) { return true; } - const bool readit = this->Makefile->ReadDependentFile(include); + const bool readit = mf.ReadDependentFile(include); if (readit) { return true; } @@ -368,24 +359,20 @@ bool cmProjectCommand::IncludeByVariable(const std::string& variable) return true; } - std::string m = cmStrCat("could not find file:\n" - " ", - include); - this->SetError(m); + status.SetError(cmStrCat("could not find file:\n ", include)); return false; } -void cmProjectCommand::TopLevelCMakeVarCondSet(const char* const name, - const char* const value) +static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name, + std::string const& value) { // Set the CMAKE_PROJECT_XXX variable to be the highest-level // project name in the tree. If there are two project commands // in the same CMakeLists.txt file, and it is the top level // CMakeLists.txt file, then go with the last one. - if (!this->Makefile->GetDefinition(name) || - (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition(name, value); - this->Makefile->AddCacheDefinition(name, value, "Value Computed by CMake", - cmStateEnums::STATIC); + if (!mf.GetDefinition(name) || mf.IsRootMakefile()) { + mf.AddDefinition(name, value); + mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake", + cmStateEnums::STATIC); } } diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h index 8b9bcc8..c06b459 100644 --- a/Source/cmProjectCommand.h +++ b/Source/cmProjectCommand.h @@ -8,41 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmProjectCommand - * \brief Specify the name for this build project. - * - * cmProjectCommand is used to specify a name for this build project. - * It is defined once per set of CMakeList.txt files (including - * all subdirectories). Currently it just sets the name of the workspace - * file for Microsoft Visual C++ - */ -class cmProjectCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmProjectCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool IncludeByVariable(const std::string& variable); - void TopLevelCMakeVarCondSet(const char* name, const char* value); -}; +bool cmProjectCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx index 5daaf9b..f752ed7 100644 --- a/Source/cmPropertyDefinitionMap.cxx +++ b/Source/cmPropertyDefinitionMap.cxx @@ -10,7 +10,7 @@ void cmPropertyDefinitionMap::DefineProperty(const std::string& name, const char* FullDescription, bool chain) { - cmPropertyDefinitionMap::iterator it = this->find(name); + auto it = this->find(name); cmPropertyDefinition* prop; if (it == this->end()) { prop = &(*this)[name]; @@ -26,7 +26,7 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const { - cmPropertyDefinitionMap::const_iterator it = this->find(name); + auto it = this->find(name); if (it == this->end()) { return false; } diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx index ba82813..cc4df8f 100644 --- a/Source/cmQTWrapCPPCommand.cxx +++ b/Source/cmQTWrapCPPCommand.cxx @@ -3,44 +3,41 @@ #include "cmQTWrapCPPCommand.h" #include "cmCustomCommandLines.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <utility> - -class cmExecutionStatus; - -// cmQTWrapCPPCommand -bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmQTWrapCPPCommand(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; } + cmMakefile& mf = status.GetMakefile(); + // Get the moc executable to run in the custom command. - std::string const& moc_exe = - this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE"); + std::string const& moc_exe = mf.GetRequiredDefinition("QT_MOC_EXECUTABLE"); // Get the variable holding the list of sources. std::string const& sourceList = args[1]; - std::string sourceListValue = this->Makefile->GetSafeDefinition(sourceList); + std::string sourceListValue = mf.GetSafeDefinition(sourceList); // Create a rule for all sources listed. for (std::string const& arg : cmMakeRange(args).advance(2)) { - cmSourceFile* curr = this->Makefile->GetSource(arg); + cmSourceFile* curr = mf.GetSource(arg); // if we should wrap the class if (!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE"))) { // Compute the name of the file to generate. std::string srcName = cmSystemTools::GetFilenameWithoutLastExtension(arg); - std::string newName = cmStrCat( - this->Makefile->GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); - cmSourceFile* sf = this->Makefile->GetOrCreateSource(newName, true); + std::string newName = + cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); + cmSourceFile* sf = mf.GetOrCreateSource(newName, true); if (curr) { sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT")); } @@ -51,9 +48,9 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, hname = arg; } else { if (curr && curr->GetIsGenerated()) { - hname = this->Makefile->GetCurrentBinaryDirectory(); + hname = mf.GetCurrentBinaryDirectory(); } else { - hname = this->Makefile->GetCurrentSourceDirectory(); + hname = mf.GetCurrentSourceDirectory(); } hname += "/"; hname += arg; @@ -66,14 +63,8 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, sourceListValue += newName; // Create the custom command to generate the file. - cmCustomCommandLine commandLine; - commandLine.push_back(moc_exe); - commandLine.push_back("-o"); - commandLine.push_back(newName); - commandLine.push_back(hname); - - cmCustomCommandLines commandLines; - commandLines.push_back(std::move(commandLine)); + cmCustomCommandLines commandLines = + cmMakeSingleCommandLine({ moc_exe, "-o", newName, hname }); std::vector<std::string> depends; depends.push_back(moc_exe); @@ -81,13 +72,13 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, std::string no_main_dependency; const char* no_working_dir = nullptr; - this->Makefile->AddCustomCommandToOutput( - newName, depends, no_main_dependency, commandLines, "Qt Wrapped File", - no_working_dir); + mf.AddCustomCommandToOutput(newName, depends, no_main_dependency, + commandLines, "Qt Wrapped File", + no_working_dir); } } // Store the final list of source files. - this->Makefile->AddDefinition(sourceList, sourceListValue); + mf.AddDefinition(sourceList, sourceListValue); return true; } diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h index 88a2210..75fa180 100644 --- a/Source/cmQTWrapCPPCommand.h +++ b/Source/cmQTWrapCPPCommand.h @@ -8,35 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmQTWrapCPPCommand - * \brief Create moc file rules for Qt classes - * - * cmQTWrapCPPCommand is used to create wrappers for Qt classes into - * normal C++ - */ -class cmQTWrapCPPCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmQTWrapCPPCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmQTWrapCPPCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx index 8bc914f..66c0228 100644 --- a/Source/cmQTWrapUICommand.cxx +++ b/Source/cmQTWrapUICommand.cxx @@ -3,51 +3,47 @@ #include "cmQTWrapUICommand.h" #include "cmCustomCommandLines.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <utility> - -class cmExecutionStatus; - -// cmQTWrapUICommand -bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmQTWrapUICommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 4) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } + cmMakefile& mf = status.GetMakefile(); + // Get the uic and moc executables to run in the custom commands. - std::string const& uic_exe = - this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE"); - std::string const& moc_exe = - this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE"); + std::string const& uic_exe = mf.GetRequiredDefinition("QT_UIC_EXECUTABLE"); + std::string const& moc_exe = mf.GetRequiredDefinition("QT_MOC_EXECUTABLE"); // Get the variable holding the list of sources. std::string const& headerList = args[1]; std::string const& sourceList = args[2]; - std::string headerListValue = this->Makefile->GetSafeDefinition(headerList); - std::string sourceListValue = this->Makefile->GetSafeDefinition(sourceList); + std::string headerListValue = mf.GetSafeDefinition(headerList); + std::string sourceListValue = mf.GetSafeDefinition(sourceList); // Create rules for all sources listed. for (std::string const& arg : cmMakeRange(args).advance(3)) { - cmSourceFile* curr = this->Makefile->GetSource(arg); + cmSourceFile* curr = mf.GetSource(arg); // if we should wrap the class if (!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE"))) { // Compute the name of the files to generate. std::string srcName = cmSystemTools::GetFilenameWithoutLastExtension(arg); - std::string hName = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), - '/', srcName, ".h"); - std::string cxxName = cmStrCat( - this->Makefile->GetCurrentBinaryDirectory(), '/', srcName, ".cxx"); - std::string mocName = cmStrCat( - this->Makefile->GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); + std::string hName = + cmStrCat(mf.GetCurrentBinaryDirectory(), '/', srcName, ".h"); + std::string cxxName = + cmStrCat(mf.GetCurrentBinaryDirectory(), '/', srcName, ".cxx"); + std::string mocName = + cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); // Compute the name of the ui file from which to generate others. std::string uiName; @@ -55,9 +51,9 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args, uiName = arg; } else { if (curr && curr->GetIsGenerated()) { - uiName = this->Makefile->GetCurrentBinaryDirectory(); + uiName = mf.GetCurrentBinaryDirectory(); } else { - uiName = this->Makefile->GetCurrentSourceDirectory(); + uiName = mf.GetCurrentSourceDirectory(); } uiName += "/"; uiName += arg; @@ -78,56 +74,34 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args, sourceListValue += mocName; // set up .ui to .h and .cxx command - cmCustomCommandLine hCommand; - hCommand.push_back(uic_exe); - hCommand.push_back("-o"); - hCommand.push_back(hName); - hCommand.push_back(uiName); - cmCustomCommandLines hCommandLines; - hCommandLines.push_back(std::move(hCommand)); - - cmCustomCommandLine cxxCommand; - cxxCommand.push_back(uic_exe); - cxxCommand.push_back("-impl"); - cxxCommand.push_back(hName); - cxxCommand.push_back("-o"); - cxxCommand.push_back(cxxName); - cxxCommand.push_back(uiName); - cmCustomCommandLines cxxCommandLines; - cxxCommandLines.push_back(std::move(cxxCommand)); - - cmCustomCommandLine mocCommand; - mocCommand.push_back(moc_exe); - mocCommand.push_back("-o"); - mocCommand.push_back(mocName); - mocCommand.push_back(hName); - cmCustomCommandLines mocCommandLines; - mocCommandLines.push_back(std::move(mocCommand)); + cmCustomCommandLines hCommandLines = + cmMakeSingleCommandLine({ uic_exe, "-o", hName, uiName }); + cmCustomCommandLines cxxCommandLines = cmMakeSingleCommandLine( + { uic_exe, "-impl", hName, "-o", cxxName, uiName }); + cmCustomCommandLines mocCommandLines = + cmMakeSingleCommandLine({ moc_exe, "-o", mocName, hName }); std::vector<std::string> depends; depends.push_back(uiName); std::string no_main_dependency; const char* no_comment = nullptr; const char* no_working_dir = nullptr; - this->Makefile->AddCustomCommandToOutput( - hName, depends, no_main_dependency, hCommandLines, no_comment, - no_working_dir); + mf.AddCustomCommandToOutput(hName, depends, no_main_dependency, + hCommandLines, no_comment, no_working_dir); depends.push_back(hName); - this->Makefile->AddCustomCommandToOutput( - cxxName, depends, no_main_dependency, cxxCommandLines, no_comment, - no_working_dir); + mf.AddCustomCommandToOutput(cxxName, depends, no_main_dependency, + cxxCommandLines, no_comment, no_working_dir); depends.clear(); depends.push_back(hName); - this->Makefile->AddCustomCommandToOutput( - mocName, depends, no_main_dependency, mocCommandLines, no_comment, - no_working_dir); + mf.AddCustomCommandToOutput(mocName, depends, no_main_dependency, + mocCommandLines, no_comment, no_working_dir); } } // Store the final list of source files and headers. - this->Makefile->AddDefinition(sourceList, sourceListValue); - this->Makefile->AddDefinition(headerList, headerListValue); + mf.AddDefinition(sourceList, sourceListValue); + mf.AddDefinition(headerList, headerListValue); return true; } diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h index 6a346d4..a17ef54 100644 --- a/Source/cmQTWrapUICommand.h +++ b/Source/cmQTWrapUICommand.h @@ -8,34 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmQTWrapUICommand - * \brief Create .h and .cxx files rules for Qt user interfaces files - * - * cmQTWrapUICommand is used to create wrappers for Qt classes into normal C++ - */ -class cmQTWrapUICommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmQTWrapUICommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmQTWrapUICommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 83df335..57c8825 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -24,8 +24,6 @@ void MergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, std::initializer_list<cm::string_view> valueOpts, bool isQt5) { - using Iter = std::vector<std::string>::iterator; - using CIter = std::vector<std::string>::const_iterator; if (newOpts.empty()) { return; } @@ -35,10 +33,10 @@ void MergeOptions(std::vector<std::string>& baseOpts, } std::vector<std::string> extraOpts; - for (CIter fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd; + for (auto fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd; ++fit) { std::string const& newOpt = *fit; - Iter existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt); + auto existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt); if (existIt != baseOpts.end()) { if (newOpt.size() >= 2) { // Acquire the option name @@ -55,8 +53,8 @@ void MergeOptions(std::vector<std::string>& baseOpts, } // Test if this is a value option and change the existing value if (!optName.empty() && cmContains(valueOpts, optName)) { - const Iter existItNext(existIt + 1); - const CIter fitNext(fit + 1); + const auto existItNext(existIt + 1); + const auto fitNext(fit + 1); if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) { *existItNext = *fitNext; ++fit; @@ -164,6 +162,15 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command) return res; } +std::string cmQtAutoGen::ParentDir(cm::string_view filename) +{ + auto slashPos = filename.rfind('/'); + if (slashPos == cm::string_view::npos) { + return std::string(); + } + return std::string(filename.substr(0, slashPos)); +} + std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename) { auto slashPos = filename.rfind('/'); diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index fb15586..2a28c1e 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cm_string_view.hxx" +#include <cm/string_view> #include <memory> #include <string> @@ -80,6 +80,9 @@ public: static std::string QuotedCommand(std::vector<std::string> const& command); + /// @brief Returns the parent directory of the file (thread safe) + static std::string ParentDir(cm::string_view filename); + /// @brief Returns the parent directory of the file with a "/" suffix static std::string SubDirPrefix(cm::string_view filename); diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index abc69d0..576a034 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -17,7 +17,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" -#include "cm_memory.hxx" +#include <cm/memory> #include <utility> diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index d6916b0..9045722 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1,9 +1,11 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenInitializer.h" + #include "cmQtAutoGen.h" #include "cmQtAutoGenGlobalInitializer.h" +#include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmFilePathChecksum.h" @@ -39,9 +41,11 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> + +namespace { -static std::size_t GetParallelCPUCount() +std::size_t GetParallelCPUCount() { static std::size_t count = 0; // Detect only on the first call @@ -55,8 +59,8 @@ static std::size_t GetParallelCPUCount() return count; } -static std::string FileProjectRelativePath(cmMakefile* makefile, - std::string const& fileName) +std::string FileProjectRelativePath(cmMakefile* makefile, + std::string const& fileName) { std::string res; { @@ -80,9 +84,9 @@ static std::string FileProjectRelativePath(cmMakefile* makefile, * recursive STATIC_LIBRARY dependencies depends on targetOrigin * (STATIC_LIBRARY cycle). */ -static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, - cmGeneratorTarget const* targetDepend, - std::string const& config) +bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, + cmGeneratorTarget const* targetDepend, + std::string const& config) { bool cycle = false; if ((targetOrigin->GetType() == cmStateEnums::STATIC_LIBRARY) && @@ -120,6 +124,42 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, return cycle; } +/** Sanitizes file search paths */ +class SearchPathSanitizer +{ +public: + SearchPathSanitizer(cmMakefile* makefile) + : SourcePath_(makefile->GetCurrentSourceDirectory()) + { + } + std::vector<std::string> operator()( + std::vector<std::string> const& paths) const; + +private: + std::string SourcePath_; +}; + +std::vector<std::string> SearchPathSanitizer::operator()( + std::vector<std::string> const& paths) const +{ + std::vector<std::string> res; + res.reserve(paths.size()); + for (std::string const& srcPath : paths) { + // Collapse relative paths + std::string path = cmSystemTools::CollapseFullPath(srcPath, SourcePath_); + // Remove suffix slashes + while (cmHasSuffix(path, '/')) { + path.pop_back(); + } + // Accept only non empty paths + if (!path.empty()) { + res.emplace_back(std::move(path)); + } + } + return res; +} +} // End of unnamed namespace + cmQtAutoGenInitializer::InfoWriter::InfoWriter(std::string const& filename) { Ofs_.SetCopyIfDifferent(true); @@ -213,11 +253,15 @@ void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists( }; cmQtAutoGenInitializer::cmQtAutoGenInitializer( - cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target, - IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled, - bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget) + cmQtAutoGenGlobalInitializer* globalInitializer, + cmGeneratorTarget* genTarget, IntegerVersion const& qtVersion, + bool mocEnabled, bool uicEnabled, bool rccEnabled, bool globalAutogenTarget, + bool globalAutoRccTarget) : GlobalInitializer(globalInitializer) - , Target(target) + , GenTarget(genTarget) + , GlobalGen(genTarget->GetGlobalGenerator()) + , LocalGen(genTarget->GetLocalGenerator()) + , Makefile(genTarget->Makefile) , QtVersion(qtVersion) { AutogenTarget.GlobalTarget = globalAutogenTarget; @@ -229,19 +273,15 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer( bool cmQtAutoGenInitializer::InitCustomTargets() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); - cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); - // Configurations - this->MultiConfig = globalGen->IsMultiConfig(); - this->ConfigDefault = makefile->GetConfigurations(this->ConfigsList); + this->MultiConfig = this->GlobalGen->IsMultiConfig(); + this->ConfigDefault = this->Makefile->GetConfigurations(this->ConfigsList); if (this->ConfigsList.empty()) { this->ConfigsList.push_back(this->ConfigDefault); } // Verbosity - this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE"); + this->Verbosity = this->Makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE"); if (!this->Verbosity.empty()) { unsigned long iVerb = 0; if (!cmStrToULong(this->Verbosity, &iVerb)) { @@ -253,14 +293,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Targets FOLDER { const char* folder = - makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); + this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); if (folder == nullptr) { - folder = - makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); + folder = this->Makefile->GetState()->GetGlobalProperty( + "AUTOGEN_TARGETS_FOLDER"); } // Inherit FOLDER property from target (#13688) if (folder == nullptr) { - folder = this->Target->GetProperty("FOLDER"); + folder = this->GenTarget->GetProperty("FOLDER"); } if (folder != nullptr) { this->TargetsFolder = folder; @@ -270,7 +310,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Check status of policy CMP0071 { cmPolicies::PolicyStatus const CMP0071_status = - makefile->GetPolicyStatus(cmPolicies::CMP0071); + this->Makefile->GetPolicyStatus(cmPolicies::CMP0071); switch (CMP0071_status) { case cmPolicies::WARN: this->CMP0071Warn = true; @@ -291,18 +331,18 @@ bool cmQtAutoGenInitializer::InitCustomTargets() { // Collapsed current binary directory std::string const cbd = cmSystemTools::CollapseFullPath( - std::string(), makefile->GetCurrentBinaryDirectory()); + std::string(), this->Makefile->GetCurrentBinaryDirectory()); // Info directory - this->Dir.Info = - cmStrCat(cbd, "/CMakeFiles/", this->Target->GetName(), "_autogen.dir"); + this->Dir.Info = cmStrCat(cbd, "/CMakeFiles/", this->GenTarget->GetName(), + "_autogen.dir"); cmSystemTools::ConvertToUnixSlashes(this->Dir.Info); // Build directory - this->Dir.Build = this->Target->GetSafeProperty("AUTOGEN_BUILD_DIR"); + this->Dir.Build = this->GenTarget->GetSafeProperty("AUTOGEN_BUILD_DIR"); if (this->Dir.Build.empty()) { this->Dir.Build = - cmStrCat(cbd, '/', this->Target->GetName(), "_autogen"); + cmStrCat(cbd, '/', this->GenTarget->GetName(), "_autogen"); } cmSystemTools::ConvertToUnixSlashes(this->Dir.Build); // Cleanup build directory @@ -339,11 +379,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets() } // Autogen target name - this->AutogenTarget.Name = cmStrCat(this->Target->GetName(), "_autogen"); + this->AutogenTarget.Name = + cmStrCat(this->GenTarget->GetName(), "_autogen"); // Autogen target parallel processing this->AutogenTarget.Parallel = - this->Target->GetSafeProperty("AUTOGEN_PARALLEL"); + this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL"); if (this->AutogenTarget.Parallel.empty() || (this->AutogenTarget.Parallel == "AUTO")) { // Autodetect number of CPUs @@ -377,15 +418,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Autogen target: Compute user defined dependencies { this->AutogenTarget.DependOrigin = - this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS"); + this->GenTarget->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS"); std::string const deps = - this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS"); + this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS"); if (!deps.empty()) { - std::vector<std::string> extraDeps = cmExpandedList(deps); - for (std::string const& depName : extraDeps) { + for (std::string const& depName : cmExpandedList(deps)) { // Allow target and file dependencies - auto* depTarget = makefile->FindTargetToUse(depName); + auto* depTarget = this->Makefile->FindTargetToUse(depName); if (depTarget != nullptr) { this->AutogenTarget.DependTargets.insert(depTarget); } else { @@ -397,13 +437,13 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // CMAKE_AUTOMOC_RELAXED_MODE deprecation warning if (this->Moc.Enabled) { - if (makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) { - makefile->IssueMessage( + if (this->Makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) { + this->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.")); + this->GenTarget->GetName(), " to regular mode.")); } } } @@ -415,7 +455,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Add autogen include directory to the origin target INCLUDE_DIRECTORIES if (this->MocOrUicEnabled() || (this->Rcc.Enabled && this->MultiConfig)) { - this->Target->AddIncludeDirectory(this->Dir.Include, true); + this->GenTarget->AddIncludeDirectory(this->Dir.Include, true); } // Scan files @@ -438,33 +478,29 @@ bool cmQtAutoGenInitializer::InitCustomTargets() bool cmQtAutoGenInitializer::InitMoc() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); - // Mocs compilation file this->Moc.MocsCompilation = cmStrCat(this->Dir.Build, "/mocs_compilation.cpp"); // Moc predefs command - if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") && + if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") && (this->QtVersion >= IntegerVersion(5, 8))) { - this->Moc.PredefsCmd = - makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"); + this->Moc.PredefsCmd = this->Makefile->GetSafeDefinition( + "CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"); } // Moc includes { - bool const appendImplicit = (this->QtVersion.Major >= 5); + SearchPathSanitizer sanitizer(this->Makefile); auto GetIncludeDirs = - [this, localGen, - appendImplicit](std::string const& cfg) -> std::vector<std::string> { + [this, &sanitizer](std::string const& cfg) -> std::vector<std::string> { // Get the include dirs for this target, without stripping the implicit - // include dirs off, see - // https://gitlab.kitware.com/cmake/cmake/issues/13667 + // include dirs off, see issue #13667. std::vector<std::string> dirs; - localGen->GetIncludeDirectoriesImplicit(dirs, this->Target, "CXX", cfg, - false, appendImplicit); - return dirs; + bool const appendImplicit = (this->QtVersion.Major >= 5); + this->LocalGen->GetIncludeDirectoriesImplicit( + dirs, this->GenTarget, "CXX", cfg, false, appendImplicit); + return sanitizer(dirs); }; // Default configuration include directories @@ -483,9 +519,9 @@ bool cmQtAutoGenInitializer::InitMoc() // Moc compile definitions { auto GetCompileDefinitions = - [this, localGen](std::string const& cfg) -> std::set<std::string> { + [this](std::string const& cfg) -> std::set<std::string> { std::set<std::string> defines; - localGen->GetTargetDefines(this->Target, cfg, "CXX", defines); + this->LocalGen->GetTargetDefines(this->GenTarget, cfg, "CXX", defines); #ifdef _WIN32 if (this->Moc.PredefsCmd.empty()) { // Add WIN32 definition if we don't have a moc_predefs.h @@ -525,18 +561,13 @@ bool cmQtAutoGenInitializer::InitMoc() bool cmQtAutoGenInitializer::InitUic() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - // Uic search paths { std::string const usp = - this->Target->GetSafeProperty("AUTOUIC_SEARCH_PATHS"); + this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS"); if (!usp.empty()) { - cmExpandList(usp, this->Uic.SearchPaths); - std::string const& srcDir = makefile->GetCurrentSourceDirectory(); - for (std::string& path : this->Uic.SearchPaths) { - path = cmSystemTools::CollapseFullPath(path, srcDir); - } + this->Uic.SearchPaths = + SearchPathSanitizer(this->Makefile)(cmExpandedList(usp)); } } // Uic target options @@ -544,7 +575,7 @@ bool cmQtAutoGenInitializer::InitUic() auto UicGetOpts = [this](std::string const& cfg) -> std::vector<std::string> { std::vector<std::string> opts; - this->Target->GetAutoUicOptions(opts, cfg); + this->GenTarget->GetAutoUicOptions(opts, cfg); return opts; }; @@ -605,14 +636,13 @@ bool cmQtAutoGenInitializer::InitRcc() bool cmQtAutoGenInitializer::InitScanFiles() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - cmake const* cm = makefile->GetCMakeInstance(); + cmake const* cm = this->Makefile->GetCMakeInstance(); auto const& kw = this->GlobalInitializer->kw(); auto makeMUFile = [this, &kw](cmSourceFile* sf, std::string const& fullPath, bool muIt) -> MUFileHandle { MUFileHandle muf = cm::make_unique<MUFile>(); - muf->RealPath = cmSystemTools::GetRealPath(fullPath); + muf->FullPath = fullPath; muf->SF = sf; muf->Generated = sf->GetIsGenerated(); bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN); @@ -642,9 +672,9 @@ bool cmQtAutoGenInitializer::InitScanFiles() { // Scan through target files std::vector<cmSourceFile*> srcFiles; - this->Target->GetConfigCommonSourceFiles(srcFiles); + this->GenTarget->GetConfigCommonSourceFiles(srcFiles); for (cmSourceFile* sf : srcFiles) { - // sf->GetExtension() is only valid after sf->GetFullPath() ... + // sf->GetExtension() is only valid after sf->ResolveFullPath() ... // Since we're iterating over source files that might be not in the // target we need to check for path errors (not existing files). std::string pathError; @@ -670,7 +700,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() !sf->GetPropertyAsBool(kw.SKIP_AUTORCC)) { // Register qrc file Qrc qrc; - qrc.QrcFile = cmSystemTools::GetRealPath(fullPath); + qrc.QrcFile = fullPath; qrc.QrcName = cmSystemTools::GetFilenameWithoutLastExtension(qrc.QrcFile); qrc.Generated = sf->GetIsGenerated(); @@ -690,7 +720,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() // sources meta data cache. Clear it so that OBJECT library targets that // are AUTOGEN initialized after this target get their added // mocs_compilation.cpp source acknowledged by this target. - this->Target->ClearSourcesCache(); + this->GenTarget->ClearSourcesCache(); // For source files find additional headers and private headers if (this->MocOrUicEnabled()) { @@ -704,21 +734,21 @@ bool cmQtAutoGenInitializer::InitScanFiles() MUFile const& muf = *pair.second; if (muf.MocIt || muf.UicIt) { // Search for the default header file and a private header - std::string const& srcPath = muf.SF->ResolveFullPath(); - std::string basePath = - cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath), - cmSystemTools::GetFilenameWithoutLastExtension(srcPath)); + std::string const& srcFullPath = muf.SF->ResolveFullPath(); + std::string basePath = cmStrCat( + cmQtAutoGen::SubDirPrefix(srcFullPath), + cmSystemTools::GetFilenameWithoutLastExtension(srcFullPath)); for (auto const& suffix : suffixes) { std::string const suffixedPath = cmStrCat(basePath, suffix); for (auto const& ext : exts) { std::string fullPath = cmStrCat(suffixedPath, '.', ext); auto constexpr locationKind = cmSourceFileLocationKind::Known; - cmSourceFile* sf = makefile->GetSource(fullPath, locationKind); + cmSourceFile* sf = + this->Makefile->GetSource(fullPath, locationKind); if (sf != nullptr) { // Check if we know about this header already - if (this->AutogenTarget.Headers.find(sf) != - this->AutogenTarget.Headers.end()) { + if (cmContains(this->AutogenTarget.Headers, sf)) { continue; } // We only accept not-GENERATED files that do exist. @@ -728,7 +758,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() } } else if (cmSystemTools::FileExists(fullPath)) { // Create a new source file for the existing file - sf = makefile->CreateSource(fullPath, false, locationKind); + sf = this->Makefile->CreateSource(fullPath, false, locationKind); } if (sf != nullptr) { @@ -757,8 +787,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() // The reason is that their file names might be discovered from source files // at generation time. if (this->MocOrUicEnabled()) { - for (cmSourceFile* sf : makefile->GetSourceFiles()) { - // sf->GetExtension() is only valid after sf->GetFullPath() ... + for (cmSourceFile* sf : this->Makefile->GetSourceFiles()) { + // sf->GetExtension() is only valid after sf->ResolveFullPath() ... // Since we're iterating over source files that might be not in the // target we need to check for path errors (not existing files). std::string pathError; @@ -770,16 +800,14 @@ bool cmQtAutoGenInitializer::InitScanFiles() cmSystemTools::LowerCase(sf->GetExtension()); if (cm->IsHeaderExtension(extLower)) { - if (this->AutogenTarget.Headers.find(sf) == - this->AutogenTarget.Headers.end()) { + if (!cmContains(this->AutogenTarget.Headers, sf)) { auto muf = makeMUFile(sf, fullPath, false); if (muf->SkipMoc || muf->SkipUic) { this->AutogenTarget.Headers.emplace(sf, std::move(muf)); } } } else if (cm->IsSourceExtension(extLower)) { - if (this->AutogenTarget.Sources.find(sf) == - this->AutogenTarget.Sources.end()) { + if (!cmContains(this->AutogenTarget.Headers, sf)) { auto muf = makeMUFile(sf, fullPath, false); if (muf->SkipMoc || muf->SkipUic) { this->AutogenTarget.Sources.emplace(sf, std::move(muf)); @@ -787,7 +815,6 @@ bool cmQtAutoGenInitializer::InitScanFiles() } } else if (this->Uic.Enabled && (extLower == kw.ui)) { // .ui file - std::string realPath = cmSystemTools::GetRealPath(fullPath); bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN); bool const skipUic = (skipAutogen || sf->GetPropertyAsBool(kw.SKIP_AUTOUIC)); @@ -795,13 +822,12 @@ bool cmQtAutoGenInitializer::InitScanFiles() // Check if the .ui file has uic options 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 = cmExpandedList(uicOpts); - this->Uic.FileOptions.push_back(std::move(optsVec)); + this->Uic.FileFiles.push_back(fullPath); + this->Uic.FileOptions.push_back(cmExpandedList(uicOpts)); } } else { // Register skipped .ui file - this->Uic.SkipUi.insert(std::move(realPath)); + this->Uic.SkipUi.insert(fullPath); } } } @@ -812,7 +838,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (this->CMP0071Accept) { // Let the autogen target depend on the GENERATED files for (MUFile* muf : this->AutogenTarget.FilesGenerated) { - this->AutogenTarget.DependFiles.insert(muf->RealPath); + this->AutogenTarget.DependFiles.insert(muf->FullPath); } } else if (this->CMP0071Warn) { cm::string_view property; @@ -825,9 +851,9 @@ bool cmQtAutoGenInitializer::InitScanFiles() } std::string files; for (MUFile* muf : this->AutogenTarget.FilesGenerated) { - files += cmStrCat(" ", Quoted(muf->RealPath), '\n'); + files += cmStrCat(" ", Quoted(muf->FullPath), '\n'); } - makefile->IssueMessage( + this->Makefile->IssueMessage( MessageType::AUTHOR_WARNING, cmStrCat( cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n', @@ -848,7 +874,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() const bool modernQt = (this->QtVersion.Major >= 5); // Target rcc options std::vector<std::string> optionsTarget = - cmExpandedList(this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS)); + cmExpandedList(this->GenTarget->GetSafeProperty(kw.AUTORCC_OPTIONS)); // Check if file name is unique for (Qrc& qrc : this->Rcc.Qrcs) { @@ -862,7 +888,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() } // Path checksum and file names { - cmFilePathChecksum const fpathCheckSum(makefile); + cmFilePathChecksum const fpathCheckSum(this->Makefile); for (Qrc& qrc : this->Rcc.Qrcs) { qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile); // RCC output file name @@ -925,12 +951,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() bool cmQtAutoGenInitializer::InitAutogenTarget() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); - cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); - // Register info file as generated by CMake - makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile); + this->Makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile); // Files provided by the autogen target std::vector<std::string> autogenProvides; @@ -952,25 +974,18 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() } tools += "UIC"; } - autogenComment = - cmStrCat("Automatic ", tools, " for target ", this->Target->GetName()); + autogenComment = cmStrCat("Automatic ", tools, " for target ", + this->GenTarget->GetName()); } // Compose command lines - cmCustomCommandLines commandLines; - { - cmCustomCommandLine currentLine; - currentLine.push_back(cmSystemTools::GetCMakeCommand()); - currentLine.push_back("-E"); - currentLine.push_back("cmake_autogen"); - currentLine.push_back(this->AutogenTarget.InfoFile); - currentLine.push_back("$<CONFIGURATION>"); - commandLines.push_back(std::move(currentLine)); - } + cmCustomCommandLines commandLines = cmMakeSingleCommandLine( + { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen", + this->AutogenTarget.InfoFile, "$<CONFIGURATION>" }); // Use PRE_BUILD on demand bool usePRE_BUILD = false; - if (globalGen->GetName().find("Visual Studio") != std::string::npos) { + if (this->GlobalGen->GetName().find("Visual Studio") != std::string::npos) { // Under VS use a PRE_BUILD event instead of a separate target to // reduce the number of targets loaded into the IDE. // This also works around a VS 11 bug that may skip updating the target: @@ -992,7 +1007,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() if (usePRE_BUILD) { // Add additional autogen target dependencies to origin target for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { - this->Target->Target->AddUtility(depTarget->GetName(), makefile); + this->GenTarget->Target->AddUtility(depTarget->GetName(), + this->Makefile); } // Add the pre-build command directly to bypass the OBJECT_LIBRARY @@ -1002,12 +1018,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() // PRE_BUILD does not support file dependencies! const std::vector<std::string> no_output; const std::vector<std::string> no_deps; - cmCustomCommand cc(makefile, no_output, autogenProvides, no_deps, + cmCustomCommand cc(this->Makefile, no_output, autogenProvides, no_deps, commandLines, autogenComment.c_str(), this->Dir.Work.c_str()); cc.SetEscapeOldStyle(false); cc.SetEscapeAllowMakeVars(true); - this->Target->Target->AddPreBuildCommand(cc); + this->GenTarget->Target->AddPreBuildCommand(cc); } else { // Add link library target dependencies to the autogen target @@ -1018,12 +1034,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() std::map<cmGeneratorTarget const*, std::size_t> commonTargets; for (std::string const& config : this->ConfigsList) { cmLinkImplementationLibraries const* libs = - this->Target->GetLinkImplementationLibraries(config); + this->GenTarget->GetLinkImplementationLibraries(config); if (libs != nullptr) { for (cmLinkItem const& item : libs->Libraries) { cmGeneratorTarget const* libTarget = item.Target; if ((libTarget != nullptr) && - !StaticLibraryCycle(this->Target, libTarget, config)) { + !StaticLibraryCycle(this->GenTarget, libTarget, config)) { // Increment target config count commonTargets[libTarget]++; } @@ -1038,25 +1054,25 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() } // Create autogen target - cmTarget* autogenTarget = makefile->AddUtilityCommand( + cmTarget* autogenTarget = this->Makefile->AddUtilityCommand( this->AutogenTarget.Name, cmMakefile::TargetOrigin::Generator, true, this->Dir.Work.c_str(), /*byproducts=*/autogenProvides, std::vector<std::string>(this->AutogenTarget.DependFiles.begin(), this->AutogenTarget.DependFiles.end()), commandLines, false, autogenComment.c_str()); // Create autogen generator target - localGen->AddGeneratorTarget( - new cmGeneratorTarget(autogenTarget, localGen)); + this->LocalGen->AddGeneratorTarget( + new cmGeneratorTarget(autogenTarget, this->LocalGen)); // Forward origin utilities to autogen target if (this->AutogenTarget.DependOrigin) { - for (BT<std::string> const& depName : this->Target->GetUtilities()) { - autogenTarget->AddUtility(depName.Value, makefile); + for (BT<std::string> const& depName : this->GenTarget->GetUtilities()) { + autogenTarget->AddUtility(depName.Value, this->Makefile); } } // Add additional autogen target dependencies to autogen target for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { - autogenTarget->AddUtility(depTarget->GetName(), makefile); + autogenTarget->AddUtility(depTarget->GetName(), this->Makefile); } // Set FOLDER property in autogen target @@ -1065,11 +1081,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() } // Add autogen target to the origin target dependencies - this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile); + this->GenTarget->Target->AddUtility(this->AutogenTarget.Name, + this->Makefile); // Add autogen target to the global autogen target dependencies if (this->AutogenTarget.GlobalTarget) { - this->GlobalInitializer->AddToGlobalAutoGen(localGen, + this->GlobalInitializer->AddToGlobalAutoGen(this->LocalGen, this->AutogenTarget.Name); } } @@ -1079,12 +1096,9 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() bool cmQtAutoGenInitializer::InitRccTargets() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); - for (Qrc const& qrc : this->Rcc.Qrcs) { // Register info file as generated by CMake - makefile->AddCMakeOutputFile(qrc.InfoFile); + this->Makefile->AddCMakeOutputFile(qrc.InfoFile); // Register file at target this->AddGeneratedSource(qrc.RccFile, this->Rcc); @@ -1100,58 +1114,52 @@ bool cmQtAutoGenInitializer::InitRccTargets() if (this->MultiConfig) { // Build for all configurations for (std::string const& config : this->ConfigsList) { - cmCustomCommandLine currentLine; - currentLine.push_back(cmSystemTools::GetCMakeCommand()); - currentLine.push_back("-E"); - currentLine.push_back("cmake_autorcc"); - currentLine.push_back(qrc.InfoFile); - currentLine.push_back(config); - commandLines.push_back(std::move(currentLine)); + commandLines.push_back( + cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", + "cmake_autorcc", qrc.InfoFile, config })); } } else { - cmCustomCommandLine currentLine; - currentLine.push_back(cmSystemTools::GetCMakeCommand()); - currentLine.push_back("-E"); - currentLine.push_back("cmake_autorcc"); - currentLine.push_back(qrc.InfoFile); - currentLine.push_back("$<CONFIG>"); - commandLines.push_back(std::move(currentLine)); + commandLines.push_back( + cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", + "cmake_autorcc", qrc.InfoFile, "$<CONFIG>" })); } - std::string ccComment = cmStrCat( - "Automatic RCC for ", FileProjectRelativePath(makefile, qrc.QrcFile)); + std::string ccComment = + cmStrCat("Automatic RCC for ", + FileProjectRelativePath(this->Makefile, qrc.QrcFile)); if (qrc.Generated || this->Rcc.GlobalTarget) { // Create custom rcc target std::string ccName; { - ccName = cmStrCat(this->Target->GetName(), "_arcc_", qrc.QrcName); + ccName = cmStrCat(this->GenTarget->GetName(), "_arcc_", qrc.QrcName); if (!qrc.Unique) { ccName += cmStrCat('_', qrc.PathChecksum); } - cmTarget* autoRccTarget = makefile->AddUtilityCommand( + cmTarget* autoRccTarget = this->Makefile->AddUtilityCommand( ccName, cmMakefile::TargetOrigin::Generator, true, this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false, ccComment.c_str()); // Create autogen generator target - localGen->AddGeneratorTarget( - new cmGeneratorTarget(autoRccTarget, localGen)); + this->LocalGen->AddGeneratorTarget( + new cmGeneratorTarget(autoRccTarget, this->LocalGen)); // Set FOLDER property in autogen target if (!this->TargetsFolder.empty()) { autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str()); } if (!this->Rcc.ExecutableTargetName.empty()) { - autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName, makefile); + autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName, + this->Makefile); } } // Add autogen target to the origin target dependencies - this->Target->Target->AddUtility(ccName, makefile); + this->GenTarget->Target->AddUtility(ccName, this->Makefile); // Add autogen target to the global autogen target dependencies if (this->Rcc.GlobalTarget) { - this->GlobalInitializer->AddToGlobalAutoRcc(localGen, ccName); + this->GlobalInitializer->AddToGlobalAutoRcc(this->LocalGen, ccName); } } else { // Create custom rcc command @@ -1166,13 +1174,15 @@ bool cmQtAutoGenInitializer::InitRccTargets() if (!this->Rcc.ExecutableTargetName.empty()) { ccDepends.push_back(this->Rcc.ExecutableTargetName); } - makefile->AddCustomCommandToOutput(ccOutput, ccByproducts, ccDepends, - /*main_dependency*/ std::string(), - commandLines, ccComment.c_str(), - this->Dir.Work.c_str()); + std::string no_main_dependency; + cmImplicitDependsList no_implicit_depends; + this->Makefile->AddCustomCommandToOutput( + ccOutput, ccByproducts, ccDepends, no_main_dependency, + no_implicit_depends, commandLines, ccComment.c_str(), + this->Dir.Work.c_str()); } // Reconfigure when .qrc file changes - makefile->AddCMakeDependFile(qrc.QrcFile); + this->Makefile->AddCMakeDependFile(qrc.QrcFile); } } @@ -1205,9 +1215,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() InfoWriter ofs(this->AutogenTarget.InfoFile); if (ofs) { // Utility lambdas - cmMakefile* makefile = this->Target->Target->GetMakefile(); - auto MfDef = [makefile](const char* key) { - return makefile->GetSafeDefinition(key); + auto MfDef = [this](const char* key) { + return this->Makefile->GetSafeDefinition(key); }; // Write common settings @@ -1223,8 +1232,6 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() MfDef("CMAKE_CURRENT_SOURCE_DIR")); ofs.Write("AM_CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR")); - ofs.Write("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", - MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")); ofs.Write("AM_BUILD_DIR", this->Dir.Build); ofs.Write("AM_INCLUDE_DIR", this->Dir.Include); ofs.WriteConfig("AM_INCLUDE_DIR", this->Dir.ConfigInclude); @@ -1251,7 +1258,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } std::sort(sortedHeaders.begin(), sortedHeaders.end(), [](MUFile const* a, MUFile const* b) { - return (a->RealPath < b->RealPath); + return (a->FullPath < b->FullPath); }); } @@ -1260,13 +1267,13 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() continue; } if (muf->SkipMoc) { - moc_skip.insert(muf->RealPath); + moc_skip.insert(muf->FullPath); } if (muf->SkipUic) { - uic_skip.insert(muf->RealPath); + uic_skip.insert(muf->FullPath); } if (muf->MocIt || muf->UicIt) { - headers.emplace_back(muf->RealPath); + headers.emplace_back(muf->FullPath); headersFlags.emplace_back( cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u')); } @@ -1274,7 +1281,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } // Header build paths { - cmFilePathChecksum const fpathCheckSum(makefile); + cmFilePathChecksum const fpathCheckSum(this->Makefile); std::unordered_set<std::string> emitted; for (std::string const& hdr : headers) { std::string const basePath = @@ -1305,7 +1312,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } std::sort(sorted.begin(), sorted.end(), [](MUFile const* a, MUFile const* b) { - return (a->RealPath < b->RealPath); + return (a->FullPath < b->FullPath); }); for (MUFile const* const muf : sorted) { @@ -1313,13 +1320,13 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() continue; } if (muf->SkipMoc) { - moc_skip.insert(muf->RealPath); + moc_skip.insert(muf->FullPath); } if (muf->SkipUic) { - uic_skip.insert(muf->RealPath); + uic_skip.insert(muf->FullPath); } if (muf->MocIt || muf->UicIt) { - sources.emplace_back(muf->RealPath); + sources.emplace_back(muf->FullPath); sourcesFlags.emplace_back( cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u')); } @@ -1352,12 +1359,14 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() ofs.WriteStrings("AM_MOC_INCLUDES", this->Moc.Includes); ofs.WriteConfigStrings("AM_MOC_INCLUDES", this->Moc.ConfigIncludes); ofs.Write("AM_MOC_OPTIONS", - this->Target->GetSafeProperty("AUTOMOC_MOC_OPTIONS")); + this->GenTarget->GetSafeProperty("AUTOMOC_MOC_OPTIONS")); ofs.Write("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE")); + ofs.Write("AM_MOC_PATH_PREFIX", + this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX")); ofs.Write("AM_MOC_MACRO_NAMES", - this->Target->GetSafeProperty("AUTOMOC_MACRO_NAMES")); + this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES")); ofs.Write("AM_MOC_DEPEND_FILTERS", - this->Target->GetSafeProperty("AUTOMOC_DEPEND_FILTERS")); + this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS")); ofs.Write("AM_MOC_PREDEFS_CMD", this->Moc.PredefsCmd); } @@ -1388,6 +1397,11 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo() for (Qrc const& qrc : this->Rcc.Qrcs) { InfoWriter ofs(qrc.InfoFile); if (ofs) { + // Utility lambdas + auto MfDef = [this](const char* key) { + return this->Makefile->GetSafeDefinition(key); + }; + // Write ofs.Write("# Configurations\n"); ofs.Write("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); @@ -1397,6 +1411,8 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo() ofs.WriteConfig("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile); ofs.Write("# Directories\n"); + ofs.Write("ARCC_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR")); + ofs.Write("ARCC_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR")); ofs.Write("ARCC_BUILD_DIR", this->Dir.Build); ofs.Write("ARCC_INCLUDE_DIR", this->Dir.Include); ofs.WriteConfig("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude); @@ -1427,8 +1443,7 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo() void cmQtAutoGenInitializer::RegisterGeneratedSource( std::string const& filename) { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); + cmSourceFile* gFile = this->Makefile->GetOrCreateSource(filename, true); gFile->SetProperty("GENERATED", "1"); gFile->SetProperty("SKIP_AUTOGEN", "1"); } @@ -1440,7 +1455,7 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename, // Register source at makefile this->RegisterGeneratedSource(filename); // Add source file to target - this->Target->AddSource(filename, prepend); + this->GenTarget->AddSource(filename, prepend); // Add source file to source group return this->AddToSourceGroup(filename, genVars.GenNameUpper); } @@ -1448,7 +1463,6 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename, bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, cm::string_view genNameUpper) { - cmMakefile* makefile = this->Target->Target->GetMakefile(); cmSourceGroup* sourceGroup = nullptr; // Acquire source group { @@ -1460,7 +1474,8 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP" }; for (std::string const& prop : props) { - const char* propName = makefile->GetState()->GetGlobalProperty(prop); + const char* propName = + this->Makefile->GetState()->GetGlobalProperty(prop); if ((propName != nullptr) && (*propName != '\0')) { groupName = propName; property = prop; @@ -1470,7 +1485,7 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, } // Generate a source group on demand if (!groupName.empty()) { - sourceGroup = makefile->GetOrCreateSourceGroup(groupName); + sourceGroup = this->Makefile->GetOrCreateSourceGroup(groupName); if (sourceGroup == nullptr) { cmSystemTools::Error( cmStrCat(genNameUpper, " error in ", property, @@ -1488,8 +1503,8 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName) { - Target->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName.c_str(), - false); + this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", + fileName.c_str(), false); } static unsigned int CharPtrToUInt(const char* const input) @@ -1502,7 +1517,7 @@ static unsigned int CharPtrToUInt(const char* const input) } static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions( - cmGeneratorTarget const* target) + cmGeneratorTarget const* genTarget) { // Qt version variable prefixes static std::initializer_list< @@ -1524,7 +1539,7 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions( } }; - cmMakefile* makefile = target->Target->GetMakefile(); + cmMakefile* makefile = genTarget->Makefile; // Read versions from variables for (auto const& keyPair : keys) { @@ -1574,22 +1589,20 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, { auto print_err = [this, &genVars](std::string const& err) { cmSystemTools::Error(cmStrCat(genVars.GenNameUpper, " for target ", - this->Target->GetName(), ": ", err)); + this->GenTarget->GetName(), ": ", err)); }; // Custom executable { std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE"); - std::string const val = this->Target->Target->GetSafeProperty(prop); + std::string const val = this->GenTarget->Target->GetSafeProperty(prop); if (!val.empty()) { // Evaluate generator expression { - cmListFileBacktrace lfbt = - this->Target->Target->GetMakefile()->GetBacktrace(); + cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(lfbt); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(val); - genVars.Executable = - cge->Evaluate(this->Target->GetLocalGenerator(), ""); + genVars.Executable = cge->Evaluate(this->LocalGen, ""); } if (genVars.Executable.empty() && !ignoreMissingTarget) { print_err(prop + " evaluates to an empty value"); @@ -1617,15 +1630,15 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, std::string const targetName = cmStrCat(prefix, executable); // Find target - cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); - cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(targetName); - if (target != nullptr) { + cmGeneratorTarget* genTarget = + this->LocalGen->FindGeneratorTargetToUse(targetName); + if (genTarget != nullptr) { genVars.ExecutableTargetName = targetName; - genVars.ExecutableTarget = target; - if (target->IsImported()) { - genVars.Executable = target->ImportedGetLocation(""); + genVars.ExecutableTarget = genTarget; + if (genTarget->IsImported()) { + genVars.Executable = genTarget->ImportedGetLocation(""); } else { - genVars.Executable = target->GetLocation(""); + genVars.Executable = genTarget->GetLocation(""); } } else { if (ignoreMissingTarget) { diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 84a27e4..7ce9fad 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -6,7 +6,8 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmGeneratedFileStream.h" #include "cmQtAutoGen.h" -#include "cm_string_view.hxx" + +#include <cm/string_view> #include <map> #include <memory> @@ -18,9 +19,12 @@ #include <vector> class cmGeneratorTarget; -class cmTarget; +class cmGlobalGenerator; +class cmLocalGenerator; +class cmMakefile; class cmQtAutoGenGlobalInitializer; class cmSourceFile; +class cmTarget; /// @brief Initializes the QtAutoGen generators class cmQtAutoGenInitializer : public cmQtAutoGen @@ -47,7 +51,7 @@ public: /// @brief Moc/Uic file struct MUFile { - std::string RealPath; + std::string FullPath; cmSourceFile* SF = nullptr; bool Generated = false; bool SkipMoc = false; @@ -112,10 +116,10 @@ public: public: /// @return The detected Qt version and the required Qt major version static std::pair<IntegerVersion, unsigned int> GetQtVersion( - cmGeneratorTarget const* target); + cmGeneratorTarget const* genTarget); cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer, - cmGeneratorTarget* target, + cmGeneratorTarget* genTarget, IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled, bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget); @@ -152,8 +156,11 @@ private: bool ignoreMissingTarget) const; private: - cmQtAutoGenGlobalInitializer* GlobalInitializer; - cmGeneratorTarget* Target; + cmQtAutoGenGlobalInitializer* GlobalInitializer = nullptr; + cmGeneratorTarget* GenTarget = nullptr; + cmGlobalGenerator* GlobalGen = nullptr; + cmLocalGenerator* LocalGen = nullptr; + cmMakefile* Makefile = nullptr; // Configuration IntegerVersion QtVersion; diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index 80b8741..eb829fa 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -2,7 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenerator.h" -#include "cm_memory.hxx" +#include <cm/memory> + #include "cmsys/FStream.hxx" #include "cmGlobalGenerator.h" @@ -93,32 +94,18 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType, } } -void cmQtAutoGenerator::Logger::WarningFile(GenT genType, - cm::string_view filename, - cm::string_view message) const -{ - Warning(genType, cmStrCat(" ", Quoted(filename), '\n', message)); -} - void cmQtAutoGenerator::Logger::Error(GenT genType, cm::string_view message) const { std::string msg = - cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " error")), message, - cmHasSuffix(message, '\n') ? "\n" : "\n\n"); + cmStrCat('\n', HeadLine(cmStrCat(GeneratorName(genType), " error")), + message, cmHasSuffix(message, '\n') ? "\n" : "\n\n"); { std::lock_guard<std::mutex> lock(Mutex_); cmSystemTools::Stderr(msg); } } -void cmQtAutoGenerator::Logger::ErrorFile(GenT genType, - cm::string_view filename, - cm::string_view message) const -{ - Error(genType, cmStrCat(" ", Quoted(filename), '\n', message)); -} - void cmQtAutoGenerator::Logger::ErrorCommand( GenT genType, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const @@ -286,3 +273,16 @@ std::string cmQtAutoGenerator::SettingsFind(std::string const& content, } return std::string(); } + +std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const +{ + std::string res; + if (cmHasPrefix(path, ProjectDirs().Source)) { + res = cmStrCat("SRC:", path.substr(ProjectDirs().Source.size())); + } else if (cmHasPrefix(path, ProjectDirs().Binary)) { + res = cmStrCat("BIN:", path.substr(ProjectDirs().Binary.size())); + } else { + res = std::string(path); + } + return cmQtAutoGen::Quoted(res); +} diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h index 4b8b0b7..f60acb0 100644 --- a/Source/cmQtAutoGenerator.h +++ b/Source/cmQtAutoGenerator.h @@ -7,7 +7,8 @@ #include "cmFileTime.h" #include "cmQtAutoGen.h" -#include "cm_string_view.hxx" + +#include <cm/string_view> #include <mutex> #include <string> @@ -23,9 +24,7 @@ class cmQtAutoGenerator : public cmQtAutoGen public: // -- Types - /** - * Thread safe logger - */ + /** Thread safe logger. */ class Logger { public: @@ -45,12 +44,8 @@ public: void Info(GenT genType, cm::string_view message) const; // -- Log warning 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, 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; @@ -64,6 +59,15 @@ public: bool ColorOutput_ = false; }; + /** Project directories. */ + struct ProjectDirsT + { + std::string Source; + std::string Binary; + std::string CurrentSource; + std::string CurrentBinary; + }; + // -- File system methods static bool MakeParentDirectory(std::string const& filename); static bool FileRead(std::string& content, std::string const& filename, @@ -91,13 +95,18 @@ public: std::string const& InfoDir() const { return InfoDir_; } std::string const& InfoConfig() const { return InfoConfig_; } + // -- Directories + ProjectDirsT const& ProjectDirs() const { return ProjectDirs_; } + // -- Utility static std::string SettingsFind(std::string const& content, const char* key); + std::string MessagePath(cm::string_view path) const; protected: // -- Abstract processing interface virtual bool Init(cmMakefile* makefile) = 0; virtual bool Process() = 0; + ProjectDirsT& ProjectDirsRef() { return ProjectDirs_; } private: // -- Info settings @@ -105,6 +114,8 @@ private: cmFileTime InfoFileTime_; std::string InfoDir_; std::string InfoConfig_; + // -- Directories + ProjectDirsT ProjectDirs_; }; #endif diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index 14329c0..5cd1ba1 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -3,12 +3,10 @@ #include "cmQtAutoMocUic.h" #include <algorithm> -#include <initializer_list> -#include <list> #include <set> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmCryptoHash.h" @@ -238,13 +236,6 @@ void cmQtAutoMocUic::JobT::LogError(GenT genType, Gen()->Log().Error(genType, message); } -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, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const @@ -269,6 +260,7 @@ bool cmQtAutoMocUic::JobT::RunProcess(GenT genType, info.empty() || cmHasSuffix(info, '\n') ? "" : "\n", QuotedCommand(command), '\n')); } + // Run command return cmWorkerPool::JobT::RunProcess(result, command, BaseConst().AutogenBuildDir); } @@ -283,24 +275,21 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() if (!Update(reason.get())) { return; } - std::string const& predefsFileRel = MocConst().PredefsFileRel; std::string const& predefsFileAbs = MocConst().PredefsFileAbs; { cmWorkerPool::ProcessResultT result; { // Compose command std::vector<std::string> cmd = MocConst().PredefsCmd; - // Add includes - cmAppend(cmd, MocConst().Includes); // Add definitions - for (std::string const& def : MocConst().Definitions) { - cmd.emplace_back("-D" + def); - } + cmAppend(cmd, MocConst().OptionsDefinitions); + // Add includes + cmAppend(cmd, MocConst().OptionsIncludes); // Execute command if (!RunProcess(GenT::MOC, result, cmd, reason.get())) { LogCommandError(GenT::MOC, cmStrCat("The content generation command for ", - Quoted(predefsFileRel), " failed.\n", + MessagePath(predefsFileAbs), " failed.\n", result.ErrorMessage), cmd, result.StdOut); return; @@ -310,19 +299,20 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() // (Re)write predefs file only on demand if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) { if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) { - LogFileError(GenT::MOC, predefsFileAbs, - cmStrCat("Writing ", Quoted(predefsFileRel), " failed.")); + LogError( + GenT::MOC, + cmStrCat("Writing ", MessagePath(predefsFileAbs), " failed.")); return; } } else { // Touch to update the time stamp if (Log().Verbose()) { - Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel)); + Log().Info(GenT::MOC, "Touching " + MessagePath(predefsFileAbs)); } if (!cmSystemTools::Touch(predefsFileAbs, false)) { - LogFileError( - GenT::MOC, predefsFileAbs, - cmStrCat("Touching ", Quoted(predefsFileAbs), " failed.")); + LogError( + GenT::MOC, + cmStrCat("Touching ", MessagePath(predefsFileAbs), " failed.")); return; } } @@ -330,7 +320,9 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() // Read file time afterwards if (!MocEval().PredefsTime.Load(predefsFileAbs)) { - LogFileError(GenT::MOC, predefsFileAbs, "File time reading failed."); + LogError(GenT::MOC, + cmStrCat("Reading the file time of ", MessagePath(predefsFileAbs), + " failed.")); return; } } @@ -340,7 +332,7 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const // Test if the file exists if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel), + *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs), ", because it doesn't exist."); } return true; @@ -349,7 +341,7 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const // Test if the settings changed if (MocConst().SettingsChanged) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel), + *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs), ", because the moc settings changed."); } return true; @@ -362,8 +354,9 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const if (execTime.Load(exec)) { if (MocEval().PredefsTime.Older(execTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel), - " because it is older than ", Quoted(exec), '.'); + *reason = + cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs), + " because it is older than ", MessagePath(exec), '.'); } return true; } @@ -380,19 +373,21 @@ bool cmQtAutoMocUic::JobParseT::ReadFile() std::string const& fileName = FileHandle->FileName; // Write info if (Log().Verbose()) { - Log().Info(GenT::GEN, "Parsing " + Quoted(fileName)); + Log().Info(GenT::GEN, cmStrCat("Parsing ", MessagePath(fileName))); } // Read file content { std::string error; if (!cmQtAutoGenerator::FileRead(Content, fileName, &error)) { - LogFileError(GenT::GEN, fileName, "Could not read the file: " + error); + LogError( + GenT::GEN, + cmStrCat("Could not read ", MessagePath(fileName), ".\n", error)); return false; } } // Warn if empty if (Content.empty()) { - Log().WarningFile(GenT::GEN, fileName, "The file is empty."); + Log().Warning(GenT::GEN, cmStrCat(MessagePath(fileName), " is empty.")); return false; } return true; @@ -555,37 +550,35 @@ void cmQtAutoMocUic::JobParseSourceT::Process() } } -void cmQtAutoMocUic::JobEvaluateT::Process() +std::string cmQtAutoMocUic::JobEvalCacheT::MessageSearchLocations() const { - // Evaluate for moc - if (MocConst().Enabled) { - // Evaluate headers - for (auto const& pair : BaseEval().Headers) { - if (!MocEvalHeader(pair.second)) { - return; - } - } - // Evaluate sources - for (auto const& pair : BaseEval().Sources) { - if (!MocEvalSource(pair.second)) { - return; - } + std::string res; + res.reserve(512); + for (std::string const& path : SearchLocations) { + res += " "; + res += MessagePath(path); + res += '\n'; + } + return res; +} + +void cmQtAutoMocUic::JobEvalCacheMocT::Process() +{ + // Evaluate headers + for (auto const& pair : BaseEval().Headers) { + if (!EvalHeader(pair.second)) { + return; } } - // Evaluate for uic - if (UicConst().Enabled) { - if (!UicEval(BaseEval().Headers) || !UicEval(BaseEval().Sources)) { + // Evaluate sources + for (auto const& pair : BaseEval().Sources) { + if (!EvalSource(pair.second)) { return; } } - - // Add discovered header parse jobs - Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered); - // Add generate job after - Gen()->WorkerPool().EmplaceJob<JobGenerateT>(); } -bool cmQtAutoMocUic::JobEvaluateT::MocEvalHeader(SourceFileHandleT source) +bool cmQtAutoMocUic::JobEvalCacheMocT::EvalHeader(SourceFileHandleT source) { SourceFileT const& sourceFile = *source; auto const& parseData = sourceFile.ParseData->Moc; @@ -606,13 +599,13 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalHeader(SourceFileHandleT source) } // Register mapping in headers map - MocRegisterMapping(handle, true); + RegisterMapping(handle); } return true; } -bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( +bool cmQtAutoMocUic::JobEvalCacheMocT::EvalSource( SourceFileHandleT const& source) { SourceFileT const& sourceFile = *source; @@ -623,7 +616,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( return true; } - std::string const sourceDir = SubDirPrefix(sourceFile.FileName); + std::string const sourceDirPrefix = SubDirPrefix(sourceFile.FileName); std::string const sourceBase = cmSystemTools::GetFilenameWithoutLastExtension(sourceFile.FileName); @@ -650,27 +643,30 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( // Check if this source needs to be moc processed but doesn't. if (!sourceIncludesDotMoc && !parseData.Macro.empty() && !(relaxedMode && sourceIncludesMocUnderscore)) { - 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")); + LogError(GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ", + Quoted(parseData.Macro), " macro, but does not include ", + MessagePath(sourceBase + ".moc"), + "!\nConsider to\n - add #include \"", sourceBase, + ".moc\"\n - enable SKIP_AUTOMOC for this file")); return false; } // Evaluate "moc_" includes for (IncludeKeyT const& incKey : parseData.Include.Underscore) { - std::string const headerBase = incKey.Dir + incKey.Base; - SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase); - if (!header) { - 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; + SourceFileHandleT headerHandle; + { + std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base); + if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) { + LogError(GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), + "\nincludes the moc file ", MessagePath(incKey.Key), + ",\nbut a header ", MessageHeader(headerBase), + "\ncould not be found " + "in the following directories\n", + MessageSearchLocations())); + return false; + } } // The include might be handled differently in relaxed mode if (relaxedMode && !sourceIncludesDotMoc && !parseData.Macro.empty() && @@ -682,30 +678,30 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( // used. This is for KDE4 compatibility. // 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"), + Log().Warning( + GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ", + Quoted(parseData.Macro), " macro, but does not include ", + MessagePath(sourceBase + ".moc"), ".\nInstead it includes ", + MessagePath(incKey.Key), ".\nRunning moc on the source\n ", + MessagePath(sourceFile.FileName), "!\nBetter include ", + MessagePath(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)) { + if (!RegisterIncluded(incKey.Key, source, source)) { return false; } continue; } // Check if header is skipped - if (MocConst().skipped(header->FileName)) { + if (MocConst().skipped(headerHandle->FileName)) { continue; } // Create mapping - if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) { + if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) { return false; } } @@ -718,53 +714,60 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( bool const ownMoc = (incKey.Base == sourceBase); if (ownMoc && !parseData.Macro.empty()) { // Create mapping for the regular use case - if (!MocRegisterIncluded(incKey.Key, source, source, false)) { + if (!RegisterIncluded(incKey.Key, source, source)) { return false; } continue; } // Try to find a header instead but issue a warning. // This is for KDE4 compatibility. - std::string const headerBase = incKey.Dir + incKey.Base; - SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase); - if (!header) { - 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))); - return false; + SourceFileHandleT headerHandle; + { + std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base); + if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) { + LogError( + GenT::MOC, + cmStrCat( + MessagePath(sourceFile.FileName), "\nincludes the moc file ", + MessagePath(incKey.Key), + ",\nwhich seems to be the moc file from a different source " + "file.\nCMAKE_AUTOMOC_RELAXED_MODE:\nAlso a matching header ", + MessageHeader(headerBase), + "\ncould not be found in the following directories\n", + MessageSearchLocations())); + return false; + } } // Check if header is skipped - if (MocConst().skipped(header->FileName)) { + if (MocConst().skipped(headerHandle->FileName)) { continue; } // Issue a warning if (ownMoc && parseData.Macro.empty()) { - Log().WarningFile( - GenT::MOC, sourceFile.FileName, - cmStrCat("The file includes the moc file ", Quoted(incKey.Key), + Log().Warning( + GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), + "\nincludes the moc file ", MessagePath(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"), + MessagePath(headerHandle->FileName), "!\nBetter include ", + MessagePath("moc_" + incKey.Base + ".cpp"), " for a compatibility with regular mode.\n", "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); } else { - Log().WarningFile( - GenT::MOC, sourceFile.FileName, - cmStrCat("The file includes the moc file ", Quoted(incKey.Key), - " instead of ", Quoted("moc_" + incKey.Base + ".cpp"), + Log().Warning( + GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), + "\nincludes the moc file ", MessagePath(incKey.Key), + " instead of ", MessagePath("moc_" + incKey.Base + ".cpp"), ".\nRunning moc on the header\n ", - Quoted(header->FileName), "!\nBetter include ", - Quoted("moc_" + incKey.Base + ".cpp"), + MessagePath(headerHandle->FileName), "!\nBetter include ", + MessagePath("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)) { + if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) { return false; } } @@ -775,25 +778,26 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( bool const ownMoc = (incKey.Base == sourceBase); if (!ownMoc) { // Don't allow <BASE>.moc include other than own in regular mode - 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.")); + LogError(GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), + "\nincludes the moc file ", MessagePath(incKey.Key), + ",\nwhich seems to be the moc file from a different " + "source file.\nThis is not supported. Include ", + MessagePath(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()) { - Log().WarningFile(GenT::MOC, sourceFile.FileName, - cmStrCat("The file includes the moc file ", - Quoted(incKey.Key), - ", but does not contain a ", - MocConst().MacrosString(), " macro.")); + Log().Warning(GenT::MOC, + cmStrCat(MessagePath(sourceFile.FileName), + "\nincludes the moc file ", + MessagePath(incKey.Key), + ", but does not contain a ", + MocConst().MacrosString(), " macro.")); } // Create mapping - if (!MocRegisterIncluded(incKey.Key, source, source, false)) { + if (!RegisterIncluded(incKey.Key, source, source)) { return false; } } @@ -802,80 +806,74 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( return true; } -cmQtAutoMocUic::SourceFileHandleT -cmQtAutoMocUic::JobEvaluateT::MocFindIncludedHeader( - std::string const& includerDir, std::string const& includeBase) const +bool cmQtAutoMocUic::JobEvalCacheMocT::FindIncludedHeader( + SourceFileHandleT& headerHandle, cm::string_view includerDir, + cm::string_view includeBase) { - // Search in vicinity of the source - { - SourceFileHandleT res = MocFindHeader(includerDir + includeBase); - if (res) { - return res; - } - } - // Search in include directories - for (std::string const& path : MocConst().IncludePaths) { - std::string testPath = cmStrCat(path, '/', includeBase); - SourceFileHandleT res = MocFindHeader(testPath); - if (res) { - return res; - } - } - // Return without success - return SourceFileHandleT(); -} + // Clear search locations + SearchLocations.clear(); + + auto findHeader = [this, + &headerHandle](std::string const& basePath) -> bool { + bool found = false; + std::string const baseCollapsed = + this->Gen()->CollapseFullPathTS(cmStrCat(basePath, '.')); + for (std::string const& ext : this->BaseConst().HeaderExtensions) { + std::string const testPath = cmStrCat(baseCollapsed, ext); + cmFileTime fileTime; + if (!fileTime.Load(testPath)) { + // File not found + continue; + } -cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader( - std::string const& basePath) const -{ - std::string testPath; - testPath.reserve(basePath.size() + 8); - for (std::string const& ext : BaseConst().HeaderExtensions) { - testPath.clear(); - testPath += basePath; - testPath += '.'; - testPath += ext; - cmFileTime fileTime; - if (fileTime.Load(testPath)) { - // Compute real path of the file - testPath = cmSystemTools::GetRealPath(testPath); // Return a known file if it exists already { auto it = BaseEval().Headers.find(testPath); if (it != BaseEval().Headers.end()) { - return it->second; + headerHandle = it->second; + found = true; + break; } } + // Created and return discovered file entry - SourceFileHandleT& res = MocEval().HeadersDiscovered[testPath]; - if (!res) { - res = std::make_shared<SourceFileT>(testPath); - res->FileTime = fileTime; - res->Moc = true; + { + SourceFileHandleT& handle = MocEval().HeadersDiscovered[testPath]; + if (!handle) { + handle = std::make_shared<SourceFileT>(testPath); + handle->FileTime = fileTime; + handle->IsHeader = true; + handle->Moc = true; + } + headerHandle = handle; + found = true; + break; } - return res; } - } - // Return without success - return SourceFileHandleT(); -} + if (!found) { + this->SearchLocations.emplace_back( + cmQtAutoGen::ParentDir(baseCollapsed)); + } + return found; + }; -std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders( - cm::string_view fileBase) const -{ - std::string const exts = - cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), '}'); - // Compose result string - std::string res = cmStrCat(" ", fileBase, exts, '\n'); + // Search in vicinity of the source + if (findHeader(cmStrCat(includerDir, includeBase))) { + return true; + } + // Search in include directories for (std::string const& path : MocConst().IncludePaths) { - res += cmStrCat(" ", path, '/', fileBase, exts, '\n'); + if (findHeader(cmStrCat(path, '/', includeBase))) { + return true; + } } - return res; + // Return without success + return false; } -bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded( +bool cmQtAutoMocUic::JobEvalCacheMocT::RegisterIncluded( std::string const& includeString, SourceFileHandleT includerFileHandle, - SourceFileHandleT sourceFileHandle, bool sourceIsHeader) const + SourceFileHandleT sourceFileHandle) const { // Check if this file is already included MappingHandleT& handle = MocEval().Includes[includeString]; @@ -883,18 +881,19 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded( // Check if the output file would be generated from different source files if (handle->SourceFile != sourceFileHandle) { std::string files = - cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n'); + cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { - files += cmStrCat(" ", Quoted(item->FileName), '\n'); + files += cmStrCat(" ", MessagePath(item->FileName), '\n'); } LogError( GenT::MOC, cmStrCat("The source files\n", files, - "contain the same include string ", Quoted(includeString), + "contain the same include string ", + MessagePath(includeString), ", but\nthe moc file would be generated from different " "source files\n ", - Quoted(sourceFileHandle->FileName), " and\n ", - Quoted(handle->SourceFile->FileName), + MessagePath(sourceFileHandle->FileName), " and\n ", + MessagePath(handle->SourceFile->FileName), ".\nConsider to\n" " - not include the \"moc_<NAME>.cpp\" file\n" " - add a directory prefix to a \"<NAME>.moc\" include " @@ -916,15 +915,16 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded( handle->OutputFile = Gen()->AbsoluteIncludePath(includeString); // Register mapping in sources/headers map - MocRegisterMapping(handle, sourceIsHeader); + RegisterMapping(handle); return true; } -void cmQtAutoMocUic::JobEvaluateT::MocRegisterMapping( - MappingHandleT mappingHandle, bool sourceIsHeader) const +void cmQtAutoMocUic::JobEvalCacheMocT::RegisterMapping( + MappingHandleT mappingHandle) const { - auto& regMap = - sourceIsHeader ? MocEval().HeaderMappings : MocEval().SourceMappings; + auto& regMap = mappingHandle->SourceFile->IsHeader + ? MocEval().HeaderMappings + : MocEval().SourceMappings; // Check if source file already gets mapped auto& regHandle = regMap[mappingHandle->SourceFile->FileName]; if (!regHandle) { @@ -938,17 +938,33 @@ void cmQtAutoMocUic::JobEvaluateT::MocRegisterMapping( } } -bool cmQtAutoMocUic::JobEvaluateT::UicEval(SourceFileMapT const& fileMap) +std::string cmQtAutoMocUic::JobEvalCacheMocT::MessageHeader( + cm::string_view headerBase) const { - for (auto const& pair : fileMap) { - if (!UicEvalFile(pair.second)) { - return false; + return MessagePath(cmStrCat( + headerBase, ".{", cmJoin(this->BaseConst().HeaderExtensions, ","), '}')); +} + +void cmQtAutoMocUic::JobEvalCacheUicT::Process() +{ + // Prepare buffers + SearchLocations.reserve((UicConst().SearchPaths.size() + 1) * 2); + + // Evaluate headers + for (auto const& pair : BaseEval().Headers) { + if (!EvalFile(pair.second)) { + return; + } + } + // Evaluate sources + for (auto const& pair : BaseEval().Sources) { + if (!EvalFile(pair.second)) { + return; } } - return true; } -bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile( +bool cmQtAutoMocUic::JobEvalCacheUicT::EvalFile( SourceFileHandleT const& sourceFileHandle) { SourceFileT const& sourceFile = *sourceFileHandle; @@ -957,17 +973,25 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile( return true; } - std::string const sourceDir = SubDirPrefix(sourceFile.FileName); + std::string const sourceDirPrefix = SubDirPrefix(sourceFile.FileName); for (IncludeKeyT const& incKey : Include) { - // Find .ui file name - SourceFileHandleT uiFileHandle = - UicFindIncludedUi(sourceFile.FileName, sourceDir, incKey); - if (!uiFileHandle || UicConst().skipped(uiFileHandle->FileName)) { + // Find .ui file + UiName = cmStrCat(incKey.Base, ".ui"); + if (!FindIncludedUi(sourceDirPrefix, incKey.Dir)) { + LogError(GenT::UIC, + cmStrCat(MessagePath(sourceFile.FileName), + "\nincludes the uic file ", MessagePath(incKey.Key), + ",\nbut the user interface file ", MessagePath(UiName), + "\ncould not be found in the following directories\n", + MessageSearchLocations())); + return false; + } + // Check if the file is skipped + if (UicConst().skipped(UiFileHandle->FileName)) { continue; } // Register mapping - if (!UicRegisterMapping(incKey.Key, std::move(uiFileHandle), - sourceFileHandle)) { + if (!RegisterMapping(incKey.Key, sourceFileHandle)) { return false; } } @@ -975,20 +999,73 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile( return true; } -bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping( - std::string const& includeString, SourceFileHandleT uiFileHandle, - SourceFileHandleT includerFileHandle) +bool cmQtAutoMocUic::JobEvalCacheUicT::FindIncludedUi( + cm::string_view sourceDirPrefix, cm::string_view includePrefix) +{ + // Clear locations buffer + SearchLocations.clear(); + + auto findUi = [this](std::string const& testPath) -> bool { + std::string const fullPath = this->Gen()->CollapseFullPathTS(testPath); + cmFileTime fileTime; + if (!fileTime.Load(fullPath)) { + this->SearchLocations.emplace_back(cmQtAutoGen::ParentDir(fullPath)); + return false; + } + // .ui file found in files system! + // Get or create .ui file handle + SourceFileHandleT& handle = this->UicEval().UiFiles[fullPath]; + if (!handle) { + // The file wasn't registered, yet + handle = std::make_shared<SourceFileT>(fullPath); + handle->FileTime = fileTime; + } + this->UiFileHandle = handle; + return true; + }; + + // Vicinity of the source + if (findUi(cmStrCat(sourceDirPrefix, UiName))) { + return true; + } + if (!includePrefix.empty()) { + if (findUi(cmStrCat(sourceDirPrefix, includePrefix, UiName))) { + return true; + } + } + // Additional AUTOUIC search paths + auto const& searchPaths = UicConst().SearchPaths; + if (!searchPaths.empty()) { + for (std::string const& sPath : searchPaths) { + if (findUi(cmStrCat(sPath, '/', UiName))) { + return true; + } + } + if (!includePrefix.empty()) { + for (std::string const& sPath : searchPaths) { + if (findUi(cmStrCat(sPath, '/', includePrefix, UiName))) { + return true; + } + } + } + } + + return false; +} + +bool cmQtAutoMocUic::JobEvalCacheUicT::RegisterMapping( + std::string const& includeString, SourceFileHandleT includerFileHandle) { auto& Includes = Gen()->UicEval().Includes; auto it = Includes.find(includeString); if (it != Includes.end()) { MappingHandleT const& handle = it->second; - if (handle->SourceFile != uiFileHandle) { + if (handle->SourceFile != UiFileHandle) { // The output file already gets generated - from a different .ui file! std::string files = - cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n'); + cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { - files += cmStrCat(" ", Quoted(item->FileName), '\n'); + files += cmStrCat(" ", MessagePath(item->FileName), '\n'); } LogError( GenT::UIC, @@ -997,8 +1074,8 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping( Quoted(includeString), ", but\nthe uic file would be generated from different " "user interface files\n ", - Quoted(uiFileHandle->FileName), " and\n ", - Quoted(handle->SourceFile->FileName), + MessagePath(UiFileHandle->FileName), " and\n ", + MessagePath(handle->SourceFile->FileName), ".\nConsider to\n" " - add a directory prefix to a \"ui_<NAME>.h\" include " "(e.g \"sub/ui_<NAME>.h\")\n" @@ -1013,7 +1090,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping( MappingHandleT handle = std::make_shared<MappingT>(); handle->IncludeString = includeString; handle->IncluderFiles.emplace_back(std::move(includerFileHandle)); - handle->SourceFile = std::move(uiFileHandle); + handle->SourceFile = UiFileHandle; handle->OutputFile = Gen()->AbsoluteIncludePath(includeString); // Register mapping Includes.emplace(includeString, std::move(handle)); @@ -1021,123 +1098,60 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping( return true; } -cmQtAutoMocUic::SourceFileHandleT -cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi( - std::string const& sourceFile, std::string const& sourceDir, - IncludeKeyT const& incKey) const +void cmQtAutoMocUic::JobEvalCacheFinishT::Process() { - std::string searchFileName = cmStrCat(incKey.Base, ".ui"); - // Collect search paths list - std::vector<std::string> testFiles; - { - auto& searchPaths = UicConst().SearchPaths; - testFiles.reserve((searchPaths.size() + 1) * 2); - - // Vicinity of the source - testFiles.emplace_back(sourceDir + searchFileName); - if (!incKey.Dir.empty()) { - testFiles.emplace_back(cmStrCat(sourceDir, incKey.Dir, searchFileName)); - } - // AUTOUIC search paths - if (!searchPaths.empty()) { - for (std::string const& sPath : searchPaths) { - testFiles.emplace_back(cmStrCat(sPath, '/', searchFileName)); - } - if (!incKey.Dir.empty()) { - for (std::string const& sPath : searchPaths) { - testFiles.emplace_back( - cmStrCat(sPath, '/', incKey.Dir, searchFileName)); - } - } - } - } - - // Search for the .ui file! - for (std::string const& testFile : testFiles) { - cmFileTime fileTime; - if (fileTime.Load(testFile)) { - // .ui file found in files system! - std::string realPath = cmSystemTools::GetRealPath(testFile); - // Get or create .ui file handle - SourceFileHandleT& handle = Gen()->UicEval().UiFiles[realPath]; - if (!handle) { - // The file wasn't registered, yet - handle = std::make_shared<SourceFileT>(realPath); - handle->FileTime = fileTime; - } - return handle; - } - } + // Add discovered header parse jobs + Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered); - // Log error + // Add dependency probing jobs { - std::string files; - for (std::string const& testFile : testFiles) { - files += cmStrCat(" ", Quoted(testFile), '\n'); + // Add fence job to ensure all parsing has finished + Gen()->WorkerPool().EmplaceJob<JobFenceT>(); + if (MocConst().Enabled) { + Gen()->WorkerPool().EmplaceJob<JobProbeDepsMocT>(); + } + if (UicConst().Enabled) { + Gen()->WorkerPool().EmplaceJob<JobProbeDepsUicT>(); } - 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)); + // Add probe finish job + Gen()->WorkerPool().EmplaceJob<JobProbeDepsFinishT>(); } - - return SourceFileHandleT(); } -void cmQtAutoMocUic::JobGenerateT::Process() +void cmQtAutoMocUic::JobProbeDepsMocT::Process() { - // Add moc compile jobs - if (MocConst().Enabled) { - for (auto const& pair : MocEval().HeaderMappings) { - // Register if this mapping is a candidate for mocs_compilation.cpp - bool const compFile = pair.second->IncludeString.empty(); - if (compFile) { - MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath); - } - if (!MocGenerate(pair.second, compFile)) { - return; - } + // Create moc header jobs + for (auto const& pair : MocEval().HeaderMappings) { + // Register if this mapping is a candidate for mocs_compilation.cpp + bool const compFile = pair.second->IncludeString.empty(); + if (compFile) { + MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath); } - for (auto const& pair : MocEval().SourceMappings) { - if (!MocGenerate(pair.second, false)) { - return; - } + if (!Generate(pair.second, compFile)) { + return; } - - // Add mocs compilations job on demand - Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>(); } - // Add uic compile jobs - if (UicConst().Enabled) { - for (auto const& pair : Gen()->UicEval().Includes) { - if (!UicGenerate(pair.second)) { - return; - } + // Create moc source jobs + for (auto const& pair : MocEval().SourceMappings) { + if (!Generate(pair.second, false)) { + return; } } - - // Add finish job - Gen()->WorkerPool().EmplaceJob<JobFinishT>(); } -bool cmQtAutoMocUic::JobGenerateT::MocGenerate(MappingHandleT const& mapping, - bool compFile) const +bool cmQtAutoMocUic::JobProbeDepsMocT::Generate(MappingHandleT const& mapping, + bool compFile) const { std::unique_ptr<std::string> reason; if (Log().Verbose()) { reason = cm::make_unique<std::string>(); } - if (MocUpdate(*mapping, reason.get())) { - // Create the parent directory - if (!MakeParentDirectory(mapping->OutputFile)) { - LogFileError(GenT::MOC, mapping->OutputFile, - "Could not create parent directory."); - return false; - } + if (Probe(*mapping, reason.get())) { + // Register the parent directory for creation + MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile)); // Add moc job - Gen()->WorkerPool().EmplaceJob<JobMocT>(mapping, std::move(reason)); + Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason)); // Check if a moc job for a mocs_compilation.cpp entry was generated if (compFile) { MocEval().CompUpdated = true; @@ -1146,7 +1160,7 @@ bool cmQtAutoMocUic::JobGenerateT::MocGenerate(MappingHandleT const& mapping, return true; } -bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, +bool cmQtAutoMocUic::JobProbeDepsMocT::Probe(MappingT const& mapping, std::string* reason) const { std::string const& sourceFile = mapping.SourceFile->FileName; @@ -1157,8 +1171,8 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, if (!outputFileTime.Load(outputFile)) { if (reason != nullptr) { *reason = - cmStrCat("Generating ", Quoted(outputFile), - ", because it doesn't exist, from ", Quoted(sourceFile)); + cmStrCat("Generating ", MessagePath(outputFile), + ", because it doesn't exist, from ", MessagePath(sourceFile)); } return true; } @@ -1166,9 +1180,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if any setting changed if (MocConst().SettingsChanged) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(outputFile), + *reason = cmStrCat("Generating ", MessagePath(outputFile), ", because the uic settings changed, from ", - Quoted(sourceFile)); + MessagePath(sourceFile)); } return true; } @@ -1176,9 +1190,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if the source file is newer if (outputFileTime.Older(mapping.SourceFile->FileTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(outputFile), + *reason = cmStrCat("Generating ", MessagePath(outputFile), ", because it's older than its source file, from ", - Quoted(sourceFile)); + MessagePath(sourceFile)); } return true; } @@ -1187,9 +1201,10 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, if (!MocConst().PredefsFileAbs.empty()) { if (outputFileTime.Older(MocEval().PredefsTime)) { if (reason != nullptr) { - *reason = cmStrCat( - "Generating ", Quoted(outputFile), ", because it's older than ", - Quoted(MocConst().PredefsFileAbs), ", from ", Quoted(sourceFile)); + *reason = cmStrCat("Generating ", MessagePath(outputFile), + ", because it's older than ", + MessagePath(MocConst().PredefsFileAbs), ", from ", + MessagePath(sourceFile)); } return true; } @@ -1198,9 +1213,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if the moc executable is newer if (outputFileTime.Older(MocConst().ExecutableTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(outputFile), + *reason = cmStrCat("Generating ", MessagePath(outputFile), ", because it's older than the moc executable, from ", - Quoted(sourceFile)); + MessagePath(sourceFile)); } return true; } @@ -1211,19 +1226,21 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, std::string const sourceDir = SubDirPrefix(sourceFile); for (std::string const& dep : mapping.SourceFile->ParseData->Moc.Depends) { // Find dependency file - auto const depMatch = MocFindDependency(sourceDir, dep); + auto const depMatch = FindDependency(sourceDir, dep); if (depMatch.first.empty()) { - Log().WarningFile(GenT::MOC, sourceFile, - "Could not find dependency file " + Quoted(dep)); + Log().Warning(GenT::MOC, + cmStrCat(MessagePath(sourceFile), " depends on ", + MessagePath(dep), + " but the file does not exist.")); continue; } // Test if dependency file is older if (outputFileTime.Older(depMatch.second)) { if (reason != nullptr) { - *reason = - cmStrCat("Generating ", Quoted(outputFile), - ", because it's older than its dependency file ", - Quoted(depMatch.first), ", from ", Quoted(sourceFile)); + *reason = cmStrCat("Generating ", MessagePath(outputFile), + ", because it's older than its dependency file ", + MessagePath(depMatch.first), ", from ", + MessagePath(sourceFile)); } return true; } @@ -1234,7 +1251,7 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, } std::pair<std::string, cmFileTime> -cmQtAutoMocUic::JobGenerateT::MocFindDependency( +cmQtAutoMocUic::JobProbeDepsMocT::FindDependency( std::string const& sourceDir, std::string const& includeString) const { using ResPair = std::pair<std::string, cmFileTime>; @@ -1256,27 +1273,26 @@ cmQtAutoMocUic::JobGenerateT::MocFindDependency( return ResPair(); } -bool cmQtAutoMocUic::JobGenerateT::UicGenerate( - MappingHandleT const& mapping) const +void cmQtAutoMocUic::JobProbeDepsUicT::Process() { - std::unique_ptr<std::string> reason; - if (Log().Verbose()) { - reason = cm::make_unique<std::string>(); - } - if (UicUpdate(*mapping, reason.get())) { - // Create the parent directory - if (!MakeParentDirectory(mapping->OutputFile)) { - LogFileError(GenT::UIC, mapping->OutputFile, - "Could not create parent directory."); - return false; + for (auto const& pair : Gen()->UicEval().Includes) { + MappingHandleT const& mapping = pair.second; + std::unique_ptr<std::string> reason; + if (Log().Verbose()) { + reason = cm::make_unique<std::string>(); } + if (!Probe(*mapping, reason.get())) { + continue; + } + + // Register the parent directory for creation + UicEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile)); // Add uic job - Gen()->WorkerPool().EmplaceJob<JobUicT>(mapping, std::move(reason)); + Gen()->WorkerPool().EmplaceJob<JobCompileUicT>(mapping, std::move(reason)); } - return true; } -bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, +bool cmQtAutoMocUic::JobProbeDepsUicT::Probe(MappingT const& mapping, std::string* reason) const { std::string const& sourceFile = mapping.SourceFile->FileName; @@ -1287,8 +1303,8 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, if (!outputFileTime.Load(outputFile)) { if (reason != nullptr) { *reason = - cmStrCat("Generating ", Quoted(outputFile), - ", because it doesn't exist, from ", Quoted(sourceFile)); + cmStrCat("Generating ", MessagePath(outputFile), + ", because it doesn't exist, from ", MessagePath(sourceFile)); } return true; } @@ -1296,9 +1312,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, // Test if the uic settings changed if (UicConst().SettingsChanged) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(outputFile), + *reason = cmStrCat("Generating ", MessagePath(outputFile), ", because the uic settings changed, from ", - Quoted(sourceFile)); + MessagePath(sourceFile)); } return true; } @@ -1306,9 +1322,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, // Test if the source file is newer if (outputFileTime.Older(mapping.SourceFile->FileTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(outputFile), + *reason = cmStrCat("Generating ", MessagePath(outputFile), " because it's older than the source file ", - Quoted(sourceFile)); + MessagePath(sourceFile)); } return true; } @@ -1316,9 +1332,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, // Test if the uic executable is newer if (outputFileTime.Older(UicConst().ExecutableTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", Quoted(outputFile), + *reason = cmStrCat("Generating ", MessagePath(outputFile), ", because it's older than the uic executable, from ", - Quoted(sourceFile)); + MessagePath(sourceFile)); } return true; } @@ -1326,24 +1342,93 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, return false; } -void cmQtAutoMocUic::JobMocT::Process() +void cmQtAutoMocUic::JobProbeDepsFinishT::Process() +{ + // Create output directories + { + using StringSet = std::unordered_set<std::string>; + auto createDirs = [this](GenT genType, StringSet const& dirSet) { + for (std::string const& dirName : dirSet) { + if (!cmSystemTools::MakeDirectory(dirName)) { + this->LogError( + genType, + cmStrCat("Creating directory ", MessagePath(dirName), " failed.")); + return; + } + } + }; + if (MocConst().Enabled && UicConst().Enabled) { + StringSet outputDirs = MocEval().OutputDirs; + outputDirs.insert(UicEval().OutputDirs.begin(), + UicEval().OutputDirs.end()); + createDirs(GenT::GEN, outputDirs); + } else if (MocConst().Enabled) { + createDirs(GenT::MOC, MocEval().OutputDirs); + } else if (UicConst().Enabled) { + createDirs(GenT::UIC, UicEval().OutputDirs); + } + } + + if (MocConst().Enabled) { + // Add mocs compilations job + Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>(); + } + + // Add finish job + Gen()->WorkerPool().EmplaceJob<JobFinishT>(); +} + +void cmQtAutoMocUic::JobCompileMocT::Process() { std::string const& sourceFile = Mapping->SourceFile->FileName; std::string const& outputFile = Mapping->OutputFile; // Compose moc command std::vector<std::string> cmd; - cmd.push_back(MocConst().Executable); - // Add options - cmAppend(cmd, MocConst().AllOptions); - // Add predefs include - if (!MocConst().PredefsFileAbs.empty()) { - cmd.emplace_back("--include"); - cmd.push_back(MocConst().PredefsFileAbs); + { + // Reserve large enough + cmd.reserve(MocConst().OptionsDefinitions.size() + + MocConst().OptionsIncludes.size() + + MocConst().OptionsExtra.size() + 16); + cmd.push_back(MocConst().Executable); + // Add definitions + cmAppend(cmd, MocConst().OptionsDefinitions); + // Add includes + cmAppend(cmd, MocConst().OptionsIncludes); + // Add predefs include + if (!MocConst().PredefsFileAbs.empty()) { + cmd.emplace_back("--include"); + cmd.push_back(MocConst().PredefsFileAbs); + } + // Add path prefix on demand + if (MocConst().PathPrefix && Mapping->SourceFile->IsHeader) { + for (std::string const& dir : MocConst().IncludePaths) { + cm::string_view prefix = sourceFile; + if (cmHasPrefix(prefix, dir)) { + prefix.remove_prefix(dir.size()); + if (cmHasPrefix(prefix, '/')) { + prefix.remove_prefix(1); + auto slashPos = prefix.rfind('/'); + if (slashPos != cm::string_view::npos) { + cmd.emplace_back("-p"); + cmd.emplace_back(prefix.substr(0, slashPos)); + } else { + cmd.emplace_back("-p"); + cmd.emplace_back("./"); + } + break; + } + } + } + } + // Add extra options + cmAppend(cmd, MocConst().OptionsExtra); + // Add output file + cmd.emplace_back("-o"); + cmd.push_back(outputFile); + // Add source file + cmd.push_back(sourceFile); } - cmd.emplace_back("-o"); - cmd.push_back(outputFile); - cmd.push_back(sourceFile); // Execute moc command cmWorkerPool::ProcessResultT result; @@ -1358,19 +1443,19 @@ void cmQtAutoMocUic::JobMocT::Process() if (!Mapping->IncluderFiles.empty()) { includers = "included by\n"; for (auto const& item : Mapping->IncluderFiles) { - includers += cmStrCat(" ", Quoted(item->FileName), '\n'); + includers += cmStrCat(" ", MessagePath(item->FileName), '\n'); } } LogCommandError(GenT::MOC, cmStrCat("The moc process failed to compile\n ", - Quoted(sourceFile), "\ninto\n ", - Quoted(outputFile), '\n', includers, + MessagePath(sourceFile), "\ninto\n ", + MessagePath(outputFile), '\n', includers, result.ErrorMessage), cmd, result.StdOut); } } -void cmQtAutoMocUic::JobUicT::Process() +void cmQtAutoMocUic::JobCompileUicT::Process() { std::string const& sourceFile = Mapping->SourceFile->FileName; std::string const& outputFile = Mapping->OutputFile; @@ -1402,13 +1487,13 @@ void cmQtAutoMocUic::JobUicT::Process() // Uic command failed std::string includers; for (auto const& item : Mapping->IncluderFiles) { - includers += cmStrCat(" ", Quoted(item->FileName), '\n'); + includers += cmStrCat(" ", MessagePath(item->FileName), '\n'); } LogCommandError(GenT::UIC, cmStrCat("The uic process failed to compile\n ", - Quoted(sourceFile), "\ninto\n ", - Quoted(outputFile), "\nincluded by\n", includers, - result.ErrorMessage), + MessagePath(sourceFile), "\ninto\n ", + MessagePath(outputFile), "\nincluded by\n", + includers, result.ErrorMessage), cmd, result.StdOut); } } @@ -1436,20 +1521,24 @@ void cmQtAutoMocUic::JobMocsCompilationT::Process() if (cmQtAutoGenerator::FileDiffers(compAbs, content)) { // Actually write mocs compilation file if (Log().Verbose()) { - Log().Info(GenT::MOC, "Generating MOC compilation " + compAbs); + Log().Info(GenT::MOC, + "Generating MOC compilation " + MessagePath(compAbs)); } if (!FileWrite(compAbs, content)) { - LogFileError(GenT::MOC, compAbs, - "mocs compilation file writing failed."); + LogError(GenT::MOC, + cmStrCat("Writing MOC compilation ", MessagePath(compAbs), + " failed.")); } } else if (MocEval().CompUpdated) { // Only touch mocs compilation file if (Log().Verbose()) { - Log().Info(GenT::MOC, "Touching mocs compilation " + compAbs); + Log().Info(GenT::MOC, + "Touching MOC compilation " + MessagePath(compAbs)); } if (!cmSystemTools::Touch(compAbs, false)) { - LogFileError(GenT::MOC, compAbs, - "mocs compilation file touching failed."); + LogError(GenT::MOC, + cmStrCat("Touching MOC compilation ", MessagePath(compAbs), + " failed.")); } } } @@ -1543,12 +1632,10 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) makefile->GetCMakeInstance()->GetHeaderExtensions(); // - Files and directories - BaseConst_.IncludeProjectDirsBefore = - InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); - BaseConst_.ProjectSourceDir = InfoGet("AM_CMAKE_SOURCE_DIR"); - BaseConst_.ProjectBinaryDir = InfoGet("AM_CMAKE_BINARY_DIR"); - BaseConst_.CurrentSourceDir = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR"); - BaseConst_.CurrentBinaryDir = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR"); + ProjectDirsRef().Source = InfoGet("AM_CMAKE_SOURCE_DIR"); + ProjectDirsRef().Binary = InfoGet("AM_CMAKE_BINARY_DIR"); + ProjectDirsRef().CurrentSource = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR"); + ProjectDirsRef().CurrentBinary = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR"); BaseConst_.AutogenBuildDir = InfoGet("AM_BUILD_DIR"); if (BaseConst_.AutogenBuildDir.empty()) { return LogInfoError("Autogen build directory missing."); @@ -1563,7 +1650,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) } if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) { return LogInfoError(cmStrCat("The CMake executable ", - Quoted(BaseConst_.CMakeExecutable), + MessagePath(BaseConst_.CMakeExecutable), " does not exist.")); } BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE"); @@ -1592,7 +1679,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Load the executable file time if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) { return LogInfoError(cmStrCat("The moc executable ", - Quoted(MocConst_.Executable), + MessagePath(MocConst_.Executable), " does not exist.")); } for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) { @@ -1600,8 +1687,11 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) } MocConst_.Definitions = InfoGetConfigList("AM_MOC_DEFINITIONS"); MocConst_.IncludePaths = InfoGetConfigList("AM_MOC_INCLUDES"); - MocConst_.Options = InfoGetList("AM_MOC_OPTIONS"); + MocConst_.OptionsExtra = InfoGetList("AM_MOC_OPTIONS"); + MocConst_.RelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE"); + MocConst_.PathPrefix = InfoGetBool("AM_MOC_PATH_PREFIX"); + for (std::string const& item : InfoGetList("AM_MOC_MACRO_NAMES")) { MocConst_.MacroFilters.emplace_back( item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]")); @@ -1658,7 +1748,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Load the executable file time if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) { return LogInfoError(cmStrCat("The uic executable ", - Quoted(UicConst_.Executable), + MessagePath(UicConst_.Executable), " does not exist.")); } for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) { @@ -1685,83 +1775,89 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) } } - // - Headers and sources + // Headers { - auto makeSource = - [&LogInfoError](std::string const& fileName, - std::string const& fileFlags) -> SourceFileHandleT { + // Get file lists + 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; + if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) { + return false; + } + if (MocConst().Enabled) { + cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS"; + builds = InfoGetList(keyPaths); + if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) { + return false; + } + } + + // Process file lists + for (std::size_t ii = 0; ii != files.size(); ++ii) { + std::string& fileName(files[ii]); + std::string const& fileFlags(flags[ii]); if (fileFlags.size() != 2) { - LogInfoError("Invalid file flags string size"); - return SourceFileHandleT(); + LogInfoError(cmStrCat("Invalid flags string size ", fileFlags.size(), + "in ", keyFlags)); + return false; } cmFileTime fileTime; if (!fileTime.Load(fileName)) { - LogInfoError("The source file " + cmQtAutoGen::Quoted(fileName) + - " does not exist."); - return SourceFileHandleT(); - } - SourceFileHandleT sfh = std::make_shared<SourceFileT>(fileName); - sfh->FileTime = fileTime; - sfh->Moc = (fileFlags[0] == 'M'); - sfh->Uic = (fileFlags[1] == 'U'); - return sfh; - }; - - // Headers - { - // Get file lists - 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; - if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) { + LogInfoError(cmStrCat("The header file ", this->MessagePath(fileName), + " does not exist.")); return false; } - if (MocConst().Enabled) { - cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS"; - builds = InfoGetList(keyPaths); - if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) { - return false; - } - } - // Process file lists - for (std::size_t ii = 0; ii != files.size(); ++ii) { - std::string& fileName(files[ii]); - SourceFileHandleT sfh = makeSource(fileName, flags[ii]); - if (!sfh) { - return false; - } - if (MocConst().Enabled) { - sfh->BuildPath = std::move(builds[ii]); - if (sfh->BuildPath.empty()) { - Log().ErrorFile(GenT::GEN, this->InfoFile(), - "Header file build path is empty"); - return false; - } + + SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(fileName); + sourceHandle->FileTime = fileTime; + sourceHandle->IsHeader = true; + sourceHandle->Moc = (fileFlags[0] == 'M'); + sourceHandle->Uic = (fileFlags[1] == 'U'); + + if (sourceHandle->Moc && MocConst().Enabled) { + sourceHandle->BuildPath = std::move(builds[ii]); + if (sourceHandle->BuildPath.empty()) { + return LogInfoError("Header file build path is empty"); } - BaseEval().Headers.emplace(std::move(fileName), std::move(sfh)); } + BaseEval().Headers.emplace(std::move(fileName), std::move(sourceHandle)); } + } - // Sources - { - 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())) { + // Sources + { + 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())) { + return false; + } + + // Process file lists + for (std::size_t ii = 0; ii != files.size(); ++ii) { + std::string& fileName(files[ii]); + std::string const& fileFlags(flags[ii]); + if (fileFlags.size() != 2) { + LogInfoError(cmStrCat("Invalid flags string size ", fileFlags.size(), + "in ", keyFlags)); return false; } - // Process file lists - for (std::size_t ii = 0; ii != files.size(); ++ii) { - std::string& fileName(files[ii]); - SourceFileHandleT sfh = makeSource(fileName, flags[ii]); - if (!sfh) { - return false; - } - BaseEval().Sources.emplace(std::move(fileName), std::move(sfh)); + cmFileTime fileTime; + if (!fileTime.Load(fileName)) { + LogInfoError(cmStrCat("The source file ", this->MessagePath(fileName), + " does not exist.")); + return false; } + + SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(fileName); + sourceHandle->FileTime = fileTime; + sourceHandle->IsHeader = false; + sourceHandle->Moc = (fileFlags[0] == 'M'); + sourceHandle->Uic = (fileFlags[1] == 'U'); + BaseEval().Sources.emplace(std::move(fileName), std::move(sourceHandle)); } } @@ -1775,49 +1871,20 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Moc predefs file if (!MocConst_.PredefsCmd.empty()) { + std::string pathRel; if (BaseConst_.MultiConfig) { - MocConst_.PredefsFileRel = - cmStrCat("moc_predefs_", InfoConfig(), ".h"); + pathRel = cmStrCat("moc_predefs_", InfoConfig(), ".h"); } else { - MocConst_.PredefsFileRel = "moc_predefs.h"; + pathRel = "moc_predefs.h"; } - MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel); + MocConst_.PredefsFileAbs = AbsoluteBuildPath(pathRel); } - // Sort include directories on demand - if (BaseConst().IncludeProjectDirsBefore) { - // Move strings to temporary list - std::list<std::string> includes(MocConst().IncludePaths.begin(), - MocConst().IncludePaths.end()); - MocConst_.IncludePaths.clear(); - MocConst_.IncludePaths.reserve(includes.size()); - // Append project directories only - { - std::initializer_list<cm::string_view> const movePaths = { - BaseConst().ProjectBinaryDir, BaseConst().ProjectSourceDir - }; - 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)) { - MocConst_.IncludePaths.push_back(path); - it = includes.erase(it); - } else { - ++it; - } - } - } - } - // Append remaining directories - MocConst_.IncludePaths.insert(MocConst_.IncludePaths.end(), - includes.begin(), includes.end()); - } // Compose moc includes list { + // Compute framework paths std::set<std::string> frameworkPaths; for (std::string const& path : MocConst().IncludePaths) { - MocConst_.Includes.push_back("-I" + path); // Extract framework path if (cmHasLiteralSuffix(path, ".framework/Headers")) { // Go up twice to get to the framework root @@ -1827,26 +1894,26 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) pathComponents.begin(), pathComponents.end() - 2)); } } + // Reserve options + MocConst_.OptionsIncludes.reserve(MocConst().IncludePaths.size() + + frameworkPaths.size() * 2); + // Append includes + for (std::string const& path : MocConst().IncludePaths) { + MocConst_.OptionsIncludes.emplace_back("-I" + path); + } // Append framework includes for (std::string const& path : frameworkPaths) { - MocConst_.Includes.emplace_back("-F"); - MocConst_.Includes.push_back(path); + MocConst_.OptionsIncludes.emplace_back("-F"); + MocConst_.OptionsIncludes.push_back(path); } } - // Setup single list with all options + + // Compose moc definitions list { - // Add includes - MocConst_.AllOptions.insert(MocConst_.AllOptions.end(), - MocConst().Includes.begin(), - MocConst().Includes.end()); - // Add definitions + MocConst_.OptionsDefinitions.reserve(MocConst().Definitions.size()); for (std::string const& def : MocConst().Definitions) { - MocConst_.AllOptions.push_back("-D" + def); + MocConst_.OptionsDefinitions.emplace_back("-D" + def); } - // Add options - MocConst_.AllOptions.insert(MocConst_.AllOptions.end(), - MocConst().Options.begin(), - MocConst().Options.end()); } } @@ -1870,18 +1937,38 @@ void cmQtAutoMocUic::CreateParseJobs(SourceFileMapT const& sourceMap) } } +/** Concurrently callable implementation of cmSystemTools::CollapseFullPath */ +std::string cmQtAutoMocUic::CollapseFullPathTS(std::string const& path) const +{ + std::lock_guard<std::mutex> guard(CMakeLibMutex_); + return cmSystemTools::CollapseFullPath(path, ProjectDirs().CurrentSource); +} + void cmQtAutoMocUic::InitJobs() { // Add moc_predefs.h job if (MocConst().Enabled && !MocConst().PredefsCmd.empty()) { WorkerPool().EmplaceJob<JobMocPredefsT>(); } + // Add header parse jobs CreateParseJobs<JobParseHeaderT>(BaseEval().Headers); // Add source parse jobs CreateParseJobs<JobParseSourceT>(BaseEval().Sources); - // Add evaluate job - WorkerPool().EmplaceJob<JobEvaluateT>(); + + // Add parse cache evaluations jobs + { + // Add a fence job to ensure all parsing has finished + WorkerPool().EmplaceJob<JobFenceT>(); + if (MocConst().Enabled) { + WorkerPool().EmplaceJob<JobEvalCacheMocT>(); + } + if (UicConst().Enabled) { + WorkerPool().EmplaceJob<JobEvalCacheUicT>(); + } + // Add evaluate job + WorkerPool().EmplaceJob<JobEvalCacheFinishT>(); + } } bool cmQtAutoMocUic::Process() @@ -1920,11 +2007,18 @@ void cmQtAutoMocUic::SettingsFileRead() if (MocConst_.Enabled) { cryptoHash.Initialize(); cha(MocConst().Executable); - std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(), - cha); - cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE"); - std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(), - cha); + for (auto const& item : MocConst().OptionsDefinitions) { + cha(item); + } + for (auto const& item : MocConst().OptionsIncludes) { + cha(item); + } + for (auto const& item : MocConst().OptionsExtra) { + cha(item); + } + for (auto const& item : MocConst().PredefsCmd) { + cha(item); + } for (auto const& filter : MocConst().DependFilters) { cha(filter.Key); } @@ -1984,7 +2078,9 @@ bool cmQtAutoMocUic::SettingsFileWrite() // Only write if any setting changed if (MocConst().SettingsChanged || UicConst().SettingsChanged) { if (Log().Verbose()) { - Log().Info(GenT::GEN, "Writing settings file " + Quoted(SettingsFile_)); + Log().Info( + GenT::GEN, + cmStrCat("Writing settings file ", MessagePath(SettingsFile_))); } // Compose settings file content std::string content; @@ -2001,8 +2097,9 @@ bool cmQtAutoMocUic::SettingsFileWrite() // Write settings file std::string error; if (!cmQtAutoGenerator::FileWrite(SettingsFile_, content, &error)) { - Log().ErrorFile(GenT::GEN, SettingsFile_, - "Settings file writing failed. " + error); + Log().Error(GenT::GEN, + cmStrCat("Writing the settings file ", + MessagePath(SettingsFile_), " failed.\n", error)); // Remove old settings file to trigger a full rebuild on the next run cmSystemTools::RemoveFile(SettingsFile_); return false; @@ -2042,12 +2139,14 @@ bool cmQtAutoMocUic::ParseCacheWrite() if (BaseEval().ParseCacheChanged) { if (Log().Verbose()) { Log().Info(GenT::GEN, - "Writing parse cache file " + - Quoted(BaseConst().ParseCacheFile)); + cmStrCat("Writing the parse cache file ", + MessagePath(BaseConst().ParseCacheFile))); } if (!BaseEval().ParseCache.WriteToFile(BaseConst().ParseCacheFile)) { - Log().ErrorFile(GenT::GEN, BaseConst().ParseCacheFile, - "Parse cache file writing failed."); + Log().Error(GenT::GEN, + cmStrCat("Writing the parse cache file ", + MessagePath(BaseConst().ParseCacheFile), + " failed.")); return false; } } @@ -2058,8 +2157,10 @@ bool cmQtAutoMocUic::CreateDirectories() { // Create AUTOGEN include directory if (!cmSystemTools::MakeDirectory(BaseConst().AutogenIncludeDir)) { - Log().ErrorFile(GenT::GEN, BaseConst().AutogenIncludeDir, - "Could not create directory."); + Log().Error(GenT::GEN, + cmStrCat("Creating the AUTOGEN include directory ", + MessagePath(BaseConst().AutogenIncludeDir), + " failed.")); return false; } return true; diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h index 549b088..15b66ca 100644 --- a/Source/cmQtAutoMocUic.h +++ b/Source/cmQtAutoMocUic.h @@ -9,13 +9,15 @@ #include "cmQtAutoGen.h" #include "cmQtAutoGenerator.h" #include "cmWorkerPool.h" -#include "cm_string_view.hxx" #include "cmsys/RegularExpression.hxx" +#include <cm/string_view> + #include <atomic> #include <cstddef> #include <map> #include <memory> +#include <mutex> #include <set> #include <string> #include <unordered_map> @@ -40,9 +42,7 @@ public: public: // -- Types - /** - * Search key plus regular expression pair - */ + /** Search key plus regular expression pair. */ struct KeyExpT { KeyExpT() = default; @@ -63,9 +63,7 @@ public: cmsys::RegularExpression Exp; }; - /** - * Include string with sub parts - */ + /** Include string with sub parts. */ struct IncludeKeyT { IncludeKeyT(std::string const& key, std::size_t basePrefixLength); @@ -75,9 +73,7 @@ public: std::string Base; // Base part of the include file name }; - /** - * Source file parsing cache - */ + /** Source file parsing cache. */ class ParseCacheT { public: @@ -127,9 +123,7 @@ public: std::unordered_map<std::string, FileHandleT> Map_; }; - /** - * Source file data - */ + /** Source file data. */ class SourceFileT { public: @@ -143,15 +137,14 @@ public: cmFileTime FileTime; ParseCacheT::FileHandleT ParseData; std::string BuildPath; + bool IsHeader = false; bool Moc = false; bool Uic = false; }; using SourceFileHandleT = std::shared_ptr<SourceFileT>; using SourceFileMapT = std::map<std::string, SourceFileHandleT>; - /** - * Meta compiler file mapping information - */ + /** Meta compiler file mapping information. */ struct MappingT { SourceFileHandleT SourceFile; @@ -162,9 +155,7 @@ public: using MappingHandleT = std::shared_ptr<MappingT>; using MappingMapT = std::map<std::string, MappingHandleT>; - /** - * Common settings - */ + /** Common settings. */ class BaseSettingsT { public: @@ -178,13 +169,8 @@ public: // -- Attributes // - Config bool MultiConfig = false; - bool IncludeProjectDirsBefore = false; unsigned int QtVersionMajor = 4; // - Directories - std::string ProjectSourceDir; - std::string ProjectBinaryDir; - std::string CurrentSourceDir; - std::string CurrentBinaryDir; std::string AutogenBuildDir; std::string AutogenIncludeDir; // - Files @@ -194,9 +180,7 @@ public: std::vector<std::string> HeaderExtensions; }; - /** - * Shared common variables - */ + /** Shared common variables. */ class BaseEvalT { public: @@ -210,9 +194,7 @@ public: SourceFileMapT Sources; }; - /** - * Moc settings - */ + /** Moc settings. */ class MocSettingsT { public: @@ -231,26 +213,24 @@ public: bool Enabled = false; bool SettingsChanged = false; bool RelaxedMode = false; + bool PathPrefix = false; cmFileTime ExecutableTime; std::string Executable; std::string CompFileAbs; - std::string PredefsFileRel; std::string PredefsFileAbs; std::unordered_set<std::string> SkipList; std::vector<std::string> IncludePaths; - std::vector<std::string> Includes; std::vector<std::string> Definitions; - std::vector<std::string> Options; - std::vector<std::string> AllOptions; + std::vector<std::string> OptionsIncludes; + std::vector<std::string> OptionsDefinitions; + std::vector<std::string> OptionsExtra; std::vector<std::string> PredefsCmd; std::vector<KeyExpT> DependFilters; std::vector<KeyExpT> MacroFilters; cmsys::RegularExpression RegExpInclude; }; - /** - * Moc shared variables - */ + /** Moc shared variables. */ class MocEvalT { public: @@ -262,14 +242,14 @@ public: MappingMapT Includes; // -- Discovered files SourceFileMapT HeadersDiscovered; + // -- Output directories + std::unordered_set<std::string> OutputDirs; // -- Mocs compilation bool CompUpdated = false; std::vector<std::string> CompFiles; }; - /** - * Uic settings - */ + /** Uic settings. */ class UicSettingsT { public: @@ -294,25 +274,23 @@ public: cmsys::RegularExpression RegExpInclude; }; - /** - * Uic shared variables - */ + /** Uic shared variables. */ class UicEvalT { public: + // -- Discovered files SourceFileMapT UiFiles; + // -- Mappings MappingMapT Includes; + // -- Output directories + std::unordered_set<std::string> OutputDirs; }; - /** - * Abstract job class for concurrent job processing - */ + /** Abstract job class for concurrent job processing. */ class JobT : public cmWorkerPool::JobT { protected: - /** - * @brief Protected default constructor - */ + /** Protected default constructor. */ JobT(bool fence = false) : cmWorkerPool::JobT(fence) { @@ -333,25 +311,24 @@ public: UicSettingsT const& UicConst() const { return Gen()->UicConst(); } UicEvalT& UicEval() const { return Gen()->UicEval(); } - // -- Error logging with automatic abort + // -- Logging + std::string MessagePath(cm::string_view path) const + { + return Gen()->MessagePath(path); + } + // - Error logging with automatic abort 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; - /** - * @brief Run an external process. Use only during Process() call! - */ + /** @brief Run an external process. Use only during Process() call! */ bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result, std::vector<std::string> const& command, std::string* infoMessage = nullptr); }; - /** - * Fence job utility class - */ + /** Fence job utility class. */ class JobFenceT : public JobT { public: @@ -362,18 +339,14 @@ public: void Process() override{}; }; - /** - * Generate moc_predefs.h - */ + /** Generate moc_predefs.h. */ class JobMocPredefsT : public JobFenceT { void Process() override; bool Update(std::string* reason) const; }; - /** - * File parse job base class - */ + /** File parse job base class. */ class JobParseT : public JobT { public: @@ -397,9 +370,7 @@ public: std::string Content; }; - /** - * Header file parse job - */ + /** Header file parse job. */ class JobParseHeaderT : public JobParseT { public: @@ -407,9 +378,7 @@ public: void Process() override; }; - /** - * Source file parse job - */ + /** Source file parse job. */ class JobParseSourceT : public JobParseT { public: @@ -417,57 +386,79 @@ public: void Process() override; }; - /** - * Evaluate parsed files - */ - class JobEvaluateT : public JobFenceT + /** Evaluate cached file parse data - moc. */ + class JobEvalCacheT : public JobT + { + protected: + std::string MessageSearchLocations() const; + std::vector<std::string> SearchLocations; + }; + + /** Evaluate cached file parse data - moc. */ + class JobEvalCacheMocT : public JobEvalCacheT { void Process() override; + bool EvalHeader(SourceFileHandleT source); + bool EvalSource(SourceFileHandleT const& source); + bool FindIncludedHeader(SourceFileHandleT& headerHandle, + cm::string_view includerDir, + cm::string_view includeBase); + bool RegisterIncluded(std::string const& includeString, + SourceFileHandleT includerFileHandle, + SourceFileHandleT sourceFileHandle) const; + void RegisterMapping(MappingHandleT mappingHandle) const; + std::string MessageHeader(cm::string_view headerBase) const; + }; - // -- Moc - bool MocEvalHeader(SourceFileHandleT source); - bool MocEvalSource(SourceFileHandleT const& source); - SourceFileHandleT MocFindIncludedHeader( - std::string const& includerDir, std::string const& includeBase) const; - SourceFileHandleT MocFindHeader(std::string const& basePath) const; - std::string MocMessageTestHeaders(cm::string_view fileBase) const; - bool MocRegisterIncluded(std::string const& includeString, - SourceFileHandleT includerFileHandle, - SourceFileHandleT sourceFileHandle, - bool sourceIsHeader) const; - void MocRegisterMapping(MappingHandleT mappingHandle, - bool sourceIsHeader) const; - - // -- Uic - bool UicEval(SourceFileMapT const& fileMap); - bool UicEvalFile(SourceFileHandleT const& sourceFileHandle); - SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile, - std::string const& sourceDir, - IncludeKeyT const& incKey) const; - bool UicRegisterMapping(std::string const& includeString, - SourceFileHandleT uiFileHandle, - SourceFileHandleT includerFileHandle); + /** Evaluate cached file parse data - uic. */ + class JobEvalCacheUicT : public JobEvalCacheT + { + void Process() override; + bool EvalFile(SourceFileHandleT const& sourceFileHandle); + bool FindIncludedUi(cm::string_view sourceDirPrefix, + cm::string_view includePrefix); + bool RegisterMapping(std::string const& includeString, + SourceFileHandleT includerFileHandle); + + std::string UiName; + SourceFileHandleT UiFileHandle; }; - /** - * Generates moc/uic jobs - */ - class JobGenerateT : public JobFenceT + /** Evaluate cached file parse data - finish */ + class JobEvalCacheFinishT : public JobFenceT { void Process() override; - // -- Moc - bool MocGenerate(MappingHandleT const& mapping, bool compFile) const; - bool MocUpdate(MappingT const& mapping, std::string* reason) const; - std::pair<std::string, cmFileTime> MocFindDependency( + }; + + /** Dependency probing base job. */ + class JobProbeDepsT : public JobT + { + }; + + /** Probes file dependencies and generates moc compile jobs. */ + class JobProbeDepsMocT : public JobProbeDepsT + { + void Process() override; + bool Generate(MappingHandleT const& mapping, bool compFile) const; + bool Probe(MappingT const& mapping, std::string* reason) const; + std::pair<std::string, cmFileTime> FindDependency( std::string const& sourceDir, std::string const& includeString) const; - // -- Uic - bool UicGenerate(MappingHandleT const& mapping) const; - bool UicUpdate(MappingT const& mapping, std::string* reason) const; }; - /** - * File compiling base job - */ + /** Probes file dependencies and generates uic compile jobs. */ + class JobProbeDepsUicT : public JobProbeDepsT + { + void Process() override; + bool Probe(MappingT const& mapping, std::string* reason) const; + }; + + /** Dependency probing finish job. */ + class JobProbeDepsFinishT : public JobFenceT + { + void Process() override; + }; + + /** Meta compiler base job. */ class JobCompileT : public JobT { public: @@ -482,36 +473,30 @@ public: std::unique_ptr<std::string> Reason; }; - /** - * moc compiles a file - */ - class JobMocT : public JobCompileT + /** moc compiles a file. */ + class JobCompileMocT : public JobCompileT { public: using JobCompileT::JobCompileT; void Process() override; }; - /** - * uic compiles a file - */ - class JobUicT : public JobCompileT + /** uic compiles a file. */ + class JobCompileUicT : public JobCompileT { public: using JobCompileT::JobCompileT; void Process() override; }; - /// @brief Generate mocs_compilation.cpp - /// + /** Generate mocs_compilation.cpp. */ class JobMocsCompilationT : public JobFenceT { private: void Process() override; }; - /// @brief The last job - /// + /** @brief The last job. */ class JobFinishT : public JobFenceT { private: @@ -536,6 +521,7 @@ public: std::string AbsoluteIncludePath(cm::string_view relativePath) const; template <class JOBTYPE> void CreateParseJobs(SourceFileMapT const& sourceMap); + std::string CollapseFullPathTS(std::string const& path) const; private: // -- Utility accessors @@ -572,6 +558,8 @@ private: // -- Worker thread pool std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false); cmWorkerPool WorkerPool_; + // -- Concurrent processing + mutable std::mutex CMakeLibMutex_; }; #endif diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx index e931346..1bf8ca4 100644 --- a/Source/cmQtAutoRcc.cxx +++ b/Source/cmQtAutoRcc.cxx @@ -11,12 +11,12 @@ #include "cmQtAutoGen.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cm_string_view.hxx" + +#include <cm/string_view> #include <algorithm> cmQtAutoRcc::cmQtAutoRcc() = default; - cmQtAutoRcc::~cmQtAutoRcc() = default; bool cmQtAutoRcc::Init(cmMakefile* makefile) @@ -41,8 +41,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) return cmExpandedList(InfoGetConfig(key)); }; auto LogInfoError = [this](cm::string_view msg) -> bool { - this->Log().Error(GenT::RCC, - cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg)); + this->Log().Error( + GenT::RCC, cmStrCat("In ", MessagePath(this->InfoFile()), ":\n", msg)); return false; }; @@ -56,6 +56,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG"); // - Directories + ProjectDirsRef().Source = InfoGet("ARCC_CMAKE_SOURCE_DIR"); + ProjectDirsRef().Binary = InfoGet("ARCC_CMAKE_BINARY_DIR"); AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR"); if (AutogenBuildDir_.empty()) { return LogInfoError("Build directory empty."); @@ -69,8 +71,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) // - Rcc executable RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE"); if (!RccExecutableTime_.Load(RccExecutable_)) { - return LogInfoError(cmStrCat("The rcc executable ", Quoted(RccExecutable_), - " does not exist.")); + return LogInfoError(cmStrCat( + "The rcc executable ", MessagePath(RccExecutable_), " does not exist.")); } RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS"); @@ -185,8 +187,9 @@ bool cmQtAutoRcc::SettingsFileRead() if (!cmSystemTools::FileExists(SettingsFile_, true)) { // Touch the settings file to make sure it exists if (!cmSystemTools::Touch(SettingsFile_, true)) { - Log().ErrorFile(GenT::RCC, SettingsFile_, - "Settings file creation failed."); + Log().Error(GenT::RCC, + cmStrCat("Touching the settings file ", + MessagePath(SettingsFile_), " failed.")); return false; } } @@ -196,7 +199,9 @@ bool cmQtAutoRcc::SettingsFileRead() // Make sure the lock file exists if (!cmSystemTools::FileExists(LockFile_, true)) { if (!cmSystemTools::Touch(LockFile_, true)) { - Log().ErrorFile(GenT::RCC, LockFile_, "Lock file creation failed."); + Log().Error(GenT::RCC, + cmStrCat("Touching the lock file ", MessagePath(LockFile_), + " failed.")); return false; } } @@ -204,8 +209,9 @@ bool cmQtAutoRcc::SettingsFileRead() cmFileLockResult lockResult = LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1)); if (!lockResult.IsOk()) { - Log().ErrorFile(GenT::RCC, LockFile_, - "File lock failed: " + lockResult.GetOutputMessage()); + Log().Error(GenT::RCC, + cmStrCat("Locking of the lock file ", MessagePath(LockFile_), + " failed.\n", lockResult.GetOutputMessage())); return false; } } @@ -221,8 +227,10 @@ bool cmQtAutoRcc::SettingsFileRead() if (SettingsChanged_) { std::string error; if (!FileWrite(SettingsFile_, "", &error)) { - Log().ErrorFile(GenT::RCC, SettingsFile_, - "Settings file clearing failed. " + error); + Log().Error(GenT::RCC, + cmStrCat("Clearing of the settings file ", + MessagePath(SettingsFile_), " failed.\n", + error)); return false; } } @@ -239,14 +247,16 @@ bool cmQtAutoRcc::SettingsFileWrite() // Only write if any setting changed if (SettingsChanged_) { if (Log().Verbose()) { - Log().Info(GenT::RCC, "Writing settings file " + Quoted(SettingsFile_)); + Log().Info(GenT::RCC, + "Writing settings file " + MessagePath(SettingsFile_)); } // Write settings file std::string content = cmStrCat("rcc:", SettingsString_, '\n'); std::string error; if (!FileWrite(SettingsFile_, content, &error)) { - Log().ErrorFile(GenT::RCC, SettingsFile_, - "Settings file writing failed. " + error); + Log().Error(GenT::RCC, + cmStrCat("Writing of the settings file ", + MessagePath(SettingsFile_), " failed.\n", error)); // Remove old settings file to trigger a full rebuild on the next run cmSystemTools::RemoveFile(SettingsFile_); return false; @@ -263,17 +273,18 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) { // Test if the rcc input file exists if (!QrcFileTime_.Load(QrcFile_)) { - Log().ErrorFile( - GenT::RCC, QrcFile_, - cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist")); + Log().Error(GenT::RCC, + cmStrCat("The resources file ", MessagePath(QrcFile_), + " does not exist")); return false; } // Test if the rcc output file exists if (!RccFileTime_.Load(RccFileOutput_)) { if (Log().Verbose()) { - Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), - ", because it doesn't exist, from ", Quoted(QrcFile_)); + Reason = + cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it doesn't exist, from ", MessagePath(QrcFile_)); } generate = true; return true; @@ -282,9 +293,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the settings changed if (SettingsChanged_) { if (Log().Verbose()) { - Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), ", because the rcc settings changed, from ", - Quoted(QrcFile_)); + MessagePath(QrcFile_)); } generate = true; return true; @@ -293,9 +304,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the rcc output file is older than the .qrc file if (RccFileTime_.Older(QrcFileTime_)) { if (Log().Verbose()) { - Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), - ", because it is older than ", Quoted(QrcFile_), - ", from ", Quoted(QrcFile_)); + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it is older than ", MessagePath(QrcFile_), + ", from ", MessagePath(QrcFile_)); } generate = true; return true; @@ -304,9 +315,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the rcc output file is older than the rcc executable if (RccFileTime_.Older(RccExecutableTime_)) { if (Log().Verbose()) { - Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), ", because it is older than the rcc executable, from ", - Quoted(QrcFile_)); + MessagePath(QrcFile_)); } generate = true; return true; @@ -322,7 +333,9 @@ bool cmQtAutoRcc::TestResources(bool& generate) std::string error; RccLister const lister(RccExecutable_, RccListOptions_); if (!lister.list(QrcFile_, Inputs_, error, Log().Verbose())) { - Log().ErrorFile(GenT::RCC, QrcFile_, error); + Log().Error( + GenT::RCC, + cmStrCat("Listing of ", MessagePath(QrcFile_), " failed.\n", error)); return false; } } @@ -332,17 +345,18 @@ bool cmQtAutoRcc::TestResources(bool& generate) // Check if the resource file exists cmFileTime fileTime; if (!fileTime.Load(resFile)) { - Log().ErrorFile(GenT::RCC, QrcFile_, - cmStrCat("Could not find the resource file\n ", - Quoted(resFile), '\n')); + Log().Error(GenT::RCC, + cmStrCat("The resource file ", MessagePath(resFile), + " listed in ", MessagePath(QrcFile_), + " does not exist.")); return false; } // Check if the resource file is newer than the rcc output file if (RccFileTime_.Older(fileTime)) { if (Log().Verbose()) { - Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), - ", because it is older than ", Quoted(resFile), - ", from ", Quoted(QrcFile_)); + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it is older than ", MessagePath(resFile), + ", from ", MessagePath(QrcFile_)); } generate = true; break; @@ -357,12 +371,15 @@ bool cmQtAutoRcc::TestInfoFile() if (RccFileTime_.Older(InfoFileTime())) { if (Log().Verbose()) { Log().Info(GenT::RCC, - cmStrCat("Touching ", Quoted(RccFileOutput_), - " because it is older than ", Quoted(InfoFile()))); + cmStrCat("Touching ", MessagePath(RccFileOutput_), + " because it is older than ", + MessagePath(InfoFile()))); } // Touch build file if (!cmSystemTools::Touch(RccFileOutput_, false)) { - Log().ErrorFile(GenT::RCC, RccFileOutput_, "Build file touch failed"); + Log().Error( + GenT::RCC, + cmStrCat("Touching ", MessagePath(RccFileOutput_), " failed.")); return false; } BuildFileChanged_ = true; @@ -375,8 +392,9 @@ bool cmQtAutoRcc::GenerateRcc() { // Make parent directory if (!MakeParentDirectory(RccFileOutput_)) { - Log().ErrorFile(GenT::RCC, RccFileOutput_, - "Could not create parent directory"); + Log().Error(GenT::RCC, + cmStrCat("Could not create parent directory of ", + MessagePath(RccFileOutput_))); return false; } @@ -405,8 +423,8 @@ bool cmQtAutoRcc::GenerateRcc() // rcc process failed Log().ErrorCommand(GenT::RCC, cmStrCat("The rcc process failed to compile\n ", - Quoted(QrcFile_), "\ninto\n ", - Quoted(RccFileOutput_)), + MessagePath(QrcFile_), "\ninto\n ", + MessagePath(RccFileOutput_)), cmd, rccStdOut + rccStdErr); cmSystemTools::RemoveFile(RccFileOutput_); return false; @@ -443,22 +461,29 @@ bool cmQtAutoRcc::GenerateWrapper() if (fileDiffers) { // Write new wrapper file if (Log().Verbose()) { - Log().Info(GenT::RCC, "Generating RCC wrapper file " + RccFilePublic_); + Log().Info(GenT::RCC, + cmStrCat("Generating RCC wrapper file ", + MessagePath(RccFilePublic_))); } std::string error; if (!FileWrite(RccFilePublic_, content, &error)) { - Log().ErrorFile(GenT::RCC, RccFilePublic_, - "RCC wrapper file writing failed. " + error); + Log().Error(GenT::RCC, + cmStrCat("Generating RCC wrapper file ", + MessagePath(RccFilePublic_), " failed.\n", + error)); return false; } } else if (BuildFileChanged_) { // Just touch the wrapper file if (Log().Verbose()) { - Log().Info(GenT::RCC, "Touching RCC wrapper file " + RccFilePublic_); + Log().Info( + GenT::RCC, + cmStrCat("Touching RCC wrapper file ", MessagePath(RccFilePublic_))); } if (!cmSystemTools::Touch(RccFilePublic_, false)) { - Log().ErrorFile(GenT::RCC, RccFilePublic_, - "RCC wrapper file touch failed."); + Log().Error(GenT::RCC, + cmStrCat("Touching RCC wrapper file ", + MessagePath(RccFilePublic_), " failed.")); return false; } } diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index 1f9aae8..edbb3de 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -10,9 +10,9 @@ #include "cmsys/FStream.hxx" #include <algorithm> -#include <ctype.h> +#include <cctype> +#include <cstddef> #include <iterator> -#include <stddef.h> #include <utility> cmRST::cmRST(std::ostream& os, std::string docroot) @@ -320,8 +320,7 @@ std::string cmRST::ReplaceSubstitutions(std::string const& line) std::string::size_type start = this->Substitution.start(2); std::string::size_type end = this->Substitution.end(2); std::string substitute = this->Substitution.match(3); - std::map<std::string, std::string>::iterator replace = - this->Replace.find(substitute); + auto replace = this->Replace.find(substitute); if (replace != this->Replace.end()) { std::pair<std::set<std::string>::iterator, bool> replaced = this->Replaced.insert(substitute); @@ -451,10 +450,10 @@ void cmRST::UnindentLines(std::vector<std::string>& lines) } } - std::vector<std::string>::const_iterator it = lines.begin(); + auto it = lines.cbegin(); size_t leadingEmpty = std::distance(it, cmFindNot(lines, std::string())); - std::vector<std::string>::const_reverse_iterator rit = lines.rbegin(); + auto rit = lines.crbegin(); size_t trailingEmpty = std::distance(rit, cmFindNot(cmReverseRange(lines), std::string())); @@ -464,7 +463,7 @@ void cmRST::UnindentLines(std::vector<std::string>& lines) return; } - std::vector<std::string>::iterator contentEnd = cmRotate( - lines.begin(), lines.begin() + leadingEmpty, lines.end() - trailingEmpty); + auto contentEnd = cmRotate(lines.begin(), lines.begin() + leadingEmpty, + lines.end() - trailingEmpty); lines.erase(contentEnd, lines.end()); } diff --git a/Source/cmRemoveDefinitionsCommand.cxx b/Source/cmRemoveDefinitionsCommand.cxx index 8d3f688..339ff9d 100644 --- a/Source/cmRemoveDefinitionsCommand.cxx +++ b/Source/cmRemoveDefinitionsCommand.cxx @@ -2,21 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmRemoveDefinitionsCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -// cmRemoveDefinitionsCommand -bool cmRemoveDefinitionsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmRemoveDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - // it is OK to have no arguments - if (args.empty()) { - return true; - } - + cmMakefile& mf = status.GetMakefile(); for (std::string const& i : args) { - this->Makefile->RemoveDefineFlag(i); + mf.RemoveDefineFlag(i); } return true; } diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h index 85d01d4..868416b 100644 --- a/Source/cmRemoveDefinitionsCommand.h +++ b/Source/cmRemoveDefinitionsCommand.h @@ -8,36 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmRemoveDefinitionsCommand - * \brief Specify a list of compiler defines - * - * cmRemoveDefinitionsCommand specifies a list of compiler defines. - * These defines will - * be removed from the compile command. - */ -class cmRemoveDefinitionsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmRemoveDefinitionsCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmRemoveDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index 33389ca..0a1d109 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -2,8 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmRulePlaceholderExpander.h" -#include <ctype.h> -#include <string.h> +#include <cctype> +#include <cstring> #include <utility> #include "cmOutputConverter.h" @@ -235,8 +235,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( cmOutputConverter::SHELL); } - std::map<std::string, std::string>::iterator compIt = - this->Compilers.find(variable); + auto compIt = this->Compilers.find(variable); if (compIt != this->Compilers.end()) { std::string ret = outputConverter->ConvertToOutputForExisting( @@ -292,8 +291,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( return ret; } - std::map<std::string, std::string>::iterator mapIt = - this->VariableMappings.find(variable); + auto mapIt = this->VariableMappings.find(variable); if (mapIt != this->VariableMappings.end()) { if (variable.find("_FLAG") == std::string::npos) { return outputConverter->ConvertToOutputForExisting(mapIt->second); diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx index 1b3f387..ed2e3e4 100644 --- a/Source/cmRuntimeDependencyArchive.cxx +++ b/Source/cmRuntimeDependencyArchive.cxx @@ -27,7 +27,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #if defined(_WIN32) static void AddVisualStudioPath(std::vector<std::string>& paths, diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h index eee331f..c8bb1ab 100644 --- a/Source/cmScriptGenerator.h +++ b/Source/cmScriptGenerator.h @@ -25,7 +25,7 @@ public: } cmScriptGeneratorIndent Next(int step = 2) const { - return cmScriptGeneratorIndent(this->Level + step); + return { this->Level + step }; } private: diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx index 27f45a8..52bde7c 100644 --- a/Source/cmSeparateArgumentsCommand.cxx +++ b/Source/cmSeparateArgumentsCommand.cxx @@ -3,10 +3,10 @@ #include "cmSeparateArgumentsCommand.h" #include <algorithm> -#include <sstream> #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" // cmSeparateArgumentsCommand @@ -56,9 +56,7 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, command = arg; doing = DoingNone; } else { - std::ostringstream e; - e << "given unknown argument " << arg; - status.SetError(e.str()); + status.SetError(cmStrCat("given unknown argument ", arg)); return false; } } diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index 9df1883..f150cf3 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -20,7 +20,8 @@ #include <mutex> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/shared_mutex> void on_signal(uv_signal_t* signal, int signum) { diff --git a/Source/cmServer.h b/Source/cmServer.h index ab2ad23..9b12604 100644 --- a/Source/cmServer.h +++ b/Source/cmServer.h @@ -5,11 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cm_jsoncpp_value.h" -#include "cm_thread.hxx" #include "cm_uv.h" #include "cmUVHandlePtr.h" +#include <cm/shared_mutex> + #include <memory> #include <string> #include <vector> diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 670161d..f889129 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -23,7 +23,7 @@ #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> // Get rid of some windows macros: #undef max @@ -167,7 +167,7 @@ bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/, std::pair<int, int> cmServerProtocol1::ProtocolVersion() const { - return std::make_pair(1, 2); + return { 1, 2 }; } static void setErrorMessage(std::string* errorMessage, const std::string& text) diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 7e3a340..112d832 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -100,11 +100,10 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args, } else if (scopeName == "INSTALL") { scope = cmProperty::INSTALL; } else { - std::ostringstream e; - e << "given invalid scope " << scopeName << ". " - << "Valid scopes are GLOBAL, DIRECTORY, " - "TARGET, SOURCE, TEST, CACHE, INSTALL."; - status.SetError(e.str()); + status.SetError(cmStrCat("given invalid scope ", scopeName, + ". " + "Valid scopes are GLOBAL, DIRECTORY, " + "TARGET, SOURCE, TEST, CACHE, INSTALL.")); return false; } @@ -149,9 +148,7 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args, propertyValue += arg; remove = false; } else { - std::ostringstream e; - e << "given invalid argument \"" << arg << "\"."; - status.SetError(e.str()); + status.SetError(cmStrCat("given invalid argument \"", arg, "\".")); return false; } } @@ -293,10 +290,8 @@ bool HandleTargetMode(cmExecutionStatus& status, return false; } } else { - std::ostringstream e; - e << "could not find TARGET " << name - << ". Perhaps it has not yet been created."; - status.SetError(e.str()); + status.SetError(cmStrCat("could not find TARGET ", name, + ". Perhaps it has not yet been created.")); return false; } } @@ -340,9 +335,8 @@ bool HandleSourceMode(cmExecutionStatus& status, return false; } } else { - std::ostringstream e; - e << "given SOURCE name that could not be found or created: " << name; - status.SetError(e.str()); + status.SetError(cmStrCat( + "given SOURCE name that could not be found or created: ", name)); return false; } } @@ -375,8 +369,7 @@ bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, { // Look for tests with all names given. std::set<std::string>::iterator next; - for (std::set<std::string>::iterator ni = names.begin(); ni != names.end(); - ni = next) { + for (auto ni = names.begin(); ni != names.end(); ni = next) { next = ni; ++next; if (cmTest* test = status.GetMakefile().GetTest(*ni)) { @@ -429,26 +422,23 @@ bool HandleCacheMode(cmExecutionStatus& status, { if (propertyName == "ADVANCED") { if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) { - std::ostringstream e; - e << "given non-boolean value \"" << propertyValue - << R"(" for CACHE property "ADVANCED". )"; - status.SetError(e.str()); + status.SetError(cmStrCat("given non-boolean value \"", propertyValue, + R"(" for CACHE property "ADVANCED". )")); return false; } } else if (propertyName == "TYPE") { if (!cmState::IsCacheEntryType(propertyValue)) { - std::ostringstream e; - e << "given invalid CACHE entry TYPE \"" << propertyValue << "\""; - status.SetError(e.str()); + status.SetError( + cmStrCat("given invalid CACHE entry TYPE \"", propertyValue, "\"")); return false; } } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" && propertyName != "VALUE") { - std::ostringstream e; - e << "given invalid CACHE property " << propertyName << ". " - << "Settable CACHE properties are: " - << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE."; - status.SetError(e.str()); + status.SetError( + cmStrCat("given invalid CACHE property ", propertyName, + ". " + "Settable CACHE properties are: " + "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.")); return false; } @@ -463,10 +453,8 @@ bool HandleCacheMode(cmExecutionStatus& status, return false; } } else { - std::ostringstream e; - e << "could not find CACHE variable " << name - << ". Perhaps it has not yet been created."; - status.SetError(e.str()); + status.SetError(cmStrCat("could not find CACHE variable ", name, + ". Perhaps it has not yet been created.")); return false; } } @@ -512,9 +500,8 @@ bool HandleInstallMode(cmExecutionStatus& status, return false; } } else { - std::ostringstream e; - e << "given INSTALL name that could not be found or created: " << name; - status.SetError(e.str()); + status.SetError(cmStrCat( + "given INSTALL name that could not be found or created: ", name)); return false; } } diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx index 8e3217f..7ff604b 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.cxx +++ b/Source/cmSetSourceFilesPropertiesCommand.cxx @@ -2,18 +2,23 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSetSourceFilesPropertiesCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" -class cmExecutionStatus; +static bool RunCommand(cmMakefile* mf, + std::vector<std::string>::const_iterator filebeg, + std::vector<std::string>::const_iterator fileend, + std::vector<std::string>::const_iterator propbeg, + std::vector<std::string>::const_iterator propend, + std::string& errors); -// cmSetSourceFilesPropertiesCommand -bool cmSetSourceFilesPropertiesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmSetSourceFilesPropertiesCommand(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; } @@ -29,22 +34,24 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass( ++j; } + cmMakefile& mf = status.GetMakefile(); + // now call the worker function std::string errors; - bool ret = cmSetSourceFilesPropertiesCommand::RunCommand( - this->Makefile, args.begin(), args.begin() + numFiles, - args.begin() + numFiles, args.end(), errors); + bool ret = RunCommand(&mf, args.begin(), args.begin() + numFiles, + args.begin() + numFiles, args.end(), errors); if (!ret) { - this->SetError(errors); + status.SetError(errors); } return ret; } -bool cmSetSourceFilesPropertiesCommand::RunCommand( - cmMakefile* mf, std::vector<std::string>::const_iterator filebeg, - std::vector<std::string>::const_iterator fileend, - std::vector<std::string>::const_iterator propbeg, - std::vector<std::string>::const_iterator propend, std::string& errors) +static bool RunCommand(cmMakefile* mf, + std::vector<std::string>::const_iterator filebeg, + std::vector<std::string>::const_iterator fileend, + std::vector<std::string>::const_iterator propbeg, + std::vector<std::string>::const_iterator propend, + std::string& errors) { std::vector<std::string> propertyPairs; bool generated = false; diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h index 6fd6c41..5eef785 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.h +++ b/Source/cmSetSourceFilesPropertiesCommand.h @@ -8,34 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmMakefile; - -class cmSetSourceFilesPropertiesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetSourceFilesPropertiesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - static bool RunCommand(cmMakefile* mf, - std::vector<std::string>::const_iterator filebeg, - std::vector<std::string>::const_iterator fileend, - std::vector<std::string>::const_iterator propbeg, - std::vector<std::string>::const_iterator propend, - std::string& errors); -}; +bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index b4360e4..8d917db 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -5,31 +5,32 @@ #include <iterator> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" -class cmExecutionStatus; +static bool SetOneTarget(const std::string& tname, + std::vector<std::string>& propertyPairs, + cmMakefile* mf); -// cmSetTargetPropertiesCommand -bool cmSetTargetPropertiesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmSetTargetPropertiesCommand(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; } // first collect up the list of files std::vector<std::string> propertyPairs; int numFiles = 0; - std::vector<std::string>::const_iterator j; - for (j = args.begin(); j != args.end(); ++j) { + for (auto j = args.begin(); j != args.end(); ++j) { if (*j == "PROPERTIES") { // now loop through the rest of the arguments, new style ++j; if (std::distance(j, args.end()) % 2 != 0) { - this->SetError("called with incorrect number of arguments."); + status.SetError("called with incorrect number of arguments."); return false; } cmAppend(propertyPairs, j, args.end()); @@ -38,33 +39,32 @@ bool cmSetTargetPropertiesCommand::InitialPass( numFiles++; } if (propertyPairs.empty()) { - this->SetError("called with illegal arguments, maybe missing " - "a PROPERTIES specifier?"); + status.SetError("called with illegal arguments, maybe missing " + "a PROPERTIES specifier?"); return false; } + cmMakefile& mf = status.GetMakefile(); + // now loop over all the targets - int i; - for (i = 0; i < numFiles; ++i) { - if (this->Makefile->IsAlias(args[i])) { - this->SetError("can not be used on an ALIAS target."); + for (int i = 0; i < numFiles; ++i) { + if (mf.IsAlias(args[i])) { + status.SetError("can not be used on an ALIAS target."); return false; } - bool ret = cmSetTargetPropertiesCommand::SetOneTarget( - args[i], propertyPairs, this->Makefile); + bool ret = SetOneTarget(args[i], propertyPairs, &mf); if (!ret) { - std::string message = - cmStrCat("Can not find target to add properties to: ", args[i]); - this->SetError(message); + status.SetError( + cmStrCat("Can not find target to add properties to: ", args[i])); return false; } } return true; } -bool cmSetTargetPropertiesCommand::SetOneTarget( - const std::string& tname, std::vector<std::string>& propertyPairs, - cmMakefile* mf) +static bool SetOneTarget(const std::string& tname, + std::vector<std::string>& propertyPairs, + cmMakefile* mf) { if (cmTarget* target = mf->FindTargetToUse(tname)) { // now loop through all the props and set them diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index 7e4606e..9d40c74 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -8,34 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmMakefile; - -class cmSetTargetPropertiesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetTargetPropertiesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - /** - * Used by this command and cmSetPropertiesCommand - */ - static bool SetOneTarget(const std::string& tname, - std::vector<std::string>& propertyPairs, - cmMakefile* mf); -}; +bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index ed909c6..de61eda 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -5,21 +5,25 @@ #include <iterator> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmTest.h" -class cmExecutionStatus; +static bool SetOneTest(const std::string& tname, + std::vector<std::string>& propertyPairs, cmMakefile* mf, + std::string& errors); -// cmSetTestsPropertiesCommand -bool cmSetTestsPropertiesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmSetTestsPropertiesCommand(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; } + cmMakefile& mf = status.GetMakefile(); + // first collect up the list of files std::vector<std::string> propertyPairs; int numFiles = 0; @@ -29,7 +33,7 @@ bool cmSetTestsPropertiesCommand::InitialPass( // now loop through the rest of the arguments, new style ++j; if (std::distance(j, args.end()) % 2 != 0) { - this->SetError("called with incorrect number of arguments."); + status.SetError("called with incorrect number of arguments."); return false; } cmAppend(propertyPairs, j, args.end()); @@ -38,8 +42,8 @@ bool cmSetTestsPropertiesCommand::InitialPass( numFiles++; } if (propertyPairs.empty()) { - this->SetError("called with illegal arguments, maybe " - "missing a PROPERTIES specifier?"); + status.SetError("called with illegal arguments, maybe " + "missing a PROPERTIES specifier?"); return false; } @@ -47,10 +51,9 @@ bool cmSetTestsPropertiesCommand::InitialPass( int i; for (i = 0; i < numFiles; ++i) { std::string errors; - bool ret = cmSetTestsPropertiesCommand::SetOneTest(args[i], propertyPairs, - this->Makefile, errors); + bool ret = SetOneTest(args[i], propertyPairs, &mf, errors); if (!ret) { - this->SetError(errors); + status.SetError(errors); return ret; } } @@ -58,9 +61,9 @@ bool cmSetTestsPropertiesCommand::InitialPass( return true; } -bool cmSetTestsPropertiesCommand::SetOneTest( - const std::string& tname, std::vector<std::string>& propertyPairs, - cmMakefile* mf, std::string& errors) +static bool SetOneTest(const std::string& tname, + std::vector<std::string>& propertyPairs, cmMakefile* mf, + std::string& errors) { if (cmTest* test = mf->GetTest(tname)) { // now loop through all the props and set them diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h index d73e95a..4b75464 100644 --- a/Source/cmSetTestsPropertiesCommand.h +++ b/Source/cmSetTestsPropertiesCommand.h @@ -8,31 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmMakefile; - -class cmSetTestsPropertiesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetTestsPropertiesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - static bool SetOneTest(const std::string& tname, - std::vector<std::string>& propertyPairs, - cmMakefile* mf, std::string& errors); -}; +bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 4deb94a..bd68d04 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -5,7 +5,6 @@ #include <array> #include <utility> -#include "cmCustomCommand.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -21,11 +20,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name, { } -cmSourceFile::~cmSourceFile() -{ - this->SetCustomCommand(nullptr); -} - std::string const& cmSourceFile::GetExtension() const { return this->Extension; @@ -320,19 +314,19 @@ bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const return cmIsOn(this->GetProperty(prop)); } -cmCustomCommand* cmSourceFile::GetCustomCommand() +void cmSourceFile::SetProperties(cmPropertyMap properties) { - return this->CustomCommand; + this->Properties = std::move(properties); + + this->IsGenerated = this->GetPropertyAsBool(propGENERATED); } -cmCustomCommand const* cmSourceFile::GetCustomCommand() const +cmCustomCommand* cmSourceFile::GetCustomCommand() const { - return this->CustomCommand; + return this->CustomCommand.get(); } -void cmSourceFile::SetCustomCommand(cmCustomCommand* cc) +void cmSourceFile::SetCustomCommand(std::unique_ptr<cmCustomCommand> cc) { - cmCustomCommand* old = this->CustomCommand; - this->CustomCommand = cc; - delete old; + this->CustomCommand = std::move(cc); } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 774cb28..3b18fdb 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -5,14 +5,15 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmCustomCommand.h" #include "cmPropertyMap.h" #include "cmSourceFileLocation.h" #include "cmSourceFileLocationKind.h" +#include <memory> #include <string> #include <vector> -class cmCustomCommand; class cmMakefile; /** \class cmSourceFile @@ -32,17 +33,11 @@ public: cmMakefile* mf, const std::string& name, cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous); - ~cmSourceFile(); - - cmSourceFile(const cmSourceFile&) = delete; - cmSourceFile& operator=(const cmSourceFile&) = delete; - /** - * Get the list of the custom commands for this source file + * Get the custom command for this source file */ - cmCustomCommand* GetCustomCommand(); - cmCustomCommand const* GetCustomCommand() const; - void SetCustomCommand(cmCustomCommand* cc); + cmCustomCommand* GetCustomCommand() const; + void SetCustomCommand(std::unique_ptr<cmCustomCommand> cc); //! Set/Get a property of this source file void SetProperty(const std::string& prop, const char* value); @@ -99,8 +94,9 @@ public: void AddDepend(const std::string& d) { this->Depends.push_back(d); } // Get the properties - cmPropertyMap& GetProperties() { return this->Properties; } const cmPropertyMap& GetProperties() const { return this->Properties; } + // Set the properties + void SetProperties(cmPropertyMap properties); /** * Check whether the given source file location could refer to this @@ -114,7 +110,7 @@ public: private: cmSourceFileLocation Location; cmPropertyMap Properties; - cmCustomCommand* CustomCommand = nullptr; + std::unique_ptr<cmCustomCommand> CustomCommand; std::string Extension; std::string Language; std::string FullPath; @@ -140,6 +136,8 @@ private: "hpj" \ "|bat)$" +#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$" + #define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$" #endif diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index 0e8d09d..bd75c14 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -9,7 +9,7 @@ #include "cmSystemTools.h" #include "cmake.h" -#include <assert.h> +#include <cassert> cmSourceFileLocation::cmSourceFileLocation() = default; diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 399f1da..3a13e57 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -2,17 +2,23 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSourceGroupCommand.h" +#include <cstddef> +#include <map> #include <set> -#include <stddef.h> #include <utility> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSourceGroup.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" namespace { + +using ParsedArguments = std::map<std::string, std::vector<std::string>>; +using ExpectedOptions = std::vector<std::string>; + const std::string kTreeOptionName = "TREE"; const std::string kPrefixOptionName = "PREFIX"; const std::string kFilesOptionName = "FILES"; @@ -117,13 +123,8 @@ bool addFilesToItsSourceGroups(const std::string& root, return true; } -} -class cmExecutionStatus; - -// cmSourceGroupCommand -cmSourceGroupCommand::ExpectedOptions -cmSourceGroupCommand::getExpectedOptions() const +ExpectedOptions getExpectedOptions() { ExpectedOptions options; @@ -135,15 +136,14 @@ cmSourceGroupCommand::getExpectedOptions() const return options; } -bool cmSourceGroupCommand::isExpectedOption( - const std::string& argument, const ExpectedOptions& expectedOptions) +bool isExpectedOption(const std::string& argument, + const ExpectedOptions& expectedOptions) { return cmContains(expectedOptions, argument); } -void cmSourceGroupCommand::parseArguments( - const std::vector<std::string>& args, - cmSourceGroupCommand::ParsedArguments& parsedArguments) +void parseArguments(const std::vector<std::string>& args, + ParsedArguments& parsedArguments) { const ExpectedOptions expectedOptions = getExpectedOptions(); size_t i = 0; @@ -172,21 +172,35 @@ void cmSourceGroupCommand::parseArguments( } } -bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +} // namespace + +static bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, + std::string& errorMsg); + +static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments, + std::string& errorMsg); + +static bool checkSingleParameterArgumentPreconditions( + const std::string& argument, const ParsedArguments& parsedArguments, + std::string& errorMsg); + +bool cmSourceGroupCommand(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; } + cmMakefile& mf = status.GetMakefile(); + // If only two arguments are given, the pre-1.8 version of the // command is being invoked. if (args.size() == 2 && args[1] != "FILES") { - cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); + cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]); if (!sg) { - this->SetError("Could not create or find source group"); + status.SetError("Could not create or find source group"); return false; } @@ -204,21 +218,21 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, } if (parsedArguments.find(kTreeOptionName) != parsedArguments.end()) { - if (!processTree(parsedArguments, errorMsg)) { - this->SetError(errorMsg); + if (!processTree(mf, parsedArguments, errorMsg)) { + status.SetError(errorMsg); return false; } } else { if (parsedArguments.find(kSourceGroupOptionName) == parsedArguments.end()) { - this->SetError("Missing source group name."); + status.SetError("Missing source group name."); return false; } - cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); + cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]); if (!sg) { - this->SetError("Could not create or find source group"); + status.SetError("Could not create or find source group"); return false; } @@ -234,8 +248,7 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, for (auto const& filesArg : filesArguments) { std::string src = filesArg; if (!cmSystemTools::FileIsFullPath(src)) { - src = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', filesArg); + src = cmStrCat(mf.GetCurrentSourceDirectory(), '/', filesArg); } src = cmSystemTools::CollapseFullPath(src); sg->AddGroupFile(src); @@ -245,8 +258,8 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, return true; } -bool cmSourceGroupCommand::checkArgumentsPreconditions( - const ParsedArguments& parsedArguments, std::string& errorMsg) const +static bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, + std::string& errorMsg) { return checkSingleParameterArgumentPreconditions( kPrefixOptionName, parsedArguments, errorMsg) && @@ -256,8 +269,8 @@ bool cmSourceGroupCommand::checkArgumentsPreconditions( parsedArguments, errorMsg); } -bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, - std::string& errorMsg) +static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments, + std::string& errorMsg) { const std::string root = cmSystemTools::CollapseFullPath(parsedArguments[kTreeOptionName].front()); @@ -265,9 +278,8 @@ bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, ? "" : parsedArguments[kPrefixOptionName].front(); - const std::vector<std::string> filesVector = - prepareFilesPathsForTree(parsedArguments[kFilesOptionName], - this->Makefile->GetCurrentSourceDirectory()); + const std::vector<std::string> filesVector = prepareFilesPathsForTree( + parsedArguments[kFilesOptionName], mf.GetCurrentSourceDirectory()); if (!rootIsPrefix(root, filesVector, errorMsg)) { return false; @@ -276,16 +288,15 @@ bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, std::set<std::string> sourceGroupPaths = getSourceGroupFilesPaths(root, filesVector); - return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix, - *(this->Makefile), errorMsg); + return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix, mf, + errorMsg); } -bool cmSourceGroupCommand::checkSingleParameterArgumentPreconditions( +static bool checkSingleParameterArgumentPreconditions( const std::string& argument, const ParsedArguments& parsedArguments, - std::string& errorMsg) const + std::string& errorMsg) { - ParsedArguments::const_iterator foundArgument = - parsedArguments.find(argument); + auto foundArgument = parsedArguments.find(argument); if (foundArgument != parsedArguments.end()) { const std::vector<std::string>& optionArguments = foundArgument->second; diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index 87a6114..ad39701 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -5,59 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <map> #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmSourceGroupCommand - * \brief Adds a cmSourceGroup to the cmMakefile. - * - * cmSourceGroupCommand is used to define cmSourceGroups which split up - * source files in to named, organized groups in the generated makefiles. - */ -class cmSourceGroupCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSourceGroupCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - using ParsedArguments = std::map<std::string, std::vector<std::string>>; - using ExpectedOptions = std::vector<std::string>; - - ExpectedOptions getExpectedOptions() const; - - bool isExpectedOption(const std::string& argument, - const ExpectedOptions& expectedOptions); - - void parseArguments(const std::vector<std::string>& args, - cmSourceGroupCommand::ParsedArguments& parsedArguments); - - bool processTree(ParsedArguments& parsedArguments, std::string& errorMsg); - - bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, - std::string& errorMsg) const; - bool checkSingleParameterArgumentPreconditions( - const std::string& argument, const ParsedArguments& parsedArguments, - std::string& errorMsg) const; -}; +bool cmSourceGroupCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 902287c..6de312c 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -4,12 +4,12 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> -#include <stdlib.h> -#include <string.h> +#include <cassert> +#include <cstdlib> +#include <cstring> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCacheManager.h" #include "cmCommand.h" @@ -324,7 +324,7 @@ cmStateSnapshot cmState::Reset() this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true); this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true); - return cmStateSnapshot(this, pos); + return { this, pos }; } void cmState::DefineProperty(const std::string& name, @@ -350,8 +350,7 @@ cmPropertyDefinition const* cmState::GetPropertyDefinition( bool cmState::IsPropertyDefined(const std::string& name, cmProperty::ScopeType scope) const { - std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it = - this->PropertyDefinitions.find(scope); + auto it = this->PropertyDefinitions.find(scope); if (it == this->PropertyDefinitions.end()) { return false; } @@ -361,8 +360,7 @@ bool cmState::IsPropertyDefined(const std::string& name, bool cmState::IsPropertyChained(const std::string& name, cmProperty::ScopeType scope) const { - std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it = - this->PropertyDefinitions.find(scope); + auto it = this->PropertyDefinitions.find(scope); if (it == this->PropertyDefinitions.end()) { return false; } @@ -371,8 +369,8 @@ bool cmState::IsPropertyChained(const std::string& name, void cmState::SetLanguageEnabled(std::string const& l) { - std::vector<std::string>::iterator it = std::lower_bound( - this->EnabledLanguages.begin(), this->EnabledLanguages.end(), l); + auto it = std::lower_bound(this->EnabledLanguages.begin(), + this->EnabledLanguages.end(), l); if (it == this->EnabledLanguages.end() || *it != l) { this->EnabledLanguages.insert(it, l); } @@ -505,7 +503,7 @@ void cmState::AddScriptedCommand(std::string const& name, Command command) std::string sName = cmSystemTools::LowerCase(name); // if the command already exists, give a new name to the old command. - if (Command oldCmd = this->GetCommand(sName)) { + if (Command oldCmd = this->GetCommandByExactName(sName)) { this->ScriptedCommands["_" + sName] = oldCmd; } @@ -789,7 +787,7 @@ cmStateSnapshot cmState::CreateBaseSnapshot() assert(pos->Vars.IsValid()); pos->Parent = this->VarTree.Root(); pos->Root = this->VarTree.Root(); - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot( @@ -842,7 +840,7 @@ cmStateSnapshot cmState::CreateFunctionCallSnapshot( cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars; pos->Parent = origin; pos->Vars = this->VarTree.Push(origin); - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateMacroCallSnapshot( @@ -857,7 +855,7 @@ cmStateSnapshot cmState::CreateMacroCallSnapshot( assert(originSnapshot.Position->Vars.IsValid()); pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateIncludeFileSnapshot( @@ -872,7 +870,7 @@ cmStateSnapshot cmState::CreateIncludeFileSnapshot( assert(originSnapshot.Position->Vars.IsValid()); pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateVariableScopeSnapshot( @@ -890,7 +888,7 @@ cmStateSnapshot cmState::CreateVariableScopeSnapshot( pos->Parent = origin; pos->Vars = this->VarTree.Push(origin); assert(pos->Vars.IsValid()); - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateInlineListFileSnapshot( @@ -904,7 +902,7 @@ cmStateSnapshot cmState::CreateInlineListFileSnapshot( originSnapshot.Position->ExecutionListFile, fileName); pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreatePolicyScopeSnapshot( @@ -916,7 +914,7 @@ cmStateSnapshot cmState::CreatePolicyScopeSnapshot( pos->Keep = false; pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot) @@ -948,7 +946,7 @@ cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot) this->SnapshotData.Pop(pos); } - return cmStateSnapshot(this, prevPos); + return { this, prevPos }; } static bool ParseEntryWithoutType(const std::string& entry, std::string& var, diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index df96bd3..1262f53 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -4,10 +4,11 @@ #include "cmStateDirectory.h" #include <algorithm> -#include <assert.h> -#include <iterator> +#include <cassert> #include <vector> +#include <cm/iterator> + #include "cmAlgorithms.h" #include "cmProperty.h" #include "cmPropertyMap.h" @@ -175,11 +176,9 @@ cmStateDirectory::cmStateDirectory( template <typename T, typename U> cmStringRange GetPropertyContent(T const& content, U contentEndPosition) { - std::vector<std::string>::const_iterator end = - content.begin() + contentEndPosition; + auto end = content.begin() + contentEndPosition; - std::vector<std::string>::const_reverse_iterator rbegin = - cmMakeReverseIterator(end); + auto rbegin = cm::make_reverse_iterator(end); rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); return cmMakeRange(rbegin.base(), end); @@ -189,17 +188,14 @@ template <typename T, typename U, typename V> cmBacktraceRange GetPropertyBacktraces(T const& content, U const& backtraces, V contentEndPosition) { - std::vector<std::string>::const_iterator entryEnd = - content.begin() + contentEndPosition; + auto entryEnd = content.begin() + contentEndPosition; - std::vector<std::string>::const_reverse_iterator rbegin = - cmMakeReverseIterator(entryEnd); + auto rbegin = cm::make_reverse_iterator(entryEnd); rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); - std::vector<cmListFileBacktrace>::const_iterator it = - backtraces.begin() + std::distance(content.begin(), rbegin.base()); + auto it = backtraces.begin() + std::distance(content.begin(), rbegin.base()); - std::vector<cmListFileBacktrace>::const_iterator end = backtraces.end(); + auto end = backtraces.end(); return cmMakeRange(it, end); } @@ -271,22 +267,17 @@ void cmStateDirectory::AppendIncludeDirectoriesEntry( void cmStateDirectory::PrependIncludeDirectoriesEntry( const std::string& vec, const cmListFileBacktrace& lfbt) { - std::vector<std::string>::iterator entryEnd = - this->DirectoryState->IncludeDirectories.begin() + + auto entryEnd = this->DirectoryState->IncludeDirectories.begin() + this->Snapshot_.Position->IncludeDirectoryPosition; - std::vector<std::string>::reverse_iterator rend = - this->DirectoryState->IncludeDirectories.rend(); - std::vector<std::string>::reverse_iterator rbegin = - cmMakeReverseIterator(entryEnd); + auto rend = this->DirectoryState->IncludeDirectories.rend(); + auto rbegin = cm::make_reverse_iterator(entryEnd); rbegin = std::find(rbegin, rend, cmPropertySentinal); - std::vector<std::string>::iterator entryIt = rbegin.base(); - std::vector<std::string>::iterator entryBegin = - this->DirectoryState->IncludeDirectories.begin(); + auto entryIt = rbegin.base(); + auto entryBegin = this->DirectoryState->IncludeDirectories.begin(); - std::vector<cmListFileBacktrace>::iterator btIt = - this->DirectoryState->IncludeDirectoryBacktraces.begin() + + auto btIt = this->DirectoryState->IncludeDirectoryBacktraces.begin() + std::distance(entryBegin, entryIt); this->DirectoryState->IncludeDirectories.insert(entryIt, vec); @@ -446,22 +437,17 @@ void cmStateDirectory::AppendLinkDirectoriesEntry( void cmStateDirectory::PrependLinkDirectoriesEntry( const std::string& vec, const cmListFileBacktrace& lfbt) { - std::vector<std::string>::iterator entryEnd = - this->DirectoryState->LinkDirectories.begin() + + auto entryEnd = this->DirectoryState->LinkDirectories.begin() + this->Snapshot_.Position->LinkDirectoriesPosition; - std::vector<std::string>::reverse_iterator rend = - this->DirectoryState->LinkDirectories.rend(); - std::vector<std::string>::reverse_iterator rbegin = - cmMakeReverseIterator(entryEnd); + auto rend = this->DirectoryState->LinkDirectories.rend(); + auto rbegin = cm::make_reverse_iterator(entryEnd); rbegin = std::find(rbegin, rend, cmPropertySentinal); - std::vector<std::string>::iterator entryIt = rbegin.base(); - std::vector<std::string>::iterator entryBegin = - this->DirectoryState->LinkDirectories.begin(); + auto entryIt = rbegin.base(); + auto entryBegin = this->DirectoryState->LinkDirectories.begin(); - std::vector<cmListFileBacktrace>::iterator btIt = - this->DirectoryState->LinkDirectoriesBacktraces.begin() + + auto btIt = this->DirectoryState->LinkDirectoriesBacktraces.begin() + std::distance(entryBegin, entryIt); this->DirectoryState->LinkDirectories.insert(entryIt, vec); diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx index 121923d..645907c 100644 --- a/Source/cmStateSnapshot.cxx +++ b/Source/cmStateSnapshot.cxx @@ -4,11 +4,11 @@ #include "cmStateSnapshot.h" #include <algorithm> -#include <assert.h> -#include <iterator> +#include <cassert> #include <string> -#include "cmAlgorithms.h" +#include <cm/iterator> + #include "cmDefinitions.h" #include "cmListFileCache.h" #include "cmPropertyMap.h" @@ -66,8 +66,7 @@ bool cmStateSnapshot::IsValid() const cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectory() const { - return cmStateSnapshot(this->State, - this->Position->BuildSystemDirectory->DirectoryEnd); + return { this->State, this->Position->BuildSystemDirectory->DirectoryEnd }; } cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectoryParent() const @@ -126,7 +125,7 @@ cmStateSnapshot cmStateSnapshot::GetCallStackBottom() const pos != this->State->SnapshotData.Root()) { ++pos; } - return cmStateSnapshot(this->State, pos); + return { this->State, pos }; } void cmStateSnapshot::PushPolicy(cmPolicies::PolicyMap const& entry, bool weak) @@ -277,22 +276,18 @@ void InitializeContentFromParent(T& parentContent, T& thisContent, U& parentBacktraces, U& thisBacktraces, V& contentEndPosition) { - std::vector<std::string>::const_iterator parentBegin = parentContent.begin(); - std::vector<std::string>::const_iterator parentEnd = parentContent.end(); + auto parentBegin = parentContent.begin(); + auto parentEnd = parentContent.end(); - std::vector<std::string>::const_reverse_iterator parentRbegin = - cmMakeReverseIterator(parentEnd); - std::vector<std::string>::const_reverse_iterator parentRend = - parentContent.rend(); + auto parentRbegin = cm::make_reverse_iterator(parentEnd); + auto parentRend = parentContent.rend(); parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal); - std::vector<std::string>::const_iterator parentIt = parentRbegin.base(); + auto parentIt = parentRbegin.base(); thisContent = std::vector<std::string>(parentIt, parentEnd); - std::vector<cmListFileBacktrace>::const_iterator btIt = - parentBacktraces.begin() + std::distance(parentBegin, parentIt); - std::vector<cmListFileBacktrace>::const_iterator btEnd = - parentBacktraces.end(); + auto btIt = parentBacktraces.begin() + std::distance(parentBegin, parentIt); + auto btEnd = parentBacktraces.end(); thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd); @@ -426,7 +421,7 @@ cmState* cmStateSnapshot::GetState() const cmStateDirectory cmStateSnapshot::GetDirectory() const { - return cmStateDirectory(this->Position->BuildSystemDirectory, *this); + return { this->Position->BuildSystemDirectory, *this }; } void cmStateSnapshot::SetProjectName(const std::string& name) diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h index da39127..021fd53 100644 --- a/Source/cmStateSnapshot.h +++ b/Source/cmStateSnapshot.h @@ -9,7 +9,7 @@ #include <string> #include <vector> -#include "cm_string_view.hxx" +#include <cm/string_view> #include "cmLinkedTree.h" #include "cmPolicies.h" diff --git a/Source/cmString.hxx b/Source/cmString.hxx index a401ad1..6223b78 100644 --- a/Source/cmString.hxx +++ b/Source/cmString.hxx @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" +#include <cm/string_view> #include <algorithm> #include <cstddef> diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index 131a01e..bb6dcd7 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx @@ -3,10 +3,10 @@ #include "cmStringAlgorithms.h" #include <algorithm> +#include <cerrno> #include <cstddef> #include <cstdio> -#include <errno.h> -#include <stdlib.h> +#include <cstdlib> std::string cmTrimWhitespace(cm::string_view str) { diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h index 7f442d8..6631e98 100644 --- a/Source/cmStringAlgorithms.h +++ b/Source/cmStringAlgorithms.h @@ -6,11 +6,13 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmRange.h" -#include "cm_string_view.hxx" + +#include <cm/string_view> + #include <cctype> +#include <cstring> #include <initializer_list> #include <sstream> -#include <string.h> #include <string> #include <utility> #include <vector> diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 9a2de9d..28616c2 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -6,16 +6,15 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <ctype.h> -#include <iterator> +#include <cctype> +#include <cstdio> +#include <cstdlib> #include <memory> -#include <sstream> -#include <stdio.h> -#include <stdlib.h> + +#include <cm/iterator> #include "cm_static_string_view.hxx" -#include "cmAlgorithms.h" #include "cmCryptoHash.h" #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" @@ -46,9 +45,8 @@ bool HandleHashCommand(std::vector<std::string> const& args, { #if !defined(CMAKE_BOOTSTRAP) if (args.size() != 3) { - std::ostringstream e; - e << args[0] << " requires an output variable and an input string"; - status.SetError(e.str()); + status.SetError( + cmStrCat(args[0], " requires an output variable and an input string")); return false; } @@ -60,9 +58,7 @@ bool HandleHashCommand(std::vector<std::string> const& args, } return false; #else - std::ostringstream e; - e << args[0] << " not available during bootstrap"; - status.SetError(e.str().c_str()); + status.SetError(cmStrCat(args[0], " not available during bootstrap")); return false; #endif } @@ -148,9 +144,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args, } else if (args[i] == "ESCAPE_QUOTES") { escapeQuotes = true; } else { - std::ostringstream err; - err << "Unrecognized argument \"" << args[i] << "\""; - status.SetError(err.str()); + status.SetError(cmStrCat("Unrecognized argument \"", args[i], "\"")); return false; } } @@ -377,9 +371,7 @@ bool HandleFindCommand(std::vector<std::string> const& args, pos = sstring.rfind(schar); } if (std::string::npos != pos) { - std::ostringstream s; - s << pos; - status.GetMakefile().AddDefinition(outvar, s.str()); + status.GetMakefile().AddDefinition(outvar, std::to_string(pos)); return true; } @@ -474,16 +466,12 @@ bool HandleSubstringCommand(std::vector<std::string> const& args, size_t stringLength = stringValue.size(); int intStringLength = static_cast<int>(stringLength); if (begin < 0 || begin > intStringLength) { - std::ostringstream ostr; - ostr << "begin index: " << begin << " is out of range 0 - " - << stringLength; - status.SetError(ostr.str()); + status.SetError( + cmStrCat("begin index: ", begin, " is out of range 0 - ", stringLength)); return false; } if (end < -1) { - std::ostringstream ostr; - ostr << "end index: " << end << " should be -1 or greater"; - status.SetError(ostr.str()); + status.SetError(cmStrCat("end index: ", end, " should be -1 or greater")); return false; } @@ -915,9 +903,7 @@ bool HandleUuidCommand(std::vector<std::string> const& args, status.GetMakefile().AddDefinition(outputVariable, uuid); return true; #else - std::ostringstream e; - e << args[0] << " not available during bootstrap"; - status.SetError(e.str().c_str()); + status.SetError(cmStrCat(args[0], " not available during bootstrap")); return false; #endif } diff --git a/Source/cmSubcommandTable.h b/Source/cmSubcommandTable.h index 21342bb..6e39a1f 100644 --- a/Source/cmSubcommandTable.h +++ b/Source/cmSubcommandTable.h @@ -6,7 +6,8 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" + +#include <cm/string_view> #include <initializer_list> #include <string> diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx index 07f8efe..2477d7a 100644 --- a/Source/cmSubdirCommand.cxx +++ b/Source/cmSubdirCommand.cxx @@ -2,22 +2,21 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSubdirCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -// cmSubdirCommand -bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmSubdirCommand(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; } bool res = true; bool excludeFromAll = false; + cmMakefile& mf = status.GetMakefile(); for (std::string const& i : args) { if (i == "EXCLUDE_FROM_ALL") { @@ -30,24 +29,21 @@ bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args, } // if they specified a relative path then compute the full - std::string srcPath = - this->Makefile->GetCurrentSourceDirectory() + "/" + i; + std::string srcPath = mf.GetCurrentSourceDirectory() + "/" + i; if (cmSystemTools::FileIsDirectory(srcPath)) { - std::string binPath = - this->Makefile->GetCurrentBinaryDirectory() + "/" + i; - this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, false); + std::string binPath = mf.GetCurrentBinaryDirectory() + "/" + i; + mf.AddSubDirectory(srcPath, binPath, excludeFromAll, false); } // otherwise it is a full path else if (cmSystemTools::FileIsDirectory(i)) { // we must compute the binPath from the srcPath, we just take the last // element from the source path and use that - std::string binPath = this->Makefile->GetCurrentBinaryDirectory() + "/" + + std::string binPath = mf.GetCurrentBinaryDirectory() + "/" + cmSystemTools::GetFilenameName(i); - this->Makefile->AddSubDirectory(i, binPath, excludeFromAll, false); + mf.AddSubDirectory(i, binPath, excludeFromAll, false); } else { - std::string error = cmStrCat("Incorrect SUBDIRS command. Directory: ", i, - " does not exist."); - this->SetError(error); + status.SetError(cmStrCat("Incorrect SUBDIRS command. Directory: ", i, + " does not exist.")); res = false; } } diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h index 3499c46..3254e84 100644 --- a/Source/cmSubdirCommand.h +++ b/Source/cmSubdirCommand.h @@ -8,36 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmSubdirCommand - * \brief Specify a list of subdirectories to build. - * - * cmSubdirCommand specifies a list of subdirectories to process - * by CMake. For each subdirectory listed, CMake will descend - * into that subdirectory and process any CMakeLists.txt found. - */ -class cmSubdirCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSubdirCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmSubdirCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index b7287d9..62a8d8f 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -40,16 +40,16 @@ #include "cmsys/System.h" #include "cmsys/Terminal.h" #include <algorithm> -#include <assert.h> -#include <ctype.h> -#include <errno.h> +#include <cassert> +#include <cctype> +#include <cerrno> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> #include <fcntl.h> #include <iostream> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> #include <utility> #include <vector> @@ -855,6 +855,18 @@ bool cmSystemTools::RenameFile(const std::string& oldname, #endif } +void cmSystemTools::MoveFileIfDifferent(const std::string& source, + const std::string& destination) +{ + if (FilesDiffer(source, destination)) { + if (RenameFile(source, destination)) { + return; + } + CopyFileAlways(source, destination); + } + RemoveFile(source); +} + std::string cmSystemTools::ComputeFileHash(const std::string& source, cmCryptoHash::Algo algo) { @@ -1633,8 +1645,8 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, std::vector<char>& err) { line.clear(); - std::vector<char>::iterator outiter = out.begin(); - std::vector<char>::iterator erriter = err.begin(); + auto outiter = out.begin(); + auto erriter = err.begin(); cmProcessOutput processOutput; std::string strdata; while (true) { @@ -2540,8 +2552,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, // Adjust the entry list as necessary to remove the run path unsigned long entriesErased = 0; - for (cmELF::DynamicEntryList::iterator it = dentries.begin(); - it != dentries.end();) { + for (auto it = dentries.begin(); it != dentries.end();) { if (it->first == cmELF::TagRPath || it->first == cmELF::TagRunPath) { it = dentries.erase(it); entriesErased++; diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 863db3f..108215c 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -8,11 +8,11 @@ #include "cmCryptoHash.h" #include "cmDuration.h" #include "cmProcessOutput.h" -#include "cm_string_view.hxx" #include "cmsys/Process.h" #include "cmsys/SystemTools.hxx" // IWYU pragma: export +#include <cm/string_view> +#include <cstddef> #include <functional> -#include <stddef.h> #include <string> #include <vector> @@ -131,6 +131,10 @@ public: static bool RenameFile(const std::string& oldname, const std::string& newname); + //! Rename a file if contents are different, delete the source otherwise + static void MoveFileIfDifferent(const std::string& source, + const std::string& destination); + //! Compute the hash of a file static std::string ComputeFileHash(const std::string& source, cmCryptoHash::Algo algo); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 10ea7dd..1b88db6 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4,15 +4,15 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> -#include <assert.h> +#include <cassert> +#include <cstring> #include <initializer_list> #include <iterator> #include <set> #include <sstream> -#include <string.h> #include <unordered_set> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmAlgorithms.h" #include "cmCustomCommand.h" @@ -312,6 +312,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("AUTOMOC_MACRO_NAMES"); initProp("AUTOMOC_MOC_OPTIONS"); initProp("AUTOUIC_OPTIONS"); + initProp("AUTOMOC_PATH_PREFIX"); initProp("AUTOUIC_SEARCH_PATHS"); initProp("AUTORCC_OPTIONS"); initProp("LINK_DEPENDS_NO_SHARED"); @@ -694,13 +695,9 @@ std::string cmTargetInternals::ProcessSourceItemCMP0049(const std::string& s) return src; } -cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s) +std::string cmTarget::GetSourceCMP0049(const std::string& s) { - std::string src = impl->ProcessSourceItemCMP0049(s); - if (!s.empty() && src.empty()) { - return nullptr; - } - return this->AddSource(src); + return impl->ProcessSourceItemCMP0049(s); } struct CreateLocation @@ -1085,6 +1082,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) MAKE_STATIC_PROP(COMPILE_FEATURES); MAKE_STATIC_PROP(COMPILE_OPTIONS); MAKE_STATIC_PROP(PRECOMPILE_HEADERS); + MAKE_STATIC_PROP(PRECOMPILE_HEADERS_REUSE_FROM); MAKE_STATIC_PROP(CUDA_PTX_COMPILATION); MAKE_STATIC_PROP(EXPORT_NAME); MAKE_STATIC_PROP(IMPORTED_GLOBAL); @@ -1231,6 +1229,41 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) << impl->Name << "\")\n"; impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; + } else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) { + if (this->GetProperty("PRECOMPILE_HEADERS")) { + std::ostringstream e; + e << "PRECOMPILE_HEADERS property is already set on target (\"" + << impl->Name << "\")\n"; + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return; + } + auto reusedTarget = + impl->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( + value); + if (!reusedTarget) { + const std::string e( + "PRECOMPILE_HEADERS_REUSE_FROM set with non existing target"); + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); + return; + } + + std::string reusedFrom = reusedTarget->GetSafeProperty(prop); + if (reusedFrom.empty()) { + reusedFrom = value; + } + + impl->Properties.SetProperty(prop, reusedFrom.c_str()); + + reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom.c_str()); + reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY", + cmStrCat(reusedFrom, ".dir/").c_str()); + + for (auto p : { "COMPILE_PDB_NAME", "PRECOMPILE_HEADERS", + "INTERFACE_PRECOMPILE_HEADERS" }) { + this->SetProperty(p, reusedTarget->GetProperty(p)); + } + + this->AddUtility(reusedFrom, impl->Makefile); } else { impl->Properties.SetProperty(prop, value); } @@ -1308,6 +1341,14 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, impl->LinkDirectoriesBacktraces.push_back(lfbt); } } else if (prop == "PRECOMPILE_HEADERS") { + if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) { + std::ostringstream e; + e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target " + "(\"" + << impl->Name << "\")\n"; + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return; + } if (value && *value) { impl->PrecompileHeadersEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); @@ -1361,13 +1402,11 @@ void cmTarget::AppendBuildInterfaceIncludes() void cmTarget::InsertInclude(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - std::vector<std::string>::iterator position = before - ? impl->IncludeDirectoriesEntries.begin() - : impl->IncludeDirectoriesEntries.end(); + auto position = before ? impl->IncludeDirectoriesEntries.begin() + : impl->IncludeDirectoriesEntries.end(); - std::vector<cmListFileBacktrace>::iterator btPosition = before - ? impl->IncludeDirectoriesBacktraces.begin() - : impl->IncludeDirectoriesBacktraces.end(); + auto btPosition = before ? impl->IncludeDirectoriesBacktraces.begin() + : impl->IncludeDirectoriesBacktraces.end(); impl->IncludeDirectoriesEntries.insert(position, entry); impl->IncludeDirectoriesBacktraces.insert(btPosition, bt); @@ -1376,13 +1415,11 @@ void cmTarget::InsertInclude(std::string const& entry, void cmTarget::InsertCompileOption(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - std::vector<std::string>::iterator position = before - ? impl->CompileOptionsEntries.begin() - : impl->CompileOptionsEntries.end(); + auto position = before ? impl->CompileOptionsEntries.begin() + : impl->CompileOptionsEntries.end(); - std::vector<cmListFileBacktrace>::iterator btPosition = before - ? impl->CompileOptionsBacktraces.begin() - : impl->CompileOptionsBacktraces.end(); + auto btPosition = before ? impl->CompileOptionsBacktraces.begin() + : impl->CompileOptionsBacktraces.end(); impl->CompileOptionsEntries.insert(position, entry); impl->CompileOptionsBacktraces.insert(btPosition, bt); @@ -1398,12 +1435,11 @@ void cmTarget::InsertCompileDefinition(std::string const& entry, void cmTarget::InsertLinkOption(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - std::vector<std::string>::iterator position = + auto position = before ? impl->LinkOptionsEntries.begin() : impl->LinkOptionsEntries.end(); - std::vector<cmListFileBacktrace>::iterator btPosition = before - ? impl->LinkOptionsBacktraces.begin() - : impl->LinkOptionsBacktraces.end(); + auto btPosition = before ? impl->LinkOptionsBacktraces.begin() + : impl->LinkOptionsBacktraces.end(); impl->LinkOptionsEntries.insert(position, entry); impl->LinkOptionsBacktraces.insert(btPosition, bt); @@ -1412,13 +1448,11 @@ void cmTarget::InsertLinkOption(std::string const& entry, void cmTarget::InsertLinkDirectory(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - std::vector<std::string>::iterator position = before - ? impl->LinkDirectoriesEntries.begin() - : impl->LinkDirectoriesEntries.end(); + auto position = before ? impl->LinkDirectoriesEntries.begin() + : impl->LinkDirectoriesEntries.end(); - std::vector<cmListFileBacktrace>::iterator btPosition = before - ? impl->LinkDirectoriesBacktraces.begin() - : impl->LinkDirectoriesBacktraces.end(); + auto btPosition = before ? impl->LinkDirectoriesBacktraces.begin() + : impl->LinkDirectoriesBacktraces.end(); impl->LinkDirectoriesEntries.insert(position, entry); impl->LinkDirectoriesBacktraces.insert(btPosition, bt); @@ -1496,8 +1530,7 @@ static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target, cmMakefile* context) { std::vector<cmTarget*> targets = context->GetOwnedImportedTargets(); - std::vector<cmTarget*>::const_iterator it = - std::find(targets.begin(), targets.end(), target); + auto it = std::find(targets.begin(), targets.end(), target); if (it == targets.end()) { std::ostringstream e; e << "Attempt to promote imported target \"" << target->GetName() @@ -1947,7 +1980,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, (this->IsAIX() && this->IsExecutableWithExports()); // If a mapping was found, check its configurations. - for (std::vector<std::string>::const_iterator mci = mappedConfigs.begin(); + for (auto mci = mappedConfigs.begin(); !*loc && !*imp && mci != mappedConfigs.end(); ++mci) { // Look for this configuration. if (mci->empty()) { @@ -2018,8 +2051,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) { cmExpandList(iconfigs, availableConfigs); } - for (std::vector<std::string>::const_iterator aci = - availableConfigs.begin(); + for (auto aci = availableConfigs.begin(); !*loc && !*imp && aci != availableConfigs.end(); ++aci) { suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci)); std::string locProp = cmStrCat(locPropBase, suffix); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e9bcffe..f4726d3 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -103,7 +103,7 @@ public: //! Add sources to the target. void AddSources(std::vector<std::string> const& srcs); void AddTracedSources(std::vector<std::string> const& srcs); - cmSourceFile* AddSourceCMP0049(const std::string& src); + std::string GetSourceCMP0049(const std::string& src); cmSourceFile* AddSource(const std::string& src, bool before = false); //! how we identify a library, by name and type diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index b64646a..94e249f 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetCompileDefinitionsCommand.h" -#include <sstream> - #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" @@ -20,11 +18,10 @@ bool cmTargetCompileDefinitionsCommand::InitialPass( void cmTargetCompileDefinitionsCommand::HandleMissingTarget( const std::string& name) { - std::ostringstream e; - e << "Cannot specify compile definitions for target \"" << name - << "\" " - "which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify compile definitions for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetCompileDefinitionsCommand::Join( diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h index 25af21d..f85dc0a 100644 --- a/Source/cmTargetCompileDefinitionsCommand.h +++ b/Source/cmTargetCompileDefinitionsCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx index 976c8cb..a22b94b 100644 --- a/Source/cmTargetCompileFeaturesCommand.cxx +++ b/Source/cmTargetCompileFeaturesCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetCompileFeaturesCommand.h" -#include <sstream> - #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" @@ -20,11 +18,10 @@ bool cmTargetCompileFeaturesCommand::InitialPass( void cmTargetCompileFeaturesCommand::HandleMissingTarget( const std::string& name) { - std::ostringstream e; - e << "Cannot specify compile features for target \"" << name - << "\" " - "which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify compile features for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetCompileFeaturesCommand::Join( diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h index 07948fa..39597ca 100644 --- a/Source/cmTargetCompileFeaturesCommand.h +++ b/Source/cmTargetCompileFeaturesCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index 7dadb82..ccc215a 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetCompileOptionsCommand.h" -#include <sstream> - #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -21,10 +19,10 @@ bool cmTargetCompileOptionsCommand::InitialPass( void cmTargetCompileOptionsCommand::HandleMissingTarget( const std::string& name) { - std::ostringstream e; - e << "Cannot specify compile options for target \"" << name - << "\" which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify compile options for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetCompileOptionsCommand::Join( diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h index a571cfb..b328ba2 100644 --- a/Source/cmTargetCompileOptionsCommand.h +++ b/Source/cmTargetCompileOptionsCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index d099349..7801ee8 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -3,7 +3,6 @@ #include "cmTargetIncludeDirectoriesCommand.h" #include <set> -#include <sstream> #include "cmGeneratorExpression.h" #include "cmListFileCache.h" @@ -25,10 +24,10 @@ bool cmTargetIncludeDirectoriesCommand::InitialPass( void cmTargetIncludeDirectoriesCommand::HandleMissingTarget( const std::string& name) { - std::ostringstream e; - e << "Cannot specify include directories for target \"" << name - << "\" which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify include directories for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetIncludeDirectoriesCommand::Join( diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h index 6defab2..f6481db 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.h +++ b/Source/cmTargetIncludeDirectoriesCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx index 435c392..c2ef6c1 100644 --- a/Source/cmTargetLinkDirectoriesCommand.cxx +++ b/Source/cmTargetLinkDirectoriesCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetLinkDirectoriesCommand.h" -#include <sstream> - #include "cmGeneratorExpression.h" #include "cmListFileCache.h" #include "cmMakefile.h" @@ -23,10 +21,10 @@ bool cmTargetLinkDirectoriesCommand::InitialPass( void cmTargetLinkDirectoriesCommand::HandleMissingTarget( const std::string& name) { - std::ostringstream e; - e << "Cannot specify link directories for target \"" << name - << "\" which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify link directories for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetLinkDirectoriesCommand::Join( diff --git a/Source/cmTargetLinkDirectoriesCommand.h b/Source/cmTargetLinkDirectoriesCommand.h index a2fcfa9..a651d73 100644 --- a/Source/cmTargetLinkDirectoriesCommand.h +++ b/Source/cmTargetLinkDirectoriesCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 4fbec90..0d2383a 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -2,9 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetLinkLibrariesCommand.h" +#include <cstring> #include <sstream> -#include <string.h> +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -15,44 +16,64 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetLinkLibraryType.h" #include "cmake.h" -class cmExecutionStatus; +namespace { -const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] = { - "general", "debug", "optimized" +enum ProcessingState +{ + ProcessingLinkLibraries, + ProcessingPlainLinkInterface, + ProcessingKeywordLinkInterface, + ProcessingPlainPublicInterface, + ProcessingKeywordPublicInterface, + ProcessingPlainPrivateInterface, + ProcessingKeywordPrivateInterface }; -// cmTargetLinkLibrariesCommand -bool cmTargetLinkLibrariesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +const char* LinkLibraryTypeNames[3] = { "general", "debug", "optimized" }; + +} // namespace + +static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left, + int right); + +static bool HandleLibrary(cmMakefile& mf, cmTarget* target, + ProcessingState currentProcessingState, + const std::string& lib, cmTargetLinkLibraryType llt); + +bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Must have at least one argument. if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } + + cmMakefile& mf = status.GetMakefile(); + // Alias targets cannot be on the LHS of this command. - if (this->Makefile->IsAlias(args[0])) { - this->SetError("can not be used on an ALIAS target."); + if (mf.IsAlias(args[0])) { + status.SetError("can not be used on an ALIAS target."); return false; } // Lookup the target for which libraries are specified. - this->Target = - this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( - args[0]); - if (!this->Target) { + cmTarget* target = + mf.GetCMakeInstance()->GetGlobalGenerator()->FindTarget(args[0]); + if (!target) { const std::vector<cmTarget*>& importedTargets = - this->Makefile->GetOwnedImportedTargets(); + mf.GetOwnedImportedTargets(); for (cmTarget* importedTarget : importedTargets) { if (importedTarget->GetName() == args[0]) { - this->Target = importedTarget; + target = importedTarget; break; } } } - if (!this->Target) { + if (!target) { MessageType t = MessageType::FATAL_ERROR; // fail by default std::ostringstream e; e << "Cannot specify link libraries for target \"" << args[0] << "\" " @@ -60,7 +81,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // The bad target is the only argument. Check how policy CMP0016 is set, // and accept, warn or fail respectively: if (args.size() < 2) { - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0016)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0016)) { case cmPolicies::WARN: t = MessageType::AUTHOR_WARNING; // Print the warning. @@ -84,10 +105,10 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // Now actually print the message. switch (t) { case MessageType::AUTHOR_WARNING: - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); break; case MessageType::FATAL_ERROR: - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); break; default: @@ -97,11 +118,11 @@ bool cmTargetLinkLibrariesCommand::InitialPass( } // Having a UTILITY library on the LHS is a bug. - if (this->Target->GetType() == cmStateEnums::UTILITY) { + if (target->GetType() == cmStateEnums::UTILITY) { std::ostringstream e; const char* modal = nullptr; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0039)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0039)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n"; modal = "should"; @@ -114,9 +135,9 @@ bool cmTargetLinkLibrariesCommand::InitialPass( messageType = MessageType::FATAL_ERROR; } if (modal) { - e << "Utility target \"" << this->Target->GetName() << "\" " << modal + e << "Utility target \"" << target->GetName() << "\" " << modal << " not be used as the target of a target_link_libraries call."; - this->Makefile->IssueMessage(messageType, e.str()); + mf.IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -134,15 +155,15 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // Start with primary linking and switch to link interface // specification if the keyword is encountered as the first argument. - this->CurrentProcessingState = ProcessingLinkLibraries; + ProcessingState currentProcessingState = ProcessingLinkLibraries; // Add libraries, note that there is an optional prefix // of debug and optimized that can be used. for (unsigned int i = 1; i < args.size(); ++i) { if (args[i] == "LINK_INTERFACE_LIBRARIES") { - this->CurrentProcessingState = ProcessingPlainLinkInterface; + currentProcessingState = ProcessingPlainLinkInterface; if (i != 1) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::FATAL_ERROR, "The LINK_INTERFACE_LIBRARIES option must appear as the second " "argument, just after the target name."); @@ -150,84 +171,83 @@ bool cmTargetLinkLibrariesCommand::InitialPass( } } else if (args[i] == "INTERFACE") { if (i != 1 && - this->CurrentProcessingState != ProcessingKeywordPrivateInterface && - this->CurrentProcessingState != ProcessingKeywordPublicInterface && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingKeywordPrivateInterface && + currentProcessingState != ProcessingKeywordPublicInterface && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The INTERFACE, PUBLIC or PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingKeywordLinkInterface; + currentProcessingState = ProcessingKeywordLinkInterface; } else if (args[i] == "LINK_PUBLIC") { if (i != 1 && - this->CurrentProcessingState != ProcessingPlainPrivateInterface && - this->CurrentProcessingState != ProcessingPlainPublicInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingPlainPrivateInterface && + currentProcessingState != ProcessingPlainPublicInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingPlainPublicInterface; + currentProcessingState = ProcessingPlainPublicInterface; } else if (args[i] == "PUBLIC") { if (i != 1 && - this->CurrentProcessingState != ProcessingKeywordPrivateInterface && - this->CurrentProcessingState != ProcessingKeywordPublicInterface && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingKeywordPrivateInterface && + currentProcessingState != ProcessingKeywordPublicInterface && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The INTERFACE, PUBLIC or PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingKeywordPublicInterface; + currentProcessingState = ProcessingKeywordPublicInterface; } else if (args[i] == "LINK_PRIVATE") { - if (i != 1 && - this->CurrentProcessingState != ProcessingPlainPublicInterface && - this->CurrentProcessingState != ProcessingPlainPrivateInterface) { - this->Makefile->IssueMessage( + if (i != 1 && currentProcessingState != ProcessingPlainPublicInterface && + currentProcessingState != ProcessingPlainPrivateInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingPlainPrivateInterface; + currentProcessingState = ProcessingPlainPrivateInterface; } else if (args[i] == "PRIVATE") { if (i != 1 && - this->CurrentProcessingState != ProcessingKeywordPrivateInterface && - this->CurrentProcessingState != ProcessingKeywordPublicInterface && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingKeywordPrivateInterface && + currentProcessingState != ProcessingKeywordPublicInterface && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The INTERFACE, PUBLIC or PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingKeywordPrivateInterface; + currentProcessingState = ProcessingKeywordPrivateInterface; } else if (args[i] == "debug") { if (haveLLT) { - this->LinkLibraryTypeSpecifierWarning(llt, DEBUG_LibraryType); + LinkLibraryTypeSpecifierWarning(mf, llt, DEBUG_LibraryType); } llt = DEBUG_LibraryType; haveLLT = true; } else if (args[i] == "optimized") { if (haveLLT) { - this->LinkLibraryTypeSpecifierWarning(llt, OPTIMIZED_LibraryType); + LinkLibraryTypeSpecifierWarning(mf, llt, OPTIMIZED_LibraryType); } llt = OPTIMIZED_LibraryType; haveLLT = true; } else if (args[i] == "general") { if (haveLLT) { - this->LinkLibraryTypeSpecifierWarning(llt, GENERAL_LibraryType); + LinkLibraryTypeSpecifierWarning(mf, llt, GENERAL_LibraryType); } llt = GENERAL_LibraryType; haveLLT = true; } else if (haveLLT) { // The link type was specified by the previous argument. haveLLT = false; - if (!this->HandleLibrary(args[i], llt)) { + if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) { return false; } } else { @@ -239,7 +259,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // with old versions of CMake and new) llt = GENERAL_LibraryType; std::string linkType = cmStrCat(args[0], "_LINK_TYPE"); - const char* linkTypeString = this->Makefile->GetDefinition(linkType); + const char* linkTypeString = mf.GetDefinition(linkType); if (linkTypeString) { if (strcmp(linkTypeString, "debug") == 0) { llt = DEBUG_LibraryType; @@ -248,7 +268,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( llt = OPTIMIZED_LibraryType; } } - if (!this->HandleLibrary(args[i], llt)) { + if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) { return false; } } @@ -256,15 +276,14 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // Make sure the last argument was not a library type specifier. if (haveLLT) { - std::ostringstream e; - e << "The \"" << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[llt] - << "\" argument must be followed by a library."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("The \"", LinkLibraryTypeNames[llt], + "\" argument must be followed by a library.")); cmSystemTools::SetFatalErrorOccured(); } const cmPolicies::PolicyStatus policy22Status = - this->Target->GetPolicyStatusCMP0022(); + target->GetPolicyStatusCMP0022(); // If any of the LINK_ options were given, make sure the // LINK_INTERFACE_LIBRARIES target property exists. @@ -273,41 +292,40 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // result in an empty link interface. if ((policy22Status == cmPolicies::OLD || policy22Status == cmPolicies::WARN) && - this->CurrentProcessingState != ProcessingLinkLibraries && - !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES")) { - this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", ""); + currentProcessingState != ProcessingLinkLibraries && + !target->GetProperty("LINK_INTERFACE_LIBRARIES")) { + target->SetProperty("LINK_INTERFACE_LIBRARIES", ""); } return true; } -void cmTargetLinkLibrariesCommand::LinkLibraryTypeSpecifierWarning(int left, - int right) +static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left, + int right) { - std::ostringstream w; - w << "Link library type specifier \"" - << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[left] - << "\" is followed by specifier \"" - << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[right] - << "\" instead of a library name. " - << "The first specifier will be ignored."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + mf.IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat( + "Link library type specifier \"", LinkLibraryTypeNames[left], + "\" is followed by specifier \"", LinkLibraryTypeNames[right], + "\" instead of a library name. The first specifier will be ignored.")); } -bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, - cmTargetLinkLibraryType llt) +static bool HandleLibrary(cmMakefile& mf, cmTarget* target, + ProcessingState currentProcessingState, + const std::string& lib, cmTargetLinkLibraryType llt) { - if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "INTERFACE library can only be used with the INTERFACE keyword of " "target_link_libraries"); return false; } - if (this->Target->IsImported() && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + if (target->IsImported() && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "IMPORTED library can only be used with the INTERFACE keyword of " "target_link_libraries"); @@ -315,19 +333,18 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, } cmTarget::TLLSignature sig = - (this->CurrentProcessingState == ProcessingPlainPrivateInterface || - this->CurrentProcessingState == ProcessingPlainPublicInterface || - this->CurrentProcessingState == ProcessingKeywordPrivateInterface || - this->CurrentProcessingState == ProcessingKeywordPublicInterface || - this->CurrentProcessingState == ProcessingKeywordLinkInterface) + (currentProcessingState == ProcessingPlainPrivateInterface || + currentProcessingState == ProcessingPlainPublicInterface || + currentProcessingState == ProcessingKeywordPrivateInterface || + currentProcessingState == ProcessingKeywordPublicInterface || + currentProcessingState == ProcessingKeywordLinkInterface) ? cmTarget::KeywordTLLSignature : cmTarget::PlainTLLSignature; - if (!this->Target->PushTLLCommandTrace( - sig, this->Makefile->GetExecutionContext())) { + if (!target->PushTLLCommandTrace(sig, mf.GetExecutionContext())) { std::ostringstream e; const char* modal = nullptr; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0023)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0023)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n"; modal = "should"; @@ -348,14 +365,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, e << "The " << existingSig << " signature for target_link_libraries has " "already been used with the target \"" - << this->Target->GetName() + << target->GetName() << "\". All uses of target_link_libraries with a target " << modal << " be either all-keyword or all-plain.\n"; - this->Target->GetTllSignatureTraces(e, - sig == cmTarget::KeywordTLLSignature - ? cmTarget::PlainTLLSignature - : cmTarget::KeywordTLLSignature); - this->Makefile->IssueMessage(messageType, e.str()); + target->GetTllSignatureTraces(e, + sig == cmTarget::KeywordTLLSignature + ? cmTarget::PlainTLLSignature + : cmTarget::KeywordTLLSignature); + mf.IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -365,9 +382,9 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, bool warnRemoteInterface = false; bool rejectRemoteLinking = false; bool encodeRemoteReference = false; - if (this->Makefile != this->Target->GetMakefile()) { + if (&mf != target->GetMakefile()) { // The LHS target was created in another directory. - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0079)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0079)) { case cmPolicies::WARN: warnRemoteInterface = true; CM_FALLTHROUGH; @@ -388,7 +405,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // same directory as the target was created. Add a suffix to // the name to tell ResolveLinkItem to look up the name in the // caller's directory. - cmDirectoryId const dirId = this->Makefile->GetDirectoryId(); + cmDirectoryId const dirId = mf.GetDirectoryId(); libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String; } else { // This is an absolute path or a library name added by a caller @@ -400,20 +417,21 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Handle normal case where the command was called with another keyword than // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES" // property of the target on the LHS shall be populated.) - if (this->CurrentProcessingState != ProcessingKeywordLinkInterface && - this->CurrentProcessingState != ProcessingPlainLinkInterface) { + if (currentProcessingState != ProcessingKeywordLinkInterface && + currentProcessingState != ProcessingPlainLinkInterface) { if (rejectRemoteLinking) { - std::ostringstream e; - e << "Attempt to add link library \"" << lib << "\" to target \"" - << this->Target->GetName() - << "\" which is not built in this directory.\n" - << "This is allowed only when policy CMP0079 is set to NEW."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Attempt to add link library \"", lib, "\" to target \"", + target->GetName(), + "\" which is not built in this " + "directory.\nThis is allowed only when policy CMP0079 " + "is set to NEW.")); return false; } - cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(lib); + cmTarget* tgt = mf.GetGlobalGenerator()->FindTarget(lib); if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) && (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) && @@ -421,47 +439,48 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, (tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) && (tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) && !tgt->IsExecutableWithExports()) { - std::ostringstream e; - e << "Target \"" << lib << "\" of type " - << cmState::GetTargetTypeName(tgt->GetType()) - << " may not be linked into another target. One may link only to " - "INTERFACE, OBJECT, STATIC or SHARED libraries, or to executables " - "with the ENABLE_EXPORTS property set."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat( + "Target \"", lib, "\" of type ", + cmState::GetTargetTypeName(tgt->GetType()), + " may not be linked into another target. One may link only to " + "INTERFACE, OBJECT, STATIC or SHARED libraries, or to ", + "executables with the ENABLE_EXPORTS property set.")); } - this->Target->AddLinkLibrary(*this->Makefile, lib, libRef, llt); + target->AddLinkLibrary(mf, lib, libRef, llt); } if (warnRemoteInterface) { - std::ostringstream w; - /* clang-format off */ - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0079) << "\n" - "Target\n " << this->Target->GetName() << "\nis not created in this " - "directory. For compatibility with older versions of CMake, link " - "library\n " << lib << "\nwill be looked up in the directory in " - "which the target was created rather than in this calling " - "directory."; - /* clang-format on */ - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + mf.IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat( + cmPolicies::GetPolicyWarning(cmPolicies::CMP0079), "\nTarget\n ", + target->GetName(), + "\nis not created in this " + "directory. For compatibility with older versions of CMake, link " + "library\n ", + lib, + "\nwill be looked up in the directory in which " + "the target was created rather than in this calling directory.")); } // Handle (additional) case where the command was called with PRIVATE / // LINK_PRIVATE and stop its processing. (The "INTERFACE_LINK_LIBRARIES" // property of the target on the LHS shall only be populated if it is a // STATIC library.) - if (this->CurrentProcessingState == ProcessingKeywordPrivateInterface || - this->CurrentProcessingState == ProcessingPlainPrivateInterface) { - if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY || - this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { + if (currentProcessingState == ProcessingKeywordPrivateInterface || + currentProcessingState == ProcessingPlainPrivateInterface) { + if (target->GetType() == cmStateEnums::STATIC_LIBRARY || + target->GetType() == cmStateEnums::OBJECT_LIBRARY) { std::string configLib = - this->Target->GetDebugGeneratorExpressions(libRef, llt); + target->GetDebugGeneratorExpressions(libRef, llt); if (cmGeneratorExpression::IsValidTargetName(lib) || cmGeneratorExpression::Find(lib) != std::string::npos) { configLib = "$<LINK_ONLY:" + configLib + ">"; } - this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", - configLib.c_str()); + target->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str()); } return true; } @@ -469,23 +488,23 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Handle general case where the command was called with another keyword than // PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES" // property of the target on the LHS shall be populated.) - this->Target->AppendProperty( + target->AppendProperty( "INTERFACE_LINK_LIBRARIES", - this->Target->GetDebugGeneratorExpressions(libRef, llt).c_str()); + target->GetDebugGeneratorExpressions(libRef, llt).c_str()); // Stop processing if called without any keyword. - if (this->CurrentProcessingState == ProcessingLinkLibraries) { + if (currentProcessingState == ProcessingLinkLibraries) { return true; } // Stop processing if policy CMP0022 is set to NEW. const cmPolicies::PolicyStatus policy22Status = - this->Target->GetPolicyStatusCMP0022(); + target->GetPolicyStatusCMP0022(); if (policy22Status != cmPolicies::OLD && policy22Status != cmPolicies::WARN) { return true; } // Stop processing if called with an INTERFACE library on the LHS. - if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { return true; } @@ -495,7 +514,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, { // Get the list of configurations considered to be DEBUG. std::vector<std::string> debugConfigs = - this->Makefile->GetCMakeInstance()->GetDebugConfigs(); + mf.GetCMakeInstance()->GetDebugConfigs(); std::string prop; // Include this library in the link interface for the target. @@ -503,19 +522,19 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Put in the DEBUG configuration interfaces. for (std::string const& dc : debugConfigs) { prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc); - this->Target->AppendProperty(prop, libRef.c_str()); + target->AppendProperty(prop, libRef.c_str()); } } if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) { // Put in the non-DEBUG configuration interfaces. - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str()); + target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str()); // Make sure the DEBUG configuration interfaces exist so that the // general one will not be used as a fall-back. for (std::string const& dc : debugConfigs) { prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc); - if (!this->Target->GetProperty(prop)) { - this->Target->SetProperty(prop, ""); + if (!target->GetProperty(prop)) { + target->SetProperty(prop, ""); } } } diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index 6698ce0..4b2deab 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -8,61 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" -#include "cmTargetLinkLibraryType.h" - class cmExecutionStatus; -class cmTarget; - -/** \class cmTargetLinkLibrariesCommand - * \brief Specify a list of libraries to link into executables. - * - * cmTargetLinkLibrariesCommand is used to specify a list of libraries to link - * into executable(s) or shared objects. The names of the libraries - * should be those defined by the LIBRARY(library) command(s). - * - * Additionally, it allows to propagate usage-requirements (including link - * libraries) from one target into another. - */ -class cmTargetLinkLibrariesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetLinkLibrariesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - void LinkLibraryTypeSpecifierWarning(int left, int right); - static const char* LinkLibraryTypeNames[3]; - - cmTarget* Target = nullptr; - enum ProcessingState - { - ProcessingLinkLibraries, - ProcessingPlainLinkInterface, - ProcessingKeywordLinkInterface, - ProcessingPlainPublicInterface, - ProcessingKeywordPublicInterface, - ProcessingPlainPrivateInterface, - ProcessingKeywordPrivateInterface - }; - - ProcessingState CurrentProcessingState = ProcessingLinkLibraries; - bool HandleLibrary(const std::string& lib, cmTargetLinkLibraryType llt); -}; +bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx index 2866cf1..dbd7bfe 100644 --- a/Source/cmTargetLinkOptionsCommand.cxx +++ b/Source/cmTargetLinkOptionsCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetLinkOptionsCommand.h" -#include <sstream> - #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -20,10 +18,10 @@ bool cmTargetLinkOptionsCommand::InitialPass( void cmTargetLinkOptionsCommand::HandleMissingTarget(const std::string& name) { - std::ostringstream e; - e << "Cannot specify link options for target \"" << name - << "\" which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify link options for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetLinkOptionsCommand::Join( diff --git a/Source/cmTargetLinkOptionsCommand.h b/Source/cmTargetLinkOptionsCommand.h index 3710739..918a8d7 100644 --- a/Source/cmTargetLinkOptionsCommand.h +++ b/Source/cmTargetLinkOptionsCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx index 30cf1be..5751fff 100644 --- a/Source/cmTargetPrecompileHeadersCommand.cxx +++ b/Source/cmTargetPrecompileHeadersCommand.cxx @@ -2,15 +2,27 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetPrecompileHeadersCommand.h" +#include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" +#include "cmSystemTools.h" #include "cmTarget.h" +#include <utility> + bool cmTargetPrecompileHeadersCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) { - return this->HandleArguments(args, "PRECOMPILE_HEADERS"); + return this->HandleArguments(args, "PRECOMPILE_HEADERS", PROCESS_REUSE_FROM); +} + +void cmTargetPrecompileHeadersCommand::HandleInterfaceContent( + cmTarget* tgt, const std::vector<std::string>& content, bool prepend, + bool system) +{ + cmTargetPropCommandBase::HandleInterfaceContent( + tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); } void cmTargetPrecompileHeadersCommand::HandleMissingTarget( @@ -31,6 +43,33 @@ std::string cmTargetPrecompileHeadersCommand::Join( bool cmTargetPrecompileHeadersCommand::HandleDirectContent( cmTarget* tgt, const std::vector<std::string>& content, bool, bool) { - tgt->AppendProperty("PRECOMPILE_HEADERS", this->Join(content).c_str()); + tgt->AppendProperty( + "PRECOMPILE_HEADERS", + this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); return true; } + +std::vector<std::string> +cmTargetPrecompileHeadersCommand::ConvertToAbsoluteContent( + cmTarget* /*tgt*/, const std::vector<std::string>& content, + bool /*isInterfaceContent*/) +{ + std::vector<std::string> absoluteContent; + absoluteContent.reserve(content.size()); + for (std::string const& src : content) { + std::string absoluteSrc; + // Use '<foo.h>' and '"foo.h"' includes and absolute paths as-is. + // Interpret relative paths with respect to the source directory. + // If the path starts in a generator expression, assume it is absolute. + if (cmHasLiteralPrefix(src, "<") || cmHasLiteralPrefix(src, "\"") || + cmSystemTools::FileIsFullPath(src) || + cmGeneratorExpression::Find(src) == 0) { + absoluteSrc = src; + } else { + absoluteSrc = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', src); + } + absoluteContent.emplace_back(std::move(absoluteSrc)); + } + return absoluteContent; +} diff --git a/Source/cmTargetPrecompileHeadersCommand.h b/Source/cmTargetPrecompileHeadersCommand.h index 1ddf2af..00dc928 100644 --- a/Source/cmTargetPrecompileHeadersCommand.h +++ b/Source/cmTargetPrecompileHeadersCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" @@ -28,6 +28,11 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; +protected: + void HandleInterfaceContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override; + private: void HandleMissingTarget(const std::string& name) override; @@ -36,6 +41,10 @@ private: bool prepend, bool system) override; std::string Join(const std::vector<std::string>& content) override; + + std::vector<std::string> ConvertToAbsoluteContent( + cmTarget* tgt, const std::vector<std::string>& content, + bool isInterfaceContent); }; #endif diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 3aa845c..4bc3125 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -65,6 +65,19 @@ bool cmTargetPropCommandBase::HandleArguments( ++argIndex; } + if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") { + if (args.size() != 3) { + this->SetError("called with incorrect number of arguments"); + return false; + } + ++argIndex; + + this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM", + args[argIndex].c_str()); + + ++argIndex; + } + this->Property = prop; while (argIndex < args.size()) { diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h index 943285d..b244417 100644 --- a/Source/cmTargetPropCommandBase.h +++ b/Source/cmTargetPropCommandBase.h @@ -17,9 +17,10 @@ class cmTargetPropCommandBase : public cmCommand public: enum ArgumentFlags { - NO_FLAGS = 0, - PROCESS_BEFORE = 1, - PROCESS_SYSTEM = 2 + NO_FLAGS = 0x0, + PROCESS_BEFORE = 0x1, + PROCESS_SYSTEM = 0x2, + PROCESS_REUSE_FROM = 0x3 }; bool HandleArguments(std::vector<std::string> const& args, diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index 2251a65..7c9d03c 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -30,11 +30,10 @@ void cmTargetSourcesCommand::HandleInterfaceContent( void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name) { - std::ostringstream e; - e << "Cannot specify sources for target \"" << name - << "\" " - "which is not built by this project."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify sources for target \"", name, + "\" which is not built by this project.")); } std::string cmTargetSourcesCommand::Join( diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h index 90fd45f..1cff8c3 100644 --- a/Source/cmTargetSourcesCommand.h +++ b/Source/cmTargetSourcesCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmTargetPropCommandBase.h" diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index a9be729..390fd16 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -2,9 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTimestamp.h" +#include <cstdlib> #include <cstring> #include <sstream> -#include <stdlib.h> #include "cmStringAlgorithms.h" #include "cmSystemTools.h" diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h index d5fbdfd..40338f8 100644 --- a/Source/cmTimestamp.h +++ b/Source/cmTimestamp.h @@ -5,8 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <ctime> #include <string> -#include <time.h> /** \class cmTimestamp * \brief Utility class to generate string representation of a timestamp diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h index ec9f8b8..e525e85 100644 --- a/Source/cmTryCompileCommand.h +++ b/Source/cmTryCompileCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmCoreTryCompile.h" diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 24d0f0f..73354ec 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -3,7 +3,7 @@ #include "cmTryRunCommand.h" #include "cmsys/FStream.hxx" -#include <stdio.h> +#include <cstdio> #include "cmDuration.h" #include "cmMakefile.h" diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h index bacfcdb..c53a694 100644 --- a/Source/cmTryRunCommand.h +++ b/Source/cmTryRunCommand.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> #include "cmCommand.h" #include "cmCoreTryCompile.h" diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx index 97c27cb..23dabb7 100644 --- a/Source/cmUVHandlePtr.cxx +++ b/Source/cmUVHandlePtr.cxx @@ -3,9 +3,9 @@ #define cmUVHandlePtr_cxx #include "cmUVHandlePtr.h" -#include <assert.h> +#include <cassert> +#include <cstdlib> #include <mutex> -#include <stdlib.h> #include "cm_uv.h" diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index 56d6c09..3adc47a 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -7,13 +7,13 @@ #include "cmUVStreambuf.h" #include "cm_uv.h" -#include <assert.h> +#include <cassert> #include <istream> // IWYU pragma: keep #include <iterator> #include <utility> -#include "cm_memory.hxx" +#include <cm/memory> struct cmUVProcessChain::InternalData { diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h index 76a9c40..8a19bc3 100644 --- a/Source/cmUVProcessChain.h +++ b/Source/cmUVProcessChain.h @@ -7,13 +7,12 @@ #include <array> #include <cstddef> +#include <cstdint> #include <iosfwd> #include <memory> #include <string> #include <vector> -#include <stdint.h> - class cmUVProcessChain; class cmUVProcessChainBuilder diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h index 873352b..0737629 100644 --- a/Source/cmUVStreambuf.h +++ b/Source/cmUVStreambuf.h @@ -61,7 +61,7 @@ public: cmBasicUVStreambuf* close(); protected: - typename cmBasicUVStreambuf::int_type underflow() override; + typename cmBasicUVStreambuf<CharT, Traits>::int_type underflow() override; std::streamsize showmanyc() override; // FIXME: Add write support diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index cfc00e8..1fd386b 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -98,7 +98,6 @@ void CopyAndFullPathMesaHeader(const std::string& source, // close the files before attempting to copy fin.close(); fout.close(); - cmSystemTools::CopyFileIfDifferent(tempOutputFile, outFile); - cmSystemTools::RemoveFile(tempOutputFile); + cmSystemTools::MoveFileIfDifferent(tempOutputFile, outFile); } } diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index 25fe4ad..a43165c 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmUtilitySourceCommand.h" -#include <string.h> +#include <cstring> #include "cmExecutionStatus.h" #include "cmMakefile.h" @@ -20,7 +20,7 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args, return false; } - std::vector<std::string>::const_iterator arg = args.begin(); + auto arg = args.begin(); // The first argument is the cache entry name. std::string const& cacheEntry = *arg++; diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx index 91c8af3..f0f2c51 100644 --- a/Source/cmUuid.cxx +++ b/Source/cmUuid.cxx @@ -5,7 +5,7 @@ #include "cmCryptoHash.h" #include <array> -#include <string.h> +#include <cstring> static const std::array<int, 5> kUuidGroups = { { 4, 2, 2, 2, 6 } }; diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index 3df1420..4995da9 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -66,8 +66,7 @@ bool cmVariableWatch::VariableAccessed(const std::string& variable, int access_type, const char* newValue, const cmMakefile* mf) const { - cmVariableWatch::StringToVectorOfPairs::const_iterator mit = - this->WatchMap.find(variable); + auto mit = this->WatchMap.find(variable); if (mit != this->WatchMap.end()) { // The strategy here is to copy the list of callbacks, and ignore // new callbacks that existing ones may add. diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index db23efd..f2c8f3c 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -3,13 +3,13 @@ #include "cmVariableWatchCommand.h" #include <memory> -#include <sstream> #include <utility> #include "cmExecutionStatus.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVariableWatch.h" #include "cmake.h" @@ -58,22 +58,20 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable, newLFF.Line = 9999; cmExecutionStatus status(*makefile); if (!makefile->ExecuteCommand(newLFF, status)) { - std::ostringstream error; - error << "Error in cmake code at\nUnknown:0:\n" - << "A command failed during the invocation of callback \"" - << data->Command << "\"."; - cmSystemTools::Error(error.str()); + cmSystemTools::Error( + cmStrCat("Error in cmake code at\nUnknown:0:\nA command failed " + "during the invocation of callback \"", + data->Command, "\".")); data->InCallback = false; return; } processed = true; } if (!processed) { - std::ostringstream msg; - msg << "Variable \"" << variable << "\" was accessed using " - << accessString << " with value \"" << (newValue ? newValue : "") - << "\"."; - makefile->IssueMessage(MessageType::LOG, msg.str()); + makefile->IssueMessage( + MessageType::LOG, + cmStrCat("Variable \"", variable, "\" was accessed using ", accessString, + " with value \"", (newValue ? newValue : ""), "\".")); } data->InCallback = false; @@ -91,6 +89,7 @@ static void deleteVariableWatchCallbackData(void* client_data) class FinalAction { public: + /* NOLINTNEXTLINE(performance-unnecessary-value-param) */ FinalAction(cmMakefile* makefile, std::string variable) : Action(std::make_shared<Impl>(makefile, std::move(variable))) { @@ -133,9 +132,7 @@ bool cmVariableWatchCommand(std::vector<std::string> const& args, command = args[1]; } if (variable == "CMAKE_CURRENT_LIST_FILE") { - std::ostringstream ostr; - ostr << "cannot be set on the variable: " << variable; - status.SetError(ostr.str()); + status.SetError(cmStrCat("cannot be set on the variable: ", variable)); return false; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 5e92622..d28905a 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -21,7 +21,7 @@ #include <iterator> #include <set> -#include "cm_memory.hxx" +#include <cm/memory> static void ConvertToWindowsSlash(std::string& s); @@ -1139,10 +1139,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0) std::string configType; if (const char* vsConfigurationType = this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(vsConfigurationType); - configType = cge->Evaluate(this->LocalGenerator, c); + configType = cmGeneratorExpression::Evaluate(vsConfigurationType, + this->LocalGenerator, c); } else { switch (this->GeneratorTarget->GetType()) { case cmStateEnums::SHARED_LIBRARY: @@ -1468,6 +1466,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } // output files for custom command std::stringstream outputs; + bool symbolic = false; { const char* sep = ""; for (std::string const& o : ccg.GetOutputs()) { @@ -1475,6 +1474,12 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( ConvertToWindowsSlash(out); outputs << sep << out; sep = ";"; + if (!symbolic) { + if (cmSourceFile* sf = this->Makefile->GetSource( + o, cmSourceFileLocationKind::Known)) { + symbolic = sf->GetPropertyAsBool("SYMBOLIC"); + } + } } } if (this->ProjectType == csproj) { @@ -1484,7 +1489,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( outputs.str(), comment); } else { this->WriteCustomRuleCpp(*spe2, c, script, additional_inputs.str(), - outputs.str(), comment); + outputs.str(), comment, symbolic); } } } @@ -1492,7 +1497,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( Elem& e2, std::string const& config, std::string const& script, std::string const& additional_inputs, std::string const& outputs, - std::string const& comment) + std::string const& comment, bool symbolic) { const std::string cond = this->CalcCondition(config); e2.WritePlatformConfigTag("Message", cond, comment); @@ -1504,6 +1509,13 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( // VS >= 11 let us turn off linking of custom command outputs. e2.WritePlatformConfigTag("LinkObjects", cond, "false"); } + if (symbolic && + this->LocalGenerator->GetVersion() >= + cmGlobalVisualStudioGenerator::VS16) { + // VS >= 16.4 warn if outputs are not created, but one of our + // outputs is marked SYMBOLIC and not expected to be created. + e2.WritePlatformConfigTag("VerifyInputsAndOutputsExist", cond, "false"); + } } void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp( @@ -2447,49 +2459,32 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( if (ttype <= cmStateEnums::UTILITY) { if (const char* workingDir = this->GeneratorTarget->GetProperty( "VS_DEBUGGER_WORKING_DIRECTORY")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(workingDir); - std::string genWorkingDir = - cge->Evaluate(this->LocalGenerator, config); - + std::string genWorkingDir = cmGeneratorExpression::Evaluate( + workingDir, this->LocalGenerator, config); e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond, genWorkingDir); } if (const char* environment = this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(environment); - std::string genEnvironment = - cge->Evaluate(this->LocalGenerator, config); - + std::string genEnvironment = cmGeneratorExpression::Evaluate( + environment, this->LocalGenerator, config); e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond, genEnvironment); } if (const char* debuggerCommand = this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) { - - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(debuggerCommand); - std::string genDebuggerCommand = - cge->Evaluate(this->LocalGenerator, config); - + std::string genDebuggerCommand = cmGeneratorExpression::Evaluate( + debuggerCommand, this->LocalGenerator, config); e1.WritePlatformConfigTag("LocalDebuggerCommand", cond, genDebuggerCommand); } if (const char* commandArguments = this->GeneratorTarget->GetProperty( "VS_DEBUGGER_COMMAND_ARGUMENTS")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(commandArguments); - std::string genCommandArguments = - cge->Evaluate(this->LocalGenerator, config); - + std::string genCommandArguments = cmGeneratorExpression::Evaluate( + commandArguments, this->LocalGenerator, config); e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond, genCommandArguments); } @@ -3152,6 +3147,82 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( "-Wno-deprecated-gpu-targets"); } + // For static libraries that have device linking enabled compute + // the libraries + if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY && + doDeviceLinking) { + cmComputeLinkInformation* pcli = + this->GeneratorTarget->GetLinkInformation(configName); + if (!pcli) { + cmSystemTools::Error( + "CMake can not compute cmComputeLinkInformation for target: " + + this->Name); + return false; + } + + // Would like to use: + // cmLinkLineDeviceComputer computer(this->LocalGenerator, + // this->LocalGenerator->GetStateSnapshot().GetDirectory()); + // std::string computed_libs = computer.ComputeLinkLibraries(cli, + // std::string{}); but it outputs in "<libA> <libB>" format instead of + // "<libA>;<libB>" + // Note: + // Any modification of this algorithm should be reflected also in + // cmLinkLineDeviceComputer + cmComputeLinkInformation& cli = *pcli; + std::vector<std::string> libVec; + const std::string currentBinDir = + this->LocalGenerator->GetCurrentBinaryDirectory(); + const auto& libs = cli.GetItems(); + for (cmComputeLinkInformation::Item const& l : libs) { + + if (l.Target) { + auto managedType = l.Target->GetManagedType(configName); + // Do not allow C# targets to be added to the LIB listing. LIB files + // are used for linking C++ dependencies. C# libraries do not have lib + // files. Instead, they compile down to C# reference libraries (DLL + // files). The + // `<ProjectReference>` elements added to the vcxproj are enough for + // the IDE to deduce the DLL file required by other C# projects that + // need its reference library. + if (managedType == cmGeneratorTarget::ManagedType::Managed) { + continue; + } + const auto type = l.Target->GetType(); + + bool skip = false; + switch (type) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::INTERFACE_LIBRARY: + skip = true; + break; + case cmStateEnums::STATIC_LIBRARY: + skip = l.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); + break; + default: + break; + } + if (skip) { + continue; + } + } + + if (l.IsPath) { + std::string path = this->LocalGenerator->MaybeConvertToRelativePath( + currentBinDir, l.Value); + ConvertToWindowsSlash(path); + if (!cmVS10IsTargetsFile(l.Value)) { + libVec.push_back(path); + } + } else { + libVec.push_back(l.Value); + } + } + + cudaLinkOptions.AddFlag("AdditionalDependencies", libVec); + } + this->CudaLinkOptions[configName] = std::move(pOptions); return true; } @@ -3403,22 +3474,16 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( if (const char* nativeLibDirectoriesExpression = this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(nativeLibDirectoriesExpression); - std::string nativeLibDirs = - cge->Evaluate(this->LocalGenerator, configName); + std::string nativeLibDirs = cmGeneratorExpression::Evaluate( + nativeLibDirectoriesExpression, this->LocalGenerator, configName); e2.Element("NativeLibDirectories", nativeLibDirs); } if (const char* nativeLibDependenciesExpression = this->GeneratorTarget->GetProperty( "ANDROID_NATIVE_LIB_DEPENDENCIES")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(nativeLibDependenciesExpression); - std::string nativeLibDeps = - cge->Evaluate(this->LocalGenerator, configName); + std::string nativeLibDeps = cmGeneratorExpression::Evaluate( + nativeLibDependenciesExpression, this->LocalGenerator, configName); e2.Element("NativeLibDependencies", nativeLibDeps); } @@ -3429,11 +3494,8 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( if (const char* jarDirectoriesExpression = this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(jarDirectoriesExpression); - std::string jarDirectories = - cge->Evaluate(this->LocalGenerator, configName); + std::string jarDirectories = cmGeneratorExpression::Evaluate( + jarDirectoriesExpression, this->LocalGenerator, configName); e2.Element("JarDirectories", jarDirectories); } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 4dd92eb..a18a33d 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -142,7 +142,7 @@ private: std::string const& script, std::string const& additional_inputs, std::string const& outputs, - std::string const& comment); + std::string const& comment, bool symbolic); void WriteCustomRuleCSharp(Elem& e0, std::string const& config, std::string const& commandName, std::string const& script, diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 3e423e9..1139aa9 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -1,5 +1,7 @@ #include "cmVisualStudioGeneratorOptions.h" +#include <cm/iterator> + #include "cmAlgorithms.h" #include "cmLocalVisualStudioGenerator.h" #include "cmOutputConverter.h" @@ -269,8 +271,8 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags() } if (keyValue[1].front() == '\'' && keyValue[1].back() == '\'') { - keyValue[1] = - keyValue[1].substr(1, std::max(0, cm::isize(keyValue[1]) - 2)); + keyValue[1] = keyValue[1].substr( + 1, std::max(std::string::size_type(0), keyValue[1].length() - 2)); } if (keyValue[0] == "level") { diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index a396852..bd71546 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -2,9 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmWhileCommand.h" -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/string_view> + #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx index 2e4d00b..9d279ab 100644 --- a/Source/cmWorkerPool.cxx +++ b/Source/cmWorkerPool.cxx @@ -11,13 +11,13 @@ #include <algorithm> #include <array> #include <condition_variable> +#include <cstddef> #include <deque> #include <functional> #include <mutex> -#include <stddef.h> #include <thread> -#include "cm_memory.hxx" +#include <cm/memory> /** * @brief libuv pipe buffer class diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h index b541ce3..9179922 100644 --- a/Source/cmWorkerPool.h +++ b/Source/cmWorkerPool.h @@ -5,12 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stdint.h> +#include <cstdint> #include <string> #include <utility> #include <vector> -#include "cm_memory.hxx" +#include <cm/memory> // -- Types class cmWorkerPoolInternal; diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index 5009b16..264dd3f 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -2,13 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmWriteFileCommand.h" +#include "cm_sys_stat.h" + #include "cmsys/FStream.hxx" #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cm_sys_stat.h" // cmLibraryCommand bool cmWriteFileCommand(std::vector<std::string> const& args, @@ -19,7 +20,7 @@ bool cmWriteFileCommand(std::vector<std::string> const& args, return false; } std::string message; - std::vector<std::string>::const_iterator i = args.begin(); + auto i = args.begin(); std::string const& fileName = *i; bool overwrite = true; diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index 0552676..d9be3d2 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -106,8 +106,7 @@ public: bool HasComment() const { return (!this->Comment.empty()); } cmXCodeObject* GetObject(const char* name) const { - std::map<std::string, cmXCodeObject*>::const_iterator i = - this->ObjectAttributes.find(name); + auto const i = this->ObjectAttributes.find(name); if (i != this->ObjectAttributes.end()) { return i->second; } diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx index 4c6c35a..1f69032 100644 --- a/Source/cmXMLParser.cxx +++ b/Source/cmXMLParser.cxx @@ -4,10 +4,10 @@ #include "cm_expat.h" #include "cmsys/FStream.hxx" -#include <ctype.h> +#include <cctype> +#include <cstring> #include <iostream> #include <sstream> -#include <string.h> cmXMLParser::cmXMLParser() { diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx index d9bdc02..7c3b306 100644 --- a/Source/cmXMLSafe.cxx +++ b/Source/cmXMLSafe.cxx @@ -4,9 +4,9 @@ #include "cm_utf8.h" +#include <cstdio> +#include <cstring> #include <sstream> -#include <stdio.h> -#include <string.h> cmXMLSafe::cmXMLSafe(const char* s) : Data(s) diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h index a5b06af..c4103cc 100644 --- a/Source/cmXMLWriter.h +++ b/Source/cmXMLWriter.h @@ -77,14 +77,11 @@ private: void CloseStartElement(); private: - static cmXMLSafe SafeAttribute(const char* value) - { - return cmXMLSafe(value); - } + static cmXMLSafe SafeAttribute(const char* value) { return { value }; } static cmXMLSafe SafeAttribute(std::string const& value) { - return cmXMLSafe(value); + return { value }; } template <typename T> diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx index 2060584..b2cb9e6 100644 --- a/Source/cm_codecvt.hxx +++ b/Source/cm_codecvt.hxx @@ -5,8 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cwchar> #include <locale> -#include <wchar.h> class codecvt : public std::codecvt<char, char, mbstate_t> { diff --git a/Source/cm_get_date.h b/Source/cm_get_date.h index 6acf8de..38a690e 100644 --- a/Source/cm_get_date.h +++ b/Source/cm_get_date.h @@ -3,7 +3,7 @@ #ifndef cm_get_date_h #define cm_get_date_h -#include <time.h> +#include <time.h> /* NOLINT(modernize-deprecated-headers) */ #ifdef __cplusplus extern "C" { diff --git a/Source/cm_static_string_view.hxx b/Source/cm_static_string_view.hxx index 1bef0c6..8351cd7 100644 --- a/Source/cm_static_string_view.hxx +++ b/Source/cm_static_string_view.hxx @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cm_string_view.hxx" +#include <cm/string_view> #include <cstddef> diff --git a/Source/cm_sys_stat.h b/Source/cm_sys_stat.h index d3b9ef2..eb874c7 100644 --- a/Source/cm_sys_stat.h +++ b/Source/cm_sys_stat.h @@ -14,6 +14,6 @@ using gid_t = unsigned short; #include <sys/types.h> // include sys/stat.h after sys/types.h -#include <sys/stat.h> +#include <sys/stat.h> // IWYU pragma: export #endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index ace9198..96d903e 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2,7 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmake.h" -#include "cm_memory.hxx" +#include <cm/memory> +#include <cm/string_view> +#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW) +# include <cm/iterator> +#endif + +#include "cm_sys_stat.h" #include "cmAlgorithms.h" #include "cmCommands.h" @@ -28,8 +34,6 @@ #include "cmUtils.hxx" #include "cmVersionConfig.h" #include "cmWorkingDirectory.h" -#include "cm_string_view.hxx" -#include "cm_sys_stat.h" #if !defined(CMAKE_BOOTSTRAP) # include "cm_jsoncpp_writer.h" @@ -105,12 +109,12 @@ #include "cmsys/Glob.hxx" #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include <cstdio> +#include <cstdlib> #include <cstring> #include <initializer_list> #include <iostream> #include <sstream> -#include <stdio.h> -#include <stdlib.h> #include <utility> namespace { @@ -1081,20 +1085,18 @@ createExtraGenerator( const std::vector<std::string> generators = i->GetSupportedGlobalGenerators(); if (i->GetName() == name) { // Match aliases - return std::make_pair(i->CreateExternalMakefileProjectGenerator(), - generators.at(0)); + return { i->CreateExternalMakefileProjectGenerator(), generators.at(0) }; } for (std::string const& g : generators) { const std::string fullName = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( g, i->GetName()); if (fullName == name) { - return std::make_pair(i->CreateExternalMakefileProjectGenerator(), g); + return { i->CreateExternalMakefileProjectGenerator(), g }; } } } - return std::make_pair( - static_cast<cmExternalMakefileProjectGenerator*>(nullptr), name); + return { nullptr, name }; } cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname) @@ -1273,8 +1275,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) << "Configure will be re-run and you may have to reset some variables.\n" << "The following variables have changed:\n"; /* clang-format on */ - for (std::vector<std::string>::iterator i = argsSplit.begin(); - i != argsSplit.end(); ++i) { + for (auto i = argsSplit.begin(); i != argsSplit.end(); ++i) { SaveCacheEntry save; save.key = *i; warning << *i << "= "; @@ -2190,7 +2191,7 @@ int cmake::CheckBuildSystem() } // Find the newest dependency. - std::vector<std::string>::iterator dep = depends.begin(); + auto dep = depends.begin(); std::string dep_newest = *dep++; for (; dep != depends.end(); ++dep) { int result = 0; @@ -2208,7 +2209,7 @@ int cmake::CheckBuildSystem() } // Find the oldest output. - std::vector<std::string>::iterator out = outputs.begin(); + auto out = outputs.begin(); std::string out_oldest = *out++; for (; out != outputs.end(); ++out) { int result = 0; @@ -2310,8 +2311,7 @@ bool cmake::GetPropertyAsBool(const std::string& prop) cmInstalledFile* cmake::GetOrCreateInstalledFile(cmMakefile* mf, const std::string& name) { - std::map<std::string, cmInstalledFile>::iterator i = - this->InstalledFiles.find(name); + auto i = this->InstalledFiles.find(name); if (i != this->InstalledFiles.end()) { cmInstalledFile& file = i->second; @@ -2324,8 +2324,7 @@ cmInstalledFile* cmake::GetOrCreateInstalledFile(cmMakefile* mf, cmInstalledFile const* cmake::GetInstalledFile(const std::string& name) const { - std::map<std::string, cmInstalledFile>::const_iterator i = - this->InstalledFiles.find(name); + auto i = this->InstalledFiles.find(name); if (i != this->InstalledFiles.end()) { cmInstalledFile const& file = i->second; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 2b51a2a..252c6d6 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -25,10 +25,10 @@ #endif #include <cassert> +#include <cctype> #include <climits> -#include <ctype.h> +#include <cstring> #include <iostream> -#include <string.h> #include <string> #include <vector> diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index a79a2ff..211fd4c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -39,13 +39,13 @@ #include "cmsys/Process.h" #include "cmsys/Terminal.h" #include <array> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> #include <iostream> #include <memory> #include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> #include <utility> class cmConnection; @@ -562,19 +562,36 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) "objlistfile [-nm=nm-path]\n"; return 1; } - FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); - if (!fout) { - std::cerr << "could not open output .def file: " << args[2].c_str() - << "\n"; - return 1; - } cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); if (!fin) { std::cerr << "could not open object list file: " << args[3].c_str() << "\n"; return 1; } - std::string file; + std::vector<std::string> files; + { + std::string file; + cmFileTime outTime; + bool outValid = outTime.Load(args[2]); + while (cmSystemTools::GetLineFromStream(fin, file)) { + files.push_back(file); + if (outValid) { + cmFileTime inTime; + outValid = inTime.Load(file) && inTime.Older(outTime); + } + } + if (outValid) { + // The def file already exists and all input files are older than the + // existing def file. + return 0; + } + } + FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); + if (!fout) { + std::cerr << "could not open output .def file: " << args[2].c_str() + << "\n"; + return 1; + } bindexplib deffile; if (args.size() >= 5) { auto a = args[4]; @@ -585,7 +602,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) std::cerr << "unknown argument: " << a << "\n"; } } - while (cmSystemTools::GetLineFromStream(fin, file)) { + for (auto const& file : files) { std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); if (cmSystemTools::LowerCase(ext) == ".def") { if (!deffile.AddDefinitionFile(file.c_str())) { @@ -1713,7 +1730,7 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg, { // Parse our own arguments. std::string intDir; - std::vector<std::string>::const_iterator arg = argBeg; + auto arg = argBeg; while (arg != argEnd && cmHasLiteralPrefix(*arg, "-")) { if (*arg == "--") { ++arg; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index a69ba15..7be6746 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -11,8 +11,8 @@ #if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) # include "cmsys/ConsoleBuf.hxx" #endif +#include <cstring> #include <iostream> -#include <string.h> #include <string> #include <vector> diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index dc9f01d..3fd1955 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -67,8 +67,8 @@ class CommandLineArgumentsInternal { public: CommandLineArgumentsInternal() - : UnknownArgumentCallback{ KWSYS_NULLPTR } - , ClientData{ KWSYS_NULLPTR } + : UnknownArgumentCallback{ nullptr } + , ClientData{ nullptr } , LastArgument{ 0 } { } @@ -187,7 +187,7 @@ int CommandLineArguments::Parse() switch (cs->ArgumentType) { case NO_ARGUMENT: // No value - if (!this->PopulateVariable(cs, KWSYS_NULLPTR)) { + if (!this->PopulateVariable(cs, nullptr)) { return 0; } break; @@ -340,7 +340,7 @@ void CommandLineArguments::AddCallback(const char* argument, s.Callback = callback; s.CallData = call_data; s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE; - s.Variable = KWSYS_NULLPTR; + s.Variable = nullptr; s.Help = help; this->Internals->Callbacks[argument] = s; @@ -355,8 +355,8 @@ void CommandLineArguments::AddArgument(const char* argument, CommandLineArgumentsCallbackStructure s; s.Argument = argument; s.ArgumentType = type; - s.Callback = KWSYS_NULLPTR; - s.CallData = KWSYS_NULLPTR; + s.Callback = nullptr; + s.CallData = nullptr; s.VariableType = vtype; s.Variable = variable; s.Help = help; @@ -427,7 +427,7 @@ const char* CommandLineArguments::GetHelp(const char* arg) CommandLineArguments::Internal::CallbacksMap::iterator it = this->Internals->Callbacks.find(arg); if (it == this->Internals->Callbacks.end()) { - return KWSYS_NULLPTR; + return nullptr; } // Since several arguments may point to the same argument, find the one this @@ -621,7 +621,7 @@ void CommandLineArguments::PopulateVariable(bool* variable, void CommandLineArguments::PopulateVariable(int* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; *variable = static_cast<int>(strtol(value.c_str(), &res, 10)); // if ( res && *res ) // { @@ -632,7 +632,7 @@ void CommandLineArguments::PopulateVariable(int* variable, void CommandLineArguments::PopulateVariable(double* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; *variable = strtod(value.c_str(), &res); // if ( res && *res ) // { @@ -669,7 +669,7 @@ void CommandLineArguments::PopulateVariable(std::vector<bool>* variable, void CommandLineArguments::PopulateVariable(std::vector<int>* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10))); // if ( res && *res ) // { @@ -680,7 +680,7 @@ void CommandLineArguments::PopulateVariable(std::vector<int>* variable, void CommandLineArguments::PopulateVariable(std::vector<double>* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; variable->push_back(strtod(value.c_str(), &res)); // if ( res && *res ) // { diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in index 92ffea3..29a2dd1 100644 --- a/Source/kwsys/Configure.hxx.in +++ b/Source/kwsys/Configure.hxx.in @@ -58,7 +58,6 @@ # define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \ @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H # define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH -# define KWSYS_NULLPTR @KWSYS_NAMESPACE@_NULLPTR # define KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP \ @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP #endif diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in index 73a1efb..49dbdf7 100644 --- a/Source/kwsys/ConsoleBuf.hxx.in +++ b/Source/kwsys/ConsoleBuf.hxx.in @@ -116,7 +116,7 @@ protected: DWORD charsWritten; success = ::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(), - &charsWritten, NULL) == 0 + &charsWritten, nullptr) == 0 ? false : true; } else { @@ -124,8 +124,9 @@ protected: std::string buffer; success = encodeOutputBuffer(wbuffer, buffer); if (success) { - success = ::WriteFile(m_hOutput, buffer.c_str(), - (DWORD)buffer.size(), &bytesWritten, NULL) == 0 + success = + ::WriteFile(m_hOutput, buffer.c_str(), (DWORD)buffer.size(), + &bytesWritten, nullptr) == 0 ? false : true; } @@ -152,7 +153,7 @@ protected: DWORD charsRead; if (ReadConsoleW(m_hInput, wbuffer, (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead, - NULL) == 0 || + nullptr) == 0 || charsRead == 0) { _setg(true); return Traits::eof(); @@ -168,7 +169,7 @@ protected: return Traits::eof(); } char* buffer = new char[size.LowPart]; - while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, NULL) == + while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, nullptr) == 0) { if (GetLastError() == ERROR_MORE_DATA) { strbuffer += std::string(buffer, bytesRead); @@ -327,11 +328,12 @@ private: } const int length = WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), NULL, 0, NULL, NULL); + (int)wbuffer.size(), nullptr, 0, nullptr, nullptr); char* buf = new char[length]; const bool success = WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), buf, length, NULL, NULL) > 0 + (int)wbuffer.size(), buf, length, nullptr, + nullptr) > 0 ? true : false; buffer = std::string(buf, length); @@ -356,7 +358,7 @@ private: length -= BOMsize; } const size_t wlength = static_cast<size_t>(MultiByteToWideChar( - actualCodepage, 0, data, static_cast<int>(length), NULL, 0)); + actualCodepage, 0, data, static_cast<int>(length), nullptr, 0)); wchar_t* wbuf = new wchar_t[wlength]; const bool success = MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length), diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index 59530a4..e379182 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -48,7 +48,7 @@ unsigned long Directory::GetNumberOfFiles() const const char* Directory::GetFile(unsigned long dindex) const { if (dindex >= this->Internal->Files.size()) { - return KWSYS_NULLPTR; + return nullptr; } return this->Internal->Files[dindex].c_str(); } diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx index b93a215..a4b8641 100644 --- a/Source/kwsys/DynamicLoader.cxx +++ b/Source/kwsys/DynamicLoader.cxx @@ -223,15 +223,15 @@ namespace KWSYS_NAMESPACE { DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname, int flags) { - CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, NULL); + CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, nullptr); DWORD llFlags = 0; if (flags & SearchBesideLibrary) { llFlags |= LOAD_WITH_ALTERED_SEARCH_PATH; } - return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), NULL, - llFlags); + return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), + nullptr, llFlags); } int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) @@ -289,9 +289,9 @@ const char* DynamicLoader::LastError() DWORD error = GetLastError(); DWORD length = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, NULL); + lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, nullptr); static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1]; @@ -305,7 +305,7 @@ const char* DynamicLoader::LastError() } if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str, - DYNLOAD_ERROR_BUFFER_SIZE, NULL, NULL)) { + DYNLOAD_ERROR_BUFFER_SIZE, nullptr, nullptr)) { /* WideCharToMultiByte failed. Use a default message. */ _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE, "DynamicLoader encountered error 0x%X. " @@ -372,7 +372,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::SymbolPointer psym; } result; - result.psym = NULL; + result.psym = nullptr; if (!lib) { last_dynamic_err = B_BAD_VALUE; @@ -384,7 +384,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid); if (rc != B_OK) { last_dynamic_err = rc; - result.psym = NULL; + result.psym = nullptr; } } return result.psym; @@ -412,7 +412,7 @@ namespace KWSYS_NAMESPACE { DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname, int flags) { - CHECK_OPEN_FLAGS(flags, 0, NULL); + CHECK_OPEN_FLAGS(flags, 0, nullptr); char* name = (char*)calloc(1, libname.size() + 1); dld_init(program_invocation_name); @@ -458,7 +458,7 @@ namespace KWSYS_NAMESPACE { DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname, int flags) { - CHECK_OPEN_FLAGS(flags, 0, NULL); + CHECK_OPEN_FLAGS(flags, 0, nullptr); return dlopen(libname.c_str(), RTLD_LAZY); } diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx index 251deef..4593c92 100644 --- a/Source/kwsys/EncodingCXX.cxx +++ b/Source/kwsys/EncodingCXX.cxx @@ -65,7 +65,7 @@ Encoding::CommandLineArguments::CommandLineArguments(int ac, for (int i = 0; i < ac; i++) { this->argv_[i] = strdup(av[i]); } - this->argv_[ac] = KWSYS_NULLPTR; + this->argv_[ac] = nullptr; } Encoding::CommandLineArguments::CommandLineArguments(int ac, @@ -75,7 +75,7 @@ Encoding::CommandLineArguments::CommandLineArguments(int ac, for (int i = 0; i < ac; i++) { this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]); } - this->argv_[ac] = KWSYS_NULLPTR; + this->argv_[ac] = nullptr; } Encoding::CommandLineArguments::~CommandLineArguments() @@ -90,7 +90,7 @@ Encoding::CommandLineArguments::CommandLineArguments( { this->argv_.resize(other.argv_.size()); for (size_t i = 0; i < this->argv_.size(); i++) { - this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : KWSYS_NULLPTR; + this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr; } } @@ -105,7 +105,7 @@ Encoding::CommandLineArguments& Encoding::CommandLineArguments::operator=( this->argv_.resize(other.argv_.size()); for (i = 0; i < this->argv_.size(); i++) { - this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : KWSYS_NULLPTR; + this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr; } } @@ -128,8 +128,9 @@ std::wstring Encoding::ToWide(const std::string& str) { std::wstring wstr; # if defined(_WIN32) - const int wlength = MultiByteToWideChar( - KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), int(str.size()), NULL, 0); + const int wlength = + MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), + int(str.size()), nullptr, 0); if (wlength > 0) { wchar_t* wdata = new wchar_t[wlength]; int r = MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), @@ -162,12 +163,12 @@ std::string Encoding::ToNarrow(const std::wstring& str) # if defined(_WIN32) int length = WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(), - int(str.size()), NULL, 0, NULL, NULL); + int(str.size()), nullptr, 0, nullptr, nullptr); if (length > 0) { char* data = new char[length]; int r = WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(), - int(str.size()), data, length, NULL, NULL); + int(str.size()), data, length, nullptr, nullptr); if (r > 0) { nstr = std::string(data, length); } @@ -193,7 +194,7 @@ std::string Encoding::ToNarrow(const std::wstring& str) std::wstring Encoding::ToWide(const char* cstr) { std::wstring wstr; - size_t length = kwsysEncoding_mbstowcs(KWSYS_NULLPTR, cstr, 0) + 1; + size_t length = kwsysEncoding_mbstowcs(nullptr, cstr, 0) + 1; if (length > 0) { std::vector<wchar_t> wchars(length); if (kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) { @@ -206,7 +207,7 @@ std::wstring Encoding::ToWide(const char* cstr) std::string Encoding::ToNarrow(const wchar_t* wcstr) { std::string str; - size_t length = kwsysEncoding_wcstombs(KWSYS_NULLPTR, wcstr, 0) + 1; + size_t length = kwsysEncoding_wcstombs(nullptr, wcstr, 0) + 1; if (length > 0) { std::vector<char> chars(length); if (kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) { @@ -227,9 +228,9 @@ std::wstring Encoding::ToWindowsExtendedPath(std::string const& source) /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that * won't return a large enough buffer size if the input is too small */ - wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3; + wfull_len = GetFullPathNameW(wsource.c_str(), 0, nullptr, nullptr) + 3; std::vector<wchar_t> wfull(wfull_len); - GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL); + GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], nullptr); /* This should get the correct size without any extra padding from the * previous size workaround. */ diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 829c138..34bb0d0 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -431,7 +431,7 @@ void Glob::SetRelative(const char* dir) const char* Glob::GetRelative() { if (this->Relative.empty()) { - return KWSYS_NULLPTR; + return nullptr; } return this->Relative.c_str(); } diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in index 4c3bde1..170766f 100644 --- a/Source/kwsys/Glob.hxx.in +++ b/Source/kwsys/Glob.hxx.in @@ -54,7 +54,7 @@ public: ~Glob(); //! Find all files that match the pattern. - bool FindFiles(const std::string& inexpr, GlobMessages* messages = 0); + bool FindFiles(const std::string& inexpr, GlobMessages* messages = nullptr); //! Return the list of files that matched. std::vector<std::string>& GetFiles(); diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx index 3e10765..5e6f8da 100644 --- a/Source/kwsys/RegularExpression.cxx +++ b/Source/kwsys/RegularExpression.cxx @@ -37,7 +37,7 @@ namespace KWSYS_NAMESPACE { RegularExpression::RegularExpression(const RegularExpression& rxp) { if (!rxp.program) { - this->program = KWSYS_NULLPTR; + this->program = nullptr; return; } int ind; @@ -48,7 +48,7 @@ RegularExpression::RegularExpression(const RegularExpression& rxp) // Copy pointers into last successful "find" operation this->regmatch = rxp.regmatch; this->regmust = rxp.regmust; // Copy field - if (rxp.regmust != KWSYS_NULLPTR) { + if (rxp.regmust != nullptr) { char* dum = rxp.program; ind = 0; while (dum != rxp.regmust) { @@ -69,7 +69,7 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp) return *this; } if (!rxp.program) { - this->program = KWSYS_NULLPTR; + this->program = nullptr; return *this; } int ind; @@ -81,7 +81,7 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp) // Copy pointers into last successful "find" operation this->regmatch = rxp.regmatch; this->regmust = rxp.regmust; // Copy field - if (rxp.regmust != KWSYS_NULLPTR) { + if (rxp.regmust != nullptr) { char* dum = rxp.program; ind = 0; while (dum != rxp.regmust) { @@ -164,8 +164,8 @@ bool RegularExpression::deep_equal(const RegularExpression& rxp) const * * regstart char that must begin a match; '\0' if none obvious * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or NULL - * regmlen length of regmust string + * regmust string (pointer into program) that match must include, or + * nullptr regmlen length of regmust string * * Regstart and reganch permit very fast decisions on suitable starting points * for a match, cutting down the work a lot. Regmust permits fast rejection @@ -339,7 +339,7 @@ bool RegularExpression::compile(const char* exp) const char* longest; int flags; - if (exp == KWSYS_NULLPTR) { + if (exp == nullptr) { // RAISE Error, SYM(RegularExpression), SYM(No_Expr), printf("RegularExpression::compile(): No expression supplied.\n"); return false; @@ -367,13 +367,13 @@ bool RegularExpression::compile(const char* exp) // Allocate space. //#ifndef _WIN32 - if (this->program != KWSYS_NULLPTR) + if (this->program != nullptr) delete[] this->program; //#endif this->program = new char[comp.regsize]; this->progsize = static_cast<int>(comp.regsize); - if (this->program == KWSYS_NULLPTR) { + if (this->program == nullptr) { // RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory), printf("RegularExpression::compile(): Out of memory.\n"); return false; @@ -389,7 +389,7 @@ bool RegularExpression::compile(const char* exp) // Dig out information for optimizations. this->regstart = '\0'; // Worst-case defaults. this->reganch = 0; - this->regmust = KWSYS_NULLPTR; + this->regmust = nullptr; this->regmlen = 0; scan = this->program + 1; // First BRANCH. if (OP(regnext(scan)) == END) { // Only one top-level choice. @@ -410,9 +410,9 @@ bool RegularExpression::compile(const char* exp) // absence of others. // if (flags & SPSTART) { - longest = KWSYS_NULLPTR; + longest = nullptr; size_t len = 0; - for (; scan != KWSYS_NULLPTR; scan = regnext(scan)) + for (; scan != nullptr; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); len = strlen(OPERAND(scan)); @@ -448,19 +448,19 @@ char* RegExpCompile::reg(int paren, int* flagp) if (regnpar >= RegularExpressionMatch::NSUBEXP) { // RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens), printf("RegularExpression::compile(): Too many parentheses.\n"); - return KWSYS_NULLPTR; + return nullptr; } parno = regnpar; regnpar++; ret = regnode(static_cast<char>(OPEN + parno)); } else - ret = KWSYS_NULLPTR; + ret = nullptr; // Pick up the branches, linking them together. br = regbranch(&flags); - if (br == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); - if (ret != KWSYS_NULLPTR) + if (br == nullptr) + return (nullptr); + if (ret != nullptr) regtail(ret, br); // OPEN -> first. else ret = br; @@ -470,8 +470,8 @@ char* RegExpCompile::reg(int paren, int* flagp) while (*regparse == '|') { regparse++; br = regbranch(&flags); - if (br == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (br == nullptr) + return (nullptr); regtail(ret, br); // BRANCH -> BRANCH. if (!(flags & HASWIDTH)) *flagp &= ~HASWIDTH; @@ -483,23 +483,23 @@ char* RegExpCompile::reg(int paren, int* flagp) regtail(ret, ender); // Hook the tails of the branches to the closing node. - for (br = ret; br != KWSYS_NULLPTR; br = regnext(br)) + for (br = ret; br != nullptr; br = regnext(br)) regoptail(br, ender); // Check for proper termination. if (paren && *regparse++ != ')') { // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens), printf("RegularExpression::compile(): Unmatched parentheses.\n"); - return KWSYS_NULLPTR; + return nullptr; } else if (!paren && *regparse != '\0') { if (*regparse == ')') { // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens), printf("RegularExpression::compile(): Unmatched parentheses.\n"); - return KWSYS_NULLPTR; + return nullptr; } else { // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), printf("RegularExpression::compile(): Internal error.\n"); - return KWSYS_NULLPTR; + return nullptr; } // NOTREACHED } @@ -521,19 +521,19 @@ char* RegExpCompile::regbranch(int* flagp) *flagp = WORST; // Tentatively. ret = regnode(BRANCH); - chain = KWSYS_NULLPTR; + chain = nullptr; while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { latest = regpiece(&flags); - if (latest == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (latest == nullptr) + return (nullptr); *flagp |= flags & HASWIDTH; - if (chain == KWSYS_NULLPTR) // First piece. + if (chain == nullptr) // First piece. *flagp |= flags & SPSTART; else regtail(chain, latest); chain = latest; } - if (chain == KWSYS_NULLPTR) // Loop ran zero times. + if (chain == nullptr) // Loop ran zero times. regnode(NOTHING); return (ret); @@ -556,8 +556,8 @@ char* RegExpCompile::regpiece(int* flagp) int flags; ret = regatom(&flags); - if (ret == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (ret == nullptr) + return (nullptr); op = *regparse; if (!ISMULT(op)) { @@ -568,7 +568,7 @@ char* RegExpCompile::regpiece(int* flagp) if (!(flags & HASWIDTH) && op != '?') { // RAISE Error, SYM(RegularExpression), SYM(Empty_Operand), printf("RegularExpression::compile() : *+ operand could be empty.\n"); - return KWSYS_NULLPTR; + return nullptr; } *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH); @@ -602,7 +602,7 @@ char* RegExpCompile::regpiece(int* flagp) if (ISMULT(*regparse)) { // RAISE Error, SYM(RegularExpression), SYM(Nested_Operand), printf("RegularExpression::compile(): Nested *?+.\n"); - return KWSYS_NULLPTR; + return nullptr; } return (ret); } @@ -655,7 +655,7 @@ char* RegExpCompile::regatom(int* flagp) if (rxpclass > rxpclassend + 1) { // RAISE Error, SYM(RegularExpression), SYM(Invalid_Range), printf("RegularExpression::compile(): Invalid range in [].\n"); - return KWSYS_NULLPTR; + return nullptr; } for (; rxpclass <= rxpclassend; rxpclass++) regc(static_cast<char>(rxpclass)); @@ -668,15 +668,15 @@ char* RegExpCompile::regatom(int* flagp) if (*regparse != ']') { // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket), printf("RegularExpression::compile(): Unmatched [].\n"); - return KWSYS_NULLPTR; + return nullptr; } regparse++; *flagp |= HASWIDTH | SIMPLE; } break; case '(': ret = reg(1, &flags); - if (ret == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (ret == nullptr) + return (nullptr); *flagp |= flags & (HASWIDTH | SPSTART); break; case '\0': @@ -684,18 +684,18 @@ char* RegExpCompile::regatom(int* flagp) case ')': // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), printf("RegularExpression::compile(): Internal error.\n"); // Never here - return KWSYS_NULLPTR; + return nullptr; case '?': case '+': case '*': // RAISE Error, SYM(RegularExpression), SYM(No_Operand), printf("RegularExpression::compile(): ?+* follows nothing.\n"); - return KWSYS_NULLPTR; + return nullptr; case '\\': if (*regparse == '\0') { // RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash), printf("RegularExpression::compile(): Trailing backslash.\n"); - return KWSYS_NULLPTR; + return nullptr; } ret = regnode(EXACTLY); regc(*regparse++); @@ -711,7 +711,7 @@ char* RegExpCompile::regatom(int* flagp) if (len <= 0) { // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), printf("RegularExpression::compile(): Internal error.\n"); - return KWSYS_NULLPTR; + return nullptr; } ender = *(regparse + len); if (len > 1 && ISMULT(ender)) @@ -809,7 +809,7 @@ void RegExpCompile::regtail(char* p, const char* val) scan = p; for (;;) { temp = regnext(scan); - if (temp == KWSYS_NULLPTR) + if (temp == nullptr) break; scan = temp; } @@ -828,7 +828,7 @@ void RegExpCompile::regtail(char* p, const char* val) void RegExpCompile::regoptail(char* p, const char* val) { // "Operandless" and "op != BRANCH" are synonymous in practice. - if (p == KWSYS_NULLPTR || p == regdummyptr || OP(p) != BRANCH) + if (p == nullptr || p == regdummyptr || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } @@ -878,14 +878,14 @@ bool RegularExpression::find(char const* string, } // If there is a "must appear" string, look for it. - if (this->regmust != KWSYS_NULLPTR) { + if (this->regmust != nullptr) { s = string; - while ((s = strchr(s, this->regmust[0])) != KWSYS_NULLPTR) { + while ((s = strchr(s, this->regmust[0])) != nullptr) { if (strncmp(s, this->regmust, this->regmlen) == 0) break; // Found it. s++; } - if (s == KWSYS_NULLPTR) // Not present. + if (s == nullptr) // Not present. return false; } @@ -903,7 +903,7 @@ bool RegularExpression::find(char const* string, s = string; if (this->regstart != '\0') // We know what char it must start with. - while ((s = strchr(s, this->regstart)) != KWSYS_NULLPTR) { + while ((s = strchr(s, this->regstart)) != nullptr) { if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program)) return true; s++; @@ -937,8 +937,8 @@ int RegExpFind::regtry(const char* string, const char** start, sp1 = start; ep = end; for (i = RegularExpressionMatch::NSUBEXP; i > 0; i--) { - *sp1++ = KWSYS_NULLPTR; - *ep++ = KWSYS_NULLPTR; + *sp1++ = nullptr; + *ep++ = nullptr; } if (regmatch(prog + 1)) { start[0] = string; @@ -966,7 +966,7 @@ int RegExpFind::regmatch(const char* prog) scan = prog; - while (scan != KWSYS_NULLPTR) { + while (scan != nullptr) { next = regnext(scan); @@ -998,14 +998,12 @@ int RegExpFind::regmatch(const char* prog) reginput += len; } break; case ANYOF: - if (*reginput == '\0' || - strchr(OPERAND(scan), *reginput) == KWSYS_NULLPTR) + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == nullptr) return (0); reginput++; break; case ANYBUT: - if (*reginput == '\0' || - strchr(OPERAND(scan), *reginput) != KWSYS_NULLPTR) + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != nullptr) return (0); reginput++; break; @@ -1034,7 +1032,7 @@ int RegExpFind::regmatch(const char* prog) // Don't set startp if some later invocation of the // same parentheses already has. // - if (regstartp[no] == KWSYS_NULLPTR) + if (regstartp[no] == nullptr) regstartp[no] = save; return (1); } else @@ -1062,7 +1060,7 @@ int RegExpFind::regmatch(const char* prog) // Don't set endp if some later invocation of the // same parentheses already has. // - if (regendp[no] == KWSYS_NULLPTR) + if (regendp[no] == nullptr) regendp[no] = save; return (1); } else @@ -1082,7 +1080,7 @@ int RegExpFind::regmatch(const char* prog) return (1); reginput = save; scan = regnext(scan); - } while (scan != KWSYS_NULLPTR && OP(scan) == BRANCH); + } while (scan != nullptr && OP(scan) == BRANCH); return (0); // NOTREACHED } @@ -1160,13 +1158,13 @@ int RegExpFind::regrepeat(const char* p) } break; case ANYOF: - while (*scan != '\0' && strchr(opnd, *scan) != KWSYS_NULLPTR) { + while (*scan != '\0' && strchr(opnd, *scan) != nullptr) { count++; scan++; } break; case ANYBUT: - while (*scan != '\0' && strchr(opnd, *scan) == KWSYS_NULLPTR) { + while (*scan != '\0' && strchr(opnd, *scan) == nullptr) { count++; scan++; } @@ -1188,11 +1186,11 @@ static const char* regnext(const char* p) int offset; if (p == regdummyptr) - return (KWSYS_NULLPTR); + return (nullptr); offset = NEXT(p); if (offset == 0) - return (KWSYS_NULLPTR); + return (nullptr); if (OP(p) == BACK) return (p - offset); @@ -1205,11 +1203,11 @@ static char* regnext(char* p) int offset; if (p == regdummyptr) - return (KWSYS_NULLPTR); + return (nullptr); offset = NEXT(p); if (offset == 0) - return (KWSYS_NULLPTR); + return (nullptr); if (OP(p) == BACK) return (p - offset); diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in index ed86418..df7eb45 100644 --- a/Source/kwsys/RegularExpression.hxx.in +++ b/Source/kwsys/RegularExpression.hxx.in @@ -71,9 +71,9 @@ private: */ inline RegularExpressionMatch::RegularExpressionMatch() { - startp[0] = 0; - endp[0] = 0; - searchstring = 0; + startp[0] = nullptr; + endp[0] = nullptr; + searchstring = nullptr; } /** @@ -81,7 +81,7 @@ inline RegularExpressionMatch::RegularExpressionMatch() */ inline bool RegularExpressionMatch::isValid() const { - return (this->startp[0] != 0); + return (this->startp[0] != nullptr); } /** @@ -89,9 +89,9 @@ inline bool RegularExpressionMatch::isValid() const */ inline void RegularExpressionMatch::clear() { - startp[0] = 0; - endp[0] = 0; - searchstring = 0; + startp[0] = nullptr; + endp[0] = nullptr; + searchstring = nullptr; } /** @@ -135,7 +135,7 @@ inline std::string::size_type RegularExpressionMatch::end(int n) const */ inline std::string RegularExpressionMatch::match(int n) const { - if (this->startp[n] == 0) { + if (this->startp[n] == nullptr) { return std::string(); } else { return std::string( @@ -230,10 +230,11 @@ inline std::string RegularExpressionMatch::match(int n) const * into the object's private data fields. The == and != operators only check * the to see if the compiled regular expression is the same, and the * deep_equal functions also checks to see if the start and end pointers are - * the same. The is_valid function returns false if program is set to NULL, - * (i.e. there is no valid compiled expression). The set_invalid function - * sets the program to NULL (Warning: this deletes the compiled expression). - * The following examples may help clarify regular expression usage: + * the same. The is_valid function returns false if program is set to + * nullptr, (i.e. there is no valid compiled expression). The set_invalid + * function sets the program to nullptr (Warning: this deletes the compiled + * expression). The following examples may help clarify regular expression + * usage: * * * The regular expression "^hello" matches a "hello" only at the * beginning of a line. It would match "hello there" but not "hi, @@ -288,7 +289,7 @@ class @KWSYS_NAMESPACE@_EXPORT RegularExpression { public: /** - * Instantiate RegularExpression with program=NULL. + * Instantiate RegularExpression with program=nullptr. */ inline RegularExpression(); @@ -410,7 +411,7 @@ inline RegularExpression::RegularExpression() : regstart{} , reganch{} , regmust{} - , program{ 0 } + , program{ nullptr } , progsize{} { } @@ -423,7 +424,7 @@ inline RegularExpression::RegularExpression(const char* s) : regstart{} , reganch{} , regmust{} - , program{ 0 } + , program{ nullptr } , progsize{} { if (s) { @@ -439,7 +440,7 @@ inline RegularExpression::RegularExpression(const std::string& s) : regstart{} , reganch{} , regmust{} - , program{ 0 } + , program{ nullptr } , progsize{} { this->compile(s); @@ -545,7 +546,7 @@ inline bool RegularExpression::operator!=(const RegularExpression& r) const */ inline bool RegularExpression::is_valid() const { - return (this->program != 0); + return (this->program != nullptr); } inline void RegularExpression::set_invalid() @@ -553,7 +554,7 @@ inline void RegularExpression::set_invalid() //#ifndef _WIN32 delete[] this->program; //#endif - this->program = 0; + this->program = nullptr; } } // namespace @KWSYS_NAMESPACE@ diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 7dc6cf4..6ec6e48 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -847,31 +847,16 @@ void SystemInformation::RunMemoryCheck() // SystemInformationImplementation starts here -#define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x -#define TLBCACHE_INFO_UNITS (15) -#define CLASSICAL_CPU_FREQ_LOOP 10000000 -#define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 - -// Status Flag -#define HT_NOT_CAPABLE 0 -#define HT_ENABLED 1 -#define HT_DISABLED 2 -#define HT_SUPPORTED_NOT_ENABLED 3 -#define HT_CANNOT_DETECT 4 - -// EDX[28] Bit 28 is set if HT is supported -#define HT_BIT 0x10000000 - -// EAX[11:8] Bit 8-11 contains family processor ID. -#define FAMILY_ID 0x0F00 -#define PENTIUM4_ID 0x0F00 -// EAX[23:20] Bit 20-23 contains extended family processor ID -#define EXT_FAMILY_ID 0x0F00000 -// EBX[23:16] Bit 16-23 in ebx contains the number of logical -#define NUM_LOGICAL_BITS 0x00FF0000 -// processors per physical processor when execute cpuid with -// eax set to 1 -// EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique +#if USE_CPUID +# define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x +# define TLBCACHE_INFO_UNITS (15) +#endif + +#if USE_ASM_INSTRUCTIONS +# define CLASSICAL_CPU_FREQ_LOOP 10000000 +# define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 +#endif + #define INITIAL_APIC_ID_BITS 0xFF000000 // initial APIC ID for the processor this code is running on. // Default value = 0xff if HT is not supported @@ -888,7 +873,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines) char buf[bufSize] = { '\0' }; while (!feof(file) && !ferror(file)) { errno = 0; - if (fgets(buf, bufSize, file) == KWSYS_NULLPTR) { + if (fgets(buf, bufSize, file) == nullptr) { if (ferror(file) && (errno == EINTR)) { clearerr(file); } @@ -952,7 +937,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values) return -1; } int i = 0; - while (fieldNames[i] != NULL) { + while (fieldNames[i] != nullptr) { int ierr = NameValue(fields, fieldNames[i], values[i]); if (ierr) { return -(i + 2); @@ -966,7 +951,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values) template <typename T> int GetFieldFromFile(const char* fileName, const char* fieldName, T& value) { - const char* fieldNames[2] = { fieldName, NULL }; + const char* fieldNames[2] = { fieldName, nullptr }; T values[1] = { T(0) }; int ierr = GetFieldsFromFile(fileName, fieldNames, values); if (ierr) { @@ -984,7 +969,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames, T* values) { FILE* file = popen(command, "r"); - if (file == KWSYS_NULLPTR) { + if (file == nullptr) { return -1; } std::vector<std::string> fields; @@ -994,7 +979,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames, return -1; } int i = 0; - while (fieldNames[i] != KWSYS_NULLPTR) { + while (fieldNames[i] != nullptr) { int ierr = NameValue(fields, fieldNames[i], values[i]); if (ierr) { return -(i + 2); @@ -1030,8 +1015,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGFPE: - oss << "Caught SIGFPE at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGFPE at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { # if defined(FPE_INTDIV) @@ -1079,8 +1063,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGSEGV: - oss << "Caught SIGSEGV at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGSEGV at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case SEGV_MAPERR: @@ -1098,8 +1081,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGBUS: - oss << "Caught SIGBUS at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGBUS at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case BUS_ADRALN: @@ -1139,8 +1121,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGILL: - oss << "Caught SIGILL at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGILL at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case ILL_ILLOPC: @@ -1324,8 +1305,8 @@ SymbolProperties::SymbolProperties() // not using an initializer list // to avoid some PGI compiler warnings this->SetBinary("???"); - this->SetBinaryBaseAddress(KWSYS_NULLPTR); - this->Address = KWSYS_NULLPTR; + this->SetBinaryBaseAddress(nullptr); + this->Address = nullptr; this->SetSourceFile("???"); this->SetFunction("???"); this->SetLineNumber(-1); @@ -1682,7 +1663,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName( return -2; } - for (ifa = ifas; ifa != KWSYS_NULLPTR; ifa = ifa->ifa_next) { + for (ifa = ifas; ifa != nullptr; ifa = ifa->ifa_next) { int fam = ifa->ifa_addr ? ifa->ifa_addr->sa_family : -1; // Skip Loopback interfaces if (((fam == AF_INET) || (fam == AF_INET6)) && @@ -1693,7 +1674,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName( : sizeof(struct sockaddr_in6)); ierr = getnameinfo(ifa->ifa_addr, static_cast<socklen_t>(addrlen), host, - NI_MAXHOST, KWSYS_NULLPTR, 0, NI_NAMEREQD); + NI_MAXHOST, nullptr, 0, NI_NAMEREQD); if (ierr) { // don't report the failure now since we may succeed on another // interface. If all attempts fail then return the failure code. @@ -2577,7 +2558,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() // If RDTSC is not supported, we fallback to trying to read this value // from the registry: if (!retrieved) { - HKEY hKey = NULL; + HKEY hKey = nullptr; LONG err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, @@ -2597,7 +2578,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() } RegCloseKey(hKey); - hKey = NULL; + hKey = nullptr; } } #endif @@ -3628,7 +3609,7 @@ SystemInformationImplementation::GetHostMemoryTotal() #elif defined(__APPLE__) uint64_t mem; size_t len = sizeof(mem); - int ierr = sysctlbyname("hw.memsize", &mem, &len, KWSYS_NULLPTR, 0); + int ierr = sysctlbyname("hw.memsize", &mem, &len, nullptr, 0); if (ierr) { return -1; } @@ -3745,12 +3726,12 @@ SystemInformationImplementation::GetHostMemoryUsed() # endif #elif defined(__linux) // First try to use MemAvailable, but it only works on newer kernels - const char* names2[3] = { "MemTotal:", "MemAvailable:", NULL }; + const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr }; SystemInformation::LongLong values2[2] = { SystemInformation::LongLong(0) }; int ierr = GetFieldsFromFile("/proc/meminfo", names2, values2); if (ierr) { const char* names4[5] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:", - NULL }; + nullptr }; SystemInformation::LongLong values4[4] = { SystemInformation::LongLong( 0) }; ierr = GetFieldsFromFile("/proc/meminfo", names4, values4); @@ -3771,8 +3752,7 @@ SystemInformationImplementation::GetHostMemoryUsed() if (psz < 1) { return -1; } - const char* names[3] = { "Pages wired down:", "Pages active:", - KWSYS_NULLPTR }; + const char* names[3] = { "Pages wired down:", "Pages active:", nullptr }; SystemInformation::LongLong values[2] = { SystemInformation::LongLong(0) }; int ierr = GetFieldsFromCommand("vm_stat", names, values); if (ierr) { @@ -3820,7 +3800,7 @@ SystemInformationImplementation::GetProcMemoryUsed() std::ostringstream oss; oss << "ps -o rss= -p " << pid; FILE* file = popen(oss.str().c_str(), "r"); - if (file == KWSYS_NULLPTR) { + if (file == nullptr) { return -1; } oss.str(""); @@ -3920,9 +3900,9 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame, void* stack[TRACE_MAX_STACK_FRAMES]; HANDLE process = GetCurrentProcess(); - SymInitialize(process, NULL, TRUE); + SymInitialize(process, nullptr, TRUE); WORD numberOfFrames = - CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, NULL); + CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, nullptr); SYMBOL_INFO* symbol = static_cast<SYMBOL_INFO*>( malloc(sizeof(SYMBOL_INFO) + (TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR))); @@ -3933,7 +3913,7 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame, line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); for (int i = 0; i < numberOfFrames; i++) { DWORD64 address = reinterpret_cast<DWORD64>(stack[i]); - SymFromAddr(process, address, NULL, symbol); + SymFromAddr(process, address, nullptr, symbol); if (SymGetLineFromAddr64(process, address, &displacement, &line)) { oss << " at " << symbol->Name << " in " << line.FileName << " line " << line.LineNumber << std::endl; @@ -4000,13 +3980,13 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable) if (enable && !saOrigValid) { // save the current actions - sigaction(SIGABRT, KWSYS_NULLPTR, &saABRTOrig); - sigaction(SIGSEGV, KWSYS_NULLPTR, &saSEGVOrig); - sigaction(SIGTERM, KWSYS_NULLPTR, &saTERMOrig); - sigaction(SIGINT, KWSYS_NULLPTR, &saINTOrig); - sigaction(SIGILL, KWSYS_NULLPTR, &saILLOrig); - sigaction(SIGBUS, KWSYS_NULLPTR, &saBUSOrig); - sigaction(SIGFPE, KWSYS_NULLPTR, &saFPEOrig); + sigaction(SIGABRT, nullptr, &saABRTOrig); + sigaction(SIGSEGV, nullptr, &saSEGVOrig); + sigaction(SIGTERM, nullptr, &saTERMOrig); + sigaction(SIGINT, nullptr, &saINTOrig); + sigaction(SIGILL, nullptr, &saILLOrig); + sigaction(SIGBUS, nullptr, &saBUSOrig); + sigaction(SIGFPE, nullptr, &saFPEOrig); // enable read, disable write saOrigValid = 1; @@ -4020,22 +4000,22 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable) # endif sigemptyset(&sa.sa_mask); - sigaction(SIGABRT, &sa, KWSYS_NULLPTR); - sigaction(SIGSEGV, &sa, KWSYS_NULLPTR); - sigaction(SIGTERM, &sa, KWSYS_NULLPTR); - sigaction(SIGINT, &sa, KWSYS_NULLPTR); - sigaction(SIGILL, &sa, KWSYS_NULLPTR); - sigaction(SIGBUS, &sa, KWSYS_NULLPTR); - sigaction(SIGFPE, &sa, KWSYS_NULLPTR); + sigaction(SIGABRT, &sa, nullptr); + sigaction(SIGSEGV, &sa, nullptr); + sigaction(SIGTERM, &sa, nullptr); + sigaction(SIGINT, &sa, nullptr); + sigaction(SIGILL, &sa, nullptr); + sigaction(SIGBUS, &sa, nullptr); + sigaction(SIGFPE, &sa, nullptr); } else if (!enable && saOrigValid) { // restore previous actions - sigaction(SIGABRT, &saABRTOrig, KWSYS_NULLPTR); - sigaction(SIGSEGV, &saSEGVOrig, KWSYS_NULLPTR); - sigaction(SIGTERM, &saTERMOrig, KWSYS_NULLPTR); - sigaction(SIGINT, &saINTOrig, KWSYS_NULLPTR); - sigaction(SIGILL, &saILLOrig, KWSYS_NULLPTR); - sigaction(SIGBUS, &saBUSOrig, KWSYS_NULLPTR); - sigaction(SIGFPE, &saFPEOrig, KWSYS_NULLPTR); + sigaction(SIGABRT, &saABRTOrig, nullptr); + sigaction(SIGSEGV, &saSEGVOrig, nullptr); + sigaction(SIGTERM, &saTERMOrig, nullptr); + sigaction(SIGINT, &saINTOrig, nullptr); + sigaction(SIGILL, &saILLOrig, nullptr); + sigaction(SIGBUS, &saBUSOrig, nullptr); + sigaction(SIGFPE, &saFPEOrig, nullptr); // enable write, disable read saOrigValid = 0; @@ -4417,7 +4397,7 @@ void SystemInformationImplementation::CPUCountWindows() std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo; { DWORD Length = 0; - DWORD rc = pGetLogicalProcessorInformation(NULL, &Length); + DWORD rc = pGetLogicalProcessorInformation(nullptr, &Length); assert(FALSE == rc); (void)rc; // Silence unused variable warning in Borland C++ 5.81 assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); @@ -4471,7 +4451,7 @@ bool SystemInformationImplementation::ParseSysCtl() int err = 0; uint64_t value = 0; size_t len = sizeof(value); - sysctlbyname("hw.memsize", &value, &len, KWSYS_NULLPTR, 0); + sysctlbyname("hw.memsize", &value, &len, nullptr, 0); this->TotalPhysicalMemory = static_cast<size_t>(value / 1048576); // Parse values for Mac @@ -4481,7 +4461,7 @@ bool SystemInformationImplementation::ParseSysCtl() if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) == KERN_SUCCESS) { len = sizeof(value); - err = sysctlbyname("hw.pagesize", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.pagesize", &value, &len, nullptr, 0); int64_t available_memory = (vmstat.free_count + vmstat.inactive_count) * value; this->AvailablePhysicalMemory = @@ -4491,10 +4471,11 @@ bool SystemInformationImplementation::ParseSysCtl() # ifdef VM_SWAPUSAGE // Virtual memory. int mib[2] = { CTL_VM, VM_SWAPUSAGE }; - size_t miblen = sizeof(mib) / sizeof(mib[0]); + unsigned int miblen = + static_cast<unsigned int>(sizeof(mib) / sizeof(mib[0])); struct xsw_usage swap; len = sizeof(swap); - err = sysctl(mib, miblen, &swap, &len, KWSYS_NULLPTR, 0); + err = sysctl(mib, miblen, &swap, &len, nullptr, 0); if (err == 0) { this->AvailableVirtualMemory = static_cast<size_t>(swap.xsu_avail / 1048576); @@ -4507,75 +4488,72 @@ bool SystemInformationImplementation::ParseSysCtl() // CPU Info len = sizeof(this->NumberOfPhysicalCPU); - sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, - KWSYS_NULLPTR, 0); + sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, nullptr, 0); len = sizeof(this->NumberOfLogicalCPU); - sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, KWSYS_NULLPTR, - 0); + sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, nullptr, 0); int cores_per_package = 0; len = sizeof(cores_per_package); err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len, - KWSYS_NULLPTR, 0); + nullptr, 0); // That name was not found, default to 1 this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = err != 0 ? 1 : static_cast<unsigned char>(cores_per_package); len = sizeof(value); - sysctlbyname("hw.cpufrequency", &value, &len, KWSYS_NULLPTR, 0); + sysctlbyname("hw.cpufrequency", &value, &len, nullptr, 0); this->CPUSpeedInMHz = static_cast<float>(value) / 1000000; // Chip family len = sizeof(this->ChipID.Family); // Seems only the intel chips will have this name so if this fails it is // probably a PPC machine - err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, - KWSYS_NULLPTR, 0); + err = + sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, nullptr, 0); if (err != 0) // Go back to names we know but are less descriptive { this->ChipID.Family = 0; ::memset(retBuf, 0, 128); len = 32; - err = sysctlbyname("hw.machine", &retBuf, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.machine", &retBuf, &len, nullptr, 0); std::string machineBuf(retBuf); if (machineBuf.find_first_of("Power") != std::string::npos) { this->ChipID.Vendor = "IBM"; len = sizeof(this->ChipID.Family); - err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, - KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, nullptr, 0); len = sizeof(this->ChipID.Model); - err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, - KWSYS_NULLPTR, 0); + err = + sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, nullptr, 0); this->FindManufacturer(); } } else // Should be an Intel Chip. { len = sizeof(this->ChipID.Family); err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, - KWSYS_NULLPTR, 0); + nullptr, 0); ::memset(retBuf, 0, 128); len = 128; - err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, nullptr, 0); // Chip Vendor this->ChipID.Vendor = retBuf; this->FindManufacturer(); // Chip Model len = sizeof(value); - err = sysctlbyname("machdep.cpu.model", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.model", &value, &len, nullptr, 0); this->ChipID.Model = static_cast<int>(value); // Chip Stepping len = sizeof(value); value = 0; - err = sysctlbyname("machdep.cpu.stepping", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.stepping", &value, &len, nullptr, 0); if (!err) { this->ChipID.Revision = static_cast<int>(value); } // feature string - char* buf = KWSYS_NULLPTR; + char* buf = nullptr; size_t allocSize = 128; err = 0; @@ -4592,8 +4570,7 @@ bool SystemInformationImplementation::ParseSysCtl() } buf[0] = ' '; len = allocSize - 2; // keep space for leading and trailing space - err = - sysctlbyname("machdep.cpu.features", buf + 1, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.features", buf + 1, &len, nullptr, 0); } if (!err && buf && len) { // now we can match every flags as space + flag + space @@ -4634,8 +4611,7 @@ bool SystemInformationImplementation::ParseSysCtl() // brand string ::memset(retBuf, 0, sizeof(retBuf)); len = sizeof(retBuf); - err = - sysctlbyname("machdep.cpu.brand_string", retBuf, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, nullptr, 0); if (!err) { this->ChipID.ProcessorName = retBuf; this->ChipID.ModelName = retBuf; @@ -4643,10 +4619,10 @@ bool SystemInformationImplementation::ParseSysCtl() // Cache size len = sizeof(value); - err = sysctlbyname("hw.l1icachesize", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.l1icachesize", &value, &len, nullptr, 0); this->Features.L1CacheSize = static_cast<int>(value); len = sizeof(value); - err = sysctlbyname("hw.l2cachesize", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.l2cachesize", &value, &len, nullptr, 0); this->Features.L2CacheSize = static_cast<int>(value); return true; @@ -4683,7 +4659,7 @@ std::string SystemInformationImplementation::RunProcess( kwsysProcess_Execute(gp); - char* data = KWSYS_NULLPTR; + char* data = nullptr; int length; double timeout = 255; int pipe; // pipe id as returned by kwsysProcess_WaitForData() @@ -4695,7 +4671,7 @@ std::string SystemInformationImplementation::RunProcess( { buffer.append(data, length); } - kwsysProcess_WaitForExit(gp, KWSYS_NULLPTR); + kwsysProcess_WaitForExit(gp, nullptr); int result = 0; switch (kwsysProcess_GetState(gp)) { @@ -4766,7 +4742,7 @@ std::string SystemInformationImplementation::ParseValueFromKStat( for (size_t i = 0; i < args_string.size(); ++i) { args.push_back(args_string[i].c_str()); } - args.push_back(KWSYS_NULLPTR); + args.push_back(nullptr); std::string buffer = this->RunProcess(args); @@ -4965,7 +4941,7 @@ bool SystemInformationImplementation::QueryBSDMemory() # endif size_t sz = sizeof(k); - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5036,7 +5012,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() size_t sz = sizeof(k); int ctrl[2] = { CTL_HW, HW_NCPU }; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5046,7 +5022,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() # if defined(HW_CPUSPEED) ctrl[1] = HW_CPUSPEED; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5057,7 +5033,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() ctrl[0] = CTL_MACHDEP; ctrl[1] = CPU_SSE; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5068,7 +5044,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() ctrl[0] = CTL_MACHDEP; ctrl[1] = CPU_SSE2; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5081,7 +5057,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() char vbuf[25]; ::memset(vbuf, 0, sizeof(vbuf)); sz = sizeof(vbuf) - 1; - if (sysctl(ctrl, 2, vbuf, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, vbuf, &sz, nullptr, 0) != 0) { return false; } @@ -5293,7 +5269,7 @@ bool SystemInformationImplementation::QueryOSInformation() RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey); - RegQueryValueExW(hKey, L"ProductType", NULL, NULL, + RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr, (LPBYTE)szProductType, &dwBufLen); RegCloseKey(hKey); @@ -5335,13 +5311,13 @@ bool SystemInformationImplementation::QueryOSInformation() // Load the Kernel32 DLL. hKernelDLL = LoadLibraryW(L"kernel32"); - if (hKernelDLL != NULL) { + if (hKernelDLL != nullptr) { // Only XP and .NET Server support IsWOW64Process so... Load // dynamically! DLLProc = (LPFNPROC)GetProcAddress(hKernelDLL, "IsWow64Process"); // If the function address is valid, call the function. - if (DLLProc != NULL) + if (DLLProc != nullptr) (DLLProc)(GetCurrentProcess(), &bIsWindows64Bit); else bIsWindows64Bit = false; @@ -5456,7 +5432,7 @@ int SystemInformationImplementation::CallSwVers(const char* arg, std::vector<const char*> args; args.push_back("sw_vers"); args.push_back(arg); - args.push_back(KWSYS_NULLPTR); + args.push_back(nullptr); ver = this->RunProcess(args); this->TrimNewline(ver); #else diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index 5e93878..fc42e9d 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -115,8 +115,8 @@ public: // returns an informative general description if the installed and // available ram on this system. See the GetHostMemoryTotal, and // Get{Host,Proc}MemoryAvailable methods for more information. - std::string GetMemoryDescription(const char* hostLimitEnvVarName = NULL, - const char* procLimitEnvVarName = NULL); + std::string GetMemoryDescription(const char* hostLimitEnvVarName = nullptr, + const char* procLimitEnvVarName = nullptr); // Retrieve amount of physical memory installed on the system in KiB // units. @@ -128,7 +128,7 @@ public: // parallel. The amount of memory reported may differ from the host // total if a host wide resource limit is applied. Such reource limits // are reported to us via an application specified environment variable. - LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = NULL); + LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr); // Get total system RAM in units of KiB available to this process. // This may differ from the host available if a per-process resource @@ -136,8 +136,8 @@ public: // system via rlimit API. Resource limits that are not imposed via // rlimit API may be reported to us via an application specified // environment variable. - LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = NULL, - const char* procLimitEnvVarName = NULL); + LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr, + const char* procLimitEnvVarName = nullptr); // Get the system RAM used by all processes on the host, in units of KiB. LongLong GetHostMemoryUsed(); diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 8571477..ce4d6ef 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -192,15 +192,15 @@ static inline char* realpath(const char* path, char* resolved_path) { const size_t maxlen = KWSYS_SYSTEMTOOLS_MAXPATH; snprintf(resolved_path, maxlen, "%s", path); - BPath normalized(resolved_path, NULL, true); + BPath normalized(resolved_path, nullptr, true); const char* resolved = normalized.Path(); - if (resolved != NULL) // NULL == No such file. + if (resolved != nullptr) // nullptr == No such file. { if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) { return resolved_path; } } - return NULL; // something went wrong. + return nullptr; // something went wrong. } #endif @@ -273,12 +273,12 @@ inline void Realpath(const std::string& path, std::string& resolved_path, if (bufferLen) { *errorMessage = "Destination path buffer size too small."; } else if (unsigned int errorId = GetLastError()) { - LPSTR message = NULL; + LPSTR message = nullptr; DWORD size = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&message, 0, NULL); + nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&message, 0, nullptr); *errorMessage = std::string(message, size); LocalFree(message); } else { @@ -313,7 +313,7 @@ inline int Chdir(const std::string& dir) return chdir(dir.c_str()); } inline void Realpath(const std::string& path, std::string& resolved_path, - std::string* errorMessage = KWSYS_NULLPTR) + std::string* errorMessage = nullptr) { char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH]; @@ -359,7 +359,7 @@ double SystemTools::GetTime(void) 11644473600.0); #else struct timeval t; - gettimeofday(&t, KWSYS_NULLPTR); + gettimeofday(&t, nullptr); return 1.0 * double(t.tv_sec) + 0.000001 * double(t.tv_usec); #endif } @@ -389,8 +389,8 @@ struct kwsysEnvCompare #else const char* leq = strchr(l, '='); const char* req = strchr(r, '='); - size_t llen = leq ? (leq - l) : strlen(l); - size_t rlen = req ? (req - r) : strlen(r); + size_t llen = leq ? static_cast<size_t>(leq - l) : strlen(l); + size_t rlen = req ? static_cast<size_t>(req - r) : strlen(r); if (llen == rlen) { return strncmp(l, r, llen) < 0; } else { @@ -420,7 +420,7 @@ public: const envchar* Release(const envchar* env) { - const envchar* old = KWSYS_NULLPTR; + const envchar* old = nullptr; iterator i = this->find(env); if (i != this->end()) { old = *i; @@ -630,7 +630,7 @@ const char* SystemToolsStatic::GetEnvBuffered(const char* key) } return menv.c_str(); } - return KWSYS_NULLPTR; + return nullptr; } #endif @@ -684,7 +684,7 @@ bool SystemTools::HasEnv(const char* key) #else const char* v = getenv(key); #endif - return v != KWSYS_NULLPTR; + return v != nullptr; } bool SystemTools::HasEnv(const std::string& key) @@ -915,7 +915,7 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) while ((pos = dir.find('/', pos)) != std::string::npos) { topdir = dir.substr(0, pos); - if (Mkdir(topdir) == 0 && mode != KWSYS_NULLPTR) { + if (Mkdir(topdir) == 0 && mode != nullptr) { SystemTools::SetPermissions(topdir, *mode); } @@ -934,7 +934,7 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) ) { return false; } - } else if (mode != KWSYS_NULLPTR) { + } else if (mode != nullptr) { SystemTools::SetPermissions(topdir, *mode); } @@ -1055,7 +1055,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode, // only add the modes when on a system that supports Wow64. static FARPROC wow64p = GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"); - if (wow64p == NULL) { + if (wow64p == nullptr) { return mode; } @@ -1136,7 +1136,7 @@ bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value, DWORD dwType, dwSize; dwSize = 1023; wchar_t data[1024]; - if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), NULL, + if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), nullptr, &dwType, (BYTE*)data, &dwSize) == ERROR_SUCCESS) { if (dwType == REG_SZ) { value = Encoding::ToNarrow(data); @@ -1186,7 +1186,7 @@ bool SystemTools::WriteRegistryValue(const std::string& key, wchar_t lpClass[] = L""; if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass, REG_OPTION_NON_VOLATILE, - SystemToolsMakeRegistryMode(KEY_WRITE, view), NULL, + SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr, &hKey, &dwDummy) != ERROR_SUCCESS) { return false; } @@ -1252,10 +1252,10 @@ bool SystemTools::SameFile(const std::string& file1, const std::string& file2) hFile1 = CreateFileW(Encoding::ToWide(file1).c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); hFile2 = CreateFileW(Encoding::ToWide(file2).c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE) { if (hFile1 != INVALID_HANDLE_VALUE) { CloseHandle(hFile1); @@ -1347,7 +1347,7 @@ bool SystemTools::FileExists(const std::string& filename) // even if we do not have permission to read the file itself HANDLE handle = CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(), 0, 0, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (handle == INVALID_HANDLE_VALUE) { return false; @@ -1493,12 +1493,12 @@ bool SystemTools::Touch(const std::string& filename, bool create) CloseHandle(h); #elif KWSYS_CXX_HAS_UTIMENSAT // utimensat is only available on newer Unixes and macOS 10.13+ - if (utimensat(AT_FDCWD, filename.c_str(), NULL, 0) < 0) { + if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) { return false; } #else // fall back to utimes - if (utimes(filename.c_str(), NULL) < 0) { + if (utimes(filename.c_str(), nullptr) < 0) { return false; } #endif @@ -1653,7 +1653,7 @@ char* SystemTools::AppendStrings(const char* str1, const char* str2) size_t len1 = strlen(str1); char* newstr = new char[len1 + strlen(str2) + 1]; if (!newstr) { - return KWSYS_NULLPTR; + return nullptr; } strcpy(newstr, str1); strcat(newstr + len1, str2); @@ -1676,7 +1676,7 @@ char* SystemTools::AppendStrings(const char* str1, const char* str2, size_t len1 = strlen(str1), len2 = strlen(str2); char* newstr = new char[len1 + len2 + strlen(str3) + 1]; if (!newstr) { - return KWSYS_NULLPTR; + return nullptr; } strcpy(newstr, str1); strcat(newstr + len1, str2); @@ -1726,7 +1726,7 @@ size_t SystemTools::CountChar(const char* str, char c) char* SystemTools::RemoveChars(const char* str, const char* toremove) { if (!str) { - return KWSYS_NULLPTR; + return nullptr; } char* clean_str = new char[strlen(str) + 1]; char* ptr = clean_str; @@ -1748,7 +1748,7 @@ char* SystemTools::RemoveChars(const char* str, const char* toremove) char* SystemTools::RemoveCharsButUpperHex(const char* str) { if (!str) { - return KWSYS_NULLPTR; + return nullptr; } char* clean_str = new char[strlen(str) + 1]; char* ptr = clean_str; @@ -1829,7 +1829,7 @@ bool SystemTools::StringEndsWith(const std::string& str1, const char* str2) const char* SystemTools::FindLastString(const char* str1, const char* str2) { if (!str1 || !str2) { - return KWSYS_NULLPTR; + return nullptr; } size_t len1 = strlen(str1), len2 = strlen(str2); @@ -1842,7 +1842,7 @@ const char* SystemTools::FindLastString(const char* str1, const char* str2) } while (ptr-- != str1); } - return KWSYS_NULLPTR; + return nullptr; } // Duplicate string @@ -1852,7 +1852,7 @@ char* SystemTools::DuplicateString(const char* str) char* newstr = new char[strlen(str) + 1]; return strcpy(newstr, str); } - return KWSYS_NULLPTR; + return nullptr; } // Return a cropped string @@ -3018,16 +3018,16 @@ bool SystemTools::FileIsSymlink(const std::string& name) // * a file or directory that has an associated reparse point, or // * a file that is a symbolic link. HANDLE hFile = CreateFileW( - path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); + path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return false; } byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; DWORD bytesReturned = 0; - if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, + if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, nullptr, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, - NULL)) { + nullptr)) { CloseHandle(hFile); // Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be // a symbolic link if it is not a reparse point. @@ -3058,7 +3058,7 @@ bool SystemTools::FileIsFIFO(const std::string& name) #if defined(_WIN32) HANDLE hFile = CreateFileW(Encoding::ToWide(name).c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return false; } @@ -3219,7 +3219,7 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut, std::string SystemTools::CollapseFullPath(const std::string& in_relative) { - return SystemTools::CollapseFullPath(in_relative, KWSYS_NULLPTR); + return SystemTools::CollapseFullPath(in_relative, nullptr); } #if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP @@ -4013,7 +4013,7 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) } std::wstring wtempPath = Encoding::ToWide(tempPath); - DWORD ret = GetShortPathNameW(wtempPath.c_str(), NULL, 0); + DWORD ret = GetShortPathNameW(wtempPath.c_str(), nullptr, 0); std::vector<wchar_t> buffer(ret); if (ret != 0) { ret = GetShortPathNameW(wtempPath.c_str(), &buffer[0], @@ -4421,7 +4421,7 @@ std::string SystemTools::GetOperatingSystemNameAndVersion() return 0; } - lRet = RegQueryValueExW(hKey, L"ProductType", NULL, NULL, + lRet = RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr, (LPBYTE)szProductType, &dwBufLen); if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE)) { diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index dd1266b..c4ab9d4 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -400,9 +400,10 @@ public: * installPrefix is a possibly null pointer to the install directory. */ static bool FindProgramPath(const char* argv0, std::string& pathOut, - std::string& errorMsg, const char* exeName = 0, - const char* buildDir = 0, - const char* installPrefix = 0); + std::string& errorMsg, + const char* exeName = nullptr, + const char* buildDir = nullptr, + const char* installPrefix = nullptr); /** * Given a path to a file or directory, convert it to a full path. @@ -420,11 +421,11 @@ public: * Get the real path for a given path, removing all symlinks. In * the event of an error (non-existent path, permissions issue, * etc.) the original path is returned if errorMessage pointer is - * NULL. Otherwise empty string is returned and errorMessage + * nullptr. Otherwise empty string is returned and errorMessage * contains error description. */ static std::string GetRealPath(const std::string& path, - std::string* errorMessage = 0); + std::string* errorMessage = nullptr); /** * Split a path name into its root component and the rest of the @@ -442,7 +443,7 @@ public: * given. */ static const char* SplitPathRootComponent(const std::string& p, - std::string* root = 0); + std::string* root = nullptr); /** * Split a path name into its basic components. The first component @@ -528,7 +529,8 @@ public: * be true when the line read had a newline character. */ static bool GetLineFromStream(std::istream& istr, std::string& line, - bool* has_newline = 0, long sizeLimit = -1); + bool* has_newline = nullptr, + long sizeLimit = -1); /** * Get the parent directory of the directory or file @@ -563,8 +565,9 @@ public: * can make a full path even if none of the directories existed * prior to calling this function. */ - static bool MakeDirectory(const char* path, const mode_t* mode = 0); - static bool MakeDirectory(const std::string& path, const mode_t* mode = 0); + static bool MakeDirectory(const char* path, const mode_t* mode = nullptr); + static bool MakeDirectory(const std::string& path, + const mode_t* mode = nullptr); /** * Copy the source file to the destination file only @@ -842,7 +845,8 @@ public: * string vector passed in. If env is set then the value * of env will be used instead of PATH. */ - static void GetPath(std::vector<std::string>& path, const char* env = 0); + static void GetPath(std::vector<std::string>& path, + const char* env = nullptr); /** * Read an environment variable diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in index 0981c66..8c4b002 100644 --- a/Source/kwsys/hashtable.hxx.in +++ b/Source/kwsys/hashtable.hxx.in @@ -354,7 +354,7 @@ public: return end(); } - iterator end() { return iterator(0, this); } + iterator end() { return iterator(nullptr, this); } const_iterator begin() const { @@ -364,7 +364,7 @@ public: return end(); } - const_iterator end() const { return const_iterator(0, this); } + const_iterator end() const { return const_iterator(nullptr, this); } friend bool operator==<>(const hashtable&, const hashtable&); @@ -510,7 +510,7 @@ private: { const size_type __n_buckets = _M_next_size(__n); _M_buckets.reserve(__n_buckets); - _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)0); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)nullptr); _M_num_elements = 0; } @@ -544,7 +544,7 @@ private: _Node* _M_new_node(const value_type& __obj) { _Node* __n = _M_get_node(); - __n->_M_next = 0; + __n->_M_next = nullptr; try { construct(&__n->_M_val, __obj); return __n; @@ -839,9 +839,9 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first, else if (__f_bucket == __l_bucket) _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { - _M_erase_bucket(__f_bucket, __first._M_cur, 0); + _M_erase_bucket(__f_bucket, __first._M_cur, nullptr); for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) - _M_erase_bucket(__n, 0); + _M_erase_bucket(__n, nullptr); if (__l_bucket != _M_buckets.size()) _M_erase_bucket(__l_bucket, __last._M_cur); } @@ -873,7 +873,8 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize( if (__num_elements_hint > __old_n) { const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { - _M_buckets_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + _M_buckets_type __tmp(__n, (_Node*)(nullptr), + _M_buckets.get_allocator()); try { for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; @@ -940,12 +941,12 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear() { for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { _Node* __cur = _M_buckets[__i]; - while (__cur != 0) { + while (__cur != nullptr) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; } - _M_buckets[__i] = 0; + _M_buckets[__i] = nullptr; } _M_num_elements = 0; } @@ -956,7 +957,7 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from( { _M_buckets.clear(); _M_buckets.reserve(__ht._M_buckets.size()); - _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)0); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)nullptr); try { for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { const _Node* __cur = __ht._M_buckets[__i]; diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx index 15f9c02..1778a9b 100644 --- a/Source/kwsys/testCommandLineArguments.cxx +++ b/Source/kwsys/testCommandLineArguments.cxx @@ -76,7 +76,7 @@ int testCommandLineArguments(int argc, char* argv[]) int some_int_variable = 10; double some_double_variable = 10.10; - char* some_string_variable = KWSYS_NULLPTR; + char* some_string_variable = nullptr; std::string some_stl_string_variable; bool some_bool_variable = false; bool some_bool_variable1 = false; @@ -203,7 +203,7 @@ int testCommandLineArguments(int argc, char* argv[]) for (cc = 0; cc < strings_argument.size(); ++cc) { delete[] strings_argument[cc]; - strings_argument[cc] = KWSYS_NULLPTR; + strings_argument[cc] = nullptr; } return res; } diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx index 9895008..64561b1 100644 --- a/Source/kwsys/testCommandLineArguments1.cxx +++ b/Source/kwsys/testCommandLineArguments1.cxx @@ -21,7 +21,7 @@ int testCommandLineArguments1(int argc, char* argv[]) arg.Initialize(argc, argv); int n = 0; - char* m = KWSYS_NULLPTR; + char* m = nullptr; std::string p; int res = 0; @@ -55,11 +55,11 @@ int testCommandLineArguments1(int argc, char* argv[]) delete[] m; } - char** newArgv = KWSYS_NULLPTR; + char** newArgv = nullptr; int newArgc = 0; arg.GetUnusedArguments(&newArgc, &newArgv); int cc; - const char* valid_unused_args[9] = { KWSYS_NULLPTR, + const char* valid_unused_args[9] = { nullptr, "--ignored", "--second-ignored", "third-ignored", diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx index b6ad118..4b7ddf0 100644 --- a/Source/kwsys/testConsoleBuf.cxx +++ b/Source/kwsys/testConsoleBuf.cxx @@ -51,7 +51,7 @@ static void displayError(DWORD errorCode) LPWSTR message; if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, errorCode, 0, (LPWSTR)&message, 0, NULL)) { + nullptr, errorCode, 0, (LPWSTR)&message, 0, nullptr)) { std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl; HeapFree(GetProcessHeap(), 0, message); @@ -124,7 +124,7 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) } WCHAR cmd[MAX_PATH]; - if (GetModuleFileNameW(NULL, cmd, MAX_PATH) == 0) { + if (GetModuleFileNameW(nullptr, cmd, MAX_PATH) == 0) { std::cerr << "GetModuleFileName failed!" << std::endl; return false; } @@ -136,14 +136,14 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) wcscat(cmd, L".exe"); bool success = - CreateProcessW(NULL, // No module name (use command line) + CreateProcessW(nullptr, // No module name (use command line) cmd, // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable bInheritHandles, // Set handle inheritance dwCreationFlags, - NULL, // Use parent's environment block - NULL, // Use parent's starting directory + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory &startupInfo, // Pointer to STARTUPINFO structure &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure @@ -174,7 +174,7 @@ static bool createPipe(PHANDLE readPipe, PHANDLE writePipe) SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.lpSecurityDescriptor = nullptr; return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0 ? false : true; } @@ -194,7 +194,7 @@ static HANDLE createFile(LPCWSTR fileName) SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.lpSecurityDescriptor = nullptr; HANDLE file = CreateFileW(fileName, GENERIC_READ | GENERIC_WRITE, @@ -202,7 +202,7 @@ static HANDLE createFile(LPCWSTR fileName) &securityAttributes, CREATE_ALWAYS, // overwrite existing FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - NULL); // no template + nullptr); // no template if (file == INVALID_HANDLE_VALUE) { DWORD lastError = GetLastError(); std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" @@ -288,7 +288,7 @@ static int testPipe() DWORD bytesWritten = 0; if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(), (DWORD)encodedInputTestString.size(), &bytesWritten, - NULL) || + nullptr) || bytesWritten == 0) { throw std::runtime_error("WriteFile failed!"); } @@ -305,7 +305,8 @@ static int testPipe() throw std::runtime_error("WaitForSingleObject failed!"); } DWORD bytesRead = 0; - if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) || + if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, + nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#1 failed!"); } @@ -313,7 +314,7 @@ static int testPipe() if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size() && !ReadFile(outPipeRead, buffer + bytesRead, - sizeof(buffer) - bytesRead, &bytesRead, NULL)) || + sizeof(buffer) - bytesRead, &bytesRead, nullptr)) || bytesRead == 0) { throw std::runtime_error("ReadFile#2 failed!"); } @@ -324,7 +325,7 @@ static int testPipe() encodedInputTestString.size()) == 0) { bytesRead = 0; if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, - NULL) || + nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#3 failed!"); } @@ -383,13 +384,13 @@ static int testFile() char buffer2[200]; int length; - if ((length = - WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1, - buffer, sizeof(buffer), NULL, NULL)) == 0) { + if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, + -1, buffer, sizeof(buffer), nullptr, + nullptr)) == 0) { throw std::runtime_error("WideCharToMultiByte failed!"); } buffer[length - 1] = '\n'; - if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL) || + if (!WriteFile(inFile, buffer, length, &bytesWritten, nullptr) || bytesWritten == 0) { throw std::runtime_error("WriteFile failed!"); } @@ -413,7 +414,7 @@ static int testFile() INVALID_SET_FILE_POINTER) { throw std::runtime_error("SetFilePointer#1 failed!"); } - if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL) || + if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#1 failed!"); } @@ -429,7 +430,8 @@ static int testFile() throw std::runtime_error("SetFilePointer#2 failed!"); } - if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL) || + if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, + nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#2 failed!"); } @@ -519,12 +521,12 @@ static int testConsole() if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) { DWORD dwordSize = sizeof(DWORD); - if (RegQueryValueExW(hConsoleKey, L"FontFamily", NULL, NULL, + if (RegQueryValueExW(hConsoleKey, L"FontFamily", nullptr, nullptr, (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) { if (FontFamily != TestFontFamily) { - RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL, + RegQueryValueExW(hConsoleKey, L"FaceName", nullptr, nullptr, (LPBYTE)FaceName, &FaceNameSize); - RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL, + RegQueryValueExW(hConsoleKey, L"FontSize", nullptr, nullptr, (LPBYTE)&FontSize, &dwordSize); RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD, @@ -557,10 +559,10 @@ static int testConsole() SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.lpSecurityDescriptor = nullptr; hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, NULL); + OPEN_EXISTING, 0, nullptr); if (hIn == INVALID_HANDLE_VALUE) { DWORD lastError = GetLastError(); std::cerr << "CreateFile(CONIN$)" << std::endl; @@ -568,7 +570,7 @@ static int testConsole() } hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, NULL); + OPEN_EXISTING, 0, nullptr); if (hOut == INVALID_HANDLE_VALUE) { DWORD lastError = GetLastError(); std::cerr << "CreateFile(CONOUT$)" << std::endl; @@ -630,7 +632,7 @@ static int testConsole() } # endif - if (createProcess(NULL, NULL, NULL)) { + if (createProcess(nullptr, nullptr, nullptr)) { try { DWORD status; if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) != @@ -746,7 +748,7 @@ int testConsoleBuf(int, char* []) int ret = 0; #if defined(_WIN32) - beforeInputEvent = CreateEventW(NULL, + beforeInputEvent = CreateEventW(nullptr, FALSE, // auto-reset event FALSE, // initial state is nonsignaled BeforeInputEventName); // object name @@ -755,7 +757,7 @@ int testConsoleBuf(int, char* []) return 1; } - afterOutputEvent = CreateEventW(NULL, FALSE, FALSE, AfterOutputEventName); + afterOutputEvent = CreateEventW(nullptr, FALSE, FALSE, AfterOutputEventName); if (!afterOutputEvent) { std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl; return 1; diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx index eff2ed7..2421ac0 100644 --- a/Source/kwsys/testDynamicLoader.cxx +++ b/Source/kwsys/testDynamicLoader.cxx @@ -21,7 +21,7 @@ // left on disk. #include <testSystemTools.h> -static std::string GetLibName(const char* lname, const char* subdir = NULL) +static std::string GetLibName(const char* lname, const char* subdir = nullptr) { // Construct proper name of lib std::string slname; diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx index fdad1cd..988697b 100644 --- a/Source/kwsys/testEncoding.cxx +++ b/Source/kwsys/testEncoding.cxx @@ -84,7 +84,7 @@ static int testRobustEncoding() // this conversion could fail std::wstring wstr = kwsys::Encoding::ToWide(cstr); - wstr = kwsys::Encoding::ToWide(KWSYS_NULLPTR); + wstr = kwsys::Encoding::ToWide(nullptr); if (wstr != L"") { const wchar_t* wcstr = wstr.c_str(); std::cout << "ToWide(NULL) returned"; @@ -112,7 +112,7 @@ static int testRobustEncoding() std::string win_str = kwsys::Encoding::ToNarrow(cwstr); #endif - std::string str = kwsys::Encoding::ToNarrow(KWSYS_NULLPTR); + std::string str = kwsys::Encoding::ToNarrow(nullptr); if (str != "") { std::cout << "ToNarrow(NULL) returned " << str << std::endl; ret++; diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c index f139f58..39aaa23 100644 --- a/Source/kwsys/testProcess.c +++ b/Source/kwsys/testProcess.c @@ -477,7 +477,7 @@ static int runChild2(kwsysProcess* kp, const char* cmd[], int state, printf("Error in administrating child process: [%s]\n", kwsysProcess_GetErrorString(kp)); break; - }; + } if (result) { if (exception != kwsysProcess_GetExitException(kp)) { diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index 88277de..1f3a15b 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -52,7 +52,7 @@ static const char* toUnixPaths[][2] = { { "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" }, { "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" }, { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo/ cal/bin/pa/ sswd" }, - { KWSYS_NULLPTR, KWSYS_NULLPTR } + { nullptr, nullptr } }; static bool CheckConvertToUnixSlashes(std::string const& input, @@ -71,7 +71,7 @@ static bool CheckConvertToUnixSlashes(std::string const& input, static const char* checkEscapeChars[][4] = { { "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2" }, { " {} ", "{}", "#", " #{#} " }, - { KWSYS_NULLPTR, KWSYS_NULLPTR, KWSYS_NULLPTR, KWSYS_NULLPTR } + { nullptr, nullptr, nullptr, nullptr } }; static bool CheckEscapeChars(std::string const& input, @@ -160,7 +160,7 @@ static bool CheckFileOperations() res = false; } // calling with 0 pointer should return false - if (kwsys::SystemTools::MakeDirectory(KWSYS_NULLPTR)) { + if (kwsys::SystemTools::MakeDirectory(nullptr)) { std::cerr << "Problem with MakeDirectory(0)" << std::endl; res = false; } @@ -218,11 +218,11 @@ static bool CheckFileOperations() } // calling with 0 pointer should return false - if (kwsys::SystemTools::FileExists(KWSYS_NULLPTR)) { + if (kwsys::SystemTools::FileExists(nullptr)) { std::cerr << "Problem with FileExists(0)" << std::endl; res = false; } - if (kwsys::SystemTools::FileExists(KWSYS_NULLPTR, true)) { + if (kwsys::SystemTools::FileExists(nullptr, true)) { std::cerr << "Problem with FileExists(0) as file" << std::endl; res = false; } diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in index c58ef71..ad8bfb0 100644 --- a/Templates/TestDriver.cxx.in +++ b/Templates/TestDriver.cxx.in @@ -13,9 +13,15 @@ @CMAKE_FORWARD_DECLARE_TESTS@ #ifdef __cplusplus -#define CM_CAST(TYPE, EXPR) static_cast<TYPE>(EXPR) +# define CM_CAST(TYPE, EXPR) static_cast<TYPE>(EXPR) +# if __cplusplus >= 201103L +# define CM_NULL nullptr +# else +# define CM_NULL NULL +# endif #else -#define CM_CAST(TYPE, EXPR) (TYPE)(EXPR) +# define CM_CAST(TYPE, EXPR) (TYPE)(EXPR) +# define CM_NULL NULL #endif /* Create map. */ @@ -29,7 +35,7 @@ typedef struct /* NOLINT */ static functionMapEntry cmakeGeneratedFunctionMapEntries[] = { @CMAKE_FUNCTION_TABLE_ENTIRES@ - { NULL, NULL } /* NOLINT */ + { CM_NULL, CM_NULL } /* NOLINT */ }; static const int NumTests = CM_CAST(int, @@ -45,8 +51,8 @@ static char* lowercase(const char* string) stringSize = CM_CAST(size_t, strlen(string) + 1); new_string = CM_CAST(char*, malloc(sizeof(char) * stringSize)); - if (new_string == NULL) { /* NOLINT */ - return NULL; /* NOLINT */ + if (new_string == CM_NULL) { /* NOLINT */ + return CM_NULL; /* NOLINT */ } strcpy(new_string, string); for (p = new_string; *p != 0; ++p) { @@ -86,7 +92,7 @@ int main(int ac, char* av[]) av++; } partial_match = 0; - arg = NULL; /* NOLINT */ + arg = CM_NULL; /* NOLINT */ /* If partial match is requested. */ if (testToRun == -1 && ac > 1) { partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; @@ -100,7 +106,7 @@ int main(int ac, char* av[]) } for (i = 0; i < NumTests && testToRun == -1; ++i) { char *test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match != 0 && strstr(test_name, arg) != NULL) { /* NOLINT */ + if (partial_match != 0 && strstr(test_name, arg) != CM_NULL) { /* NOLINT */ testToRun = i; ac -= 2; av += 2; diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index b1541e2..4a79c80 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -1,9 +1,9 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmsys/FStream.hxx" +#include <cstdlib> #include <iostream> #include <map> -#include <stdlib.h> #include <string> #include <utility> #include <vector> @@ -18,7 +18,7 @@ public: public: std::string const& at(std::string const& k) const { - const_iterator i = this->find(k); + auto i = this->find(k); if (i != this->end()) { return i->second; } diff --git a/Tests/CMakeLib/testArgumentParser.cxx b/Tests/CMakeLib/testArgumentParser.cxx index 788fece..909f71b 100644 --- a/Tests/CMakeLib/testArgumentParser.cxx +++ b/Tests/CMakeLib/testArgumentParser.cxx @@ -4,7 +4,7 @@ #include "cmArgumentParser.h" #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" +#include <cm/string_view> #include <initializer_list> #include <iostream> diff --git a/Tests/CMakeLib/testOptional.cxx b/Tests/CMakeLib/testOptional.cxx index a5e30fb..cefe9fa 100644 --- a/Tests/CMakeLib/testOptional.cxx +++ b/Tests/CMakeLib/testOptional.cxx @@ -1,9 +1,8 @@ -#include "cm_optional.hxx" -#include "cm_utility.hxx" +#include <cm/optional> +#include <cm/utility> #include <iostream> #include <type_traits> -#include <utility> #include <vector> class EventLogger; diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx index 075892f..3b47a9c 100644 --- a/Tests/CMakeLib/testString.cxx +++ b/Tests/CMakeLib/testString.cxx @@ -4,7 +4,7 @@ #include "cmString.hxx" #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" +#include <cm/string_view> #include <cstddef> #include <cstring> diff --git a/Tests/CMakeLib/testStringAlgorithms.cxx b/Tests/CMakeLib/testStringAlgorithms.cxx index a92a910..4e48f6e 100644 --- a/Tests/CMakeLib/testStringAlgorithms.cxx +++ b/Tests/CMakeLib/testStringAlgorithms.cxx @@ -3,7 +3,8 @@ #include <cmConfigure.h> // IWYU pragma: keep -#include "cm_string_view.hxx" +#include <cm/string_view> + #include <iostream> #include <sstream> #include <string> diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx index 63c9943..8cee49d 100644 --- a/Tests/CMakeLib/testUVProcessChain.cxx +++ b/Tests/CMakeLib/testUVProcessChain.cxx @@ -15,7 +15,7 @@ #include <csignal> -#include "cm_memory.hxx" +#include <cm/memory> struct ExpectedStatus { diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index 263665d..a77ec90 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx @@ -44,7 +44,7 @@ int main(int argc, char** argv) } if (command == "dedup") { // Use a nested scope to free all resources before aborting below. - { + try { std::string input = getStdin(); std::set<char> seen; std::string output; @@ -56,6 +56,7 @@ int main(int argc, char** argv) } std::cout << output << std::flush; std::cerr << "3" << std::flush; + } catch (...) { } // On Windows, the exit code of abort() is different between debug and diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index c14107a..78ae7aa 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1394,6 +1394,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH GIF Git GLEW + GnuTLS GSL GTK2 Iconv diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt index 796e133..64845c5 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt +++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt @@ -16,21 +16,29 @@ else() endif() #Goal for this example: -# Build a static library that defines multiple methods and kernels that -# use each other. -# Resolve the device symbols into that static library -# Verify that we can't use those device symbols from anything that links +# 1. Build two static libraries that defines multiple methods and kernels +# 2. Resolve the device symbols into the second static library, therefore +# confirming that the first static library is on the device link line +# 3. Verify that we can't use those device symbols from anything that links # to the static library -string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CUDA_STANDARD 11) -add_library(CUDAResolveDeviceLib STATIC file1.cu file2.cu) +add_library(CUDAResolveDeviceDepsA STATIC file1.cu) +add_library(CUDAResolveDeviceDepsB STATIC file2.cu) +set_target_properties(CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB + PROPERTIES + CUDA_SEPARABLE_COMPILATION ON + POSITION_INDEPENDENT_CODE ON) + +add_library(CUDAResolveDeviceLib STATIC file2_launch.cu) set_target_properties(CUDAResolveDeviceLib PROPERTIES CUDA_SEPARABLE_COMPILATION ON CUDA_RESOLVE_DEVICE_SYMBOLS ON POSITION_INDEPENDENT_CODE ON) +target_link_libraries(CUDAResolveDeviceLib PRIVATE CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB) if(dump_command) add_custom_command(TARGET CUDAResolveDeviceLib POST_BUILD @@ -45,7 +53,8 @@ endif() add_executable(CudaOnlyResolveDeviceSymbols main.cu) set_target_properties(CudaOnlyResolveDeviceSymbols PROPERTIES - CUDA_SEPARABLE_COMPILATION ON) + CUDA_SEPARABLE_COMPILATION OFF + CUDA_RESOLVE_DEVICE_SYMBOLS OFF) target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE CUDAResolveDeviceLib) diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h index ff1945c..b33bcae 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h @@ -1,7 +1,10 @@ #pragma once + struct result_type { int input; int sum; }; + +result_type __device__ file1_func(int x); diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu index 278fd6c..0e5e7aa 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu @@ -1,25 +1,9 @@ #include "file2.h" -result_type __device__ file1_func(int x); - result_type_dynamic __device__ file2_func(int x) { const result_type r = file1_func(x); const result_type_dynamic rd{ r.input, r.sum, true }; return rd; } - -static __global__ void file2_kernel(result_type_dynamic& r, int x) -{ - // call static_func which is a method that is defined in the - // static library that is always out of date - r = file2_func(x); -} - -int file2_launch_kernel(int x) -{ - result_type_dynamic r; - file2_kernel<<<1, 1>>>(r, x); - return r.sum; -} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h index d2dbaa4..c6e2875 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h @@ -8,3 +8,5 @@ struct result_type_dynamic int sum; bool from_static; }; + +result_type_dynamic __device__ file2_func(int x); diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu new file mode 100644 index 0000000..4e8da13 --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu @@ -0,0 +1,18 @@ + +#include "file2.h" + +static __global__ void file2_kernel(result_type_dynamic& r, int x) +{ + // call static_func which is a method that is defined in the + // static library that is always out of date + r = file2_func(x); +} + +static __global__ void file2_kernel(result_type_dynamic& r, int x); + +int file2_launch_kernel(int x) +{ + result_type_dynamic r; + file2_kernel<<<1, 1>>>(r, x); + return r.sum; +} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu index d464f96..ea842cc 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu +++ b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu @@ -1,26 +1,10 @@ #include <iostream> -#include "file1.h" #include "file2.h" int file2_launch_kernel(int x); -result_type_dynamic __device__ file2_func(int x); -static __global__ void main_kernel(result_type_dynamic& r, int x) -{ - // call function that was not device linked to us, this will cause - // a runtime failure of "invalid device function" - r = file2_func(x); -} - -int main_launch_kernel(int x) -{ - result_type_dynamic r; - main_kernel<<<1, 1>>>(r, x); - return r.sum; -} - int choose_cuda_device() { int nDevices = 0; @@ -62,12 +46,10 @@ int main(int argc, char** argv) return 0; } - main_launch_kernel(1); + file2_launch_kernel(1); cudaError_t err = cudaGetLastError(); - if (err == cudaSuccess) { - // This kernel launch should fail as the file2_func was device linked - // into the static library and is not usable by the executable - std::cerr << "main_launch_kernel: kernel launch should have failed" + if (err != cudaSuccess) { + std::cerr << "file2_launch_kernel: kernel launch should have passed" << std::endl; return 1; } diff --git a/Tests/CustomCommandByproducts/CMakeLists.txt b/Tests/CustomCommandByproducts/CMakeLists.txt index d0bf648..08c897c 100644 --- a/Tests/CustomCommandByproducts/CMakeLists.txt +++ b/Tests/CustomCommandByproducts/CMakeLists.txt @@ -14,20 +14,21 @@ add_custom_command( # Generate a byproduct in a rule that runs in a dependency of the consumer. add_custom_command( - OUTPUT timestamp2.txt + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/timestamp2.txt COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in byproduct2.c - BYPRODUCTS byproduct2.c + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/byproduct2.c COMMAND ${CMAKE_COMMAND} -E touch timestamp2.txt DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in ) -add_custom_target(Producer2 DEPENDS timestamp2.txt) +add_custom_target(Producer2 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/timestamp2.txt) # Generate a byproduct in a custom target. add_custom_target(Producer3_4 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/byproduct3.c.in byproduct3.c - BYPRODUCTS byproduct3.c + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/byproduct3.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct3.c.in ) # Generate a byproduct in a custom target POST_BUILD command. @@ -35,33 +36,37 @@ add_custom_command( TARGET Producer3_4 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/byproduct4.c.in byproduct4.c - BYPRODUCTS byproduct4.c + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../CustomCommandByproducts/byproduct4.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct4.c.in ) -add_executable(ProducerExe ProducerExe.c) +add_executable(ProducerExe5_6_7 ProducerExe.c) # Generate a byproduct in an executable POST_BUILD command. add_custom_command( - TARGET ProducerExe POST_BUILD + TARGET ProducerExe5_6_7 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/byproduct5.c.in byproduct5.c BYPRODUCTS byproduct5.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct5.c.in ) # Generate a byproduct in an executable PRE_LINK command. add_custom_command( - TARGET ProducerExe PRE_LINK + TARGET ProducerExe5_6_7 PRE_LINK COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/byproduct6.c.in byproduct6.c BYPRODUCTS byproduct6.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct6.c.in ) # Generate a byproduct in an executable PRE_BUILD command. add_custom_command( - TARGET ProducerExe PRE_BUILD + TARGET ProducerExe5_6_7 PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/byproduct7.c.in byproduct7.c BYPRODUCTS byproduct7.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct7.c.in ) # Generate a byproduct in a custom command that consumes other byproducts. @@ -80,6 +85,25 @@ add_custom_command(OUTPUT timestamp8.txt ${CMAKE_CURRENT_SOURCE_DIR}/byproduct8.c.in ) +add_executable(ProducerExe9 ProducerExe.c) + +# Generate a byproduct in a custom target which depends on a byproduct of a +# POST_BUILD command (test if dependency of custom target Producer9 to +# ProducerExe9 is added). +add_custom_command( + TARGET ProducerExe9 POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct9.c.in byproduct9a.c + BYPRODUCTS byproduct9a.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct9.c.in + ) +add_custom_target(Producer9 + COMMAND ${CMAKE_COMMAND} -E copy_if_different + byproduct9a.c byproduct9.c + BYPRODUCTS byproduct9.c + DEPENDS byproduct9a.c + ) + # Generate the library file of an imported target as a byproduct # of an external project. get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) @@ -136,10 +160,13 @@ add_executable(CustomCommandByproducts byproduct6.c byproduct7.c byproduct8.c timestamp8.txt + byproduct9.c ) + +# Dependencies to byproducts of custom commands other than build events are not +# yet traced (see issue #19005). add_dependencies(CustomCommandByproducts Producer2) -add_dependencies(CustomCommandByproducts Producer3_4) -add_dependencies(CustomCommandByproducts ProducerExe) + target_link_libraries(CustomCommandByproducts ExternalLibrary) if(CMAKE_GENERATOR STREQUAL "Ninja") diff --git a/Tests/CustomCommandByproducts/CustomCommandByproducts.c b/Tests/CustomCommandByproducts/CustomCommandByproducts.c index 02ad7ea..0658d05 100644 --- a/Tests/CustomCommandByproducts/CustomCommandByproducts.c +++ b/Tests/CustomCommandByproducts/CustomCommandByproducts.c @@ -6,10 +6,11 @@ extern int byproduct5(void); extern int byproduct6(void); extern int byproduct7(void); extern int byproduct8(void); +extern int byproduct9(void); extern int ExternalLibrary(void); int main(void) { return (byproduct1() + byproduct2() + byproduct3() + byproduct4() + byproduct5() + byproduct6() + byproduct7() + byproduct8() + - ExternalLibrary() + 0); + byproduct9() + ExternalLibrary() + 0); } diff --git a/Tests/CustomCommandByproducts/byproduct9.c.in b/Tests/CustomCommandByproducts/byproduct9.c.in new file mode 100644 index 0000000..11eed2c --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct9.c.in @@ -0,0 +1 @@ +int byproduct9(void) { return 0; } diff --git a/Tests/FindEnvModules/EnvModules.cmake b/Tests/FindEnvModules/EnvModules.cmake index 0c81bf2..21b0042 100644 --- a/Tests/FindEnvModules/EnvModules.cmake +++ b/Tests/FindEnvModules/EnvModules.cmake @@ -18,18 +18,16 @@ if(avail_mods) message("module list") env_module_list(loaded_mods) + set(mod0_found FALSE) foreach(mod IN LISTS loaded_mods) message(" ${mod}") + if(NOT mod0_found AND mod MATCHES "^${mod0}") + set(mod0_found ${mod}) + endif() endforeach() - list(LENGTH loaded_mods num_loaded_mods) - message("Number of modules loaded: ${num_loaded_mods}") - if(NOT num_loaded_mods EQUAL 1) - message(FATAL_ERROR "Exactly 1 module should be loaded. Found ${num_loaded_mods}") - endif() - - list(GET loaded_mods 0 mod0_actual) - if(NOT (mod0_actual MATCHES "^${mod0}")) - message(FATAL_ERROR "Loaded module does not match ${mod0}. Actual: ${mod0_actual}") + if(NOT mod0_found) + message(FATAL_ERROR "Requested module ${mod0} not found in loaded modules") endif() + message("module ${mod0} found loaded as ${mod0_found}") endif() diff --git a/Tests/FindGnuTLS/CMakeLists.txt b/Tests/FindGnuTLS/CMakeLists.txt new file mode 100644 index 0000000..059ac7b --- /dev/null +++ b/Tests/FindGnuTLS/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindGnuTLS.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindGnuTLS/Test" + "${CMake_BINARY_DIR}/Tests/FindGnuTLS/Test" + ${build_generator_args} + --build-project TestFindGnuTLS + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/FindGnuTLS/Test/CMakeLists.txt b/Tests/FindGnuTLS/Test/CMakeLists.txt new file mode 100644 index 0000000..c5a9819 --- /dev/null +++ b/Tests/FindGnuTLS/Test/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.4) +project(TestFindGnuTLS C) +include(CTest) + +find_package(GnuTLS REQUIRED) + +add_definitions(-DCMAKE_EXPECTED_GNUTLS_VERSION="${GNUTLS_VERSION}") + +add_executable(test_tgt main.c) +target_link_libraries(test_tgt GnuTLS::GnuTLS) +add_test(NAME test_tgt COMMAND test_tgt) + +add_executable(test_var main.c) +target_include_directories(test_var PRIVATE ${GNUTLS_INCLUDE_DIRS}) +target_link_libraries(test_var PRIVATE ${GNUTLS_LIBRARIES}) +target_compile_definitions(test_var PRIVATE ${GNUTLS_DEFINITIONS}) +add_test(NAME test_var COMMAND test_var) diff --git a/Tests/FindGnuTLS/Test/main.c b/Tests/FindGnuTLS/Test/main.c new file mode 100644 index 0000000..122fb2d --- /dev/null +++ b/Tests/FindGnuTLS/Test/main.c @@ -0,0 +1,22 @@ +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include <gnutls/gnutls.h> + +int main() +{ + // test the linker + gnutls_session_t session; + if (gnutls_init(&session, GNUTLS_CLIENT)) { + gnutls_deinit(session); + } + + // check the version + char gnutls_version_string[16]; + snprintf(gnutls_version_string, 16, "%i.%i.%i", GNUTLS_VERSION_MAJOR, + GNUTLS_VERSION_MINOR, GNUTLS_VERSION_PATCH); + assert(strcmp(gnutls_version_string, CMAKE_EXPECTED_GNUTLS_VERSION) == 0); + + return 0; +} diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 3ff2b85..9d51342 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -86,7 +86,7 @@ add_custom_target(check-part1 ALL -Dtest_colons_4=$<1:C:\\CMake> -Dtest_colons_5=$<1:C:/CMake> -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake - COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 4)" + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 5)" VERBATIM ) @@ -157,7 +157,7 @@ add_custom_target(check-part2 ALL -Dtest_arbitrary_content_comma_9=$<1:a,,b,,> -Dtest_arbitrary_content_comma_10=$<1:,,a,,b,,> -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake - COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 4)" + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 5)" VERBATIM ) @@ -251,7 +251,7 @@ add_custom_target(check-part3 ALL -Dequal22=$<EQUAL:10,-012> -Dequal23=$<EQUAL:-10,-012> -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake - COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 4)" + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 5)" VERBATIM ) @@ -277,7 +277,27 @@ add_custom_target(check-part4 ALL -DWIN32=${WIN32} -DCMAKE_GENERATOR=${CMAKE_GENERATOR} -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part4.cmake - COMMAND ${CMAKE_COMMAND} -E echo "check done (part 4 of 4)" + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 4 of 5)" + VERBATIM + ) + +add_custom_target(check-part5 ALL + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 5 of 5)" + DEPENDS check-part5.stamp + VERBATIM + ) + +add_custom_command( + OUTPUT check-part5.stamp + DEPENDS $<FILTER:file.foo.bar,EXCLUDE,\\.foo\\.bar$> + COMMAND ${CMAKE_COMMAND} -E sleep 0 + VERBATIM + ) +set_property(SOURCE check-part5.stamp PROPERTY SYMBOLIC 1) + +add_custom_command( + OUTPUT file.foo.bar + COMMAND ${CMAKE_COMMAND} -P check-part5.cmake VERBATIM ) diff --git a/Tests/GeneratorExpression/check-part5.cmake b/Tests/GeneratorExpression/check-part5.cmake new file mode 100644 index 0000000..77d1387 --- /dev/null +++ b/Tests/GeneratorExpression/check-part5.cmake @@ -0,0 +1 @@ +message(SEND_ERROR "$<FILTER:file.foo.bar,EXCLUDE,\\.foo\\.bar$> genex in DEPENDS argument of 'add_custom_command()' is not empty") diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt index 8e8fa07..729bba3 100644 --- a/Tests/Plugin/CMakeLists.txt +++ b/Tests/Plugin/CMakeLists.txt @@ -10,14 +10,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/plugin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/static) -# We need the dynamic loader support from KWSys to load the plugin in -# the executable. -set(KWSYS_NAMESPACE kwsys) -set(KWSYS_HEADER_ROOT ${Plugin_BINARY_DIR}/include) -set(KWSYS_USE_DynamicLoader 1) -set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8) -add_subdirectory(${Plugin_SOURCE_DIR}/../../Source/kwsys src/kwsys) - # Configure the location of plugins. configure_file(${Plugin_SOURCE_DIR}/src/example_exe.h.in ${Plugin_BINARY_DIR}/include/example_exe.h @ONLY) @@ -36,14 +28,14 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND endif() # Create an executable that exports an API for use by plugins. -add_executable(example_exe src/example_exe.cxx) +add_executable(example_exe src/example_exe.cxx src/DynamicLoader.cxx) set_target_properties(example_exe PROPERTIES ENABLE_EXPORTS 1 OUTPUT_NAME example # Test placing exe import library in unique directory. ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/exe ) -target_link_libraries(example_exe kwsys) +target_link_libraries(example_exe ${CMAKE_DL_LIBS}) # Create a plugin that uses the API provided by the executable. # This module "links" to the executable to use the symbols. diff --git a/Tests/Plugin/include/DynamicLoader.hxx b/Tests/Plugin/include/DynamicLoader.hxx new file mode 100644 index 0000000..20b37de --- /dev/null +++ b/Tests/Plugin/include/DynamicLoader.hxx @@ -0,0 +1,49 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See https://cmake.org/licensing#kwsys for details. */ +#ifndef DynamicLoader_hxx +#define DynamicLoader_hxx + +#include <string> + +#if defined(__hpux) +# include <dl.h> +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> +#elif defined(__APPLE__) +# include <AvailabilityMacros.h> +# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 +# include <mach-o/dyld.h> +# endif +#elif defined(__BEOS__) +# include <be/kernel/image.h> +#endif + +class DynamicLoader +{ +public: +#if defined(__hpux) + typedef shl_t LibraryHandle; +#elif defined(_WIN32) && !defined(__CYGWIN__) + typedef HMODULE LibraryHandle; +#elif defined(__APPLE__) +# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 + typedef NSModule LibraryHandle; +# else + typedef void* LibraryHandle; +# endif +#elif defined(__BEOS__) + typedef image_id LibraryHandle; +#else // POSIX + typedef void* LibraryHandle; +#endif + + typedef void (*SymbolPointer)(); + + static LibraryHandle OpenLibrary(const std::string&); + + static int CloseLibrary(LibraryHandle); + + static SymbolPointer GetSymbolAddress(LibraryHandle, const std::string&); +}; + +#endif diff --git a/Tests/Plugin/src/DynamicLoader.cxx b/Tests/Plugin/src/DynamicLoader.cxx new file mode 100644 index 0000000..d4a2637 --- /dev/null +++ b/Tests/Plugin/src/DynamicLoader.cxx @@ -0,0 +1,263 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See https://cmake.org/licensing#kwsys for details. */ +#if defined(_WIN32) +# define NOMINMAX // hide min,max to not conflict with <limits> +#endif + +#include <DynamicLoader.hxx> + +#if defined(__hpux) +# include <dl.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L); +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + if (!lib) { + return 0; + } + return !shl_unload(lib); +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + void* addr; + int status; + + /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default) + * TYPE_DATA Look for a symbol in the data segment (for example, + * variables). + * TYPE_UNDEFINED Look for any symbol. + */ + status = shl_findsym(&lib, sym.c_str(), TYPE_UNDEFINED, &addr); + void* result = (status < 0) ? (void*)0 : addr; + + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); +} + +#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1030) +# include <mach-o/dyld.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + NSObjectFileImageReturnCode rc; + NSObjectFileImage image = 0; + + rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image); + // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file + if (rc != NSObjectFileImageSuccess) { + return 0; + } + NSModule handle = NSLinkModule(image, libname.c_str(), + NSLINKMODULE_OPTION_BINDNOW | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(image); + return handle; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE); + return success; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + void* result = 0; + // Need to prepend symbols with '_' on Apple-gcc compilers + std::string rsym = '_' + sym; + + NSSymbol symbol = NSLookupSymbolInModule(lib, rsym.c_str()); + if (symbol) { + result = NSAddressOfSymbol(symbol); + } + + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); +} + +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> + +# include <stdio.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + DynamicLoader::LibraryHandle lh; + int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0); + wchar_t* wchars = new wchar_t[length + 1]; + wchars[0] = '\0'; + MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, wchars, length); + lh = LoadLibraryW(wchars); + delete[] wchars; + return lh; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + return (int)FreeLibrary(lib); +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + void* result; +# if defined(__BORLANDC__) || defined(__WATCOMC__) + // Need to prepend symbols with '_' + std::string ssym = '_' + sym; + const char* rsym = ssym.c_str(); +# else + const char* rsym = sym.c_str(); +# endif + result = (void*)GetProcAddress(lib, rsym); +// Hack to cast pointer-to-data to pointer-to-function. +# ifdef __WATCOMC__ + return *(DynamicLoader::SymbolPointer*)(&result); +# else + return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); +# endif +} + +#elif defined(__BEOS__) +# include <be/kernel/image.h> +# include <be/support/Errors.h> + +static image_id last_dynamic_err = B_OK; + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + // image_id's are integers, errors are negative. Add one just in case we + // get a valid image_id of zero (is that even possible?). + image_id rc = load_add_on(libname.c_str()); + if (rc < 0) { + last_dynamic_err = rc; + return 0; + } + + return rc + 1; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + if (!lib) { + last_dynamic_err = B_BAD_VALUE; + return 0; + } else { + // The function dlclose() returns 0 on success, and non-zero on error. + status_t rc = unload_add_on(lib - 1); + if (rc != B_OK) { + last_dynamic_err = rc; + return 0; + } + } + + return 1; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + // Hack to cast pointer-to-data to pointer-to-function. + union + { + void* pvoid; + DynamicLoader::SymbolPointer psym; + } result; + + result.psym = NULL; + + if (!lib) { + last_dynamic_err = B_BAD_VALUE; + } else { + // !!! FIXME: BeOS can do function-only lookups...does this ever + // !!! FIXME: actually _want_ a data symbol lookup, or was this union + // !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only). + status_t rc = + get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid); + if (rc != B_OK) { + last_dynamic_err = rc; + result.psym = NULL; + } + } + return result.psym; +} + +#elif defined(__MINT__) +# define _GNU_SOURCE /* for program_invocation_name */ +# include <dld.h> +# include <errno.h> +# include <malloc.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + char* name = (char*)calloc(1, libname.size() + 1); + dld_init(program_invocation_name); + strncpy(name, libname.c_str(), libname.size()); + dld_link(libname.c_str()); + return (void*)name; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + dld_unlink_by_file((char*)lib, 0); + free(lib); + return 0; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + // Hack to cast pointer-to-data to pointer-to-function. + union + { + void* pvoid; + DynamicLoader::SymbolPointer psym; + } result; + result.pvoid = dld_get_symbol(sym.c_str()); + return result.psym; +} + +#else +# include <dlfcn.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + return dlopen(libname.c_str(), RTLD_LAZY); +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + if (lib) { + // The function dlclose() returns 0 on success, and non-zero on error. + return !dlclose(lib); + } + // else + return 0; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + // Hack to cast pointer-to-data to pointer-to-function. + union + { + void* pvoid; + DynamicLoader::SymbolPointer psym; + } result; + result.pvoid = dlsym(lib, sym.c_str()); + return result.psym; +} + +#endif diff --git a/Tests/Plugin/src/example_exe.cxx b/Tests/Plugin/src/example_exe.cxx index 257a35c..fd810a9 100644 --- a/Tests/Plugin/src/example_exe.cxx +++ b/Tests/Plugin/src/example_exe.cxx @@ -1,4 +1,4 @@ -#include <kwsys/DynamicLoader.hxx> +#include "DynamicLoader.hxx" #include <example.h> @@ -24,20 +24,17 @@ extern "C" int example_exe_function() int main() { - std::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/"; - libName += kwsys::DynamicLoader::LibPrefix(); - libName += "example_mod_1"; - libName += kwsys::DynamicLoader::LibExtension(); - kwsys::DynamicLoader::LibraryHandle handle = - kwsys::DynamicLoader::OpenLibrary(libName.c_str()); + std::string const libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR + "/" EXAMPLE_EXE_MOD_PREFIX "example_mod_1" EXAMPLE_EXE_MOD_SUFFIX; + DynamicLoader::LibraryHandle handle = DynamicLoader::OpenLibrary(libName); if (!handle) { // Leave the .c_str() on this one. It is needed on OpenWatcom. std::cerr << "Could not open plugin \"" << libName.c_str() << "\"!" << std::endl; return 1; } - kwsys::DynamicLoader::SymbolPointer sym = - kwsys::DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function"); + DynamicLoader::SymbolPointer sym = + DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function"); if (!sym) { std::cerr << "Could not get plugin symbol \"example_mod_1_function\"!" << std::endl; @@ -52,6 +49,6 @@ int main() std::cerr << "Incorrect return value from plugin!" << std::endl; return 1; } - kwsys::DynamicLoader::CloseLibrary(handle); + DynamicLoader::CloseLibrary(handle); return 0; } diff --git a/Tests/Plugin/src/example_exe.h.in b/Tests/Plugin/src/example_exe.h.in index 62f0d9f..af71021 100644 --- a/Tests/Plugin/src/example_exe.h.in +++ b/Tests/Plugin/src/example_exe.h.in @@ -2,5 +2,7 @@ #define example_exe_h #define EXAMPLE_EXE_PLUGIN_DIR "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@" +#define EXAMPLE_EXE_MOD_PREFIX "@CMAKE_SHARED_MODULE_PREFIX@" +#define EXAMPLE_EXE_MOD_SUFFIX "@CMAKE_SHARED_MODULE_SUFFIX@" #endif diff --git a/Tests/QtAutogen/MocInclude/CMakeLists.txt b/Tests/QtAutogen/MocInclude/CMakeLists.txt new file mode 100644 index 0000000..04c8baf --- /dev/null +++ b/Tests/QtAutogen/MocInclude/CMakeLists.txt @@ -0,0 +1,112 @@ +cmake_minimum_required(VERSION 3.15) +project(MocInclude) +get_filename_component(CS_REAL ${CMAKE_CURRENT_SOURCE_DIR} REALPATH) +include("${CS_REAL}/../AutogenCoreTest.cmake") + +# Test moc include patterns + +set(COM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Common") + +macro(addCopyCommand from to) + add_custom_command( + OUTPUT ${to} + COMMAND ${CMAKE_COMMAND} -E copy ${from} ${to} + DEPENDS ${from}) +endmacro() + +# Create an executable +function(makeExecutable TARGET_NAME) + # Utility variables + set(CB_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + # Copy directory + file(REMOVE_RECURSE "${CB_DIR}/InIncludes") + file(COPY "${COM_DIR}/InIncludes.in" DESTINATION "${CB_DIR}") + file(RENAME "${CB_DIR}/InIncludes.in" "${CB_DIR}/InIncludes") + + # Generate .moc file from the header externally and + # enabled SKIP_AUTOMOC on the source file + qtx_wrap_cpp(ExternDotMOC ${COM_DIR}/ExternDot.hpp OPTIONS "-p" "./") + addCopyCommand(${ExternDotMOC} + ${CB_DIR}/ExternDot.moc) + set_property( + SOURCE ${COM_DIR}/ExternDot.cpp + PROPERTY SKIP_AUTOMOC ON) + + # Generate .moc file from the GENERATED header externally + # and enabled SKIP_AUTOMOC on the source file + addCopyCommand(${COM_DIR}/ExternDotGenerated.hpp.in + ${CB_DIR}/ExternDotGenerated.hpp) + addCopyCommand(${COM_DIR}/ExternDotGenerated.cpp.in + ${CB_DIR}/ExternDotGenerated.cpp) + qtx_wrap_cpp(ExternDotGeneratedMOC + ${CB_DIR}/ExternDotGenerated.hpp + OPTIONS "-p" "./") + addCopyCommand(${ExternDotGeneratedMOC} + ${CB_DIR}/ExternDotGenerated.moc) + set_property( + SOURCE ${CB_DIR}/ExternDotGenerated.cpp + PROPERTY SKIP_AUTOMOC ON) + + # Generate header moc file externally with a custom name + # and enabled SKIP_AUTOMOC on the header + qtx_wrap_cpp(MixedCustomMOC + ${COM_DIR}/MixedCustom.hpp + OPTIONS "-p" "./") + addCopyCommand(${MixedCustomMOC} + ${CB_DIR}/MixedCustom_extMoc.cpp) + set_property( + SOURCE ${COM_DIR}/MixedCustom.hpp + PROPERTY SKIP_AUTOMOC ON) + # Custom target to depend on + add_custom_target("${TARGET_NAME}_MixedCustom" + DEPENDS ${CB_DIR}/MixedCustom_extMoc.cpp + BYPRODUCTS ${CB_DIR}/moc_MixedCustom.cpp + COMMAND ${CMAKE_COMMAND} -E copy + ${COM_DIR}/moc_MixedCustom.cpp.in + ${CB_DIR}/moc_MixedCustom.cpp) + + add_executable(${TARGET_NAME} + # Test own "*.moc" and "moc_*.cpp" includes + ${COM_DIR}/None.cpp + ${COM_DIR}/OwnDot.cpp + ${COM_DIR}/OwnUnderscore.cpp + ${COM_DIR}/OwnDotUnderscore.cpp + + # Test "moc_*.cpp" includes of other files + ${COM_DIR}/OtherUnderscore.cpp + ${COM_DIR}/OtherUnderscoreExtra.cpp + ${COM_DIR}/OtherUnderscoreSub.cpp + ${COM_DIR}/OtherUnderscoreSubDir/SubExtra.cpp + + # Test relative ../../ path for moc includes + ${COM_DIR}/DualSub/Second/Second.cpp + ${COM_DIR}/DualSubMocked.cpp + + # Test externally generated moc files + ${COM_DIR}/ExternDot.cpp + ${CB_DIR}/ExternDot.moc + + # Test externally generated moc files for GENERATED source + ${CB_DIR}/ExternDotGenerated.cpp + ${CB_DIR}/ExternDotGenerated.moc + + # Test externally generated moc files and SKIP_AUTOMOC enabled header + ${COM_DIR}/MixedSkipped.cpp + ${COM_DIR}/MixedCustom.hpp + ${COM_DIR}/MixedCustom.cpp + + # Test sources in a subdirectory + ${CB_DIR}/InIncludes/SubOwnDot.cpp + ${COM_DIR}/InIncludesMoc.cpp + ) + add_dependencies(${TARGET_NAME} "${TARGET_NAME}_MixedCustom") + target_include_directories(${TARGET_NAME} PRIVATE "${COM_DIR}") + target_include_directories(${TARGET_NAME} PRIVATE "${CB_DIR}") + target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + target_link_libraries(${TARGET_NAME} ${QT_LIBRARIES}) + set_target_properties(${TARGET_NAME} PROPERTIES AUTOMOC ON) +endfunction() + +add_subdirectory(Strict) +add_subdirectory(Relaxed) diff --git a/Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.cpp b/Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.cpp new file mode 100644 index 0000000..453add1 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.cpp @@ -0,0 +1,11 @@ +#include "Second.hpp" + +Second::Second() +{ +} + +Second::~Second() +{ +} + +#include "../../moc_DualSubMocked.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.hpp b/Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.hpp new file mode 100644 index 0000000..e1f3eac --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.hpp @@ -0,0 +1,14 @@ +#ifndef Second_HPP +#define Second_HPP + +#include <QObject> + +class Second : public QObject +{ + Q_OBJECT +public: + Second(); + ~Second(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/DualSubMocked.cpp b/Tests/QtAutogen/MocInclude/Common/DualSubMocked.cpp new file mode 100644 index 0000000..1d4658d --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/DualSubMocked.cpp @@ -0,0 +1,9 @@ +#include "DualSubMocked.hpp" + +DualSubMocked::DualSubMocked() +{ +} + +DualSubMocked::~DualSubMocked() +{ +} diff --git a/Tests/QtAutogen/MocInclude/Common/DualSubMocked.hpp b/Tests/QtAutogen/MocInclude/Common/DualSubMocked.hpp new file mode 100644 index 0000000..58cb571 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/DualSubMocked.hpp @@ -0,0 +1,15 @@ +#ifndef DualSubMocked_HPP +#define DualSubMocked_HPP + +#include <QObject> + +// Header moc file is included by DualSub/Second/Second.cpp +class DualSubMocked : public QObject +{ + Q_OBJECT +public: + DualSubMocked(); + ~DualSubMocked(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/ExternDot.cpp b/Tests/QtAutogen/MocInclude/Common/ExternDot.cpp new file mode 100644 index 0000000..2495aa7 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/ExternDot.cpp @@ -0,0 +1,11 @@ +#include "ExternDot.hpp" + +ExternDot::ExternDot() +{ +} + +ExternDot::~ExternDot() +{ +} + +#include "ExternDot.moc" diff --git a/Tests/QtAutogen/MocInclude/SObjA.hpp b/Tests/QtAutogen/MocInclude/Common/ExternDot.hpp index 1436abc..7eaab2a 100644 --- a/Tests/QtAutogen/MocInclude/SObjA.hpp +++ b/Tests/QtAutogen/MocInclude/Common/ExternDot.hpp @@ -1,15 +1,15 @@ -#ifndef SOBJA_HPP -#define SOBJA_HPP +#ifndef ExternDot_HPP +#define ExternDot_HPP #include <QObject> // Object source includes externally generated .moc file -class SObjA : public QObject +class ExternDot : public QObject { Q_OBJECT public: - SObjA(); - ~SObjA(); + ExternDot(); + ~ExternDot(); }; #endif diff --git a/Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.cpp.in b/Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.cpp.in new file mode 100644 index 0000000..09ce5cd --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.cpp.in @@ -0,0 +1,11 @@ +#include "ExternDotGenerated.hpp" + +ExternDotGenerated::ExternDotGenerated() +{ +} + +ExternDotGenerated::~ExternDotGenerated() +{ +} + +#include "ExternDotGenerated.moc" diff --git a/Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.hpp.in b/Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.hpp.in new file mode 100644 index 0000000..21c69be --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.hpp.in @@ -0,0 +1,15 @@ +#ifndef ExternDotGenerated_HPP +#define ExternDotGenerated_HPP + +#include <QObject> + +// GENERATED Object source includes externally generated .moc file +class ExternDotGenerated : public QObject +{ + Q_OBJECT +public: + ExternDotGenerated(); + ~ExternDotGenerated(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.cpp b/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.cpp new file mode 100644 index 0000000..af35711 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.cpp @@ -0,0 +1,43 @@ +#include "SubOwnDot.hpp" +#include "SubOwnDot_p.hpp" + +namespace InIncludes { + +class SubOwnDotLocal : public QObject +{ + Q_OBJECT +public: + SubOwnDotLocal(); + ~SubOwnDotLocal(); +}; + +SubOwnDotLocal::SubOwnDotLocal() +{ +} + +SubOwnDotLocal::~SubOwnDotLocal() +{ +} + +SubOwnDotPrivate::SubOwnDotPrivate() +{ +} + +SubOwnDotPrivate::~SubOwnDotPrivate() +{ +} + +SubOwnDot::SubOwnDot() +{ + SubOwnDotPrivate privateObj; + SubOwnDotLocal localObj; +} + +SubOwnDot::~SubOwnDot() +{ +} + +} // End of namespace + +// For the local QObject +#include "SubOwnDot.moc" diff --git a/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.hpp b/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.hpp new file mode 100644 index 0000000..038ddfa --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.hpp @@ -0,0 +1,17 @@ +#ifndef InIncludes_SubOwnDot_HPP +#define InIncludes_SubOwnDot_HPP + +#include <QObject> + +namespace InIncludes { + +class SubOwnDot : public QObject +{ + Q_OBJECT +public: + SubOwnDot(); + ~SubOwnDot(); +}; +} + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot_p.hpp b/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot_p.hpp new file mode 100644 index 0000000..626a9a8 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot_p.hpp @@ -0,0 +1,18 @@ +#ifndef InIncludes_SubOwnDot_P_HPP +#define InIncludes_SubOwnDot_P_HPP + +#include <QObject> + +namespace InIncludes { + +class SubOwnDotPrivate : public QObject +{ + Q_OBJECT +public: + SubOwnDotPrivate(); + ~SubOwnDotPrivate(); +}; + +} // End of namespace + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/InIncludesMoc.cpp b/Tests/QtAutogen/MocInclude/Common/InIncludesMoc.cpp new file mode 100644 index 0000000..88f53a4 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/InIncludesMoc.cpp @@ -0,0 +1,4 @@ + +// Moc a header that is not in the sources but in a directory that +// is in the list of include directories. +#include "InIncludes/moc_SubOwnDot.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/MixedCustom.cpp b/Tests/QtAutogen/MocInclude/Common/MixedCustom.cpp new file mode 100644 index 0000000..557cc62 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/MixedCustom.cpp @@ -0,0 +1,32 @@ +#include "MixedCustom.hpp" + +class MixedCustomLocal : public QObject +{ + Q_OBJECT + +public: + MixedCustomLocal(); + ~MixedCustomLocal(); +}; + +MixedCustomLocal::MixedCustomLocal() +{ +} + +MixedCustomLocal::~MixedCustomLocal() +{ +} + +MixedCustom::MixedCustom() +{ + MixedCustomLocal local; +} + +MixedCustom::~MixedCustom() +{ +} + +// AUTOMOC generated source moc +#include "MixedCustom.moc" +// Externally generated header moc +#include "MixedCustom_extMoc.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/MixedCustom.hpp b/Tests/QtAutogen/MocInclude/Common/MixedCustom.hpp new file mode 100644 index 0000000..6e8ff88 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/MixedCustom.hpp @@ -0,0 +1,20 @@ +#ifndef MixedCustom_HPP +#define MixedCustom_HPP + +#include <QObject> + +// Object source includes +// - externally generated header moc file +// - AUTOMOC generated source .moc file +class MixedCustom : public QObject +{ + Q_OBJECT +public: + MixedCustom(); + ~MixedCustom(); +}; + +// Function forward declaration +void moc_MixedCustom(MixedCustom const& arg); + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/MixedSkipped.cpp b/Tests/QtAutogen/MocInclude/Common/MixedSkipped.cpp new file mode 100644 index 0000000..df08ff1 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/MixedSkipped.cpp @@ -0,0 +1,39 @@ +#include "MixedSkipped.hpp" +#include "MixedCustom.hpp" + +class MixedSkippedLocal : public QObject +{ + Q_OBJECT + +public: + MixedSkippedLocal(); + ~MixedSkippedLocal(); +}; + +MixedSkippedLocal::MixedSkippedLocal() +{ +} + +MixedSkippedLocal::~MixedSkippedLocal() +{ +} + +MixedSkipped::MixedSkipped() +{ + MixedSkippedLocal local; + MixedCustom externCutom; + // Call moc named function + moc_MixedCustom(externCutom); +} + +MixedSkipped::~MixedSkipped() +{ +} + +// Include AUTOMOC generated moc files +#include "MixedSkipped.moc" +#include "moc_MixedSkipped.cpp" + +// Include externally generated moc_ named file that is not a moc file +// and for which the relevant header is SKIP_AUTOMOC enabled +#include "moc_MixedCustom.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/MixedSkipped.hpp b/Tests/QtAutogen/MocInclude/Common/MixedSkipped.hpp new file mode 100644 index 0000000..5f6c664 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/MixedSkipped.hpp @@ -0,0 +1,17 @@ +#ifndef MixedSkipped_HPP +#define MixedSkipped_HPP + +#include <QObject> + +// Object source includes +// - Own moc_ and .moc files. +// - externally generated moc_ file from a SKIP_AUTOMOC enabled header +class MixedSkipped : public QObject +{ + Q_OBJECT +public: + MixedSkipped(); + ~MixedSkipped(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/None.cpp b/Tests/QtAutogen/MocInclude/Common/None.cpp new file mode 100644 index 0000000..d01d5ec --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/None.cpp @@ -0,0 +1,20 @@ +#include "None.hpp" +#include "None_p.h" + +NonePrivate::NonePrivate() +{ +} + +NonePrivate::~NonePrivate() +{ +} + +None::None() + : d(new NonePrivate) +{ +} + +None::~None() +{ + delete d; +} diff --git a/Tests/QtAutogen/MocInclude/Common/None.hpp b/Tests/QtAutogen/MocInclude/Common/None.hpp new file mode 100644 index 0000000..ca0713e --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/None.hpp @@ -0,0 +1,19 @@ +#ifndef None_HPP +#define None_HPP + +#include <QObject> + +// Object source comes without any _moc/.moc includes +class NonePrivate; +class None : public QObject +{ + Q_OBJECT +public: + None(); + ~None(); + +private: + NonePrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/None_p.h b/Tests/QtAutogen/MocInclude/Common/None_p.h new file mode 100644 index 0000000..e209aeb --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/None_p.h @@ -0,0 +1,14 @@ +#ifndef None_P_HPP +#define None_P_HPP + +#include <QObject> + +class NonePrivate : public QObject +{ + Q_OBJECT +public: + NonePrivate(); + ~NonePrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscore.cpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscore.cpp new file mode 100644 index 0000000..219619f --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscore.cpp @@ -0,0 +1,44 @@ +#include "OtherUnderscore.hpp" +#include "OtherUnderscoreExtra.hpp" +#include "OtherUnderscore_p.hpp" + +class OtherUnderscoreLocal : public QObject +{ + Q_OBJECT +public: + OtherUnderscoreLocal(); + ~OtherUnderscoreLocal(); +}; + +OtherUnderscoreLocal::OtherUnderscoreLocal() +{ +} + +OtherUnderscoreLocal::~OtherUnderscoreLocal() +{ +} + +OtherUnderscorePrivate::OtherUnderscorePrivate() +{ + OtherUnderscoreLocal localObj; + OtherUnderscoreExtra extraObj; +} + +OtherUnderscorePrivate::~OtherUnderscorePrivate() +{ +} + +OtherUnderscore::OtherUnderscore() + : d(new OtherUnderscorePrivate) +{ +} + +OtherUnderscore::~OtherUnderscore() +{ + delete d; +} + +// For OtherUnderscoreLocal +#include "OtherUnderscore.moc" +// - Not the own header +#include "moc_OtherUnderscoreExtra.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscore.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscore.hpp new file mode 100644 index 0000000..a4ff603 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscore.hpp @@ -0,0 +1,19 @@ +#ifndef OtherUnderscore_HPP +#define OtherUnderscore_HPP + +#include <QObject> + +// Sources includes a moc_ includes of an extra object +class OtherUnderscorePrivate; +class OtherUnderscore : public QObject +{ + Q_OBJECT +public: + OtherUnderscore(); + ~OtherUnderscore(); + +private: + OtherUnderscorePrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.cpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.cpp new file mode 100644 index 0000000..4ccf080 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.cpp @@ -0,0 +1,20 @@ +#include "OtherUnderscoreExtra.hpp" +#include "OtherUnderscoreExtra_p.hpp" + +OtherUnderscoreExtraPrivate::OtherUnderscoreExtraPrivate() +{ +} + +OtherUnderscoreExtraPrivate::~OtherUnderscoreExtraPrivate() +{ +} + +OtherUnderscoreExtra::OtherUnderscoreExtra() + : d(new OtherUnderscoreExtraPrivate) +{ +} + +OtherUnderscoreExtra::~OtherUnderscoreExtra() +{ + delete d; +} diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.hpp new file mode 100644 index 0000000..5afe48c --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.hpp @@ -0,0 +1,18 @@ +#ifndef OtherUnderscoreEXTRA_HPP +#define OtherUnderscoreEXTRA_HPP + +#include <QObject> + +class OtherUnderscoreExtraPrivate; +class OtherUnderscoreExtra : public QObject +{ + Q_OBJECT +public: + OtherUnderscoreExtra(); + ~OtherUnderscoreExtra(); + +private: + OtherUnderscoreExtraPrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra_p.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra_p.hpp new file mode 100644 index 0000000..2066ac3 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra_p.hpp @@ -0,0 +1,14 @@ +#ifndef OtherUnderscoreEXTRA_P_HPP +#define OtherUnderscoreEXTRA_P_HPP + +#include <QObject> + +class OtherUnderscoreExtraPrivate : public QObject +{ + Q_OBJECT +public: + OtherUnderscoreExtraPrivate(); + ~OtherUnderscoreExtraPrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.cpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.cpp new file mode 100644 index 0000000..28850aa --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.cpp @@ -0,0 +1,45 @@ +#include "OtherUnderscoreSub.hpp" +#include "OtherUnderscoreSubDir/SubExtra.hpp" +#include "OtherUnderscoreSub_p.hpp" + +class OtherUnderscoreSubLocal : public QObject +{ + Q_OBJECT +public: + OtherUnderscoreSubLocal(); + ~OtherUnderscoreSubLocal(); +}; + +OtherUnderscoreSubLocal::OtherUnderscoreSubLocal() +{ +} + +OtherUnderscoreSubLocal::~OtherUnderscoreSubLocal() +{ +} + +OtherUnderscoreSubPrivate::OtherUnderscoreSubPrivate() +{ + OtherUnderscoreSubLocal localObj; + SubExtra extraObj; +} + +OtherUnderscoreSubPrivate::~OtherUnderscoreSubPrivate() +{ +} + +OtherUnderscoreSub::OtherUnderscoreSub() + : d(new OtherUnderscoreSubPrivate) +{ +} + +OtherUnderscoreSub::~OtherUnderscoreSub() +{ + delete d; +} + +// For OtherUnderscoreSubLocal +#include "OtherUnderscoreSub.moc" +// - Not the own header +// - in a subdirectory +#include "OtherUnderscoreSubDir/moc_SubExtra.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.hpp new file mode 100644 index 0000000..7feaa46 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.hpp @@ -0,0 +1,19 @@ +#ifndef OtherUnderscoreSub_HPP +#define OtherUnderscoreSub_HPP + +#include <QObject> + +// Sources includes a moc_ includes of an extra object in a subdirectory +class OtherUnderscoreSubPrivate; +class OtherUnderscoreSub : public QObject +{ + Q_OBJECT +public: + OtherUnderscoreSub(); + ~OtherUnderscoreSub(); + +private: + OtherUnderscoreSubPrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.cpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.cpp new file mode 100644 index 0000000..e323ed8 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.cpp @@ -0,0 +1,20 @@ +#include "SubExtra.hpp" +#include "SubExtra_p.hpp" + +SubExtraPrivate::SubExtraPrivate() +{ +} + +SubExtraPrivate::~SubExtraPrivate() +{ +} + +SubExtra::SubExtra() + : d(new SubExtraPrivate) +{ +} + +SubExtra::~SubExtra() +{ + delete d; +} diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.hpp new file mode 100644 index 0000000..5700634 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.hpp @@ -0,0 +1,18 @@ +#ifndef SubExtra_HPP +#define SubExtra_HPP + +#include <QObject> + +class SubExtraPrivate; +class SubExtra : public QObject +{ + Q_OBJECT +public: + SubExtra(); + ~SubExtra(); + +private: + SubExtraPrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra_p.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra_p.hpp new file mode 100644 index 0000000..5a14a2d --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra_p.hpp @@ -0,0 +1,14 @@ +#ifndef SubExtra_P_HPP +#define SubExtra_P_HPP + +#include <QObject> + +class SubExtraPrivate : public QObject +{ + Q_OBJECT +public: + SubExtraPrivate(); + ~SubExtraPrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub_p.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub_p.hpp new file mode 100644 index 0000000..7d5999c --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub_p.hpp @@ -0,0 +1,14 @@ +#ifndef OtherUnderscoreSub_P_HPP +#define OtherUnderscoreSub_P_HPP + +#include <QObject> + +class OtherUnderscoreSubPrivate : public QObject +{ + Q_OBJECT +public: + OtherUnderscoreSubPrivate(); + ~OtherUnderscoreSubPrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OtherUnderscore_p.hpp b/Tests/QtAutogen/MocInclude/Common/OtherUnderscore_p.hpp new file mode 100644 index 0000000..96906cf --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OtherUnderscore_p.hpp @@ -0,0 +1,14 @@ +#ifndef OtherUnderscore_P_HPP +#define OtherUnderscore_P_HPP + +#include <QObject> + +class OtherUnderscorePrivate : public QObject +{ + Q_OBJECT +public: + OtherUnderscorePrivate(); + ~OtherUnderscorePrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OwnDot.cpp b/Tests/QtAutogen/MocInclude/Common/OwnDot.cpp new file mode 100644 index 0000000..1cce272 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnDot.cpp @@ -0,0 +1,39 @@ +#include "OwnDot.hpp" +#include "OwnDot_p.h" + +class OwnDotLocal : public QObject +{ + Q_OBJECT +public: + OwnDotLocal(); + ~OwnDotLocal(); +}; + +OwnDotLocal::OwnDotLocal() +{ +} + +OwnDotLocal::~OwnDotLocal() +{ +} + +OwnDotPrivate::OwnDotPrivate() +{ + OwnDotLocal localObj; +} + +OwnDotPrivate::~OwnDotPrivate() +{ +} + +OwnDot::OwnDot() + : d(new OwnDotPrivate) +{ +} + +OwnDot::~OwnDot() +{ + delete d; +} + +#include "OwnDot.moc" diff --git a/Tests/QtAutogen/MocInclude/Common/OwnDot.hpp b/Tests/QtAutogen/MocInclude/Common/OwnDot.hpp new file mode 100644 index 0000000..6f49f12 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnDot.hpp @@ -0,0 +1,19 @@ +#ifndef OwnDot_HPP +#define OwnDot_HPP + +#include <QObject> + +// Object source comes with a .moc include +class OwnDotPrivate; +class OwnDot : public QObject +{ + Q_OBJECT +public: + OwnDot(); + ~OwnDot(); + +private: + OwnDotPrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.cpp b/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.cpp new file mode 100644 index 0000000..2a0b8ad --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.cpp @@ -0,0 +1,40 @@ +#include "OwnDotUnderscore.hpp" +#include "OwnDotUnderscore_p.h" + +class OwnDotUnderscoreLocal : public QObject +{ + Q_OBJECT +public: + OwnDotUnderscoreLocal(); + ~OwnDotUnderscoreLocal(); +}; + +OwnDotUnderscoreLocal::OwnDotUnderscoreLocal() +{ +} + +OwnDotUnderscoreLocal::~OwnDotUnderscoreLocal() +{ +} + +OwnDotUnderscorePrivate::OwnDotUnderscorePrivate() +{ + OwnDotUnderscoreLocal localObj; +} + +OwnDotUnderscorePrivate::~OwnDotUnderscorePrivate() +{ +} + +OwnDotUnderscore::OwnDotUnderscore() + : d(new OwnDotUnderscorePrivate) +{ +} + +OwnDotUnderscore::~OwnDotUnderscore() +{ + delete d; +} + +#include "OwnDotUnderscore.moc" +#include "moc_OwnDotUnderscore.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.hpp b/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.hpp new file mode 100644 index 0000000..478955c --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.hpp @@ -0,0 +1,19 @@ +#ifndef LOwnDotUnderscore_HPP +#define LOwnDotUnderscore_HPP + +#include <QObject> + +// Object source comes with a .moc and a _moc include +class OwnDotUnderscorePrivate; +class OwnDotUnderscore : public QObject +{ + Q_OBJECT +public: + OwnDotUnderscore(); + ~OwnDotUnderscore(); + +private: + OwnDotUnderscorePrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore_p.h b/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore_p.h new file mode 100644 index 0000000..6950b7f --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore_p.h @@ -0,0 +1,14 @@ +#ifndef OwnDotUnderscore_P_HPP +#define OwnDotUnderscore_P_HPP + +#include <QObject> + +class OwnDotUnderscorePrivate : public QObject +{ + Q_OBJECT +public: + OwnDotUnderscorePrivate(); + ~OwnDotUnderscorePrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OwnDot_p.h b/Tests/QtAutogen/MocInclude/Common/OwnDot_p.h new file mode 100644 index 0000000..f3aff32 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnDot_p.h @@ -0,0 +1,14 @@ +#ifndef OwnDot_P_HPP +#define OwnDot_P_HPP + +#include <QObject> + +class OwnDotPrivate : public QObject +{ + Q_OBJECT +public: + OwnDotPrivate(); + ~OwnDotPrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OwnUnderscore.cpp b/Tests/QtAutogen/MocInclude/Common/OwnUnderscore.cpp new file mode 100644 index 0000000..ebbcf45 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnUnderscore.cpp @@ -0,0 +1,22 @@ +#include "OwnUnderscore.hpp" +#include "OwnUnderscore_p.h" + +OwnUnderscorePrivate::OwnUnderscorePrivate() +{ +} + +OwnUnderscorePrivate::~OwnUnderscorePrivate() +{ +} + +OwnUnderscore::OwnUnderscore() + : d(new OwnUnderscorePrivate) +{ +} + +OwnUnderscore::~OwnUnderscore() +{ + delete d; +} + +#include "moc_OwnUnderscore.cpp" diff --git a/Tests/QtAutogen/MocInclude/Common/OwnUnderscore.hpp b/Tests/QtAutogen/MocInclude/Common/OwnUnderscore.hpp new file mode 100644 index 0000000..e6a6a6e --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnUnderscore.hpp @@ -0,0 +1,19 @@ +#ifndef OwnUnderscore_HPP +#define OwnUnderscore_HPP + +#include <QObject> + +// Object source comes with a _moc include +class OwnUnderscorePrivate; +class OwnUnderscore : public QObject +{ + Q_OBJECT +public: + OwnUnderscore(); + ~OwnUnderscore(); + +private: + OwnUnderscorePrivate* const d; +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/OwnUnderscore_p.h b/Tests/QtAutogen/MocInclude/Common/OwnUnderscore_p.h new file mode 100644 index 0000000..a3a6b00 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/OwnUnderscore_p.h @@ -0,0 +1,14 @@ +#ifndef OwnUnderscore_P_HPP +#define OwnUnderscore_P_HPP + +#include <QObject> + +class OwnUnderscorePrivate : public QObject +{ + Q_OBJECT +public: + OwnUnderscorePrivate(); + ~OwnUnderscorePrivate(); +}; + +#endif diff --git a/Tests/QtAutogen/MocInclude/Common/common.cpp.in b/Tests/QtAutogen/MocInclude/Common/common.cpp.in new file mode 100644 index 0000000..b53e93d --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/common.cpp.in @@ -0,0 +1,32 @@ +#include "DualSub/Second/Second.hpp" +#include "DualSubMocked.hpp" +#include "ExternDot.hpp" +#include "ExternDotGenerated.hpp" +#include "None.hpp" +#include "OtherUnderscore.hpp" +#include "OtherUnderscoreSub.hpp" +#include "OwnDot.hpp" +#include "OwnDotUnderscore.hpp" +#include "OwnUnderscore.hpp" +#include "InIncludes/SubOwnDot.hpp" + +bool @COMMON_FUNCTION_NAME@() +{ + None objNone; + OwnUnderscore objOwnUnderscore; + OwnDot objOwnDot; + OwnDotUnderscore objOwnDotUnderscore; + + OtherUnderscore objOtherUnderscore; + OtherUnderscoreSub objOtherUnderscoreSub; + + Second second; + DualSubMocked dualSubMocked; + + ExternDot objExternDot; + ExternDotGenerated objGeneratedExternDot; + + InIncludes::SubOwnDot subOwnDot; + + return true; +} diff --git a/Tests/QtAutogen/MocInclude/Common/moc_MixedCustom.cpp.in b/Tests/QtAutogen/MocInclude/Common/moc_MixedCustom.cpp.in new file mode 100644 index 0000000..6c44793 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Common/moc_MixedCustom.cpp.in @@ -0,0 +1,5 @@ + +void moc_MixedCustom(MixedCustom const & arg) +{ + (void)arg; +} diff --git a/Tests/QtAutogen/MocInclude/EObjA.cpp b/Tests/QtAutogen/MocInclude/EObjA.cpp deleted file mode 100644 index 7681c29..0000000 --- a/Tests/QtAutogen/MocInclude/EObjA.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "EObjA.hpp" -#include "EObjAExtra.hpp" -#include "EObjA_p.hpp" - -class EObjALocal : public QObject -{ - Q_OBJECT -public: - EObjALocal(); - ~EObjALocal(); -}; - -EObjALocal::EObjALocal() -{ -} - -EObjALocal::~EObjALocal() -{ -} - -EObjAPrivate::EObjAPrivate() -{ - EObjALocal localObj; - EObjAExtra extraObj; -} - -EObjAPrivate::~EObjAPrivate() -{ -} - -EObjA::EObjA() - : d(new EObjAPrivate) -{ -} - -EObjA::~EObjA() -{ - delete d; -} - -// For EObjALocal -#include "EObjA.moc" -// - Not the own header -#include "moc_EObjAExtra.cpp" diff --git a/Tests/QtAutogen/MocInclude/EObjA.hpp b/Tests/QtAutogen/MocInclude/EObjA.hpp deleted file mode 100644 index 0939ab6..0000000 --- a/Tests/QtAutogen/MocInclude/EObjA.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef EOBJA_HPP -#define EOBJA_HPP - -#include <QObject> - -// Sources includes a moc_ includes of an extra object -class EObjAPrivate; -class EObjA : public QObject -{ - Q_OBJECT -public: - EObjA(); - ~EObjA(); - -private: - EObjAPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/EObjAExtra.cpp b/Tests/QtAutogen/MocInclude/EObjAExtra.cpp deleted file mode 100644 index 369ca8f..0000000 --- a/Tests/QtAutogen/MocInclude/EObjAExtra.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "EObjAExtra.hpp" -#include "EObjAExtra_p.hpp" - -EObjAExtraPrivate::EObjAExtraPrivate() -{ -} - -EObjAExtraPrivate::~EObjAExtraPrivate() -{ -} - -EObjAExtra::EObjAExtra() - : d(new EObjAExtraPrivate) -{ -} - -EObjAExtra::~EObjAExtra() -{ - delete d; -} diff --git a/Tests/QtAutogen/MocInclude/EObjAExtra.hpp b/Tests/QtAutogen/MocInclude/EObjAExtra.hpp deleted file mode 100644 index b10681d..0000000 --- a/Tests/QtAutogen/MocInclude/EObjAExtra.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef EOBJAEXTRA_HPP -#define EOBJAEXTRA_HPP - -#include <QObject> - -class EObjAExtraPrivate; -class EObjAExtra : public QObject -{ - Q_OBJECT -public: - EObjAExtra(); - ~EObjAExtra(); - -private: - EObjAExtraPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/EObjAExtra_p.hpp b/Tests/QtAutogen/MocInclude/EObjAExtra_p.hpp deleted file mode 100644 index d8bf284..0000000 --- a/Tests/QtAutogen/MocInclude/EObjAExtra_p.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef EOBJAEXTRA_P_HPP -#define EOBJAEXTRA_P_HPP - -#include <QObject> - -class EObjAExtraPrivate : public QObject -{ - Q_OBJECT -public: - EObjAExtraPrivate(); - ~EObjAExtraPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/EObjA_p.hpp b/Tests/QtAutogen/MocInclude/EObjA_p.hpp deleted file mode 100644 index 9ef5624..0000000 --- a/Tests/QtAutogen/MocInclude/EObjA_p.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef EOBJA_P_HPP -#define EOBJA_P_HPP - -#include <QObject> - -class EObjAPrivate : public QObject -{ - Q_OBJECT -public: - EObjAPrivate(); - ~EObjAPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/EObjB.cpp b/Tests/QtAutogen/MocInclude/EObjB.cpp deleted file mode 100644 index 3068c68..0000000 --- a/Tests/QtAutogen/MocInclude/EObjB.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "EObjB.hpp" -#include "EObjB_p.hpp" -#include "subExtra/EObjBExtra.hpp" - -class EObjBLocal : public QObject -{ - Q_OBJECT -public: - EObjBLocal(); - ~EObjBLocal(); -}; - -EObjBLocal::EObjBLocal() -{ -} - -EObjBLocal::~EObjBLocal() -{ -} - -EObjBPrivate::EObjBPrivate() -{ - EObjBLocal localObj; - EObjBExtra extraObj; -} - -EObjBPrivate::~EObjBPrivate() -{ -} - -EObjB::EObjB() - : d(new EObjBPrivate) -{ -} - -EObjB::~EObjB() -{ - delete d; -} - -// For EObjBLocal -#include "EObjB.moc" -// - Not the own header -// - in a subdirectory -#include "subExtra/moc_EObjBExtra.cpp" diff --git a/Tests/QtAutogen/MocInclude/EObjB.hpp b/Tests/QtAutogen/MocInclude/EObjB.hpp deleted file mode 100644 index 6632bdb..0000000 --- a/Tests/QtAutogen/MocInclude/EObjB.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef EOBJB_HPP -#define EOBJB_HPP - -#include <QObject> - -// Sources includes a moc_ includes of an extra object in a subdirectory -class EObjBPrivate; -class EObjB : public QObject -{ - Q_OBJECT -public: - EObjB(); - ~EObjB(); - -private: - EObjBPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/EObjB_p.hpp b/Tests/QtAutogen/MocInclude/EObjB_p.hpp deleted file mode 100644 index 84b1ea2..0000000 --- a/Tests/QtAutogen/MocInclude/EObjB_p.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef EOBJB_P_HPP -#define EOBJB_P_HPP - -#include <QObject> - -class EObjBPrivate : public QObject -{ - Q_OBJECT -public: - EObjBPrivate(); - ~EObjBPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/LObjA.cpp b/Tests/QtAutogen/MocInclude/LObjA.cpp deleted file mode 100644 index 9aae991..0000000 --- a/Tests/QtAutogen/MocInclude/LObjA.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "LObjA.hpp" -#include "LObjA_p.h" - -class LObjALocal : public QObject -{ - Q_OBJECT -public: - LObjALocal(); - ~LObjALocal(); -}; - -LObjALocal::LObjALocal() -{ -} - -LObjALocal::~LObjALocal() -{ -} - -LObjAPrivate::LObjAPrivate() -{ - LObjALocal localObj; -} - -LObjAPrivate::~LObjAPrivate() -{ -} - -LObjA::LObjA() - : d(new LObjAPrivate) -{ -} - -LObjA::~LObjA() -{ - delete d; -} - -#include "LObjA.moc" diff --git a/Tests/QtAutogen/MocInclude/LObjA.hpp b/Tests/QtAutogen/MocInclude/LObjA.hpp deleted file mode 100644 index aac670c..0000000 --- a/Tests/QtAutogen/MocInclude/LObjA.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LOBJA_HPP -#define LOBJA_HPP - -#include <QObject> - -// Object source comes with a .moc include -class LObjAPrivate; -class LObjA : public QObject -{ - Q_OBJECT -public: - LObjA(); - ~LObjA(); - -private: - LObjAPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/LObjA_p.h b/Tests/QtAutogen/MocInclude/LObjA_p.h deleted file mode 100644 index 97113d6..0000000 --- a/Tests/QtAutogen/MocInclude/LObjA_p.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LOBJA_P_HPP -#define LOBJA_P_HPP - -#include <QObject> - -class LObjAPrivate : public QObject -{ - Q_OBJECT -public: - LObjAPrivate(); - ~LObjAPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/LObjB.cpp b/Tests/QtAutogen/MocInclude/LObjB.cpp deleted file mode 100644 index 7485d8f..0000000 --- a/Tests/QtAutogen/MocInclude/LObjB.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "LObjB.hpp" -#include "LObjB_p.h" - -class LObjBLocal : public QObject -{ - Q_OBJECT -public: - LObjBLocal(); - ~LObjBLocal(); -}; - -LObjBLocal::LObjBLocal() -{ -} - -LObjBLocal::~LObjBLocal() -{ -} - -LObjBPrivate::LObjBPrivate() -{ - LObjBLocal localObj; -} - -LObjBPrivate::~LObjBPrivate() -{ -} - -LObjB::LObjB() - : d(new LObjBPrivate) -{ -} - -LObjB::~LObjB() -{ - delete d; -} - -#include "LObjB.moc" -#include "moc_LObjB.cpp" diff --git a/Tests/QtAutogen/MocInclude/LObjB.hpp b/Tests/QtAutogen/MocInclude/LObjB.hpp deleted file mode 100644 index eb4e58d..0000000 --- a/Tests/QtAutogen/MocInclude/LObjB.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LLObjB_HPP -#define LLObjB_HPP - -#include <QObject> - -// Object source comes with a .moc and a _moc include -class LObjBPrivate; -class LObjB : public QObject -{ - Q_OBJECT -public: - LObjB(); - ~LObjB(); - -private: - LObjBPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/LObjB_p.h b/Tests/QtAutogen/MocInclude/LObjB_p.h deleted file mode 100644 index b88f40e..0000000 --- a/Tests/QtAutogen/MocInclude/LObjB_p.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LOBJB_P_HPP -#define LOBJB_P_HPP - -#include <QObject> - -class LObjBPrivate : public QObject -{ - Q_OBJECT -public: - LObjBPrivate(); - ~LObjBPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/ObjA.cpp b/Tests/QtAutogen/MocInclude/ObjA.cpp deleted file mode 100644 index 6f6b90e..0000000 --- a/Tests/QtAutogen/MocInclude/ObjA.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "ObjA.hpp" -#include "ObjA_p.h" - -ObjAPrivate::ObjAPrivate() -{ -} - -ObjAPrivate::~ObjAPrivate() -{ -} - -ObjA::ObjA() - : d(new ObjAPrivate) -{ -} - -ObjA::~ObjA() -{ - delete d; -} diff --git a/Tests/QtAutogen/MocInclude/ObjA.hpp b/Tests/QtAutogen/MocInclude/ObjA.hpp deleted file mode 100644 index f16c924..0000000 --- a/Tests/QtAutogen/MocInclude/ObjA.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef OBJA_HPP -#define OBJA_HPP - -#include <QObject> - -// Object source comes without any _moc/.moc includes -class ObjAPrivate; -class ObjA : public QObject -{ - Q_OBJECT -public: - ObjA(); - ~ObjA(); - -private: - ObjAPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/ObjA_p.h b/Tests/QtAutogen/MocInclude/ObjA_p.h deleted file mode 100644 index d944bc6..0000000 --- a/Tests/QtAutogen/MocInclude/ObjA_p.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef OBJA_P_HPP -#define OBJA_P_HPP - -#include <QObject> - -class ObjAPrivate : public QObject -{ - Q_OBJECT -public: - ObjAPrivate(); - ~ObjAPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/ObjB.cpp b/Tests/QtAutogen/MocInclude/ObjB.cpp deleted file mode 100644 index a6f2509..0000000 --- a/Tests/QtAutogen/MocInclude/ObjB.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "ObjB.hpp" -#include "ObjB_p.h" - -ObjBPrivate::ObjBPrivate() -{ -} - -ObjBPrivate::~ObjBPrivate() -{ -} - -ObjB::ObjB() - : d(new ObjBPrivate) -{ -} - -ObjB::~ObjB() -{ - delete d; -} - -#include "moc_ObjB.cpp" diff --git a/Tests/QtAutogen/MocInclude/ObjB.hpp b/Tests/QtAutogen/MocInclude/ObjB.hpp deleted file mode 100644 index 2ac8d17..0000000 --- a/Tests/QtAutogen/MocInclude/ObjB.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ObjB_HPP -#define ObjB_HPP - -#include <QObject> - -// Object source comes with a _moc include -class ObjBPrivate; -class ObjB : public QObject -{ - Q_OBJECT -public: - ObjB(); - ~ObjB(); - -private: - ObjBPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/ObjB_p.h b/Tests/QtAutogen/MocInclude/ObjB_p.h deleted file mode 100644 index 61ba604..0000000 --- a/Tests/QtAutogen/MocInclude/ObjB_p.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef OBJB_P_HPP -#define OBJB_P_HPP - -#include <QObject> - -class ObjBPrivate : public QObject -{ - Q_OBJECT -public: - ObjBPrivate(); - ~ObjBPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/Relaxed/CMakeLists.txt b/Tests/QtAutogen/MocInclude/Relaxed/CMakeLists.txt new file mode 100644 index 0000000..048b79c --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Relaxed/CMakeLists.txt @@ -0,0 +1,17 @@ +# Enable relaxed mode +set(CMAKE_AUTOMOC_RELAXED_MODE TRUE) + +# Common test +set(COMMON_FUNCTION_NAME commonRelaxed) +configure_file( + "${COM_DIR}/common.cpp.in" + "${CMAKE_CURRENT_BINARY_DIR}/commonRelaxed.cpp") + +makeExecutable(libRelaxed) +target_sources(libRelaxed PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}/commonRelaxed.cpp" + RObjA.cpp + RObjB.cpp + RObjC.cpp + relaxed.cpp + ) diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjA.cpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjA.cpp index 2e2cf6a..2e2cf6a 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjA.cpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjA.cpp diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjA.hpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjA.hpp index 5974187..5974187 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjA.hpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjA.hpp diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjB.cpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjB.cpp index c56d10f..c56d10f 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjB.cpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjB.cpp diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjB.hpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjB.hpp index d6d0474..d6d0474 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjB.hpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjB.hpp diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjBExtra.hpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjBExtra.hpp index 5d6be75..5d6be75 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjBExtra.hpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjBExtra.hpp diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjC.cpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjC.cpp index 4ba32f5..4ba32f5 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjC.cpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjC.cpp diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RObjC.hpp b/Tests/QtAutogen/MocInclude/Relaxed/RObjC.hpp index 5552ede..5552ede 100644 --- a/Tests/QtAutogen/MocIncludeRelaxed/RObjC.hpp +++ b/Tests/QtAutogen/MocInclude/Relaxed/RObjC.hpp diff --git a/Tests/QtAutogen/MocInclude/Relaxed/relaxed.cpp b/Tests/QtAutogen/MocInclude/Relaxed/relaxed.cpp new file mode 100644 index 0000000..5a511b6 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Relaxed/relaxed.cpp @@ -0,0 +1,21 @@ +// AUTOMOC relaxed mode objects +#include "RObjA.hpp" +#include "RObjB.hpp" +#include "RObjC.hpp" + +// Forward declaration +bool commonRelaxed(); + +int main(int argv, char** args) +{ + // Common tests + if (!commonRelaxed()) { + return -1; + } + + // Relaxed tests + RObjA rObjA; + RObjB rObjB; + RObjC rObjC; + return 0; +} diff --git a/Tests/QtAutogen/MocInclude/SObjA.cpp b/Tests/QtAutogen/MocInclude/SObjA.cpp deleted file mode 100644 index 7e75bf9..0000000 --- a/Tests/QtAutogen/MocInclude/SObjA.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "SObjA.hpp" - -SObjA::SObjA() -{ -} - -SObjA::~SObjA() -{ -} - -#include "SObjA.moc" diff --git a/Tests/QtAutogen/MocInclude/SObjB.cpp.in b/Tests/QtAutogen/MocInclude/SObjB.cpp.in deleted file mode 100644 index b1cc12a..0000000 --- a/Tests/QtAutogen/MocInclude/SObjB.cpp.in +++ /dev/null @@ -1,11 +0,0 @@ -#include "SObjB.hpp" - -SObjB::SObjB() -{ -} - -SObjB::~SObjB() -{ -} - -#include "SObjB.moc" diff --git a/Tests/QtAutogen/MocInclude/SObjB.hpp.in b/Tests/QtAutogen/MocInclude/SObjB.hpp.in deleted file mode 100644 index 5e396ae..0000000 --- a/Tests/QtAutogen/MocInclude/SObjB.hpp.in +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SOBJB_HPP -#define SOBJB_HPP - -#include <QObject> - -// Object source includes externally generated .moc file -class SObjB : public QObject -{ - Q_OBJECT -public: - SObjB(); - ~SObjB(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/SObjC.cpp b/Tests/QtAutogen/MocInclude/SObjC.cpp deleted file mode 100644 index 1e8d397..0000000 --- a/Tests/QtAutogen/MocInclude/SObjC.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "SObjC.hpp" - -void SObjCLocalFunction(); - -class SObjCLocal : public QObject -{ - Q_OBJECT - -public: - SObjCLocal(); - ~SObjCLocal(); -}; - -SObjCLocal::SObjCLocal() -{ -} - -SObjCLocal::~SObjCLocal() -{ -} - -SObjC::SObjC() -{ - SObjCLocal localObject; - SObjCLocalFunction(); -} - -SObjC::~SObjC() -{ -} - -#include "SObjC.moc" -#include "moc_SObjC.cpp" -// Include moc_ file for which the header is SKIP_AUTOMOC enabled -#include "moc_SObjCExtra.cpp" diff --git a/Tests/QtAutogen/MocInclude/SObjC.hpp b/Tests/QtAutogen/MocInclude/SObjC.hpp deleted file mode 100644 index def0f9d..0000000 --- a/Tests/QtAutogen/MocInclude/SObjC.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SOBJC_HPP -#define SOBJC_HPP - -#include <QObject> - -// Object source includes externally generated .moc file -class SObjC : public QObject -{ - Q_OBJECT -public: - SObjC(); - ~SObjC(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/SObjCExtra.cpp b/Tests/QtAutogen/MocInclude/SObjCExtra.cpp deleted file mode 100644 index 55dd1c3..0000000 --- a/Tests/QtAutogen/MocInclude/SObjCExtra.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "SObjCExtra.hpp" - -class SObjCLocalExtra : public QObject -{ - Q_OBJECT - -public: - SObjCLocalExtra(); - ~SObjCLocalExtra(); -}; - -SObjCLocalExtra::SObjCLocalExtra() -{ -} - -SObjCLocalExtra::~SObjCLocalExtra() -{ -} - -SObjCExtra::SObjCExtra() -{ -} - -SObjCExtra::~SObjCExtra() -{ -} - -// Externally generated header moc -#include "SObjCExtra_extMoc.cpp" -// AUTOMOC generated source moc -#include "SObjCExtra.moc" diff --git a/Tests/QtAutogen/MocInclude/SObjCExtra.hpp b/Tests/QtAutogen/MocInclude/SObjCExtra.hpp deleted file mode 100644 index 08545ac..0000000 --- a/Tests/QtAutogen/MocInclude/SObjCExtra.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SOBJCEXTRA_HPP -#define SOBJCEXTRA_HPP - -#include <QObject> - -// Object source includes externally generated .moc file -class SObjCExtra : public QObject -{ - Q_OBJECT -public: - SObjCExtra(); - ~SObjCExtra(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/SObjCExtra.moc.in b/Tests/QtAutogen/MocInclude/SObjCExtra.moc.in deleted file mode 100644 index 00fc4aa..0000000 --- a/Tests/QtAutogen/MocInclude/SObjCExtra.moc.in +++ /dev/null @@ -1,4 +0,0 @@ - -void SObjCLocalFunction() -{ -} diff --git a/Tests/QtAutogen/MocInclude/Strict/CMakeLists.txt b/Tests/QtAutogen/MocInclude/Strict/CMakeLists.txt new file mode 100644 index 0000000..12c503f --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Strict/CMakeLists.txt @@ -0,0 +1,14 @@ +# Disable relaxed mode +set(CMAKE_AUTOMOC_RELAXED_MODE FALSE) + +# Common test +set(COMMON_FUNCTION_NAME commonStrict) +configure_file( + "${COM_DIR}/common.cpp.in" + "${CMAKE_CURRENT_BINARY_DIR}/commonStrict.cpp") + +makeExecutable(libStrict) +target_sources(libStrict PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}/commonStrict.cpp" + strict.cpp + ) diff --git a/Tests/QtAutogen/MocInclude/Strict/strict.cpp b/Tests/QtAutogen/MocInclude/Strict/strict.cpp new file mode 100644 index 0000000..dd24bb0 --- /dev/null +++ b/Tests/QtAutogen/MocInclude/Strict/strict.cpp @@ -0,0 +1,7 @@ +// Forward declaration +bool commonStrict(); + +int main(int argv, char** args) +{ + return commonStrict() ? 0 : -1; +} diff --git a/Tests/QtAutogen/MocInclude/main.cpp b/Tests/QtAutogen/MocInclude/main.cpp new file mode 100644 index 0000000..371c5fd --- /dev/null +++ b/Tests/QtAutogen/MocInclude/main.cpp @@ -0,0 +1,9 @@ + +// Forward declaration +bool libStrict(); +bool libRelaxed(); + +int main(int argv, char** args) +{ + return (libStrict() && libRelaxed()) ? 0 : -1; +} diff --git a/Tests/QtAutogen/MocInclude/shared.cmake b/Tests/QtAutogen/MocInclude/shared.cmake deleted file mode 100644 index 2ca2841..0000000 --- a/Tests/QtAutogen/MocInclude/shared.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Test moc include patterns -include_directories("../MocInclude") -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -# Generate .moc file externally and enabled SKIP_AUTOMOC on the file -qtx_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjA.hpp - ${CMAKE_CURRENT_BINARY_DIR}/SObjA.moc) -set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjA.cpp PROPERTY SKIP_AUTOMOC ON) - -# Generate .moc file externally from generated source file -# and enabled SKIP_AUTOMOC on the source file -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SObjB.hpp - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjB.hpp.in - ${CMAKE_CURRENT_BINARY_DIR}/SObjB.hpp) -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SObjB.cpp - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjB.cpp.in - ${CMAKE_CURRENT_BINARY_DIR}/SObjB.cpp) -qtx_generate_moc( - ${CMAKE_CURRENT_BINARY_DIR}/SObjB.hpp - ${CMAKE_CURRENT_BINARY_DIR}/SObjB.moc) -set_property(SOURCE ${CMAKE_CURRENT_BINARY_DIR}/SObjB.cpp PROPERTY SKIP_AUTOMOC ON) - -# Generate moc file externally and enabled SKIP_AUTOMOC on the header -qtx_generate_moc( - ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjCExtra.hpp - ${CMAKE_CURRENT_BINARY_DIR}/SObjCExtra_extMoc.cpp) -set_property( - SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjCExtra.hpp - PROPERTY SKIP_AUTOMOC ON) -# Custom target to depend on -set(SOBJC_MOC ${CMAKE_CURRENT_BINARY_DIR}/moc_SObjCExtra.cpp) -add_custom_target("${MOC_INCLUDE_NAME}_SOBJC" - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SObjCExtra_extMoc.cpp - BYPRODUCTS ${SOBJC_MOC} - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/SObjCExtra.moc.in - ${SOBJC_MOC}) - -# MOC_INCLUDE_NAME must be defined by the includer -add_executable(${MOC_INCLUDE_NAME} - # Common sources - ../MocInclude/ObjA.cpp - ../MocInclude/ObjB.cpp - - ../MocInclude/LObjA.cpp - ../MocInclude/LObjB.cpp - - ../MocInclude/EObjA.cpp - ../MocInclude/EObjAExtra.cpp - ../MocInclude/EObjB.cpp - ../MocInclude/subExtra/EObjBExtra.cpp - - ../MocInclude/SObjA.cpp - ${CMAKE_CURRENT_BINARY_DIR}/SObjA.moc - ${CMAKE_CURRENT_BINARY_DIR}/SObjB.cpp - ${CMAKE_CURRENT_BINARY_DIR}/SObjB.moc - ../MocInclude/SObjC.cpp - ../MocInclude/SObjCExtra.hpp - ../MocInclude/SObjCExtra.cpp - - ../MocInclude/subGlobal/GObj.cpp - main.cpp -) -add_dependencies(${MOC_INCLUDE_NAME} "${MOC_INCLUDE_NAME}_SOBJC") -target_link_libraries(${MOC_INCLUDE_NAME} ${QT_LIBRARIES}) -set_target_properties(${MOC_INCLUDE_NAME} PROPERTIES AUTOMOC ON) diff --git a/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra.cpp b/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra.cpp deleted file mode 100644 index c697866..0000000 --- a/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "EObjBExtra.hpp" -#include "EObjBExtra_p.hpp" - -EObjBExtraPrivate::EObjBExtraPrivate() -{ -} - -EObjBExtraPrivate::~EObjBExtraPrivate() -{ -} - -EObjBExtra::EObjBExtra() - : d(new EObjBExtraPrivate) -{ -} - -EObjBExtra::~EObjBExtra() -{ - delete d; -} diff --git a/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra.hpp b/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra.hpp deleted file mode 100644 index 3798d7f..0000000 --- a/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef EOBJBEXTRA_HPP -#define EOBJBEXTRA_HPP - -#include <QObject> - -class EObjBExtraPrivate; -class EObjBExtra : public QObject -{ - Q_OBJECT -public: - EObjBExtra(); - ~EObjBExtra(); - -private: - EObjBExtraPrivate* const d; -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra_p.hpp b/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra_p.hpp deleted file mode 100644 index 3231fac..0000000 --- a/Tests/QtAutogen/MocInclude/subExtra/EObjBExtra_p.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef EOBJBEXTRA_P_HPP -#define EOBJBEXTRA_P_HPP - -#include <QObject> - -class EObjBExtraPrivate : public QObject -{ - Q_OBJECT -public: - EObjBExtraPrivate(); - ~EObjBExtraPrivate(); -}; - -#endif diff --git a/Tests/QtAutogen/MocInclude/subGlobal/GObj.cpp b/Tests/QtAutogen/MocInclude/subGlobal/GObj.cpp deleted file mode 100644 index 6b92f21..0000000 --- a/Tests/QtAutogen/MocInclude/subGlobal/GObj.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "GObj.hpp" -#include "GObj_p.hpp" - -namespace subGlobal { - -class GObjLocal : public QObject -{ - Q_OBJECT -public: - GObjLocal(); - ~GObjLocal(); -}; - -GObjLocal::GObjLocal() -{ -} - -GObjLocal::~GObjLocal() -{ -} - -GObjPrivate::GObjPrivate() -{ -} - -GObjPrivate::~GObjPrivate() -{ -} - -GObj::GObj() -{ - GObjLocal localObj; -} - -GObj::~GObj() -{ -} -} - -// For the local QObject -#include "GObj.moc" diff --git a/Tests/QtAutogen/MocInclude/subGlobal/GObj.hpp b/Tests/QtAutogen/MocInclude/subGlobal/GObj.hpp deleted file mode 100644 index 2f9ee82..0000000 --- a/Tests/QtAutogen/MocInclude/subGlobal/GObj.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GOBJ_HPP -#define GOBJ_HPP - -#include <QObject> - -namespace subGlobal { - -class GObj : public QObject -{ - Q_OBJECT -public: - GObj(); - ~GObj(); -}; -} - -#endif diff --git a/Tests/QtAutogen/MocInclude/subGlobal/GObj_p.hpp b/Tests/QtAutogen/MocInclude/subGlobal/GObj_p.hpp deleted file mode 100644 index 4a43755..0000000 --- a/Tests/QtAutogen/MocInclude/subGlobal/GObj_p.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GOBJ_P_HPP -#define GOBJ_P_HPP - -#include <QObject> - -namespace subGlobal { - -class GObjPrivate : public QObject -{ - Q_OBJECT -public: - GObjPrivate(); - ~GObjPrivate(); -}; -} - -#endif diff --git a/Tests/QtAutogen/MocIncludeRelaxed/CMakeLists.txt b/Tests/QtAutogen/MocIncludeRelaxed/CMakeLists.txt deleted file mode 100644 index 8b4da34..0000000 --- a/Tests/QtAutogen/MocIncludeRelaxed/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(MocIncludeRelaxed) -include("../AutogenCoreTest.cmake") - -# Test moc include patterns -set(CMAKE_AUTOMOC_RELAXED_MODE TRUE) - -# Shared executable -set(MOC_INCLUDE_NAME "mocIncludeRelaxed") -include(${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/shared.cmake) - -# Relaxed only executable -add_executable(mocIncludeRelaxedOnly - RObjA.cpp - RObjB.cpp - RObjC.cpp - RMain.cpp -) -target_link_libraries(mocIncludeRelaxedOnly ${QT_LIBRARIES}) -set_target_properties(mocIncludeRelaxedOnly PROPERTIES AUTOMOC ON) diff --git a/Tests/QtAutogen/MocIncludeRelaxed/RMain.cpp b/Tests/QtAutogen/MocIncludeRelaxed/RMain.cpp deleted file mode 100644 index 5b2c070..0000000 --- a/Tests/QtAutogen/MocIncludeRelaxed/RMain.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Relaxed AUTOMOC objects -#include "RObjA.hpp" -#include "RObjB.hpp" -#include "RObjC.hpp" - -int main(int argv, char** args) -{ - RObjA rObjA; - RObjB rObjB; - RObjC rObjC; - return 0; -} diff --git a/Tests/QtAutogen/MocIncludeRelaxed/main.cpp b/Tests/QtAutogen/MocIncludeRelaxed/main.cpp deleted file mode 100644 index 5a3148d..0000000 --- a/Tests/QtAutogen/MocIncludeRelaxed/main.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "EObjA.hpp" -#include "EObjB.hpp" -#include "LObjA.hpp" -#include "LObjB.hpp" -#include "ObjA.hpp" -#include "ObjB.hpp" -#include "SObjA.hpp" -#include "SObjB.hpp" -#include "subGlobal/GObj.hpp" - -int main(int argv, char** args) -{ - subGlobal::GObj gObj; - ObjA objA; - ObjB objB; - LObjA lObjA; - LObjB lObjB; - EObjA eObjA; - EObjB eObjB; - SObjA sObjA; - SObjB sObjB; - return 0; -} - -// Header in global subdirectory -#include "subGlobal/moc_GObj.cpp" diff --git a/Tests/QtAutogen/MocIncludeStrict/CMakeLists.txt b/Tests/QtAutogen/MocIncludeStrict/CMakeLists.txt deleted file mode 100644 index d0aaebf..0000000 --- a/Tests/QtAutogen/MocIncludeStrict/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(MocIncludeStrict) -include("../AutogenCoreTest.cmake") - -# Test moc include patterns -set(CMAKE_AUTOMOC_RELAXED_MODE FALSE) - -# Shared executable -set(MOC_INCLUDE_NAME "mocIncludeStrict") -include(${CMAKE_CURRENT_SOURCE_DIR}/../MocInclude/shared.cmake) diff --git a/Tests/QtAutogen/MocIncludeStrict/main.cpp b/Tests/QtAutogen/MocIncludeStrict/main.cpp deleted file mode 100644 index 5a3148d..0000000 --- a/Tests/QtAutogen/MocIncludeStrict/main.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "EObjA.hpp" -#include "EObjB.hpp" -#include "LObjA.hpp" -#include "LObjB.hpp" -#include "ObjA.hpp" -#include "ObjB.hpp" -#include "SObjA.hpp" -#include "SObjB.hpp" -#include "subGlobal/GObj.hpp" - -int main(int argv, char** args) -{ - subGlobal::GObj gObj; - ObjA objA; - ObjB objB; - LObjA lObjA; - LObjB lObjB; - EObjA eObjA; - EObjB eObjB; - SObjA sObjA; - SObjB sObjB; - return 0; -} - -// Header in global subdirectory -#include "subGlobal/moc_GObj.cpp" diff --git a/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt b/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt new file mode 100644 index 0000000..1627b39 --- /dev/null +++ b/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.15) +project(MocIncludeSymlink) +include("../AutogenCoreTest.cmake") + +# +# Tests if MocInclude can be build when +# - The source directory is a symbolic link +# - The build directory is a symbolic link +# + +# -- Utility variables +set(CS_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(CB_DIR "${CMAKE_CURRENT_BINARY_DIR}") + +# Absolute MocInclude path +get_filename_component(MocIncludePath "../MocInclude" ABSOLUTE) +message("MocIncludePath: ${MocIncludePath}") + +# Use nested subdirectories to ensure relatives paths are correct as well +set(BUILD_DIR_NORMAL "${CB_DIR}/Build/Normal") +set(BUILD_DIR_LINKED "${CB_DIR}/Build/Linked") + +set(SL_SOURCE_DIR "${CB_DIR}/SL_Source") +set(SL_BUILD_DIR "${CB_DIR}/SL_Build") + +# -- Utility macros +function(makeSymLink origin link) + message("Creating symbolic link\n Link: ${link}\n To: ${origin}") + file(CREATE_LINK ${origin} ${link} RESULT res SYMBOLIC) + if(NOT (${res} STREQUAL "0")) + message("Symlink creation failed.\n Link: ${link}\n To: ${origin}\n Result: ${res}") + endif() +endfunction() + +# -- Make source directory symlink +makeSymLink(${MocIncludePath} ${SL_SOURCE_DIR} linkResult) +if(NOT EXISTS ${SL_SOURCE_DIR}) + message("Directory symlink can't be created. Skipping test.") + return() +endif() + +# -- Make normal build directory +file(REMOVE_RECURSE ${BUILD_DIR_NORMAL}) +file(MAKE_DIRECTORY ${BUILD_DIR_NORMAL}) + +# -- Make linked build directory and symlink +file(REMOVE_RECURSE ${BUILD_DIR_LINKED}) +file(MAKE_DIRECTORY ${BUILD_DIR_LINKED}) +makeSymLink(${BUILD_DIR_LINKED} ${SL_BUILD_DIR} linkResult) +if(NOT EXISTS ${SL_BUILD_DIR}) + message("Directory symlink can't be created. Skipping test.") + return() +endif() + + +# -- Building +macro(buildMocInclude sourceDir binaryDir) + message("Building MocInclude\n - source dir: ${sourceDir}\n - binary dir: ${binaryDir}\n") + try_compile(result + "${binaryDir}" + "${sourceDir}" + MocInclude + CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}" + "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}" + "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" + OUTPUT_VARIABLE output + ) + if (result) + message(STATUS "--- Build success. ---") + else() + message(STATUS "\n### Building MocInclude failed. ###\n\n--- Output ---\n${output}") + message(FATAL_ERROR "--- Building MocInclude failed. End of output. ---") + endif() +endmacro() + +message("\nTry building with\n - symbolic link source dir\n - non symbolic build dir\n") +buildMocInclude(${SL_SOURCE_DIR} ${BUILD_DIR_NORMAL}) + +message("\nTry building with\n - symbolic link source dir\n - symbolic link build dir\n") +buildMocInclude(${SL_SOURCE_DIR} ${SL_BUILD_DIR}) diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake index 6771828..2b001d4 100644 --- a/Tests/QtAutogen/Tests.cmake +++ b/Tests/QtAutogen/Tests.cmake @@ -32,8 +32,8 @@ ADD_AUTOGEN_TEST(UicSkipSource) if(QT_TEST_ALLOW_QT_MACROS) ADD_AUTOGEN_TEST(MocCMP0071) - ADD_AUTOGEN_TEST(MocIncludeRelaxed mocIncludeRelaxed) - ADD_AUTOGEN_TEST(MocIncludeStrict mocIncludeStrict) + ADD_AUTOGEN_TEST(MocInclude) + ADD_AUTOGEN_TEST(MocIncludeSymlink) ADD_AUTOGEN_TEST(MocSkipSource) endif() diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake index 27a609d..6c9be4b 100644 --- a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake +++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake @@ -7,9 +7,13 @@ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") run_cmake(AutoExport) unset(RunCMake_TEST_OPTIONS) # don't run this test on Watcom or Borland make as it is not supported -if("${RunCMake_GENERATOR}" MATCHES "Watcom WMake|Borland Makefiles") +if(RunCMake_GENERATOR MATCHES "Watcom WMake|Borland Makefiles") return() endif() +if(RunCMake_GENERATOR MATCHES "Ninja|Visual Studio" AND + CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(EXPORTS TRUE) +endif() # we build debug so the say.exe will be found in Debug/say.exe for # Visual Studio generators if(RunCMake_GENERATOR_IS_MULTI_CONFIG) @@ -18,9 +22,36 @@ endif() # build AutoExport run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first) +# save the current timestamp of exports.def +if(EXPORTS) + set(EXPORTS_DEF "${RunCMake_TEST_BINARY_DIR}/say.dir/${INTDIR}exports.def") + if(NOT EXISTS "${EXPORTS_DEF}") + set(EXPORTS_DEF + "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/say.dir/${INTDIR}exports.def") + endif() + file(TIMESTAMP "${EXPORTS_DEF}" timestamp) + if(NOT timestamp) + message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + endif() +endif() # run the executable that uses symbols from the dll if(WIN32) set(EXE_EXT ".exe") endif() run_cmake_command(AutoExportRun - ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT}) + ${RunCMake_TEST_BINARY_DIR}/bin/${INTDIR}say${EXE_EXT}) +# build AutoExport again without modification +run_cmake_command(AutoExportBuildAgain ${CMAKE_COMMAND} --build + ${RunCMake_TEST_BINARY_DIR} --config Debug) +# compare timestamps of exports.def to make sure it has not been updated +if(EXPORTS) + file(TIMESTAMP "${EXPORTS_DEF}" timestamp_after) + if(NOT timestamp_after) + message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + endif() + if (timestamp_after STREQUAL timestamp) + message(STATUS "AutoExportTimeStamp - PASSED") + else() + message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.") + endif() +endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 13fbecf..0c6e770 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -544,7 +544,7 @@ set(cpack_tests add_RunCMake_test_group(CPack "${cpack_tests}") # add a test to make sure symbols are exported from a shared library # for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used -add_RunCMake_test(AutoExportDll) +add_RunCMake_test(AutoExportDll -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}) add_RunCMake_test(AndroidMK) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 89f63d0..52934f2 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -232,17 +232,37 @@ def check_target(c): assert is_string(obj["link"]["language"], expected["link"]["language"]) - # FIXME: Properly test commandFragments if "commandFragments" in obj["link"]: link_keys.append("commandFragments") assert is_list(obj["link"]["commandFragments"]) for f in obj["link"]["commandFragments"]: assert is_dict(f) - assert sorted(f.keys()) == ["fragment", "role"] + assert sorted(f.keys()) == ["fragment", "role"] or sorted(f.keys()) == ["backtrace", "fragment", "role"] assert is_string(f["fragment"]) assert is_string(f["role"]) assert f["role"] in ("flags", "libraries", "libraryPath", "frameworkPath") + if expected["link"]["commandFragments"] is not None: + def check_link_command_fragments(actual, expected): + assert is_dict(actual) + expected_keys = ["fragment", "role"] + + if expected["backtrace"] is not None: + expected_keys.append("backtrace") + assert matches(actual["fragment"], expected["fragment"]) + assert actual["role"] == expected["role"] + check_backtrace(obj, actual["backtrace"], expected["backtrace"]) + + assert sorted(actual.keys()) == sorted(expected_keys) + + check_list_match(lambda a, e: matches(a["fragment"], e["fragment"]), + obj["link"]["commandFragments"], expected["link"]["commandFragments"], + check=check_link_command_fragments, + check_exception=lambda a, e: "Link fragment: %s" % a["fragment"], + missing_exception=lambda e: "Link fragment: %s" % e["fragment"], + extra_exception=lambda a: "Link fragment: %s" % a["fragment"], + allow_extra=True) + if expected["link"]["lto"] is not None: link_keys.append("lto") assert is_bool(obj["link"]["lto"], expected["link"]["lto"]) @@ -327,15 +347,33 @@ def check_target(c): missing_exception=lambda e: "Source path: %s" % e, extra_exception=lambda a: "Source path: %s" % obj["sources"][a]["path"]) - # FIXME: Properly test compileCommandFragments if "compileCommandFragments" in actual: expected_keys.append("compileCommandFragments") assert is_list(actual["compileCommandFragments"]) for f in actual["compileCommandFragments"]: assert is_dict(f) - assert sorted(f.keys()) == ["fragment"] assert is_string(f["fragment"]) + if expected["compileCommandFragments"] is not None: + def check_compile_command_fragments(actual, expected): + assert is_dict(actual) + expected_keys = ["fragment"] + + if expected["backtrace"] is not None: + expected_keys.append("backtrace") + assert actual["fragment"] == expected["fragment"] + check_backtrace(obj, actual["backtrace"], expected["backtrace"]) + + assert sorted(actual.keys()) == sorted(expected_keys) + + check_list_match(lambda a, e: is_string(a["fragment"], e["fragment"]), + actual["compileCommandFragments"], expected["compileCommandFragments"], + check=check_compile_command_fragments, + check_exception=lambda a, e: "Compile fragment: %s" % a["fragment"], + missing_exception=lambda e: "Compile fragment: %s" % e["fragment"], + extra_exception=lambda a: "Compile fragment: %s" % a["fragment"], + allow_extra=True) + if expected["includes"] is not None: expected_keys.append("includes") @@ -931,6 +969,7 @@ def gen_check_targets(c, g, inSource): "backtrace": None, }, ], + "compileCommandFragments": None, }, ], "backtrace": [ @@ -998,6 +1037,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -1064,6 +1104,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -1171,6 +1212,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -1217,6 +1259,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -1317,6 +1360,7 @@ def gen_check_targets(c, g, inSource): "backtrace": None, }, ], + "compileCommandFragments": None, }, ], "backtrace": [ @@ -1367,6 +1411,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": True, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -1433,6 +1478,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -1479,6 +1525,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": True, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -1574,6 +1621,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -1681,6 +1729,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -1727,6 +1776,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -1979,6 +2029,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2062,6 +2113,25 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": [ + { + "fragment" : "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": True, + }, + { + "file" : "^cxx/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + } + ], }, ], "backtrace": [ @@ -2129,6 +2199,62 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": [ + { + "fragment" : "TargetLinkOptions", + "role" : "flags", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 18, + "command": "target_link_options", + "hasParent": True, + }, + { + "file" : "^cxx/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "fragment" : ".*TargetLinkDir\\\"?$", + "role" : "libraryPath", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 19, + "command": "target_link_directories", + "hasParent": True, + }, + { + "file" : "^cxx/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "fragment" : ".*cxx_lib.*", + "role" : "libraries", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 6, + "command": "target_link_libraries", + "hasParent": True, + }, + { + "file" : "^cxx/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + ], }, "archive": None, "dependencies": [ @@ -2205,6 +2331,7 @@ def gen_check_targets(c, g, inSource): "backtrace": None, }, ], + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2243,6 +2370,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -2297,6 +2425,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2331,6 +2460,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -2402,6 +2532,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2485,6 +2616,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2519,6 +2651,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -2743,6 +2876,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2777,6 +2911,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -2848,6 +2983,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -2882,6 +3018,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -3114,6 +3251,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3221,6 +3359,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3276,6 +3415,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -3337,6 +3477,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3444,6 +3585,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3499,6 +3641,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -3725,6 +3868,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3759,6 +3903,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -3813,6 +3958,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3847,6 +3993,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -3901,6 +4048,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -3935,6 +4083,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -3989,6 +4138,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -4023,6 +4173,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -4077,6 +4228,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -4111,6 +4263,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -4401,6 +4554,7 @@ def gen_check_targets(c, g, inSource): ], "includes": None, "defines": None, + "compileCommandFragments": None, }, ], "backtrace": [ @@ -4435,6 +4589,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "C", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ @@ -4748,6 +4903,7 @@ def gen_check_targets(c, g, inSource): ], }, ], + "compileCommandFragments": None, }, { "language": "CXX", @@ -4810,6 +4966,7 @@ def gen_check_targets(c, g, inSource): ], }, ], + "compileCommandFragments": None, }, ], "backtrace": [ @@ -4844,6 +5001,7 @@ def gen_check_targets(c, g, inSource): "link": { "language": "CXX", "lto": None, + "commandFragments": None, }, "archive": None, "dependencies": [ diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt index 29b61b8..b0564f5 100644 --- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt +++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt @@ -13,3 +13,7 @@ target_link_libraries(cxx_shared_exe PRIVATE cxx_shared_lib) add_library(cxx_static_lib STATIC ../empty.cxx) add_executable(cxx_static_exe ../empty.cxx) target_link_libraries(cxx_static_exe PRIVATE cxx_static_lib) + +target_compile_options(cxx_exe PUBLIC TargetCompileOptions) +target_link_options(cxx_exe PUBLIC TargetLinkOptions) +target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir") diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake index e82b05f..62bb5de 100644 --- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake @@ -39,7 +39,7 @@ foreach(i 1 2) "Name: CMakeInternalFakePackage${i} Description: Dummy package (${i}) for FindPkgConfig IMPORTED_TARGET test Version: 1.2.3 -Libs: -l${pname} +Libs: -l${pname} -l${pname}-doesnotexist ") endforeach() @@ -47,27 +47,6 @@ endforeach() # the import target find_library() calls handle the NO...PATH options correctly set(ENV{PKG_CONFIG_PATH} ${fakePkgDir}/lib/pkgconfig) -# Confirm correct behavior of NO_CMAKE_PATH, ensuring we only find the library -# for the imported target if we have both set CMAKE_PREFIX_PATH and have not -# given the NO_CMAKE_PATH option -unset(CMAKE_PREFIX_PATH) -unset(ENV{CMAKE_PREFIX_PATH}) -pkg_check_modules(FakePackage1 QUIET IMPORTED_TARGET cmakeinternalfakepackage1) -if (TARGET PkgConfig::FakePackage1) - message(FATAL_ERROR "Have import target for fake package 1 with no path prefix") -endif() - -set(CMAKE_PREFIX_PATH ${fakePkgDir}) -pkg_check_modules(FakePackage1 QUIET IMPORTED_TARGET NO_CMAKE_PATH cmakeinternalfakepackage1) -if (TARGET PkgConfig::FakePackage1) - message(FATAL_ERROR "Have import target for fake package 1 with ignored cmake path") -endif() - -pkg_check_modules(FakePackage1 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage1) -if (NOT TARGET PkgConfig::FakePackage1) - message(FATAL_ERROR "No import target for fake package 1 with prefix path") -endif() - # find targets in subdir and check their visibility add_subdirectory(target_subdir) if (TARGET PkgConfig::FakePackage1_dir) @@ -82,31 +61,35 @@ endif() # combination unset(CMAKE_PREFIX_PATH) unset(ENV{CMAKE_PREFIX_PATH}) -pkg_check_modules(FakePackage2 QUIET IMPORTED_TARGET cmakeinternalfakepackage2) -if (TARGET PkgConfig::FakePackage2) - message(FATAL_ERROR "Have import target for fake package 2 with no path prefix") -endif() - set(ENV{CMAKE_PREFIX_PATH} ${fakePkgDir}) -pkg_check_modules(FakePackage2 QUIET IMPORTED_TARGET NO_CMAKE_ENVIRONMENT_PATH cmakeinternalfakepackage2) -if (TARGET PkgConfig::FakePackage2) - message(FATAL_ERROR "Have import target for fake package 2 with ignored cmake path") -endif() pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2) if (NOT TARGET PkgConfig::FakePackage2) message(FATAL_ERROR "No import target for fake package 2 with prefix path") endif() +# check that 2 library entries exist +list(LENGTH FakePackage2_LINK_LIBRARIES fp2_nlibs) +if (NOT fp2_nlibs EQUAL 2) + message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has ${fp2_nlibs} entries but should have exactly 2") +endif() + # check that the full library path is also returned -if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a") +list(GET FakePackage2_LINK_LIBRARIES 0 fp2_lib0) +if (NOT fp2_lib0 STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a") + message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}") +endif() + +# check that the library that couldn't be found still shows up +list(GET FakePackage2_LINK_LIBRARIES 1 fp2_lib1) +if (NOT fp2_lib1 STREQUAL "cmakeinternalfakepackage2-doesnotexist") message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}") endif() # the information in *_LINK_LIBRARIES is not cached, so ensure is also is present on second run unset(FakePackage2_LINK_LIBRARIES) pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2) -if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a") +if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a;cmakeinternalfakepackage2-doesnotexist") message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on second run: ${FakePackage2_LINK_LIBRARIES}") endif() diff --git a/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake b/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake index ee47980..59ee14b 100644 --- a/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake +++ b/Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake @@ -4,7 +4,7 @@ project(DisabledPch C) add_library(foo foo.c) target_include_directories(foo PUBLIC include) target_precompile_headers(foo PUBLIC - foo.h + include/foo.h <stdio.h> \"string.h\" ) diff --git a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake index cbd6ede..caeb22b 100644 --- a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake +++ b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake @@ -18,19 +18,14 @@ 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") +if (NOT foo_pch_header_strings MATCHES ";#include \"[^\"]*PrecompileHeaders/include/foo.h\";#include \"foo2.h\";#include <stdio.h>;#include \"string.h\"(;|$)") + set(RunCMake_TEST_FAILED "Generated foo pch header\n ${foo_pch_header}\nhas bad content:\n ${foo_pch_header_strings}") 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") +if (NOT foobar_pch_header_strings MATCHES ";#include \"[^\"]*PrecompileHeaders/include/foo.h\";#include \"foo2.h\";#include <stdio.h>;#include \"string.h\";#include \"[^\"]*PrecompileHeaders/include/bar.h\"(;|$)") + set(RunCMake_TEST_FAILED "Generated foobar pch header\n ${foobar_pch_header}\nhas bad content:\n ${foobar_pch_header_strings}") return() endif() diff --git a/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake b/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake index 9041b09..a1e0792 100644 --- a/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake +++ b/Tests/RunCMake/PrecompileHeaders/PchInterface.cmake @@ -4,14 +4,15 @@ project(PchInterface C) add_library(foo foo.c) target_include_directories(foo PUBLIC include) target_precompile_headers(foo PUBLIC - foo.h + include/foo.h + \"foo2.h\" <stdio.h> \"string.h\" ) add_library(bar INTERFACE) target_include_directories(bar INTERFACE include) -target_precompile_headers(bar INTERFACE bar.h) +target_precompile_headers(bar INTERFACE include/bar.h) add_executable(foobar foobar.c) target_link_libraries(foobar foo bar) diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake new file mode 100644 index 0000000..4502456 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15) +project(PchReuseFrom C) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) +target_include_directories(empty PUBLIC include) + +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) +target_precompile_headers(foo REUSE_FROM empty) + +add_executable(foobar foobar.c) +target_link_libraries(foobar foo ) +set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo) + +enable_testing() +add_test(NAME foobar COMMAND foobar) diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt new file mode 100644 index 0000000..8cdcfd9 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt @@ -0,0 +1,2 @@ +^(|Warning #670: precompiled header file [^ +]* was not generated in this directory)$ diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake new file mode 100644 index 0000000..fff74dc --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.15) +project(PchReuseFromSubdir C) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) +target_include_directories(empty PUBLIC include) + +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) +target_precompile_headers(foo REUSE_FROM empty) + +subdirs(subdir) + +enable_testing() +add_test(NAME foobar COMMAND foobar) diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index fffcc47..bd3b1b8 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -16,3 +16,5 @@ run_cmake(DisabledPch) run_test(PchInterface) run_cmake(PchPrologueEpilogue) run_test(SkipPrecompileHeaders) +run_test(PchReuseFrom) +run_test(PchReuseFromSubdir) diff --git a/Tests/RunCMake/PrecompileHeaders/empty.c b/Tests/RunCMake/PrecompileHeaders/empty.c new file mode 100644 index 0000000..30ae1c4 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/empty.c @@ -0,0 +1,3 @@ +void nothing() +{ +} diff --git a/Tests/RunCMake/PrecompileHeaders/foo.c b/Tests/RunCMake/PrecompileHeaders/foo.c index 974a248..85ea230 100644 --- a/Tests/RunCMake/PrecompileHeaders/foo.c +++ b/Tests/RunCMake/PrecompileHeaders/foo.c @@ -1,6 +1,12 @@ #include "foo.h" +#include "foo2.h" int foo() { return 0; } + +int foo2() +{ + return 0; +} diff --git a/Tests/RunCMake/PrecompileHeaders/foobar.c b/Tests/RunCMake/PrecompileHeaders/foobar.c index 6dbf8ce..7a135ea 100644 --- a/Tests/RunCMake/PrecompileHeaders/foobar.c +++ b/Tests/RunCMake/PrecompileHeaders/foobar.c @@ -1,7 +1,8 @@ #include "bar.h" #include "foo.h" +#include "foo2.h" int main() { - return foo() + bar(); + return foo() + foo2() + bar(); } diff --git a/Tests/RunCMake/PrecompileHeaders/include/foo.h b/Tests/RunCMake/PrecompileHeaders/include/foo.h index 4a49474..fc0ae14 100644 --- a/Tests/RunCMake/PrecompileHeaders/include/foo.h +++ b/Tests/RunCMake/PrecompileHeaders/include/foo.h @@ -1,6 +1,6 @@ #ifndef foo_h #define foo_h -extern int foo(); +int foo(void); #endif diff --git a/Tests/RunCMake/PrecompileHeaders/include/foo2.h b/Tests/RunCMake/PrecompileHeaders/include/foo2.h new file mode 100644 index 0000000..4bf9c81 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/include/foo2.h @@ -0,0 +1,6 @@ +#ifndef foo2_h +#define foo2_h + +int foo2(void); + +#endif diff --git a/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt b/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt new file mode 100644 index 0000000..fa926c4 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(foobar ../foobar.c) +target_link_libraries(foobar foo ) +set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo) diff --git a/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-result.txt b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-stderr.txt new file mode 100644 index 0000000..503385f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at AppendLiteralQuotes.cmake:2 \(add_custom_command\): + COMMAND may not contain literal quotes: + + "c" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/AppendLiteralQuotes.cmake b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes.cmake new file mode 100644 index 0000000..038fb3f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes.cmake @@ -0,0 +1,2 @@ +add_custom_command(OUTPUT a COMMAND b) +add_custom_command(OUTPUT a COMMAND "\"c\"" APPEND) diff --git a/Tests/RunCMake/add_custom_command/GeneratedProperty.cmake b/Tests/RunCMake/add_custom_command/GeneratedProperty.cmake new file mode 100644 index 0000000..628134b --- /dev/null +++ b/Tests/RunCMake/add_custom_command/GeneratedProperty.cmake @@ -0,0 +1,10 @@ +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/a" + BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/b" + COMMAND c + ) +get_source_file_property(GENERATED_A "${CMAKE_CURRENT_BINARY_DIR}/a" GENERATED) +get_source_file_property(GENERATED_B "${CMAKE_CURRENT_BINARY_DIR}/b" GENERATED) +if(NOT GENERATED_A OR NOT GENERATED_B) + message(FATAL_ERROR "failed") +endif() diff --git a/Tests/RunCMake/add_custom_command/LiteralQuotes-result.txt b/Tests/RunCMake/add_custom_command/LiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/LiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/LiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_command/LiteralQuotes-stderr.txt new file mode 100644 index 0000000..e7d6155 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/LiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at LiteralQuotes.cmake:1 \(add_custom_command\): + COMMAND may not contain literal quotes: + + "b" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/LiteralQuotes.cmake b/Tests/RunCMake/add_custom_command/LiteralQuotes.cmake new file mode 100644 index 0000000..046ddd9 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/LiteralQuotes.cmake @@ -0,0 +1 @@ +add_custom_command(OUTPUT a COMMAND "\"b\"") diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake index 0387dbb..270df2f 100644 --- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake @@ -1,14 +1,18 @@ include(RunCMake) +run_cmake(AppendLiteralQuotes) run_cmake(AppendNoOutput) run_cmake(AppendNotOutput) run_cmake(BadArgument) +run_cmake(GeneratedProperty) +run_cmake(LiteralQuotes) run_cmake(NoArguments) run_cmake(NoOutputOrTarget) run_cmake(OutputAndTarget) run_cmake(SourceByproducts) run_cmake(SourceUsesTerminal) run_cmake(TargetImported) +run_cmake(TargetLiteralQuotes) run_cmake(TargetNotInDir) if(${RunCMake_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") diff --git a/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-result.txt b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-stderr.txt new file mode 100644 index 0000000..c4589b4 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at TargetLiteralQuotes.cmake:2 \(add_custom_command\): + COMMAND may not contain literal quotes: + + "b" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/TargetLiteralQuotes.cmake b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes.cmake new file mode 100644 index 0000000..5f11ed1 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes.cmake @@ -0,0 +1,2 @@ +add_library(a) +add_custom_command(TARGET a POST_BUILD COMMAND "\"b\"") diff --git a/Tests/RunCMake/add_custom_target/GeneratedProperty.cmake b/Tests/RunCMake/add_custom_target/GeneratedProperty.cmake new file mode 100644 index 0000000..d034534 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/GeneratedProperty.cmake @@ -0,0 +1,14 @@ +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/a" + COMMAND b + ) +add_custom_target(CollapseFullPath + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/a" + BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/../GeneratedProperty-build/c" + COMMAND d + ) +get_source_file_property(GENERATED_A "${CMAKE_CURRENT_BINARY_DIR}/a" GENERATED) +get_source_file_property(GENERATED_C "${CMAKE_CURRENT_BINARY_DIR}/c" GENERATED) +if(NOT GENERATED_A OR NOT GENERATED_C) + message(FATAL_ERROR "failed") +endif() diff --git a/Tests/RunCMake/add_custom_target/LiteralQuotes-result.txt b/Tests/RunCMake/add_custom_target/LiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/LiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/LiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_target/LiteralQuotes-stderr.txt new file mode 100644 index 0000000..bc5187a --- /dev/null +++ b/Tests/RunCMake/add_custom_target/LiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at LiteralQuotes.cmake:1 \(add_custom_target\): + COMMAND may not contain literal quotes: + + "b" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/LiteralQuotes.cmake b/Tests/RunCMake/add_custom_target/LiteralQuotes.cmake new file mode 100644 index 0000000..9870608 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/LiteralQuotes.cmake @@ -0,0 +1 @@ +add_custom_target(a COMMAND "\"b\"") diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake index 2caed03..49c7d3e 100644 --- a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake @@ -1,9 +1,11 @@ include(RunCMake) run_cmake(CommandExpandsEmpty) +run_cmake(GeneratedProperty) run_cmake(NoArguments) run_cmake(BadTargetName) run_cmake(ByproductsNoCommand) +run_cmake(LiteralQuotes) run_cmake(UsesTerminalNoCommand) function(run_TargetOrder) diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index 78026fa..ef31e8b 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -95,7 +95,6 @@ { include: [ "<inttypes.h>", public, "\"cm_kwiml.h\"", public ] }, # Self-sufficient wrapper for <sys/stat.h> - { include: [ "<sys/stat.h>", public, "\"cm_sys_stat.h\"", public ] }, { symbol: [ "mode_t", private, "\"cm_sys_stat.h\"", public ] }, # Wrappers for 3rd-party libraries used from the system. diff --git a/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp b/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp index 4b17875..593822a 100644 --- a/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp +++ b/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp @@ -10,7 +10,8 @@ std::wstring get_property(MSIHANDLE msi_handle, std::wstring const& name) { DWORD size = 0; - UINT status = MsiGetPropertyW(msi_handle, name.c_str(), L"", &size); + WCHAR value_buffer[] = L""; + UINT status = MsiGetPropertyW(msi_handle, name.c_str(), value_buffer, &size); if (status == ERROR_MORE_DATA) { std::vector<wchar_t> buffer(size + 1); diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp index 6e6e57e..fc86505 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp @@ -30,7 +30,7 @@ #define isfinite finite #endif #elif defined(__hpux) -#if !defined(isfinite) +#if !defined(isfinite) && !defined(__GNUC__) #if defined(__ia64) && !defined(finite) #define isfinite(x) ((sizeof(x) == sizeof(float) ? \ _Isfinitef(x) : _IsFinite(x))) @@ -86,10 +86,11 @@ // HP-UX #if defined(__hpux) # if !defined(isfinite) -# if defined(__ia64) && !defined(finite) +# if defined(__ia64) && !defined(finite) && !defined(__GNUC__) # define isfinite(x) ((sizeof(x) == sizeof(float) ? \ _Isfinitef(x) : _Isfinite(x))) # else +# include <math.h> # define isfinite finite # endif # endif diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index 2e781f1..fe2ef75 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -300,6 +300,23 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") ) endif() +if(CMAKE_SYSTEM_NAME STREQUAL "HP-UX") + list(APPEND uv_libraries + rt + ) + list(APPEND uv_headers + include/uv/posix.h + ) + list(APPEND uv_defines + _XOPEN_SOURCE_EXTENDED + ) + list(APPEND uv_sources + src/unix/hpux.c + src/unix/no-fsevents.c + src/unix/posix-poll.c + ) +endif() + include_directories( ${uv_includes} ${KWSYS_HEADER_ROOT} diff --git a/Utilities/cmlibuv/include/uv/unix.h b/Utilities/cmlibuv/include/uv/unix.h index 011abcf..4e26108 100644 --- a/Utilities/cmlibuv/include/uv/unix.h +++ b/Utilities/cmlibuv/include/uv/unix.h @@ -55,6 +55,8 @@ # include "aix.h" #elif defined(__sun) # include "sunos.h" +#elif defined(__hpux) +# include "posix.h" #elif defined(__APPLE__) # include "darwin.h" #elif defined(__DragonFly__) || \ diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c index 93df7af..cf7dea0 100644 --- a/Utilities/cmlibuv/src/unix/core.c +++ b/Utilities/cmlibuv/src/unix/core.c @@ -587,7 +587,7 @@ int uv__nonblock_ioctl(int fd, int set) { } -#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__) +#if !defined(__hpux) && !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__) int uv__cloexec_ioctl(int fd, int set) { int r; diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c index 3023b1e..5fb34f1b 100644 --- a/Utilities/cmlibuv/src/unix/fs.c +++ b/Utilities/cmlibuv/src/unix/fs.c @@ -234,7 +234,7 @@ static ssize_t uv__fs_futime(uv_fs_t* req) { #endif } -#if defined(__sun) && (_XOPEN_SOURCE < 600 || defined(CMAKE_BOOTSTRAP)) +#if (defined(__sun) || defined(__hpux)) && (_XOPEN_SOURCE < 600 || defined(CMAKE_BOOTSTRAP)) static char* uv__mkdtemp(char *template) { if (!mktemp(template) || mkdir(template, 0700)) diff --git a/Utilities/cmlibuv/src/unix/hpux.c b/Utilities/cmlibuv/src/unix/hpux.c new file mode 100644 index 0000000..4d3f628 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/hpux.c @@ -0,0 +1,30 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stdint.h> +#include <time.h> + +uint64_t uv__hrtime(uv_clocktype_t type) { + return (uint64_t) gethrtime(); +} diff --git a/Utilities/cmlibuv/src/unix/posix-hrtime.c b/Utilities/cmlibuv/src/unix/posix-hrtime.c index a264250..870b45c 100644 --- a/Utilities/cmlibuv/src/unix/posix-hrtime.c +++ b/Utilities/cmlibuv/src/unix/posix-hrtime.c @@ -43,6 +43,20 @@ uint64_t uv__hrtime(uv_clocktype_t type) { return mach_absolute_time() * info.numer / info.denom; } +#elif defined(__hpux) +/* Special case for CMake bootstrap: no CLOCK_MONOTONIC on HP-UX */ + +#ifndef CMAKE_BOOTSTRAP +#error "This code path meant only for use during CMake bootstrap." +#endif + +#include <stdint.h> +#include <time.h> + +uint64_t uv__hrtime(uv_clocktype_t type) { + return (uint64_t) gethrtime(); +} + #else #include <stdint.h> diff --git a/Utilities/cmlibuv/src/unix/thread.c b/Utilities/cmlibuv/src/unix/thread.c index cd0b7aa..0453221 100644 --- a/Utilities/cmlibuv/src/unix/thread.c +++ b/Utilities/cmlibuv/src/unix/thread.c @@ -700,7 +700,7 @@ int uv_cond_init(uv_cond_t* cond) { if (err) return UV__ERR(err); -#if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21) +#if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21) && !defined(__hpux) err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); if (err) goto error2; diff --git a/Utilities/cmlibuv/src/unix/tty.c b/Utilities/cmlibuv/src/unix/tty.c index b8bc283..db479d6 100644 --- a/Utilities/cmlibuv/src/unix/tty.c +++ b/Utilities/cmlibuv/src/unix/tty.c @@ -200,7 +200,7 @@ skip: static void uv__tty_make_raw(struct termios* tio) { assert(tio != NULL); -#if defined __sun || defined __MVS__ +#if defined __sun || defined __MVS__ || defined __hpux /* * This implementation of cfmakeraw for Solaris and derivatives is taken from * http://www.perkin.org.uk/posts/solaris-portability-cfmakeraw.html. diff --git a/Utilities/std/.gitattributes b/Utilities/std/.gitattributes new file mode 100644 index 0000000..cd20549 --- /dev/null +++ b/Utilities/std/.gitattributes @@ -0,0 +1 @@ +cm/* our-c-style diff --git a/Utilities/std/CMakeLists.txt b/Utilities/std/CMakeLists.txt new file mode 100644 index 0000000..63c0a60 --- /dev/null +++ b/Utilities/std/CMakeLists.txt @@ -0,0 +1,10 @@ + +# source files for CMake std library +set(SRCS cm/bits/string_view.cxx + cm/memory + cm/optional + cm/shared_mutex + cm/string_view + cm/utility) + +add_library(cmstd STATIC ${SRCS}) diff --git a/Source/cm_string_view.cxx b/Utilities/std/cm/bits/string_view.cxx index 61fa80e..3b283da 100644 --- a/Source/cm_string_view.cxx +++ b/Utilities/std/cm/bits/string_view.cxx @@ -1,7 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cm_string_view.hxx" +#include <cm/string_view> // IWYU pragma: associated #ifndef CMake_HAVE_CXX_STRING_VIEW diff --git a/Utilities/std/cm/iterator b/Utilities/std/cm/iterator new file mode 100644 index 0000000..718f1d6 --- /dev/null +++ b/Utilities/std/cm/iterator @@ -0,0 +1,216 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_iterator +#define cm_iterator + +#include <iterator> // IWYU pragma: export + +namespace cm { + +#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L +using std::make_reverse_iterator; + +using std::cbegin; +using std::cend; + +using std::rbegin; +using std::rend; +using std::crbegin; +using std::crend; +#else +template <class Iter> +std::reverse_iterator<Iter> make_reverse_iterator(Iter it) +{ + return std::reverse_iterator<Iter>(it); +} + +// std::c{begin,end} backport from C++14 +template <class C> +# if defined(_MSC_VER) && _MSC_VER < 1900 +auto cbegin(C const& c) +# else +constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c))) +# endif + -> decltype(std::begin(c)) +{ + return std::begin(c); +} + +template <class C> +# if defined(_MSC_VER) && _MSC_VER < 1900 +auto cend(C const& c) +# else +constexpr auto cend(C const& c) noexcept(noexcept(std::end(c))) +# endif + -> decltype(std::end(c)) +{ + return std::end(c); +} + +// std::r{begin,end} backport from C++14 +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + rbegin(C& c) -> decltype(c.rbegin()) +{ + return c.rbegin(); +} +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + rbegin(C const& c) -> decltype(c.rbegin()) +{ + return c.rbegin(); +} +template <typename T, size_t N> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + std::reverse_iterator<T*> + rbegin(T (&arr)[N]) +{ + return std::reverse_iterator<T*>(arr + N); +} + +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + rend(C& c) -> decltype(c.rend()) +{ + return c.rend(); +} +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + rend(C const& c) -> decltype(c.rend()) +{ + return c.rend(); +} +template <typename T, size_t N> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + std::reverse_iterator<T*> + rend(T (&arr)[N]) +{ + return std::reverse_iterator<T*>(arr); +} + +// std::cr{begin,end} backport from C++14 +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + crbegin(C const& c) -> decltype(cm::rbegin(c)) +{ + return cm::rbegin(c); +} + +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + crend(C const& c) -> decltype(cm::rend(c)) +{ + return cm::rend(c); +} +#endif + +#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +using std::size; + +using std::empty; +using std::data; +#else + +// std::size backport from C++17. +template <class C> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + auto + size(C const& c) -> decltype(c.size()) +{ + return c.size(); +} + +template <typename T, size_t N> +# if !defined(_MSC_VER) || _MSC_VER >= 1900 +constexpr +# endif + std::size_t + size(const T (&)[N]) throw() +{ + return N; +} + +// std::empty backport from C++17. +template <class C> +# if defined(_MSC_VER) && _MSC_VER < 1900 +auto empty(C const& c) +# else +constexpr auto empty(C const& c) noexcept(noexcept(c.empty())) +# endif + -> decltype(c.empty()) +{ + return c.empty(); +} +template <typename T, size_t N> +# if defined(_MSC_VER) && _MSC_VER < 1900 +bool empty(const T (&)[N]) +# else +constexpr bool empty(const T (&)[N]) noexcept +# endif +{ + return false; +} + +// std::data backport from C++17. +template <class C> +# if defined(_MSC_VER) && _MSC_VER < 1900 +auto data(C const& c) +# else +constexpr auto data(C const& c) noexcept(noexcept(c.data())) +# endif + -> decltype(c.data()) +{ + return c.data(); +} +template <class C> +# if defined(_MSC_VER) && _MSC_VER < 1900 +auto data(C& c) +# else +constexpr auto data(C& c) noexcept(noexcept(c.data())) +# endif + -> decltype(c.data()) +{ + return c.data(); +} +template <typename T, size_t N> +# if defined(_MSC_VER) && _MSC_VER < 1900 +T* data(T (&)[N]) +# else +constexpr T* data(T (&arr)[N]) noexcept +# endif +{ + return arr; +} + +#endif + +} // namespace cm + +#endif diff --git a/Source/cm_memory.hxx b/Utilities/std/cm/memory index 9f5e678..8ebded2 100644 --- a/Source/cm_memory.hxx +++ b/Utilities/std/cm/memory @@ -1,9 +1,10 @@ +// -*-c++-*- +// vim: set ft=cpp: + /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cm_memory_hxx -#define cm_memory_hxx - -#include "cmConfigure.h" // IWYU pragma: keep +#ifndef cm_memory +#define cm_memory #include <memory> // IWYU pragma: export #if !defined(CMake_HAVE_CXX_MAKE_UNIQUE) diff --git a/Source/cm_optional.hxx b/Utilities/std/cm/optional index 295571d..80b0951 100644 --- a/Source/cm_optional.hxx +++ b/Utilities/std/cm/optional @@ -1,20 +1,21 @@ +// -*-c++-*- +// vim: set ft=cpp: + /* 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 +#ifndef cm_optional +#define cm_optional #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define CMake_HAVE_CXX_OPTIONAL #endif #if defined(CMake_HAVE_CXX_OPTIONAL) -# include <optional> +# include <optional> // IWYU pragma: export #else -# include "cm_utility.hxx" # include <memory> -# include <utility> + +# include <cm/utility> #endif namespace cm { diff --git a/Source/cm_thread.hxx b/Utilities/std/cm/shared_mutex index b1f0645..2ac9447 100644 --- a/Source/cm_thread.hxx +++ b/Utilities/std/cm/shared_mutex @@ -1,18 +1,36 @@ +// -*-c++-*- +// vim: set ft=cpp: + /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef CM_THREAD_HXX -#define CM_THREAD_HXX +#ifndef cm_shared_mutex +#define cm_shared_mutex -#include "cmConfigure.h" // IWYU pragma: keep -#include "cm_uv.h" +#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L +# define CMake_HAVE_CXX_SHARED_LOCK +#endif +#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define CMake_HAVE_CXX_SHARED_MUTEX +#endif -namespace cm { +#if defined(CMake_HAVE_CXX_SHARED_LOCK) +# include <shared_mutex> // IWYU pragma: export +#endif +#if !defined(CMake_HAVE_CXX_SHARED_MUTEX) +# include "cm_uv.h" +#endif +namespace cm { +#if defined(CMake_HAVE_CXX_SHARED_MUTEX) +using std::shared_mutex; +#else class shared_mutex { uv_rwlock_t _M_; public: + using native_handle_type = uv_rwlock_t*; + shared_mutex() { uv_rwlock_init(&_M_); } ~shared_mutex() { uv_rwlock_destroy(&_M_); } @@ -20,18 +38,27 @@ public: shared_mutex& operator=(shared_mutex const&) = delete; void lock() { uv_rwlock_wrlock(&_M_); } + bool try_lock() { return uv_rwlock_trywrlock(&_M_) == 0; } void unlock() { uv_rwlock_wrunlock(&_M_); } void lock_shared() { uv_rwlock_rdlock(&_M_); } void unlock_shared() { uv_rwlock_rdunlock(&_M_); } + + native_handle_type native_handle() { return &_M_; } }; +#endif +#if defined(CMake_HAVE_CXX_SHARED_LOCK) +using std::shared_lock; +#else template <typename T> class shared_lock { T& _mutex; public: + using mutex_type = T; + shared_lock(T& m) : _mutex(m) { @@ -43,6 +70,7 @@ public: shared_lock(shared_lock const&) = delete; shared_lock& operator=(shared_lock const&) = delete; }; +#endif } #endif diff --git a/Source/cm_string_view.hxx b/Utilities/std/cm/string_view index 04de797..4d359cb 100644 --- a/Source/cm_string_view.hxx +++ b/Utilities/std/cm/string_view @@ -1,16 +1,17 @@ +// -*-c++-*- +// vim: set ft=cpp: + /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cm_string_view_hxx -#define cm_string_view_hxx - -#include "cmConfigure.h" // IWYU pragma: keep +#ifndef cm_string_view +#define cm_string_view #if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L # define CMake_HAVE_CXX_STRING_VIEW #endif #ifdef CMake_HAVE_CXX_STRING_VIEW -# include <string_view> +# include <string_view> // IWYU pragma: export namespace cm { using std::string_view; } diff --git a/Source/cm_utility.hxx b/Utilities/std/cm/utility index 99d7f8b..3acac4f 100644 --- a/Source/cm_utility.hxx +++ b/Utilities/std/cm/utility @@ -1,17 +1,16 @@ +// -*-c++-*- +// vim: set ft=cpp: + /* 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 +#ifndef cm_utility +#define cm_utility #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 +#include <utility> // IWYU pragma: export namespace cm { @@ -307,7 +307,6 @@ CMAKE_CXX_SOURCES="\ cmExportFileGenerator \ cmExportInstallFileGenerator \ cmExportSet \ - cmExportSetMap \ cmExportTryCompileFileGenerator \ cmExprParserHelper \ cmExternalMakefileProjectGenerator \ @@ -453,7 +452,6 @@ CMAKE_CXX_SOURCES="\ cmake \ cmakemain \ cmcmd \ - cm_string_view \ " if ${cmake_system_mingw}; then @@ -464,6 +462,17 @@ if ${cmake_system_mingw}; then " fi +CMAKE_STD_CXX_HEADERS="\ + memory \ + optional \ + shared_mutex \ + string_view \ + utility \ +" +CMAKE_STD_CXX_SOURCES="\ + string_view \ +" + LexerParser_CXX_SOURCES="\ cmCommandArgumentLexer \ cmCommandArgumentParser \ @@ -1060,6 +1069,10 @@ echo ' #error "On Solaris we need C99." #endif +#if defined(__hpux) && !(defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 409) +#error "On HP-UX we need GCC 4.9 or higher." +#endif + #include <stdio.h> int main(int argc, char* argv[]) @@ -1128,6 +1141,10 @@ echo ' #error "SunPro <= 5.13 mode not supported due to bug in move semantics." #endif +#if defined(__hpux) && !(defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 409) +#error "On HP-UX we need GCC 4.9 or higher." +#endif + #if __cplusplus > 201103L #include <iterator> int check_cxx14() @@ -1346,6 +1363,8 @@ cmake_compiler_settings_comment="/* * * Sources: * ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} + * STD Sources: + * ${CMAKE_STD_CXX_HEADERS} ${CMAKE_STD_CXX_SOURCES} * LexerParser Sources: * ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} * kwSys Sources: @@ -1412,9 +1431,12 @@ done cmake_generate_file "${cmake_bootstrap_dir}/cmThirdParty.h" "" # Generate Makefile -dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.h" +dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.hxx `cmake_escape \"${cmake_source_dir}\"`/Source/*.h" +for h in ${CMAKE_STD_CXX_HEADERS}; do + dep="${dep} `cmake_escape \"${cmake_source_dir}\"`/Utilities/std/cm/${h}" +done objs="" -for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do +for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${CMAKE_STD_CXX_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do objs="${objs} ${a}.o" done for a in ${LIBUV_C_SOURCES}; do @@ -1436,6 +1458,9 @@ else *Darwin*) uv_c_flags="${uv_c_flags} -D_DARWIN_USE_64_BIT_INODE=1 -D_DARWIN_UNLIMITED_SELECT=1" ;; + *HP-UX*) + uv_c_flags="${uv_c_flags} -D_XOPEN_SOURCE_EXTENDED" + ;; *Linux*) uv_c_flags="${uv_c_flags} -D_GNU_SOURCE" libs="${libs} -ldl -lrt" @@ -1498,6 +1523,7 @@ cmake_cxx_flags="${cmake_cxx_flags} \ -I`cmake_escape \"${cmake_bootstrap_dir}\"` \ -I`cmake_escape \"${cmake_source_dir}/Source\"` \ -I`cmake_escape \"${cmake_source_dir}/Source/LexerParser\"` \ + -I`cmake_escape \"${cmake_source_dir}/Utilities/std\"` \ -I`cmake_escape \"${cmake_source_dir}/Utilities\"`" echo "cmake: ${objs}" > "${cmake_bootstrap_dir}/Makefile" echo " ${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} ${libs} -o cmake" >> "${cmake_bootstrap_dir}/Makefile" @@ -1512,6 +1538,12 @@ for a in ${CMAKE_C_SOURCES}; do echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" echo " ${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" done +for a in ${CMAKE_STD_CXX_SOURCES}; do + src=`cmake_escape "${cmake_source_dir}/Utilities/std/cm/bits/${a}.cxx"` + src_flags=`eval echo \\${cmake_cxx_flags_\${a}}` + echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" + echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" +done for a in ${LexerParser_CXX_SOURCES}; do src=`cmake_escape "${cmake_source_dir}/Source/LexerParser/${a}.cxx"` src_flags=`eval echo \\${cmake_cxx_flags_\${a}}` |