diff options
44 files changed, 787 insertions, 316 deletions
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-properties.7.rst b/Help/manual/cmake-properties.7.rst index a2bbdcd..cbb2298 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -378,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 @@ -487,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/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/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/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_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/FindBoost.cmake b/Modules/FindBoost.cmake index 3c52466..38d3bfa 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1646,10 +1646,15 @@ endif() # Prefix initialization # ------------------------------------------------------------------------ -set(Boost_LIB_PREFIX "") -if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR - (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) ) +# Boost's static libraries use a "lib" prefix on DLL platforms +# to distinguish them from the DLL import libraries. +if (Boost_USE_STATIC_LIBS AND ( + (WIN32 AND NOT CYGWIN) + OR GHSMULTI + )) set(Boost_LIB_PREFIX "lib") +else() + set(Boost_LIB_PREFIX "") endif() if ( NOT Boost_NAMESPACE ) diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 69cbf9c..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() @@ -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 868c7d2..018de4c 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -134,7 +134,7 @@ 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(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_ID) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3d6a0f6..61750d3 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 20200327) +set(CMake_VERSION_PATCH 20200330) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) 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/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/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/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}") |