From f2e0a18761a7b0aa16b7f22e82481aed7b160f58 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 18 Mar 2012 12:41:28 +0100 Subject: find_package: add OPTIONAL_COMPONENTS keyword Add an OPTIONAL_COMPONENTS keyword to find_package() so we can have a clear distinction between required and optional components. Don't allow a component to be both required and optional. Alex --- Source/cmFindPackageCommand.cxx | 44 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 3541ca3..b9872e9 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -410,6 +410,8 @@ bool cmFindPackageCommand this->Name = args[0]; std::string components; const char* components_sep = ""; + std::set requiredComponents; + std::set optionalComponents; // Check ancient compatibility. this->Compatibility_1_6 = @@ -420,8 +422,8 @@ bool cmFindPackageCommand this->SearchPathSuffixes.push_back(""); // Parse the arguments. - enum Doing { DoingNone, DoingComponents, DoingNames, DoingPaths, - DoingPathSuffixes, DoingConfigs, DoingHints }; + enum Doing { DoingNone, DoingComponents, DoingOptionalComponents, DoingNames, + DoingPaths, DoingPathSuffixes, DoingConfigs, DoingHints }; Doing doing = DoingNone; cmsys::RegularExpression version("^[0-9.]+$"); bool haveVersion = false; @@ -465,6 +467,11 @@ bool cmFindPackageCommand this->Compatibility_1_6 = false; doing = DoingComponents; } + else if(args[i] == "OPTIONAL_COMPONENTS") + { + this->Compatibility_1_6 = false; + doing = DoingOptionalComponents; + } else if(args[i] == "NAMES") { configArgs.insert(i); @@ -528,12 +535,23 @@ bool cmFindPackageCommand this->Compatibility_1_6 = false; doing = DoingNone; } - else if(doing == DoingComponents) + else if((doing == DoingComponents) || (doing == DoingOptionalComponents)) { - // Set a variable telling the find script this component + // Set a variable telling the find script whether this component // is required. + const char* isRequired = "1"; + if (doing == DoingOptionalComponents) + { + isRequired = "0"; + optionalComponents.insert(args[i]); + } + else + { + requiredComponents.insert(args[i]); + } + std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i]; - this->AddFindDefinition(req_var.c_str(), "1"); + this->AddFindDefinition(req_var.c_str(), isRequired); // Append to the list of required components. components += components_sep; @@ -584,6 +602,22 @@ bool cmFindPackageCommand } } + std::vector doubledComponents; + std::set_intersection(requiredComponents.begin(), requiredComponents.end(), + optionalComponents.begin(), optionalComponents.end(), + std::back_inserter(doubledComponents)); + if(!doubledComponents.empty()) + { + cmOStringStream e; + e << "called with components that are both required and optional:\n"; + for(unsigned int i=0; iSetError(e.str().c_str()); + return false; + } + // Maybe choose one mode exclusively. this->UseFindModules = configArgs.empty(); this->UseConfigFiles = moduleArgs.empty(); -- cgit v0.12