RunCMakeTest.cmake 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. cmake_minimum_required(VERSION 3.19) # CMP0053
  2. include(RunCMake)
  3. # Fix Visual Studio generator name
  4. if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
  5. set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
  6. endif()
  7. set(RunCMake-check-file check.cmake)
  8. function(validate_schema file expected_result)
  9. execute_process(
  10. COMMAND "${PYTHON_EXECUTABLE}" "${RunCMake_SOURCE_DIR}/validate_schema.py" "${file}"
  11. RESULT_VARIABLE _result
  12. OUTPUT_VARIABLE _output
  13. ERROR_VARIABLE _error
  14. )
  15. if(NOT _result STREQUAL expected_result)
  16. string(REPLACE "\n" "\n" _output_p "${_output}")
  17. string(REPLACE "\n" "\n" _error_p "${_error}")
  18. string(APPEND RunCMake_TEST_FAILED "Expected result of validating ${file}: ${expected_result}\nActual result: ${_result}\nOutput:\n${_output_p}\nError:\n${_error_p}")
  19. endif()
  20. set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
  21. endfunction()
  22. function(run_cmake_presets name)
  23. set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
  24. set(_source_arg "${RunCMake_TEST_SOURCE_DIR}")
  25. if(CMakePresets_SOURCE_ARG)
  26. set(_source_arg "${CMakePresets_SOURCE_ARG}")
  27. endif()
  28. file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
  29. file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
  30. configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY)
  31. if(NOT CMakePresets_FILE)
  32. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in")
  33. endif()
  34. if(EXISTS "${CMakePresets_FILE}")
  35. configure_file("${CMakePresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY)
  36. endif()
  37. if(NOT CMakeUserPresets_FILE)
  38. set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in")
  39. endif()
  40. if(EXISTS "${CMakeUserPresets_FILE}")
  41. configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY)
  42. endif()
  43. set(_s_arg -S)
  44. if(CMakePresets_NO_S_ARG)
  45. set(_s_arg)
  46. endif()
  47. set(_source_args ${_s_arg} ${_source_arg})
  48. if(CMakePresets_NO_SOURCE_ARGS)
  49. set(_source_args)
  50. endif()
  51. set(_unused_cli --no-warn-unused-cli)
  52. if(CMakePresets_WARN_UNUSED_CLI)
  53. set(_unused_cli)
  54. endif()
  55. set(RunCMake_TEST_COMMAND ${CMAKE_COMMAND}
  56. ${_source_args}
  57. -DRunCMake_TEST=${name}
  58. -DRunCMake_GENERATOR=${RunCMake_GENERATOR}
  59. -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}
  60. ${_unused_cli}
  61. --preset=${name}
  62. ${ARGN}
  63. )
  64. run_cmake(${name})
  65. endfunction()
  66. # Test CMakePresets.json errors
  67. set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
  68. run_cmake_presets(NoCMakePresets)
  69. run_cmake_presets(JSONParseError)
  70. run_cmake_presets(InvalidRoot)
  71. run_cmake_presets(NoVersion)
  72. run_cmake_presets(InvalidVersion)
  73. run_cmake_presets(LowVersion)
  74. run_cmake_presets(HighVersion)
  75. run_cmake_presets(InvalidVendor)
  76. set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
  77. run_cmake_presets(NoPresets)
  78. set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
  79. run_cmake_presets(InvalidPresets)
  80. run_cmake_presets(PresetNotObject)
  81. run_cmake_presets(NoPresetName)
  82. run_cmake_presets(InvalidPresetName)
  83. run_cmake_presets(EmptyPresetName)
  84. set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
  85. run_cmake_presets(NoPresetGenerator)
  86. set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
  87. run_cmake_presets(InvalidPresetGenerator)
  88. set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
  89. run_cmake_presets(NoPresetBinaryDir)
  90. set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
  91. run_cmake_presets(InvalidPresetBinaryDir)
  92. run_cmake_presets(InvalidVariables)
  93. run_cmake_presets(VariableNotObject)
  94. run_cmake_presets(NoVariableValue)
  95. run_cmake_presets(InvalidVariableValue)
  96. run_cmake_presets(ExtraRootField)
  97. run_cmake_presets(ExtraPresetField)
  98. run_cmake_presets(ExtraVariableField)
  99. run_cmake_presets(InvalidPresetVendor)
  100. set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
  101. run_cmake_presets(DuplicatePresets)
  102. run_cmake_presets(CyclicInheritance0)
  103. run_cmake_presets(CyclicInheritance1)
  104. run_cmake_presets(CyclicInheritance2)
  105. run_cmake_presets(InvalidInheritance)
  106. run_cmake_presets(ErrorNoWarningDev)
  107. run_cmake_presets(ErrorNoWarningDeprecated)
  108. set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
  109. run_cmake_presets(InvalidArchitectureStrategy)
  110. run_cmake_presets(UnknownArchitectureStrategy)
  111. run_cmake_presets(InvalidToolsetStrategy)
  112. run_cmake_presets(UnknownToolsetStrategy)
  113. run_cmake_presets(EmptyCacheKey)
  114. run_cmake_presets(EmptyEnvKey)
  115. set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
  116. run_cmake_presets(UnclosedMacro)
  117. run_cmake_presets(NoSuchMacro)
  118. run_cmake_presets(EnvCycle)
  119. run_cmake_presets(EmptyEnv)
  120. run_cmake_presets(EmptyPenv)
  121. set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
  122. # Test cmakeMinimumRequired field
  123. run_cmake_presets(MinimumRequiredInvalid)
  124. set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
  125. run_cmake_presets(MinimumRequiredEmpty)
  126. run_cmake_presets(MinimumRequiredMajor)
  127. run_cmake_presets(MinimumRequiredMinor)
  128. run_cmake_presets(MinimumRequiredPatch)
  129. # Test properly working CMakePresets.json
  130. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
  131. unset(ENV{TEST_ENV})
  132. unset(ENV{TEST_ENV_REF})
  133. unset(ENV{TEST_D_ENV_REF})
  134. set(ENV{TEST_ENV_OVERRIDE} "This environment variable will be overridden")
  135. set(ENV{TEST_PENV} "Process environment variable")
  136. set(ENV{TEST_ENV_REF_PENV} "suffix")
  137. run_cmake_presets(Good "-DTEST_OVERRIDE_1=Overridden value" "-DTEST_OVERRIDE_2:STRING=Overridden value" -C "${RunCMake_SOURCE_DIR}/CacheOverride.cmake" "-UTEST_UNDEF")
  138. unset(ENV{TEST_ENV_OVERRIDE})
  139. unset(ENV{TEST_PENV})
  140. unset(ENV{TEST_ENV_REF_PENV})
  141. run_cmake_presets(GoodNoArgs)
  142. file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryUp-build)
  143. run_cmake_presets(GoodBinaryUp)
  144. set(CMakePresets_SOURCE_ARG "../GoodBinaryRelative")
  145. run_cmake_presets(GoodBinaryRelative)
  146. unset(CMakePresets_SOURCE_ARG)
  147. run_cmake_presets(GoodSpaces "--preset=Good Spaces")
  148. if(WIN32)
  149. run_cmake_presets(GoodWindowsBackslash)
  150. endif()
  151. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodBOM.json.in")
  152. run_cmake_presets(GoodBOM)
  153. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
  154. file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build)
  155. run_cmake_presets(GoodBinaryCmdLine -B ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build)
  156. run_cmake_presets(GoodGeneratorCmdLine -G ${RunCMake_GENERATOR})
  157. run_cmake_presets(InvalidGeneratorCmdLine -G "Invalid Generator")
  158. set(CMakePresets_NO_S_ARG TRUE)
  159. run_cmake_presets(GoodNoS)
  160. set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/GoodNoSCachePrep-build")
  161. run_cmake_presets(GoodNoSCachePrep)
  162. set(CMakePresets_SOURCE_ARG ".")
  163. set(RunCMake_TEST_NO_CLEAN 1)
  164. run_cmake_presets(GoodNoSCache)
  165. unset(RunCMake_TEST_NO_CLEAN)
  166. unset(CMakePresets_SOURCE_ARG)
  167. unset(RunCMake_TEST_BINARY_DIR)
  168. unset(CMakePresets_NO_S_ARG)
  169. run_cmake_presets(GoodInheritanceParent)
  170. run_cmake_presets(GoodInheritanceChild)
  171. run_cmake_presets(GoodInheritanceOverride)
  172. run_cmake_presets(GoodInheritanceMulti)
  173. run_cmake_presets(GoodInheritanceMultiSecond)
  174. run_cmake_presets(GoodInheritanceMacro)
  175. # Test bad preset arguments
  176. run_cmake_presets(VendorMacro)
  177. run_cmake_presets(InvalidGenerator)
  178. # Test Visual Studio-specific stuff
  179. if(RunCMake_GENERATOR MATCHES "^Visual Studio ")
  180. run_cmake_presets(VisualStudioGeneratorArch)
  181. run_cmake_presets(VisualStudioWin32)
  182. run_cmake_presets(VisualStudioWin64)
  183. run_cmake_presets(VisualStudioWin32Override -A x64)
  184. if(NOT RunCMake_GENERATOR STREQUAL "Visual Studio 9 2008")
  185. run_cmake_presets(VisualStudioToolset)
  186. run_cmake_presets(VisualStudioToolsetOverride -T "Test Toolset")
  187. run_cmake_presets(VisualStudioInheritanceParent)
  188. run_cmake_presets(VisualStudioInheritanceChild)
  189. run_cmake_presets(VisualStudioInheritanceOverride)
  190. run_cmake_presets(VisualStudioInheritanceMulti)
  191. run_cmake_presets(VisualStudioInheritanceMultiSecond)
  192. endif()
  193. else()
  194. run_cmake_presets(ArchToolsetStrategyNone)
  195. run_cmake_presets(ArchToolsetStrategyDefault)
  196. run_cmake_presets(ArchToolsetStrategyIgnore)
  197. endif()
  198. # Test bad command line arguments
  199. run_cmake_presets(NoSuchPreset)
  200. run_cmake_presets(NoPresetArgument --preset=)
  201. run_cmake_presets(UseHiddenPreset)
  202. # Test CMakeUserPresets.json
  203. unset(CMakePresets_FILE)
  204. run_cmake_presets(GoodUserOnly)
  205. run_cmake_presets(GoodUserFromMain)
  206. run_cmake_presets(GoodUserFromUser)
  207. # Test CMakeUserPresets.json errors
  208. run_cmake_presets(UserDuplicateInUser)
  209. run_cmake_presets(UserDuplicateCross)
  210. run_cmake_presets(UserInheritance)
  211. # Test listing presets
  212. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListPresets.json.in")
  213. run_cmake_presets(ListPresets --list-presets)
  214. set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ListPresetsWorkingDir")
  215. set(RunCMake_TEST_NO_CLEAN 1)
  216. set(CMakePresets_NO_SOURCE_ARGS 1)
  217. run_cmake_presets(ListPresetsWorkingDir --list-presets)
  218. unset(CMakePresets_NO_SOURCE_ARGS)
  219. unset(RunCMake_TEST_NO_CLEAN)
  220. unset(RunCMake_TEST_BINARY_DIR)
  221. run_cmake_presets(ListPresetsNoSuchPreset)
  222. run_cmake_presets(ListPresetsHidden)
  223. # Test warning and error flags
  224. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Warnings.json.in")
  225. set(CMakePresets_WARN_UNUSED_CLI 1)
  226. run_cmake_presets(NoWarningFlags)
  227. run_cmake_presets(WarningFlags)
  228. run_cmake_presets(DisableWarningFlags)
  229. run_cmake_presets(ErrorDev)
  230. run_cmake_presets(ErrorDeprecated)
  231. unset(CMakePresets_WARN_UNUSED_CLI)
  232. # Test debug
  233. set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Debug.json.in")
  234. run_cmake_presets(NoDebug)
  235. run_cmake_presets(Debug)
  236. # Test the example from the documentation
  237. file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example)
  238. string(REPLACE "\"generator\": \"Ninja\"" "\"generator\": \"@RunCMake_GENERATOR@\"" _example "${_example}")
  239. file(WRITE "${RunCMake_BINARY_DIR}/example.json.in" "${_example}")
  240. set(CMakePresets_FILE "${RunCMake_BINARY_DIR}/example.json.in")
  241. run_cmake_presets(DocumentationExample --preset=default)