diff options
118 files changed, 1327 insertions, 598 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index cf67a66..b6ef543 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -814,6 +814,10 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE) PATTERN "*.sh*" PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + PATTERN "ExportImportList" + PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE REGEX "Help/(dev|guide)($|/)" EXCLUDE ) diff --git a/Help/command/install.rst b/Help/command/install.rst index abf6b17..cf04eda 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -644,6 +644,13 @@ present, causes the contents of the properties matching ``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when policy :policy:`CMP0022` is ``NEW``. +.. note:: + The installed ``<export-name>.cmake`` file may come with additional + per-configuration ``<export-name>-*.cmake`` files to be loaded by + globbing. Do not use an export name that is the same as the package + name in combination with installing a ``<package-name>-config.cmake`` + file or the latter may be incorrectly matched by the glob and loaded. + When a ``COMPONENT`` option is given, the listed ``<component>`` implicitly depends on all components mentioned in the export set. The exported ``<name>.cmake`` file will require each of the exported components to be diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst index 1f68535..f480eb8 100644 --- a/Help/generator/Ninja Multi-Config.rst +++ b/Help/generator/Ninja Multi-Config.rst @@ -33,53 +33,19 @@ below for how to enable cross-config mode. The ``Ninja Multi-Config`` generator recognizes the following variables: :variable:`CMAKE_CONFIGURATION_TYPES` - Specifies the total set of configurations to build. See the variable's - documentation for more information. + Specifies the total set of configurations to build. :variable:`CMAKE_CROSS_CONFIGS` Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations available from all ``build-<Config>.ninja`` files. - This variable activates cross-config mode. - Targets from each config specified in this variable can be built from any - ``build-<Config>.ninja`` file. Custom commands will use the configuration - native to ``build-<Config>.ninja``. If it is set to ``all``, all - configurations from :variable:`CMAKE_CONFIGURATION_TYPES` are cross-configs. - If it is not specified, or empty, each ``build-<Config>.ninja`` file will - only contain build rules for its own configuration. - - The value of this variable must be a subset of - :variable:`CMAKE_CONFIGURATION_TYPES`. :variable:`CMAKE_DEFAULT_BUILD_TYPE` - Specifies the configuration to use by default in a ``build.ninja`` file. If - this variable is specified, ``build.ninja`` uses build rules from - ``build-<Config>.ninja`` by default. All custom commands are executed with - this configuration. If the variable is not specified, the first item from - :variable:`CMAKE_CONFIGURATION_TYPES` is used instead. - - The value of this variable must be one of the items from - :variable:`CMAKE_CONFIGURATION_TYPES`. + Specifies the configuration to use by default in a ``build.ninja`` file. :variable:`CMAKE_DEFAULT_CONFIGS` Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations to build for a target in ``build.ninja`` - if no ``:<Config>`` suffix is specified. If it is set to ``all``, all - configurations from :variable:`CMAKE_CROSS_CONFIGS` are used. If - it is not specified, it defaults to - :variable:`CMAKE_DEFAULT_BUILD_TYPE`. - - For example, if you set - :variable:`CMAKE_DEFAULT_BUILD_TYPE` to ``Release``, but - set :variable:`CMAKE_DEFAULT_CONFIGS` to ``Debug`` or ``all``, - all ``<target>`` aliases in ``build.ninja`` will resolve to - ``<target>:Debug`` or ``<target>:all``, but custom commands will still use - the ``Release`` configuration. - - The value of this variable must be a subset of - :variable:`CMAKE_CROSS_CONFIGS` or be the same as - :variable:`CMAKE_DEFAULT_BUILD_TYPE`. It must not be - specified if :variable:`CMAKE_DEFAULT_BUILD_TYPE` or - :variable:`CMAKE_CROSS_CONFIGS` is not used. + if no ``:<Config>`` suffix is specified. Consider the following example: diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index c256250..08d59e7 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used to determine whether to report an error on use of deprecated macros or functions. +Policies Introduced by CMake 3.18 +================================= + +.. toctree:: + :maxdepth: 1 + + CMP0103: Multiple export() with same FILE without APPEND is not allowed. </policy/CMP0103> + Policies Introduced by CMake 3.17 ================================= diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index e552377..cbb2298 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -127,6 +127,7 @@ Properties on Targets /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG /prop_tgt/ARCHIVE_OUTPUT_NAME + /prop_tgt/PCH_WARN_INVALID /prop_tgt/AUTOGEN_BUILD_DIR /prop_tgt/AUTOGEN_ORIGIN_DEPENDS /prop_tgt/AUTOGEN_PARALLEL @@ -377,6 +378,7 @@ Properties on Targets /prop_tgt/VS_SCC_PROVIDER /prop_tgt/VS_SDK_REFERENCES /prop_tgt/VS_SOLUTION_DEPLOY + /prop_tgt/VS_SOURCE_SETTINGS_tool /prop_tgt/VS_USER_PROPS /prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION /prop_tgt/VS_WINRT_COMPONENT @@ -486,6 +488,7 @@ Properties on Source Files /prop_sf/VS_DEPLOYMENT_LOCATION /prop_sf/VS_INCLUDE_IN_VSIX /prop_sf/VS_RESOURCE_GENERATOR + /prop_sf/VS_SETTINGS /prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS /prop_sf/VS_SHADER_ENABLE_DEBUG /prop_sf/VS_SHADER_ENTRYPOINT diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index c271024..62c301c 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -438,6 +438,7 @@ Variables that Control the Build /variable/CMAKE_OSX_ARCHITECTURES /variable/CMAKE_OSX_DEPLOYMENT_TARGET /variable/CMAKE_OSX_SYSROOT + /variable/CMAKE_PCH_WARN_INVALID /variable/CMAKE_PDB_OUTPUT_DIRECTORY /variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG /variable/CMAKE_POSITION_INDEPENDENT_CODE diff --git a/Help/policy/CMP0103.rst b/Help/policy/CMP0103.rst new file mode 100644 index 0000000..223e0cb --- /dev/null +++ b/Help/policy/CMP0103.rst @@ -0,0 +1,22 @@ +CMP0103 +------- + +Multiple calls to :command:`export` command with same ``FILE`` without +``APPEND`` is no longer allowed. + +In CMake 3.17 and below, multiple calls to :command:`export` command with the +same ``FILE`` without ``APPEND`` are accepted silently but only the last +occurrence is taken into account during the generation. + +The ``OLD`` behavior for this policy is to ignore the multiple occurrences of + :command:`export` command except the last one. + +The ``NEW`` behavior of this policy is to raise an error on second call to +:command:`export` command with same ``FILE`` without ``APPEND``. + +This policy was introduced in CMake version 3.18. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_sf/VS_SETTINGS.rst b/Help/prop_sf/VS_SETTINGS.rst new file mode 100644 index 0000000..0719406 --- /dev/null +++ b/Help/prop_sf/VS_SETTINGS.rst @@ -0,0 +1,18 @@ +VS_SETTINGS +----------- + +Set any item metadata on a non-built file. + +Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator to set +``Key`` to ``Value`` as item metadata on the file. + +For example: + +.. code-block:: cmake + + set_property(SOURCE file.hlsl PROPERTY VS_SETTINGS "Key=Value" "Key2=Value2") + +will set ``Key`` to ``Value`` and ``Key2`` to ``Value2`` on the +``file.hlsl`` item as metadata. + +Generator expressions are supported. diff --git a/Help/prop_tgt/PCH_WARN_INVALID.rst b/Help/prop_tgt/PCH_WARN_INVALID.rst new file mode 100644 index 0000000..36ec348 --- /dev/null +++ b/Help/prop_tgt/PCH_WARN_INVALID.rst @@ -0,0 +1,8 @@ +PCH_WARN_INVALID +---------------- + +When this property is set to true, the precompile header compiler options +will contain a compiler flag wich should warn about invalid precompiled +headers e.g. ``-Winvalid-pch`` for GNU compiler. + +The defalut value is ``ON``. diff --git a/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst new file mode 100644 index 0000000..f706888 --- /dev/null +++ b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst @@ -0,0 +1,19 @@ +VS_SOURCE_SETTINGS_<tool> +------------------------- + +Set any item metadata on all non-built files that use <tool>. + +Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator +to set ``Key`` to ``Value`` as item metadata on all non-built files +that use ``<tool>``. + +For example: + +.. code-block:: cmake + + set_property(TARGET main PROPERTY VS_SOURCE_SETTINGS_FXCompile "Key=Value" "Key2=Value2") + +will set ``Key`` to ``Value`` and ``Key2`` to ``Value2`` for all +non-built files that use ``FXCompile``. + +Generator expressions are supported. diff --git a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst index 0e182cf..c32b4de 100644 --- a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst +++ b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst @@ -38,3 +38,4 @@ The following target properties will be applied on the - :prop_tgt:`XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING` - :prop_tgt:`XCODE_SCHEME_ENVIRONMENT` - :prop_tgt:`XCODE_SCHEME_EXECUTABLE` +- :prop_tgt:`XCODE_SCHEME_WORKING_DIRECTORY` diff --git a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst index 7ffa74b..f538f1d 100644 --- a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst +++ b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst @@ -1,8 +1,8 @@ XCODE_SCHEME_WORKING_DIRECTORY ------------------------------ -Specify the ``Working Directory`` a of the `Run` and `Profile` -action in the generated Xcode scheme. In case the value contains +Specify the ``Working Directory`` of the *Run* and *Profile* +actions in the generated Xcode scheme. In case the value contains generator expressions those are evaluated. This property is initialized by the value of the variable diff --git a/Help/release/dev/export-multiple-calls.rst b/Help/release/dev/export-multiple-calls.rst new file mode 100644 index 0000000..00372ce --- /dev/null +++ b/Help/release/dev/export-multiple-calls.rst @@ -0,0 +1,5 @@ +export-multiple-calls +--------------------- + +* The :command:`export` command now raise an error if used multiple times with + same ``FILE`` without ``APPEND``. See policy :policy:`CMP0103`. diff --git a/Help/release/dev/pch-warn-invalid.rst b/Help/release/dev/pch-warn-invalid.rst new file mode 100644 index 0000000..5fa3de7 --- /dev/null +++ b/Help/release/dev/pch-warn-invalid.rst @@ -0,0 +1,6 @@ +pch-warn-invalid +---------------- + +* The :variable:`CMAKE_PCH_WARN_INVALID` variable was added to initialize the + :prop_tgt:`PCH_WARN_INVALID` target property to allow the removal of the + precompiled header invalid warning. diff --git a/Help/release/dev/vs-non-built-file-item-metadata.rst b/Help/release/dev/vs-non-built-file-item-metadata.rst new file mode 100644 index 0000000..26cbad0 --- /dev/null +++ b/Help/release/dev/vs-non-built-file-item-metadata.rst @@ -0,0 +1,10 @@ +vs-non-built-file-item-metadata +------------------------------- + +* The :prop_tgt:`VS_SOURCE_SETTINGS_<tool>` target property was added + to tell :ref:`Visual Studio Generators` for VS 2010 and above to add + metadata to non-built source files using ``<tool>``. + +* The :prop_sf:`VS_SETTINGS` source file property was added to tell + :ref:`Visual Studio Generators` for VS 2010 and above to add + metadata to a non-built source file. diff --git a/Help/variable/CMAKE_CROSS_CONFIGS.rst b/Help/variable/CMAKE_CROSS_CONFIGS.rst index c850af2..94157f3 100644 --- a/Help/variable/CMAKE_CROSS_CONFIGS.rst +++ b/Help/variable/CMAKE_CROSS_CONFIGS.rst @@ -3,5 +3,13 @@ CMAKE_CROSS_CONFIGS Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations available from all ``build-<Config>.ninja`` files in the -:generator:`Ninja Multi-Config` generator. See the generator's -documentation for more details. +:generator:`Ninja Multi-Config` generator. This variable activates +cross-config mode. Targets from each config specified in this variable can be +built from any ``build-<Config>.ninja`` file. Custom commands will use the +configuration native to ``build-<Config>.ninja``. If it is set to ``all``, all +configurations from :variable:`CMAKE_CONFIGURATION_TYPES` are cross-configs. If +it is not specified, or empty, each ``build-<Config>.ninja`` file will only +contain build rules for its own configuration. + +The value of this variable must be a subset of +:variable:`CMAKE_CONFIGURATION_TYPES`. diff --git a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst index 62ee0d2..aa4f82d 100644 --- a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst +++ b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst @@ -2,5 +2,11 @@ CMAKE_DEFAULT_BUILD_TYPE ------------------------ Specifies the configuration to use by default in a ``build.ninja`` file in the -:generator:`Ninja Multi-Config` generator. See the generator's documentation -for more details. +:generator:`Ninja Multi-Config` generator. If this variable is specified, +``build.ninja`` uses build rules from ``build-<Config>.ninja`` by default. All +custom commands are executed with this configuration. If the variable is not +specified, the first item from :variable:`CMAKE_CONFIGURATION_TYPES` is used +instead. + +The value of this variable must be one of the items from +:variable:`CMAKE_CONFIGURATION_TYPES`. diff --git a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst index 86d8a5a..84c642a 100644 --- a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst +++ b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst @@ -3,5 +3,17 @@ CMAKE_DEFAULT_CONFIGS Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in -the :generator:`Ninja Multi-Config` generator. -See the generator's documentation for more details. +the :generator:`Ninja Multi-Config` generator. If it is set to ``all``, all +configurations from :variable:`CMAKE_CROSS_CONFIGS` are used. If it is not +specified, it defaults to :variable:`CMAKE_DEFAULT_BUILD_TYPE`. + +For example, if you set :variable:`CMAKE_DEFAULT_BUILD_TYPE` to ``Release``, +but set :variable:`CMAKE_DEFAULT_CONFIGS` to ``Debug`` or ``all``, all +``<target>`` aliases in ``build.ninja`` will resolve to ``<target>:Debug`` or +``<target>:all``, but custom commands will still use the ``Release`` +configuration. + +The value of this variable must be a subset of :variable:`CMAKE_CROSS_CONFIGS` +or be the same as :variable:`CMAKE_DEFAULT_BUILD_TYPE`. It must not be +specified if :variable:`CMAKE_DEFAULT_BUILD_TYPE` or +:variable:`CMAKE_CROSS_CONFIGS` is not used. diff --git a/Help/variable/CMAKE_PCH_WARN_INVALID.rst b/Help/variable/CMAKE_PCH_WARN_INVALID.rst new file mode 100644 index 0000000..e152abd --- /dev/null +++ b/Help/variable/CMAKE_PCH_WARN_INVALID.rst @@ -0,0 +1,5 @@ +CMAKE_PCH_WARN_INVALID +---------------------- + +This variable is used to initialize the :prop_tgt:`PCH_WARN_INVALID` +property of targets when they are created. diff --git a/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst index cc690f7..5bb7907 100644 --- a/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst +++ b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst @@ -1,8 +1,8 @@ CMAKE_XCODE_SCHEME_WORKING_DIRECTORY ------------------------------------ -Specify the ``Working Directory`` a of the `Run` and `Profile` -action in the generated Xcode scheme. +Specify the ``Working Directory`` of the *Run* and *Profile* +actions in the generated Xcode scheme. This variable initializes the :prop_tgt:`XCODE_SCHEME_WORKING_DIRECTORY` diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 62ea686..95c3cc9 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -74,6 +74,7 @@ endif() set(_CMAKE_PROCESSING_LANGUAGE "CUDA") include(CMakeFindBinUtils) +include(Compiler/${CMAKE_CUDA_COMPILER_ID}-FindBinUtils OPTIONAL) unset(_CMAKE_PROCESSING_LANGUAGE) if(MSVC_CUDA_ARCHITECTURE_ID) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 812f032..9ebaa6c 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -128,7 +128,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format") endif() - if(CMAKE_GENERATOR STREQUAL "Ninja" AND MSVC_${lang}_ARCHITECTURE_ID) + if(CMAKE_GENERATOR MATCHES "^Ninja" AND MSVC_${lang}_ARCHITECTURE_ID) foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "") CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}") endforeach() @@ -246,8 +246,10 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} set(id_platform ${CMAKE_VS_PLATFORM_NAME}) set(id_lang "${lang}") set(id_PostBuildEvent_Command "") - if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^([Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?|[Cc][Ll][Aa][Nn][Gg][Cc][Ll])$") + if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$") set(id_cl_var "ClangClExecutable") + elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg][Cc][Ll]$") + set(id_cl "$(CLToolExe)") elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*") set(id_cl clang.exe) else() diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake index 0d6ad20..90a9f61 100644 --- a/Modules/CheckIPOSupported.cmake +++ b/Modules/CheckIPOSupported.cmake @@ -113,7 +113,7 @@ macro(_ipo_run_language_check language) endforeach() try_compile( - result + _IPO_LANGUAGE_CHECK_RESULT "${bindir}" "${srcdir}" "${TRY_COMPILE_PROJECT_NAME}" @@ -122,8 +122,10 @@ macro(_ipo_run_language_check language) "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON" OUTPUT_VARIABLE output ) + set(_IPO_LANGUAGE_CHECK_RESULT "${_IPO_LANGUAGE_CHECK_RESULT}") + unset(_IPO_LANGUAGE_CHECK_RESULT CACHE) - if(NOT result) + if(NOT _IPO_LANGUAGE_CHECK_RESULT) file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${language} compiler IPO check failed with the following output:\n" "${output}\n") diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 1c050a2..3357a86 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -114,6 +114,7 @@ macro(__compiler_gnu lang) if (NOT CMAKE_GENERATOR MATCHES "Xcode") set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header") endif() - set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>) - set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) + set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -x ${__pch_header_${lang}} -include <PCH_HEADER>) endmacro() diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake index d895ed0..63a20af 100644 --- a/Modules/Compiler/Intel.cmake +++ b/Modules/Compiler/Intel.cmake @@ -37,7 +37,8 @@ else() set(CMAKE_PCH_EXTENSION .pchi) set(CMAKE_LINK_PCH ON) set(CMAKE_PCH_EPILOGUE "#pragma hdrstop") - set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>) - set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) + set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>) endmacro() endif() diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 0ca1f56..68be3f9 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -321,7 +321,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING) if (NAME STREQUAL "PREFIX") - execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -332,16 +332,23 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) list (REMOVE_DUPLICATES _values) endif() elseif (NAME STREQUAL "INCLUDES") - execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))" + if (WIN32) + set (_scheme "nt") + else() + set (_scheme "posix_prefix") + endif() + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (_result) unset (_values) + else() + list (REMOVE_DUPLICATES _values) endif() elseif (NAME STREQUAL "SOABI") - execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))" RESULT_VARIABLE _result OUTPUT_VARIABLE _soabi ERROR_QUIET @@ -349,14 +356,15 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) if (_result) unset (_values) else() - list (GET _soabi 0 _values) - if (NOT _values) - # try to compute SOABI from EXT_SUFFIX - list (GET _soabi 1 _values) - if (_values) - # clean-up: remove prefix character and suffix - string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") + foreach (_item IN LISTS _soabi) + if (_item) + set (_values "${_item}") + break() endif() + endforeach() + if (_values) + # clean-up: remove prefix character and suffix + string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") endif() endif() else() @@ -364,7 +372,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) if (NAME STREQUAL "CONFIGDIR") set (config_flag "LIBPL") endif() - execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -392,6 +400,10 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) list (REMOVE_DUPLICATES _values) endif() + if (WIN32 AND NAME MATCHES "^(PREFIX|CONFIGDIR|INCLUDES)$") + file (TO_CMAKE_PATH "${_values}" _values) + endif() + set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) endfunction() @@ -1297,7 +1309,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 1 ${_PYTHON_PREFIX}_VERSION_MAJOR) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 2 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATH) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATCH) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 4 _${_PYTHON_PREFIX}_ARCH) set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) @@ -1381,7 +1393,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() # retrieve various package installation directories - execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS ERROR_QUIET) diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake index 1d4398e..975ce6c 100644 --- a/Modules/GoogleTest.cmake +++ b/Modules/GoogleTest.cmake @@ -152,6 +152,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also [TEST_LIST var] [DISCOVERY_TIMEOUT seconds] [XML_OUTPUT_DIR dir] + [DISCOVERY_MODE <POST_BUILD|PRE_TEST>] ) ``gtest_discover_tests`` sets up a post-build command on the test executable @@ -244,6 +245,22 @@ same as the Google Test name (i.e. ``suite.testcase``); see also ``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the XML result output when using parallel test execution. + ``DISCOVERY_MODE`` + Provides greater control over when ``gtest_discover_tests``performs test + discovery. By default, ``POST_BUILD`` sets up a post-build command + to perform test discovery at build time. In certain scenarios, like + cross-compiling, this ``POST_BUILD`` behavior is not desirable. + By contrast, ``PRE_TEST`` delays test discovery until just prior to test + execution. This way test discovery occurs in the target environment + where the test has a better chance at finding appropriate runtime + dependencies. + + ``DISCOVERY_MODE`` defaults to the value of the + ``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not + passed when calling ``gtest_discover_tests``. This provides a mechanism + for globally selecting a preferred test discovery behavior without having + to modify each call site. + #]=======================================================================] # Save project's policies @@ -376,11 +393,12 @@ function(gtest_add_tests) endfunction() #------------------------------------------------------------------------------ + function(gtest_discover_tests TARGET) cmake_parse_arguments( "" "NO_PRETTY_TYPES;NO_PRETTY_VALUES" - "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR" + "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE" "EXTRA_ARGS;PROPERTIES" ${ARGN} ) @@ -394,6 +412,12 @@ function(gtest_discover_tests TARGET) if(NOT _DISCOVERY_TIMEOUT) set(_DISCOVERY_TIMEOUT 5) endif() + if(NOT _DISCOVERY_MODE) + if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE) + set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD") + endif() + set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE}) + endif() get_property( has_counter @@ -425,35 +449,86 @@ function(gtest_discover_tests TARGET) TARGET ${TARGET} PROPERTY CROSSCOMPILING_EMULATOR ) - add_custom_command( - TARGET ${TARGET} POST_BUILD - BYPRODUCTS "${ctest_tests_file}" - COMMAND "${CMAKE_COMMAND}" - -D "TEST_TARGET=${TARGET}" - -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>" - -D "TEST_EXECUTOR=${crosscompiling_emulator}" - -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" - -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" - -D "TEST_PROPERTIES=${_PROPERTIES}" - -D "TEST_PREFIX=${_TEST_PREFIX}" - -D "TEST_SUFFIX=${_TEST_SUFFIX}" - -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}" - -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}" - -D "TEST_LIST=${_TEST_LIST}" - -D "CTEST_FILE=${ctest_tests_file}" - -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}" - -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}" - -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}" - VERBATIM - ) - file(WRITE "${ctest_include_file}" - "if(EXISTS \"${ctest_tests_file}\")\n" - " include(\"${ctest_tests_file}\")\n" - "else()\n" - " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n" - "endif()\n" - ) + if(_DISCOVERY_MODE STREQUAL "POST_BUILD") + add_custom_command( + TARGET ${TARGET} POST_BUILD + BYPRODUCTS "${ctest_tests_file}" + COMMAND "${CMAKE_COMMAND}" + -D "TEST_TARGET=${TARGET}" + -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>" + -D "TEST_EXECUTOR=${crosscompiling_emulator}" + -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" + -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" + -D "TEST_PROPERTIES=${_PROPERTIES}" + -D "TEST_PREFIX=${_TEST_PREFIX}" + -D "TEST_SUFFIX=${_TEST_SUFFIX}" + -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}" + -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}" + -D "TEST_LIST=${_TEST_LIST}" + -D "CTEST_FILE=${ctest_tests_file}" + -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}" + -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}" + -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}" + VERBATIM + ) + + file(WRITE "${ctest_include_file}" + "if(EXISTS \"${ctest_tests_file}\")\n" + " include(\"${ctest_tests_file}\")\n" + "else()\n" + " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n" + "endif()\n" + ) + elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST") + + get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL + PROPERTY GENERATOR_IS_MULTI_CONFIG + ) + + if(GENERATOR_IS_MULTI_CONFIG) + set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake") + endif() + + string(CONCAT ctest_include_content + "if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n" + " if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n" + " include(GoogleTestAddTests)" "\n" + " gtest_discover_tests_impl(" "\n" + " TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n" + " TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n" + " TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n" + " TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n" + " TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n" + " TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n" + " TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n" + " NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n" + " NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n" + " TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n" + " CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n" + " TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n" + " TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n" + " )" "\n" + " endif()" "\n" + " include(\"${ctest_tests_file}\")" "\n" + "else()" "\n" + " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n" + "endif()" "\n" + ) + + if(GENERATOR_IS_MULTI_CONFIG) + foreach(_config ${CMAKE_CONFIGURATION_TYPES}) + file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>) + endforeach() + file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")") + else() + file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}") + file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")") + endif() + + else() + message(SEND_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}") + endif() # Add discovered tests to directory TEST_INCLUDE_FILES set_property(DIRECTORY diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake index 753319f..65af4c2 100644 --- a/Modules/GoogleTestAddTests.cmake +++ b/Modules/GoogleTestAddTests.cmake @@ -3,21 +3,12 @@ cmake_minimum_required(VERSION ${CMAKE_VERSION}) -set(prefix "${TEST_PREFIX}") -set(suffix "${TEST_SUFFIX}") -set(extra_args ${TEST_EXTRA_ARGS}) -set(properties ${TEST_PROPERTIES}) -set(script) -set(suite) -set(tests) -set(tests_buffer) - -# Overwrite possibly existing ${CTEST_FILE} with empty file +# Overwrite possibly existing ${_CTEST_FILE} with empty file set(flush_tests_MODE WRITE) -# Flushes script to ${CTEST_FILE} +# Flushes script to ${_CTEST_FILE} macro(flush_script) - file(${flush_tests_MODE} "${CTEST_FILE}" "${script}") + file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}") set(flush_tests_MODE APPEND) set(script "") @@ -48,98 +39,137 @@ macro(add_command NAME) unset(_script_len) endmacro() -# Run test executable to get list of available tests -if(NOT EXISTS "${TEST_EXECUTABLE}") - message(FATAL_ERROR - "Specified test executable does not exist.\n" - " Path: '${TEST_EXECUTABLE}'" +function(gtest_discover_tests_impl) + + cmake_parse_arguments( + "" + "" + "NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR" + "TEST_EXTRA_ARGS;TEST_PROPERTIES" + ${ARGN} ) -endif() -execute_process( - COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" --gtest_list_tests - WORKING_DIRECTORY "${TEST_WORKING_DIR}" - TIMEOUT ${TEST_DISCOVERY_TIMEOUT} - OUTPUT_VARIABLE output - RESULT_VARIABLE result -) -if(NOT ${result} EQUAL 0) - string(REPLACE "\n" "\n " output "${output}") - message(FATAL_ERROR - "Error running test executable.\n" - " Path: '${TEST_EXECUTABLE}'\n" - " Result: ${result}\n" - " Output:\n" - " ${output}\n" + + set(prefix "${_TEST_PREFIX}") + set(suffix "${_TEST_SUFFIX}") + set(extra_args ${_TEST_EXTRA_ARGS}) + set(properties ${_TEST_PROPERTIES}) + set(script) + set(suite) + set(tests) + set(tests_buffer) + + # Run test executable to get list of available tests + if(NOT EXISTS "${_TEST_EXECUTABLE}") + message(FATAL_ERROR + "Specified test executable does not exist.\n" + " Path: '${_TEST_EXECUTABLE}'" + ) + endif() + execute_process( + COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests + WORKING_DIRECTORY "${_TEST_WORKING_DIR}" + TIMEOUT ${_TEST_DISCOVERY_TIMEOUT} + OUTPUT_VARIABLE output + RESULT_VARIABLE result ) -endif() + if(NOT ${result} EQUAL 0) + string(REPLACE "\n" "\n " output "${output}") + message(FATAL_ERROR + "Error running test executable.\n" + " Path: '${_TEST_EXECUTABLE}'\n" + " Result: ${result}\n" + " Output:\n" + " ${output}\n" + ) + endif() -string(REPLACE "\n" ";" output "${output}") - -# Parse output -foreach(line ${output}) - # Skip header - if(NOT line MATCHES "gtest_main\\.cc") - # Do we have a module name or a test name? - if(NOT line MATCHES "^ ") - # Module; remove trailing '.' to get just the name... - string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}") - if(line MATCHES "#" AND NOT NO_PRETTY_TYPES) - string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}") - else() - set(pretty_suite "${suite}") - endif() - string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}") - else() - # Test name; strip spaces and comments to get just the name... - string(REGEX REPLACE " +" "" test "${line}") - if(test MATCHES "#" AND NOT NO_PRETTY_VALUES) - string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}") - else() - string(REGEX REPLACE "#.*" "" pretty_test "${test}") - endif() - string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}") - string(REGEX REPLACE "#.*" "" test "${test}") - if(NOT TEST_XML_OUTPUT_DIR STREQUAL "") - set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${TEST_XML_OUTPUT_DIR}/${prefix}${pretty_suite}.${pretty_test}${suffix}.xml") + string(REPLACE "\n" ";" output "${output}") + + # Parse output + foreach(line ${output}) + # Skip header + if(NOT line MATCHES "gtest_main\\.cc") + # Do we have a module name or a test name? + if(NOT line MATCHES "^ ") + # Module; remove trailing '.' to get just the name... + string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}") + if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES) + string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}") + else() + set(pretty_suite "${suite}") + endif() + string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}") else() - unset(TEST_XML_OUTPUT_PARAM) - endif() - # ...and add to script - add_command(add_test - "${prefix}${pretty_suite}.${pretty_test}${suffix}" - ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - "--gtest_filter=${suite}.${test}" - "--gtest_also_run_disabled_tests" - ${TEST_XML_OUTPUT_PARAM} - ${extra_args} - ) - if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED") + # Test name; strip spaces and comments to get just the name... + string(REGEX REPLACE " +" "" test "${line}") + if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES) + string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}") + else() + string(REGEX REPLACE "#.*" "" pretty_test "${test}") + endif() + string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}") + string(REGEX REPLACE "#.*" "" test "${test}") + if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "") + set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${pretty_suite}.${pretty_test}${suffix}.xml") + else() + unset(TEST_XML_OUTPUT_PARAM) + endif() + # ...and add to script + add_command(add_test + "${prefix}${pretty_suite}.${pretty_test}${suffix}" + ${_TEST_EXECUTOR} + "${_TEST_EXECUTABLE}" + "--gtest_filter=${suite}.${test}" + "--gtest_also_run_disabled_tests" + ${TEST_XML_OUTPUT_PARAM} + ${extra_args} + ) + if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED") + add_command(set_tests_properties + "${prefix}${pretty_suite}.${pretty_test}${suffix}" + PROPERTIES DISABLED TRUE + ) + endif() add_command(set_tests_properties "${prefix}${pretty_suite}.${pretty_test}${suffix}" - PROPERTIES DISABLED TRUE + PROPERTIES + WORKING_DIRECTORY "${_TEST_WORKING_DIR}" + ${properties} ) - endif() - add_command(set_tests_properties - "${prefix}${pretty_suite}.${pretty_test}${suffix}" - PROPERTIES - WORKING_DIRECTORY "${TEST_WORKING_DIR}" - ${properties} - ) - list(APPEND tests_buffer "${prefix}${pretty_suite}.${pretty_test}${suffix}") - list(LENGTH tests_buffer tests_buffer_length) - if(${tests_buffer_length} GREATER "250") - flush_tests_buffer() + list(APPEND tests_buffer "${prefix}${pretty_suite}.${pretty_test}${suffix}") + list(LENGTH tests_buffer tests_buffer_length) + if(${tests_buffer_length} GREATER "250") + flush_tests_buffer() + endif() endif() endif() - endif() -endforeach() + endforeach() + + + # Create a list of all discovered tests, which users may use to e.g. set + # properties on the tests + flush_tests_buffer() + add_command(set ${_TEST_LIST} ${tests}) + # Write CTest script + flush_script() -# Create a list of all discovered tests, which users may use to e.g. set -# properties on the tests -flush_tests_buffer() -add_command(set ${TEST_LIST} ${tests}) +endfunction() -# Write CTest script -flush_script() +if(CMAKE_SCRIPT_MODE_FILE) + gtest_discover_tests_impl( + NO_PRETTY_TYPES ${NO_PRETTY_TYPES} + NO_PRETTY_VALUES ${NO_PRETTY_VALUES} + TEST_EXECUTABLE ${TEST_EXECUTABLE} + TEST_EXECUTOR ${TEST_EXECUTOR} + TEST_WORKING_DIR ${TEST_WORKING_DIR} + TEST_PREFIX ${TEST_PREFIX} + TEST_SUFFIX ${TEST_SUFFIX} + TEST_LIST ${TEST_LIST} + CTEST_FILE ${CTEST_FILE} + TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT} + TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR} + TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS} + TEST_PROPERTIES ${TEST_PROPERTIES} + ) +endif() diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 0c366b4..018de4c 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -134,14 +134,15 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" include(Platform/Windows-MSVC) # Feed the preprocessed rc file to llvm-rc - if(CMAKE_RC_COMPILER_INIT STREQUAL "llvm-rc") - if(DEFINED CMAKE_C_COMPILER) + if(CMAKE_RC_COMPILER_INIT MATCHES "llvm-rc") + if(DEFINED CMAKE_C_COMPILER_ID) set(CMAKE_RC_PREPROCESSOR CMAKE_C_COMPILER) - elseif(DEFINED CMAKE_CXX_COMPILER) + elseif(DEFINED CMAKE_CXX_COMPILER_ID) set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER) endif() if(DEFINED CMAKE_RC_PREPROCESSOR) - set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -clang:-MD -clang:-MF -clang:<SOURCE>.d -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> /fo <OBJECT> <OBJECT>.pp") + set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>") + set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> /fo <OBJECT> <OBJECT>.pp") if(CMAKE_GENERATOR STREQUAL "Ninja") set(CMAKE_NINJA_CMCLDEPS_RC 0) set(CMAKE_NINJA_DEP_TYPE_RC gcc) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 73b7771..b37e1ee 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 17) -set(CMake_VERSION_PATCH 20200326) +set(CMake_VERSION_PATCH 20200331) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index d867fa1..811a7e8 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -260,11 +260,10 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); if (cm) { - const char* subproject = - cm->GetState()->GetGlobalProperty("SubProject"); + cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject"); if (subproject) { upload_as += "&subproject="; - upload_as += ctest_curl.Escape(subproject); + upload_as += ctest_curl.Escape(*subproject); } } } @@ -556,11 +555,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, // a "&subproject=subprojectname" to the first POST. cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); - const char* subproject = cm->GetState()->GetGlobalProperty("SubProject"); + cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject"); // TODO: Encode values for a URL instead of trusting caller. std::ostringstream str; if (subproject) { - str << "subproject=" << curl.Escape(subproject) << "&"; + str << "subproject=" << curl.Escape(*subproject) << "&"; } auto timeNow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 76ffb20..2742fd7 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -249,7 +249,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf) this->PipeReader.reset(); if (this->ProcessHandleClosed) { uv_timer_stop(this->Timer); - this->Runner->FinalizeTest(); + this->Finish(); } } @@ -291,7 +291,7 @@ void cmProcess::OnTimeout() // Our on-exit handler already ran but did not finish the test // because we were still reading output. We've just dropped // our read handler, so we need to finish the test now. - this->Runner->FinalizeTest(); + this->Finish(); } } @@ -321,6 +321,16 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal) // Record exit information. this->ExitValue = exit_status; this->Signal = term_signal; + + this->ProcessHandleClosed = true; + if (this->ReadHandleClosed) { + uv_timer_stop(this->Timer); + this->Finish(); + } +} + +void cmProcess::Finish() +{ this->TotalTime = std::chrono::steady_clock::now() - this->StartTime; // Because of a processor clock scew the runtime may become slightly // negative. If someone changed the system clock while the process was @@ -329,12 +339,7 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal) if (this->TotalTime <= cmDuration::zero()) { this->TotalTime = cmDuration::zero(); } - - this->ProcessHandleClosed = true; - if (this->ReadHandleClosed) { - uv_timer_stop(this->Timer); - this->Runner->FinalizeTest(); - } + this->Runner->FinalizeTest(); } cmProcess::State cmProcess::GetProcessStatus() diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index 0f69f68..526c920 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -108,6 +108,7 @@ private: void OnAllocate(size_t suggested_size, uv_buf_t* buf); void StartTimer(); + void Finish(); class Buffer : public std::vector<char> { diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index 9a0d966..9250fbc 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -71,11 +71,11 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( break; } case cmStateEnums::STRING: { - const char* stringsProp = state->GetCacheEntryProperty(key, "STRINGS"); + cmProp stringsProp = state->GetCacheEntryProperty(key, "STRINGS"); if (stringsProp) { auto ow = cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1); - for (std::string const& opt : cmExpandedList(stringsProp)) { + for (std::string const& opt : cmExpandedList(*stringsProp)) { ow->AddOption(opt); } ow->SetOption(*value); diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 9670595..7752a68 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -407,9 +407,10 @@ void cmCursesMainForm::UpdateStatusBar(cm::optional<std::string> message) auto cmakeState = this->CMakeInstance->GetState(); cmProp existingValue = cmakeState->GetCacheEntryValue(labelValue); if (existingValue) { - auto help = cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING"); + cmProp help = + cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING"); if (help) { - bar += help; + bar += *help; } } } @@ -802,7 +803,7 @@ void cmCursesMainForm::HandleInput() cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>( field_userptr(this->Fields[findex - 2])); const char* curField = lbl->GetValue(); - const char* helpString = nullptr; + cmProp helpString = nullptr; cmProp existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(curField); @@ -813,7 +814,7 @@ void cmCursesMainForm::HandleInput() if (helpString) { this->HelpMessage[1] = cmStrCat("Current option is: ", curField, '\n', - "Help string for this option is: ", helpString, '\n'); + "Help string for this option is: ", *helpString, '\n'); } else { this->HelpMessage[1] = ""; } diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 2543215..776af81 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -306,8 +306,9 @@ QCMakePropertyList QCMake::properties() const QCMakeProperty prop; prop.Key = QString::fromLocal8Bit(key.c_str()); - prop.Help = - QString::fromLocal8Bit(state->GetCacheEntryProperty(key, "HELPSTRING")); + if (cmProp hs = state->GetCacheEntryProperty(key, "HELPSTRING")) { + prop.Help = QString::fromLocal8Bit(hs->c_str()); + } prop.Value = QString::fromLocal8Bit(cachedValue->c_str()); prop.Advanced = state->GetCacheEntryPropertyAsBool(key, "ADVANCED"); if (t == cmStateEnums::BOOL) { @@ -319,10 +320,10 @@ QCMakePropertyList QCMake::properties() const prop.Type = QCMakeProperty::FILEPATH; } else if (t == cmStateEnums::STRING) { prop.Type = QCMakeProperty::STRING; - const char* stringsProperty = - state->GetCacheEntryProperty(key, "STRINGS"); + cmProp stringsProperty = state->GetCacheEntryProperty(key, "STRINGS"); if (stringsProperty) { - prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";"); + prop.Strings = + QString::fromLocal8Bit(stringsProperty->c_str()).split(";"); } } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index b9fb4a0..c5505f9 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1443,16 +1443,15 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml) return; } // This code should go when cdash is changed to use labels only - const char* subproject = cm->GetState()->GetGlobalProperty("SubProject"); + cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject"); if (subproject) { xml.StartElement("Subproject"); - xml.Attribute("name", subproject); - const char* labels = + xml.Attribute("name", *subproject); + cmProp labels = ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels"); if (labels) { xml.StartElement("Labels"); - std::string l = labels; - std::vector<std::string> args = cmExpandedList(l); + std::vector<std::string> args = cmExpandedList(*labels); for (std::string const& i : args) { xml.Element("Label", i); } @@ -1462,10 +1461,10 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml) } // This code should stay when cdash only does label based sub-projects - const char* label = cm->GetState()->GetGlobalProperty("Label"); + cmProp label = cm->GetState()->GetGlobalProperty("Label"); if (label) { xml.StartElement("Labels"); - xml.Element("Label", label); + xml.Element("Label", *label); xml.EndElement(); } } diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index c444fce..31a8692 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -77,7 +77,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, } while (realbuffer[0] == '/' && realbuffer[1] == '/') { if ((realbuffer[2] == '\\') && (realbuffer[3] == 'n')) { - helpString += "\n"; + helpString += '\n'; helpString += &realbuffer[4]; } else { helpString += &realbuffer[2]; @@ -117,8 +117,8 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, } } else { std::ostringstream error; - error << "Parse error in cache file " << cacheFile; - error << " on line " << lineno << ". Offending entry: " << realbuffer; + error << "Parse error in cache file " << cacheFile << " on line " + << lineno << ". Offending entry: " << realbuffer; cmSystemTools::Error(error.str()); } } @@ -217,7 +217,7 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i, cmCacheManager::OutputKey(os, key); os << ":INTERNAL="; cmCacheManager::OutputValue(os, *value); - os << "\n"; + os << '\n'; cmCacheManager::OutputNewlineTruncationWarning(os, key, *value, messenger); } @@ -268,31 +268,29 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) /* clang-format off */ fout << "# This is the CMakeCache file.\n" - << "# For build in directory: " << currentcwd << "\n" - << "# It was generated by CMake: " - << cmSystemTools::GetCMakeCommand() << std::endl; + "# For build in directory: " << currentcwd << "\n" + "# It was generated by CMake: " + << cmSystemTools::GetCMakeCommand() + << "\n" + "# You can edit this file to change values found and used by cmake." + "\n" + "# If you do not want to change any of the values, simply exit the " + "editor.\n" + "# If you do want to change a value, simply edit, save, and exit " + "the editor.\n" + "# The syntax for the file is as follows:\n" + "# KEY:TYPE=VALUE\n" + "# KEY is the name of a variable in the cache.\n" + "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!." + "\n" + "# VALUE is the current value for the KEY.\n" + "\n" + "########################\n" + "# EXTERNAL cache entries\n" + "########################\n" + "\n"; /* clang-format on */ - /* clang-format off */ - fout << "# You can edit this file to change values found and used by cmake." - << std::endl - << "# If you do not want to change any of the values, simply exit the " - "editor." << std::endl - << "# If you do want to change a value, simply edit, save, and exit " - "the editor." << std::endl - << "# The syntax for the file is as follows:\n" - << "# KEY:TYPE=VALUE\n" - << "# KEY is the name of a variable in the cache.\n" - << "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT " - "TYPE!." << std::endl - << "# VALUE is the current value for the KEY.\n\n"; - /* clang-format on */ - - fout << "########################\n"; - fout << "# EXTERNAL cache entries\n"; - fout << "########################\n"; - fout << "\n"; - for (auto const& i : this->Cache) { CacheEntry const& ce = i.second; cmStateEnums::CacheEntryType t = ce.Type; @@ -309,20 +307,20 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) cmCacheManager::OutputHelpString(fout, "Missing description"); } cmCacheManager::OutputKey(fout, i.first); - fout << ":" << cmState::CacheEntryTypeToString(t) << "="; + fout << ':' << cmState::CacheEntryTypeToString(t) << '='; cmCacheManager::OutputValue(fout, ce.Value); - fout << "\n"; + fout << '\n'; cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value, messenger); - fout << "\n"; + fout << '\n'; } } - fout << "\n"; - fout << "########################\n"; - fout << "# INTERNAL cache entries\n"; - fout << "########################\n"; - fout << "\n"; + fout << "\n" + "########################\n" + "# INTERNAL cache entries\n" + "########################\n" + "\n"; for (cmCacheManager::CacheIterator i = this->NewIterator(); !i.IsAtEnd(); i.Next()) { @@ -338,14 +336,14 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) cmCacheManager::OutputHelpString(fout, *help); } cmCacheManager::OutputKey(fout, i.GetName()); - fout << ":" << cmState::CacheEntryTypeToString(t) << "="; + fout << ':' << cmState::CacheEntryTypeToString(t) << '='; cmCacheManager::OutputValue(fout, i.GetValue()); - fout << "\n"; + fout << '\n'; cmCacheManager::OutputNewlineTruncationWarning(fout, i.GetName(), i.GetValue(), messenger); } } - fout << "\n"; + fout << '\n'; fout.Close(); std::string checkCacheFile = cmStrCat(path, "/CMakeFiles"); cmSystemTools::MakeDirectory(checkCacheFile); @@ -430,7 +428,7 @@ void cmCacheManager::OutputHelpString(std::ostream& fout, fout << "\\n"; } oneLine = helpString.substr(pos, i - pos); - fout << oneLine << "\n"; + fout << oneLine << '\n'; pos = i; } } @@ -452,7 +450,7 @@ void cmCacheManager::OutputWarningComment(std::ostream& fout, fout << "\\n"; } oneLine = message.substr(pos, i - pos); - fout << oneLine << "\n"; + fout << oneLine << '\n'; pos = i; } } @@ -519,17 +517,17 @@ cmProp cmCacheManager::GetInitializedCacheValue(const std::string& key) const void cmCacheManager::PrintCache(std::ostream& out) const { - out << "=================================================" << std::endl; - out << "CMakeCache Contents:" << std::endl; + out << "=================================================\n" + "CMakeCache Contents:\n"; for (auto const& i : this->Cache) { if (i.second.Type != cmStateEnums::INTERNAL) { - out << i.first << " = " << i.second.Value << std::endl; + out << i.first << " = " << i.second.Value << '\n'; } } - out << "\n\n"; - out << "To change values in the CMakeCache, " << std::endl - << "edit CMakeCache.txt in your output directory.\n"; - out << "=================================================" << std::endl; + out << "\n\n" + "To change values in the CMakeCache, \n" + "edit CMakeCache.txt in your output directory.\n" + "=================================================\n"; } void cmCacheManager::AddCacheEntry(const std::string& key, const char* value, diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx index 9e152ff..94b6e18 100644 --- a/Source/cmCallVisualStudioMacro.cxx +++ b/Source/cmCallVisualStudioMacro.cxx @@ -43,8 +43,7 @@ static bool LogErrorsAsMessages; if (LogErrorsAsMessages) { \ std::ostringstream _hresult_oss; \ _hresult_oss.flags(std::ios::hex); \ - _hresult_oss << context << " failed HRESULT, hr = 0x" << hr \ - << std::endl; \ + _hresult_oss << context << " failed HRESULT, hr = 0x" << hr << '\n'; \ _hresult_oss.flags(std::ios::dec); \ _hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \ cmSystemTools::Message(_hresult_oss.str()); \ @@ -98,32 +97,37 @@ HRESULT InstanceCallMacro(IDispatch* vsIDE, const std::string& macro, DISPATCH_METHOD, ¶ms, &result, &excep, &arg); std::ostringstream oss; - oss << std::endl; - oss << "Invoke(ExecuteCommand)" << std::endl; - oss << " Macro: " << macro << std::endl; - oss << " Args: " << args << std::endl; + /* clang-format off */ + oss << "\nInvoke(ExecuteCommand)\n" + " Macro: " << macro << "\n" + " Args: " << args << '\n'; + /* clang-format on */ if (DISP_E_EXCEPTION == hr) { - oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl; - oss << " wCode: " << excep.wCode << std::endl; - oss << " wReserved: " << excep.wReserved << std::endl; + /* clang-format off */ + oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << "\n" + " wCode: " << excep.wCode << "\n" + " wReserved: " << excep.wReserved << '\n'; + /* clang-format on */ if (excep.bstrSource) { oss << " bstrSource: " << (const char*)(_bstr_t)excep.bstrSource - << std::endl; + << '\n'; } if (excep.bstrDescription) { oss << " bstrDescription: " - << (const char*)(_bstr_t)excep.bstrDescription << std::endl; + << (const char*)(_bstr_t)excep.bstrDescription << '\n'; } if (excep.bstrHelpFile) { oss << " bstrHelpFile: " << (const char*)(_bstr_t)excep.bstrHelpFile - << std::endl; + << '\n'; } - oss << " dwHelpContext: " << excep.dwHelpContext << std::endl; - oss << " pvReserved: " << excep.pvReserved << std::endl; - oss << " pfnDeferredFillIn: " - << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << std::endl; - oss << " scode: " << excep.scode << std::endl; + /* clang-format off */ + oss << " dwHelpContext: " << excep.dwHelpContext << "\n" + " pvReserved: " << excep.pvReserved << "\n" + " pfnDeferredFillIn: " + << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << "\n" + " scode: " << excep.scode << '\n'; + /* clang-format on */ } std::string exstr(oss.str()); diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index e49c174..f31759d 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -24,6 +24,7 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -183,6 +184,28 @@ bool cmExportCommand(std::vector<std::string> const& args, return false; } + // if cmExportBuildFileGenerator is already defined for the file + // and APPEND is not specified, if CMP0103 is OLD ignore previous definition + // else raise an error + if (gg->GetExportedTargetsFile(fname) != nullptr) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) { + case cmPolicies::WARN: + mf.IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0103), '\n', + "export() command already specified for the file\n ", + arguments.Filename, "\nDid you miss 'APPEND' keyword?")); + CM_FALLTHROUGH; + case cmPolicies::OLD: + break; + default: + status.SetError(cmStrCat("command already specified for the file\n ", + arguments.Filename, + "\nDid you miss 'APPEND' keyword?")); + return false; + } + } + // Setup export file generation. std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr; if (android) { diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 003019a..ea31417 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -276,8 +276,7 @@ static bool checkInterfaceDirs(const std::string& prepro, << "\"\nhowever it is also " "a subdirectory of the " << (inBinary ? "build" : "source") << " tree:\n \"" - << (inBinary ? topBinaryDir : topSourceDir) << "\"" - << std::endl; + << (inBinary ? topBinaryDir : topSourceDir) << "\"\n"; target->GetLocalGenerator()->IssueMessage( MessageType::AUTHOR_WARNING, s.str()); CM_FALLTHROUGH; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index aea3dc4..737b0e5 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -415,9 +415,9 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() xml.Element("nature", n); } - if (const char* extraNaturesProp = + if (cmProp extraNaturesProp = mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) { - std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp); + std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp); for (std::string const& n : extraNatures) { xml.Element("nature", n); } @@ -1033,9 +1033,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const xml.EndElement(); // storageModule // Append additional cproject contents without applying any XML formatting - if (const char* extraCProjectContents = + if (cmProp extraCProjectContents = mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_CPROJECT_CONTENTS")) { - fout << extraCProjectContents; + fout << *extraCProjectContents; } xml.EndElement(); // cproject diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx index 639df52..5d2ddf9 100644 --- a/Source/cmFileAPICache.cxx +++ b/Source/cmFileAPICache.cxx @@ -94,7 +94,8 @@ Json::Value Cache::DumpEntryProperty(std::string const& name, { Json::Value property = Json::objectValue; property["name"] = prop; - property["value"] = this->State->GetCacheEntryProperty(name, prop); + cmProp p = this->State->GetCacheEntryProperty(name, prop); + property["value"] = p ? *p : ""; return property; } } diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 4d627bd..b5553b8 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -312,9 +312,9 @@ bool cmFindBase::CheckForVariableInCache() return true; } if (cached) { - const char* hs = + cmProp hs = state->GetCacheEntryProperty(this->VariableName, "HELPSTRING"); - this->VariableDocumentation = hs ? hs : "(none)"; + this->VariableDocumentation = hs ? *hs : "(none)"; } } return false; diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index f606002..e996327 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1114,12 +1114,10 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f, void cmFindPackageCommand::AppendToFoundProperty(bool found) { std::vector<std::string> foundContents; - const char* foundProp = + cmProp foundProp = this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND"); - if (foundProp && *foundProp) { - std::string tmp = foundProp; - - cmExpandList(tmp, foundContents, false); + if (foundProp && !foundProp->empty()) { + cmExpandList(*foundProp, foundContents, false); auto nameIt = std::find(foundContents.begin(), foundContents.end(), this->Name); if (nameIt != foundContents.end()) { @@ -1128,12 +1126,10 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) } std::vector<std::string> notFoundContents; - const char* notFoundProp = + cmProp notFoundProp = this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND"); - if (notFoundProp && *notFoundProp) { - std::string tmp = notFoundProp; - - cmExpandList(tmp, notFoundContents, false); + if (notFoundProp && !notFoundProp->empty()) { + cmExpandList(*notFoundProp, notFoundContents, false); auto nameIt = std::find(notFoundContents.begin(), notFoundContents.end(), this->Name); if (nameIt != notFoundContents.end()) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index af95089..e722034 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3781,9 +3781,16 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions( if (inserted.second) { std::string& createOptionList = inserted.first->second; + if (this->GetPropertyAsBool("PCH_WARN_INVALID")) { + createOptionList = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH")); + } + const std::string createOptVar = cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH"); - createOptionList = this->Makefile->GetSafeDefinition(createOptVar); + + createOptionList = cmStrCat( + createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar)); const std::string pchHeader = this->GetPchHeader(config, language); const std::string pchFile = this->GetPchFile(config, language); @@ -3802,9 +3809,16 @@ std::string cmGeneratorTarget::GetPchUseCompileOptions( if (inserted.second) { std::string& useOptionList = inserted.first->second; + if (this->GetPropertyAsBool("PCH_WARN_INVALID")) { + useOptionList = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH")); + } + const std::string useOptVar = cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH"); - useOptionList = this->Makefile->GetSafeDefinition(useOptVar); + + useOptionList = cmStrCat(useOptionList, ";", + this->Makefile->GetSafeDefinition(useOptVar)); const std::string pchHeader = this->GetPchHeader(config, language); const std::string pchFile = this->GetPchFile(config, language); diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index ff4e312..4a9509b 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -36,12 +36,12 @@ bool cmGetCMakePropertyCommand(std::vector<std::string> const& args, status.GetMakefile().GetGlobalGenerator()->GetInstallComponents(); output = cmJoin(*components, ";"); } else { - const char* prop = nullptr; + cmProp prop = nullptr; if (!args[1].empty()) { prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]); } if (prop) { - output = prop; + output = *prop; } } diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index 2c3adde..1d8f0a9 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -241,8 +241,9 @@ bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name, // Get the property. cmake* cm = status.GetMakefile().GetCMakeInstance(); + cmProp p = cm->GetState()->GetGlobalProperty(propertyName); return StoreResult(infoType, status.GetMakefile(), variable, - cm->GetState()->GetGlobalProperty(propertyName)); + p ? p->c_str() : nullptr); } bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name, @@ -387,12 +388,13 @@ bool HandleCacheMode(cmExecutionStatus& status, const std::string& name, return false; } - const char* value = nullptr; + cmProp value = nullptr; if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) { value = status.GetMakefile().GetState()->GetCacheEntryProperty( name, propertyName); } - StoreResult(infoType, status.GetMakefile(), variable, value); + StoreResult(infoType, status.GetMakefile(), variable, + value ? value->c_str() : nullptr); return true; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 0e10734..6d08369 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -246,11 +246,10 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, cmSystemTools::ConvertToUnixSlashes(cnameString); cmSystemTools::ConvertToUnixSlashes(pathString); if (cnameString != pathString) { - const char* cvars = - this->GetCMakeInstance()->GetState()->GetGlobalProperty( - "__CMAKE_DELETE_CACHE_CHANGE_VARS_"); + cmProp cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty( + "__CMAKE_DELETE_CACHE_CHANGE_VARS_"); if (cvars) { - changeVars += cvars; + changeVars += *cvars; changeVars += ";"; } changeVars += langComp; @@ -2674,13 +2673,13 @@ void cmGlobalGenerator::AddGlobalTarget_Install( } } -const char* cmGlobalGenerator::GetPredefinedTargetsFolder() +std::string cmGlobalGenerator::GetPredefinedTargetsFolder() { - const char* prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty( + cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "PREDEFINED_TARGETS_FOLDER"); if (prop) { - return prop; + return *prop; } return "CMakePredefinedTargets"; @@ -2688,13 +2687,13 @@ const char* cmGlobalGenerator::GetPredefinedTargetsFolder() bool cmGlobalGenerator::UseFolderProperty() const { - const char* prop = + cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS"); // If this property is defined, let the setter turn this on or off... // if (prop) { - return cmIsOn(prop); + return cmIsOn(*prop); } // By default, this feature is OFF, since it is not supported in the diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 7dc4822..70e43b5 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -588,7 +588,7 @@ protected: cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const; - const char* GetPredefinedTargetsFolder(); + std::string GetPredefinedTargetsFolder(); private: using TargetMap = std::unordered_map<std::string, cmTarget*>; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 94483ca..062f8e9 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1011,7 +1011,7 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand( cm::make_unique<cmGeneratedFileStream>(buildFilePath); *this->CompileCommandsStream << "[\n"; } else { - *this->CompileCommandsStream << "," << std::endl; + *this->CompileCommandsStream << ",\n"; } std::string sourceFileName = sourceFile; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index e213023..582877f 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -159,7 +159,7 @@ void cmGlobalUnixMakefileGenerator3::Generate() this->WriteMainCMakefile(); if (this->CommandDatabase) { - *this->CommandDatabase << std::endl << "]"; + *this->CommandDatabase << "\n]"; this->CommandDatabase.reset(); } } @@ -174,21 +174,20 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand( "/compile_commands.json"; this->CommandDatabase = cm::make_unique<cmGeneratedFileStream>(commandDatabaseName); - *this->CommandDatabase << "[" << std::endl; + *this->CommandDatabase << "[\n"; } else { - *this->CommandDatabase << "," << std::endl; + *this->CommandDatabase << ",\n"; } - *this->CommandDatabase << "{" << std::endl + *this->CommandDatabase << "{\n" << R"( "directory": ")" << cmGlobalGenerator::EscapeJSON(workingDirectory) - << "\"," << std::endl + << "\",\n" << R"( "command": ")" << cmGlobalGenerator::EscapeJSON(compileCommand) - << "\"," << std::endl + << "\",\n" << R"( "file": ")" - << cmGlobalGenerator::EscapeJSON(sourceFile) << "\"" - << std::endl - << "}"; + << cmGlobalGenerator::EscapeJSON(sourceFile) + << "\"\n}"; } void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() @@ -674,10 +673,10 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( } bool targetMessages = true; - if (const char* tgtMsg = + if (cmProp tgtMsg = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "TARGET_MESSAGES")) { - targetMessages = cmIsOn(tgtMsg); + targetMessages = cmIsOn(*tgtMsg); } if (targetMessages) { diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index fab5bce..1c1aaad 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -3696,15 +3696,14 @@ bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation( bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const { - const char* epnValue = - this->GetCMakeInstance()->GetState()->GetGlobalProperty( - "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME"); + cmProp epnValue = this->GetCMakeInstance()->GetState()->GetGlobalProperty( + "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME"); if (!epnValue) { return mf->PlatformIsAppleEmbedded(); } - return cmIsOn(epnValue); + return cmIsOn(*epnValue); } bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index e908180..0a78af6 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2432,11 +2432,9 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) } for (std::string const& config : configsList) { - const std::string buildType = cmSystemTools::UpperCase(config); - // FIXME: Refactor collection of sources to not evaluate object libraries. std::vector<cmSourceFile*> sources; - target->GetSourceFiles(sources, buildType); + target->GetSourceFiles(sources, config); for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) { auto langSources = std::count_if( @@ -2605,15 +2603,13 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); } - const std::string buildType = cmSystemTools::UpperCase(config); - std::string filename_base = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", target->GetName(), ".dir/Unity/"); // FIXME: Refactor collection of sources to not evaluate object libraries. std::vector<cmSourceFile*> sources; - target->GetSourceFiles(sources, buildType); + target->GetSourceFiles(sources, config); auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE"); const size_t unityBatchSize = @@ -2965,8 +2961,8 @@ const char* cmLocalGenerator::GetFeature(const std::string& feature, } cmStateSnapshot snp = this->StateSnapshot; while (snp.IsValid()) { - if (const char* value = snp.GetDirectory().GetProperty(featureName)) { - return value; + if (cmProp value = snp.GetDirectory().GetProperty(featureName)) { + return value->c_str(); } snp = snp.GetBuildsystemDirectoryParent(); } diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 1568397..e62371d 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -207,9 +207,8 @@ void cmLocalNinjaGenerator::WriteBuildFileTop() void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); - os << "# Project: " << this->GetProjectName() << std::endl - << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ") - << std::endl; + os << "# Project: " << this->GetProjectName() << '\n' + << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ") << '\n'; cmGlobalNinjaGenerator::WriteDivider(os); } @@ -236,8 +235,7 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os) cmGlobalNinjaGenerator::WriteComment( os, "Minimal version of Ninja required by this file"); - os << "ninja_required_version = " << requiredVersion << std::endl - << std::endl; + os << "ninja_required_version = " << requiredVersion << "\n\n"; } void cmLocalNinjaGenerator::WriteNinjaConfigurationVariable( @@ -252,23 +250,22 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); - const char* jobpools = + cmProp jobpools = this->GetCMakeInstance()->GetState()->GetGlobalProperty("JOB_POOLS"); if (!jobpools) { - jobpools = this->GetMakefile()->GetDefinition("CMAKE_JOB_POOLS"); + jobpools = this->GetMakefile()->GetDef("CMAKE_JOB_POOLS"); } if (jobpools) { cmGlobalNinjaGenerator::WriteComment( os, "Pools defined by global property JOB_POOLS"); - std::vector<std::string> pools = cmExpandedList(jobpools); + std::vector<std::string> pools = cmExpandedList(*jobpools); for (std::string const& pool : pools) { const std::string::size_type eq = pool.find('='); unsigned int jobs; if (eq != std::string::npos && sscanf(pool.c_str() + eq, "=%u", &jobs) == 1) { - os << "pool " << pool.substr(0, eq) << std::endl; - os << " depth = " << jobs << std::endl; - os << std::endl; + os << "pool " << pool.substr(0, eq) << "\n depth = " << jobs + << "\n\n"; } else { cmSystemTools::Error("Invalid pool defined by property 'JOB_POOLS': " + pool); @@ -280,8 +277,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os) void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); - os << "# Include auxiliary files.\n" - << "\n"; + os << "# Include auxiliary files.\n\n"; cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator(); std::string const ninjaCommonFile = ng->NinjaOutputPath(cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE); @@ -294,8 +290,7 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os) void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); - os << "# Include auxiliary files.\n" - << "\n"; + os << "# Include auxiliary files.\n\n"; cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator(); std::string const ninjaRulesFile = ng->NinjaOutputPath(cmGlobalNinjaGenerator::NINJA_RULES_FILE); @@ -308,14 +303,14 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os) void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); - os << "# Write statements declared in CMakeLists.txt:" << std::endl + os << "# Write statements declared in CMakeLists.txt:\n" << "# " << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE") - << std::endl; + << '\n'; if (this->IsRootMakefile()) { - os << "# Which is the root file." << std::endl; + os << "# Which is the root file.\n"; } cmGlobalNinjaGenerator::WriteDivider(os); - os << std::endl; + os << '\n'; } void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target, diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 95c326a..593a6d9 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -725,6 +725,10 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop( ; /* clang-format on */ } else { + makefileStream << "# Command-line flag to silence nested $(MAKE).\n" + "$(VERBOSE)MAKESILENT = -s\n" + "\n"; + // Write special target to silence make output. This must be after // the default target in case VERBOSE is set (which changes the // name). The setting of CMAKE_VERBOSE_MAKEFILE to ON will cause a @@ -1322,10 +1326,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( int result; if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) { if (verbose) { - std::ostringstream msg; - msg << "Dependee \"" << tgtInfo << "\" is newer than depender \"" - << internalDependFile << "\"." << std::endl; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo, + "\" is newer than depender \"", + internalDependFile, "\".\n")); } needRescanDependInfo = true; } @@ -1342,10 +1345,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( if (!ftc->Compare(internalDependFile, dirInfoFile, &result) || result < 0) { if (verbose) { - std::ostringstream msg; - msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \"" - << internalDependFile << "\"." << std::endl; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile, + "\" is newer than depender \"", + internalDependFile, "\".\n")); } needRescanDirInfo = true; } @@ -1511,11 +1513,9 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) if (cmSystemTools::FileExists(dependee) && !cmSystemTools::FileExists(depender)) { if (verbose) { - std::ostringstream msg; - msg << "Deleting primary custom command output \"" << dependee - << "\" because another output \"" << depender - << "\" does not exist." << std::endl; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout(cmStrCat( + "Deleting primary custom command output \"", dependee, + "\" because another output \"", depender, "\" does not exist.\n")); } cmSystemTools::RemoveFile(dependee); } @@ -1919,7 +1919,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall( { // Call make on the given file. std::string cmd = cmStrCat( - "$(MAKE) -f ", + "$(MAKE) $(MAKESILENT) -f ", this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL), ' '); cmGlobalUnixMakefileGenerator3* gg = @@ -1962,7 +1962,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall( void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os) { os << "#======================================" - << "=======================================\n"; + "=======================================\n"; } void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os, @@ -1970,7 +1970,7 @@ void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os, { // Write the given string to the stream with escaping to get it back // into CMake through the lexical scanner. - os << "\""; + os << '"'; for (char c : s) { if (c == '\\') { os << "\\\\"; @@ -1980,7 +1980,7 @@ void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os, os << c; } } - os << "\""; + os << '"'; } std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath( diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 2487f4d..812f922 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4102,12 +4102,14 @@ const char* cmMakefile::GetProperty(const std::string& prop) const return output.c_str(); } - return this->StateSnapshot.GetDirectory().GetProperty(prop); + cmProp retVal = this->StateSnapshot.GetDirectory().GetProperty(prop); + return retVal ? retVal->c_str() : nullptr; } const char* cmMakefile::GetProperty(const std::string& prop, bool chain) const { - return this->StateSnapshot.GetDirectory().GetProperty(prop, chain); + cmProp retVal = this->StateSnapshot.GetDirectory().GetProperty(prop, chain); + return retVal ? retVal->c_str() : nullptr; } bool cmMakefile::GetPropertyAsBool(const std::string& prop) const diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index f0fc34f..4fb84ee 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -46,9 +46,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) this->LocalGenerator->GetGlobalGenerator()); cmake* cm = this->GlobalGenerator->GetCMakeInstance(); this->NoRuleMessages = false; - if (const char* ruleStatus = - cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) { - this->NoRuleMessages = cmIsOff(ruleStatus); + if (cmProp ruleStatus = cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) { + this->NoRuleMessages = cmIsOff(*ruleStatus); } MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this); } @@ -300,8 +299,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); depFileStream << "# Empty dependencies file for " << this->GeneratorTarget->GetName() << ".\n" - << "# This may be replaced when dependencies are built." - << std::endl; + << "# This may be replaced when dependencies are built.\n"; } // Open the flags file. This should be copy-if-different because the diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 1366ff0..d3daad8 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -305,7 +305,10 @@ class cmMakefile; 17, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0102, \ "mark_as_advanced() does nothing if a cache entry does not exist.", \ - 3, 17, 0, cmPolicies::WARN) + 3, 17, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0103, \ + "multiple export() with same FILE without APPEND is not allowed.", \ + 3, 18, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 7a6cb42..18b135d 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -164,10 +164,10 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( // Set FOLDER property in the target { - char const* folder = + cmProp folder = makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); if (folder != nullptr) { - target->SetProperty("FOLDER", folder); + target->SetProperty("FOLDER", *folder); } } } diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 629367d..dddba0a 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -339,15 +339,18 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Targets FOLDER { - const char* folder = + cmProp prop = this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); - if (folder == nullptr) { - folder = this->Makefile->GetState()->GetGlobalProperty( + if (prop == nullptr) { + prop = this->Makefile->GetState()->GetGlobalProperty( "AUTOGEN_TARGETS_FOLDER"); } + const char* folder; // Inherit FOLDER property from target (#13688) - if (folder == nullptr) { + if (prop == nullptr) { folder = this->GenTarget->GetProperty("FOLDER"); + } else { + folder = prop->c_str(); } if (folder != nullptr) { this->TargetsFolder = folder; @@ -1604,10 +1607,9 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP" }; for (std::string const& prop : props) { - const char* propName = - this->Makefile->GetState()->GetGlobalProperty(prop); - if ((propName != nullptr) && (*propName != '\0')) { - groupName = propName; + cmProp propName = this->Makefile->GetState()->GetGlobalProperty(prop); + if (propName && !propName->empty()) { + groupName = *propName; property = prop; break; } diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 83a7f7b..c5f3463 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -450,7 +450,7 @@ cmServerResponse cmServerProtocol1::ProcessCache( bool haveProperties = false; for (auto const& prop : state->GetCacheEntryPropertyList(key)) { haveProperties = true; - props[prop] = state->GetCacheEntryProperty(key, prop); + props[prop] = *state->GetCacheEntryProperty(key, prop); } if (haveProperties) { entry[kPROPERTIES_KEY] = props; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 6d95c7a..5a113dd 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -206,15 +206,14 @@ std::vector<std::string> cmState::GetCacheEntryPropertyList( return it.GetPropertyList(); } -const char* cmState::GetCacheEntryProperty(std::string const& key, - std::string const& propertyName) +cmProp cmState::GetCacheEntryProperty(std::string const& key, + std::string const& propertyName) { cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key); if (!it.PropertyExists(propertyName)) { return nullptr; } - cmProp retVal = it.GetProperty(propertyName); - return retVal ? retVal->c_str() : nullptr; + return it.GetProperty(propertyName); } bool cmState::GetCacheEntryPropertyAsBool(std::string const& key, @@ -587,7 +586,7 @@ void cmState::AppendGlobalProperty(const std::string& prop, this->GlobalProperties.AppendProperty(prop, value, asString); } -const char* cmState::GetGlobalProperty(const std::string& prop) +cmProp cmState::GetGlobalProperty(const std::string& prop) { if (prop == "CACHE_VARIABLES") { std::vector<std::string> cacheKeys = this->GetCacheEntryKeys(); @@ -611,41 +610,59 @@ const char* cmState::GetGlobalProperty(const std::string& prop) } #define STRING_LIST_ELEMENT(F) ";" #F if (prop == "CMAKE_C_KNOWN_FEATURES") { - return &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_C90_KNOWN_FEATURES") { - return &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_C99_KNOWN_FEATURES") { - return &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_C11_KNOWN_FEATURES") { - return &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_CXX_KNOWN_FEATURES") { - return &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_CXX98_KNOWN_FEATURES") { - return &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_CXX11_KNOWN_FEATURES") { - return &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_CXX14_KNOWN_FEATURES") { - return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } if (prop == "CMAKE_CUDA_KNOWN_FEATURES") { - return &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]; + static const std::string s_out( + &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]); + return &s_out; } #undef STRING_LIST_ELEMENT - cmProp retVal = this->GlobalProperties.GetPropertyValue(prop); - return retVal ? retVal->c_str() : nullptr; + return this->GlobalProperties.GetPropertyValue(prop); } bool cmState::GetGlobalPropertyAsBool(const std::string& prop) { - return cmIsOn(this->GetGlobalProperty(prop)); + cmProp p = this->GetGlobalProperty(prop); + return p && cmIsOn(*p); } void cmState::SetSourceDirectory(std::string const& sourceDirectory) diff --git a/Source/cmState.h b/Source/cmState.h index 89400d6..e3fbfdc 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -105,8 +105,8 @@ public: void SetCacheEntryBoolProperty(std::string const& key, std::string const& propertyName, bool value); std::vector<std::string> GetCacheEntryPropertyList(std::string const& key); - const char* GetCacheEntryProperty(std::string const& key, - std::string const& propertyName); + cmProp GetCacheEntryProperty(std::string const& key, + std::string const& propertyName); bool GetCacheEntryPropertyAsBool(std::string const& key, std::string const& propertyName); void AppendCacheEntryProperty(std::string const& key, @@ -174,7 +174,7 @@ public: void SetGlobalProperty(const std::string& prop, const char* value); void AppendGlobalProperty(const std::string& prop, const std::string& value, bool asString = false); - const char* GetGlobalProperty(const std::string& prop); + cmProp GetGlobalProperty(const std::string& prop); bool GetGlobalPropertyAsBool(const std::string& prop); std::string const& GetSourceDirectory() const; diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index e7de3c7..a4fe663 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -548,32 +548,31 @@ void cmStateDirectory::AppendProperty(const std::string& prop, this->DirectoryState->Properties.AppendProperty(prop, value, asString); } -const char* cmStateDirectory::GetProperty(const std::string& prop) const +cmProp cmStateDirectory::GetProperty(const std::string& prop) const { const bool chain = this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY); return this->GetProperty(prop, chain); } -const char* cmStateDirectory::GetProperty(const std::string& prop, - bool chain) const +cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const { static std::string output; output.clear(); if (prop == "PARENT_DIRECTORY") { cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent(); if (parent.IsValid()) { - return parent.GetDirectory().GetCurrentSource().c_str(); + return &parent.GetDirectory().GetCurrentSource(); } - return ""; + return &output; } if (prop == kBINARY_DIR) { output = this->GetCurrentBinary(); - return output.c_str(); + return &output; } if (prop == kSOURCE_DIR) { output = this->GetCurrentSource(); - return output.c_str(); + return &output; } if (prop == kSUBDIRECTORIES) { std::vector<std::string> child_dirs; @@ -584,11 +583,11 @@ const char* cmStateDirectory::GetProperty(const std::string& prop, child_dirs.push_back(ci.GetDirectory().GetCurrentSource()); } output = cmJoin(child_dirs, ";"); - return output.c_str(); + return &output; } if (prop == kBUILDSYSTEM_TARGETS) { output = cmJoin(this->DirectoryState->NormalTargetNames, ";"); - return output.c_str(); + return &output; } if (prop == "LISTFILE_STACK") { @@ -600,38 +599,38 @@ const char* cmStateDirectory::GetProperty(const std::string& prop, } std::reverse(listFiles.begin(), listFiles.end()); output = cmJoin(listFiles, ";"); - return output.c_str(); + return &output; } if (prop == "CACHE_VARIABLES") { output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";"); - return output.c_str(); + return &output; } if (prop == "VARIABLES") { std::vector<std::string> res = this->Snapshot_.ClosureKeys(); cm::append(res, this->Snapshot_.State->GetCacheEntryKeys()); std::sort(res.begin(), res.end()); output = cmJoin(res, ";"); - return output.c_str(); + return &output; } if (prop == "INCLUDE_DIRECTORIES") { output = cmJoin(this->GetIncludeDirectoriesEntries(), ";"); - return output.c_str(); + return &output; } if (prop == "COMPILE_OPTIONS") { output = cmJoin(this->GetCompileOptionsEntries(), ";"); - return output.c_str(); + return &output; } if (prop == "COMPILE_DEFINITIONS") { output = cmJoin(this->GetCompileDefinitionsEntries(), ";"); - return output.c_str(); + return &output; } if (prop == "LINK_OPTIONS") { output = cmJoin(this->GetLinkOptionsEntries(), ";"); - return output.c_str(); + return &output; } if (prop == "LINK_DIRECTORIES") { output = cmJoin(this->GetLinkDirectoriesEntries(), ";"); - return output.c_str(); + return &output; } cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop); @@ -644,12 +643,13 @@ const char* cmStateDirectory::GetProperty(const std::string& prop, return this->Snapshot_.State->GetGlobalProperty(prop); } - return retVal ? retVal->c_str() : nullptr; + return retVal; } bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const { - return cmIsOn(this->GetProperty(prop)); + cmProp p = this->GetProperty(prop); + return p && cmIsOn(*p); } std::vector<std::string> cmStateDirectory::GetPropertyKeys() const diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index 53a2d54..8144160 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -16,6 +16,8 @@ #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" +using cmProp = const std::string*; + class cmStateDirectory { cmStateDirectory( @@ -86,8 +88,8 @@ public: cmListFileBacktrace const& lfbt); void AppendProperty(const std::string& prop, const std::string& value, bool asString, cmListFileBacktrace const& lfbt); - const char* GetProperty(const std::string& prop) const; - const char* GetProperty(const std::string& prop, bool chain) const; + cmProp GetProperty(const std::string& prop) const; + cmProp GetProperty(const std::string& prop, bool chain) const; bool GetPropertyAsBool(const std::string& prop) const; std::vector<std::string> GetPropertyKeys() const; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 3838356..93c168a 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -368,6 +368,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("DISABLE_PRECOMPILE_HEADERS"); initProp("UNITY_BUILD"); initPropValue("UNITY_BUILD_BATCH_SIZE", "8"); + initPropValue("PCH_WARN_INVALID", "ON"); #ifdef __APPLE__ if (this->GetGlobalGenerator()->IsXcode()) { initProp("XCODE_SCHEME_ADDRESS_SANITIZER"); @@ -1778,8 +1779,11 @@ const char* cmTarget::GetProperty(const std::string& prop) const const bool chain = impl->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TARGET); if (chain) { - return impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty( + retVal = impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty( prop, chain); + if (retVal) { + return retVal->c_str(); + } } return nullptr; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 1273308..abc8b6f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1745,20 +1745,65 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1, } } +void cmVisualStudio10TargetGenerator::ParseSettingsProperty( + const char* settingsPropertyValue, ConfigToSettings& toolSettings) +{ + if (settingsPropertyValue) { + cmGeneratorExpression ge; + + std::unique_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(settingsPropertyValue); + + for (const std::string& config : this->Configurations) { + std::string evaluated = cge->Evaluate(this->LocalGenerator, config); + + std::vector<std::string> settings = cmExpandedList(evaluated); + for (const std::string& setting : settings) { + const std::string::size_type assignment = setting.find('='); + if (assignment != std::string::npos) { + const std::string propName = setting.substr(0, assignment); + const std::string propValue = setting.substr(assignment + 1); + + if (!propValue.empty()) { + toolSettings[config][propName] = propValue; + } + } + } + } + } +} + +bool cmVisualStudio10TargetGenerator::PropertyIsSameInAllConfigs( + const ConfigToSettings& toolSettings, const std::string& propName) +{ + std::string firstPropValue = ""; + for (const auto& configToSettings : toolSettings) { + const std::unordered_map<std::string, std::string>& settings = + configToSettings.second; + + if (firstPropValue.empty()) { + if (settings.find(propName) != settings.end()) { + firstPropValue = settings.find(propName)->second; + } + } + + if (settings.find(propName) == settings.end()) { + return false; + } + + if (settings.find(propName)->second != firstPropValue) { + return false; + } + } + + return true; +} + void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, cmSourceFile const* sf) { bool toolHasSettings = false; const char* tool = "None"; - std::string shaderType; - std::string shaderEntryPoint; - std::string shaderModel; - std::string shaderAdditionalFlags; - std::string shaderDisableOptimizations; - std::string shaderEnableDebug; - std::string shaderObjectFileName; - std::string outputHeaderFile; - std::string variableName; std::string settingsGenerator; std::string settingsLastGenOutput; std::string sourceLink; @@ -1766,6 +1811,11 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, std::string copyToOutDir; std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); + ConfigToSettings toolSettings; + for (const auto& config : this->Configurations) { + toolSettings[config]; + } + if (this->ProjectType == csproj && !this->InSourceBuild) { toolHasSettings = true; } @@ -1773,47 +1823,72 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, tool = "FXCompile"; // Figure out the type of shader compiler to use. if (const char* st = sf->GetProperty("VS_SHADER_TYPE")) { - shaderType = st; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["ShaderType"] = st; + } } // Figure out which entry point to use if any if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) { - shaderEntryPoint = se; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["EntryPointName"] = se; + } } // Figure out which shader model to use if any if (const char* sm = sf->GetProperty("VS_SHADER_MODEL")) { - shaderModel = sm; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["ShaderModel"] = sm; + } } // Figure out which output header file to use if any if (const char* ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) { - outputHeaderFile = ohf; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["HeaderFileOutput"] = ohf; + } } // Figure out which variable name to use if any if (const char* vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) { - variableName = vn; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["VariableName"] = vn; + } } // Figure out if there's any additional flags to use if (const char* saf = sf->GetProperty("VS_SHADER_FLAGS")) { - shaderAdditionalFlags = saf; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["AdditionalOptions"] = saf; + } } // Figure out if debug information should be generated if (const char* sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) { - shaderEnableDebug = sed; - toolHasSettings = true; + cmGeneratorExpression ge; + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(sed); + + for (const std::string& config : this->Configurations) { + std::string evaluated = cge->Evaluate(this->LocalGenerator, config); + + if (!evaluated.empty()) { + toolSettings[config]["EnableDebuggingInformation"] = + cmIsOn(evaluated) ? "true" : "false"; + } + } } // Figure out if optimizations should be disabled if (const char* sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) { - shaderDisableOptimizations = sdo; - toolHasSettings = true; + cmGeneratorExpression ge; + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(sdo); + + for (const std::string& config : this->Configurations) { + std::string evaluated = cge->Evaluate(this->LocalGenerator, config); + + if (!evaluated.empty()) { + toolSettings[config]["DisableOptimizations"] = + cmIsOn(evaluated) ? "true" : "false"; + } + } } if (const char* sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) { - shaderObjectFileName = sofn; - toolHasSettings = true; + for (const std::string& config : this->Configurations) { + toolSettings[config]["ObjectFileOutput"] = sofn; + } } } else if (ext == "jpg" || ext == "png") { tool = "Image"; @@ -1883,11 +1958,55 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } + if (ParsedToolTargetSettings.find(tool) == ParsedToolTargetSettings.end()) { + const char* toolTargetProperty = + this->GeneratorTarget->Target->GetProperty("VS_SOURCE_SETTINGS_" + + std::string(tool)); + ConfigToSettings toolTargetSettings; + ParseSettingsProperty(toolTargetProperty, toolTargetSettings); + + ParsedToolTargetSettings[tool] = toolTargetSettings; + } + + for (const auto& configToSetting : ParsedToolTargetSettings[tool]) { + for (const auto& setting : configToSetting.second) { + toolSettings[configToSetting.first][setting.first] = setting.second; + } + } + + ParseSettingsProperty(sf->GetProperty("VS_SETTINGS"), toolSettings); + + if (!toolSettings.empty()) { + toolHasSettings = true; + } + Elem e2(e1, tool); this->WriteSource(e2, sf); if (toolHasSettings) { e2.SetHasElements(); + std::vector<std::string> writtenSettings; + for (const auto& configSettings : toolSettings) { + for (const auto& setting : configSettings.second) { + + if (std::find(writtenSettings.begin(), writtenSettings.end(), + setting.first) != writtenSettings.end()) { + continue; + } + + if (PropertyIsSameInAllConfigs(toolSettings, setting.first)) { + e2.Element(setting.first, setting.second); + writtenSettings.push_back(setting.first); + } else { + e2.WritePlatformConfigTag(setting.first, + "'$(Configuration)|$(Platform)'=='" + + configSettings.first + "|" + + this->Platform + "'", + setting.second); + } + } + } + if (!deployContent.empty()) { cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = @@ -1913,73 +2032,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } } - if (!shaderType.empty()) { - e2.Element("ShaderType", shaderType); - } - if (!shaderEntryPoint.empty()) { - e2.Element("EntryPointName", shaderEntryPoint); - } - if (!shaderModel.empty()) { - e2.Element("ShaderModel", shaderModel); - } - if (!outputHeaderFile.empty()) { - for (size_t i = 0; i != this->Configurations.size(); ++i) { - e2.WritePlatformConfigTag("HeaderFileOutput", - "'$(Configuration)|$(Platform)'=='" + - this->Configurations[i] + "|" + - this->Platform + "'", - outputHeaderFile); - } - } - if (!variableName.empty()) { - for (size_t i = 0; i != this->Configurations.size(); ++i) { - e2.WritePlatformConfigTag("VariableName", - "'$(Configuration)|$(Platform)'=='" + - this->Configurations[i] + "|" + - this->Platform + "'", - variableName); - } - } - if (!shaderEnableDebug.empty()) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(shaderEnableDebug); - for (size_t i = 0; i != this->Configurations.size(); ++i) { - const std::string& enableDebug = - cge->Evaluate(this->LocalGenerator, this->Configurations[i]); - if (!enableDebug.empty()) { - e2.WritePlatformConfigTag("EnableDebuggingInformation", - "'$(Configuration)|$(Platform)'=='" + - this->Configurations[i] + "|" + - this->Platform + "'", - cmIsOn(enableDebug) ? "true" : "false"); - } - } - } - if (!shaderDisableOptimizations.empty()) { - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(shaderDisableOptimizations); - - for (size_t i = 0; i != this->Configurations.size(); ++i) { - const std::string& disableOptimizations = - cge->Evaluate(this->LocalGenerator, this->Configurations[i]); - if (!disableOptimizations.empty()) { - e2.WritePlatformConfigTag( - "DisableOptimizations", - "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] + - "|" + this->Platform + "'", - (cmIsOn(disableOptimizations) ? "true" : "false")); - } - } - } - if (!shaderObjectFileName.empty()) { - e2.Element("ObjectFileOutput", shaderObjectFileName); - } - if (!shaderAdditionalFlags.empty()) { - e2.Element("AdditionalOptions", shaderAdditionalFlags); - } if (!settingsGenerator.empty()) { e2.Element("Generator", settingsGenerator); } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 25b3d02..e588de8 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -10,6 +10,7 @@ #include <memory> #include <set> #include <string> +#include <unordered_map> #include <vector> class cmComputeLinkInformation; @@ -234,6 +235,15 @@ private: using ToolSourceMap = std::map<std::string, ToolSources>; ToolSourceMap Tools; + + using ConfigToSettings = + std::unordered_map<std::string, + std::unordered_map<std::string, std::string>>; + std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings; + bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings, + const std::string& propName); + void ParseSettingsProperty(const char* settingsPropertyValue, + ConfigToSettings& toolSettings); std::string GetCMakeFilePath(const char* name) const; }; diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index 34e21b2..666ba87 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -72,7 +72,7 @@ bool cmWriteFileCommand(std::vector<std::string> const& args, status.SetError(error); return false; } - file << message << std::endl; + file << message << '\n'; file.close(); if (mode && !writable) { cmSystemTools::SetPermissions(fileName.c_str(), mode); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 59e7a37..2ec893f 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1410,9 +1410,9 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) cmProp existingValue = this->State->GetCacheEntryValue(save.key); if (existingValue) { save.type = this->State->GetCacheEntryType(save.key); - if (const char* help = + if (cmProp help = this->State->GetCacheEntryProperty(save.key, "HELPSTRING")) { - save.help = help; + save.help = *help; } } saved.push_back(std::move(save)); @@ -1511,10 +1511,10 @@ int cmake::Configure() this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(*value)); int ret = this->ActualConfigure(); - const char* delCacheVars = + cmProp delCacheVars = this->State->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_"); - if (delCacheVars && delCacheVars[0] != 0) { - return this->HandleDeleteCacheVariables(delCacheVars); + if (delCacheVars && !delCacheVars->empty()) { + return this->HandleDeleteCacheVariables(*delCacheVars); } return ret; } @@ -2430,7 +2430,7 @@ void cmake::AppendProperty(const std::string& prop, const std::string& value, this->State->AppendGlobalProperty(prop, value, asString); } -const char* cmake::GetProperty(const std::string& prop) +cmProp cmake::GetProperty(const std::string& prop) { return this->State->GetGlobalProperty(prop); } @@ -2671,10 +2671,10 @@ void cmake::IssueMessage(MessageType t, std::string const& text, std::vector<std::string> cmake::GetDebugConfigs() { std::vector<std::string> configs; - if (const char* config_list = + if (cmProp config_list = this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) { // Expand the specified list and convert to upper-case. - cmExpandList(config_list, configs); + cmExpandList(*config_list, configs); std::transform(configs.begin(), configs.end(), configs.begin(), cmSystemTools::UpperCase); } diff --git a/Source/cmake.h b/Source/cmake.h index 0f6440f..cfcd264 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -366,7 +366,7 @@ public: void SetProperty(const std::string& prop, const char* value); void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); - const char* GetProperty(const std::string& prop); + cmProp GetProperty(const std::string& prop); bool GetPropertyAsBool(const std::string& prop); //! Get or create an cmInstalledFile instance and return a pointer to it diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 0e99117..84d0538 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -292,13 +292,13 @@ int do_cmake(int ac, char const* const* av) cmStateEnums::CacheEntryType t = cm.GetState()->GetCacheEntryType(k); if (t != cmStateEnums::INTERNAL && t != cmStateEnums::STATIC && t != cmStateEnums::UNINITIALIZED) { - const char* advancedProp = + cmProp advancedProp = cm.GetState()->GetCacheEntryProperty(k, "ADVANCED"); if (list_all_cached || !advancedProp) { if (list_help) { - std::cout << "// " - << cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING") - << std::endl; + cmProp help = + cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING"); + std::cout << "// " << (help ? *help : "") << std::endl; } std::cout << k << ":" << cmState::CacheEntryTypeToString(t) << "=" << cm.GetState()->GetSafeCacheEntryValue(k) << std::endl; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index a395089..18a2108 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1698,6 +1698,11 @@ int cmcmd::RunPreprocessor(const std::vector<std::string>& command, } auto status = process.GetStatus(); if (!status[0] || status[0]->ExitStatus != 0) { + auto errorStream = process.ErrorStream(); + if (errorStream) { + std::cerr << errorStream->rdbuf(); + } + return 1; } @@ -1766,6 +1771,10 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args) } auto status = process.GetStatus(); if (!status[0] || status[0]->ExitStatus != 0) { + auto errorStream = process.ErrorStream(); + if (errorStream) { + std::cerr << errorStream->rdbuf(); + } return 1; } diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 101e10c..2a4af3e 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -665,7 +665,7 @@ endif() add_RunCMake_test("CTestCommandExpandLists") -add_RunCMake_test(PrecompileHeaders) +add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) add_RunCMake_test("UnityBuild") add_RunCMake_test(cmake_command) diff --git a/Tests/RunCMake/CTestTimeout/Basic-stdout.txt b/Tests/RunCMake/CTestTimeout/Basic-stdout.txt index 30ed178..db59dbf 100644 --- a/Tests/RunCMake/CTestTimeout/Basic-stdout.txt +++ b/Tests/RunCMake/CTestTimeout/Basic-stdout.txt @@ -1,6 +1,6 @@ Test project [^ ]*/Tests/RunCMake/CTestTimeout/Basic-build Start 1: TestTimeout -1/1 Test #1: TestTimeout ......................\*\*\*Timeout +[0-9.]+ sec +1/1 Test #1: TestTimeout ......................\*\*\*Timeout +[1-9][0-9.]* sec + 0% tests passed, 1 tests failed out of 1 diff --git a/Tests/RunCMake/CTestTimeout/Fork-stdout.txt b/Tests/RunCMake/CTestTimeout/Fork-stdout.txt index 284e4b1..2938d8e 100644 --- a/Tests/RunCMake/CTestTimeout/Fork-stdout.txt +++ b/Tests/RunCMake/CTestTimeout/Fork-stdout.txt @@ -1,6 +1,6 @@ Test project [^ ]*/Tests/RunCMake/CTestTimeout/Fork-build Start 1: TestTimeout -1/1 Test #1: TestTimeout ......................\*\*\*Timeout +[0-9.]+ sec +1/1 Test #1: TestTimeout ......................\*\*\*Timeout +[1-9][0-9.]* sec + 0% tests passed, 1 tests failed out of 1 diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 41f13db..f95a6ee 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -673,12 +673,11 @@ function(run_llvm_rc) set(RunCMake_TEST_NO_CLEAN 1) file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") - run_cmake_command(llvm_rc_no_args ${CMAKE_COMMAND} -E cmake_llvm_rc) run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E echo "This is a test") run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test") - run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E false -- ${CMAKE_COMMAND} -E echo "This is a test") - run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E false ) + run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake -- ${CMAKE_COMMAND} -E echo "This is a test") + run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -P FailedProgram.cmake ) if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp) message(SEND_ERROR "${test} - FAILED:\n" "test.tmp was not deleted") diff --git a/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt new file mode 100644 index 0000000..765b708 --- /dev/null +++ b/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt @@ -0,0 +1 @@ +CMake Error diff --git a/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt new file mode 100644 index 0000000..765b708 --- /dev/null +++ b/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt @@ -0,0 +1 @@ +CMake Error diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt new file mode 100644 index 0000000..1f5d1a5 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt @@ -0,0 +1,5 @@ +Test project .*GoogleTest-discovery-multi-config +[ \t]*Test #[0-9]+: configuration\.case_release \(Disabled\) +[ \t]*Test #[0-9]+: configuration\.case_debug ++ +Total Tests: 2 diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt new file mode 100644 index 0000000..4f91664 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt @@ -0,0 +1,5 @@ +Test project .*GoogleTest-discovery-multi-config +[ \t]*Test #[0-9]+: configuration\.case_release +[ \t]*Test #[0-9]+: configuration\.case_debug \(Disabled\) ++ +Total Tests: 2 diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-test-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt index d197c91..d197c91 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-test-result.txt +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-build-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt index 3a6572c..3a6572c 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-build-stdout.txt +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-build-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt index d197c91..d197c91 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-build-result.txt +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt index f6be939..f6be939 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-test-stderr.txt +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt index d4c4e7b..d9de3f8 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-test-stdout.txt +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt @@ -1,4 +1,4 @@ -Test project .*GoogleTest-build +Test project .*GoogleTest-discovery-timeout [ \t]*Start [0-9]+: discovery_timeout_test_NOT_BUILT Could not find executable discovery_timeout_test_NOT_BUILT Looked in the following places: diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt new file mode 100644 index 0000000..75afe4a --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at .*GoogleTestAddTests.cmake:[0-9]+ \(message\): +[ \t]*Error running test executable. ++ +[ \t]*Path: '.*discovery_timeout_test(\.exe)?' +[ \t]*Result: Process terminated due to timeout +[ \t]*Output: +[ \t]*timeout. +[ \t]*case diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt new file mode 100644 index 0000000..d65061f --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt @@ -0,0 +1 @@ +Test project .*GoogleTest-discovery-timeout diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake index 31808c6..4bc6b9d 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake +++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake @@ -49,11 +49,3 @@ gtest_discover_tests( DISCOVERY_TIMEOUT 20 PROPERTIES TIMEOUT 2 ) - -add_executable(discovery_timeout_test timeout_test.cpp) -target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10) -gtest_discover_tests( - discovery_timeout_test - TEST_PREFIX discovery_ - DISCOVERY_TIMEOUT 2 -) diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake new file mode 100644 index 0000000..1919dc1 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake @@ -0,0 +1,14 @@ +project(test_include_dirs) +include(CTest) +include(GoogleTest) + +enable_testing() + +add_executable(configuration_gtest configuration_gtest.cpp) +target_compile_definitions(configuration_gtest PRIVATE $<$<CONFIG:Debug>:DEBUG=1>) + +gtest_discover_tests( + configuration_gtest + PROPERTIES LABELS CONFIG + DISCOVERY_MODE PRE_TEST +) diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake new file mode 100644 index 0000000..7398faf --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake @@ -0,0 +1,14 @@ +project(test_include_dirs) +include(CTest) +include(GoogleTest) + +enable_testing() + +add_executable(discovery_timeout_test timeout_test.cpp) +target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10) +gtest_discover_tests( + discovery_timeout_test + TEST_PREFIX discovery_ + DISCOVERY_TIMEOUT 2 + DISCOVERY_MODE ${DISCOVERY_MODE} +) diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake index 8070512..6b9d458 100644 --- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake +++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake @@ -1,6 +1,6 @@ include(RunCMake) -function(run_GoogleTest) +function(run_GoogleTest DISCOVERY_MODE) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-build) set(RunCMake_TEST_NO_CLEAN 1) @@ -10,7 +10,7 @@ function(run_GoogleTest) file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") - run_cmake(GoogleTest) + run_cmake_with_options(GoogleTest -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE}) run_cmake_command(GoogleTest-build ${CMAKE_COMMAND} @@ -26,15 +26,6 @@ function(run_GoogleTest) --target property_timeout_test ) - set(RunCMake_TEST_OUTPUT_MERGE 1) - run_cmake_command(GoogleTest-discovery-timeout-build - ${CMAKE_COMMAND} - --build . - --config Debug - --target discovery_timeout_test - ) - set(RunCMake_TEST_OUTPUT_MERGE 0) - run_cmake_command(GoogleTest-test1 ${CMAKE_CTEST_COMMAND} -C Debug @@ -69,16 +60,9 @@ function(run_GoogleTest) -R property_timeout\\.case_with_discovery --no-label-summary ) - - run_cmake_command(GoogleTest-discovery-timeout-test - ${CMAKE_CTEST_COMMAND} - -C Debug - -R discovery_timeout_test - --no-label-summary - ) endfunction() -function(run_GoogleTestXML) +function(run_GoogleTestXML DISCOVERY_MODE) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTestXML-build) set(RunCMake_TEST_NO_CLEAN 1) @@ -88,7 +72,7 @@ function(run_GoogleTestXML) file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") - run_cmake(GoogleTestXML) + run_cmake_with_options(GoogleTestXML -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE}) run_cmake_command(GoogleTestXML-discovery ${CMAKE_COMMAND} @@ -105,5 +89,80 @@ function(run_GoogleTestXML) ) endfunction() -run_GoogleTest() -run_GoogleTestXML() +function(run_GoogleTest_discovery_timeout DISCOVERY_MODE) + # Use a single build tree for a few tests without cleaning. + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-timeout) + set(RunCMake_TEST_NO_CLEAN 1) + if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) + endif() + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake_with_options(GoogleTestDiscoveryTimeout -DDISCOVERY_MODE=${DISCOVERY_MODE}) + + set(RunCMake_TEST_OUTPUT_MERGE 1) + run_cmake_command(GoogleTest-discovery-${DISCOVERY_MODE}-timeout-build + ${CMAKE_COMMAND} + --build . + --config Debug + --target discovery_timeout_test + ) + set(RunCMake_TEST_OUTPUT_MERGE 0) + + run_cmake_command(GoogleTest-discovery-${DISCOVERY_MODE}-timeout-test + ${CMAKE_CTEST_COMMAND} + -C Debug + -R discovery_timeout_test + --no-label-sumary + ) +endfunction() + +function(run_GoogleTest_discovery_multi_config) + # Use a single build tree for a few tests without cleaning. + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-multi-config) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(GoogleTestDiscoveryMultiConfig) + + run_cmake_command(GoogleTest-build-release + ${CMAKE_COMMAND} + --build . + --config Release + --target configuration_gtest + ) + run_cmake_command(GoogleTest-build-debug + ${CMAKE_COMMAND} + --build . + --config Debug + --target configuration_gtest + ) + run_cmake_command(GoogleTest-configuration-release + ${CMAKE_CTEST_COMMAND} + -C Release + -L CONFIG + -N + ) + run_cmake_command(GoogleTest-configuration-debug + ${CMAKE_CTEST_COMMAND} + -C Debug + -L CONFIG + -N + ) + +endfunction() + +foreach(DISCOVERY_MODE POST_BUILD PRE_TEST) + message("Testing ${DISCOVERY_MODE} discovery mode via CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE global override...") + run_GoogleTest(${DISCOVERY_MODE}) + run_GoogleTestXML(${DISCOVERY_MODE}) + message("Testing ${DISCOVERY_MODE} discovery mode via DISCOVERY_MODE option...") + run_GoogleTest_discovery_timeout(${DISCOVERY_MODE}) +endforeach() + +if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + message("Testing PRE_TEST discovery multi configuration...") + run_GoogleTest_discovery_multi_config() +endif() diff --git a/Tests/RunCMake/GoogleTest/configuration_gtest.cpp b/Tests/RunCMake/GoogleTest/configuration_gtest.cpp new file mode 100644 index 0000000..3cbb134 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/configuration_gtest.cpp @@ -0,0 +1,23 @@ +#include <iostream> +#include <string> + +int main(int argc, char** argv) +{ + // Note: GoogleTest.cmake doesn't actually depend on Google Test as such; + // it only requires that we produces output in the expected format when + // invoked with --gtest_list_tests. Thus, we fake that here. This allows us + // to test the module without actually needing Google Test. + if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") { + std::cout << "configuration." << std::endl; +#ifdef DEBUG + std::cout << " DISABLED_case_release" << std::endl; + std::cout << " case_debug" << std::endl; +#else + std::cout << " case_release" << std::endl; + std::cout << " DISABLED_case_debug" << std::endl; +#endif + return 0; + } + + return 1; +} diff --git a/Tests/RunCMake/GoogleTest/timeout_test.cpp b/Tests/RunCMake/GoogleTest/timeout_test.cpp index b8ad055..5506269 100644 --- a/Tests/RunCMake/GoogleTest/timeout_test.cpp +++ b/Tests/RunCMake/GoogleTest/timeout_test.cpp @@ -4,9 +4,10 @@ # include <unistd.h> #endif -#include <iostream> #include <string> +#include <stdio.h> + void sleepFor(unsigned seconds) { #if defined(_WIN32) @@ -23,8 +24,8 @@ int main(int argc, char** argv) // invoked with --gtest_list_tests. Thus, we fake that here. This allows us // to test the module without actually needing Google Test. if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") { - std::cout << "timeout." << std::endl; - std::cout << " case" << std::endl; + printf("timeout.\n case\n"); + fflush(stdout); #ifdef discoverySleepSec sleepFor(discoverySleepSec); #endif diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake new file mode 100644 index 0000000..3e7fb30 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake @@ -0,0 +1,22 @@ +if (NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Intel" OR + (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND CMAKE_HOST_WIN32)) + return() +endif() + +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json empty_dir_commands + REGEX "command.*-Winvalid-pch.*empty.dir/cmake_pch.h") +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json foo_dir_commands + REGEX "command.*-Winvalid-pch.*foo.dir/cmake_pch.h") + +list(LENGTH empty_dir_commands empty_dir_commands_size) +list(LENGTH foo_dir_commands foo_dir_commands_size) + +if (empty_dir_commands_size EQUAL 0) + set(RunCMake_TEST_FAILED "empty target should have -Winvalid-pch compile option present") + return() +endif() + +if (foo_dir_commands_size GREATER 0) + set(RunCMake_TEST_FAILED "foo target should not have -Winvalid-pch compile option present") + return() +endif() diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake new file mode 100644 index 0000000..4525664 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake @@ -0,0 +1,16 @@ +enable_language(C) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) + +add_library(foo foo.c) +target_precompile_headers(foo PUBLIC + <stdio.h> + <string.h> +) +set_target_properties(foo PROPERTIES PCH_WARN_INVALID OFF) diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index f587c7d..3f684fc 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -21,3 +21,6 @@ run_test(PchReuseFrom) run_test(PchReuseFromPrefixed) run_test(PchReuseFromSubdir) run_cmake(PchMultilanguage) +if(RunCMake_GENERATOR MATCHES "Make|Ninja") + run_cmake(PchWarnInvalid) +endif() diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index 3ca7cc0..5ccca01 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -31,6 +31,8 @@ run_cmake(VsDpiAwareBadParam) run_cmake(VsPrecompileHeaders) run_cmake(VsPrecompileHeadersReuseFromCompilePDBName) run_cmake(VsDeployEnabled) +run_cmake(VsSettings) +run_cmake(VsSourceSettingsTool) run_cmake(VsWinRTByDefault) diff --git a/Tests/RunCMake/VS10Project/VsSettings-check.cmake b/Tests/RunCMake/VS10Project/VsSettings-check.cmake new file mode 100644 index 0000000..0f8b26c --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsSettings-check.cmake @@ -0,0 +1,23 @@ +macro(ensure_props_set projectFile) + if(NOT EXISTS "${projectFile}") + set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.") + return() + endif() + + set(SettingFound FALSE) + + file(STRINGS "${projectFile}" lines) + foreach(line IN LISTS lines) + if(line MATCHES "<SourceProperty1.*Debug.*>SourceProperty1Value</SourceProperty1>") + message("SourceProperty1 setting found") + set(SettingFound TRUE) + endif() + endforeach() + + if (NOT SettingFound) + set(RunCMake_TEST_FAILED "SourceProperty1 setting was not found") + return() + endif() +endmacro() + +ensure_props_set("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj") diff --git a/Tests/RunCMake/VS10Project/VsSettings.cmake b/Tests/RunCMake/VS10Project/VsSettings.cmake new file mode 100644 index 0000000..a4b321b --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsSettings.cmake @@ -0,0 +1,5 @@ +enable_language(CXX) + +add_library(foo foo.cpp shader.hlsl) +set_property(SOURCE shader.hlsl PROPERTY VS_SETTINGS + "$<$<CONFIG:DEBUG>:SourceProperty1=SourceProperty1Value>") diff --git a/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake b/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake new file mode 100644 index 0000000..29a89c3 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake @@ -0,0 +1,34 @@ +macro(ensure_props_set projectFile) + if(NOT EXISTS "${projectFile}") + set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.") + return() + endif() + + set(FirstSettingFound FALSE) + set(SecondSettingFound FALSE) + + file(STRINGS "${projectFile}" lines) + foreach(line IN LISTS lines) + if(line MATCHES "<TargetProperty1.*Debug.*>TargetProperty1ValueDebug</TargetProperty1>") + if (FirstSettingFound) + message("TargetProperty1 setting found twice") + set(SecondSettingFound TRUE) + else() + message("TargetProperty1 setting found once") + set(FirstSettingFound TRUE) + endif() + endif() + endforeach() + + if (NOT FirstSettingFound) + set(RunCMake_TEST_FAILED "TargetProperty1 setting not found at all") + return() + endif() + + if (NOT SecondSettingFound) + set(RunCMake_TEST_FAILED "TargetProperty1 setting found once when it should be found twice") + return() + endif() +endmacro() + +ensure_props_set("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj") diff --git a/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake b/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake new file mode 100644 index 0000000..498962f --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake @@ -0,0 +1,5 @@ +enable_language(CXX) + +add_library(foo foo.cpp shader.hlsl shader2.hlsl) +set_property(TARGET foo PROPERTY VS_SOURCE_SETTINGS_FXCompile + "$<$<CONFIG:DEBUG>:TargetProperty1=TargetProperty1ValueDebug>") diff --git a/Tests/RunCMake/VS10Project/shader.hlsl b/Tests/RunCMake/VS10Project/shader.hlsl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Tests/RunCMake/VS10Project/shader.hlsl @@ -0,0 +1 @@ + diff --git a/Tests/RunCMake/VS10Project/shader2.hlsl b/Tests/RunCMake/VS10Project/shader2.hlsl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Tests/RunCMake/VS10Project/shader2.hlsl @@ -0,0 +1 @@ + diff --git a/Tests/RunCMake/export/Repeat-CMP0103-NEW-result.txt b/Tests/RunCMake/export/Repeat-CMP0103-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt b/Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt new file mode 100644 index 0000000..48ab7b1 --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt @@ -0,0 +1,17 @@ +CMake Error at Repeat.cmake:[0-9]+ \(export\): + export command already specified for the file + + foo.cmake + + Did you miss 'APPEND' keyword\? +Call Stack \(most recent call first\): + Repeat-CMP0103-NEW.cmake:[0-9]+ \(include\) + CMakeLists.txt:[0-9]+ \(include\) + + +CMake Error at Repeat/CMakeLists.txt:[0-9]+ \(export\): + export command already specified for the file + + .+/foo.cmake + + Did you miss 'APPEND' keyword\? diff --git a/Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake b/Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake new file mode 100644 index 0000000..69381df --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0103 NEW) +include(Repeat.cmake) diff --git a/Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake b/Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake new file mode 100644 index 0000000..25134d6 --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0103 OLD) +include(Repeat.cmake) diff --git a/Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt b/Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt new file mode 100644 index 0000000..3104df4 --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt @@ -0,0 +1,26 @@ +CMake Warning \(dev\) at Repeat.cmake:[0-9]+ \(export\): + Policy CMP0103 is not set: multiple export\(\) with same FILE without APPEND + is not allowed. Run "cmake --help-policy CMP0103" for policy details. Use + the cmake_policy command to set the policy and suppress this warning. + + export\(\) command already specified for the file + + foo.cmake + + Did you miss 'APPEND' keyword\? +Call Stack \(most recent call first\): + Repeat-CMP0103-WARN.cmake:[0-9]+ \(include\) + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\) at Repeat/CMakeLists.txt:[0-9]+ \(export\): + Policy CMP0103 is not set: multiple export\(\) with same FILE without APPEND + is not allowed. Run "cmake --help-policy CMP0103" for policy details. Use + the cmake_policy command to set the policy and suppress this warning. + + export\(\) command already specified for the file + + .+/foo.cmake + + Did you miss 'APPEND' keyword\? +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake b/Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake new file mode 100644 index 0000000..3a630c5 --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake @@ -0,0 +1 @@ +include(Repeat.cmake) diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake index df35d95..1c74762 100644 --- a/Tests/RunCMake/export/RunCMakeTest.cmake +++ b/Tests/RunCMake/export/RunCMakeTest.cmake @@ -2,7 +2,9 @@ include(RunCMake) run_cmake(CustomTarget) run_cmake(Empty) -run_cmake(Repeat) +run_cmake(Repeat-CMP0103-WARN) +run_cmake(Repeat-CMP0103-OLD) +run_cmake(Repeat-CMP0103-NEW) run_cmake(TargetNotFound) run_cmake(AppendExport) run_cmake(OldIface) diff --git a/Tests/RunCMake/target_link_libraries/ConfigCase-result.txt b/Tests/RunCMake/target_link_libraries/ConfigCase-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/ConfigCase-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt b/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt new file mode 100644 index 0000000..953c972 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt @@ -0,0 +1,13 @@ +^CMake Error at ConfigCase.cmake:[0-9]+ \(add_library\): + Target "impl" links to target "config::impl-Debug" but the target was not + found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or + an ALIAS target is missing\? +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) ++ +CMake Error at ConfigCase.cmake:[0-9]+ \(add_library\): + Target "impl" links to target "config::iface-Debug" but the target was not + found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or + an ALIAS target is missing\? +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/target_link_libraries/ConfigCase.cmake b/Tests/RunCMake/target_link_libraries/ConfigCase.cmake new file mode 100644 index 0000000..fc39478 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/ConfigCase.cmake @@ -0,0 +1,6 @@ +cmake_policy(VERSION 3.15) +enable_language(C) +add_library(iface INTERFACE) +target_link_libraries(iface INTERFACE "config::iface-$<CONFIG>") +add_library(impl empty.c) +target_link_libraries(impl PRIVATE "config::impl-$<CONFIG>" iface) diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake index c7feb5f..fb223ab 100644 --- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake @@ -1,5 +1,13 @@ include(RunCMake) +if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug) +else() + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) +endif() +run_cmake(ConfigCase) +unset(RunCMake_TEST_OPTIONS) + run_cmake(CMP0023-WARN) run_cmake(CMP0023-NEW) run_cmake(CMP0023-WARN-2) diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt index b8e157d..558d5de 100644 --- a/Tests/VSWinStorePhone/CMakeLists.txt +++ b/Tests/VSWinStorePhone/CMakeLists.txt @@ -127,7 +127,7 @@ set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainVS) set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3) set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_FLAGS "/DFLAGS_ADDED") set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_OUTPUT_HEADER_FILE "$(OutDir)%(Filename).h") - +set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SETTINGS "$<$<CONFIG:DEBUG>:SourceProperty1=SourceProperty1Value>") source_group("Source Files" FILES ${SOURCE_FILES}) source_group("Header Files" FILES ${HEADER_FILES}) @@ -135,6 +135,11 @@ source_group("Resource Files" FILES ${RESOURCE_FILES}) add_executable(${EXE_NAME} WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES}) set_property(TARGET ${EXE_NAME} PROPERTY VS_WINRT_COMPONENT TRUE) +set_property(TARGET ${EXE_NAME} PROPERTY VS_SOURCE_SETTINGS_FXCompile + "TargetProperty1=$<$<CONFIG:DEBUG>:TargetProperty1ValueDebug>$<$<CONFIG:RELEASE>:TargetProperty1ValueRelease>") + +add_custom_command(TARGET ${EXE_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -Dvcxproj="${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME}.vcxproj" -P "${CMAKE_CURRENT_SOURCE_DIR}/EnsurePropertiesSet.cmake") string(SUBSTRING "${CMAKE_SYSTEM_VERSION}" 0, 4, SHORT_VERSION) diff --git a/Tests/VSWinStorePhone/EnsurePropertiesSet.cmake b/Tests/VSWinStorePhone/EnsurePropertiesSet.cmake new file mode 100644 index 0000000..528c46f --- /dev/null +++ b/Tests/VSWinStorePhone/EnsurePropertiesSet.cmake @@ -0,0 +1,45 @@ +macro(ensure_props_set projectFile) + if(NOT EXISTS "${projectFile}") + message(FATAL_ERROR "Project file ${projectFile} does not exist.") + return() + endif() + + set(SourcePropertyFound FALSE) + set(DebugTargetPropertyFound FALSE) + set(ReleaseTargetPropertyFound FALSE) + + file(STRINGS "${projectFile}" lines) + foreach(line IN LISTS lines) + if(line MATCHES "<SourceProperty1.*Debug.*>SourceProperty1Value</SourceProperty1>") + message("SourceProperty1 setting found") + set(SourcePropertyFound TRUE) + endif() + + if(line MATCHES "<TargetProperty1.*Debug.*>TargetProperty1ValueDebug</TargetProperty1>") + message("Debug TargetProperty1 setting found") + set(DebugTargetPropertyFound TRUE) + endif() + + if(line MATCHES "<TargetProperty1.*Release.*>TargetProperty1ValueRelease</TargetProperty1>") + message("Release TargetProperty1 setting found") + set(ReleaseTargetPropertyFound TRUE) + endif() + endforeach() + + if (NOT SourcePropertyFound) + message(FATAL_ERROR "SourceProperty1 setting not found") + return() + endif() + + if (NOT DebugTargetPropertyFound) + message(FATAL_ERROR "Debug TargetProperty1 setting not found") + return() + endif() + + if (NOT ReleaseTargetPropertyFound) + message(FATAL_ERROR "Release TargetProperty1 setting not found") + return() + endif() +endmacro() + +ensure_props_set("${vcxproj}") |