1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmFindPackageCommand.h"
14 #include <cmsys/Directory.hxx>
15 #include <cmsys/RegularExpression.hxx>
17 #ifdef CMAKE_BUILD_WITH_CMAKE
18 #include "cmVariableWatch.h"
21 #if defined(__HAIKU__)
22 #include <StorageKit.h>
25 void cmFindPackageNeedBackwardsCompatibility(const std::string& variable,
26 int access_type, void*, const char* newValue,
30 #ifdef CMAKE_BUILD_WITH_CMAKE
31 if(access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
33 std::string message = "An attempt was made to access a variable: ";
36 " that has not been defined. This variable is created by the "
37 "FIND_PACKAGE command. CMake version 1.6 always converted the "
38 "variable name to upper-case, but this behavior is no longer the "
39 "case. To fix this you might need to set the cache value of "
40 "CMAKE_BACKWARDS_COMPATIBILITY to 1.6 or less. If you are writing a "
41 "CMake listfile, you should change the variable reference to use "
42 "the case of the argument to FIND_PACKAGE.";
43 cmSystemTools::Error(message.c_str());
51 //----------------------------------------------------------------------------
52 cmFindPackageCommand::cmFindPackageCommand()
54 this->CMakePathName = "PACKAGE";
56 this->Required = false;
57 this->NoUserRegistry = false;
58 this->NoSystemRegistry = false;
59 this->NoBuilds = false;
60 this->UseConfigFiles = true;
61 this->UseFindModules = true;
62 this->DebugMode = false;
63 this->UseLib64Paths = false;
64 this->PolicyScope = true;
65 this->VersionMajor = 0;
66 this->VersionMinor = 0;
67 this->VersionPatch = 0;
68 this->VersionTweak = 0;
69 this->VersionCount = 0;
70 this->VersionExact = false;
71 this->VersionFoundMajor = 0;
72 this->VersionFoundMinor = 0;
73 this->VersionFoundPatch = 0;
74 this->VersionFoundTweak = 0;
75 this->VersionFoundCount = 0;
76 this->RequiredCMakeVersion = 0;
79 //----------------------------------------------------------------------------
80 void cmFindPackageCommand::GenerateDocumentation()
82 this->cmFindCommon::GenerateDocumentation();
83 cmSystemTools::ReplaceString(this->GenericDocumentationRootPath,
84 "CMAKE_FIND_ROOT_PATH_MODE_XXX",
85 "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE");
86 cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
87 "FIND_ARGS_XXX", "<package>");
88 cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
89 "FIND_XXX", "find_package");
90 this->CommandDocumentation =
91 " find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n"
92 " [REQUIRED] [[COMPONENTS] [components...]]\n"
93 " [OPTIONAL_COMPONENTS components...]\n"
94 " [NO_POLICY_SCOPE])\n"
95 "Finds and loads settings from an external project. "
96 "<package>_FOUND will be set to indicate whether the package was found. "
97 "When the package is found package-specific information is provided "
98 "through variables documented by the package itself. "
99 "The QUIET option disables messages if the package cannot be found. "
100 "The MODULE option disables the second signature documented below. "
101 "The REQUIRED option stops processing with an error message if the "
102 "package cannot be found."
104 "A package-specific list of required components may be listed after the "
105 "COMPONENTS option (or after the REQUIRED option if present). "
106 "Additional optional components may be listed after OPTIONAL_COMPONENTS. "
107 "Available components and their influence on whether a package is "
108 "considered to be found are defined by the target package."
110 "The [version] argument requests a version with which the package found "
111 "should be compatible (format is major[.minor[.patch[.tweak]]]). "
112 "The EXACT option requests that the version be matched exactly. "
113 "If no [version] and/or component list is given to a recursive "
114 "invocation inside a find-module, the corresponding arguments "
115 "are forwarded automatically from the outer call (including the "
116 "EXACT flag for [version]). "
117 "Version support is currently provided only on a package-by-package "
118 "basis (details below).\n"
119 "User code should generally look for packages using the above simple "
120 "signature. The remainder of this command documentation specifies the "
121 "full command signature and details of the search process. Project "
122 "maintainers wishing to provide a package to be found by this command "
123 "are encouraged to read on.\n"
124 "The command has two modes by which it searches for packages: "
125 "\"Module\" mode and \"Config\" mode. "
126 "Module mode is available when the command is invoked with the above "
127 "reduced signature. "
128 "CMake searches for a file called \"Find<package>.cmake\" in "
129 "the CMAKE_MODULE_PATH followed by the CMake installation. "
130 "If the file is found, it is read and processed by CMake. "
131 "It is responsible for finding the package, checking the version, "
132 "and producing any needed messages. "
133 "Many find-modules provide limited or no support for versioning; "
134 "check the module documentation. "
135 "If no module is found and the MODULE option is not given the command "
136 "proceeds to Config mode.\n"
137 "The complete Config mode command signature is:\n"
138 " find_package(<package> [version] [EXACT] [QUIET]\n"
139 " [REQUIRED] [[COMPONENTS] [components...]]\n"
140 " [CONFIG|NO_MODULE]\n"
141 " [NO_POLICY_SCOPE]\n"
142 " [NAMES name1 [name2 ...]]\n"
143 " [CONFIGS config1 [config2 ...]]\n"
144 " [HINTS path1 [path2 ... ]]\n"
145 " [PATHS path1 [path2 ... ]]\n"
146 " [PATH_SUFFIXES suffix1 [suffix2 ...]]\n"
147 " [NO_DEFAULT_PATH]\n"
148 " [NO_CMAKE_ENVIRONMENT_PATH]\n"
150 " [NO_SYSTEM_ENVIRONMENT_PATH]\n"
151 " [NO_CMAKE_PACKAGE_REGISTRY]\n"
152 " [NO_CMAKE_BUILDS_PATH]\n"
153 " [NO_CMAKE_SYSTEM_PATH]\n"
154 " [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]\n"
155 " [CMAKE_FIND_ROOT_PATH_BOTH |\n"
156 " ONLY_CMAKE_FIND_ROOT_PATH |\n"
157 " NO_CMAKE_FIND_ROOT_PATH])\n"
158 "The CONFIG option may be used to skip Module mode explicitly and "
159 "switch to Config mode. It is synonymous to using NO_MODULE. "
160 "Config mode is also implied by use of options not specified in the "
161 "reduced signature. "
163 "Config mode attempts to locate a configuration file provided by the "
164 "package to be found. A cache entry called <package>_DIR is created to "
165 "hold the directory containing the file. "
166 "By default the command searches for a package with the name <package>. "
167 "If the NAMES option is given the names following it are used instead "
169 "The command searches for a file called \"<name>Config.cmake\" or "
170 "\"<lower-case-name>-config.cmake\" for each name specified. "
171 "A replacement set of possible configuration file names may be given "
172 "using the CONFIGS option. "
173 "The search procedure is specified below. Once found, the configuration "
174 "file is read and processed by CMake. Since the file is provided by the "
175 "package it already knows the location of package contents. "
176 "The full path to the configuration file is stored in the cmake "
177 "variable <package>_CONFIG."
179 "All configuration files which have been considered by CMake while "
180 "searching for an installation of the package with an appropriate "
181 "version are stored in the cmake variable <package>_CONSIDERED_CONFIGS, "
182 "the associated versions in <package>_CONSIDERED_VERSIONS. "
184 "If the package configuration file cannot be found CMake "
185 "will generate an error describing the problem unless the QUIET "
186 "argument is specified. If REQUIRED is specified and the package "
187 "is not found a fatal error is generated and the configure step stops "
188 "executing. If <package>_DIR has been set to a directory not containing "
189 "a configuration file CMake will ignore it and search from scratch."
191 "When the [version] argument is given Config mode will only find a "
192 "version of the package that claims compatibility with the requested "
193 "version (format is major[.minor[.patch[.tweak]]]). "
194 "If the EXACT option is given only a version of the package claiming "
195 "an exact match of the requested version may be found. "
196 "CMake does not establish any convention for the meaning of version "
198 "Package version numbers are checked by \"version\" files provided by "
199 "the packages themselves. "
200 "For a candidate package configuration file \"<config-file>.cmake\" the "
201 "corresponding version file is located next to it and named either "
202 "\"<config-file>-version.cmake\" or \"<config-file>Version.cmake\". "
203 "If no such version file is available then the configuration file "
204 "is assumed to not be compatible with any requested version. "
205 "A basic version file containing generic version matching code can be "
206 "created using the macro write_basic_package_version_file(), see its "
207 "documentation for more details. "
208 "When a version file is found it is loaded to check the requested "
210 "The version file is loaded in a nested scope in which the following "
211 "variables have been defined:\n"
212 " PACKAGE_FIND_NAME = the <package> name\n"
213 " PACKAGE_FIND_VERSION = full requested version string\n"
214 " PACKAGE_FIND_VERSION_MAJOR = major version if requested, else 0\n"
215 " PACKAGE_FIND_VERSION_MINOR = minor version if requested, else 0\n"
216 " PACKAGE_FIND_VERSION_PATCH = patch version if requested, else 0\n"
217 " PACKAGE_FIND_VERSION_TWEAK = tweak version if requested, else 0\n"
218 " PACKAGE_FIND_VERSION_COUNT = number of version components, 0 to 4\n"
219 "The version file checks whether it satisfies the requested version "
220 "and sets these variables:\n"
221 " PACKAGE_VERSION = full provided version string\n"
222 " PACKAGE_VERSION_EXACT = true if version is exact match\n"
223 " PACKAGE_VERSION_COMPATIBLE = true if version is compatible\n"
224 " PACKAGE_VERSION_UNSUITABLE = true if unsuitable as any version\n"
225 "These variables are checked by the find_package command to determine "
226 "whether the configuration file provides an acceptable version. "
227 "They are not available after the find_package call returns. "
228 "If the version is acceptable the following variables are set:\n"
229 " <package>_VERSION = full provided version string\n"
230 " <package>_VERSION_MAJOR = major version if provided, else 0\n"
231 " <package>_VERSION_MINOR = minor version if provided, else 0\n"
232 " <package>_VERSION_PATCH = patch version if provided, else 0\n"
233 " <package>_VERSION_TWEAK = tweak version if provided, else 0\n"
234 " <package>_VERSION_COUNT = number of version components, 0 to 4\n"
235 "and the corresponding package configuration file is loaded. "
236 "When multiple package configuration files are available whose version "
237 "files claim compatibility with the version requested it is unspecified "
238 "which one is chosen. "
239 "No attempt is made to choose a highest or closest version number."
241 "Config mode provides an elaborate interface and search procedure. "
242 "Much of the interface is provided for completeness and for use "
243 "internally by find-modules loaded by Module mode. "
244 "Most user code should simply call\n"
245 " find_package(<package> [major[.minor]] [EXACT] [REQUIRED|QUIET])\n"
246 "in order to find a package. Package maintainers providing CMake "
247 "package configuration files are encouraged to name and install "
248 "them such that the procedure outlined below will find them "
249 "without requiring use of additional options."
251 "CMake constructs a set of possible installation prefixes for the "
252 "package. Under each prefix several directories are searched for a "
253 "configuration file. The tables below show the directories searched. "
254 "Each entry is meant for installation trees following Windows (W), "
255 "UNIX (U), or Apple (A) conventions.\n"
257 " <prefix>/(cmake|CMake)/ (W)\n"
258 " <prefix>/<name>*/ (W)\n"
259 " <prefix>/<name>*/(cmake|CMake)/ (W)\n"
260 " <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)\n"
261 " <prefix>/(lib/<arch>|lib|share)/<name>*/ (U)\n"
262 " <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)\n"
263 "On systems supporting OS X Frameworks and Application Bundles "
264 "the following directories are searched for frameworks or bundles "
265 "containing a configuration file:\n"
266 " <prefix>/<name>.framework/Resources/ (A)\n"
267 " <prefix>/<name>.framework/Resources/CMake/ (A)\n"
268 " <prefix>/<name>.framework/Versions/*/Resources/ (A)\n"
269 " <prefix>/<name>.framework/Versions/*/Resources/CMake/ (A)\n"
270 " <prefix>/<name>.app/Contents/Resources/ (A)\n"
271 " <prefix>/<name>.app/Contents/Resources/CMake/ (A)\n"
272 "In all cases the <name> is treated as case-insensitive and corresponds "
273 "to any of the names specified (<package> or names given by NAMES). "
274 "Paths with lib/<arch> are enabled if CMAKE_LIBRARY_ARCHITECTURE is set. "
275 "If PATH_SUFFIXES is specified the suffixes are appended to each "
276 "(W) or (U) directory entry one-by-one.\n"
277 "This set of directories is intended to work in cooperation with "
278 "projects that provide configuration files in their installation trees. "
279 "Directories above marked with (W) are intended for installations on "
280 "Windows where the prefix may point at the top of an application's "
281 "installation directory. Those marked with (U) are intended for "
282 "installations on UNIX platforms where the prefix is shared by "
283 "multiple packages. This is merely a convention, so all (W) and (U) "
284 "directories are still searched on all platforms. "
285 "Directories marked with (A) are intended for installations on "
286 "Apple platforms. The cmake variables CMAKE_FIND_FRAMEWORK and "
287 "CMAKE_FIND_APPBUNDLE determine the order of preference "
288 "as specified below.\n"
289 "The set of installation prefixes is constructed using the following "
290 "steps. If NO_DEFAULT_PATH is specified all NO_* options are enabled.\n"
291 "1. Search paths specified in cmake-specific cache variables. "
292 "These are intended to be used on the command line with a -DVAR=value. "
293 "This can be skipped if NO_CMAKE_PATH is passed.\n"
294 " CMAKE_PREFIX_PATH\n"
295 " CMAKE_FRAMEWORK_PATH\n"
296 " CMAKE_APPBUNDLE_PATH\n"
297 "2. Search paths specified in cmake-specific environment variables. "
298 "These are intended to be set in the user's shell configuration. "
299 "This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.\n"
301 " CMAKE_PREFIX_PATH\n"
302 " CMAKE_FRAMEWORK_PATH\n"
303 " CMAKE_APPBUNDLE_PATH\n"
304 "3. Search paths specified by the HINTS option. "
305 "These should be paths computed by system introspection, such as a "
306 "hint provided by the location of another item already found. "
307 "Hard-coded guesses should be specified with the PATHS option.\n"
308 "4. Search the standard system environment variables. "
309 "This can be skipped if NO_SYSTEM_ENVIRONMENT_PATH is passed. "
310 "Path entries ending in \"/bin\" or \"/sbin\" are automatically "
311 "converted to their parent directories.\n"
313 "5. Search project build trees recently configured in a CMake GUI. "
314 "This can be skipped if NO_CMAKE_BUILDS_PATH is passed. "
315 "It is intended for the case when a user is building multiple "
316 "dependent projects one after another.\n"
317 "6. Search paths stored in the CMake user package registry. "
318 "This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. "
319 "On Windows a <package> may appear under registry key\n"
320 " HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Packages\\<package>\n"
321 "as a REG_SZ value, with arbitrary name, that specifies the directory "
322 "containing the package configuration file. "
323 "On UNIX platforms a <package> may appear under the directory\n"
324 " ~/.cmake/packages/<package>\n"
325 "as a file, with arbitrary name, whose content specifies the directory "
326 "containing the package configuration file. "
327 "See the export(PACKAGE) command to create user package registry entries "
328 "for project build trees."
330 "7. Search cmake variables defined in the Platform files "
331 "for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
333 " CMAKE_SYSTEM_PREFIX_PATH\n"
334 " CMAKE_SYSTEM_FRAMEWORK_PATH\n"
335 " CMAKE_SYSTEM_APPBUNDLE_PATH\n"
336 "8. Search paths stored in the CMake system package registry. "
337 "This can be skipped if NO_CMAKE_SYSTEM_PACKAGE_REGISTRY is passed. "
338 "On Windows a <package> may appear under registry key\n"
339 " HKEY_LOCAL_MACHINE\\Software\\Kitware\\CMake\\Packages\\<package>\n"
340 "as a REG_SZ value, with arbitrary name, that specifies the directory "
341 "containing the package configuration file. "
342 "There is no system package registry on non-Windows platforms."
344 "9. Search paths specified by the PATHS option. "
345 "These are typically hard-coded guesses.\n"
347 this->CommandDocumentation += this->GenericDocumentationMacPolicy;
348 this->CommandDocumentation += this->GenericDocumentationRootPath;
349 this->CommandDocumentation += this->GenericDocumentationPathsOrder;
350 this->CommandDocumentation +=
352 "Every non-REQUIRED find_package() call can be disabled by setting the "
353 "variable CMAKE_DISABLE_FIND_PACKAGE_<package> to TRUE. See the "
354 "documentation for the CMAKE_DISABLE_FIND_PACKAGE_<package> variable for "
355 "more information.\n"
356 "When loading a find module or package configuration file find_package "
357 "defines variables to provide information about the call arguments "
358 "(and restores their original state before returning):\n"
359 " <package>_FIND_REQUIRED = true if REQUIRED option was given\n"
360 " <package>_FIND_QUIETLY = true if QUIET option was given\n"
361 " <package>_FIND_VERSION = full requested version string\n"
362 " <package>_FIND_VERSION_MAJOR = major version if requested, else 0\n"
363 " <package>_FIND_VERSION_MINOR = minor version if requested, else 0\n"
364 " <package>_FIND_VERSION_PATCH = patch version if requested, else 0\n"
365 " <package>_FIND_VERSION_TWEAK = tweak version if requested, else 0\n"
366 " <package>_FIND_VERSION_COUNT = number of version components, 0 to 4\n"
367 " <package>_FIND_VERSION_EXACT = true if EXACT option was given\n"
368 " <package>_FIND_COMPONENTS = list of requested components\n"
369 " <package>_FIND_REQUIRED_<c> = true if component <c> is required\n"
370 " false if component <c> is optional\n"
371 "In Module mode the loaded find module is responsible to honor the "
372 "request detailed by these variables; see the find module for details. "
373 "In Config mode find_package handles REQUIRED, QUIET, and version "
374 "options automatically but leaves it to the package configuration file "
375 "to handle components in a way that makes sense for the package. "
376 "The package configuration file may set <package>_FOUND to false "
377 "to tell find_package that component requirements are not satisfied."
379 "See the cmake_policy() command documentation for discussion of the "
380 "NO_POLICY_SCOPE option."
384 //----------------------------------------------------------------------------
385 const char* cmFindPackageCommand::GetFullDocumentation() const
387 if(this->CommandDocumentation.empty())
389 const_cast<cmFindPackageCommand *>(this)->GenerateDocumentation();
391 return this->CommandDocumentation.c_str();
394 //----------------------------------------------------------------------------
395 bool cmFindPackageCommand
396 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
400 this->SetError("called with incorrect number of arguments");
404 // Lookup required version of CMake.
406 this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"))
408 unsigned int v[3] = {0,0,0};
409 sscanf(rv, "%u.%u.%u", &v[0], &v[1], &v[2]);
410 this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0],v[1],v[2]);
413 // Check for debug mode.
414 this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
416 // Lookup target architecture, if any.
417 if(const char* arch =
418 this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
420 this->LibraryArchitecture = arch;
423 // Lookup whether lib64 paths should be used.
424 if(this->Makefile->PlatformIs64Bit() &&
425 this->Makefile->GetCMakeInstance()
426 ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
428 this->UseLib64Paths = true;
431 // Find the current root path mode.
432 this->SelectDefaultRootPathMode();
434 // Find the current bundle/framework search policy.
435 this->SelectDefaultMacMode();
438 this->Name = args[0];
439 std::string components;
440 const char* components_sep = "";
441 std::set<std::string> requiredComponents;
442 std::set<std::string> optionalComponents;
444 // Check ancient compatibility.
445 this->Compatibility_1_6 =
446 this->Makefile->GetLocalGenerator()
447 ->NeedBackwardsCompatibility(1, 6);
449 // Always search directly in a generated path.
450 this->SearchPathSuffixes.push_back("");
452 // Parse the arguments.
453 enum Doing { DoingNone, DoingComponents, DoingOptionalComponents, DoingNames,
454 DoingPaths, DoingPathSuffixes, DoingConfigs, DoingHints };
455 Doing doing = DoingNone;
456 cmsys::RegularExpression version("^[0-9.]+$");
457 bool haveVersion = false;
458 std::set<unsigned int> configArgs;
459 std::set<unsigned int> moduleArgs;
460 for(unsigned int i=1; i < args.size(); ++i)
462 if(args[i] == "QUIET")
467 else if(args[i] == "EXACT")
469 this->VersionExact = true;
470 this->Compatibility_1_6 = false;
473 else if(args[i] == "MODULE")
475 moduleArgs.insert(i);
478 else if(args[i] == "CONFIG")
480 configArgs.insert(i);
483 else if(args[i] == "NO_MODULE")
485 configArgs.insert(i);
488 else if(args[i] == "REQUIRED")
490 this->Required = true;
491 doing = DoingComponents;
493 else if(args[i] == "COMPONENTS")
495 this->Compatibility_1_6 = false;
496 doing = DoingComponents;
498 else if(args[i] == "OPTIONAL_COMPONENTS")
500 this->Compatibility_1_6 = false;
501 doing = DoingOptionalComponents;
503 else if(args[i] == "NAMES")
505 configArgs.insert(i);
506 this->Compatibility_1_6 = false;
509 else if(args[i] == "PATHS")
511 configArgs.insert(i);
512 this->Compatibility_1_6 = false;
515 else if(args[i] == "HINTS")
517 configArgs.insert(i);
518 this->Compatibility_1_6 = false;
521 else if(args[i] == "PATH_SUFFIXES")
523 configArgs.insert(i);
524 this->Compatibility_1_6 = false;
525 doing = DoingPathSuffixes;
527 else if(args[i] == "CONFIGS")
529 configArgs.insert(i);
530 this->Compatibility_1_6 = false;
531 doing = DoingConfigs;
533 else if(args[i] == "NO_POLICY_SCOPE")
535 this->PolicyScope = false;
536 this->Compatibility_1_6 = false;
539 else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
541 this->NoUserRegistry = true;
542 configArgs.insert(i);
543 this->Compatibility_1_6 = false;
546 else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
548 this->NoSystemRegistry = true;
549 configArgs.insert(i);
550 this->Compatibility_1_6 = false;
553 else if(args[i] == "NO_CMAKE_BUILDS_PATH")
555 this->NoBuilds = true;
556 configArgs.insert(i);
557 this->Compatibility_1_6 = false;
560 else if(this->CheckCommonArgument(args[i]))
562 configArgs.insert(i);
563 this->Compatibility_1_6 = false;
566 else if((doing == DoingComponents) || (doing == DoingOptionalComponents))
568 // Set a variable telling the find script whether this component
570 const char* isRequired = "1";
571 if (doing == DoingOptionalComponents)
574 optionalComponents.insert(args[i]);
578 requiredComponents.insert(args[i]);
581 std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
582 this->AddFindDefinition(req_var.c_str(), isRequired);
584 // Append to the list of required components.
585 components += components_sep;
586 components += args[i];
587 components_sep = ";";
589 else if(doing == DoingNames)
591 this->Names.push_back(args[i]);
593 else if(doing == DoingPaths)
595 this->AddUserPath(args[i], this->UserPaths);
597 else if(doing == DoingHints)
599 this->AddUserPath(args[i], this->UserHints);
601 else if(doing == DoingPathSuffixes)
603 this->AddPathSuffix(args[i]);
605 else if(doing == DoingConfigs)
607 if(args[i].find_first_of(":/\\") != args[i].npos ||
608 cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake")
611 e << "given CONFIGS option followed by invalid file name \""
612 << args[i] << "\". The names given must be file names without "
613 << "a path and with a \".cmake\" extension.";
614 this->SetError(e.str().c_str());
617 this->Configs.push_back(args[i]);
619 else if(!haveVersion && version.find(args[i].c_str()))
622 this->Version = args[i];
627 e << "called with invalid argument \"" << args[i].c_str() << "\"";
628 this->SetError(e.str().c_str());
633 std::vector<std::string> doubledComponents;
634 std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
635 optionalComponents.begin(), optionalComponents.end(),
636 std::back_inserter(doubledComponents));
637 if(!doubledComponents.empty())
640 e << "called with components that are both required and optional:\n";
641 for(unsigned int i=0; i<doubledComponents.size(); ++i)
643 e << " " << doubledComponents[i] << "\n";
645 this->SetError(e.str().c_str());
649 // Maybe choose one mode exclusively.
650 this->UseFindModules = configArgs.empty();
651 this->UseConfigFiles = moduleArgs.empty();
652 if(!this->UseFindModules && !this->UseConfigFiles)
655 e << "given options exclusive to Module mode:\n";
656 for(std::set<unsigned int>::const_iterator si = moduleArgs.begin();
657 si != moduleArgs.end(); ++si)
659 e << " " << args[*si] << "\n";
661 e << "and options exclusive to Config mode:\n";
662 for(std::set<unsigned int>::const_iterator si = configArgs.begin();
663 si != configArgs.end(); ++si)
665 e << " " << args[*si] << "\n";
667 e << "The options are incompatible.";
668 this->SetError(e.str().c_str());
672 // Ignore EXACT with no version.
673 if(this->Version.empty() && this->VersionExact)
675 this->VersionExact = false;
676 this->Makefile->IssueMessage(
677 cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested.");
680 if(this->Version.empty() || components.empty())
682 // Check whether we are recursing inside "Find<name>.cmake" within
683 // another find_package(<name>) call.
684 std::string mod = this->Name;
685 mod += "_FIND_MODULE";
686 if(this->Makefile->IsOn(mod.c_str()))
688 if(this->Version.empty())
690 // Get version information from the outer call if necessary.
691 // Requested version string.
692 std::string ver = this->Name;
693 ver += "_FIND_VERSION";
694 this->Version = this->Makefile->GetSafeDefinition(ver.c_str());
696 // Whether an exact version is required.
697 std::string exact = this->Name;
698 exact += "_FIND_VERSION_EXACT";
699 this->VersionExact = this->Makefile->IsOn(exact.c_str());
701 if(components.empty())
703 std::string components_var = this->Name + "_FIND_COMPONENTS";
704 components = this->Makefile->GetSafeDefinition(components_var.c_str());
709 if(!this->Version.empty())
711 // Try to parse the version number and store the results that were
712 // successfully parsed.
713 unsigned int parsed_major;
714 unsigned int parsed_minor;
715 unsigned int parsed_patch;
716 unsigned int parsed_tweak;
717 this->VersionCount = sscanf(this->Version.c_str(), "%u.%u.%u.%u",
718 &parsed_major, &parsed_minor,
719 &parsed_patch, &parsed_tweak);
720 switch(this->VersionCount)
722 case 4: this->VersionTweak = parsed_tweak; // no break!
723 case 3: this->VersionPatch = parsed_patch; // no break!
724 case 2: this->VersionMinor = parsed_minor; // no break!
725 case 1: this->VersionMajor = parsed_major; // no break!
730 std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_";
731 disableFindPackageVar += this->Name;
732 if(this->Makefile->IsOn(disableFindPackageVar.c_str()))
737 e << "for module " << this->Name << " called with REQUIRED, but "
738 << disableFindPackageVar
739 << " is enabled. A REQUIRED package cannot be disabled.";
740 this->SetError(e.str().c_str());
748 this->SetModuleVariables(components);
750 // See if there is a Find<package>.cmake module.
751 if(this->UseFindModules)
753 bool foundModule = false;
754 if(!this->FindModule(foundModule))
756 this->AppendSuccessInformation();
761 this->AppendSuccessInformation();
766 if(this->UseFindModules && this->UseConfigFiles &&
767 this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE"))
770 if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8))
772 aw << "find_package called without either MODULE or CONFIG option and "
773 "no Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. "
774 "Add MODULE to exclusively request Module mode and fail if "
775 "Find" << this->Name << ".cmake is missing. "
776 "Add CONFIG to exclusively request Config mode and search for a "
777 "package configuration file provided by " << this->Name <<
778 " (" << this->Name << "Config.cmake or " <<
779 cmSystemTools::LowerCase(this->Name) << "-config.cmake). ";
783 aw << "find_package called without NO_MODULE option and no "
784 "Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. "
785 "Add NO_MODULE to exclusively request Config mode and search for a "
786 "package configuration file provided by " << this->Name <<
787 " (" << this->Name << "Config.cmake or " <<
788 cmSystemTools::LowerCase(this->Name) << "-config.cmake). "
789 "Otherwise make Find" << this->Name << ".cmake available in "
790 "CMAKE_MODULE_PATH.";
793 "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)";
794 this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str());
797 // No find module. Assume the project has a CMake config file. Use
798 // a <package>_DIR cache variable to locate it.
799 this->Variable = this->Name;
800 this->Variable += "_DIR";
802 // Add the default name.
803 if(this->Names.empty())
805 this->Names.push_back(this->Name);
808 // Add the default configs.
809 if(this->Configs.empty())
811 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
812 ni != this->Names.end(); ++ni)
814 std::string config = *ni;
815 config += "Config.cmake";
816 this->Configs.push_back(config);
818 config = cmSystemTools::LowerCase(*ni);
819 config += "-config.cmake";
820 this->Configs.push_back(config);
824 // get igonored paths from vars and reroot them.
825 std::vector<std::string> ignored;
826 this->GetIgnoredPaths(ignored);
827 this->RerootPaths(ignored);
829 // Construct a set of ignored paths
830 this->IgnoredPaths.clear();
831 this->IgnoredPaths.insert(ignored.begin(), ignored.end());
833 // Find and load the package.
834 bool result = this->HandlePackageMode();
835 this->AppendSuccessInformation();
840 //----------------------------------------------------------------------------
841 void cmFindPackageCommand::SetModuleVariables(const std::string& components)
843 // Store the list of components.
844 std::string components_var = this->Name + "_FIND_COMPONENTS";
845 this->AddFindDefinition(components_var.c_str(), components.c_str());
849 // Tell the module that is about to be read that it should find
851 std::string quietly = this->Name;
852 quietly += "_FIND_QUIETLY";
853 this->AddFindDefinition(quietly.c_str(), "1");
858 // Tell the module that is about to be read that it should report
859 // a fatal error if the package is not found.
860 std::string req = this->Name;
861 req += "_FIND_REQUIRED";
862 this->AddFindDefinition(req.c_str(), "1");
865 if(!this->Version.empty())
867 // Tell the module that is about to be read what version of the
868 // package has been requested.
869 std::string ver = this->Name;
870 ver += "_FIND_VERSION";
871 this->AddFindDefinition(ver.c_str(), this->Version.c_str());
873 sprintf(buf, "%u", this->VersionMajor);
874 this->AddFindDefinition((ver+"_MAJOR").c_str(), buf);
875 sprintf(buf, "%u", this->VersionMinor);
876 this->AddFindDefinition((ver+"_MINOR").c_str(), buf);
877 sprintf(buf, "%u", this->VersionPatch);
878 this->AddFindDefinition((ver+"_PATCH").c_str(), buf);
879 sprintf(buf, "%u", this->VersionTweak);
880 this->AddFindDefinition((ver+"_TWEAK").c_str(), buf);
881 sprintf(buf, "%u", this->VersionCount);
882 this->AddFindDefinition((ver+"_COUNT").c_str(), buf);
884 // Tell the module whether an exact version has been requested.
885 std::string exact = this->Name;
886 exact += "_FIND_VERSION_EXACT";
887 this->AddFindDefinition(exact.c_str(), this->VersionExact? "1":"0");
891 //----------------------------------------------------------------------------
892 void cmFindPackageCommand::AddFindDefinition(const char* var, const char* val)
894 if(const char* old = this->Makefile->GetDefinition(var))
896 this->OriginalDefs[var].exists = true;
897 this->OriginalDefs[var].value = old;
901 this->OriginalDefs[var].exists = false;
903 this->Makefile->AddDefinition(var, val);
906 //----------------------------------------------------------------------------
907 void cmFindPackageCommand::RestoreFindDefinitions()
909 for(std::map<cmStdString, OriginalDef>::iterator
910 i = this->OriginalDefs.begin(); i != this->OriginalDefs.end(); ++i)
912 OriginalDef const& od = i->second;
915 this->Makefile->AddDefinition(i->first.c_str(), od.value.c_str());
919 this->Makefile->RemoveDefinition(i->first.c_str());
924 //----------------------------------------------------------------------------
925 bool cmFindPackageCommand::FindModule(bool& found)
927 std::string module = "Find";
928 module += this->Name;
930 std::string mfile = this->Makefile->GetModulesFile(module.c_str());
933 // Load the module we found, and set "<name>_FIND_MODULE" to true
936 std::string var = this->Name;
937 var += "_FIND_MODULE";
938 this->Makefile->AddDefinition(var.c_str(), "1");
939 bool result = this->ReadListFile(mfile.c_str(), DoPolicyScope);
940 this->Makefile->RemoveDefinition(var.c_str());
946 //----------------------------------------------------------------------------
947 bool cmFindPackageCommand::HandlePackageMode()
949 this->ConsideredConfigs.clear();
951 // Support old capitalization behavior.
952 std::string upperDir = cmSystemTools::UpperCase(this->Name);
953 std::string upperFound = cmSystemTools::UpperCase(this->Name);
955 upperFound += "_FOUND";
956 if(upperDir == this->Variable)
958 this->Compatibility_1_6 = false;
961 // Try to find the config file.
962 const char* def = this->Makefile->GetDefinition(this->Variable.c_str());
963 if(this->Compatibility_1_6 && cmSystemTools::IsOff(def))
965 // Use the setting of the old name of the variable to provide the
967 const char* oldDef = this->Makefile->GetDefinition(upperDir.c_str());
968 if(!cmSystemTools::IsOff(oldDef))
970 this->Makefile->AddDefinition(this->Variable.c_str(), oldDef);
971 def = this->Makefile->GetDefinition(this->Variable.c_str());
975 // Try to load the config file if the directory is known
976 bool fileFound = false;
977 if (this->UseConfigFiles)
979 if(!cmSystemTools::IsOff(def))
981 // Get the directory from the variable value.
982 std::string dir = def;
983 cmSystemTools::ConvertToUnixSlashes(dir);
985 // Treat relative paths with respect to the current source dir.
986 if(!cmSystemTools::FileIsFullPath(dir.c_str()))
989 dir = this->Makefile->GetCurrentDirectory() + dir;
991 // The file location was cached. Look for the correct file.
993 if (this->FindConfigFile(dir, file))
995 this->FileFound = file;
998 def = this->Makefile->GetDefinition(this->Variable.c_str());
1001 // Search for the config file if it is not already found.
1002 if(cmSystemTools::IsOff(def) || !fileFound)
1004 fileFound = this->FindConfig();
1005 def = this->Makefile->GetDefinition(this->Variable.c_str());
1009 if(fileFound && this->FileFound.empty())
1011 this->Makefile->IssueMessage(
1012 cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!");
1017 std::string foundVar = this->Name;
1018 foundVar += "_FOUND";
1020 // If the directory for the config file was found, try to read the file.
1023 bool configFileSetFOUNDFalse = false;
1027 if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
1028 && (this->Makefile->IsOn(foundVar.c_str()) == false))
1030 // by removing Foo_FOUND here if it is FALSE, we don't really change
1031 // the situation for the Config file which is about to be included,
1032 // but we make it possible to detect later on whether the Config file
1033 // has set Foo_FOUND to FALSE itself:
1034 this->Makefile->RemoveDefinition(foundVar.c_str());
1037 // Set the version variables before loading the config file.
1038 // It may override them.
1039 this->StoreVersionFound();
1041 // Parse the configuration file.
1042 if(this->ReadListFile(this->FileFound.c_str(), DoPolicyScope))
1044 // The package has been found.
1047 // Check whether the Config file has set Foo_FOUND to FALSE:
1048 if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
1049 && (this->Makefile->IsOn(foundVar.c_str()) == false))
1051 // we get here if the Config file has set Foo_FOUND actively to FALSE
1053 configFileSetFOUNDFalse = true;
1058 // The configuration file is invalid.
1063 if (result && !found && (!this->Quiet || this->Required))
1065 // The variable is not set.
1068 if (configFileSetFOUNDFalse)
1070 e << "Found package configuration file:\n"
1071 " " << this->FileFound << "\n"
1072 "but it set " << foundVar << " to FALSE so package \"" <<
1073 this->Name << "\" is considered to be NOT FOUND.";
1075 // If there are files in ConsideredConfigs, it means that FooConfig.cmake
1076 // have been found, but they didn't have appropriate versions.
1077 else if (this->ConsideredConfigs.size() > 0)
1079 e << "Could not find a configuration file for package \""
1080 << this->Name << "\" that "
1081 << (this->VersionExact? "exactly matches" : "is compatible with")
1082 << " requested version \"" << this->Version << "\".\n"
1083 << "The following configuration files were considered but not "
1085 for(std::vector<ConfigFileInfo>::size_type i=0;
1086 i<this->ConsideredConfigs.size(); i++)
1088 e << " " << this->ConsideredConfigs[i].filename
1089 << ", version: " << this->ConsideredConfigs[i].version << "\n";
1094 std::string requestedVersionString;
1095 if(!this->Version.empty())
1097 requestedVersionString = " (requested version ";
1098 requestedVersionString += this->Version;
1099 requestedVersionString += ")";
1102 if (this->UseConfigFiles)
1104 if(this->UseFindModules)
1106 e << "By not providing \"Find" << this->Name << ".cmake\" in "
1107 "CMAKE_MODULE_PATH this project has asked CMake to find a "
1108 "package configuration file provided by \""<<this->Name<< "\", "
1109 "but CMake did not find one.\n";
1112 if(this->Configs.size() == 1)
1114 e << "Could not find a package configuration file named \""
1115 << this->Configs[0] << "\" provided by package \""
1116 << this->Name << "\"" << requestedVersionString <<".\n";
1120 e << "Could not find a package configuration file provided by \""
1121 << this->Name << "\"" << requestedVersionString
1122 << " with any of the following names:\n";
1123 for(std::vector<std::string>::const_iterator ci =
1124 this->Configs.begin();
1125 ci != this->Configs.end(); ++ci)
1127 e << " " << *ci << "\n";
1131 e << "Add the installation prefix of \"" << this->Name << "\" to "
1132 "CMAKE_PREFIX_PATH or set \"" << this->Variable << "\" to a "
1133 "directory containing one of the above files. "
1134 "If \"" << this->Name << "\" provides a separate development "
1135 "package or SDK, be sure it has been installed.";
1137 else // if(!this->UseFindModules && !this->UseConfigFiles)
1139 e << "No \"Find" << this->Name << ".cmake\" found in "
1140 << "CMAKE_MODULE_PATH.";
1142 aw<< "Find"<< this->Name <<".cmake must either be part of this "
1143 "project itself, in this case adjust CMAKE_MODULE_PATH so that "
1144 "it points to the correct location inside its source tree.\n"
1145 "Or it must be installed by a package which has already been "
1146 "found via find_package(). In this case make sure that "
1147 "package has indeed been found and adjust CMAKE_MODULE_PATH to "
1148 "contain the location where that package has installed "
1149 "Find" << this->Name << ".cmake. This must be a location "
1150 "provided by that package. This error in general means that "
1151 "the buildsystem of this project is relying on a Find-module "
1152 "without ensuring that it is actually available.\n";
1157 this->Makefile->IssueMessage(
1158 this->Required? cmake::FATAL_ERROR : cmake::WARNING, e.str());
1161 cmSystemTools::SetFatalErrorOccured();
1164 if (!aw.str().empty())
1166 this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,aw.str());
1170 // Set a variable marking whether the package was found.
1171 this->Makefile->AddDefinition(foundVar.c_str(), found? "1":"0");
1173 // Set a variable naming the configuration file that was found.
1174 std::string fileVar = this->Name;
1175 fileVar += "_CONFIG";
1178 this->Makefile->AddDefinition(fileVar.c_str(), this->FileFound.c_str());
1182 this->Makefile->RemoveDefinition(fileVar.c_str());
1185 // Handle some ancient compatibility stuff.
1186 if(this->Compatibility_1_6)
1188 // Listfiles will be looking for the capitalized version of the
1189 // name. Provide it.
1190 this->Makefile->AddDefinition
1192 this->Makefile->GetDefinition(this->Variable.c_str()));
1193 this->Makefile->AddDefinition
1194 (upperFound.c_str(),
1195 this->Makefile->GetDefinition(foundVar.c_str()));
1198 #ifdef CMAKE_BUILD_WITH_CMAKE
1199 if(!(upperDir == this->Variable))
1201 if(this->Compatibility_1_6)
1203 // Listfiles may use the capitalized version of the name.
1204 // Remove any previously added watch.
1205 this->Makefile->GetVariableWatch()->RemoveWatch(
1207 cmFindPackageNeedBackwardsCompatibility
1212 // Listfiles should not be using the capitalized version of the
1213 // name. Add a watch to warn the user.
1214 this->Makefile->GetVariableWatch()->AddWatch(
1216 cmFindPackageNeedBackwardsCompatibility
1222 std::string consideredConfigsVar = this->Name;
1223 consideredConfigsVar += "_CONSIDERED_CONFIGS";
1224 std::string consideredVersionsVar = this->Name;
1225 consideredVersionsVar += "_CONSIDERED_VERSIONS";
1227 std::string consideredConfigFiles;
1228 std::string consideredVersions;
1230 const char* sep = "";
1231 for(std::vector<ConfigFileInfo>::size_type i=0;
1232 i<this->ConsideredConfigs.size(); i++)
1234 consideredConfigFiles += sep;
1235 consideredVersions += sep;
1236 consideredConfigFiles += this->ConsideredConfigs[i].filename;
1237 consideredVersions += this->ConsideredConfigs[i].version;
1241 this->Makefile->AddDefinition(consideredConfigsVar.c_str(),
1242 consideredConfigFiles.c_str());
1244 this->Makefile->AddDefinition(consideredVersionsVar.c_str(),
1245 consideredVersions.c_str());
1250 //----------------------------------------------------------------------------
1251 bool cmFindPackageCommand::FindConfig()
1253 // Compute the set of search prefixes.
1254 this->ComputePrefixes();
1256 // Look for the project's configuration file.
1259 // Search for frameworks.
1260 if(!found && (this->SearchFrameworkFirst || this->SearchFrameworkOnly))
1262 found = this->FindFrameworkConfig();
1266 if(!found && (this->SearchAppBundleFirst || this->SearchAppBundleOnly))
1268 found = this->FindAppBundleConfig();
1272 if(!found && !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
1274 found = this->FindPrefixedConfig();
1277 // Search for frameworks.
1278 if(!found && this->SearchFrameworkLast)
1280 found = this->FindFrameworkConfig();
1284 if(!found && this->SearchAppBundleLast)
1286 found = this->FindAppBundleConfig();
1289 // Store the entry in the cache so it can be set by the user.
1293 init = cmSystemTools::GetFilenamePath(this->FileFound);
1297 init = this->Variable + "-NOTFOUND";
1300 "The directory containing a CMake configuration file for ";
1303 // We force the value since we do not get here if it was already set.
1304 this->Makefile->AddCacheDefinition(this->Variable.c_str(),
1305 init.c_str(), help.c_str(),
1306 cmCacheManager::PATH, true);
1310 //----------------------------------------------------------------------------
1311 bool cmFindPackageCommand::FindPrefixedConfig()
1313 std::vector<std::string>& prefixes = this->SearchPaths;
1314 for(std::vector<std::string>::const_iterator pi = prefixes.begin();
1315 pi != prefixes.end(); ++pi)
1317 if(this->SearchPrefix(*pi))
1325 //----------------------------------------------------------------------------
1326 bool cmFindPackageCommand::FindFrameworkConfig()
1328 std::vector<std::string>& prefixes = this->SearchPaths;
1329 for(std::vector<std::string>::const_iterator i = prefixes.begin();
1330 i != prefixes.end(); ++i)
1332 if(this->SearchFrameworkPrefix(*i))
1340 //----------------------------------------------------------------------------
1341 bool cmFindPackageCommand::FindAppBundleConfig()
1343 std::vector<std::string>& prefixes = this->SearchPaths;
1344 for(std::vector<std::string>::const_iterator i = prefixes.begin();
1345 i != prefixes.end(); ++i)
1347 if(this->SearchAppBundlePrefix(*i))
1355 //----------------------------------------------------------------------------
1356 bool cmFindPackageCommand::ReadListFile(const char* f, PolicyScopeRule psr)
1358 if(this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), f, 0,
1359 !this->PolicyScope || psr == NoPolicyScope))
1363 std::string e = "Error reading CMake code from \"";
1366 this->SetError(e.c_str());
1370 //----------------------------------------------------------------------------
1371 void cmFindPackageCommand::AppendToFoundProperty(bool found)
1373 std::vector<std::string> foundContents;
1374 const char *foundProp =
1375 this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_FOUND");
1376 if (foundProp && *foundProp)
1378 std::string tmp = foundProp;
1380 cmSystemTools::ExpandListArgument(tmp, foundContents, false);
1381 std::vector<std::string>::iterator nameIt = std::find(
1382 foundContents.begin(), foundContents.end(), this->Name);
1383 if(nameIt != foundContents.end())
1385 foundContents.erase(nameIt);
1389 std::vector<std::string> notFoundContents;
1390 const char *notFoundProp =
1391 this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_NOT_FOUND");
1392 if (notFoundProp && *notFoundProp)
1394 std::string tmp = notFoundProp;
1396 cmSystemTools::ExpandListArgument(tmp, notFoundContents, false);
1397 std::vector<std::string>::iterator nameIt = std::find(
1398 notFoundContents.begin(), notFoundContents.end(), this->Name);
1399 if(nameIt != notFoundContents.end())
1401 notFoundContents.erase(nameIt);
1407 foundContents.push_back(this->Name);
1411 notFoundContents.push_back(this->Name);
1416 const char* sep ="";
1417 for(size_t i=0; i<foundContents.size(); i++)
1420 tmp += foundContents[i];
1424 this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_FOUND",
1429 for(size_t i=0; i<notFoundContents.size(); i++)
1432 tmp += notFoundContents[i];
1435 this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_NOT_FOUND",
1439 //----------------------------------------------------------------------------
1440 void cmFindPackageCommand::AppendSuccessInformation()
1442 std::string found = this->Name;
1444 std::string upperFound = cmSystemTools::UpperCase(found);
1446 const char* upperResult = this->Makefile->GetDefinition(upperFound.c_str());
1447 const char* result = this->Makefile->GetDefinition(found.c_str());
1448 bool packageFound = ((cmSystemTools::IsOn(result))
1449 || (cmSystemTools::IsOn(upperResult)));
1451 this->AppendToFoundProperty(packageFound);
1453 // Record whether the find was quiet or not, so this can be used
1454 // e.g. in FeatureSummary.cmake
1455 std::string quietInfoPropName = "_CMAKE_";
1456 quietInfoPropName += this->Name;
1457 quietInfoPropName += "_QUIET";
1458 this->Makefile->GetCMakeInstance()->SetProperty(quietInfoPropName.c_str(),
1459 this->Quiet ? "TRUE" : "FALSE");
1461 // set a global property to record the required version of this package
1462 std::string versionInfoPropName = "_CMAKE_";
1463 versionInfoPropName += this->Name;
1464 versionInfoPropName += "_REQUIRED_VERSION";
1465 std::string versionInfo;
1466 if(!this->Version.empty())
1468 versionInfo = this->VersionExact ? "==" : ">=";
1470 versionInfo += this->Version;
1472 this->Makefile->GetCMakeInstance()->SetProperty(versionInfoPropName.c_str(),
1473 versionInfo.c_str());
1476 std::string requiredInfoPropName = "_CMAKE_";
1477 requiredInfoPropName += this->Name;
1478 requiredInfoPropName += "_TYPE";
1479 this->Makefile->GetCMakeInstance()->SetProperty(
1480 requiredInfoPropName.c_str(), "REQUIRED");
1484 // Restore original state of "_FIND_" variables we set.
1485 this->RestoreFindDefinitions();
1488 //----------------------------------------------------------------------------
1489 void cmFindPackageCommand::ComputePrefixes()
1491 this->AddPrefixesCMakeVariable();
1492 this->AddPrefixesCMakeEnvironment();
1493 this->AddPrefixesUserHints();
1494 this->AddPrefixesSystemEnvironment();
1495 this->AddPrefixesUserRegistry();
1496 this->AddPrefixesBuilds();
1497 this->AddPrefixesCMakeSystemVariable();
1498 this->AddPrefixesSystemRegistry();
1499 this->AddPrefixesUserGuess();
1500 this->ComputeFinalPaths();
1503 //----------------------------------------------------------------------------
1504 void cmFindPackageCommand::AddPrefixesCMakeEnvironment()
1506 if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath)
1508 // Check the environment variable with the same name as the cache
1511 if(cmSystemTools::GetEnv(this->Variable.c_str(), env) && env.length() > 0)
1513 cmSystemTools::ConvertToUnixSlashes(env);
1514 this->AddPathInternal(env, EnvPath);
1517 this->AddEnvPath("CMAKE_PREFIX_PATH");
1518 this->AddEnvPath("CMAKE_FRAMEWORK_PATH");
1519 this->AddEnvPath("CMAKE_APPBUNDLE_PATH");
1523 //----------------------------------------------------------------------------
1524 void cmFindPackageCommand::AddPrefixesCMakeVariable()
1526 if(!this->NoCMakePath && !this->NoDefaultPath)
1528 this->AddCMakePath("CMAKE_PREFIX_PATH");
1529 this->AddCMakePath("CMAKE_FRAMEWORK_PATH");
1530 this->AddCMakePath("CMAKE_APPBUNDLE_PATH");
1534 //----------------------------------------------------------------------------
1535 void cmFindPackageCommand::AddPrefixesSystemEnvironment()
1537 if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
1539 // Use the system search path to generate prefixes.
1540 // Relative paths are interpreted with respect to the current
1541 // working directory.
1542 std::vector<std::string> tmp;
1543 cmSystemTools::GetPath(tmp);
1544 for(std::vector<std::string>::iterator i = tmp.begin();
1545 i != tmp.end(); ++i)
1547 std::string const& d = *i;
1549 // If the path is a PREFIX/bin case then add its parent instead.
1550 if((d.size() >= 4 && strcmp(d.c_str()+d.size()-4, "/bin") == 0) ||
1551 (d.size() >= 5 && strcmp(d.c_str()+d.size()-5, "/sbin") == 0))
1553 this->AddPathInternal(cmSystemTools::GetFilenamePath(d), EnvPath);
1557 this->AddPathInternal(d, EnvPath);
1563 //----------------------------------------------------------------------------
1564 void cmFindPackageCommand::AddPrefixesUserRegistry()
1566 if(this->NoUserRegistry || this->NoDefaultPath)
1571 #if defined(_WIN32) && !defined(__CYGWIN__)
1572 this->LoadPackageRegistryWinUser();
1573 #elif defined(__HAIKU__)
1575 if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK)
1577 dir.Append("cmake/packages");
1578 dir.Append(this->Name.c_str());
1579 this->LoadPackageRegistryDir(dir.Path());
1582 if(const char* home = cmSystemTools::GetEnv("HOME"))
1584 std::string dir = home;
1585 dir += "/.cmake/packages/";
1587 this->LoadPackageRegistryDir(dir);
1592 //----------------------------------------------------------------------------
1593 void cmFindPackageCommand::AddPrefixesSystemRegistry()
1595 if(this->NoSystemRegistry || this->NoDefaultPath)
1600 #if defined(_WIN32) && !defined(__CYGWIN__)
1601 this->LoadPackageRegistryWinSystem();
1605 #if defined(_WIN32) && !defined(__CYGWIN__)
1606 # include <windows.h>
1607 # undef GetCurrentDirectory
1608 // http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
1609 # if !defined(KEY_WOW64_32KEY)
1610 # define KEY_WOW64_32KEY 0x0200
1612 # if !defined(KEY_WOW64_64KEY)
1613 # define KEY_WOW64_64KEY 0x0100
1615 //----------------------------------------------------------------------------
1616 void cmFindPackageCommand::LoadPackageRegistryWinUser()
1618 // HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
1619 this->LoadPackageRegistryWin(true, 0);
1622 //----------------------------------------------------------------------------
1623 void cmFindPackageCommand::LoadPackageRegistryWinSystem()
1625 // HKEY_LOCAL_MACHINE\\SOFTWARE has separate 32-bit and 64-bit views.
1626 // Prefer the target platform view first.
1627 if(this->Makefile->PlatformIs64Bit())
1629 this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
1630 this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
1634 this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
1635 this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
1639 //----------------------------------------------------------------------------
1640 void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
1643 std::string key = "Software\\Kitware\\CMake\\Packages\\";
1645 std::set<cmStdString> bad;
1647 if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
1648 0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
1650 DWORD valueType = REG_NONE;
1652 std::vector<char> data(512);
1657 DWORD nameSize = static_cast<DWORD>(sizeof(name));
1658 DWORD dataSize = static_cast<DWORD>(data.size()-1);
1659 switch(RegEnumValue(hKey, index, name, &nameSize,
1660 0, &valueType, (BYTE*)&data[0], &dataSize))
1664 if(valueType == REG_SZ)
1667 cmsys_ios::stringstream ss(&data[0]);
1668 if(!this->CheckPackageRegistryEntry(ss))
1670 // The entry is invalid.
1675 case ERROR_MORE_DATA:
1676 data.resize(dataSize+1);
1678 case ERROR_NO_MORE_ITEMS: default: done = true; break;
1684 // Remove bad values if possible.
1685 if(user && !bad.empty() &&
1686 RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
1687 0, KEY_SET_VALUE|view, &hKey) == ERROR_SUCCESS)
1689 for(std::set<cmStdString>::const_iterator vi = bad.begin();
1690 vi != bad.end(); ++vi)
1692 RegDeleteValue(hKey, vi->c_str());
1698 //----------------------------------------------------------------------------
1699 class cmFindPackageCommandHoldFile
1703 cmFindPackageCommandHoldFile(const char* f): File(f) {}
1704 ~cmFindPackageCommandHoldFile()
1705 { if(this->File) { cmSystemTools::RemoveFile(this->File); } }
1706 void Release() { this->File = 0; }
1709 //----------------------------------------------------------------------------
1710 void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
1712 cmsys::Directory files;
1713 if(!files.Load(dir.c_str()))
1719 for(unsigned long i=0; i < files.GetNumberOfFiles(); ++i)
1723 fname += files.GetFile(i);
1725 if(!cmSystemTools::FileIsDirectory(fname.c_str()))
1727 // Hold this file hostage until it behaves.
1728 cmFindPackageCommandHoldFile holdFile(fname.c_str());
1731 std::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary);
1732 if(fin && this->CheckPackageRegistryEntry(fin))
1734 // The file references an existing package, so release it.
1740 // TODO: Wipe out the directory if it is empty.
1744 //----------------------------------------------------------------------------
1745 bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is)
1747 // Parse the content of one package registry entry.
1749 if(cmSystemTools::GetLineFromStream(is, fname) &&
1750 cmSystemTools::FileIsFullPath(fname.c_str()))
1752 // The first line in the stream is the full path to a file or
1753 // directory containing the package.
1754 if(cmSystemTools::FileExists(fname.c_str()))
1756 // The path exists. Look for the package here.
1757 if(!cmSystemTools::FileIsDirectory(fname.c_str()))
1759 fname = cmSystemTools::GetFilenamePath(fname);
1761 this->AddPathInternal(fname, FullPath);
1766 // The path does not exist. Assume the stream content is
1767 // associated with an old package that no longer exists, and
1768 // delete it to keep the package registry clean.
1774 // The first line in the stream is not the full path to a file or
1775 // directory. Assume the stream content was created by a future
1776 // version of CMake that uses a different format, and leave it.
1781 //----------------------------------------------------------------------------
1782 void cmFindPackageCommand::AddPrefixesBuilds()
1784 if(!this->NoBuilds && !this->NoDefaultPath)
1786 // It is likely that CMake will have recently built the project.
1787 for(int i=0; i <= 10; ++i)
1791 "[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\"
1792 "Settings\\StartPath;WhereBuild" << i << "]";
1793 std::string f = r.str();
1794 cmSystemTools::ExpandRegistryValues(f);
1795 cmSystemTools::ConvertToUnixSlashes(f);
1796 if(cmSystemTools::FileIsFullPath(f.c_str()) &&
1797 cmSystemTools::FileIsDirectory(f.c_str()))
1799 this->AddPathInternal(f, FullPath);
1805 //----------------------------------------------------------------------------
1806 void cmFindPackageCommand::AddPrefixesCMakeSystemVariable()
1808 if(!this->NoCMakeSystemPath && !this->NoDefaultPath)
1810 this->AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
1811 this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
1812 this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
1816 //----------------------------------------------------------------------------
1817 void cmFindPackageCommand::AddPrefixesUserGuess()
1819 // Add guesses specified by the caller.
1820 this->AddPathsInternal(this->UserPaths, CMakePath);
1823 //----------------------------------------------------------------------------
1824 void cmFindPackageCommand::AddPrefixesUserHints()
1826 // Add hints specified by the caller.
1827 this->AddPathsInternal(this->UserHints, CMakePath);
1830 //----------------------------------------------------------------------------
1831 bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
1833 assert(!dir.empty() && dir[dir.size()-1] == '/');
1835 // Check each path suffix on this directory.
1836 for(std::vector<std::string>::const_iterator
1837 si = this->SearchPathSuffixes.begin();
1838 si != this->SearchPathSuffixes.end(); ++si)
1840 std::string d = dir;
1846 if(this->CheckDirectory(d))
1854 //----------------------------------------------------------------------------
1855 bool cmFindPackageCommand::CheckDirectory(std::string const& dir)
1857 assert(!dir.empty() && dir[dir.size()-1] == '/');
1859 // Look for the file in this directory.
1860 std::string d = dir.substr(0, dir.size()-1);
1861 if(this->FindConfigFile(d, this->FileFound))
1863 // Remove duplicate slashes.
1864 cmSystemTools::ConvertToUnixSlashes(this->FileFound);
1870 //----------------------------------------------------------------------------
1871 bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
1874 if (this->IgnoredPaths.count(dir))
1879 for(std::vector<std::string>::const_iterator ci = this->Configs.begin();
1880 ci != this->Configs.end(); ++ci)
1887 fprintf(stderr, "Checking file [%s]\n", file.c_str());
1889 if(cmSystemTools::FileExists(file.c_str(), true) &&
1890 this->CheckVersion(file))
1898 //----------------------------------------------------------------------------
1899 bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
1901 bool result = false; // by default, assume the version is not ok.
1902 bool haveResult = false;
1903 std::string version = "unknown";
1905 // Get the filename without the .cmake extension.
1906 std::string::size_type pos = config_file.rfind('.');
1907 std::string version_file_base = config_file.substr(0, pos);
1909 // Look for foo-config-version.cmake
1910 std::string version_file = version_file_base;
1911 version_file += "-version.cmake";
1912 if ((haveResult == false)
1913 && (cmSystemTools::FileExists(version_file.c_str(), true)))
1915 result = this->CheckVersionFile(version_file, version);
1919 // Look for fooConfigVersion.cmake
1920 version_file = version_file_base;
1921 version_file += "Version.cmake";
1922 if ((haveResult == false)
1923 && (cmSystemTools::FileExists(version_file.c_str(), true)))
1925 result = this->CheckVersionFile(version_file, version);
1930 // If no version was requested a versionless package is acceptable.
1931 if ((haveResult == false) && (this->Version.empty()))
1937 ConfigFileInfo configFileInfo;
1938 configFileInfo.filename = config_file;
1939 configFileInfo.version = version;
1940 this->ConsideredConfigs.push_back(configFileInfo);
1945 //----------------------------------------------------------------------------
1946 bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
1947 std::string& result_version)
1949 // The version file will be loaded in an isolated scope.
1950 cmMakefile::ScopePushPop varScope(this->Makefile);
1951 cmMakefile::PolicyPushPop polScope(this->Makefile);
1952 static_cast<void>(varScope);
1953 static_cast<void>(polScope);
1955 // Clear the output variables.
1956 this->Makefile->RemoveDefinition("PACKAGE_VERSION");
1957 this->Makefile->RemoveDefinition("PACKAGE_VERSION_UNSUITABLE");
1958 this->Makefile->RemoveDefinition("PACKAGE_VERSION_COMPATIBLE");
1959 this->Makefile->RemoveDefinition("PACKAGE_VERSION_EXACT");
1961 // Set the input variables.
1962 this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name.c_str());
1963 this->Makefile->AddDefinition("PACKAGE_FIND_VERSION",
1964 this->Version.c_str());
1966 sprintf(buf, "%u", this->VersionMajor);
1967 this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MAJOR", buf);
1968 sprintf(buf, "%u", this->VersionMinor);
1969 this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MINOR", buf);
1970 sprintf(buf, "%u", this->VersionPatch);
1971 this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_PATCH", buf);
1972 sprintf(buf, "%u", this->VersionTweak);
1973 this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_TWEAK", buf);
1974 sprintf(buf, "%u", this->VersionCount);
1975 this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_COUNT", buf);
1977 // Load the version check file. Pass NoPolicyScope because we do
1978 // our own policy push/pop independent of CMP0011.
1979 bool suitable = false;
1980 if(this->ReadListFile(version_file.c_str(), NoPolicyScope))
1982 // Check the output variables.
1983 bool okay = this->Makefile->IsOn("PACKAGE_VERSION_EXACT");
1984 bool unsuitable = this->Makefile->IsOn("PACKAGE_VERSION_UNSUITABLE");
1985 if(!okay && !this->VersionExact)
1987 okay = this->Makefile->IsOn("PACKAGE_VERSION_COMPATIBLE");
1990 // The package is suitable if the version is okay and not
1991 // explicitly unsuitable.
1992 suitable = !unsuitable && (okay || this->Version.empty());
1995 // Get the version found.
1996 this->VersionFound =
1997 this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
1999 // Try to parse the version number and store the results that were
2000 // successfully parsed.
2001 unsigned int parsed_major;
2002 unsigned int parsed_minor;
2003 unsigned int parsed_patch;
2004 unsigned int parsed_tweak;
2005 this->VersionFoundCount =
2006 sscanf(this->VersionFound.c_str(), "%u.%u.%u.%u",
2007 &parsed_major, &parsed_minor,
2008 &parsed_patch, &parsed_tweak);
2009 switch(this->VersionFoundCount)
2011 case 4: this->VersionFoundTweak = parsed_tweak; // no break!
2012 case 3: this->VersionFoundPatch = parsed_patch; // no break!
2013 case 2: this->VersionFoundMinor = parsed_minor; // no break!
2014 case 1: this->VersionFoundMajor = parsed_major; // no break!
2020 result_version = this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
2021 if (result_version.empty())
2023 result_version = "unknown";
2026 // Succeed if the version is suitable.
2030 //----------------------------------------------------------------------------
2031 void cmFindPackageCommand::StoreVersionFound()
2033 // Store the whole version string.
2034 std::string ver = this->Name;
2036 if(this->VersionFound.empty())
2038 this->Makefile->RemoveDefinition(ver.c_str());
2042 this->Makefile->AddDefinition(ver.c_str(), this->VersionFound.c_str());
2045 // Store the version components.
2047 sprintf(buf, "%u", this->VersionFoundMajor);
2048 this->Makefile->AddDefinition((ver+"_MAJOR").c_str(), buf);
2049 sprintf(buf, "%u", this->VersionFoundMinor);
2050 this->Makefile->AddDefinition((ver+"_MINOR").c_str(), buf);
2051 sprintf(buf, "%u", this->VersionFoundPatch);
2052 this->Makefile->AddDefinition((ver+"_PATCH").c_str(), buf);
2053 sprintf(buf, "%u", this->VersionFoundTweak);
2054 this->Makefile->AddDefinition((ver+"_TWEAK").c_str(), buf);
2055 sprintf(buf, "%u", this->VersionFoundCount);
2056 this->Makefile->AddDefinition((ver+"_COUNT").c_str(), buf);
2059 //----------------------------------------------------------------------------
2060 #include <cmsys/Glob.hxx>
2061 #include <cmsys/String.h>
2062 #include <cmsys/auto_ptr.hxx>
2065 class cmFileListGeneratorBase
2068 virtual ~cmFileListGeneratorBase() {}
2070 bool Consider(std::string const& fullPath, cmFileList& listing);
2072 bool Search(cmFileList&);
2073 virtual bool Search(std::string const& parent, cmFileList&) = 0;
2074 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const = 0;
2075 friend class cmFileList;
2076 cmFileListGeneratorBase* SetNext(cmFileListGeneratorBase const& next);
2077 cmsys::auto_ptr<cmFileListGeneratorBase> Next;
2083 cmFileList(): First(), Last(0) {}
2084 virtual ~cmFileList() {}
2085 cmFileList& operator/(cmFileListGeneratorBase const& rhs)
2089 this->Last = this->Last->SetNext(rhs);
2093 this->First = rhs.Clone();
2094 this->Last = this->First.get();
2100 if(this->First.get())
2102 return this->First->Search(*this);
2107 virtual bool Visit(std::string const& fullPath) = 0;
2108 friend class cmFileListGeneratorBase;
2109 cmsys::auto_ptr<cmFileListGeneratorBase> First;
2110 cmFileListGeneratorBase* Last;
2113 class cmFindPackageFileList: public cmFileList
2116 cmFindPackageFileList(cmFindPackageCommand* fpc,
2117 bool use_suffixes = true):
2118 cmFileList(), FPC(fpc), UseSuffixes(use_suffixes) {}
2120 bool Visit(std::string const& fullPath)
2122 if(this->UseSuffixes)
2124 return this->FPC->SearchDirectory(fullPath);
2128 return this->FPC->CheckDirectory(fullPath);
2131 cmFindPackageCommand* FPC;
2135 bool cmFileListGeneratorBase::Search(cmFileList& listing)
2137 return this->Search("", listing);
2140 cmFileListGeneratorBase*
2141 cmFileListGeneratorBase::SetNext(cmFileListGeneratorBase const& next)
2143 this->Next = next.Clone();
2144 return this->Next.get();
2147 bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
2148 cmFileList& listing)
2150 if(this->Next.get())
2152 return this->Next->Search(fullPath + "/", listing);
2156 return listing.Visit(fullPath + "/");
2160 class cmFileListGeneratorFixed: public cmFileListGeneratorBase
2163 cmFileListGeneratorFixed(std::string const& str):
2164 cmFileListGeneratorBase(), String(str) {}
2165 cmFileListGeneratorFixed(cmFileListGeneratorFixed const& r):
2166 cmFileListGeneratorBase(), String(r.String) {}
2169 virtual bool Search(std::string const& parent, cmFileList& lister)
2171 std::string fullPath = parent + this->String;
2172 return this->Consider(fullPath, lister);
2174 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2176 cmsys::auto_ptr<cmFileListGeneratorBase>
2177 g(new cmFileListGeneratorFixed(*this));
2182 class cmFileListGeneratorEnumerate: public cmFileListGeneratorBase
2185 cmFileListGeneratorEnumerate(std::vector<std::string> const& v):
2186 cmFileListGeneratorBase(), Vector(v) {}
2187 cmFileListGeneratorEnumerate(cmFileListGeneratorEnumerate const& r):
2188 cmFileListGeneratorBase(), Vector(r.Vector) {}
2190 std::vector<std::string> const& Vector;
2191 virtual bool Search(std::string const& parent, cmFileList& lister)
2193 for(std::vector<std::string>::const_iterator i = this->Vector.begin();
2194 i != this->Vector.end(); ++i)
2196 if(this->Consider(parent + *i, lister))
2203 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2205 cmsys::auto_ptr<cmFileListGeneratorBase>
2206 g(new cmFileListGeneratorEnumerate(*this));
2211 class cmFileListGeneratorProject: public cmFileListGeneratorBase
2214 cmFileListGeneratorProject(std::vector<std::string> const& names):
2215 cmFileListGeneratorBase(), Names(names) {}
2216 cmFileListGeneratorProject(cmFileListGeneratorProject const& r):
2217 cmFileListGeneratorBase(), Names(r.Names) {}
2219 std::vector<std::string> const& Names;
2220 virtual bool Search(std::string const& parent, cmFileList& lister)
2222 // Construct a list of matches.
2223 std::vector<std::string> matches;
2225 d.Load(parent.c_str());
2226 for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
2228 const char* fname = d.GetFile(i);
2229 if(strcmp(fname, ".") == 0 ||
2230 strcmp(fname, "..") == 0)
2234 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
2235 ni != this->Names.end(); ++ni)
2237 if(cmsysString_strncasecmp(fname, ni->c_str(),
2240 matches.push_back(fname);
2245 for(std::vector<std::string>::const_iterator i = matches.begin();
2246 i != matches.end(); ++i)
2248 if(this->Consider(parent + *i, lister))
2255 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2257 cmsys::auto_ptr<cmFileListGeneratorBase>
2258 g(new cmFileListGeneratorProject(*this));
2263 class cmFileListGeneratorMacProject: public cmFileListGeneratorBase
2266 cmFileListGeneratorMacProject(std::vector<std::string> const& names,
2268 cmFileListGeneratorBase(), Names(names), Extension(ext) {}
2269 cmFileListGeneratorMacProject(cmFileListGeneratorMacProject const& r):
2270 cmFileListGeneratorBase(), Names(r.Names), Extension(r.Extension) {}
2272 std::vector<std::string> const& Names;
2273 std::string Extension;
2274 virtual bool Search(std::string const& parent, cmFileList& lister)
2276 // Construct a list of matches.
2277 std::vector<std::string> matches;
2279 d.Load(parent.c_str());
2280 for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
2282 const char* fname = d.GetFile(i);
2283 if(strcmp(fname, ".") == 0 ||
2284 strcmp(fname, "..") == 0)
2288 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
2289 ni != this->Names.end(); ++ni)
2291 std::string name = *ni;
2292 name += this->Extension;
2293 if(cmsysString_strcasecmp(fname, name.c_str()) == 0)
2295 matches.push_back(fname);
2300 for(std::vector<std::string>::const_iterator i = matches.begin();
2301 i != matches.end(); ++i)
2303 if(this->Consider(parent + *i, lister))
2310 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2312 cmsys::auto_ptr<cmFileListGeneratorBase>
2313 g(new cmFileListGeneratorMacProject(*this));
2318 class cmFileListGeneratorCaseInsensitive: public cmFileListGeneratorBase
2321 cmFileListGeneratorCaseInsensitive(std::string const& str):
2322 cmFileListGeneratorBase(), String(str) {}
2323 cmFileListGeneratorCaseInsensitive(
2324 cmFileListGeneratorCaseInsensitive const& r):
2325 cmFileListGeneratorBase(), String(r.String) {}
2328 virtual bool Search(std::string const& parent, cmFileList& lister)
2330 // Look for matching files.
2331 std::vector<std::string> matches;
2333 d.Load(parent.c_str());
2334 for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
2336 const char* fname = d.GetFile(i);
2337 if(strcmp(fname, ".") == 0 ||
2338 strcmp(fname, "..") == 0)
2342 if(cmsysString_strcasecmp(fname, this->String.c_str()) == 0)
2344 if(this->Consider(parent + fname, lister))
2352 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2354 cmsys::auto_ptr<cmFileListGeneratorBase>
2355 g(new cmFileListGeneratorCaseInsensitive(*this));
2360 class cmFileListGeneratorGlob: public cmFileListGeneratorBase
2363 cmFileListGeneratorGlob(std::string const& str):
2364 cmFileListGeneratorBase(), Pattern(str) {}
2365 cmFileListGeneratorGlob(cmFileListGeneratorGlob const& r):
2366 cmFileListGeneratorBase(), Pattern(r.Pattern) {}
2368 std::string Pattern;
2369 virtual bool Search(std::string const& parent, cmFileList& lister)
2371 // Glob the set of matching files.
2372 std::string expr = parent;
2373 expr += this->Pattern;
2375 if(!g.FindFiles(expr))
2379 std::vector<std::string> const& files = g.GetFiles();
2381 // Look for directories among the matches.
2382 for(std::vector<std::string>::const_iterator fi = files.begin();
2383 fi != files.end(); ++fi)
2385 if(cmSystemTools::FileIsDirectory(fi->c_str()))
2387 if(this->Consider(*fi, lister))
2395 virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2397 cmsys::auto_ptr<cmFileListGeneratorBase>
2398 g(new cmFileListGeneratorGlob(*this));
2403 //----------------------------------------------------------------------------
2404 bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
2406 assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
2409 fprintf(stderr, "Checking prefix [%s]\n", prefix_in.c_str());
2412 // Skip this if the prefix does not exist.
2413 if(!cmSystemTools::FileIsDirectory(prefix_in.c_str()))
2418 // PREFIX/ (useful on windows or in build trees)
2419 if(this->SearchDirectory(prefix_in))
2424 // Strip the trailing slash because the path generator is about to
2426 std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
2428 // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
2430 cmFindPackageFileList lister(this);
2432 / cmFileListGeneratorFixed(prefix)
2433 / cmFileListGeneratorCaseInsensitive("cmake");
2440 // PREFIX/(Foo|foo|FOO).*/
2442 cmFindPackageFileList lister(this);
2444 / cmFileListGeneratorFixed(prefix)
2445 / cmFileListGeneratorProject(this->Names);
2452 // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
2454 cmFindPackageFileList lister(this);
2456 / cmFileListGeneratorFixed(prefix)
2457 / cmFileListGeneratorProject(this->Names)
2458 / cmFileListGeneratorCaseInsensitive("cmake");
2465 // Construct list of common install locations (lib and share).
2466 std::vector<std::string> common;
2467 if(!this->LibraryArchitecture.empty())
2469 common.push_back("lib/"+this->LibraryArchitecture);
2471 if(this->UseLib64Paths)
2473 common.push_back("lib64");
2475 common.push_back("lib");
2476 common.push_back("share");
2478 // PREFIX/(lib/ARCH|lib|share)/cmake/(Foo|foo|FOO).*/
2480 cmFindPackageFileList lister(this);
2482 / cmFileListGeneratorFixed(prefix)
2483 / cmFileListGeneratorEnumerate(common)
2484 / cmFileListGeneratorFixed("cmake")
2485 / cmFileListGeneratorProject(this->Names);
2492 // PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/
2494 cmFindPackageFileList lister(this);
2496 / cmFileListGeneratorFixed(prefix)
2497 / cmFileListGeneratorEnumerate(common)
2498 / cmFileListGeneratorProject(this->Names);
2505 // PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/(cmake|CMake)/
2507 cmFindPackageFileList lister(this);
2509 / cmFileListGeneratorFixed(prefix)
2510 / cmFileListGeneratorEnumerate(common)
2511 / cmFileListGeneratorProject(this->Names)
2512 / cmFileListGeneratorCaseInsensitive("cmake");
2522 //----------------------------------------------------------------------------
2523 bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
2525 assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
2528 fprintf(stderr, "Checking framework prefix [%s]\n", prefix_in.c_str());
2531 // Strip the trailing slash because the path generator is about to
2533 std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
2535 // <prefix>/Foo.framework/Resources/
2537 cmFindPackageFileList lister(this);
2539 / cmFileListGeneratorFixed(prefix)
2540 / cmFileListGeneratorMacProject(this->Names, ".framework")
2541 / cmFileListGeneratorFixed("Resources");
2547 // <prefix>/Foo.framework/Resources/CMake/
2549 cmFindPackageFileList lister(this);
2551 / cmFileListGeneratorFixed(prefix)
2552 / cmFileListGeneratorMacProject(this->Names, ".framework")
2553 / cmFileListGeneratorFixed("Resources")
2554 / cmFileListGeneratorCaseInsensitive("cmake");
2561 // <prefix>/Foo.framework/Versions/*/Resources/
2563 cmFindPackageFileList lister(this);
2565 / cmFileListGeneratorFixed(prefix)
2566 / cmFileListGeneratorMacProject(this->Names, ".framework")
2567 / cmFileListGeneratorFixed("Versions")
2568 / cmFileListGeneratorGlob("*/Resources");
2575 // <prefix>/Foo.framework/Versions/*/Resources/CMake/
2577 cmFindPackageFileList lister(this);
2579 / cmFileListGeneratorFixed(prefix)
2580 / cmFileListGeneratorMacProject(this->Names, ".framework")
2581 / cmFileListGeneratorFixed("Versions")
2582 / cmFileListGeneratorGlob("*/Resources")
2583 / cmFileListGeneratorCaseInsensitive("cmake");
2593 //----------------------------------------------------------------------------
2594 bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
2596 assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
2599 fprintf(stderr, "Checking bundle prefix [%s]\n", prefix_in.c_str());
2602 // Strip the trailing slash because the path generator is about to
2604 std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
2606 // <prefix>/Foo.app/Contents/Resources
2608 cmFindPackageFileList lister(this);
2610 / cmFileListGeneratorFixed(prefix)
2611 / cmFileListGeneratorMacProject(this->Names, ".app")
2612 / cmFileListGeneratorFixed("Contents/Resources");
2619 // <prefix>/Foo.app/Contents/Resources/CMake
2621 cmFindPackageFileList lister(this);
2623 / cmFileListGeneratorFixed(prefix)
2624 / cmFileListGeneratorMacProject(this->Names, ".app")
2625 / cmFileListGeneratorFixed("Contents/Resources")
2626 / cmFileListGeneratorCaseInsensitive("cmake");
2636 // TODO: Debug cmsys::Glob double slash problem.