|  | @@ -42,7 +42,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      gtest_add_tests(TARGET target
 | 
	
		
			
				|  |  |                      [SOURCES src1...]
 | 
	
		
			
				|  |  | -                    [EXTRA_ARGS arg1...]
 | 
	
		
			
				|  |  | +                    [EXTRA_ARGS args...]
 | 
	
		
			
				|  |  |                      [WORKING_DIRECTORY dir]
 | 
	
		
			
				|  |  |                      [TEST_PREFIX prefix]
 | 
	
		
			
				|  |  |                      [TEST_SUFFIX suffix]
 | 
	
	
		
			
				|  | @@ -72,9 +72,12 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
 | 
	
		
			
				|  |  |      this option is not given, the :prop_tgt:`SOURCES` property of the
 | 
	
		
			
				|  |  |      specified ``target`` will be used to obtain the list of sources.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  ``EXTRA_ARGS arg1...``
 | 
	
		
			
				|  |  | +  ``EXTRA_ARGS args...``
 | 
	
		
			
				|  |  |      Any extra arguments to pass on the command line to each test case.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    .. versionchanged:: 3.31
 | 
	
		
			
				|  |  | +      Empty values in ``args...`` are preserved, see :policy:`CMP0178`.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    ``WORKING_DIRECTORY dir``
 | 
	
		
			
				|  |  |      Specifies the directory in which to run the discovered test cases.  If this
 | 
	
		
			
				|  |  |      option is not provided, the current binary directory is used.
 | 
	
	
		
			
				|  | @@ -101,6 +104,11 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
 | 
	
		
			
				|  |  |      with the list of discovered test cases.  This allows the caller to do
 | 
	
		
			
				|  |  |      things like manipulate test properties of the discovered tests.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  .. versionchanged:: 3.31
 | 
	
		
			
				|  |  | +    Empty values in the :prop_tgt:`TEST_LAUNCHER` and
 | 
	
		
			
				|  |  | +    :prop_tgt:`CROSSCOMPILING_EMULATOR` target properties are preserved,
 | 
	
		
			
				|  |  | +    see policy :policy:`CMP0178`.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    Usage example:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    .. code-block:: cmake
 | 
	
	
		
			
				|  | @@ -147,7 +155,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
 | 
	
		
			
				|  |  |    for available tests::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      gtest_discover_tests(target
 | 
	
		
			
				|  |  | -                         [EXTRA_ARGS arg1...]
 | 
	
		
			
				|  |  | +                         [EXTRA_ARGS args...]
 | 
	
		
			
				|  |  |                           [WORKING_DIRECTORY dir]
 | 
	
		
			
				|  |  |                           [TEST_PREFIX prefix]
 | 
	
		
			
				|  |  |                           [TEST_SUFFIX suffix]
 | 
	
	
		
			
				|  | @@ -187,9 +195,12 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
 | 
	
		
			
				|  |  |      executable target.  CMake will substitute the location of the built
 | 
	
		
			
				|  |  |      executable when running the test.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  ``EXTRA_ARGS arg1...``
 | 
	
		
			
				|  |  | +  ``EXTRA_ARGS args...``
 | 
	
		
			
				|  |  |      Any extra arguments to pass on the command line to each test case.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    .. versionchanged:: 3.31
 | 
	
		
			
				|  |  | +      Empty values in ``args...`` are preserved, see :policy:`CMP0178`.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    ``WORKING_DIRECTORY dir``
 | 
	
		
			
				|  |  |      Specifies the directory in which to run the discovered test cases.  If this
 | 
	
		
			
				|  |  |      option is not provided, the current binary directory is used.
 | 
	
	
		
			
				|  | @@ -283,6 +294,15 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
 | 
	
		
			
				|  |  |      for globally selecting a preferred test discovery behavior without having
 | 
	
		
			
				|  |  |      to modify each call site.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  .. versionadded:: 3.29
 | 
	
		
			
				|  |  | +    The :prop_tgt:`TEST_LAUNCHER` target property is honored during test
 | 
	
		
			
				|  |  | +    discovery and test execution.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  .. versionchanged:: 3.31
 | 
	
		
			
				|  |  | +    Empty values in the :prop_tgt:`TEST_LAUNCHER` and
 | 
	
		
			
				|  |  | +    :prop_tgt:`CROSSCOMPILING_EMULATOR` target properties are preserved,
 | 
	
		
			
				|  |  | +    see policy :policy:`CMP0178`.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  #]=======================================================================]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  # Save project's policies
 | 
	
	
		
			
				|  | @@ -312,9 +332,41 @@ function(gtest_add_tests)
 | 
	
		
			
				|  |  |    )
 | 
	
		
			
				|  |  |    set(allKeywords ${options} ${oneValueArgs} ${multiValueArgs})
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  cmake_policy(GET CMP0178 cmp0178
 | 
	
		
			
				|  |  | +    PARENT_SCOPE # undocumented, do not use outside of CMake
 | 
	
		
			
				|  |  | +  )
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    unset(sources)
 | 
	
		
			
				|  |  |    if("${ARGV0}" IN_LIST allKeywords)
 | 
	
		
			
				|  |  | -    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 | 
	
		
			
				|  |  | +    if(cmp0178 STREQUAL "NEW")
 | 
	
		
			
				|  |  | +      cmake_parse_arguments(PARSE_ARGV 0 arg
 | 
	
		
			
				|  |  | +        "${options}" "${oneValueArgs}" "${multiValueArgs}"
 | 
	
		
			
				|  |  | +      )
 | 
	
		
			
				|  |  | +    else()
 | 
	
		
			
				|  |  | +      cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 | 
	
		
			
				|  |  | +      if(NOT cmp0178 STREQUAL "OLD")
 | 
	
		
			
				|  |  | +        block(SCOPE_FOR VARIABLES)
 | 
	
		
			
				|  |  | +          cmake_parse_arguments(PARSE_ARGV 0 arg_new
 | 
	
		
			
				|  |  | +            "${options}" "${oneValueArgs}" "${multiValueArgs}"
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          # Due to a quirk of cmake_parse_arguments(PARSE_ARGV),
 | 
	
		
			
				|  |  | +          # arg_new_EXTRA_ARGS will have semicolons already escaped, but
 | 
	
		
			
				|  |  | +          # arg_EXTRA_ARGS won't. We need to pass the former through one round
 | 
	
		
			
				|  |  | +          # of command argument parsing to de-escape them for comparison with
 | 
	
		
			
				|  |  | +          # the latter.
 | 
	
		
			
				|  |  | +          set(__newArgs ${arg_new_EXTRA_ARGS})
 | 
	
		
			
				|  |  | +          if(NOT "${arg_EXTRA_ARGS}" STREQUAL "${__newArgs}")
 | 
	
		
			
				|  |  | +            cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
 | 
	
		
			
				|  |  | +            message(AUTHOR_WARNING
 | 
	
		
			
				|  |  | +              "The EXTRA_ARGS contain one or more empty values. Those empty "
 | 
	
		
			
				|  |  | +              "values are being silently discarded to preserve backward "
 | 
	
		
			
				|  |  | +              "compatibility.\n"
 | 
	
		
			
				|  |  | +              "${cmp0178_warning}"
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  | +          endif()
 | 
	
		
			
				|  |  | +        endblock()
 | 
	
		
			
				|  |  | +      endif()
 | 
	
		
			
				|  |  | +    endif()
 | 
	
		
			
				|  |  |      set(autoAddSources YES)
 | 
	
		
			
				|  |  |    else()
 | 
	
		
			
				|  |  |      # Non-keyword syntax, convert to keyword form
 | 
	
	
		
			
				|  | @@ -408,6 +460,11 @@ function(gtest_add_tests)
 | 
	
		
			
				|  |  |          continue()
 | 
	
		
			
				|  |  |        endif()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +      set(extra_args "")
 | 
	
		
			
				|  |  | +      foreach(arg IN LISTS arg_EXTRA_ARGS)
 | 
	
		
			
				|  |  | +        string(APPEND extra_args " [==[${arg}]==]")
 | 
	
		
			
				|  |  | +      endforeach()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        # Make sure tests disabled in GTest get disabled in CTest
 | 
	
		
			
				|  |  |        if(gtest_test_name MATCHES "(^|\\.)DISABLED_")
 | 
	
		
			
				|  |  |          # Add the disabled test if CMake is new enough
 | 
	
	
		
			
				|  | @@ -422,12 +479,15 @@ function(gtest_add_tests)
 | 
	
		
			
				|  |  |            set(ctest_test_name
 | 
	
		
			
				|  |  |                ${arg_TEST_PREFIX}${orig_test_name}${arg_TEST_SUFFIX}
 | 
	
		
			
				|  |  |            )
 | 
	
		
			
				|  |  | -          add_test(NAME ${ctest_test_name}
 | 
	
		
			
				|  |  | -                   ${workDir}
 | 
	
		
			
				|  |  | -                   COMMAND ${arg_TARGET}
 | 
	
		
			
				|  |  | -                     --gtest_also_run_disabled_tests
 | 
	
		
			
				|  |  | -                     --gtest_filter=${gtest_test_name}
 | 
	
		
			
				|  |  | -                     ${arg_EXTRA_ARGS}
 | 
	
		
			
				|  |  | +          cmake_language(EVAL CODE "
 | 
	
		
			
				|  |  | +            add_test(NAME ${ctest_test_name}
 | 
	
		
			
				|  |  | +                     ${workDir}
 | 
	
		
			
				|  |  | +                     COMMAND ${arg_TARGET}
 | 
	
		
			
				|  |  | +                       --gtest_also_run_disabled_tests
 | 
	
		
			
				|  |  | +                       --gtest_filter=${gtest_test_name}
 | 
	
		
			
				|  |  | +                       ${extra_args}
 | 
	
		
			
				|  |  | +                     __CMP0178 [==[${cmp0178}]==]
 | 
	
		
			
				|  |  | +            )"
 | 
	
		
			
				|  |  |            )
 | 
	
		
			
				|  |  |            set_tests_properties(${ctest_test_name} PROPERTIES DISABLED TRUE
 | 
	
		
			
				|  |  |              DEF_SOURCE_LINE "${source}:${accumulate_line}")
 | 
	
	
		
			
				|  | @@ -435,11 +495,14 @@ function(gtest_add_tests)
 | 
	
		
			
				|  |  |          endif()
 | 
	
		
			
				|  |  |        else()
 | 
	
		
			
				|  |  |          set(ctest_test_name ${arg_TEST_PREFIX}${gtest_test_name}${arg_TEST_SUFFIX})
 | 
	
		
			
				|  |  | -        add_test(NAME ${ctest_test_name}
 | 
	
		
			
				|  |  | -                 ${workDir}
 | 
	
		
			
				|  |  | -                 COMMAND ${arg_TARGET}
 | 
	
		
			
				|  |  | -                   --gtest_filter=${gtest_test_name}
 | 
	
		
			
				|  |  | -                   ${arg_EXTRA_ARGS}
 | 
	
		
			
				|  |  | +        cmake_language(EVAL CODE "
 | 
	
		
			
				|  |  | +          add_test(NAME ${ctest_test_name}
 | 
	
		
			
				|  |  | +                   ${workDir}
 | 
	
		
			
				|  |  | +                   COMMAND ${arg_TARGET}
 | 
	
		
			
				|  |  | +                     --gtest_filter=${gtest_test_name}
 | 
	
		
			
				|  |  | +                     ${extra_args}
 | 
	
		
			
				|  |  | +                   __CMP0178 [==[${cmp0178}]==]
 | 
	
		
			
				|  |  | +          )"
 | 
	
		
			
				|  |  |          )
 | 
	
		
			
				|  |  |          # Makes sure a skipped GTest is reported as so by CTest
 | 
	
		
			
				|  |  |          set_tests_properties(
 | 
	
	
		
			
				|  | @@ -480,9 +543,8 @@ function(gtest_discover_tests target)
 | 
	
		
			
				|  |  |      PROPERTIES
 | 
	
		
			
				|  |  |      TEST_FILTER
 | 
	
		
			
				|  |  |    )
 | 
	
		
			
				|  |  | -  cmake_parse_arguments(arg
 | 
	
		
			
				|  |  | +  cmake_parse_arguments(PARSE_ARGV 1 arg
 | 
	
		
			
				|  |  |      "${options}" "${oneValueArgs}" "${multiValueArgs}"
 | 
	
		
			
				|  |  | -    ${ARGN}
 | 
	
		
			
				|  |  |    )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if(NOT arg_WORKING_DIRECTORY)
 | 
	
	
		
			
				|  | @@ -551,6 +613,38 @@ function(gtest_discover_tests target)
 | 
	
		
			
				|  |  |      set(test_executor "")
 | 
	
		
			
				|  |  |    endif()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  cmake_policy(GET CMP0178 cmp0178
 | 
	
		
			
				|  |  | +    PARENT_SCOPE # undocumented, do not use outside of CMake
 | 
	
		
			
				|  |  | +  )
 | 
	
		
			
				|  |  | +  if(NOT cmp0178 STREQUAL "NEW")
 | 
	
		
			
				|  |  | +    # Preserve old behavior where empty list items are silently discarded
 | 
	
		
			
				|  |  | +    set(test_executor_orig "${test_executor}")
 | 
	
		
			
				|  |  | +    set(test_executor ${test_executor})
 | 
	
		
			
				|  |  | +    set(arg_EXTRA_ARGS_orig "${arg_EXTRA_ARGS}")
 | 
	
		
			
				|  |  | +    set(arg_EXTRA_ARGS ${arg_EXTRA_ARGS})
 | 
	
		
			
				|  |  | +    if(NOT cmp0178 STREQUAL "OLD")
 | 
	
		
			
				|  |  | +      if(NOT "${test_executor}" STREQUAL "${test_executor_orig}")
 | 
	
		
			
				|  |  | +        cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
 | 
	
		
			
				|  |  | +        message(AUTHOR_WARNING
 | 
	
		
			
				|  |  | +          "The '${target}' target's TEST_LAUNCHER or CROSSCOMPILING_EMULATOR "
 | 
	
		
			
				|  |  | +          "test properties contain one or more empty values. Those empty "
 | 
	
		
			
				|  |  | +          "values are being silently discarded to preserve backward "
 | 
	
		
			
				|  |  | +          "compatibility.\n"
 | 
	
		
			
				|  |  | +          "${cmp0178_warning}"
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +      endif()
 | 
	
		
			
				|  |  | +      if(NOT "${arg_EXTRA_ARGS}" STREQUAL "${arg_EXTRA_ARGS_orig}")
 | 
	
		
			
				|  |  | +        cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
 | 
	
		
			
				|  |  | +        message(AUTHOR_WARNING
 | 
	
		
			
				|  |  | +          "The EXTRA_ARGS value contains one or more empty values. "
 | 
	
		
			
				|  |  | +          "Those empty values are being silently discarded to preserve "
 | 
	
		
			
				|  |  | +          "backward compatibility.\n"
 | 
	
		
			
				|  |  | +          "${cmp0178_warning}"
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +      endif()
 | 
	
		
			
				|  |  | +    endif()
 | 
	
		
			
				|  |  | +  endif()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    if(arg_DISCOVERY_MODE STREQUAL "POST_BUILD")
 | 
	
		
			
				|  |  |      add_custom_command(
 | 
	
		
			
				|  |  |        TARGET ${target} POST_BUILD
 |