summaryrefslogtreecommitdiffstats
path: root/Source/cmFindPackageCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2022-05-25 11:24:40 (GMT)
committerKitware Robot <kwrobot@kitware.com>2022-05-25 11:24:48 (GMT)
commit5dcf505f63037e23094146730704b031c57c5d06 (patch)
treeb9921b81b3741cad9d1ce13a5a5a0b69fed4d678 /Source/cmFindPackageCommand.cxx
parent7120221e2464f3ee0f4d511783a78d0d83e9cb03 (diff)
parent2aa83fa15b01941f0267e20a1a4e29793651fefd (diff)
downloadCMake-5dcf505f63037e23094146730704b031c57c5d06.zip
CMake-5dcf505f63037e23094146730704b031c57c5d06.tar.gz
CMake-5dcf505f63037e23094146730704b031c57c5d06.tar.bz2
Merge topic 'dependency-providers'
2aa83fa15b Dependency providers: Add find_package and FetchContent support 8a28368feb FetchContent: Don't discard non-empty SOURCE_DIR and BINARY_DIR 8ce9bb8a0c FetchContent: Don't leak internal variables 74a6ddc339 cmFindPackageCommand: Handle Makefile variable definitions more robustly Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Gerhard Olsson <gerhard.nospam@gmail.com> Merge-request: !7276
Diffstat (limited to 'Source/cmFindPackageCommand.cxx')
-rw-r--r--Source/cmFindPackageCommand.cxx75
1 files changed, 64 insertions, 11 deletions
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 6586c69..e41d5e4 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -23,6 +23,7 @@
#include "cmsys/String.h"
#include "cmAlgorithms.h"
+#include "cmDependencyProvider.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -238,6 +239,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
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;
// Always search directly in a generated path.
this->SearchPathSuffixes.emplace_back();
@@ -268,6 +271,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
if (args[i] == "QUIET") {
this->Quiet = true;
doing = DoingNone;
+ } else if (args[i] == "BYPASS_PROVIDER") {
+ bypassProvider = true;
+ doing = DoingNone;
} else if (args[i] == "EXACT") {
this->VersionExact = true;
doing = DoingNone;
@@ -356,7 +362,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
- this->AddFindDefinition(req_var, isRequired);
+ componentVarDefs.emplace_back(req_var, isRequired);
// Append to the list of required components.
components += components_sep;
@@ -408,7 +414,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
- // Maybe choose one mode exclusively.
+ // Check and eliminate search modes not allowed by the args provided
this->UseFindModules = configArgs.empty();
this->UseConfigFiles = moduleArgs.empty();
if (!this->UseFindModules && !this->UseConfigFiles) {
@@ -543,6 +549,48 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return true;
}
+ // Now choose what method(s) we will use to satisfy the request. Note that
+ // we still want all the above checking of arguments, etc. regardless of the
+ // method used. This will ensure ill-formed arguments are caught earlier,
+ // before things like dependency providers need to deal with them.
+
+ // A dependency provider (if set) gets first look before other methods.
+ // We do this before modifying the package root path stack because a
+ // provider might use methods that ignore that.
+ cmState* state = this->Makefile->GetState();
+ cmState::Command providerCommand = state->GetDependencyProviderCommand(
+ cmDependencyProvider::Method::FindPackage);
+ if (bypassProvider) {
+ if (this->DebugMode && providerCommand) {
+ this->DebugMessage(
+ "BYPASS_PROVIDER given, skipping dependency provider");
+ }
+ } else if (providerCommand) {
+ if (this->DebugMode) {
+ this->DebugMessage(cmStrCat("Trying dependency provider command: ",
+ state->GetDependencyProvider()->GetCommand(),
+ "()"));
+ }
+ std::vector<cmListFileArgument> listFileArgs(args.size() + 1);
+ listFileArgs[0] =
+ cmListFileArgument("FIND_PACKAGE", cmListFileArgument::Unquoted, 0);
+ std::transform(args.begin(), args.end(), listFileArgs.begin() + 1,
+ [](const std::string& arg) {
+ return cmListFileArgument(arg,
+ cmListFileArgument::Bracket, 0);
+ });
+ if (!providerCommand(listFileArgs, this->Status)) {
+ return false;
+ }
+ if (this->Makefile->IsOn(cmStrCat(this->Name, "_FOUND"))) {
+ if (this->DebugMode) {
+ this->DebugMessage("Package was found by the dependency provider");
+ }
+ this->AppendSuccessInformation();
+ return true;
+ }
+ }
+
{
// Allocate a PACKAGE_ROOT_PATH for the current find_package call.
this->Makefile->FindPackageRootPathStack.emplace_back();
@@ -573,7 +621,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
}
- this->SetModuleVariables(components);
+ this->SetModuleVariables(components, componentVarDefs);
// See if we have been told to delegate to FetchContent or some other
// redirected config package first. We have to check all names that
@@ -697,6 +745,12 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->AppendSuccessInformation();
+ // Restore original state of "_FIND_" variables set in SetModuleVariables()
+ this->RestoreFindDefinitions();
+
+ // Pop the package stack
+ this->Makefile->FindPackageRootPathStack.pop_back();
+
if (!this->DebugBuffer.empty()) {
this->DebugMessage(this->DebugBuffer);
}
@@ -778,13 +832,18 @@ void cmFindPackageCommand::SetVersionVariables(
addDefinition(prefix + "_COUNT", buf);
}
-void cmFindPackageCommand::SetModuleVariables(const std::string& components)
+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);
- // Store the list of components.
+ // Store the list of components and associated variable definitions
std::string components_var = this->Name + "_FIND_COMPONENTS";
this->AddFindDefinition(components_var, components);
+ for (const auto& varDef : componentVarDefs) {
+ this->AddFindDefinition(varDef.first, varDef.second);
+ }
if (this->Quiet) {
// Tell the module that is about to be read that it should find
@@ -1388,12 +1447,6 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName,
"REQUIRED");
}
-
- // Restore original state of "_FIND_" variables we set.
- this->RestoreFindDefinitions();
-
- // Pop the package stack
- this->Makefile->FindPackageRootPathStack.pop_back();
}
inline std::size_t collectPathsForDebug(std::string& buffer,