GoogleTest.cmake 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file LICENSE.rst or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. GoogleTest
  5. ----------
  6. .. versionadded:: 3.9
  7. This module provides commands to help use the Google Test infrastructure.
  8. Load this module in a CMake project with:
  9. .. code-block:: cmake
  10. include(GoogleTest)
  11. Two mechanisms for adding tests are provided. :command:`gtest_add_tests` has
  12. been around for some time, originally via ``find_package(GTest)``.
  13. :command:`gtest_discover_tests` was introduced in CMake 3.10.
  14. The (older) :command:`gtest_add_tests` scans source files to identify tests.
  15. This is usually effective, with some caveats, including in cross-compiling
  16. environments, and makes setting additional properties on tests more convenient.
  17. However, its handling of parameterized tests is less comprehensive, and it
  18. requires re-running CMake to detect changes to the list of tests.
  19. The (newer) :command:`gtest_discover_tests` discovers tests by asking the
  20. compiled test executable to enumerate its tests. This is more robust and
  21. provides better handling of parameterized tests, and does not require CMake
  22. to be re-run when tests change. However, it may not work in a cross-compiling
  23. environment, and setting test properties is less convenient.
  24. More details can be found in the documentation of the respective functions.
  25. Both commands are intended to replace use of :command:`add_test` to register
  26. tests, and will create a separate CTest test for each Google Test test case.
  27. Note that this is in some cases less efficient, as common set-up and tear-down
  28. logic cannot be shared by multiple test cases executing in the same instance.
  29. However, it provides more fine-grained pass/fail information to CTest, which is
  30. usually considered as more beneficial. By default, the CTest test name is the
  31. same as the Google Test name (i.e. ``suite.testcase``); see also
  32. ``TEST_PREFIX`` and ``TEST_SUFFIX``.
  33. .. command:: gtest_add_tests
  34. Automatically add tests with CTest by scanning source code for Google Test
  35. macros:
  36. .. code-block:: cmake
  37. gtest_add_tests(TARGET target
  38. [SOURCES src1...]
  39. [EXTRA_ARGS args...]
  40. [WORKING_DIRECTORY dir]
  41. [TEST_PREFIX prefix]
  42. [TEST_SUFFIX suffix]
  43. [SKIP_DEPENDENCY]
  44. [TEST_LIST outVar]
  45. )
  46. ``gtest_add_tests`` attempts to identify tests by scanning source files.
  47. Although this is generally effective, it uses only a basic regular expression
  48. match, which can be defeated by atypical test declarations, and is unable to
  49. fully "split" parameterized tests. Additionally, it requires that CMake be
  50. re-run to discover any newly added, removed or renamed tests (by default,
  51. this means that CMake is re-run when any test source file is changed, but see
  52. ``SKIP_DEPENDENCY``). However, it has the advantage of declaring tests at
  53. CMake time, which somewhat simplifies setting additional properties on tests,
  54. and always works in a cross-compiling environment.
  55. The options are:
  56. ``TARGET target``
  57. Specifies the Google Test executable, which must be a known CMake
  58. executable target. CMake will substitute the location of the built
  59. executable when running the test.
  60. ``SOURCES src1...``
  61. When provided, only the listed files will be scanned for test cases. If
  62. this option is not given, the :prop_tgt:`SOURCES` property of the
  63. specified ``target`` will be used to obtain the list of sources.
  64. ``EXTRA_ARGS args...``
  65. Any extra arguments to pass on the command line to each test case.
  66. .. versionchanged:: 3.31
  67. Empty values in ``args...`` are preserved, see :policy:`CMP0178`.
  68. ``WORKING_DIRECTORY dir``
  69. Specifies the directory in which to run the discovered test cases. If this
  70. option is not provided, the current binary directory is used.
  71. ``TEST_PREFIX prefix``
  72. Specifies a ``prefix`` to be prepended to the name of each discovered test
  73. case. This can be useful when the same source files are being used in
  74. multiple calls to ``gtest_add_test()`` but with different ``EXTRA_ARGS``.
  75. ``TEST_SUFFIX suffix``
  76. Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
  77. every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
  78. be specified.
  79. ``SKIP_DEPENDENCY``
  80. Normally, the function creates a dependency which will cause CMake to be
  81. re-run if any of the sources being scanned are changed. This is to ensure
  82. that the list of discovered tests is updated. If this behavior is not
  83. desired (as may be the case while actually writing the test cases), this
  84. option can be used to prevent the dependency from being added.
  85. ``TEST_LIST outVar``
  86. The variable named by ``outVar`` will be populated in the calling scope
  87. with the list of discovered test cases. This allows the caller to do
  88. things like manipulate test properties of the discovered tests.
  89. .. versionchanged:: 3.31
  90. Empty values in the :prop_tgt:`TEST_LAUNCHER` and
  91. :prop_tgt:`CROSSCOMPILING_EMULATOR` target properties are preserved,
  92. see policy :policy:`CMP0178`.
  93. Usage example:
  94. .. code-block:: cmake
  95. include(GoogleTest)
  96. add_executable(FooTest FooUnitTest.cxx)
  97. gtest_add_tests(TARGET FooTest
  98. TEST_SUFFIX .noArgs
  99. TEST_LIST noArgsTests
  100. )
  101. gtest_add_tests(TARGET FooTest
  102. EXTRA_ARGS --someArg someValue
  103. TEST_SUFFIX .withArgs
  104. TEST_LIST withArgsTests
  105. )
  106. set_tests_properties(${noArgsTests} PROPERTIES TIMEOUT 10)
  107. set_tests_properties(${withArgsTests} PROPERTIES TIMEOUT 20)
  108. For backward compatibility, the following form is also supported:
  109. .. code-block:: cmake
  110. gtest_add_tests(exe args files...)
  111. ``exe``
  112. The path to the test executable or the name of a CMake target.
  113. ``args``
  114. A ;-list of extra arguments to be passed to executable. The entire
  115. list must be passed as a single argument. Enclose it in quotes,
  116. or pass ``""`` for no arguments.
  117. ``files...``
  118. A list of source files to search for tests and test fixtures.
  119. Alternatively, use ``AUTO`` to specify that ``exe`` is the name
  120. of a CMake executable target whose sources should be scanned.
  121. .. code-block:: cmake
  122. include(GoogleTest)
  123. set(FooTestArgs --foo 1 --bar 2)
  124. add_executable(FooTest FooUnitTest.cxx)
  125. gtest_add_tests(FooTest "${FooTestArgs}" AUTO)
  126. .. command:: gtest_discover_tests
  127. Automatically add tests with CTest by querying the compiled test executable
  128. for available tests:
  129. .. code-block:: cmake
  130. gtest_discover_tests(target
  131. [EXTRA_ARGS args...]
  132. [WORKING_DIRECTORY dir]
  133. [TEST_PREFIX prefix]
  134. [TEST_SUFFIX suffix]
  135. [TEST_FILTER expr]
  136. [NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
  137. [PROPERTIES name1 value1...]
  138. [TEST_LIST var]
  139. [DISCOVERY_TIMEOUT seconds]
  140. [XML_OUTPUT_DIR dir]
  141. [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
  142. [DISCOVERY_EXTRA_ARGS args...]
  143. )
  144. .. versionadded:: 3.10
  145. ``gtest_discover_tests()`` sets up a post-build or pre-test command on the
  146. test executable that generates the list of tests by parsing the output from
  147. running the test executable with the ``--gtest_list_tests`` argument.
  148. Compared to the source parsing approach of :command:`gtest_add_tests`,
  149. this ensures that the full list of tests, including instantiations of
  150. parameterized tests, is obtained. Since test discovery occurs at build
  151. or test time, it is not necessary to re-run CMake when the list of tests
  152. changes. However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR`
  153. is properly set in order to function in a cross-compiling environment.
  154. Additionally, setting properties on tests is somewhat less convenient, since
  155. the tests are not available at CMake time. Additional test properties may be
  156. assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
  157. more fine-grained test control is needed, custom content may be provided
  158. through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
  159. directory property. The set of discovered tests is made accessible to such a
  160. script via the ``<target>_TESTS`` variable (see the ``TEST_LIST`` option
  161. below for further discussion and limitations).
  162. The options are:
  163. ``target``
  164. Specifies the Google Test executable, which must be a known CMake
  165. executable target. CMake will substitute the location of the built
  166. executable when running the test.
  167. ``EXTRA_ARGS args...``
  168. Any extra arguments to pass on the command line to each test case.
  169. .. versionchanged:: 3.31
  170. Empty values in ``args...`` are preserved, see :policy:`CMP0178`.
  171. ``WORKING_DIRECTORY dir``
  172. Specifies the directory in which to run the discovered test cases. If this
  173. option is not provided, the current binary directory is used.
  174. ``TEST_PREFIX prefix``
  175. Specifies a ``prefix`` to be prepended to the name of each discovered test
  176. case. This can be useful when the same test executable is being used in
  177. multiple calls to ``gtest_discover_tests()`` but with different
  178. ``EXTRA_ARGS``.
  179. ``TEST_SUFFIX suffix``
  180. Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
  181. every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
  182. be specified.
  183. ``TEST_FILTER expr``
  184. .. versionadded:: 3.22
  185. Filter expression to pass as a ``--gtest_filter`` argument during test
  186. discovery. Note that the expression is a wildcard-based format that
  187. matches against the original test names as used by gtest. For type or
  188. value-parameterized tests, these names may be different to the potentially
  189. pretty-printed test names that :program:`ctest` uses.
  190. ``NO_PRETTY_TYPES``
  191. By default, the type index of type-parameterized tests is replaced by the
  192. actual type name in the CTest test name. If this behavior is undesirable
  193. (e.g. because the type names are unwieldy), this option will suppress this
  194. behavior.
  195. ``NO_PRETTY_VALUES``
  196. By default, the value index of value-parameterized tests is replaced by the
  197. actual value in the CTest test name. If this behavior is undesirable
  198. (e.g. because the value strings are unwieldy), this option will suppress
  199. this behavior.
  200. ``PROPERTIES name1 value1...``
  201. Specifies additional properties to be set on all tests discovered by this
  202. invocation of ``gtest_discover_tests()``.
  203. ``TEST_LIST var``
  204. Make the list of tests available in the variable ``var``, rather than the
  205. default ``<target>_TESTS``. This can be useful when the same test
  206. executable is being used in multiple calls to ``gtest_discover_tests()``.
  207. Note that this variable is only available in CTest.
  208. Due to a limitation of CMake's parsing rules, any test with a square
  209. bracket in its name will be omitted from the list of tests stored in
  210. this variable. Such tests will still be defined and executed by
  211. ``ctest`` as normal though.
  212. ``DISCOVERY_TIMEOUT num``
  213. .. versionadded:: 3.10.3
  214. Specifies how long (in seconds) CMake will wait for the test to enumerate
  215. available tests. If the test takes longer than this, discovery (and your
  216. build) will fail. Most test executables will enumerate their tests very
  217. quickly, but under some exceptional circumstances, a test may require a
  218. longer timeout. The default is 5. See also the ``TIMEOUT`` option of
  219. :command:`execute_process`.
  220. .. note::
  221. In CMake versions 3.10.1 and 3.10.2, this option was called ``TIMEOUT``.
  222. This clashed with the ``TIMEOUT`` test property, which is one of the
  223. common properties that would be set with the ``PROPERTIES`` keyword,
  224. usually leading to legal but unintended behavior. The keyword was
  225. changed to ``DISCOVERY_TIMEOUT`` in CMake 3.10.3 to address this
  226. problem. The ambiguous behavior of the ``TIMEOUT`` keyword in 3.10.1
  227. and 3.10.2 has not been preserved.
  228. ``XML_OUTPUT_DIR dir``
  229. .. versionadded:: 3.18
  230. If specified, the parameter is passed along with ``--gtest_output=xml:``
  231. to test executable. The actual file name is the same as the test target,
  232. including prefix and suffix. This should be used instead of
  233. ``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the
  234. XML result output when using parallel test execution.
  235. ``DISCOVERY_MODE``
  236. .. versionadded:: 3.18
  237. Provides greater control over when ``gtest_discover_tests()`` performs test
  238. discovery. By default, ``POST_BUILD`` sets up a post-build command
  239. to perform test discovery at build time. In certain scenarios, like
  240. cross-compiling, this ``POST_BUILD`` behavior is not desirable.
  241. By contrast, ``PRE_TEST`` delays test discovery until just prior to test
  242. execution. This way test discovery occurs in the target environment
  243. where the test has a better chance at finding appropriate runtime
  244. dependencies.
  245. ``DISCOVERY_MODE`` defaults to the value of the
  246. ``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not
  247. passed when calling ``gtest_discover_tests()``. This provides a mechanism
  248. for globally selecting a preferred test discovery behavior without having
  249. to modify each call site.
  250. ``DISCOVERY_EXTRA_ARGS args...``
  251. .. versionadded:: 3.31
  252. Any extra arguments to pass on the command line for the discovery command.
  253. .. versionadded:: 3.29
  254. The :prop_tgt:`TEST_LAUNCHER` target property is honored during test
  255. discovery and test execution.
  256. .. versionchanged:: 3.31
  257. Empty values in the :prop_tgt:`TEST_LAUNCHER` and
  258. :prop_tgt:`CROSSCOMPILING_EMULATOR` target properties are preserved,
  259. see policy :policy:`CMP0178`.
  260. #]=======================================================================]
  261. # Save project's policies
  262. block(SCOPE_FOR POLICIES)
  263. cmake_policy(VERSION 3.30)
  264. #------------------------------------------------------------------------------
  265. function(gtest_add_tests)
  266. if (ARGC LESS 1)
  267. message(FATAL_ERROR "No arguments supplied to gtest_add_tests()")
  268. endif()
  269. set(options
  270. SKIP_DEPENDENCY
  271. )
  272. set(oneValueArgs
  273. TARGET
  274. WORKING_DIRECTORY
  275. TEST_PREFIX
  276. TEST_SUFFIX
  277. TEST_LIST
  278. )
  279. set(multiValueArgs
  280. SOURCES
  281. EXTRA_ARGS
  282. )
  283. set(allKeywords ${options} ${oneValueArgs} ${multiValueArgs})
  284. cmake_policy(GET CMP0178 cmp0178
  285. PARENT_SCOPE # undocumented, do not use outside of CMake
  286. )
  287. unset(sources)
  288. if("${ARGV0}" IN_LIST allKeywords)
  289. if(cmp0178 STREQUAL "NEW")
  290. cmake_parse_arguments(PARSE_ARGV 0 arg
  291. "${options}" "${oneValueArgs}" "${multiValueArgs}"
  292. )
  293. else()
  294. cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  295. if(NOT cmp0178 STREQUAL "OLD")
  296. block(SCOPE_FOR VARIABLES)
  297. cmake_parse_arguments(PARSE_ARGV 0 arg_new
  298. "${options}" "${oneValueArgs}" "${multiValueArgs}"
  299. )
  300. # Due to a quirk of cmake_parse_arguments(PARSE_ARGV),
  301. # arg_new_EXTRA_ARGS will have semicolons already escaped, but
  302. # arg_EXTRA_ARGS won't. We need to pass the former through one round
  303. # of command argument parsing to de-escape them for comparison with
  304. # the latter.
  305. set(__newArgs ${arg_new_EXTRA_ARGS})
  306. if(NOT "${arg_EXTRA_ARGS}" STREQUAL "${__newArgs}")
  307. cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
  308. message(AUTHOR_WARNING
  309. "The EXTRA_ARGS contain one or more empty values. Those empty "
  310. "values are being silently discarded to preserve backward "
  311. "compatibility.\n"
  312. "${cmp0178_warning}"
  313. )
  314. endif()
  315. endblock()
  316. endif()
  317. endif()
  318. set(autoAddSources YES)
  319. else()
  320. # Non-keyword syntax, convert to keyword form
  321. if (ARGC LESS 3)
  322. message(FATAL_ERROR "gtest_add_tests() without keyword options requires at least 3 arguments")
  323. endif()
  324. set(arg_TARGET "${ARGV0}")
  325. set(arg_EXTRA_ARGS "${ARGV1}")
  326. if(NOT "${ARGV2}" STREQUAL "AUTO")
  327. set(arg_SOURCES "${ARGV}")
  328. list(REMOVE_AT arg_SOURCES 0 1)
  329. endif()
  330. endif()
  331. # The non-keyword syntax allows the first argument to be an arbitrary
  332. # executable rather than a target if source files are also provided. In all
  333. # other cases, both forms require a target.
  334. if(NOT TARGET "${arg_TARGET}" AND NOT arg_SOURCES)
  335. message(FATAL_ERROR "${arg_TARGET} does not define an existing CMake target")
  336. endif()
  337. if(NOT arg_WORKING_DIRECTORY)
  338. unset(maybe_WORKING_DIRECTORY)
  339. else()
  340. set(maybe_WORKING_DIRECTORY "WORKING_DIRECTORY \${arg_WORKING_DIRECTORY}")
  341. endif()
  342. if(NOT arg_SOURCES)
  343. get_property(arg_SOURCES TARGET ${arg_TARGET} PROPERTY SOURCES)
  344. endif()
  345. unset(testList)
  346. set(gtest_case_name_regex ".*\\([ \r\n\t]*([A-Za-z_0-9]+)[ \r\n\t]*,[ \r\n\t]*([A-Za-z_0-9]+)[ \r\n\t]*\\).*")
  347. set(gtest_test_type_regex "(TYPED_TEST|TEST)_?[FP]?")
  348. set(each_line_regex "([^\r\n]*[\r\n])")
  349. foreach(source IN LISTS arg_SOURCES)
  350. if(NOT arg_SKIP_DEPENDENCY)
  351. set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
  352. endif()
  353. file(READ "${source}" contents)
  354. # Replace characters in file content that are special to CMake
  355. string(REPLACE "[" "<OPEN_BRACKET>" contents "${contents}")
  356. string(REPLACE "]" "<CLOSE_BRACKET>" contents "${contents}")
  357. string(REPLACE ";" "\\;" contents "${contents}")
  358. # Split into lines
  359. string(REGEX MATCHALL "${each_line_regex}" content_lines "${contents}")
  360. set(line "0")
  361. # Stores the line number of the start of a test definition
  362. set(accumulate_line "0")
  363. # Stores accumulated lines to match multi-line test definitions
  364. set(accumulated "")
  365. # Iterate over each line in the file so that we know the line number of a test definition
  366. foreach(line_str IN LISTS content_lines)
  367. math(EXPR line "${line}+1")
  368. # Check if the current line is the start of a test definition
  369. string(REGEX MATCH "[ \t]*${gtest_test_type_regex}[ \t]*[\\(]*" accumulate_start_hit "${line_str}")
  370. if(accumulate_start_hit)
  371. set(accumulate_line "${line}")
  372. endif()
  373. # Append the current line to the accumulated string
  374. set(accumulated "${accumulated}${line_str}")
  375. # Attempt to match a complete test definition in the accumulated string
  376. string(REGEX MATCH "${gtest_test_type_regex}[ \r\n\t]*\\(([A-Za-z_0-9 ,\r\n\t]+)\\)" hit "${accumulated}")
  377. if(hit)
  378. # Reset accumulated for the next match
  379. set(accumulated "")
  380. else()
  381. # Continue accumulating lines
  382. continue()
  383. endif()
  384. # At this point, the start line of the test definition is known
  385. # Hence, we can set the test's DEF_SOURCE_LINE property with
  386. # ${source}:${accumulate_line} below.
  387. # VS Code CMake Tools extension looks for DEF_SOURCE_LINE
  388. # to locate the test definition for its "Go to test" feature.
  389. string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit})
  390. # Parameterized tests have a different signature for the filter
  391. if("x${test_type}" STREQUAL "xTEST_P")
  392. string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" gtest_test_name ${hit})
  393. elseif("x${test_type}" STREQUAL "xTYPED_TEST_P")
  394. string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1/*.\\2" gtest_test_name ${hit})
  395. elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST")
  396. string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" gtest_test_name ${hit})
  397. elseif("x${test_type}" STREQUAL "xTYPED_TEST")
  398. string(REGEX REPLACE ${gtest_case_name_regex} "\\1/*.\\2" gtest_test_name ${hit})
  399. else()
  400. message(WARNING "Could not parse GTest ${hit} for adding to CTest.")
  401. continue()
  402. endif()
  403. set(extra_args "")
  404. foreach(arg IN LISTS arg_EXTRA_ARGS)
  405. string(APPEND extra_args " [==[${arg}]==]")
  406. endforeach()
  407. # Make sure tests disabled in GTest get disabled in CTest
  408. if(gtest_test_name MATCHES "(^|\\.)DISABLED_")
  409. # Add the disabled test if CMake is new enough
  410. # Note that this check is to allow backwards compatibility so this
  411. # module can be copied locally in projects to use with older CMake
  412. # versions
  413. if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.8.20170401)
  414. string(REGEX REPLACE
  415. "(^|\\.)DISABLED_" "\\1"
  416. orig_test_name "${gtest_test_name}"
  417. )
  418. set(ctest_test_name
  419. ${arg_TEST_PREFIX}${orig_test_name}${arg_TEST_SUFFIX}
  420. )
  421. cmake_language(EVAL CODE "
  422. add_test(NAME \${ctest_test_name}
  423. ${maybe_WORKING_DIRECTORY}
  424. COMMAND \${arg_TARGET}
  425. --gtest_also_run_disabled_tests
  426. --gtest_filter=\${gtest_test_name}
  427. ${extra_args}
  428. __CMP0178 [==[${cmp0178}]==]
  429. )"
  430. )
  431. set_tests_properties(${ctest_test_name} PROPERTIES DISABLED TRUE
  432. DEF_SOURCE_LINE "${source}:${accumulate_line}")
  433. list(APPEND testList ${ctest_test_name})
  434. endif()
  435. else()
  436. set(ctest_test_name ${arg_TEST_PREFIX}${gtest_test_name}${arg_TEST_SUFFIX})
  437. cmake_language(EVAL CODE "
  438. add_test(NAME \${ctest_test_name}
  439. ${maybe_WORKING_DIRECTORY}
  440. COMMAND \${arg_TARGET}
  441. --gtest_filter=\${gtest_test_name}
  442. ${extra_args}
  443. __CMP0178 [==[${cmp0178}]==]
  444. )"
  445. )
  446. # Makes sure a skipped GTest is reported as so by CTest
  447. set_tests_properties(
  448. ${ctest_test_name}
  449. PROPERTIES
  450. SKIP_REGULAR_EXPRESSION "\\[ SKIPPED \\]"
  451. DEF_SOURCE_LINE "${source}:${accumulate_line}"
  452. )
  453. list(APPEND testList ${ctest_test_name})
  454. endif()
  455. endforeach()
  456. endforeach()
  457. if(arg_TEST_LIST)
  458. set(${arg_TEST_LIST} ${testList} PARENT_SCOPE)
  459. endif()
  460. endfunction()
  461. #------------------------------------------------------------------------------
  462. function(gtest_discover_tests target)
  463. set(options
  464. NO_PRETTY_TYPES
  465. NO_PRETTY_VALUES
  466. )
  467. set(oneValueArgs
  468. TEST_PREFIX
  469. TEST_SUFFIX
  470. WORKING_DIRECTORY
  471. TEST_LIST
  472. DISCOVERY_TIMEOUT
  473. XML_OUTPUT_DIR
  474. DISCOVERY_MODE
  475. )
  476. set(multiValueArgs
  477. EXTRA_ARGS
  478. DISCOVERY_EXTRA_ARGS
  479. PROPERTIES
  480. TEST_FILTER
  481. )
  482. cmake_parse_arguments(PARSE_ARGV 1 arg
  483. "${options}" "${oneValueArgs}" "${multiValueArgs}"
  484. )
  485. if(NOT arg_WORKING_DIRECTORY)
  486. set(arg_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
  487. endif()
  488. if(NOT arg_TEST_LIST)
  489. set(arg_TEST_LIST ${target}_TESTS)
  490. endif()
  491. if(NOT arg_DISCOVERY_TIMEOUT)
  492. set(arg_DISCOVERY_TIMEOUT 5)
  493. endif()
  494. if(NOT arg_DISCOVERY_MODE)
  495. if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
  496. set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
  497. endif()
  498. set(arg_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
  499. endif()
  500. get_property(
  501. has_counter
  502. TARGET ${target}
  503. PROPERTY CTEST_DISCOVERED_TEST_COUNTER
  504. SET
  505. )
  506. if(has_counter)
  507. get_property(
  508. counter
  509. TARGET ${target}
  510. PROPERTY CTEST_DISCOVERED_TEST_COUNTER
  511. )
  512. math(EXPR counter "${counter} + 1")
  513. else()
  514. set(counter 1)
  515. endif()
  516. set_property(
  517. TARGET ${target}
  518. PROPERTY CTEST_DISCOVERED_TEST_COUNTER
  519. ${counter}
  520. )
  521. # Define rule to generate test list for aforementioned test executable
  522. set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/${target}[${counter}]")
  523. set(ctest_include_file "${ctest_file_base}_include.cmake")
  524. set(ctest_tests_file "${ctest_file_base}_tests.cmake")
  525. get_property(test_launcher
  526. TARGET ${target}
  527. PROPERTY TEST_LAUNCHER
  528. )
  529. cmake_policy(GET CMP0158 _CMP0158
  530. PARENT_SCOPE # undocumented, do not use outside of CMake
  531. )
  532. if(NOT _CMP0158 OR _CMP0158 STREQUAL "OLD" OR _CMP0158 STREQUAL "NEW" AND CMAKE_CROSSCOMPILING)
  533. get_property(crosscompiling_emulator
  534. TARGET ${target}
  535. PROPERTY CROSSCOMPILING_EMULATOR
  536. )
  537. endif()
  538. if(test_launcher AND crosscompiling_emulator)
  539. set(test_executor "${test_launcher}" "${crosscompiling_emulator}")
  540. elseif(test_launcher)
  541. set(test_executor "${test_launcher}")
  542. elseif(crosscompiling_emulator)
  543. set(test_executor "${crosscompiling_emulator}")
  544. else()
  545. set(test_executor "")
  546. endif()
  547. cmake_policy(GET CMP0178 cmp0178
  548. PARENT_SCOPE # undocumented, do not use outside of CMake
  549. )
  550. if(NOT cmp0178 STREQUAL "NEW")
  551. # Preserve old behavior where empty list items are silently discarded
  552. set(test_executor_orig "${test_executor}")
  553. set(test_executor ${test_executor})
  554. set(arg_EXTRA_ARGS_orig "${arg_EXTRA_ARGS}")
  555. set(arg_EXTRA_ARGS ${arg_EXTRA_ARGS})
  556. if(NOT cmp0178 STREQUAL "OLD")
  557. if(NOT "${test_executor}" STREQUAL "${test_executor_orig}")
  558. cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
  559. message(AUTHOR_WARNING
  560. "The '${target}' target's TEST_LAUNCHER or CROSSCOMPILING_EMULATOR "
  561. "test properties contain one or more empty values. Those empty "
  562. "values are being silently discarded to preserve backward "
  563. "compatibility.\n"
  564. "${cmp0178_warning}"
  565. )
  566. endif()
  567. if(NOT "${arg_EXTRA_ARGS}" STREQUAL "${arg_EXTRA_ARGS_orig}")
  568. cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
  569. message(AUTHOR_WARNING
  570. "The EXTRA_ARGS value contains one or more empty values. "
  571. "Those empty values are being silently discarded to preserve "
  572. "backward compatibility.\n"
  573. "${cmp0178_warning}"
  574. )
  575. endif()
  576. endif()
  577. endif()
  578. if(arg_DISCOVERY_MODE STREQUAL "POST_BUILD")
  579. add_custom_command(
  580. TARGET ${target} POST_BUILD
  581. BYPRODUCTS "${ctest_tests_file}"
  582. COMMAND "${CMAKE_COMMAND}"
  583. -D "TEST_TARGET=${target}"
  584. -D "TEST_EXECUTABLE=$<TARGET_FILE:${target}>"
  585. -D "TEST_EXECUTOR=${test_executor}"
  586. -D "TEST_WORKING_DIR=${arg_WORKING_DIRECTORY}"
  587. -D "TEST_EXTRA_ARGS=${arg_EXTRA_ARGS}"
  588. -D "TEST_PROPERTIES=${arg_PROPERTIES}"
  589. -D "TEST_PREFIX=${arg_TEST_PREFIX}"
  590. -D "TEST_SUFFIX=${arg_TEST_SUFFIX}"
  591. -D "TEST_FILTER=${arg_TEST_FILTER}"
  592. -D "NO_PRETTY_TYPES=${arg_NO_PRETTY_TYPES}"
  593. -D "NO_PRETTY_VALUES=${arg_NO_PRETTY_VALUES}"
  594. -D "TEST_LIST=${arg_TEST_LIST}"
  595. -D "CTEST_FILE=${ctest_tests_file}"
  596. -D "TEST_DISCOVERY_TIMEOUT=${arg_DISCOVERY_TIMEOUT}"
  597. -D "TEST_DISCOVERY_EXTRA_ARGS=${arg_DISCOVERY_EXTRA_ARGS}"
  598. -D "TEST_XML_OUTPUT_DIR=${arg_XML_OUTPUT_DIR}"
  599. -P "${CMAKE_ROOT}/Modules/GoogleTestAddTests.cmake"
  600. VERBATIM
  601. )
  602. file(WRITE "${ctest_include_file}"
  603. "if(EXISTS \"${ctest_tests_file}\")\n"
  604. " include(\"${ctest_tests_file}\")\n"
  605. "else()\n"
  606. " add_test(${target}_NOT_BUILT ${target}_NOT_BUILT)\n"
  607. "endif()\n"
  608. )
  609. elseif(arg_DISCOVERY_MODE STREQUAL "PRE_TEST")
  610. get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
  611. PROPERTY GENERATOR_IS_MULTI_CONFIG
  612. )
  613. if(GENERATOR_IS_MULTI_CONFIG)
  614. set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
  615. endif()
  616. string(CONCAT ctest_include_content
  617. "if(EXISTS \"$<TARGET_FILE:${target}>\")" "\n"
  618. " if(NOT EXISTS \"${ctest_tests_file}\" OR" "\n"
  619. " NOT \"${ctest_tests_file}\" IS_NEWER_THAN \"$<TARGET_FILE:${target}>\" OR\n"
  620. " NOT \"${ctest_tests_file}\" IS_NEWER_THAN \"\${CMAKE_CURRENT_LIST_FILE}\")\n"
  621. " include(\"${CMAKE_ROOT}/Modules/GoogleTestAddTests.cmake\")" "\n"
  622. " gtest_discover_tests_impl(" "\n"
  623. " TEST_EXECUTABLE" " [==[$<TARGET_FILE:${target}>]==]" "\n"
  624. " TEST_EXECUTOR" " [==[${test_executor}]==]" "\n"
  625. " TEST_WORKING_DIR" " [==[${arg_WORKING_DIRECTORY}]==]" "\n"
  626. " TEST_EXTRA_ARGS" " [==[${arg_EXTRA_ARGS}]==]" "\n"
  627. " TEST_PROPERTIES" " [==[${arg_PROPERTIES}]==]" "\n"
  628. " TEST_PREFIX" " [==[${arg_TEST_PREFIX}]==]" "\n"
  629. " TEST_SUFFIX" " [==[${arg_TEST_SUFFIX}]==]" "\n"
  630. " TEST_FILTER" " [==[${arg_TEST_FILTER}]==]" "\n"
  631. " NO_PRETTY_TYPES" " [==[${arg_NO_PRETTY_TYPES}]==]" "\n"
  632. " NO_PRETTY_VALUES" " [==[${arg_NO_PRETTY_VALUES}]==]" "\n"
  633. " TEST_LIST" " [==[${arg_TEST_LIST}]==]" "\n"
  634. " CTEST_FILE" " [==[${ctest_tests_file}]==]" "\n"
  635. " TEST_DISCOVERY_TIMEOUT" " [==[${arg_DISCOVERY_TIMEOUT}]==]" "\n"
  636. " TEST_DISCOVERY_EXTRA_ARGS [==[${arg_DISCOVERY_EXTRA_ARGS}]==]" "\n"
  637. " TEST_XML_OUTPUT_DIR" " [==[${arg_XML_OUTPUT_DIR}]==]" "\n"
  638. " )" "\n"
  639. " endif()" "\n"
  640. " include(\"${ctest_tests_file}\")" "\n"
  641. "else()" "\n"
  642. " add_test(${target}_NOT_BUILT ${target}_NOT_BUILT)" "\n"
  643. "endif()" "\n"
  644. )
  645. if(GENERATOR_IS_MULTI_CONFIG)
  646. foreach(_config ${CMAKE_CONFIGURATION_TYPES})
  647. file(GENERATE
  648. OUTPUT "${ctest_file_base}_include-${_config}.cmake"
  649. CONTENT "${ctest_include_content}"
  650. CONDITION $<CONFIG:${_config}>
  651. )
  652. endforeach()
  653. file(WRITE "${ctest_include_file}"
  654. "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")"
  655. )
  656. else()
  657. file(GENERATE
  658. OUTPUT "${ctest_file_base}_include.cmake"
  659. CONTENT "${ctest_include_content}"
  660. )
  661. file(WRITE "${ctest_include_file}"
  662. "include(\"${ctest_file_base}_include.cmake\")"
  663. )
  664. endif()
  665. else()
  666. message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${arg_DISCOVERY_MODE}")
  667. endif()
  668. # Add discovered tests to directory TEST_INCLUDE_FILES
  669. set_property(DIRECTORY
  670. APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
  671. )
  672. endfunction()
  673. ###############################################################################
  674. # Restore project's policies
  675. endblock()