|
|
@@ -57,7 +57,8 @@ cmFindPackageCommand::cmFindPackageCommand()
|
|
|
this->NoUserRegistry = false;
|
|
|
this->NoSystemRegistry = false;
|
|
|
this->NoBuilds = false;
|
|
|
- this->NoModule = false;
|
|
|
+ this->UseConfigFiles = true;
|
|
|
+ this->UseFindModules = true;
|
|
|
this->DebugMode = false;
|
|
|
this->UseLib64Paths = false;
|
|
|
this->PolicyScope = true;
|
|
|
@@ -72,6 +73,7 @@ cmFindPackageCommand::cmFindPackageCommand()
|
|
|
this->VersionFoundPatch = 0;
|
|
|
this->VersionFoundTweak = 0;
|
|
|
this->VersionFoundCount = 0;
|
|
|
+ this->RequiredCMakeVersion = 0;
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
@@ -86,7 +88,7 @@ void cmFindPackageCommand::GenerateDocumentation()
|
|
|
cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
|
|
|
"FIND_XXX", "find_package");
|
|
|
this->CommandDocumentation =
|
|
|
- " find_package(<package> [version] [EXACT] [QUIET]\n"
|
|
|
+ " find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n"
|
|
|
" [[REQUIRED|COMPONENTS] [components...]]\n"
|
|
|
" [NO_POLICY_SCOPE])\n"
|
|
|
"Finds and loads settings from an external project. "
|
|
|
@@ -94,6 +96,7 @@ void cmFindPackageCommand::GenerateDocumentation()
|
|
|
"When the package is found package-specific information is provided "
|
|
|
"through variables documented by the package itself. "
|
|
|
"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 "
|
|
|
@@ -124,10 +127,12 @@ void cmFindPackageCommand::GenerateDocumentation()
|
|
|
"and producing any needed messages. "
|
|
|
"Many find-modules provide limited or no support for versioning; "
|
|
|
"check the module documentation. "
|
|
|
- "If no module is found the command proceeds to Config mode.\n"
|
|
|
+ "If no module is found and the MODULE option is not given the command "
|
|
|
+ "proceeds to Config mode.\n"
|
|
|
"The complete Config mode command signature is:\n"
|
|
|
" find_package(<package> [version] [EXACT] [QUIET]\n"
|
|
|
- " [[REQUIRED|COMPONENTS] [components...]] [NO_MODULE]\n"
|
|
|
+ " [[REQUIRED|COMPONENTS] [components...]]\n"
|
|
|
+ " [CONFIG|NO_MODULE]\n"
|
|
|
" [NO_POLICY_SCOPE]\n"
|
|
|
" [NAMES name1 [name2 ...]]\n"
|
|
|
" [CONFIGS config1 [config2 ...]]\n"
|
|
|
@@ -145,9 +150,10 @@ void cmFindPackageCommand::GenerateDocumentation()
|
|
|
" [CMAKE_FIND_ROOT_PATH_BOTH |\n"
|
|
|
" ONLY_CMAKE_FIND_ROOT_PATH |\n"
|
|
|
" NO_CMAKE_FIND_ROOT_PATH])\n"
|
|
|
- "The NO_MODULE option may be used to skip Module mode explicitly. "
|
|
|
- "It is also implied by use of options not specified in the reduced "
|
|
|
- "signature. "
|
|
|
+ "The CONFIG option may be used to skip Module mode explicitly and "
|
|
|
+ "switch to Config mode. It is synonymous to using NO_MODULE. "
|
|
|
+ "Config mode is also implied by use of options not specified in the "
|
|
|
+ "reduced signature. "
|
|
|
"\n"
|
|
|
"Config mode attempts to locate a configuration file provided by the "
|
|
|
"package to be found. A cache entry called <package>_DIR is created to "
|
|
|
@@ -367,6 +373,15 @@ bool cmFindPackageCommand
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ // Lookup required version of CMake.
|
|
|
+ if(const char* rv =
|
|
|
+ this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"))
|
|
|
+ {
|
|
|
+ unsigned int v[3] = {0,0,0};
|
|
|
+ sscanf(rv, "%u.%u.%u", &v[0], &v[1], &v[2]);
|
|
|
+ this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0],v[1],v[2]);
|
|
|
+ }
|
|
|
+
|
|
|
// Check for debug mode.
|
|
|
this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
|
|
|
|
|
|
@@ -410,6 +425,8 @@ bool cmFindPackageCommand
|
|
|
Doing doing = DoingNone;
|
|
|
cmsys::RegularExpression version("^[0-9.]+$");
|
|
|
bool haveVersion = false;
|
|
|
+ std::set<unsigned int> configArgs;
|
|
|
+ std::set<unsigned int> moduleArgs;
|
|
|
for(unsigned int i=1; i < args.size(); ++i)
|
|
|
{
|
|
|
if(args[i] == "QUIET")
|
|
|
@@ -423,9 +440,19 @@ bool cmFindPackageCommand
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingNone;
|
|
|
}
|
|
|
+ else if(args[i] == "MODULE")
|
|
|
+ {
|
|
|
+ moduleArgs.insert(i);
|
|
|
+ doing = DoingNone;
|
|
|
+ }
|
|
|
+ else if(args[i] == "CONFIG")
|
|
|
+ {
|
|
|
+ configArgs.insert(i);
|
|
|
+ doing = DoingNone;
|
|
|
+ }
|
|
|
else if(args[i] == "NO_MODULE")
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
doing = DoingNone;
|
|
|
}
|
|
|
else if(args[i] == "REQUIRED")
|
|
|
@@ -440,31 +467,31 @@ bool cmFindPackageCommand
|
|
|
}
|
|
|
else if(args[i] == "NAMES")
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingNames;
|
|
|
}
|
|
|
else if(args[i] == "PATHS")
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingPaths;
|
|
|
}
|
|
|
else if(args[i] == "HINTS")
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingHints;
|
|
|
}
|
|
|
else if(args[i] == "PATH_SUFFIXES")
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingPathSuffixes;
|
|
|
}
|
|
|
else if(args[i] == "CONFIGS")
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingConfigs;
|
|
|
}
|
|
|
@@ -477,27 +504,27 @@ bool cmFindPackageCommand
|
|
|
else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
|
|
|
{
|
|
|
this->NoUserRegistry = true;
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingNone;
|
|
|
}
|
|
|
else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
|
|
|
{
|
|
|
this->NoSystemRegistry = true;
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingNone;
|
|
|
}
|
|
|
else if(args[i] == "NO_CMAKE_BUILDS_PATH")
|
|
|
{
|
|
|
this->NoBuilds = true;
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingNone;
|
|
|
}
|
|
|
else if(this->CheckCommonArgument(args[i]))
|
|
|
{
|
|
|
- this->NoModule = true;
|
|
|
+ configArgs.insert(i);
|
|
|
this->Compatibility_1_6 = false;
|
|
|
doing = DoingNone;
|
|
|
}
|
|
|
@@ -557,6 +584,29 @@ bool cmFindPackageCommand
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Maybe choose one mode exclusively.
|
|
|
+ this->UseFindModules = configArgs.empty();
|
|
|
+ this->UseConfigFiles = moduleArgs.empty();
|
|
|
+ if(!this->UseFindModules && !this->UseConfigFiles)
|
|
|
+ {
|
|
|
+ cmOStringStream e;
|
|
|
+ e << "given options exclusive to Module mode:\n";
|
|
|
+ for(std::set<unsigned int>::const_iterator si = moduleArgs.begin();
|
|
|
+ si != moduleArgs.end(); ++si)
|
|
|
+ {
|
|
|
+ e << " " << args[*si] << "\n";
|
|
|
+ }
|
|
|
+ e << "and options exclusive to Config mode:\n";
|
|
|
+ for(std::set<unsigned int>::const_iterator si = configArgs.begin();
|
|
|
+ si != configArgs.end(); ++si)
|
|
|
+ {
|
|
|
+ e << " " << args[*si] << "\n";
|
|
|
+ }
|
|
|
+ e << "The options are incompatible.";
|
|
|
+ this->SetError(e.str().c_str());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
// Ignore EXACT with no version.
|
|
|
if(this->Version.empty() && this->VersionExact)
|
|
|
{
|
|
|
@@ -636,7 +686,7 @@ bool cmFindPackageCommand
|
|
|
this->SetModuleVariables(components);
|
|
|
|
|
|
// See if there is a Find<package>.cmake module.
|
|
|
- if(!this->NoModule)
|
|
|
+ if(this->UseFindModules)
|
|
|
{
|
|
|
bool foundModule = false;
|
|
|
if(!this->FindModule(foundModule))
|
|
|
@@ -651,6 +701,37 @@ bool cmFindPackageCommand
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if(this->UseFindModules && this->UseConfigFiles &&
|
|
|
+ this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE"))
|
|
|
+ {
|
|
|
+ cmOStringStream aw;
|
|
|
+ if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8))
|
|
|
+ {
|
|
|
+ aw << "find_package called without either MODULE or CONFIG option and "
|
|
|
+ "no Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. "
|
|
|
+ "Add MODULE to exclusively request Module mode and fail if "
|
|
|
+ "Find" << this->Name << ".cmake is missing. "
|
|
|
+ "Add CONFIG to exclusively request Config mode and search for a "
|
|
|
+ "package configuration file provided by " << this->Name <<
|
|
|
+ " (" << this->Name << "Config.cmake or " <<
|
|
|
+ cmSystemTools::LowerCase(this->Name) << "-config.cmake). ";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ aw << "find_package called without NO_MODULE option and no "
|
|
|
+ "Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. "
|
|
|
+ "Add NO_MODULE to exclusively request Config mode and search for a "
|
|
|
+ "package configuration file provided by " << this->Name <<
|
|
|
+ " (" << this->Name << "Config.cmake or " <<
|
|
|
+ cmSystemTools::LowerCase(this->Name) << "-config.cmake). "
|
|
|
+ "Otherwise make Find" << this->Name << ".cmake available in "
|
|
|
+ "CMAKE_MODULE_PATH.";
|
|
|
+ }
|
|
|
+ aw << "\n"
|
|
|
+ "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)";
|
|
|
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str());
|
|
|
+ }
|
|
|
+
|
|
|
// No find module. Assume the project has a CMake config file. Use
|
|
|
// a <package>_DIR cache variable to locate it.
|
|
|
this->Variable = this->Name;
|
|
|
@@ -831,41 +912,44 @@ bool cmFindPackageCommand::HandlePackageMode()
|
|
|
|
|
|
// Try to load the config file if the directory is known
|
|
|
bool fileFound = false;
|
|
|
- if(!cmSystemTools::IsOff(def))
|
|
|
+ if (this->UseConfigFiles)
|
|
|
{
|
|
|
- // Get the directory from the variable value.
|
|
|
- std::string dir = def;
|
|
|
- cmSystemTools::ConvertToUnixSlashes(dir);
|
|
|
-
|
|
|
- // Treat relative paths with respect to the current source dir.
|
|
|
- if(!cmSystemTools::FileIsFullPath(dir.c_str()))
|
|
|
+ if(!cmSystemTools::IsOff(def))
|
|
|
{
|
|
|
- dir = "/" + dir;
|
|
|
- dir = this->Makefile->GetCurrentDirectory() + dir;
|
|
|
+ // Get the directory from the variable value.
|
|
|
+ std::string dir = def;
|
|
|
+ cmSystemTools::ConvertToUnixSlashes(dir);
|
|
|
+
|
|
|
+ // Treat relative paths with respect to the current source dir.
|
|
|
+ if(!cmSystemTools::FileIsFullPath(dir.c_str()))
|
|
|
+ {
|
|
|
+ dir = "/" + dir;
|
|
|
+ dir = this->Makefile->GetCurrentDirectory() + dir;
|
|
|
+ }
|
|
|
+ // The file location was cached. Look for the correct file.
|
|
|
+ std::string file;
|
|
|
+ if (this->FindConfigFile(dir, file))
|
|
|
+ {
|
|
|
+ this->FileFound = file;
|
|
|
+ fileFound = true;
|
|
|
+ }
|
|
|
+ def = this->Makefile->GetDefinition(this->Variable.c_str());
|
|
|
}
|
|
|
- // The file location was cached. Look for the correct file.
|
|
|
- std::string file;
|
|
|
- if (this->FindConfigFile(dir, file))
|
|
|
+
|
|
|
+ // Search for the config file if it is not already found.
|
|
|
+ if(cmSystemTools::IsOff(def) || !fileFound)
|
|
|
{
|
|
|
- this->FileFound = file;
|
|
|
- fileFound = true;
|
|
|
+ fileFound = this->FindConfig();
|
|
|
+ def = this->Makefile->GetDefinition(this->Variable.c_str());
|
|
|
}
|
|
|
- def = this->Makefile->GetDefinition(this->Variable.c_str());
|
|
|
- }
|
|
|
|
|
|
- // Search for the config file if it is not already found.
|
|
|
- if(cmSystemTools::IsOff(def) || !fileFound)
|
|
|
- {
|
|
|
- fileFound = this->FindConfig();
|
|
|
- def = this->Makefile->GetDefinition(this->Variable.c_str());
|
|
|
- }
|
|
|
-
|
|
|
- // Sanity check.
|
|
|
- if(fileFound && this->FileFound.empty())
|
|
|
- {
|
|
|
- this->Makefile->IssueMessage(
|
|
|
- cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!");
|
|
|
- fileFound = false;
|
|
|
+ // Sanity check.
|
|
|
+ if(fileFound && this->FileFound.empty())
|
|
|
+ {
|
|
|
+ this->Makefile->IssueMessage(
|
|
|
+ cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!");
|
|
|
+ fileFound = false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// If the directory for the config file was found, try to read the file.
|
|
|
@@ -893,6 +977,7 @@ bool cmFindPackageCommand::HandlePackageMode()
|
|
|
{
|
|
|
// The variable is not set.
|
|
|
cmOStringStream e;
|
|
|
+ cmOStringStream aw;
|
|
|
// If there are files in ConsideredConfigs, it means that FooConfig.cmake
|
|
|
// have been found, but they didn't have appropriate versions.
|
|
|
if (this->ConsideredConfigs.size() > 0)
|
|
|
@@ -912,41 +997,76 @@ bool cmFindPackageCommand::HandlePackageMode()
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- e << "Could not find ";
|
|
|
- if(!this->NoModule)
|
|
|
- {
|
|
|
- e << "module Find" << this->Name << ".cmake or ";
|
|
|
- }
|
|
|
- e << "a configuration file for package " << this->Name << ".\n";
|
|
|
- if(!this->NoModule)
|
|
|
- {
|
|
|
- e << "Adjust CMAKE_MODULE_PATH to find Find"
|
|
|
- << this->Name << ".cmake or set ";
|
|
|
- }
|
|
|
- else
|
|
|
+ std::string requestedVersionString;
|
|
|
+ if(!this->Version.empty())
|
|
|
{
|
|
|
- e << "Set ";
|
|
|
+ requestedVersionString = " (requested version ";
|
|
|
+ requestedVersionString += this->Version;
|
|
|
+ requestedVersionString += ")";
|
|
|
}
|
|
|
- e << this->Variable << " to the directory containing a CMake "
|
|
|
- << "configuration file for " << this->Name << ". ";
|
|
|
- if(this->Configs.size() == 1)
|
|
|
- {
|
|
|
- e << "The file will be called " << this->Configs[0];
|
|
|
- }
|
|
|
- else
|
|
|
+
|
|
|
+ if (this->UseConfigFiles)
|
|
|
{
|
|
|
- e << "The file will have one of the following names:\n";
|
|
|
- for(std::vector<std::string>::const_iterator ci=this->Configs.begin();
|
|
|
- ci != this->Configs.end(); ++ci)
|
|
|
+ if(this->UseFindModules)
|
|
|
{
|
|
|
- e << " " << *ci << "\n";
|
|
|
+ e << "By not providing \"Find" << this->Name << ".cmake\" in "
|
|
|
+ "CMAKE_MODULE_PATH this project has asked CMake to find a "
|
|
|
+ "package configuration file provided by \""<<this->Name<< "\", "
|
|
|
+ "but CMake did not find one.\n";
|
|
|
}
|
|
|
+
|
|
|
+ if(this->Configs.size() == 1)
|
|
|
+ {
|
|
|
+ e << "Could not find a package configuration file named \""
|
|
|
+ << this->Configs[0] << "\" provided by package \""
|
|
|
+ << this->Name << "\"" << requestedVersionString <<".\n";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ e << "Could not find a package configuration file provided by \""
|
|
|
+ << this->Name << "\"" << requestedVersionString
|
|
|
+ << " with any of the following names:\n";
|
|
|
+ for(std::vector<std::string>::const_iterator ci =
|
|
|
+ this->Configs.begin();
|
|
|
+ ci != this->Configs.end(); ++ci)
|
|
|
+ {
|
|
|
+ e << " " << *ci << "\n";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ e << "Add the installation prefix of \"" << this->Name << "\" to "
|
|
|
+ "CMAKE_PREFIX_PATH or set \"" << this->Variable << "\" to a "
|
|
|
+ "directory containing one of the above files. "
|
|
|
+ "If \"" << this->Name << "\" provides a separate development "
|
|
|
+ "package or SDK, be sure it has been installed.";
|
|
|
+ }
|
|
|
+ else // if(!this->UseFindModules && !this->UseConfigFiles)
|
|
|
+ {
|
|
|
+ e << "No \"Find" << this->Name << ".cmake\" found in "
|
|
|
+ << "CMAKE_MODULE_PATH.";
|
|
|
+
|
|
|
+ aw<< "Find"<< this->Name <<".cmake must either be part of this "
|
|
|
+ "project itself, in this case adjust CMAKE_MODULE_PATH so that "
|
|
|
+ "it points to the correct location inside its source tree.\n"
|
|
|
+ "Or it must be installed by a package which has already been "
|
|
|
+ "found via find_package(). In this case make sure that "
|
|
|
+ "package has indeed been found and adjust CMAKE_MODULE_PATH to "
|
|
|
+ "contain the location where that package has installed "
|
|
|
+ "Find" << this->Name << ".cmake. This must be a location "
|
|
|
+ "provided by that package. This error in general means that "
|
|
|
+ "the buildsystem of this project is relying on a Find-module "
|
|
|
+ "without ensuring that it is actually available.\n";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
this->Makefile->IssueMessage(
|
|
|
this->Required? cmake::FATAL_ERROR : cmake::WARNING, e.str());
|
|
|
+
|
|
|
+ if (!aw.str().empty())
|
|
|
+ {
|
|
|
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,aw.str());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Set a variable marking whether the package was found.
|