RunCMakeTest.cmake 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. cmake_minimum_required(VERSION 3.16)
  2. include(RunCMake)
  3. set(RunCMake_GENERATOR "Ninja Multi-Config")
  4. set(RunCMake_GENERATOR_IS_MULTI_CONFIG 1)
  5. function(check_files dir)
  6. cmake_parse_arguments(_check_files "" "" "INCLUDE;EXCLUDE" ${ARGN})
  7. set(expected ${_check_files_INCLUDE})
  8. list(FILTER expected EXCLUDE REGEX "^$")
  9. list(REMOVE_DUPLICATES expected)
  10. list(SORT expected)
  11. file(GLOB_RECURSE actual "${dir}/*")
  12. list(FILTER actual EXCLUDE REGEX "/CMakeFiles/|\\.ninja$|/CMakeCache\\.txt$|/target_files[^/]*\\.cmake$|/\\.ninja_[^/]*$|/cmake_install\\.cmake$|\\.ilk$|\\.manifest$|\\.pdb$|\\.exp$|/install_manifest\\.txt$")
  13. foreach(f IN LISTS _check_files_INCLUDE _check_files_EXCLUDE)
  14. if(EXISTS ${f})
  15. list(APPEND actual ${f})
  16. endif()
  17. endforeach()
  18. list(REMOVE_DUPLICATES actual)
  19. list(SORT actual)
  20. if(NOT "${expected}" STREQUAL "${actual}")
  21. string(REPLACE ";" "\n " expected_formatted "${expected}")
  22. string(REPLACE ";" "\n " actual_formatted "${actual}")
  23. string(APPEND RunCMake_TEST_FAILED "Actual files did not match expected\nExpected:\n ${expected_formatted}\nActual:\n ${actual_formatted}\n")
  24. endif()
  25. set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
  26. endfunction()
  27. function(check_file_contents filename expected)
  28. if(NOT EXISTS "${filename}")
  29. string(APPEND RunCMake_TEST_FAILED "File ${filename} does not exist\n")
  30. else()
  31. file(READ "${filename}" actual)
  32. if(NOT actual MATCHES "${expected}")
  33. string(REPLACE "\n" "\n " expected_formatted "${expected}")
  34. string(REPLACE "\n" "\n " actual_formatted "${actual}")
  35. string(APPEND RunCMake_TEST_FAILED "Contents of ${filename} do not match expected\nExpected:\n ${expected_formatted}\nActual:\n ${actual_formatted}\n")
  36. endif()
  37. endif()
  38. set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
  39. endfunction()
  40. function(run_cmake_configure case)
  41. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
  42. set(RunCMake_TEST_NO_CLEAN 1)
  43. file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
  44. file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
  45. run_cmake(${case})
  46. endfunction()
  47. function(run_cmake_build case suffix config)
  48. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
  49. set(RunCMake_TEST_NO_CLEAN 1)
  50. set(tgts)
  51. foreach(tgt IN LISTS ARGN)
  52. list(APPEND tgts --target ${tgt})
  53. endforeach()
  54. if(config)
  55. set(config_arg --config ${config})
  56. else()
  57. set(config_arg)
  58. endif()
  59. run_cmake_command(${case}-${suffix}-build "${CMAKE_COMMAND}" --build . ${config_arg} ${tgts})
  60. endfunction()
  61. function(run_ninja case suffix file)
  62. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
  63. set(RunCMake_TEST_NO_CLEAN 1)
  64. run_cmake_command(${case}-${suffix}-ninja "${RunCMake_MAKE_PROGRAM}" -f "${file}" ${ARGN})
  65. endfunction()
  66. ###############################################################################
  67. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Simple-build)
  68. # IMPORTANT: Setting RelWithDebInfo as the first item in CMAKE_CONFIGURATION_TYPES
  69. # generates a build.ninja file with that configuration
  70. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo\\;Debug\\;Release\\;MinSizeRel;-DCMAKE_CROSS_CONFIGS=all")
  71. run_cmake_configure(Simple)
  72. unset(RunCMake_TEST_OPTIONS)
  73. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  74. run_cmake_build(Simple debug-target Debug simpleexe)
  75. run_ninja(Simple debug-target build-Debug.ninja simplestatic)
  76. get_filename_component(simpleshared_Release "${TARGET_FILE_simpleshared_Release}" NAME)
  77. run_cmake_build(Simple release-filename Release ${simpleshared_Release})
  78. file(RELATIVE_PATH simpleexe_Release "${RunCMake_TEST_BINARY_DIR}" "${TARGET_FILE_simpleexe_Release}")
  79. run_ninja(Simple release-file build-Release.ninja ${simpleexe_Release})
  80. run_cmake_build(Simple all-configs Release simplestatic:all)
  81. run_ninja(Simple default-build-file build.ninja simpleexe)
  82. run_cmake_build(Simple all-clean Release clean:all)
  83. run_cmake_build(Simple debug-subdir Debug SimpleSubdir/all)
  84. run_ninja(Simple release-in-minsizerel-graph-subdir build-MinSizeRel.ninja SimpleSubdir/all:Release)
  85. run_cmake_build(Simple all-subdir Release SimpleSubdir/all:all)
  86. run_ninja(Simple minsizerel-top build-MinSizeRel.ninja all)
  87. run_cmake_build(Simple debug-in-release-graph-top Release all:Debug)
  88. run_ninja(Simple all-clean-again build-Debug.ninja clean:all)
  89. run_ninja(Simple all-top build-RelWithDebInfo.ninja all:all)
  90. # Leave enough time for the timestamp to change on second-resolution systems
  91. execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
  92. file(TOUCH "${RunCMake_TEST_BINARY_DIR}/empty.cmake")
  93. run_ninja(Simple reconfigure-config build-Release.ninja simpleexe)
  94. execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
  95. file(TOUCH "${RunCMake_TEST_BINARY_DIR}/empty.cmake")
  96. run_ninja(Simple reconfigure-noconfig build.ninja simpleexe)
  97. run_ninja(Simple default-build-file-clean build.ninja clean)
  98. run_ninja(Simple default-build-file-clean-minsizerel build.ninja clean:MinSizeRel)
  99. run_ninja(Simple default-build-file-all build.ninja all)
  100. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAlias-build)
  101. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=all")
  102. run_cmake_configure(SimpleDefaultBuildAlias)
  103. unset(RunCMake_TEST_OPTIONS)
  104. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  105. run_ninja(SimpleDefaultBuildAlias target build.ninja simpleexe)
  106. run_ninja(SimpleDefaultBuildAlias all build.ninja all)
  107. run_ninja(SimpleDefaultBuildAlias clean build.ninja clean)
  108. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasList-build)
  109. set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
  110. run_cmake_configure(SimpleDefaultBuildAliasList)
  111. unset(RunCMake_TEST_OPTIONS)
  112. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  113. run_ninja(SimpleDefaultBuildAliasList target-configs build.ninja simpleexe)
  114. # IMPORTANT: This tests cmake --build . with no config using build.ninja
  115. run_cmake_build(SimpleDefaultBuildAliasList all-configs "" all)
  116. run_ninja(SimpleDefaultBuildAliasList all-relwithdebinfo build.ninja all:RelWithDebInfo)
  117. run_ninja(SimpleDefaultBuildAliasList clean-configs build.ninja clean)
  118. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasListCross-build)
  119. set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=Debug\\;Release")
  120. run_cmake_configure(SimpleDefaultBuildAliasListCross)
  121. unset(RunCMake_TEST_OPTIONS)
  122. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  123. run_ninja(SimpleDefaultBuildAliasListCross target-configs build.ninja simpleexe)
  124. unset(RunCMake_TEST_BINARY_DIR)
  125. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
  126. run_cmake(InvalidCrossConfigs)
  127. unset(RunCMake_TEST_OPTIONS)
  128. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo")
  129. run_cmake(InvalidDefaultBuildFileConfig)
  130. unset(RunCMake_TEST_OPTIONS)
  131. set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
  132. run_cmake(InvalidDefaultConfigsCross)
  133. unset(RunCMake_TEST_OPTIONS)
  134. set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all")
  135. run_cmake(InvalidDefaultConfigsNoCross)
  136. unset(RunCMake_TEST_OPTIONS)
  137. set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release")
  138. run_cmake(DefaultBuildFileConfig)
  139. unset(RunCMake_TEST_OPTIONS)
  140. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleNoCross-build)
  141. run_cmake_configure(SimpleNoCross)
  142. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  143. run_cmake_build(SimpleNoCross debug-target Debug simpleexe)
  144. run_ninja(SimpleNoCross debug-target build-Debug.ninja simplestatic:Debug)
  145. run_ninja(SimpleNoCross relwithdebinfo-in-release-graph-target build-Release.ninja simplestatic:RelWithDebInfo)
  146. run_cmake_build(SimpleNoCross relwithdebinfo-in-release-graph-all Release all:RelWithDebInfo)
  147. run_cmake_build(SimpleNoCross relwithdebinfo-in-release-graph-clean Release clean:RelWithDebInfo)
  148. run_ninja(SimpleNoCross all-target build-Debug.ninja simplestatic:all)
  149. run_ninja(SimpleNoCross all-all build-Debug.ninja all:all)
  150. run_cmake_build(SimpleNoCross all-clean Debug clean:all)
  151. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleCrossConfigs-build)
  152. set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release")
  153. run_cmake_configure(SimpleCrossConfigs)
  154. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  155. run_ninja(SimpleCrossConfigs release-in-release-graph build-Release.ninja simpleexe)
  156. run_cmake_build(SimpleCrossConfigs debug-in-release-graph Release simpleexe:Debug)
  157. run_cmake_build(SimpleCrossConfigs relwithdebinfo-in-release-graph Release simpleexe:RelWithDebInfo)
  158. run_ninja(SimpleCrossConfigs relwithdebinfo-in-relwithdebinfo-graph build-RelWithDebInfo.ninja simpleexe:RelWithDebInfo)
  159. run_ninja(SimpleCrossConfigs release-in-relwithdebinfo-graph build-RelWithDebInfo.ninja simplestatic:Release)
  160. run_cmake_build(SimpleCrossConfigs all-in-relwithdebinfo-graph RelWithDebInfo simplestatic:all)
  161. run_ninja(SimpleCrossConfigs clean-all-in-release-graph build-Release.ninja clean:all)
  162. run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all)
  163. run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo)
  164. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
  165. set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
  166. run_cmake_configure(Framework)
  167. unset(RunCMake_TEST_OPTIONS)
  168. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  169. run_cmake_build(Framework framework Debug all)
  170. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/FrameworkDependencyAutogen-build)
  171. set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
  172. run_cmake_configure(FrameworkDependencyAutogen)
  173. unset(RunCMake_TEST_OPTIONS)
  174. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  175. run_cmake_build(FrameworkDependencyAutogen framework Release test2:Debug)
  176. set(RunCMake_TEST_NO_CLEAN 1)
  177. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandGenerator-build)
  178. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all")
  179. run_cmake_configure(CustomCommandGenerator)
  180. unset(RunCMake_TEST_OPTIONS)
  181. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  182. run_cmake_build(CustomCommandGenerator debug Debug generated)
  183. run_cmake_command(CustomCommandGenerator-debug-generated "${TARGET_FILE_generated_Debug}")
  184. run_ninja(CustomCommandGenerator release build-Release.ninja generated)
  185. run_cmake_command(CustomCommandGenerator-release-generated "${TARGET_FILE_generated_Release}")
  186. run_ninja(CustomCommandGenerator debug-clean build-Debug.ninja clean)
  187. run_cmake_build(CustomCommandGenerator release-clean Release clean)
  188. run_cmake_build(CustomCommandGenerator debug-in-release-graph Release generated:Debug)
  189. run_cmake_command(CustomCommandGenerator-debug-in-release-graph-generated "${TARGET_FILE_generated_Debug}")
  190. run_ninja(CustomCommandGenerator debug-in-release-graph-clean build-Debug.ninja clean:Debug)
  191. run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja generated:Release)
  192. run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}")
  193. unset(RunCMake_TEST_NO_CLEAN)
  194. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandsAndTargets-build)
  195. set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
  196. run_cmake_configure(CustomCommandsAndTargets)
  197. unset(RunCMake_TEST_OPTIONS)
  198. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  199. run_cmake_build(CustomCommandsAndTargets release-command Release SubdirCommand)
  200. #FIXME Get this working
  201. #run_ninja(CustomCommandsAndTargets minsizerel-command build-MinSizeRel.ninja CustomCommandsAndTargetsSubdir/SubdirCommand)
  202. run_ninja(CustomCommandsAndTargets debug-command build-Debug.ninja TopCommand)
  203. run_ninja(CustomCommandsAndTargets release-target build-Release.ninja SubdirTarget)
  204. run_cmake_build(CustomCommandsAndTargets debug-target Debug TopTarget)
  205. run_cmake_build(CustomCommandsAndTargets debug-in-release-graph-postbuild Release SubdirPostBuild:Debug)
  206. run_ninja(CustomCommandsAndTargets release-postbuild build-Release.ninja SubdirPostBuild)
  207. run_cmake_build(CustomCommandsAndTargets debug-targetpostbuild Debug TopTargetPostBuild)
  208. run_ninja(CustomCommandsAndTargets release-targetpostbuild build-Release.ninja SubdirTargetPostBuild)
  209. unset(RunCMake_TEST_BINARY_DIR)
  210. run_cmake(CustomCommandDepfile)
  211. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build)
  212. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
  213. run_cmake_configure(PostfixAndLocation)
  214. unset(RunCMake_TEST_OPTIONS)
  215. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  216. run_cmake_build(PostfixAndLocation release-in-release-graph Release mylib:Release)
  217. run_cmake_build(PostfixAndLocation debug-in-release-graph Release mylib:Debug)
  218. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Clean-build)
  219. run_cmake_configure(Clean)
  220. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  221. run_cmake_build(Clean release Release)
  222. run_ninja(Clean release-notall build-Release.ninja exenotall)
  223. run_cmake_build(Clean release-clean Release clean)
  224. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdditionalCleanFiles-build)
  225. set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all")
  226. run_cmake_configure(AdditionalCleanFiles)
  227. unset(RunCMake_TEST_OPTIONS)
  228. run_cmake_build(AdditionalCleanFiles release-clean Release clean)
  229. run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all)
  230. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build)
  231. set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_CROSS_CONFIGS=all")
  232. run_cmake_configure(Install)
  233. unset(RunCMake_TEST_OPTIONS)
  234. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  235. run_cmake_build(Install release-install Release install)
  236. run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Debug)
  237. # FIXME Get this working
  238. #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
  239. #run_cmake_configure(AutoMocExecutable)
  240. #run_cmake_build(AutoMocExecutable debug-in-release-graph Release exe)
  241. # Need to test this manually because run_cmake() adds --no-warn-unused-cli
  242. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/NoUnusedVariables-build)
  243. run_cmake_command(NoUnusedVariables ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR}
  244. -G "Ninja Multi-Config"
  245. "-DRunCMake_TEST=NoUnusedVariables"
  246. "-DCMAKE_CROSS_CONFIGS=all"
  247. "-DCMAKE_DEFAULT_BUILD_TYPE=Debug"
  248. "-DCMAKE_DEFAULT_CONFIGS=all"
  249. )
  250. if(CMake_TEST_CUDA)
  251. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build)
  252. run_cmake_configure(CudaSimple)
  253. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  254. run_cmake_build(CudaSimple debug-target Debug simplecudaexe)
  255. run_ninja(CudaSimple all-clean build-Debug.ninja clean:Debug)
  256. endif()
  257. if(CMake_TEST_Qt5)
  258. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build)
  259. set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
  260. run_cmake_configure(Qt5)
  261. unset(RunCMake_TEST_OPTIONS)
  262. include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
  263. run_cmake_build(Qt5 debug-in-release-graph Release exe:Debug)
  264. endif()