summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorDavid Cole <david.cole@kitware.com>2012-03-21 17:26:46 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2012-03-21 17:26:46 (GMT)
commit349ea3f6e6db59a4c1d3a1a8ea6a25e3f55ab713 (patch)
treead7851b6dc3b60d4e17c34b06730df7caf3f7ab6 /Source
parent45b27021e56845934e996f44739b87e330346dc5 (diff)
parent6d100f9f469b48ad25a3958e2b4865a9d9d37523 (diff)
downloadCMake-349ea3f6e6db59a4c1d3a1a8ea6a25e3f55ab713.zip
CMake-349ea3f6e6db59a4c1d3a1a8ea6a25e3f55ab713.tar.gz
CMake-349ea3f6e6db59a4c1d3a1a8ea6a25e3f55ab713.tar.bz2
Merge topic 'ImprovedCOMPONENTSSupportInFindPackage2'
6d100f9 find_package: Test rejection of required+optional components d81d83c add macro check_required_components() to configure_package_config_file() b15c0b4 FPHSA(): add HANDLE_COMPONENTS option 34108cd find_package: add documentation for OPTIONAL_COMPONENTS cdabde8 FPHSA(): add missing "]" to documentation f2e0a18 find_package: add OPTIONAL_COMPONENTS keyword
Diffstat (limited to 'Source')
-rw-r--r--Source/cmFindPackageCommand.cxx57
1 files changed, 48 insertions, 9 deletions
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 3541ca3..ef16ce8 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -90,6 +90,7 @@ void cmFindPackageCommand::GenerateDocumentation()
this->CommandDocumentation =
" find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n"
" [[REQUIRED|COMPONENTS] [components...]]\n"
+ " [OPTIONAL_COMPONENTS components...]\n"
" [NO_POLICY_SCOPE])\n"
"Finds and loads settings from an external project. "
"<package>_FOUND will be set to indicate whether the package was found. "
@@ -98,10 +99,14 @@ void cmFindPackageCommand::GenerateDocumentation()
"The QUIET option disables messages if the package cannot be found. "
"The MODULE option disables the second signature documented below. "
"The REQUIRED option stops processing with an error message if the "
- "package cannot be found. "
- "A package-specific list of components may be listed after the "
- "REQUIRED option or after the COMPONENTS option if no REQUIRED "
- "option is given. "
+ "package cannot be found."
+ "\n"
+ "A package-specific list of required components may be listed after the "
+ "COMPONENTS option or directly after the REQUIRED option. "
+ "Additional optional components may be listed after OPTIONAL_COMPONENTS. "
+ "Available components and their influence on whether a package is "
+ "considered to be found are defined by the target package."
+ "\n"
"The [version] argument requests a version with which the package found "
"should be compatible (format is major[.minor[.patch[.tweak]]]). "
"The EXACT option requests that the version be matched exactly. "
@@ -410,6 +415,8 @@ bool cmFindPackageCommand
this->Name = args[0];
std::string components;
const char* components_sep = "";
+ std::set<std::string> requiredComponents;
+ std::set<std::string> optionalComponents;
// Check ancient compatibility.
this->Compatibility_1_6 =
@@ -420,8 +427,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 +472,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 +540,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 +607,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.
this->UseFindModules = configArgs.empty();
this->UseConfigFiles = moduleArgs.empty();