RunCMakeTest.cmake 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. include(RunCMake)
  2. # For `if (IN_LIST)`
  3. cmake_policy(SET CMP0057 NEW)
  4. run_cmake(compiler_introspection)
  5. include("${RunCMake_BINARY_DIR}/compiler_introspection-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. endif ()
  14. # This test uses C++20, but another prerequisite is missing, so forced
  15. # standards don't matter.
  16. run_cmake(NoCXX20ModuleFlag)
  17. endif ()
  18. if (RunCMake_GENERATOR MATCHES "Ninja")
  19. execute_process(
  20. COMMAND "${CMAKE_MAKE_PROGRAM}" --version
  21. RESULT_VARIABLE res
  22. OUTPUT_VARIABLE ninja_version
  23. ERROR_VARIABLE err
  24. OUTPUT_STRIP_TRAILING_WHITESPACE
  25. ERROR_STRIP_TRAILING_WHITESPACE)
  26. if (res)
  27. message(WARNING
  28. "Failed to determine `ninja` version: ${err}")
  29. set(ninja_version "0")
  30. endif ()
  31. endif ()
  32. set(generator_supports_cxx_modules 0)
  33. if (RunCMake_GENERATOR MATCHES "Ninja" AND
  34. ninja_version VERSION_GREATER_EQUAL "1.11" AND
  35. "cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
  36. set(generator_supports_cxx_modules 1)
  37. endif ()
  38. if (RunCMake_GENERATOR MATCHES "Visual Studio" AND
  39. CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34")
  40. set(generator_supports_cxx_modules 1)
  41. endif ()
  42. # Test behavior when the generator does not support C++20 modules.
  43. if (NOT generator_supports_cxx_modules)
  44. if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
  45. run_cmake(NoDyndepSupport)
  46. endif ()
  47. # Bail; the remaining tests require the generator to successfully generate
  48. # with C++20 modules in the source list.
  49. return ()
  50. endif ()
  51. set(fileset_types
  52. Modules)
  53. set(scopes
  54. Interface
  55. Private
  56. Public)
  57. foreach (fileset_type IN LISTS fileset_types)
  58. foreach (scope IN LISTS scopes)
  59. run_cmake("FileSet${fileset_type}${scope}")
  60. endforeach ()
  61. run_cmake("FileSet${fileset_type}InterfaceImported")
  62. # Test the error message when a non-C++ source file is found in the source
  63. # list.
  64. run_cmake("NotCXXSource${fileset_type}")
  65. endforeach ()
  66. run_cmake(InstallBMI)
  67. run_cmake(InstallBMIGenericArgs)
  68. run_cmake(InstallBMIIgnore)
  69. run_cmake(ExportBuildCxxModules)
  70. run_cmake(ExportInstallCxxModules)
  71. # Generator-specific tests.
  72. if (RunCMake_GENERATOR MATCHES "Ninja")
  73. run_cmake(NinjaDependInfoFileSet)
  74. run_cmake(NinjaDependInfoExport)
  75. run_cmake(NinjaDependInfoBMIInstall)
  76. elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
  77. # Not supported yet.
  78. else ()
  79. message(FATAL_ERROR
  80. "Please add 'DependInfo' tests for the '${RunCMake_GENERATOR}' generator.")
  81. endif ()
  82. # Actual compilation tests.
  83. if (NOT CMake_TEST_MODULE_COMPILATION)
  84. return ()
  85. endif ()
  86. function (run_cxx_module_test directory)
  87. set(test_name "${directory}")
  88. if (NOT ARGN STREQUAL "")
  89. list(POP_FRONT ARGN test_name)
  90. endif ()
  91. set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/examples/${directory}")
  92. set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/examples/${test_name}-build")
  93. if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
  94. set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
  95. else ()
  96. set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
  97. endif ()
  98. if (RunCMake_CXXModules_INSTALL)
  99. set(prefix "${RunCMake_BINARY_DIR}/examples/${test_name}-install")
  100. file(REMOVE_RECURSE "${prefix}")
  101. list(APPEND RunCMake_TEST_OPTIONS
  102. "-DCMAKE_INSTALL_PREFIX=${prefix}")
  103. endif ()
  104. list(APPEND RunCMake_TEST_OPTIONS
  105. "-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
  106. ${ARGN})
  107. run_cmake("examples/${test_name}")
  108. set(RunCMake_TEST_NO_CLEAN 1)
  109. run_cmake_command("examples/${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
  110. if (RunCMake_CXXModules_INSTALL)
  111. run_cmake_command("examples/${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug)
  112. endif ()
  113. if (NOT RunCMake_CXXModules_NO_TEST)
  114. run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
  115. endif ()
  116. endfunction ()
  117. string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
  118. # Tests which use named modules.
  119. if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
  120. run_cxx_module_test(simple)
  121. run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
  122. run_cxx_module_test(object-library)
  123. run_cxx_module_test(generated)
  124. run_cxx_module_test(deep-chain)
  125. run_cxx_module_test(duplicate)
  126. set(RunCMake_CXXModules_NO_TEST 1)
  127. run_cxx_module_test(circular)
  128. run_cxx_module_test(try-compile)
  129. run_cxx_module_test(try-run)
  130. unset(RunCMake_CXXModules_NO_TEST)
  131. run_cxx_module_test(same-src-name)
  132. run_cxx_module_test(scan_properties)
  133. endif ()
  134. # Tests which require compile commands support.
  135. if ("compile_commands" IN_LIST CMake_TEST_MODULE_COMPILATION)
  136. run_cxx_module_test(export-compile-commands)
  137. endif ()
  138. # Tests which require collation work.
  139. if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
  140. run_cxx_module_test(public-req-private)
  141. set(RunCMake_CXXModules_NO_TEST 1)
  142. run_cxx_module_test(req-private-other-target)
  143. unset(RunCMake_CXXModules_NO_TEST)
  144. endif ()
  145. # Tests which use named modules in shared libraries.
  146. if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
  147. run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
  148. endif ()
  149. # Tests which use partitions.
  150. if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
  151. run_cxx_module_test(partitions)
  152. endif ()
  153. # Tests which use internal partitions.
  154. if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
  155. run_cxx_module_test(internal-partitions)
  156. endif ()
  157. # Tests which install BMIs
  158. if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
  159. run_cxx_module_test(export-interface-no-properties-build)
  160. run_cxx_module_test(export-interface-build)
  161. run_cxx_module_test(export-usage-build)
  162. run_cxx_module_test(export-bmi-and-interface-build)
  163. endif ()
  164. # All of the following tests perform installation.
  165. set(RunCMake_CXXModules_INSTALL 1)
  166. # Tests which install BMIs
  167. if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
  168. run_cxx_module_test(install-bmi)
  169. run_cxx_module_test(install-bmi-and-interfaces)
  170. if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
  171. run_cxx_module_test(export-interface-no-properties-install)
  172. run_cxx_module_test(export-interface-install)
  173. run_cxx_module_test(export-usage-install)
  174. run_cxx_module_test(export-bmi-and-interface-install)
  175. endif ()
  176. endif ()