set_property(TEST): Add DIRECTORY option

This commit is contained in:
Kyle Edwards 2023-08-10 10:02:36 -04:00
parent 5ed03aa07a
commit 753999d4db
11 changed files with 145 additions and 8 deletions

View File

@ -12,7 +12,8 @@ Set a named property in a given scope.
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...] |
INSTALL [<file1> ...] |
TEST [<test1> ...] |
TEST [<test1> ...]
[DIRECTORY <dir>] |
CACHE [<entry1> ...] >
[APPEND] [APPEND_STRING]
PROPERTY <name> [<value1> ...])
@ -91,6 +92,17 @@ It must be one of the following:
:manual:`generator expressions <cmake-generator-expressions(7)>`
for tests created by the :command:`add_test(NAME)` signature.
.. versionadded:: 3.28
Visibility can be set in other directory scopes using the following sub-option:
``DIRECTORY <dir>``
The test property will be set in the ``<dir>`` directory's scope. CMake must
already know about this directory, either by having added it through a call
to :command:`add_subdirectory` or it being the top level source directory.
Relative paths are treated as relative to the current source directory.
``<dir>`` may reference a binary directory.
``CACHE``
Scope must name zero or more existing cache entries.

View File

@ -0,0 +1,6 @@
test-properties-directory
-------------------------
* The ``TEST`` mode of the :command:`set_property` command gained a
``DIRECTORY`` sub-option, which allows you to set properties on tests in
other directories.

View File

@ -58,7 +58,8 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove);
bool appendMode, bool remove,
cmMakefile* test_directory_makefile);
bool HandleTest(cmTest* test, const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove);
@ -184,6 +185,60 @@ bool HandleAndValidateSourceFileDirectoryScopes(
return scope_options_valid;
}
bool HandleTestDirectoryScopes(cmExecutionStatus& status,
std::string& test_directory,
cmMakefile*& directory_makefile)
{
cmMakefile* current_dir_mf = &status.GetMakefile();
if (!test_directory.empty()) {
const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
test_directory, current_dir_mf->GetCurrentSourceDirectory());
cmMakefile* dir_mf =
status.GetMakefile().GetGlobalGenerator()->FindMakefile(
absolute_dir_path);
if (!dir_mf) {
status.SetError(
cmStrCat("given non-existent DIRECTORY ", test_directory));
return false;
}
directory_makefile = dir_mf;
} else {
directory_makefile = current_dir_mf;
}
return true;
}
bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status,
bool test_directory_option_enabled,
std::string& test_directory)
{
// Validate source file directory scopes.
if (test_directory_option_enabled && test_directory.empty()) {
std::string errors = "called with incorrect number of arguments "
"no value provided to the DIRECTORY option";
status.SetError(errors);
return false;
}
return true;
}
bool HandleAndValidateTestDirectoryScopes(cmExecutionStatus& status,
bool test_directory_option_enabled,
std::string& test_directory,
cmMakefile*& test_directory_makefile)
{
bool scope_options_valid =
SetPropertyCommand::HandleTestDirectoryScopeValidation(
status, test_directory_option_enabled, test_directory);
if (!scope_options_valid) {
return false;
}
scope_options_valid = SetPropertyCommand::HandleTestDirectoryScopes(
status, test_directory, test_directory_makefile);
return scope_options_valid;
}
std::string MakeSourceFilePathAbsoluteIfNeeded(
cmExecutionStatus& status, const std::string& source_file_path,
const bool needed)
@ -352,6 +407,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
bool source_file_directory_option_enabled = false;
bool source_file_target_option_enabled = false;
std::string test_directory;
bool test_directory_option_enabled = false;
// Parse the rest of the arguments up to the values.
enum Doing
{
@ -360,7 +418,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
DoingProperty,
DoingValues,
DoingSourceDirectory,
DoingSourceTargetDirectory
DoingSourceTargetDirectory,
DoingTestDirectory,
};
Doing doing = DoingNames;
const char* sep = "";
@ -385,12 +444,19 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
scope == cmProperty::SOURCE_FILE && arg == "TARGET_DIRECTORY") {
doing = DoingSourceTargetDirectory;
source_file_target_option_enabled = true;
} else if (doing != DoingProperty && doing != DoingValues &&
scope == cmProperty::TEST && arg == "DIRECTORY") {
doing = DoingTestDirectory;
test_directory_option_enabled = true;
} else if (doing == DoingNames) {
names.insert(arg);
} else if (doing == DoingSourceDirectory) {
source_file_directories.push_back(arg);
} else if (doing == DoingSourceTargetDirectory) {
source_file_target_directories.push_back(arg);
} else if (doing == DoingTestDirectory) {
test_directory = arg;
doing = DoingNone;
} else if (doing == DoingProperty) {
propertyName = arg;
doing = DoingValues;
@ -412,12 +478,17 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
}
std::vector<cmMakefile*> source_file_directory_makefiles;
bool file_scopes_handled =
bool source_file_scopes_handled =
SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
if (!file_scopes_handled) {
cmMakefile* test_directory_makefile;
bool test_scopes_handled =
SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
status, test_directory_option_enabled, test_directory,
test_directory_makefile);
if (!(source_file_scopes_handled && test_scopes_handled)) {
return false;
}
bool source_file_paths_should_be_absolute =
@ -441,7 +512,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
source_file_paths_should_be_absolute);
case cmProperty::TEST:
return HandleTestMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
appendAsString, appendMode, remove,
test_directory_makefile);
case cmProperty::CACHE:
return HandleCacheMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
@ -642,14 +714,14 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove)
bool appendMode, bool remove, cmMakefile* test_makefile)
{
// Look for tests with all names given.
std::set<std::string>::iterator next;
for (auto ni = names.begin(); ni != names.end(); ni = next) {
next = ni;
++next;
if (cmTest* test = status.GetMakefile().GetTest(*ni)) {
if (cmTest* test = test_makefile->GetTest(*ni)) {
if (HandleTest(test, propertyName, propertyValue, appendAsString,
appendMode, remove)) {
names.erase(ni);

View File

@ -33,6 +33,18 @@ bool HandleAndValidateSourceFileDirectoryScopes(
std::vector<std::string>& source_target_directories,
std::vector<cmMakefile*>& source_file_directory_makefiles);
bool HandleTestDirectoryScopes(cmExecutionStatus& status,
std::string& test_directory,
cmMakefile*& directory_makefile);
bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status,
bool test_directory_option_enabled,
std::string& test_directory);
bool HandleAndValidateTestDirectoryScopes(
cmExecutionStatus& status, bool test_directory_option_encountered,
std::string& test_directory, cmMakefile*& test_directory_makefile);
std::string MakeSourceFilePathAbsoluteIfNeeded(
cmExecutionStatus& status, const std::string& source_file_path, bool needed);
void MakeSourceFilePathsAbsoluteIfNeeded(

View File

@ -10,6 +10,12 @@ run_cmake(LINK_DIRECTORIES)
run_cmake(LINK_LIBRARIES)
run_cmake(SOURCES)
run_cmake(SOURCE_FILE)
run_cmake(TEST-invalid)
run_cmake(TYPE)
run_cmake(USER_PROP)
run_cmake(USER_PROP_INHERITED)
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/TEST-build")
run_cmake(TEST)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(TEST-test ${CMAKE_CTEST_COMMAND} -C Debug)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,11 @@
^CMake Error at TEST-invalid\.cmake:[0-9]+ \(set_property\):
set_property called with incorrect number of arguments no value provided to
the DIRECTORY option
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
CMake Error at TEST-invalid\.cmake:[0-9]+ \(set_property\):
set_property given non-existent DIRECTORY nonexistent
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$

View File

@ -0,0 +1,4 @@
enable_testing()
set_property(TEST t DIRECTORY PROPERTY PASS_REGULAR_EXPRESSION "Invalid")
set_property(TEST t DIRECTORY nonexistent PROPERTY PASS_REGULAR_EXPRESSION "Invalid")

View File

@ -0,0 +1,3 @@
add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
add_test(NAME t2 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
add_test(NAME t3 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")

View File

@ -0,0 +1 @@
set_property(TEST t3 DIRECTORY ../TEST-subdir1 PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")

View File

@ -0,0 +1,9 @@
enable_testing()
add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Top directory")
add_subdirectory(TEST-subdir1)
add_subdirectory(TEST-subdir2)
set_property(TEST t PROPERTY PASS_REGULAR_EXPRESSION "Top directory")
set_property(TEST t DIRECTORY TEST-subdir1 PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")
set_property(TEST t2 DIRECTORY "${CMAKE_BINARY_DIR}/TEST-subdir1" PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")