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
This commit is contained in:
parent
0cf84472d7
commit
f2e0a18761
|
@ -410,6 +410,8 @@ bool cmFindPackageCommand
|
||||||
this->Name = args[0];
|
this->Name = args[0];
|
||||||
std::string components;
|
std::string components;
|
||||||
const char* components_sep = "";
|
const char* components_sep = "";
|
||||||
|
std::set<std::string> requiredComponents;
|
||||||
|
std::set<std::string> optionalComponents;
|
||||||
|
|
||||||
// Check ancient compatibility.
|
// Check ancient compatibility.
|
||||||
this->Compatibility_1_6 =
|
this->Compatibility_1_6 =
|
||||||
|
@ -420,8 +422,8 @@ bool cmFindPackageCommand
|
||||||
this->SearchPathSuffixes.push_back("");
|
this->SearchPathSuffixes.push_back("");
|
||||||
|
|
||||||
// Parse the arguments.
|
// Parse the arguments.
|
||||||
enum Doing { DoingNone, DoingComponents, DoingNames, DoingPaths,
|
enum Doing { DoingNone, DoingComponents, DoingOptionalComponents, DoingNames,
|
||||||
DoingPathSuffixes, DoingConfigs, DoingHints };
|
DoingPaths, DoingPathSuffixes, DoingConfigs, DoingHints };
|
||||||
Doing doing = DoingNone;
|
Doing doing = DoingNone;
|
||||||
cmsys::RegularExpression version("^[0-9.]+$");
|
cmsys::RegularExpression version("^[0-9.]+$");
|
||||||
bool haveVersion = false;
|
bool haveVersion = false;
|
||||||
|
@ -465,6 +467,11 @@ bool cmFindPackageCommand
|
||||||
this->Compatibility_1_6 = false;
|
this->Compatibility_1_6 = false;
|
||||||
doing = DoingComponents;
|
doing = DoingComponents;
|
||||||
}
|
}
|
||||||
|
else if(args[i] == "OPTIONAL_COMPONENTS")
|
||||||
|
{
|
||||||
|
this->Compatibility_1_6 = false;
|
||||||
|
doing = DoingOptionalComponents;
|
||||||
|
}
|
||||||
else if(args[i] == "NAMES")
|
else if(args[i] == "NAMES")
|
||||||
{
|
{
|
||||||
configArgs.insert(i);
|
configArgs.insert(i);
|
||||||
|
@ -528,12 +535,23 @@ bool cmFindPackageCommand
|
||||||
this->Compatibility_1_6 = false;
|
this->Compatibility_1_6 = false;
|
||||||
doing = DoingNone;
|
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.
|
// 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];
|
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.
|
// Append to the list of required components.
|
||||||
components += components_sep;
|
components += components_sep;
|
||||||
|
@ -584,6 +602,22 @@ bool cmFindPackageCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> 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; i<doubledComponents.size(); ++i)
|
||||||
|
{
|
||||||
|
e << " " << doubledComponents[i] << "\n";
|
||||||
|
}
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Maybe choose one mode exclusively.
|
// Maybe choose one mode exclusively.
|
||||||
this->UseFindModules = configArgs.empty();
|
this->UseFindModules = configArgs.empty();
|
||||||
this->UseConfigFiles = moduleArgs.empty();
|
this->UseConfigFiles = moduleArgs.empty();
|
||||||
|
|
Loading…
Reference in New Issue