mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-15 03:48:02 +08:00
find_package: Refactor in support of recursion
Separate argument handling and actual operation of the find_package command into separate methods. This is preparatory to adding improved support for transitive dependencies and will allow nested calls to be set up using structured data types, rather than having to perform all communication via a constructed argument list. As a consequence, the sets of required and optional components, as well as the component list string, are now members rather than local variables. This also allows us to drop some parameters and simplify how we set the variables indicating which components are required.
This commit is contained in:
@@ -468,12 +468,10 @@ class cmFindPackageCommand::SetRestoreFindDefinitions
|
|||||||
cmFindPackageCommand& Command;
|
cmFindPackageCommand& Command;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SetRestoreFindDefinitions(
|
SetRestoreFindDefinitions(cmFindPackageCommand& command)
|
||||||
cmFindPackageCommand& command, const std::string& components,
|
|
||||||
const std::vector<std::pair<std::string, const char*>>& componentVarDefs)
|
|
||||||
: Command(command)
|
: Command(command)
|
||||||
{
|
{
|
||||||
Command.SetModuleVariables(components, componentVarDefs);
|
Command.SetModuleVariables();
|
||||||
}
|
}
|
||||||
~SetRestoreFindDefinitions() { Command.RestoreFindDefinitions(); }
|
~SetRestoreFindDefinitions() { Command.RestoreFindDefinitions(); }
|
||||||
};
|
};
|
||||||
@@ -651,11 +649,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
|
|
||||||
// Record options.
|
// Record options.
|
||||||
this->Name = args[0];
|
this->Name = args[0];
|
||||||
std::string components;
|
cm::string_view componentsSep = ""_s;
|
||||||
const char* components_sep = "";
|
|
||||||
std::set<std::string> requiredComponents;
|
|
||||||
std::set<std::string> optionalComponents;
|
|
||||||
std::vector<std::pair<std::string, const char*>> componentVarDefs;
|
|
||||||
bool bypassProvider = false;
|
bool bypassProvider = false;
|
||||||
|
|
||||||
// Always search directly in a generated path.
|
// Always search directly in a generated path.
|
||||||
@@ -769,21 +763,16 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
(doing == DoingOptionalComponents)) {
|
(doing == DoingOptionalComponents)) {
|
||||||
// Set a variable telling the find script whether this component
|
// Set a variable telling the find script whether this component
|
||||||
// is required.
|
// is required.
|
||||||
const char* isRequired = "1";
|
|
||||||
if (doing == DoingOptionalComponents) {
|
if (doing == DoingOptionalComponents) {
|
||||||
isRequired = "0";
|
this->OptionalComponents.insert(args[i]);
|
||||||
optionalComponents.insert(args[i]);
|
|
||||||
} else {
|
} else {
|
||||||
requiredComponents.insert(args[i]);
|
this->RequiredComponents.insert(args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentVarDefs.emplace_back(this->Name + "_FIND_REQUIRED_" + args[i],
|
|
||||||
isRequired);
|
|
||||||
|
|
||||||
// Append to the list of required components.
|
// Append to the list of required components.
|
||||||
components += components_sep;
|
this->Components += componentsSep;
|
||||||
components += args[i];
|
this->Components += args[i];
|
||||||
components_sep = ";";
|
componentsSep = ";"_s;
|
||||||
} else if (doing == DoingNames) {
|
} else if (doing == DoingNames) {
|
||||||
this->Names.push_back(args[i]);
|
this->Names.push_back(args[i]);
|
||||||
} else if (doing == DoingPaths) {
|
} else if (doing == DoingPaths) {
|
||||||
@@ -819,9 +808,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> doubledComponents;
|
std::vector<std::string> doubledComponents;
|
||||||
std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
|
std::set_intersection(
|
||||||
optionalComponents.begin(), optionalComponents.end(),
|
this->RequiredComponents.begin(), this->RequiredComponents.end(),
|
||||||
std::back_inserter(doubledComponents));
|
this->OptionalComponents.begin(), this->OptionalComponents.end(),
|
||||||
|
std::back_inserter(doubledComponents));
|
||||||
if (!doubledComponents.empty()) {
|
if (!doubledComponents.empty()) {
|
||||||
this->SetError(
|
this->SetError(
|
||||||
cmStrCat("called with components that are both required and "
|
cmStrCat("called with components that are both required and "
|
||||||
@@ -856,7 +846,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
"Ignoring EXACT since no version is requested.");
|
"Ignoring EXACT since no version is requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->VersionComplete.empty() || components.empty()) {
|
if (this->VersionComplete.empty() || this->Components.empty()) {
|
||||||
// Check whether we are recursing inside "Find<name>.cmake" within
|
// Check whether we are recursing inside "Find<name>.cmake" within
|
||||||
// another find_package(<name>) call.
|
// another find_package(<name>) call.
|
||||||
std::string const mod = cmStrCat(this->Name, "_FIND_MODULE");
|
std::string const mod = cmStrCat(this->Name, "_FIND_MODULE");
|
||||||
@@ -871,9 +861,12 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
std::string const exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
|
std::string const exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
|
||||||
this->VersionExact = this->Makefile->IsOn(exact);
|
this->VersionExact = this->Makefile->IsOn(exact);
|
||||||
}
|
}
|
||||||
if (components.empty()) {
|
if (this->Components.empty()) {
|
||||||
std::string const components_var = this->Name + "_FIND_COMPONENTS";
|
std::string const components_var = this->Name + "_FIND_COMPONENTS";
|
||||||
components = this->Makefile->GetSafeDefinition(components_var);
|
this->Components = this->Makefile->GetSafeDefinition(components_var);
|
||||||
|
for (auto const& component : cmList{ this->Components }) {
|
||||||
|
this->RequiredComponents.insert(component);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -924,6 +917,12 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
this->VersionMaxPatch, this->VersionMaxTweak);
|
this->VersionMaxPatch, this->VersionMaxTweak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this->FindPackage(bypassProvider ? std::vector<std::string>{} : args);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmFindPackageCommand::FindPackage(
|
||||||
|
std::vector<std::string> const& argsForProvider)
|
||||||
|
{
|
||||||
const std::string makePackageRequiredVar =
|
const std::string makePackageRequiredVar =
|
||||||
cmStrCat("CMAKE_REQUIRE_FIND_PACKAGE_", this->Name);
|
cmStrCat("CMAKE_REQUIRE_FIND_PACKAGE_", this->Name);
|
||||||
const bool makePackageRequiredSet =
|
const bool makePackageRequiredSet =
|
||||||
@@ -997,7 +996,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
cmState* const state = this->Makefile->GetState();
|
cmState* const state = this->Makefile->GetState();
|
||||||
cmState::Command const providerCommand = state->GetDependencyProviderCommand(
|
cmState::Command const providerCommand = state->GetDependencyProviderCommand(
|
||||||
cmDependencyProvider::Method::FindPackage);
|
cmDependencyProvider::Method::FindPackage);
|
||||||
if (bypassProvider) {
|
if (argsForProvider.empty()) {
|
||||||
if (this->DebugMode && providerCommand) {
|
if (this->DebugMode && providerCommand) {
|
||||||
this->DebugMessage(
|
this->DebugMessage(
|
||||||
"BYPASS_PROVIDER given, skipping dependency provider");
|
"BYPASS_PROVIDER given, skipping dependency provider");
|
||||||
@@ -1008,11 +1007,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
state->GetDependencyProvider()->GetCommand(),
|
state->GetDependencyProvider()->GetCommand(),
|
||||||
"()"));
|
"()"));
|
||||||
}
|
}
|
||||||
std::vector<cmListFileArgument> listFileArgs(args.size() + 1);
|
std::vector<cmListFileArgument> listFileArgs(argsForProvider.size() + 1);
|
||||||
listFileArgs[0] =
|
listFileArgs[0] =
|
||||||
cmListFileArgument("FIND_PACKAGE", cmListFileArgument::Unquoted, 0);
|
cmListFileArgument("FIND_PACKAGE", cmListFileArgument::Unquoted, 0);
|
||||||
std::transform(args.begin(), args.end(), listFileArgs.begin() + 1,
|
std::transform(argsForProvider.begin(), argsForProvider.end(),
|
||||||
[](const std::string& arg) {
|
listFileArgs.begin() + 1, [](const std::string& arg) {
|
||||||
return cmListFileArgument(arg,
|
return cmListFileArgument(arg,
|
||||||
cmListFileArgument::Bracket, 0);
|
cmListFileArgument::Bracket, 0);
|
||||||
});
|
});
|
||||||
@@ -1043,11 +1042,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RAII objects to ensure we leave this function with consistent state
|
// RAII objects to ensure we leave this function with consistent state.
|
||||||
FlushDebugBufferOnExit flushDebugBufferOnExit(*this);
|
FlushDebugBufferOnExit flushDebugBufferOnExit(*this);
|
||||||
PushPopRootPathStack pushPopRootPathStack(*this);
|
PushPopRootPathStack pushPopRootPathStack(*this);
|
||||||
SetRestoreFindDefinitions setRestoreFindDefinitions(*this, components,
|
SetRestoreFindDefinitions setRestoreFindDefinitions(*this);
|
||||||
componentVarDefs);
|
|
||||||
cmMakefile::FindPackageStackRAII findPackageStackRAII(this->Makefile,
|
cmMakefile::FindPackageStackRAII findPackageStackRAII(this->Makefile,
|
||||||
this->Name);
|
this->Name);
|
||||||
|
|
||||||
@@ -1247,17 +1245,20 @@ void cmFindPackageCommand::SetVersionVariables(
|
|||||||
addDefinition(prefix + "_COUNT", buf);
|
addDefinition(prefix + "_COUNT", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmFindPackageCommand::SetModuleVariables(
|
void cmFindPackageCommand::SetModuleVariables()
|
||||||
const std::string& components,
|
|
||||||
const std::vector<std::pair<std::string, const char*>>& componentVarDefs)
|
|
||||||
{
|
{
|
||||||
this->AddFindDefinition("CMAKE_FIND_PACKAGE_NAME", this->Name);
|
this->AddFindDefinition("CMAKE_FIND_PACKAGE_NAME", this->Name);
|
||||||
|
|
||||||
// Store the list of components and associated variable definitions
|
// Store the list of components and associated variable definitions.
|
||||||
std::string components_var = this->Name + "_FIND_COMPONENTS";
|
std::string components_var = this->Name + "_FIND_COMPONENTS";
|
||||||
this->AddFindDefinition(components_var, components);
|
this->AddFindDefinition(components_var, this->Components);
|
||||||
for (const auto& varDef : componentVarDefs) {
|
for (auto const& component : this->OptionalComponents) {
|
||||||
this->AddFindDefinition(varDef.first, varDef.second);
|
this->AddFindDefinition(
|
||||||
|
cmStrCat(this->Name, "_FIND_REQUIRED_"_s, component), "0"_s);
|
||||||
|
}
|
||||||
|
for (auto const& component : this->RequiredComponents) {
|
||||||
|
this->AddFindDefinition(
|
||||||
|
cmStrCat(this->Name, "_FIND_REQUIRED_"_s, component), "1"_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->Quiet) {
|
if (this->Quiet) {
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cm/string_view>
|
#include <cm/string_view>
|
||||||
@@ -83,6 +82,11 @@ private:
|
|||||||
static PathLabel SystemRegistry;
|
static PathLabel SystemRegistry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Try to find a package, assuming most state has already been set up. This
|
||||||
|
// is used for recursive dependency solving, particularly when importing
|
||||||
|
// packages via CPS. Bypasses providers if argsForProvider is empty.
|
||||||
|
bool FindPackage(std::vector<std::string> const& argsForProvider);
|
||||||
|
|
||||||
bool FindPackageUsingModuleMode();
|
bool FindPackageUsingModuleMode();
|
||||||
bool FindPackageUsingConfigMode();
|
bool FindPackageUsingConfigMode();
|
||||||
|
|
||||||
@@ -98,9 +102,7 @@ private:
|
|||||||
const std::string& prefix, const std::string& version, unsigned int count,
|
const std::string& prefix, const std::string& version, unsigned int count,
|
||||||
unsigned int major, unsigned int minor, unsigned int patch,
|
unsigned int major, unsigned int minor, unsigned int patch,
|
||||||
unsigned int tweak);
|
unsigned int tweak);
|
||||||
void SetModuleVariables(
|
void SetModuleVariables();
|
||||||
const std::string& components,
|
|
||||||
const std::vector<std::pair<std::string, const char*>>& componentVarDefs);
|
|
||||||
bool FindModule(bool& found);
|
bool FindModule(bool& found);
|
||||||
void AddFindDefinition(const std::string& var, cm::string_view value);
|
void AddFindDefinition(const std::string& var, cm::string_view value);
|
||||||
void RestoreFindDefinitions();
|
void RestoreFindDefinitions();
|
||||||
@@ -216,6 +218,9 @@ private:
|
|||||||
std::vector<std::string> Configs;
|
std::vector<std::string> Configs;
|
||||||
std::set<std::string> IgnoredPaths;
|
std::set<std::string> IgnoredPaths;
|
||||||
std::set<std::string> IgnoredPrefixPaths;
|
std::set<std::string> IgnoredPrefixPaths;
|
||||||
|
std::string Components;
|
||||||
|
std::set<std::string> RequiredComponents;
|
||||||
|
std::set<std::string> OptionalComponents;
|
||||||
std::string DebugBuffer;
|
std::string DebugBuffer;
|
||||||
|
|
||||||
class FlushDebugBufferOnExit;
|
class FlushDebugBufferOnExit;
|
||||||
|
Reference in New Issue
Block a user