1cmake_minimum_required(VERSION 3.19) # CMP0053
2
3include(RunCMake)
4
5# Fix Visual Studio generator name
6if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
7  set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
8endif()
9
10set(RunCMake-check-file check.cmake)
11
12include("${RunCMake_SOURCE_DIR}/validate_schema.cmake")
13
14function(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}")
18endfunction()
19
20function(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}")
25  endif()
26
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}")
30  endif()
31  configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY)
32
33  if(NOT CMakePresets_FILE)
34    set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in")
35  endif()
36  if(EXISTS "${CMakePresets_FILE}")
37    configure_file("${CMakePresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY)
38  endif()
39
40  if(NOT CMakeUserPresets_FILE)
41    set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in")
42  endif()
43  if(EXISTS "${CMakeUserPresets_FILE}")
44    configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY)
45  endif()
46
47  set(_s_arg -S)
48  if(CMakePresets_NO_S_ARG)
49    set(_s_arg)
50  endif()
51  set(_source_args ${_s_arg} ${_source_arg})
52  if(CMakePresets_NO_SOURCE_ARGS)
53    set(_source_args)
54  endif()
55  set(_unused_cli --no-warn-unused-cli)
56  if(CMakePresets_WARN_UNUSED_CLI)
57    set(_unused_cli)
58  endif()
59
60  set(RunCMake_TEST_COMMAND ${CMAKE_COMMAND}
61    ${_source_args}
62    -DRunCMake_TEST=${name}
63    -DRunCMake_GENERATOR=${RunCMake_GENERATOR}
64    -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}
65    ${_unused_cli}
66    --preset=${name}
67    ${ARGN}
68    )
69  run_cmake(${name})
70endfunction()
71
72# Test CMakePresets.json errors
73set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
74run_cmake_presets(NoCMakePresets)
75run_cmake_presets(Comment)
76run_cmake_presets(JSONParseError)
77run_cmake_presets(InvalidRoot)
78run_cmake_presets(NoVersion)
79run_cmake_presets(InvalidVersion)
80run_cmake_presets(LowVersion)
81run_cmake_presets(HighVersion)
82run_cmake_presets(InvalidVendor)
83set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
84run_cmake_presets(NoPresets)
85set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
86run_cmake_presets(InvalidPresets)
87run_cmake_presets(PresetNotObject)
88run_cmake_presets(NoPresetName)
89run_cmake_presets(InvalidPresetName)
90run_cmake_presets(EmptyPresetName)
91set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
92run_cmake_presets(NoPresetGenerator)
93set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
94run_cmake_presets(InvalidPresetGenerator)
95set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
96run_cmake_presets(NoPresetBinaryDir)
97set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
98run_cmake_presets(InvalidPresetBinaryDir)
99run_cmake_presets(InvalidVariables)
100run_cmake_presets(VariableNotObject)
101run_cmake_presets(NoVariableValue)
102run_cmake_presets(InvalidVariableValue)
103run_cmake_presets(ExtraRootField)
104run_cmake_presets(ExtraPresetField)
105run_cmake_presets(ExtraVariableField)
106run_cmake_presets(FuturePresetInstallDirField)
107run_cmake_presets(FuturePresetToolchainField)
108run_cmake_presets(InvalidPresetVendor)
109set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
110run_cmake_presets(DuplicatePresets)
111run_cmake_presets(CyclicInheritance0)
112run_cmake_presets(CyclicInheritance1)
113run_cmake_presets(CyclicInheritance2)
114run_cmake_presets(InvalidInheritance)
115run_cmake_presets(ErrorNoWarningDev)
116run_cmake_presets(ErrorNoWarningDeprecated)
117set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
118run_cmake_presets(InvalidArchitectureStrategy)
119run_cmake_presets(UnknownArchitectureStrategy)
120run_cmake_presets(InvalidToolsetStrategy)
121run_cmake_presets(UnknownToolsetStrategy)
122run_cmake_presets(EmptyCacheKey)
123run_cmake_presets(EmptyEnvKey)
124set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
125run_cmake_presets(UnclosedMacro)
126run_cmake_presets(NoSuchMacro)
127run_cmake_presets(EnvCycle)
128run_cmake_presets(EmptyEnv)
129run_cmake_presets(EmptyPenv)
130run_cmake_presets(InvalidRegex)
131set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
132run_cmake_presets(ConditionFuture)
133run_cmake_presets(SubConditionNull)
134
135# Test cmakeMinimumRequired field
136run_cmake_presets(MinimumRequiredInvalid)
137set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
138run_cmake_presets(MinimumRequiredEmpty)
139run_cmake_presets(MinimumRequiredMajor)
140run_cmake_presets(MinimumRequiredMinor)
141run_cmake_presets(MinimumRequiredPatch)
142
143# Test properly working CMakePresets.json
144set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
145unset(ENV{TEST_ENV})
146unset(ENV{TEST_ENV_REF})
147unset(ENV{TEST_D_ENV_REF})
148set(ENV{TEST_ENV_OVERRIDE} "This environment variable will be overridden")
149set(ENV{TEST_PENV} "Process environment variable")
150set(ENV{TEST_ENV_REF_PENV} "suffix")
151run_cmake_presets(Good "-DTEST_OVERRIDE_1=Overridden value" "-DTEST_OVERRIDE_2:STRING=Overridden value" -C "${RunCMake_SOURCE_DIR}/CacheOverride.cmake" "-UTEST_UNDEF")
152unset(ENV{TEST_ENV_OVERRIDE})
153unset(ENV{TEST_PENV})
154unset(ENV{TEST_ENV_REF_PENV})
155run_cmake_presets(GoodNoArgs)
156file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryUp-build)
157run_cmake_presets(GoodBinaryUp)
158set(CMakePresets_SOURCE_ARG "../GoodBinaryRelative")
159run_cmake_presets(GoodBinaryRelative)
160unset(CMakePresets_SOURCE_ARG)
161run_cmake_presets(GoodSpaces "--preset" "Good Spaces")
162run_cmake_presets(GoodSpacesEq "--preset=Good Spaces")
163if(WIN32)
164  run_cmake_presets(GoodWindowsBackslash)
165endif()
166set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodBOM.json.in")
167run_cmake_presets(GoodBOM)
168set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
169file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build)
170run_cmake_presets(GoodBinaryCmdLine -B ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build)
171run_cmake_presets(GoodGeneratorCmdLine -G ${RunCMake_GENERATOR})
172run_cmake_presets(InvalidGeneratorCmdLine -G "Invalid Generator")
173set(CMakePresets_NO_S_ARG TRUE)
174run_cmake_presets(GoodNoS)
175set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/GoodNoSCachePrep-build")
176run_cmake_presets(GoodNoSCachePrep)
177set(CMakePresets_SOURCE_ARG ".")
178set(RunCMake_TEST_NO_CLEAN 1)
179run_cmake_presets(GoodNoSCache)
180unset(RunCMake_TEST_NO_CLEAN)
181unset(CMakePresets_SOURCE_ARG)
182unset(RunCMake_TEST_BINARY_DIR)
183unset(CMakePresets_NO_S_ARG)
184set(CMakePresets_NO_SOURCE_ARGS 1)
185set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/GoodNoSourceArg")
186set(RunCMake_TEST_NO_CLEAN 1)
187run_cmake_presets(GoodNoSourceArg)
188unset(RunCMake_TEST_NO_CLEAN)
189unset(RunCMake_TEST_BINARY_DIR)
190unset(CMakePresets_NO_SOURCE_ARGS)
191run_cmake_presets(GoodInheritanceParent)
192run_cmake_presets(GoodInheritanceChild)
193run_cmake_presets(GoodInheritanceOverride)
194run_cmake_presets(GoodInheritanceMulti)
195run_cmake_presets(GoodInheritanceMultiSecond)
196run_cmake_presets(GoodInheritanceMacro)
197
198set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodInstall.json.in")
199run_cmake_presets(GoodInstallDefault)
200run_cmake_presets(GoodInstallInherit)
201run_cmake_presets(GoodInstallOverride)
202run_cmake_presets(GoodInstallCommandLine  "--install-prefix=${RunCMake_SOURCE_DIR}/path/passed/on/command_line")
203
204set(RunCMake_TEST_SOURCE_DIR_NO_CLEAN 1)
205set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodToolchain.json.in")
206
207reset_cmake_presets_directory(GoodToolchainInherit)
208file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainDefault/toolchain.cmake" "")
209run_cmake_presets(GoodToolchainDefault)
210
211reset_cmake_presets_directory(GoodToolchainInherit)
212file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainInherit/toolchain.cmake" "")
213run_cmake_presets(GoodToolchainInherit)
214
215reset_cmake_presets_directory(GoodToolchainOverride)
216file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainOverride/override_toolchain.cmake" "")
217run_cmake_presets(GoodToolchainOverride)
218
219reset_cmake_presets_directory(GoodToolchainCommandLine)
220file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake" "")
221run_cmake_presets(GoodToolchainCommandLine  "--toolchain=${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake")
222
223unset(RunCMake_TEST_SOURCE_DIR_NO_CLEAN)
224
225
226set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in")
227# Test bad preset arguments
228run_cmake_presets(VendorMacro)
229run_cmake_presets(InvalidGenerator)
230
231# Test Visual Studio-specific stuff
232if(RunCMake_GENERATOR MATCHES "^Visual Studio ")
233  run_cmake_presets(VisualStudioGeneratorArch)
234  run_cmake_presets(VisualStudioWin32)
235  run_cmake_presets(VisualStudioWin64)
236  run_cmake_presets(VisualStudioWin32Override -A x64)
237  if(NOT RunCMake_GENERATOR STREQUAL "Visual Studio 9 2008")
238    run_cmake_presets(VisualStudioToolset)
239    run_cmake_presets(VisualStudioToolsetOverride -T "Test Toolset")
240    run_cmake_presets(VisualStudioInheritanceParent)
241    run_cmake_presets(VisualStudioInheritanceChild)
242    run_cmake_presets(VisualStudioInheritanceOverride)
243    run_cmake_presets(VisualStudioInheritanceMulti)
244    run_cmake_presets(VisualStudioInheritanceMultiSecond)
245  endif()
246else()
247  run_cmake_presets(ArchToolsetStrategyNone)
248  run_cmake_presets(ArchToolsetStrategyDefault)
249  run_cmake_presets(ArchToolsetStrategyIgnore)
250endif()
251
252# Test bad command line arguments
253run_cmake_presets(NoSuchPreset)
254run_cmake_presets(NoPresetArgument --preset)
255run_cmake_presets(NoPresetArgumentEq --preset= -DA=B)
256run_cmake_presets(UseHiddenPreset)
257
258# Test CMakeUserPresets.json
259unset(CMakePresets_FILE)
260run_cmake_presets(GoodUserOnly)
261run_cmake_presets(GoodUserFromMain)
262run_cmake_presets(GoodUserFromUser)
263run_cmake_presets(V2InheritV3Optional)
264
265# Test CMakeUserPresets.json errors
266run_cmake_presets(UserDuplicateInUser)
267run_cmake_presets(UserDuplicateCross)
268run_cmake_presets(UserInheritance)
269
270# Test listing presets
271set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListPresets.json.in")
272run_cmake_presets(ListPresets --list-presets)
273
274set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ListPresetsWorkingDir")
275set(RunCMake_TEST_NO_CLEAN 1)
276set(CMakePresets_NO_SOURCE_ARGS 1)
277run_cmake_presets(ListPresetsWorkingDir --list-presets)
278unset(CMakePresets_NO_SOURCE_ARGS)
279unset(RunCMake_TEST_NO_CLEAN)
280unset(RunCMake_TEST_BINARY_DIR)
281
282run_cmake_presets(ListPresetsNoSuchPreset)
283run_cmake_presets(ListPresetsHidden)
284
285# Test warning and error flags
286set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Warnings.json.in")
287set(CMakePresets_WARN_UNUSED_CLI 1)
288run_cmake_presets(NoWarningFlags)
289run_cmake_presets(WarningFlags)
290run_cmake_presets(DisableWarningFlags)
291run_cmake_presets(ErrorDev)
292run_cmake_presets(ErrorDeprecated)
293unset(CMakePresets_WARN_UNUSED_CLI)
294
295# Test debug
296set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Debug.json.in")
297run_cmake_presets(NoDebug)
298run_cmake_presets(Debug)
299
300# Test ${hostSystemName} macro
301set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/HostSystemName.json.in")
302run_cmake_presets(HostSystemName)
303set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/HostSystemNameFuture.json.in")
304run_cmake_presets(HostSystemNameFuture)
305
306# Test conditions
307set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Conditions.json.in")
308run_cmake_presets(ListConditions --list-presets)
309run_cmake_presets(SimpleTrue)
310run_cmake_presets(SimpleFalse)
311unset(CMakePresets_FILE)
312
313# Test optional generator and buildDir fields
314run_cmake_presets(OptionalBinaryDirField -B "${RunCMake_BINARY_DIR}/OptionalBinaryDirField/build")
315run_cmake_presets(OptionalGeneratorField -G "${RunCMake_GENERATOR}")
316set(CMakePresets_NO_S_ARG TRUE)
317set(CMakePresets_SOURCE_ARG "../OptionalBinaryDirFieldNoS")
318run_cmake_presets(OptionalBinaryDirFieldNoS)
319unset(CMakePresets_SOURCE_ARG)
320unset(CMakePresets_NO_S_ARG)
321
322# Test the example from the documentation
323file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example)
324string(REPLACE "\"generator\": \"Ninja\"" "\"generator\": \"@RunCMake_GENERATOR@\"" _example "${_example}")
325if(CMAKE_HOST_WIN32)
326  string(REPLACE [["PATH": "$env{HOME}/ninja/bin:$penv{PATH}"]] [["PATH": "$env{HOME}/ninja/bin;$penv{PATH}"]] _example "${_example}")
327endif()
328file(WRITE "${RunCMake_BINARY_DIR}/example.json.in" "${_example}")
329set(CMakePresets_FILE "${RunCMake_BINARY_DIR}/example.json.in")
330run_cmake_presets(DocumentationExample --preset=default)
331