mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-29 03:08:17 +00:00
ctest: Honor preset binaryDir for initial configuration
Prior to this commit, ctest would sometimes use the current working directory as its binary directory rather than honoring `binaryDir` from a configure preset. This would occur when using ctest in dashboard client mode to perform an initial configuration with a preset. `ctest --source-dir=<dir> -T Configure -D CTEST_PRESET=<preset>` An explicit `--build-dir` still takes precedence over the preset's `binaryDir`.
This commit is contained in:
@@ -896,6 +896,13 @@ The available ``<dashboard-options>`` are the following:
|
||||
specify a different location. The binary directory is created automatically
|
||||
if it does not yet exist.
|
||||
|
||||
When a :manual:`configure preset <cmake-presets(7)>` is specified that
|
||||
defines a :preset:`binaryDir <configurePresets.binaryDir>`, CTest uses that
|
||||
path as the binary directory automatically (without requiring
|
||||
:ctest-dashboard-option:`--build-dir`). An explicit
|
||||
:ctest-dashboard-option:`--build-dir` takes precedence over the preset's
|
||||
:preset:`binaryDir <configurePresets.binaryDir>`.
|
||||
|
||||
A CMake generator must also be specified. Use
|
||||
:option:`-D CTEST_CMAKE_GENERATOR=\<gen\> <ctest-dashboard -D>` to supply one,
|
||||
or set :variable:`CTEST_CONFIGURE_PRESET` to specify a
|
||||
|
||||
@@ -353,6 +353,11 @@ CTest
|
||||
on the :program:`ctest` command line via the
|
||||
:ctest-dashboard-option:`-D` option.
|
||||
|
||||
* :manual:`ctest(1)` gained a :ctest-dashboard-option:`--source-dir` option
|
||||
to specify the source directory. When combined with
|
||||
:ctest-option:`-T` Configure, this allows CTest to perform an
|
||||
initial configure step for an empty binary directory.
|
||||
|
||||
* :manual:`ctest(1)` gained support for a :variable:`CTEST_SUBMIT_PARTS`
|
||||
variable that restricts which parts are uploaded when operating in
|
||||
:ref:`Dashboard Client` mode.
|
||||
|
||||
@@ -750,6 +750,57 @@ int cmCTest::ProcessSteps()
|
||||
mf.AddDefinition(def.first, def.second);
|
||||
}
|
||||
|
||||
if (!this->Impl->SourceDir.empty() && this->Impl->TestDir.empty() &&
|
||||
this->Impl->CTestConfigurationOverwrites.find("BuildDirectory") ==
|
||||
this->Impl->CTestConfigurationOverwrites.end()) {
|
||||
std::string const configurePresetName =
|
||||
cmNonempty(mf.GetDefinition("CTEST_CONFIGURE_PRESET"))
|
||||
? *mf.GetDefinition("CTEST_CONFIGURE_PRESET")
|
||||
: mf.GetSafeDefinition("CTEST_PRESET");
|
||||
if (!configurePresetName.empty()) {
|
||||
// Check if we should use the binary directory from the specified
|
||||
// configure preset.
|
||||
std::string const sourceDir =
|
||||
this->GetCTestConfiguration("SourceDirectory");
|
||||
std::string const rawPresetsFile =
|
||||
mf.GetSafeDefinition("CTEST_PRESETS_FILE");
|
||||
std::string const presetsFile = rawPresetsFile.empty()
|
||||
? std::string{}
|
||||
: cmSystemTools::CollapseFullPath(rawPresetsFile, sourceDir);
|
||||
cmCMakePresetsGraph presetsGraph;
|
||||
if (!sourceDir.empty()) {
|
||||
if (!presetsGraph.ReadProjectPresets(sourceDir, presetsFile)) {
|
||||
cmCTestLog(this, ERROR_MESSAGE,
|
||||
"Could not read presets from \""
|
||||
<< sourceDir << "\":\n "
|
||||
<< presetsGraph.parseState.GetErrorMessage()
|
||||
<< std::endl);
|
||||
return 12;
|
||||
}
|
||||
cmCMakePresetsGraph::PresetResolveResult<
|
||||
cmCMakePresetsGraph::ConfigurePreset>
|
||||
resolveResult = presetsGraph.ResolvePreset(
|
||||
configurePresetName, presetsGraph.ConfigurePresets);
|
||||
cm::optional<std::string> resolveError =
|
||||
cmCMakePresetsGraph::FormatPresetError<
|
||||
cmCMakePresetsGraph::ConfigurePreset>(
|
||||
resolveResult.StatusCode, resolveResult.ErrorPresetName,
|
||||
sourceDir);
|
||||
if (resolveError) {
|
||||
cmCTestLog(this, ERROR_MESSAGE, *resolveError << std::endl);
|
||||
return 12;
|
||||
}
|
||||
if (resolveResult.Preset && !resolveResult.Preset->BinaryDir.empty()) {
|
||||
std::string const binaryDir = resolveResult.Preset->BinaryDir;
|
||||
this->SetCTestConfiguration("BuildDirectory", binaryDir);
|
||||
this->Impl->BinaryDir = binaryDir;
|
||||
cmSystemTools::SetLogicalWorkingDirectory(binaryDir);
|
||||
mf.AddDefinition("CTEST_BINARY_DIRECTORY", binaryDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CTEST_TIME_LIMIT may come from CTestCustom.cmake (already in the makefile)
|
||||
// or from the config map (just populated by SetCMakeVariables above).
|
||||
this->SetTimeLimit(mf.GetDefinition("CTEST_TIME_LIMIT"));
|
||||
|
||||
1
Tests/RunCMake/CTestCommandLine/BadCMakePresets.json.in
Normal file
1
Tests/RunCMake/CTestCommandLine/BadCMakePresets.json.in
Normal file
@@ -0,0 +1 @@
|
||||
{ this is not valid json
|
||||
21
Tests/RunCMake/CTestCommandLine/CMakePresets.json.in
Normal file
21
Tests/RunCMake/CTestCommandLine/CMakePresets.json.in
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"version": 1,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 18,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "my-preset",
|
||||
"generator": "@RunCMake_GENERATOR@",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"MY_CUSTOM_VAR": {
|
||||
"type": "STRING",
|
||||
"value": "this-gets-set"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1 @@
|
||||
Could not read presets from ".*"
|
||||
@@ -0,0 +1,13 @@
|
||||
# --build-dir should take precedence over the preset's binaryDir.
|
||||
# Configure.xml must be in the explicit build dir, not in ${sourceDir}/build.
|
||||
file(GLOB configure_xml_file
|
||||
"${RunCMake_TEST_BINARY_DIR}/Testing/*/Configure.xml")
|
||||
if(NOT configure_xml_file)
|
||||
set(RunCMake_TEST_FAILED
|
||||
"Configure.xml not found in explicit --build-dir (${RunCMake_TEST_BINARY_DIR})")
|
||||
endif()
|
||||
|
||||
if(IS_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}/build")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"Preset binaryDir (${RunCMake_TEST_SOURCE_DIR}/build) was created")
|
||||
endif()
|
||||
@@ -0,0 +1,23 @@
|
||||
# The preset's binaryDir is "${sourceDir}/build", so Testing/ should be
|
||||
# written there, not in the working directory used to invoke ctest.
|
||||
file(GLOB configure_xml_file
|
||||
"${RunCMake_TEST_SOURCE_DIR}/build/Testing/*/Configure.xml")
|
||||
if(configure_xml_file)
|
||||
file(READ "${configure_xml_file}" configure_xml)
|
||||
if(NOT configure_xml MATCHES "\"--preset\" \"my-preset\"")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"Configure.xml does not contain the expected --preset argument")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Configure.xml not found in preset binaryDir")
|
||||
endif()
|
||||
|
||||
set(cmakecache_file "${RunCMake_TEST_SOURCE_DIR}/build/CMakeCache.txt")
|
||||
if(EXISTS "${cmakecache_file}")
|
||||
file(READ "${cmakecache_file}" cmakecache_txt)
|
||||
if(NOT cmakecache_txt MATCHES "MY_CUSTOM_VAR:STRING=this-gets-set")
|
||||
set(RunCMake_TEST_FAILED "CMakeCache.txt does not contain MY_CUSTOM_VAR")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "CMakeCache.txt not found in preset binaryDir")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
^Cannot find file: .*/DartConfiguration\.tcl$
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1,2 @@
|
||||
^Cannot find file: .*/DartConfiguration\.tcl
|
||||
No such configure preset in .*: "nonexistent-preset"$
|
||||
@@ -714,6 +714,76 @@ function(run_configure_no_cmakelists)
|
||||
endfunction()
|
||||
run_configure_no_cmakelists()
|
||||
|
||||
# Helper for tests that invoke ctest -M/-T Configure with -D CTEST_PRESET.
|
||||
# Options:
|
||||
# SOURCE_DIR -- pass --source-dir to ctest
|
||||
# BUILD_DIR -- create a separate <CASE_NAME>-build dir with
|
||||
# DartConfiguration.tcl and pass --build-dir to ctest
|
||||
function(run_ctest_configure_cli_preset CASE_NAME)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 ARG "SOURCE_DIR;BUILD_DIR;BAD_PRESETS" "PRESET_NAME" "")
|
||||
set(src "${RunCMake_BINARY_DIR}/${CASE_NAME}")
|
||||
set(bin "${src}")
|
||||
if(ARG_BUILD_DIR)
|
||||
set(bin "${RunCMake_BINARY_DIR}/${CASE_NAME}-build")
|
||||
endif()
|
||||
set(preset_name "my-preset")
|
||||
if(ARG_PRESET_NAME)
|
||||
set(preset_name "${ARG_PRESET_NAME}")
|
||||
endif()
|
||||
configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in"
|
||||
"${src}/CMakeLists.txt" @ONLY)
|
||||
if(ARG_BAD_PRESETS)
|
||||
configure_file("${RunCMake_SOURCE_DIR}/BadCMakePresets.json.in"
|
||||
"${src}/CMakePresets.json" @ONLY)
|
||||
else()
|
||||
configure_file("${RunCMake_SOURCE_DIR}/CMakePresets.json.in"
|
||||
"${src}/CMakePresets.json" @ONLY)
|
||||
endif()
|
||||
file(REMOVE_RECURSE "${src}/build")
|
||||
if(ARG_BUILD_DIR)
|
||||
file(REMOVE_RECURSE "${bin}")
|
||||
file(MAKE_DIRECTORY "${bin}")
|
||||
file(WRITE "${bin}/DartConfiguration.tcl"
|
||||
"BuildDirectory: ${bin}\n"
|
||||
"SourceDirectory: ${src}\n"
|
||||
"ConfigureCommand: \"${CMAKE_COMMAND}\" -S\"${src}\" -B\"${bin}\"\n")
|
||||
endif()
|
||||
set(extra_args "")
|
||||
if(ARG_SOURCE_DIR)
|
||||
list(APPEND extra_args --source-dir "${src}")
|
||||
endif()
|
||||
if(ARG_BUILD_DIR)
|
||||
list(APPEND extra_args --build-dir "${bin}")
|
||||
endif()
|
||||
set(RunCMake_TEST_SOURCE_DIR "${src}")
|
||||
set(RunCMake_TEST_BINARY_DIR "${bin}")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${CASE_NAME}
|
||||
${CMAKE_CTEST_COMMAND}
|
||||
${extra_args}
|
||||
-M Experimental
|
||||
-D "CTEST_PRESET=${preset_name}"
|
||||
-T Configure
|
||||
-V)
|
||||
endfunction()
|
||||
|
||||
# CTEST_PRESET via -D reaches ctest_configure() when run with -M/-T.
|
||||
run_ctest_configure_cli_preset(ConfigurePresetCLIVar BUILD_DIR)
|
||||
|
||||
# --source-dir + -D CTEST_PRESET picks up the preset's binaryDir when no
|
||||
# DartConfiguration.tcl / explicit --build-dir is provided.
|
||||
run_ctest_configure_cli_preset(ConfigurePresetCLIVarSourceDir SOURCE_DIR)
|
||||
|
||||
# An explicit --build-dir takes precedence over the preset's binaryDir.
|
||||
run_ctest_configure_cli_preset(ConfigurePresetCLIVarBuildDirOverride SOURCE_DIR BUILD_DIR)
|
||||
|
||||
# A malformed presets file is an error.
|
||||
run_ctest_configure_cli_preset(ConfigurePresetCLIVarBadPresets SOURCE_DIR BAD_PRESETS)
|
||||
|
||||
# Referencing a preset that does not exist is an error.
|
||||
run_ctest_configure_cli_preset(ConfigurePresetCLIVarUnknownPreset SOURCE_DIR
|
||||
PRESET_NAME nonexistent-preset)
|
||||
|
||||
# Test --output-junit
|
||||
function(run_output_junit)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/output-junit)
|
||||
|
||||
@@ -56,36 +56,3 @@ run_ctest(ConfigurePresetFromFileVar)
|
||||
unset(CASE_TEST_PREFIX_CODE)
|
||||
unset(custom_presets_file)
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
|
||||
# Verify that CTEST_PRESET passed via -D on the command line reaches
|
||||
# ctest_configure() when ctest is run with -M/-T.
|
||||
set(case_source_dir "${RunCMake_BINARY_DIR}/ConfigurePresetCLIVar")
|
||||
set(case_binary_dir "${RunCMake_BINARY_DIR}/ConfigurePresetCLIVar-build")
|
||||
set(CASE_NAME "ConfigurePresetCLIVar")
|
||||
file(MAKE_DIRECTORY "${case_source_dir}")
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt.in"
|
||||
"${case_source_dir}/CMakeLists.txt"
|
||||
@ONLY)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakePresets.json.in"
|
||||
"${case_source_dir}/CMakePresets.json"
|
||||
@ONLY)
|
||||
file(REMOVE_RECURSE "${case_binary_dir}")
|
||||
file(MAKE_DIRECTORY "${case_binary_dir}")
|
||||
file(WRITE "${case_binary_dir}/DartConfiguration.tcl"
|
||||
"BuildDirectory: ${case_binary_dir}\n"
|
||||
"SourceDirectory: ${case_source_dir}\n"
|
||||
"ConfigureCommand: \"${CMAKE_COMMAND}\" -S\"${case_source_dir}\" -B\"${case_binary_dir}\"\n")
|
||||
set(RunCMake_TEST_SOURCE_DIR "${case_source_dir}")
|
||||
set(RunCMake_TEST_BINARY_DIR "${case_binary_dir}")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(ConfigurePresetCLIVar
|
||||
${CMAKE_CTEST_COMMAND}
|
||||
-M Experimental
|
||||
-D "CTEST_PRESET=my-preset"
|
||||
-T Configure
|
||||
-V)
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
|
||||
Reference in New Issue
Block a user