diff options
author | Brad King <brad.king@kitware.com> | 2022-05-25 11:24:40 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2022-05-25 11:24:48 (GMT) |
commit | 5dcf505f63037e23094146730704b031c57c5d06 (patch) | |
tree | b9921b81b3741cad9d1ce13a5a5a0b69fed4d678 /Source/cmFindPackageCommand.cxx | |
parent | 7120221e2464f3ee0f4d511783a78d0d83e9cb03 (diff) | |
parent | 2aa83fa15b01941f0267e20a1a4e29793651fefd (diff) | |
download | CMake-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.cxx | 75 |
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, |