discover_tests: Add CMake command implementation

This commit is contained in:
Daniel Pfeifer authored and Brad King committed 2026-03-26 10:36:21 -04:00
1 parent 3f1fce6b48
commit 3947842733
5 files changed
+135

No files matched your search

+2
View File
@@ -611,6 +611,8 @@ add_library(
cmCreateTestSourceList.h
cmDefinePropertyCommand.cxx
cmDefinePropertyCommand.h
cmDiscoverTestsCommand.cxx
cmDiscoverTestsCommand.h
cmEnableLanguageCommand.cxx
cmEnableLanguageCommand.h
cmEnableTestingCommand.cxx
+2
View File
@@ -26,6 +26,7 @@
#include "cmContinueCommand.h"
#include "cmCreateTestSourceList.h"
#include "cmDefinePropertyCommand.h"
#include "cmDiscoverTestsCommand.h"
#include "cmEnableLanguageCommand.h"
#include "cmEnableTestingCommand.h"
#include "cmExecProgramCommand.h"
@@ -239,6 +240,7 @@ void GetProjectCommands(cmState* state)
state->AddBuiltinCommand("build_command", cmBuildCommand);
state->AddBuiltinCommand("create_test_sourcelist", cmCreateTestSourceList);
state->AddBuiltinCommand("define_property", cmDefinePropertyCommand);
state->AddBuiltinCommand("discover_tests", cmDiscoverTestsCommand);
state->AddBuiltinCommand("enable_language", cmEnableLanguageCommand);
state->AddBuiltinCommand("enable_testing", cmEnableTestingCommand);
state->AddBuiltinCommand("get_source_file_property",
+117
View File
@@ -0,0 +1,117 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmDiscoverTestsCommand.h"
#include <cstddef>
#include <ostream>
#include <utility>
#include <vector>
#include <cm/memory>
#include <cmext/string_view>
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmScriptGenerator.h"
#include "cmTestDiscovery.h"
#include "cmTestGenerator.h"
namespace {
struct Arguments : cmTestDiscoveryArgs
{
bool CommandExpandLists = false;
ArgumentParser::MaybeEmpty<std::vector<std::string>> Configurations;
};
class DiscoveryGenerator : public cmTestGenerator
{
public:
DiscoveryGenerator(Arguments arguments, cmListFileBacktrace backtrace)
: cmTestGenerator(nullptr, arguments.Configurations)
, Args{ std::move(arguments) }
, Backtrace{ std::move(backtrace) }
{
}
private:
void GenerateProperties(std::ostream& os, Indent indent,
std::vector<std::string> const& props,
std::string const& config, cmGeneratorExpression& ge)
{
for (std::size_t i = 0; i < props.size(); i += 2) {
os << '\n'
<< indent << Quote(props[i]) << ' '
<< Quote(ge.Parse(props[i + 1])->Evaluate(this->LG, config));
}
}
void GenerateScriptForConfig(std::ostream& os, std::string const& config,
Indent indent) override
{
// Set up generator expression evaluation context.
cmGeneratorExpression ge(*this->LG->GetMakefile()->GetCMakeInstance(),
this->Backtrace);
auto const in = indent.Next();
os << indent << "discover_tests(COMMAND ";
this->GenerateCommand(os, this->Args.Command, config,
this->Args.CommandExpandLists, ge);
os << '\n' << in << "DISCOVERY_ARGS";
for (auto const& arg : this->Args.DiscoveryArgs) {
os << ' ' << Quote(arg);
}
os << '\n' << in << "DISCOVERY_MATCH " << Quote(this->Args.DiscoveryMatch);
if (!this->Args.DiscoveryProperties.empty()) {
os << '\n' << in << "DISCOVERY_PROPERTIES";
this->GenerateProperties(os, in.Next(), this->Args.DiscoveryProperties,
config, ge);
}
os << '\n' << in << "TEST_NAME " << Quote(this->Args.TestName);
os << '\n' << in << "TEST_ARGS";
for (auto const& arg : this->Args.TestArgs) {
os << ' ' << Quote(arg);
}
os << '\n' << in << "TEST_PROPERTIES";
this->GenerateProperties(os, in.Next(), this->Args.TestProperties, config,
ge);
os << '\n' << in.Next();
this->GenerateBacktrace(os, this->Backtrace);
os << '\n' << in << ")\n";
}
Arguments Args;
cmListFileBacktrace Backtrace;
};
} // namespace
bool cmDiscoverTestsCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
static auto const parser =
cmArgumentParser<Arguments>{ cmTestDiscoveryParser<Arguments>() }
.Bind("COMMAND_EXPAND_LISTS"_s, &Arguments::CommandExpandLists)
.Bind("CONFIGURATIONS"_s, &Arguments::Configurations);
auto unparsed = std::vector<std::string>{};
Arguments arguments = parser.Parse(args, &unparsed);
if (arguments.MaybeReportError(status.GetMakefile())) {
return true;
}
if (!unparsed.empty()) {
status.SetError(" given unknown argument \"" + unparsed.front() + "\".");
return false;
}
cmMakefile& mf = status.GetMakefile();
mf.AddTestGenerator(cm::make_unique<DiscoveryGenerator>(std::move(arguments),
mf.GetBacktrace()));
return true;
}
+13
View File
@@ -0,0 +1,13 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
#include <vector>
class cmExecutionStatus;
bool cmDiscoverTestsCommand(std::vector<std::string> const& args,
cmExecutionStatus& status);
+1
View File
@@ -338,6 +338,7 @@ CMAKE_CXX_SOURCES="\
cmDefinePropertyCommand \
cmDefinitions \
cmDiagnostics \
cmDiscoverTestsCommand \
cmDocumentationFormatter \
cmELF \
cmEnableLanguageCommand \