Files
cmake/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
T
Tyler Yankee 95edd93948 presets: Support loading from arbitrary file
Allow CMake, CTest, and CPack to read presets from a path given by
command-line argument instead of always requiring `CMakePresets.json`
or `CMakeUserPresets.json` in the source tree. This makes the presets
feature more extensible to cases in which the user doesn't have access
to the presets defined in the source tree (e.g., if the source tree is
not writable).

For now, there is no equivalent implementation of such an option in the
`cmake-gui`, nor for the recent presets functionality implemented in
`ctest_configure` and `ctest_build`.

Fixes: #27329
2026-04-30 08:04:26 -04:00

137 lines
5.4 KiB
CMake

include(RunCMake)
# Isolate our ctest runs from external environment.
unset(ENV{CTEST_PARALLEL_LEVEL})
unset(ENV{CTEST_OUTPUT_ON_FAILURE})
# Presets do not support legacy VS generator name architecture suffix.
if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
endif()
function(run_cmake_test_presets name CMakePresetsTest_CONFIGURE_PRESETS CMakePresetsTest_BUILD_PRESETS CMakePresetsTest_TEST_PRESETS)
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
set(RunCMake_TEST_BINARY_DIR "${RunCMake_TEST_SOURCE_DIR}/build")
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
set(RunCMake_TEST_NO_CLEAN TRUE)
file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
set(CASE_NAME "${name}")
set(CASE_SOURCE_DIR "${RunCMake_SOURCE_DIR}")
configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY)
if(NOT CMakePresetsTest_FILE)
set(CMakePresetsTest_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in")
endif()
if(EXISTS "${CMakePresetsTest_FILE}")
configure_file("${CMakePresetsTest_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY)
endif()
if(NOT CMakeUserPresets_FILE)
set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in")
endif()
if(EXISTS "${CMakeUserPresets_FILE}")
configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY)
endif()
set(_presets_file)
if(CMakePresets_FILE_ARG)
set(_presets_file "--presets-file=${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}")
configure_file("${RunCMake_SOURCE_DIR}/${CMakePresets_FILE_ARG}.in" "${RunCMake_TEST_SOURCE_DIR}/${CMakePresets_FILE_ARG}" @ONLY)
endif()
foreach(ASSET ${CMakePresetsTest_ASSETS})
configure_file("${RunCMake_SOURCE_DIR}/${ASSET}" "${RunCMake_TEST_SOURCE_DIR}" COPYONLY)
endforeach()
if (NOT CMakePresetsTest_NO_CONFIGURE)
foreach(CONFIGURE_PRESET ${CMakePresetsTest_CONFIGURE_PRESETS})
run_cmake_command("${name}-configure-${CONFIGURE_PRESET}"
"${CMAKE_COMMAND}" "--preset" "${CONFIGURE_PRESET}")
endforeach()
endif()
if (NOT CMakePresetsTest_NO_BUILD)
foreach(BUILD_PRESET ${CMakePresetsTest_BUILD_PRESETS})
run_cmake_command("${name}-build-${BUILD_PRESET}"
"${CMAKE_COMMAND}" "--build" "--preset" "${BUILD_PRESET}")
endforeach()
endif()
set(eq 0)
foreach(TEST_PRESET ${CMakePresetsTest_TEST_PRESETS})
if (EXISTS "${RunCMake_SOURCE_DIR}/${name}-test-${TEST_PRESET}-check.cmake")
set(RunCMake-check-file "${name}-test-${TEST_PRESET}-check.cmake")
else()
set(RunCMake-check-file "check.cmake")
endif()
if(eq)
run_cmake_command(${name}-test-${TEST_PRESET}
${CMAKE_CTEST_COMMAND} "--preset=${TEST_PRESET}" ${_presets_file} ${ARGN})
set(eq 0)
else()
run_cmake_command(${name}-test-${TEST_PRESET}
${CMAKE_CTEST_COMMAND} "--preset" "${TEST_PRESET}" ${_presets_file} ${ARGN})
set(eq 1)
endif()
endforeach()
endfunction()
set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
set(CMakePresetsTest_NO_BUILD 1)
set(CMakePresetsTest_ASSETS "Good-indexFile.txt")
set(GoodTestPresets
"minimal;defaults;noEnvironment;withEnvironment"
"config-debug;config-release"
"exclude;index;indexFile;jobsProc;showOnly;outputLog;outputJUnit")
run_cmake_test_presets(Good
"default"
""
"${GoodTestPresets}")
unset(CMakePresetsTest_ASSETS)
run_cmake_test_presets(InvalidConfigurePreset "default" "" "badConfigurePreset")
set(CMakePresetsTest_NO_CONFIGURE 1)
set(CMakePresetsTest_FILE "${RunCMake_SOURCE_DIR}/Good.json.in")
run_cmake_test_presets(ListPresets "" "" "x" "--list-presets")
run_cmake_command(PresetsNoArg-test ${CMAKE_CTEST_COMMAND} "--preset")
run_cmake_command(PresetsNoArgEq-test ${CMAKE_CTEST_COMMAND} "--preset=")
run_cmake_command(PresetsFileNoArg-test ${CMAKE_CTEST_COMMAND} "--presets-file")
set(CMakePresetsTest_FILE "${RunCMake_SOURCE_DIR}/Condition.json.in")
run_cmake_test_presets(ConditionListPresets "" "" "x" "--list-presets")
unset(CMakePresetsTest_NO_CONFIGURE)
run_cmake_test_presets(ConditionRunTests "default" "" "enabled;disabled")
set(CMakePresetsTest_NO_CONFIGURE 1)
unset(CMakePresetsTest_FILE)
run_cmake_test_presets(NoConfigurePreset "" "" "noConfigurePreset")
run_cmake_test_presets(NoTestsAction "default" "" "noTestsAction")
run_cmake_test_presets(Invalid "" "" "hidden;vendorMacro")
set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
run_cmake_test_presets(PresetsUnsupported "" "" "x")
run_cmake_test_presets(ConditionFuture "" "" "x")
run_cmake_test_presets(TestOutputTruncationUnsupported "" "" "x")
run_cmake_test_presets(OutputJUnitUnsupported "" "" "x")
run_cmake_test_presets(InvalidJobs "" "" "x")
run_cmake_test_presets(JobsProcUnsupported "" "" "x")
run_cmake_test_presets(PassthroughUnsupported "" "" "x")
set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
run_cmake_test_presets(ConfigurePresetUnreachable "" "" "x")
set(CMakePresetsTest_NO_CONFIGURE 0)
run_cmake_test_presets(Passthrough "default" "" "basic;inherit;execOnly")
run_cmake_test_presets(PassthroughCombined "default" "" "combined" "--" "--cli-arg")
set(CMakePresets_FILE_ARG OtherCMakePresetsFile.json)
run_cmake_test_presets(OtherCMakePresetsFile "default" "" "default-from-other-file")
run_cmake_test_presets(OtherCMakePresetsFileListPresets "" "" "x" "--list-presets")