1 cmake_minimum_required(VERSION 3.19) # CMP0053
5 # Fix Visual Studio generator name
6 if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
7 set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
10 set(RunCMake-check-file check.cmake)
12 include("${RunCMake_SOURCE_DIR}/validate_schema.cmake")
14 function(reset_cmake_presets_directory name)
15 set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
16 file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
17 file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
20 function(run_cmake_presets name)
21 set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
22 set(_source_arg "${RunCMake_TEST_SOURCE_DIR}")
23 if(CMakePresets_SOURCE_ARG)
24 set(_source_arg "${CMakePresets_SOURCE_ARG}")
27 if(NOT RunCMake_TEST_SOURCE_DIR_NO_CLEAN)
28 file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
29 file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
31 configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY)
33 if(NOT CMakePresets_FILE)
34 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in")
36 if(EXISTS "${CMakePresets_FILE}")
37 configure_file("${CMakePresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY)
40 if(NOT CMakeUserPresets_FILE)
41 set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in")
43 if(EXISTS "${CMakeUserPresets_FILE}")
44 configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY)
47 set(_CMakePresets_EXTRA_FILES_OUT)
48 set(_CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS)
49 foreach(_extra_file IN LISTS CMakePresets_EXTRA_FILES)
50 cmake_path(RELATIVE_PATH _extra_file
51 BASE_DIRECTORY "${RunCMake_SOURCE_DIR}"
52 OUTPUT_VARIABLE _extra_file_relative
54 string(REGEX REPLACE "\\.in$" "" _extra_file_out_relative "${_extra_file_relative}")
55 set(_extra_file_out "${RunCMake_TEST_SOURCE_DIR}/${_extra_file_out_relative}")
56 configure_file("${_extra_file}" "${_extra_file_out}" @ONLY)
57 list(APPEND _CMakePresets_EXTRA_FILES_OUT "${_extra_file_out}")
58 list(APPEND _CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS 0)
62 if(CMakePresets_NO_S_ARG)
65 set(_source_args ${_s_arg} ${_source_arg})
66 if(CMakePresets_NO_SOURCE_ARGS)
69 set(_unused_cli --no-warn-unused-cli)
70 if(CMakePresets_WARN_UNUSED_CLI)
74 set(_preset "--preset=${name}")
75 if(CMakePresets_NO_PRESET)
79 set(RunCMake_TEST_COMMAND ${CMAKE_COMMAND}
81 -DRunCMake_TEST=${name}
82 -DRunCMake_GENERATOR=${RunCMake_GENERATOR}
83 -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}
91 # Test CMakePresets.json errors
92 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
93 run_cmake_presets(NoCMakePresets)
94 run_cmake_presets(Comment)
95 run_cmake_presets(JSONParseError)
96 run_cmake_presets(InvalidRoot)
97 run_cmake_presets(NoVersion)
98 run_cmake_presets(InvalidVersion)
99 run_cmake_presets(LowVersion)
100 run_cmake_presets(HighVersion)
101 run_cmake_presets(InvalidVendor)
102 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
103 run_cmake_presets(NoPresets)
104 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
105 run_cmake_presets(InvalidPresets)
106 run_cmake_presets(PresetNotObject)
107 run_cmake_presets(NoPresetName)
108 run_cmake_presets(InvalidPresetName)
109 run_cmake_presets(EmptyPresetName)
110 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
111 run_cmake_presets(NoPresetGenerator)
112 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
113 run_cmake_presets(InvalidPresetGenerator)
114 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
115 run_cmake_presets(NoPresetBinaryDir)
116 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
117 run_cmake_presets(InvalidPresetBinaryDir)
118 run_cmake_presets(InvalidVariables)
119 run_cmake_presets(VariableNotObject)
120 run_cmake_presets(NoVariableValue)
121 run_cmake_presets(InvalidVariableValue)
122 run_cmake_presets(ExtraRootField)
123 run_cmake_presets(ExtraPresetField)
124 run_cmake_presets(ExtraVariableField)
125 run_cmake_presets(FuturePresetInstallDirField)
126 run_cmake_presets(FuturePresetToolchainField)
127 run_cmake_presets(InvalidPresetVendor)
128 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
129 run_cmake_presets(DuplicatePresets)
130 run_cmake_presets(CyclicInheritance0)
131 run_cmake_presets(CyclicInheritance1)
132 run_cmake_presets(CyclicInheritance2)
133 run_cmake_presets(InvalidInheritance)
134 run_cmake_presets(ErrorNoWarningDev)
135 run_cmake_presets(ErrorNoWarningDeprecated)
136 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
137 run_cmake_presets(InvalidArchitectureStrategy)
138 run_cmake_presets(UnknownArchitectureStrategy)
139 run_cmake_presets(InvalidToolsetStrategy)
140 run_cmake_presets(UnknownToolsetStrategy)
141 run_cmake_presets(EmptyCacheKey)
142 run_cmake_presets(EmptyEnvKey)
143 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
144 run_cmake_presets(UnclosedMacro)
145 run_cmake_presets(NoSuchMacro)
146 run_cmake_presets(EnvCycle)
147 run_cmake_presets(EmptyEnv)
148 run_cmake_presets(EmptyPenv)
149 run_cmake_presets(InvalidRegex)
150 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
151 run_cmake_presets(ConditionFuture)
152 run_cmake_presets(SubConditionNull)
154 # Test cmakeMinimumRequired field
155 run_cmake_presets(MinimumRequiredInvalid)
156 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
157 run_cmake_presets(MinimumRequiredEmpty)
158 run_cmake_presets(MinimumRequiredMajor)
159 run_cmake_presets(MinimumRequiredMinor)
160 run_cmake_presets(MinimumRequiredPatch)
162 # Test properly working CMakePresets.json
163 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
165 unset(ENV{TEST_ENV_REF})
166 unset(ENV{TEST_D_ENV_REF})
167 set(ENV{TEST_ENV_OVERRIDE} "This environment variable will be overridden")
168 set(ENV{TEST_PENV} "Process environment variable")
169 set(ENV{TEST_ENV_REF_PENV} "suffix")
170 run_cmake_presets(Good "-DTEST_OVERRIDE_1=Overridden value" "-DTEST_OVERRIDE_2:STRING=Overridden value" -C "${RunCMake_SOURCE_DIR}/CacheOverride.cmake" "-UTEST_UNDEF")
171 unset(ENV{TEST_ENV_OVERRIDE})
172 unset(ENV{TEST_PENV})
173 unset(ENV{TEST_ENV_REF_PENV})
174 run_cmake_presets(GoodNoArgs)
175 file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryUp-build)
176 run_cmake_presets(GoodBinaryUp)
177 set(CMakePresets_SOURCE_ARG "../GoodBinaryRelative")
178 run_cmake_presets(GoodBinaryRelative)
179 unset(CMakePresets_SOURCE_ARG)
180 run_cmake_presets(GoodSpaces "--preset" "Good Spaces")
181 run_cmake_presets(GoodSpacesEq "--preset=Good Spaces")
183 run_cmake_presets(GoodWindowsBackslash)
185 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodBOM.json.in")
186 run_cmake_presets(GoodBOM)
187 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
188 file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build)
189 run_cmake_presets(GoodBinaryCmdLine -B ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build)
190 run_cmake_presets(GoodGeneratorCmdLine -G ${RunCMake_GENERATOR})
191 run_cmake_presets(InvalidGeneratorCmdLine -G "Invalid Generator")
192 set(CMakePresets_NO_S_ARG TRUE)
193 run_cmake_presets(GoodNoS)
194 set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/GoodNoSCachePrep-build")
195 run_cmake_presets(GoodNoSCachePrep)
196 set(CMakePresets_SOURCE_ARG ".")
197 set(RunCMake_TEST_NO_CLEAN 1)
198 run_cmake_presets(GoodNoSCache)
199 unset(RunCMake_TEST_NO_CLEAN)
200 unset(CMakePresets_SOURCE_ARG)
201 unset(RunCMake_TEST_BINARY_DIR)
202 unset(CMakePresets_NO_S_ARG)
203 set(CMakePresets_NO_SOURCE_ARGS 1)
204 set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/GoodNoSourceArg")
205 set(RunCMake_TEST_NO_CLEAN 1)
206 run_cmake_presets(GoodNoSourceArg)
207 unset(RunCMake_TEST_NO_CLEAN)
208 unset(RunCMake_TEST_BINARY_DIR)
209 unset(CMakePresets_NO_SOURCE_ARGS)
210 run_cmake_presets(GoodInheritanceParent)
211 run_cmake_presets(GoodInheritanceChild)
212 run_cmake_presets(GoodInheritanceOverride)
213 run_cmake_presets(GoodInheritanceMulti)
214 run_cmake_presets(GoodInheritanceMultiSecond)
215 run_cmake_presets(GoodInheritanceMacro)
217 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodInstall.json.in")
218 run_cmake_presets(GoodInstallDefault)
219 run_cmake_presets(GoodInstallInherit)
220 run_cmake_presets(GoodInstallOverride)
221 run_cmake_presets(GoodInstallCommandLine "--install-prefix=${RunCMake_SOURCE_DIR}/path/passed/on/command_line")
223 set(RunCMake_TEST_SOURCE_DIR_NO_CLEAN 1)
224 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodToolchain.json.in")
226 reset_cmake_presets_directory(GoodToolchainInherit)
227 file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainDefault/toolchain.cmake" "")
228 run_cmake_presets(GoodToolchainDefault)
230 reset_cmake_presets_directory(GoodToolchainInherit)
231 file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainInherit/toolchain.cmake" "")
232 run_cmake_presets(GoodToolchainInherit)
234 reset_cmake_presets_directory(GoodToolchainOverride)
235 file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainOverride/override_toolchain.cmake" "")
236 run_cmake_presets(GoodToolchainOverride)
238 reset_cmake_presets_directory(GoodToolchainCommandLine)
239 file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake" "")
240 run_cmake_presets(GoodToolchainCommandLine "--toolchain=${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake")
242 unset(RunCMake_TEST_SOURCE_DIR_NO_CLEAN)
245 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
246 # Test bad preset arguments
247 run_cmake_presets(VendorMacro)
248 run_cmake_presets(InvalidGenerator)
250 # Test Visual Studio-specific stuff
251 if(RunCMake_GENERATOR MATCHES "^Visual Studio ")
252 run_cmake_presets(VisualStudioGeneratorArch)
253 run_cmake_presets(VisualStudioWin32)
254 run_cmake_presets(VisualStudioWin64)
255 run_cmake_presets(VisualStudioWin32Override -A x64)
256 if(NOT RunCMake_GENERATOR STREQUAL "Visual Studio 9 2008")
257 run_cmake_presets(VisualStudioToolset)
258 run_cmake_presets(VisualStudioToolsetOverride -T "Test Toolset")
259 run_cmake_presets(VisualStudioInheritanceParent)
260 run_cmake_presets(VisualStudioInheritanceChild)
261 run_cmake_presets(VisualStudioInheritanceOverride)
262 run_cmake_presets(VisualStudioInheritanceMulti)
263 run_cmake_presets(VisualStudioInheritanceMultiSecond)
266 run_cmake_presets(ArchToolsetStrategyNone)
267 run_cmake_presets(ArchToolsetStrategyDefault)
268 run_cmake_presets(ArchToolsetStrategyIgnore)
271 # Test bad command line arguments
272 run_cmake_presets(NoSuchPreset)
273 run_cmake_presets(NoPresetArgument --preset)
274 run_cmake_presets(NoPresetArgumentEq --preset= -DA=B)
275 run_cmake_presets(UseHiddenPreset)
277 # Test CMakeUserPresets.json
278 unset(CMakePresets_FILE)
279 run_cmake_presets(GoodUserOnly)
280 run_cmake_presets(GoodUserFromMain)
281 run_cmake_presets(GoodUserFromUser)
282 run_cmake_presets(V2InheritV3Optional)
284 # Test CMakeUserPresets.json errors
285 run_cmake_presets(UserDuplicateInUser)
286 run_cmake_presets(UserDuplicateCross)
287 run_cmake_presets(UserInheritance)
289 # Test listing presets
290 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListPresets.json.in")
291 run_cmake_presets(ListPresets --list-presets)
293 set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ListPresetsWorkingDir")
294 set(RunCMake_TEST_NO_CLEAN 1)
295 set(CMakePresets_NO_SOURCE_ARGS 1)
296 set(CMakePresets_NO_PRESET 1)
297 run_cmake_presets(ListPresetsWorkingDir --list-presets)
298 run_cmake_presets(ListConfigurePresetsWorkingDir --list-presets=configure)
299 unset(CMakePresets_NO_PRESET)
300 unset(CMakePresets_NO_SOURCE_ARGS)
301 unset(RunCMake_TEST_NO_CLEAN)
302 unset(RunCMake_TEST_BINARY_DIR)
304 run_cmake_presets(ListPresetsNoSuchPreset)
305 run_cmake_presets(ListPresetsHidden)
307 # Test warning and error flags
308 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Warnings.json.in")
309 set(CMakePresets_WARN_UNUSED_CLI 1)
310 run_cmake_presets(NoWarningFlags)
311 run_cmake_presets(WarningFlags)
312 run_cmake_presets(DisableWarningFlags)
313 run_cmake_presets(ErrorDev)
314 run_cmake_presets(ErrorDeprecated)
315 unset(CMakePresets_WARN_UNUSED_CLI)
318 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Debug.json.in")
319 run_cmake_presets(NoDebug)
320 run_cmake_presets(Debug)
322 # Test ${hostSystemName} macro
323 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/HostSystemName.json.in")
324 run_cmake_presets(HostSystemName)
325 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/HostSystemNameFuture.json.in")
326 run_cmake_presets(HostSystemNameFuture)
328 # Test ${fileDir} macro
329 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/FileDir.json.in")
330 set(CMakePresets_EXTRA_FILES
331 "${RunCMake_SOURCE_DIR}/subdir/FileDir.json.in"
333 run_cmake_presets(FileDir)
334 unset(CMakePresets_EXTRA_FILES)
335 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/FileDirFuture.json.in")
336 run_cmake_presets(FileDirFuture)
338 # Test ${pathListSep} macro
339 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/PathListSep.json.in")
340 run_cmake_presets(PathListSep)
341 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/PathListSepFuture.json.in")
342 run_cmake_presets(PathListSepFuture)
345 set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Conditions.json.in")
346 run_cmake_presets(ListConditions --list-presets)
347 run_cmake_presets(SimpleTrue)
348 run_cmake_presets(SimpleFalse)
349 unset(CMakePresets_FILE)
351 # Test optional generator and buildDir fields
352 run_cmake_presets(OptionalBinaryDirField -B "${RunCMake_BINARY_DIR}/OptionalBinaryDirField/build")
353 run_cmake_presets(OptionalGeneratorField -G "${RunCMake_GENERATOR}")
354 set(CMakePresets_NO_S_ARG TRUE)
355 set(CMakePresets_SOURCE_ARG "../OptionalBinaryDirFieldNoS")
356 run_cmake_presets(OptionalBinaryDirFieldNoS)
357 unset(CMakePresets_SOURCE_ARG)
358 unset(CMakePresets_NO_S_ARG)
361 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
362 run_cmake_presets(IncludeV3)
363 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
364 set(CMakePresets_EXTRA_FILES
365 "${RunCMake_SOURCE_DIR}/IncludeV4V3Extra.json.in"
367 set(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS 1)
368 run_cmake_presets(IncludeV4V3)
369 unset(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS)
370 set(CMakePresets_EXTRA_FILES
371 "${RunCMake_SOURCE_DIR}/IncludeCommon.json.in"
372 "${RunCMake_SOURCE_DIR}/IncludeUserCommon.json.in"
373 "${RunCMake_SOURCE_DIR}/subdir/CMakePresets.json.in"
375 run_cmake_presets(Include --list-presets)
376 unset(CMakePresets_EXTRA_FILES)
377 run_cmake_presets(IncludeNotFound)
378 run_cmake_presets(IncludeCycle)
379 set(CMakePresets_EXTRA_FILES
380 "${RunCMake_SOURCE_DIR}/IncludeCycle3Files2.json.in"
381 "${RunCMake_SOURCE_DIR}/IncludeCycle3Files3.json.in"
383 run_cmake_presets(IncludeCycle3Files)
384 set(CMakePresets_EXTRA_FILES
385 "${RunCMake_SOURCE_DIR}/IncludeOutsideProjectIntermediate.json.in"
387 run_cmake_presets(IncludeOutsideProject)
388 unset(CMakePresets_EXTRA_FILES)
389 run_cmake_presets(IncludeUserOutsideProject)
391 # Test the example from the documentation
392 file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example)
393 string(REPLACE "\"generator\": \"Ninja\"" "\"generator\": \"@RunCMake_GENERATOR@\"" _example "${_example}")
395 string(REPLACE [["PATH": "$env{HOME}/ninja/bin:$penv{PATH}"]] [["PATH": "$env{HOME}/ninja/bin;$penv{PATH}"]] _example "${_example}")
397 file(WRITE "${RunCMake_BINARY_DIR}/example.json.in" "${_example}")
398 set(CMakePresets_FILE "${RunCMake_BINARY_DIR}/example.json.in")
399 set(CMakePresets_EXTRA_FILES
400 "${RunCMake_SOURCE_DIR}/otherThings.json.in"
401 "${RunCMake_SOURCE_DIR}/moreThings.json.in"
403 run_cmake_presets(DocumentationExample --preset=default)
404 unset(CMakePresets_EXTRA_FILES)