RunCMakeTest.cmake 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. include(RunCMake)
  2. # For `if (IN_LIST)`
  3. cmake_policy(SET CMP0057 NEW)
  4. run_cmake(Inspect)
  5. include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
  6. # Test negative cases where C++20 modules do not work.
  7. run_cmake(NoCXX)
  8. if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
  9. # This test requires that the compiler be told to compile in an older-than-20
  10. # standard. If the compiler forces a standard to be used, skip it.
  11. if (NOT forced_cxx_standard)
  12. run_cmake(NoCXX20)
  13. if(CMAKE_CXX_STANDARD_DEFAULT AND CMAKE_CXX20_STANDARD_COMPILE_OPTION)
  14. run_cmake_with_options(ImplicitCXX20 -DCMAKE_CXX20_STANDARD_COMPILE_OPTION=${CMAKE_CXX20_STANDARD_COMPILE_OPTION})
  15. endif()
  16. endif ()
  17. run_cmake(NoScanningSourceFileProperty)
  18. run_cmake(NoScanningTargetProperty)
  19. run_cmake(NoScanningVariable)
  20. run_cmake(CMP0155-OLD)
  21. run_cmake(CMP0155-NEW)
  22. endif ()
  23. if (RunCMake_GENERATOR MATCHES "Ninja")
  24. execute_process(
  25. COMMAND "${CMAKE_MAKE_PROGRAM}" --version
  26. RESULT_VARIABLE res
  27. OUTPUT_VARIABLE ninja_version
  28. ERROR_VARIABLE err
  29. OUTPUT_STRIP_TRAILING_WHITESPACE
  30. ERROR_STRIP_TRAILING_WHITESPACE)
  31. if (res)
  32. message(WARNING
  33. "Failed to determine `ninja` version: ${err}")
  34. set(ninja_version "0")
  35. endif ()
  36. endif ()
  37. set(generator_supports_cxx_modules 0)
  38. if (RunCMake_GENERATOR MATCHES "Ninja" AND
  39. ninja_version VERSION_GREATER_EQUAL "1.11" AND
  40. "cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
  41. set(generator_supports_cxx_modules 1)
  42. endif ()
  43. if (RunCMake_GENERATOR MATCHES "Visual Studio" AND
  44. CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34")
  45. set(generator_supports_cxx_modules 1)
  46. endif ()
  47. # Test behavior when the generator does not support C++20 modules.
  48. if (NOT generator_supports_cxx_modules)
  49. if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
  50. run_cmake(NoDyndepSupport)
  51. endif ()
  52. # Bail; the remaining tests require the generator to successfully generate
  53. # with C++20 modules in the source list.
  54. return ()
  55. endif ()
  56. set(fileset_types
  57. Modules)
  58. set(scopes
  59. Interface
  60. Private
  61. Public)
  62. foreach (fileset_type IN LISTS fileset_types)
  63. foreach (scope IN LISTS scopes)
  64. run_cmake("FileSet${fileset_type}${scope}")
  65. endforeach ()
  66. run_cmake("FileSet${fileset_type}InterfaceImported")
  67. # Test the error messages when a non-C++ source file is found in the source
  68. # list.
  69. run_cmake("NotCompiledSource${fileset_type}")
  70. run_cmake("NotCXXSource${fileset_type}")
  71. endforeach ()
  72. run_cmake(InstallBMI)
  73. run_cmake(InstallBMIGenericArgs)
  74. run_cmake(InstallBMIIgnore)
  75. run_cmake(ExportBuildCxxModules)
  76. run_cmake(ExportInstallCxxModules)
  77. # Generator-specific tests.
  78. if (RunCMake_GENERATOR MATCHES "Ninja")
  79. run_cmake(NinjaDependInfoFileSet)
  80. run_cmake(NinjaDependInfoExport)
  81. run_cmake(NinjaDependInfoBMIInstall)
  82. elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
  83. run_cmake(VisualStudioNoSyntheticTargets)
  84. else ()
  85. message(FATAL_ERROR
  86. "Please add 'DependInfo' tests for the '${RunCMake_GENERATOR}' generator.")
  87. endif ()
  88. # Actual compilation tests.
  89. if (NOT CMake_TEST_MODULE_COMPILATION)
  90. return ()
  91. endif ()
  92. function (run_cxx_module_test directory)
  93. set(test_name "${directory}")
  94. if (NOT ARGN STREQUAL "")
  95. list(POP_FRONT ARGN test_name)
  96. endif ()
  97. set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/examples/${directory}")
  98. set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/examples/${test_name}-build")
  99. if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
  100. set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
  101. else ()
  102. set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
  103. endif ()
  104. if (RunCMake_CXXModules_INSTALL)
  105. set(prefix "${RunCMake_BINARY_DIR}/examples/${test_name}-install")
  106. file(REMOVE_RECURSE "${prefix}")
  107. list(APPEND RunCMake_TEST_OPTIONS
  108. "-DCMAKE_INSTALL_PREFIX=${prefix}")
  109. endif ()
  110. list(APPEND RunCMake_TEST_OPTIONS
  111. "-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
  112. ${ARGN})
  113. run_cmake("examples/${test_name}")
  114. set(RunCMake_TEST_NO_CLEAN 1)
  115. if (RunCMake_CXXModules_TARGET)
  116. run_cmake_command("examples/${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug --target "${RunCMake_CXXModules_TARGET}")
  117. else ()
  118. run_cmake_command("examples/${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
  119. endif ()
  120. if (RunCMake_CXXModules_INSTALL)
  121. run_cmake_command("examples/${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug)
  122. endif ()
  123. if (NOT RunCMake_CXXModules_NO_TEST)
  124. run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
  125. endif ()
  126. endfunction ()
  127. function (run_cxx_module_test_target directory target)
  128. set(RunCMake_CXXModules_TARGET "${target}")
  129. set(RunCMake_CXXModules_NO_TEST 1)
  130. run_cxx_module_test("${directory}" ${ARGN})
  131. endfunction ()
  132. string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
  133. if (RunCMake_GENERATOR MATCHES "Ninja")
  134. if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
  135. set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/Debug/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
  136. else ()
  137. set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
  138. endif ()
  139. run_cxx_module_test_target(ninja-cmp0154 "${ninja_cmp0154_target}")
  140. endif ()
  141. # Tests which use named modules.
  142. if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
  143. run_cxx_module_test(simple)
  144. run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
  145. run_cxx_module_test(object-library)
  146. run_cxx_module_test(generated)
  147. run_cxx_module_test(deep-chain)
  148. run_cxx_module_test(duplicate)
  149. set(RunCMake_CXXModules_NO_TEST 1)
  150. run_cxx_module_test(circular)
  151. run_cxx_module_test(try-compile)
  152. run_cxx_module_test(try-run)
  153. unset(RunCMake_CXXModules_NO_TEST)
  154. run_cxx_module_test(same-src-name)
  155. run_cxx_module_test(scan_properties)
  156. endif ()
  157. # Tests which require compile commands support.
  158. if ("compile_commands" IN_LIST CMake_TEST_MODULE_COMPILATION)
  159. run_cxx_module_test(export-compile-commands)
  160. endif ()
  161. # Tests which require collation work.
  162. if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
  163. run_cxx_module_test(public-req-private)
  164. set(RunCMake_CXXModules_NO_TEST 1)
  165. run_cxx_module_test(req-private-other-target)
  166. unset(RunCMake_CXXModules_NO_TEST)
  167. endif ()
  168. # Tests which use named modules in shared libraries.
  169. if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
  170. run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
  171. endif ()
  172. # Tests which use partitions.
  173. if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
  174. run_cxx_module_test(partitions)
  175. endif ()
  176. # Tests which use internal partitions.
  177. if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
  178. run_cxx_module_test(internal-partitions)
  179. endif ()
  180. # Tests which install BMIs
  181. if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
  182. run_cxx_module_test(export-interface-no-properties-build)
  183. run_cxx_module_test(export-interface-build)
  184. run_cxx_module_test(export-include-directories-build)
  185. run_cxx_module_test(export-usage-build)
  186. run_cxx_module_test(export-bmi-and-interface-build)
  187. if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
  188. "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
  189. set(test_suffix export-interface-build)
  190. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build")
  191. set(test_suffix export-interface-no-properties-build)
  192. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DNO_PROPERTIES=1)
  193. set(test_suffix export-include-directories-build)
  194. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DINCLUDE_PROPERTIES=1)
  195. set(test_suffix export-bmi-and-interface-build)
  196. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DWITH_BMIS=1)
  197. endif ()
  198. endif ()
  199. # All of the following tests perform installation.
  200. set(RunCMake_CXXModules_INSTALL 1)
  201. # Tests which install BMIs
  202. if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
  203. run_cxx_module_test(install-bmi)
  204. run_cxx_module_test(install-bmi-and-interfaces)
  205. if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
  206. run_cxx_module_test(export-interface-no-properties-install)
  207. run_cxx_module_test(export-interface-install)
  208. run_cxx_module_test(export-include-directories-install)
  209. run_cxx_module_test(export-usage-install)
  210. run_cxx_module_test(export-bmi-and-interface-install)
  211. if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
  212. "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
  213. set(RunCMake_CXXModules_INSTALL 0)
  214. set(test_suffix export-interface-install)
  215. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install")
  216. set(test_suffix export-interface-no-properties-install)
  217. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DNO_PROPERTIES=1)
  218. set(test_suffix export-include-directories-install)
  219. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DINCLUDE_PROPERTIES=1)
  220. set(test_suffix export-bmi-and-interface-install)
  221. run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DWITH_BMIS=1)
  222. set(RunCMake_CXXModules_INSTALL 1)
  223. endif ()
  224. endif ()
  225. endif ()