Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmFindPackageCommand.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
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"
13
14 #include <cmsys/Directory.hxx>
15 #include <cmsys/RegularExpression.hxx>
16
17 #ifdef CMAKE_BUILD_WITH_CMAKE
18 #include "cmVariableWatch.h"
19 #endif
20
21 #if defined(__HAIKU__)
22 #include <StorageKit.h>
23 #endif
24
25 void cmFindPackageNeedBackwardsCompatibility(const std::string& variable,
26   int access_type, void*, const char* newValue,
27   const cmMakefile*)
28 {
29   (void)newValue;
30 #ifdef CMAKE_BUILD_WITH_CMAKE
31   if(access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
32     {
33     std::string message = "An attempt was made to access a variable: ";
34     message += variable;
35     message +=
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());
44     }
45 #else
46   (void)variable;
47   (void)access_type;
48 #endif
49 }
50
51 //----------------------------------------------------------------------------
52 cmFindPackageCommand::cmFindPackageCommand()
53 {
54   this->CMakePathName = "PACKAGE";
55   this->Quiet = false;
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;
77 }
78
79 //----------------------------------------------------------------------------
80 void cmFindPackageCommand::GenerateDocumentation()
81 {
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."
103     "\n"
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."
109     "\n"
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"
149     "               [NO_CMAKE_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.  "
162     "\n"
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 "
168     "of <package>.  "
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."
178     "\n"
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. "
183     "\n"
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."
190     "\n"
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 "
197     "numbers.  "
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 "
209     "version number.  "
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."
240     "\n"
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."
250     "\n"
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"
256     "  <prefix>/                                               (W)\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"
300     "   <package>_DIR\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"
312     "   PATH\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."
329     "\n"
330     "7. Search cmake variables defined in the Platform files "
331     "for the current system.  This can be skipped if NO_CMAKE_SYSTEM_PATH "
332     "is passed.\n"
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."
343     "\n"
344     "9. Search paths specified by the PATHS option.  "
345     "These are typically hard-coded guesses.\n"
346     ;
347   this->CommandDocumentation += this->GenericDocumentationMacPolicy;
348   this->CommandDocumentation += this->GenericDocumentationRootPath;
349   this->CommandDocumentation += this->GenericDocumentationPathsOrder;
350   this->CommandDocumentation +=
351     "\n"
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."
378     "\n"
379     "See the cmake_policy() command documentation for discussion of the "
380     "NO_POLICY_SCOPE option."
381     ;
382 }
383
384 //----------------------------------------------------------------------------
385 const char* cmFindPackageCommand::GetFullDocumentation() const
386 {
387   if(this->CommandDocumentation.empty())
388     {
389     const_cast<cmFindPackageCommand *>(this)->GenerateDocumentation();
390     }
391   return this->CommandDocumentation.c_str();
392 }
393
394 //----------------------------------------------------------------------------
395 bool cmFindPackageCommand
396 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
397 {
398   if(args.size() < 1)
399     {
400     this->SetError("called with incorrect number of arguments");
401     return false;
402     }
403
404   // Lookup required version of CMake.
405   if(const char* rv =
406      this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"))
407     {
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]);
411     }
412
413   // Check for debug mode.
414   this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
415
416   // Lookup target architecture, if any.
417   if(const char* arch =
418      this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
419     {
420     this->LibraryArchitecture = arch;
421     }
422
423   // Lookup whether lib64 paths should be used.
424   if(this->Makefile->PlatformIs64Bit() &&
425      this->Makefile->GetCMakeInstance()
426      ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
427     {
428     this->UseLib64Paths = true;
429     }
430
431   // Find the current root path mode.
432   this->SelectDefaultRootPathMode();
433
434   // Find the current bundle/framework search policy.
435   this->SelectDefaultMacMode();
436
437   // Record options.
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;
443
444   // Check ancient compatibility.
445   this->Compatibility_1_6 =
446     this->Makefile->GetLocalGenerator()
447     ->NeedBackwardsCompatibility(1, 6);
448
449   // Always search directly in a generated path.
450   this->SearchPathSuffixes.push_back("");
451
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)
461     {
462     if(args[i] == "QUIET")
463       {
464       this->Quiet = true;
465       doing = DoingNone;
466       }
467     else if(args[i] == "EXACT")
468       {
469       this->VersionExact = true;
470       this->Compatibility_1_6 = false;
471       doing = DoingNone;
472       }
473     else if(args[i] == "MODULE")
474       {
475       moduleArgs.insert(i);
476       doing = DoingNone;
477       }
478     else if(args[i] == "CONFIG")
479       {
480       configArgs.insert(i);
481       doing = DoingNone;
482       }
483     else if(args[i] == "NO_MODULE")
484       {
485       configArgs.insert(i);
486       doing = DoingNone;
487       }
488     else if(args[i] == "REQUIRED")
489       {
490       this->Required = true;
491       doing = DoingComponents;
492       }
493     else if(args[i] == "COMPONENTS")
494       {
495       this->Compatibility_1_6 = false;
496       doing = DoingComponents;
497       }
498     else if(args[i] == "OPTIONAL_COMPONENTS")
499       {
500       this->Compatibility_1_6 = false;
501       doing = DoingOptionalComponents;
502       }
503     else if(args[i] == "NAMES")
504       {
505       configArgs.insert(i);
506       this->Compatibility_1_6 = false;
507       doing = DoingNames;
508       }
509     else if(args[i] == "PATHS")
510       {
511       configArgs.insert(i);
512       this->Compatibility_1_6 = false;
513       doing = DoingPaths;
514       }
515     else if(args[i] == "HINTS")
516       {
517       configArgs.insert(i);
518       this->Compatibility_1_6 = false;
519       doing = DoingHints;
520       }
521     else if(args[i] == "PATH_SUFFIXES")
522       {
523       configArgs.insert(i);
524       this->Compatibility_1_6 = false;
525       doing = DoingPathSuffixes;
526       }
527     else if(args[i] == "CONFIGS")
528       {
529       configArgs.insert(i);
530       this->Compatibility_1_6 = false;
531       doing = DoingConfigs;
532       }
533     else if(args[i] == "NO_POLICY_SCOPE")
534       {
535       this->PolicyScope = false;
536       this->Compatibility_1_6 = false;
537       doing = DoingNone;
538       }
539     else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
540       {
541       this->NoUserRegistry = true;
542       configArgs.insert(i);
543       this->Compatibility_1_6 = false;
544       doing = DoingNone;
545       }
546     else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
547       {
548       this->NoSystemRegistry = true;
549       configArgs.insert(i);
550       this->Compatibility_1_6 = false;
551       doing = DoingNone;
552       }
553     else if(args[i] == "NO_CMAKE_BUILDS_PATH")
554       {
555       this->NoBuilds = true;
556       configArgs.insert(i);
557       this->Compatibility_1_6 = false;
558       doing = DoingNone;
559       }
560     else if(this->CheckCommonArgument(args[i]))
561       {
562       configArgs.insert(i);
563       this->Compatibility_1_6 = false;
564       doing = DoingNone;
565       }
566     else if((doing == DoingComponents) || (doing == DoingOptionalComponents))
567       {
568       // Set a variable telling the find script whether this component
569       // is required.
570       const char* isRequired = "1";
571       if (doing == DoingOptionalComponents)
572         {
573         isRequired = "0";
574         optionalComponents.insert(args[i]);
575         }
576       else
577         {
578         requiredComponents.insert(args[i]);
579         }
580
581       std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
582       this->AddFindDefinition(req_var.c_str(), isRequired);
583
584       // Append to the list of required components.
585       components += components_sep;
586       components += args[i];
587       components_sep = ";";
588       }
589     else if(doing == DoingNames)
590       {
591       this->Names.push_back(args[i]);
592       }
593     else if(doing == DoingPaths)
594       {
595       this->AddUserPath(args[i], this->UserPaths);
596       }
597     else if(doing == DoingHints)
598       {
599       this->AddUserPath(args[i], this->UserHints);
600       }
601     else if(doing == DoingPathSuffixes)
602       {
603       this->AddPathSuffix(args[i]);
604       }
605     else if(doing == DoingConfigs)
606       {
607       if(args[i].find_first_of(":/\\") != args[i].npos ||
608          cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake")
609         {
610         cmOStringStream e;
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());
615         return false;
616         }
617       this->Configs.push_back(args[i]);
618       }
619     else if(!haveVersion && version.find(args[i].c_str()))
620       {
621       haveVersion = true;
622       this->Version = args[i];
623       }
624     else
625       {
626       cmOStringStream e;
627       e << "called with invalid argument \"" << args[i].c_str() << "\"";
628       this->SetError(e.str().c_str());
629       return false;
630       }
631     }
632
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())
638     {
639     cmOStringStream e;
640     e << "called with components that are both required and optional:\n";
641     for(unsigned int i=0; i<doubledComponents.size(); ++i)
642       {
643       e << "  " << doubledComponents[i] << "\n";
644       }
645     this->SetError(e.str().c_str());
646     return false;
647     }
648
649   // Maybe choose one mode exclusively.
650   this->UseFindModules = configArgs.empty();
651   this->UseConfigFiles = moduleArgs.empty();
652   if(!this->UseFindModules && !this->UseConfigFiles)
653     {
654     cmOStringStream e;
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)
658       {
659       e << "  " << args[*si] << "\n";
660       }
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)
664       {
665       e << "  " << args[*si] << "\n";
666       }
667     e << "The options are incompatible.";
668     this->SetError(e.str().c_str());
669     return false;
670     }
671
672   // Ignore EXACT with no version.
673   if(this->Version.empty() && this->VersionExact)
674     {
675     this->VersionExact = false;
676     this->Makefile->IssueMessage(
677       cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested.");
678     }
679
680   if(this->Version.empty() || components.empty())
681     {
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()))
687       {
688       if(this->Version.empty())
689         {
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());
695
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());
700         }
701       if(components.empty())
702         {
703         std::string components_var = this->Name + "_FIND_COMPONENTS";
704         components = this->Makefile->GetSafeDefinition(components_var.c_str());
705         }
706       }
707     }
708
709   if(!this->Version.empty())
710     {
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)
721       {
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!
726       default: break;
727       }
728     }
729
730   std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_";
731   disableFindPackageVar += this->Name;
732   if(this->Makefile->IsOn(disableFindPackageVar.c_str()))
733     {
734     if (this->Required)
735       {
736       cmOStringStream e;
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());
741       return false;
742       }
743
744     return true;
745     }
746
747
748   this->SetModuleVariables(components);
749
750   // See if there is a Find<package>.cmake module.
751   if(this->UseFindModules)
752     {
753     bool foundModule = false;
754     if(!this->FindModule(foundModule))
755       {
756       this->AppendSuccessInformation();
757       return false;
758       }
759     if(foundModule)
760       {
761       this->AppendSuccessInformation();
762       return true;
763       }
764     }
765
766   if(this->UseFindModules && this->UseConfigFiles &&
767      this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE"))
768     {
769     cmOStringStream aw;
770     if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8))
771       {
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).  ";
780       }
781     else
782       {
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.";
791       }
792     aw << "\n"
793       "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)";
794     this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str());
795     }
796
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";
801
802   // Add the default name.
803   if(this->Names.empty())
804     {
805     this->Names.push_back(this->Name);
806     }
807
808   // Add the default configs.
809   if(this->Configs.empty())
810     {
811     for(std::vector<std::string>::const_iterator ni = this->Names.begin();
812         ni != this->Names.end(); ++ni)
813       {
814       std::string config = *ni;
815       config += "Config.cmake";
816       this->Configs.push_back(config);
817
818       config = cmSystemTools::LowerCase(*ni);
819       config += "-config.cmake";
820       this->Configs.push_back(config);
821       }
822     }
823
824   // get igonored paths from vars and reroot them.
825   std::vector<std::string> ignored;
826   this->GetIgnoredPaths(ignored);
827   this->RerootPaths(ignored);
828
829   // Construct a set of ignored paths
830   this->IgnoredPaths.clear();
831   this->IgnoredPaths.insert(ignored.begin(), ignored.end());
832
833   // Find and load the package.
834   bool result = this->HandlePackageMode();
835   this->AppendSuccessInformation();
836   return result;
837 }
838
839
840 //----------------------------------------------------------------------------
841 void cmFindPackageCommand::SetModuleVariables(const std::string& components)
842 {
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());
846
847   if(this->Quiet)
848     {
849     // Tell the module that is about to be read that it should find
850     // quietly.
851     std::string quietly = this->Name;
852     quietly += "_FIND_QUIETLY";
853     this->AddFindDefinition(quietly.c_str(), "1");
854     }
855
856   if(this->Required)
857     {
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");
863     }
864
865   if(!this->Version.empty())
866     {
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());
872     char buf[64];
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);
883
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");
888    }
889 }
890
891 //----------------------------------------------------------------------------
892 void cmFindPackageCommand::AddFindDefinition(const char* var, const char* val)
893 {
894   if(const char* old = this->Makefile->GetDefinition(var))
895     {
896     this->OriginalDefs[var].exists = true;
897     this->OriginalDefs[var].value = old;
898     }
899   else
900     {
901     this->OriginalDefs[var].exists = false;
902     }
903   this->Makefile->AddDefinition(var, val);
904 }
905
906 //----------------------------------------------------------------------------
907 void cmFindPackageCommand::RestoreFindDefinitions()
908 {
909   for(std::map<cmStdString, OriginalDef>::iterator
910         i = this->OriginalDefs.begin(); i != this->OriginalDefs.end(); ++i)
911     {
912     OriginalDef const& od = i->second;
913     if(od.exists)
914       {
915       this->Makefile->AddDefinition(i->first.c_str(), od.value.c_str());
916       }
917     else
918       {
919       this->Makefile->RemoveDefinition(i->first.c_str());
920       }
921     }
922 }
923
924 //----------------------------------------------------------------------------
925 bool cmFindPackageCommand::FindModule(bool& found)
926 {
927   std::string module = "Find";
928   module += this->Name;
929   module += ".cmake";
930   std::string mfile = this->Makefile->GetModulesFile(module.c_str());
931   if ( mfile.size() )
932     {
933     // Load the module we found, and set "<name>_FIND_MODULE" to true
934     // while inside it.
935     found = 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());
941     return result;
942     }
943   return true;
944 }
945
946 //----------------------------------------------------------------------------
947 bool cmFindPackageCommand::HandlePackageMode()
948 {
949   this->ConsideredConfigs.clear();
950
951   // Support old capitalization behavior.
952   std::string upperDir = cmSystemTools::UpperCase(this->Name);
953   std::string upperFound = cmSystemTools::UpperCase(this->Name);
954   upperDir += "_DIR";
955   upperFound += "_FOUND";
956   if(upperDir == this->Variable)
957     {
958     this->Compatibility_1_6 = false;
959     }
960
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))
964     {
965     // Use the setting of the old name of the variable to provide the
966     // value of the new.
967     const char* oldDef = this->Makefile->GetDefinition(upperDir.c_str());
968     if(!cmSystemTools::IsOff(oldDef))
969       {
970       this->Makefile->AddDefinition(this->Variable.c_str(), oldDef);
971       def = this->Makefile->GetDefinition(this->Variable.c_str());
972       }
973     }
974
975   // Try to load the config file if the directory is known
976   bool fileFound = false;
977   if (this->UseConfigFiles)
978     {
979     if(!cmSystemTools::IsOff(def))
980       {
981       // Get the directory from the variable value.
982       std::string dir = def;
983       cmSystemTools::ConvertToUnixSlashes(dir);
984
985       // Treat relative paths with respect to the current source dir.
986       if(!cmSystemTools::FileIsFullPath(dir.c_str()))
987         {
988         dir = "/" + dir;
989         dir = this->Makefile->GetCurrentDirectory() + dir;
990         }
991       // The file location was cached.  Look for the correct file.
992       std::string file;
993       if (this->FindConfigFile(dir, file))
994         {
995         this->FileFound = file;
996         fileFound = true;
997         }
998       def = this->Makefile->GetDefinition(this->Variable.c_str());
999       }
1000
1001     // Search for the config file if it is not already found.
1002     if(cmSystemTools::IsOff(def) || !fileFound)
1003       {
1004       fileFound = this->FindConfig();
1005       def = this->Makefile->GetDefinition(this->Variable.c_str());
1006       }
1007
1008     // Sanity check.
1009     if(fileFound && this->FileFound.empty())
1010       {
1011       this->Makefile->IssueMessage(
1012         cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!");
1013       fileFound = false;
1014       }
1015     }
1016
1017   std::string foundVar = this->Name;
1018   foundVar += "_FOUND";
1019
1020   // If the directory for the config file was found, try to read the file.
1021   bool result = true;
1022   bool found = false;
1023   bool configFileSetFOUNDFalse = false;
1024
1025   if(fileFound)
1026     {
1027     if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
1028       && (this->Makefile->IsOn(foundVar.c_str()) == false))
1029       {
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());
1035       }
1036
1037     // Set the version variables before loading the config file.
1038     // It may override them.
1039     this->StoreVersionFound();
1040
1041     // Parse the configuration file.
1042     if(this->ReadListFile(this->FileFound.c_str(), DoPolicyScope))
1043       {
1044       // The package has been found.
1045       found = true;
1046
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))
1050         {
1051         // we get here if the Config file has set Foo_FOUND actively to FALSE
1052         found = false;
1053         configFileSetFOUNDFalse = true;
1054         }
1055       }
1056     else
1057       {
1058       // The configuration file is invalid.
1059       result = false;
1060       }
1061     }
1062
1063   if (result && !found && (!this->Quiet || this->Required))
1064     {
1065     // The variable is not set.
1066     cmOStringStream e;
1067     cmOStringStream aw;
1068     if (configFileSetFOUNDFalse)
1069       {
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.";
1074       }
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)
1078       {
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 "
1084            "accepted:\n";
1085       for(std::vector<ConfigFileInfo>::size_type i=0;
1086           i<this->ConsideredConfigs.size(); i++)
1087         {
1088         e << "  " << this->ConsideredConfigs[i].filename
1089           << ", version: " << this->ConsideredConfigs[i].version << "\n";
1090         }
1091       }
1092     else
1093       {
1094       std::string requestedVersionString;
1095       if(!this->Version.empty())
1096         {
1097         requestedVersionString = " (requested version ";
1098         requestedVersionString += this->Version;
1099         requestedVersionString += ")";
1100         }
1101
1102       if (this->UseConfigFiles)
1103         {
1104         if(this->UseFindModules)
1105           {
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";
1110           }
1111
1112         if(this->Configs.size() == 1)
1113           {
1114           e << "Could not find a package configuration file named \""
1115             << this->Configs[0] << "\" provided by package \""
1116             << this->Name << "\"" << requestedVersionString <<".\n";
1117           }
1118         else
1119           {
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)
1126             {
1127             e << "  " << *ci << "\n";
1128             }
1129           }
1130
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.";
1136         }
1137       else // if(!this->UseFindModules && !this->UseConfigFiles)
1138         {
1139         e << "No \"Find" << this->Name << ".cmake\" found in "
1140           << "CMAKE_MODULE_PATH.";
1141
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";
1153         }
1154       }
1155
1156
1157     this->Makefile->IssueMessage(
1158       this->Required? cmake::FATAL_ERROR : cmake::WARNING, e.str());
1159     if (this->Required)
1160       {
1161       cmSystemTools::SetFatalErrorOccured();
1162       }
1163
1164     if (!aw.str().empty())
1165       {
1166       this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,aw.str());
1167       }
1168     }
1169
1170   // Set a variable marking whether the package was found.
1171   this->Makefile->AddDefinition(foundVar.c_str(), found? "1":"0");
1172
1173   // Set a variable naming the configuration file that was found.
1174   std::string fileVar = this->Name;
1175   fileVar += "_CONFIG";
1176   if(found)
1177     {
1178     this->Makefile->AddDefinition(fileVar.c_str(), this->FileFound.c_str());
1179     }
1180   else
1181     {
1182     this->Makefile->RemoveDefinition(fileVar.c_str());
1183     }
1184
1185   // Handle some ancient compatibility stuff.
1186   if(this->Compatibility_1_6)
1187     {
1188     // Listfiles will be looking for the capitalized version of the
1189     // name.  Provide it.
1190     this->Makefile->AddDefinition
1191       (upperDir.c_str(),
1192        this->Makefile->GetDefinition(this->Variable.c_str()));
1193     this->Makefile->AddDefinition
1194       (upperFound.c_str(),
1195        this->Makefile->GetDefinition(foundVar.c_str()));
1196     }
1197
1198 #ifdef CMAKE_BUILD_WITH_CMAKE
1199   if(!(upperDir == this->Variable))
1200     {
1201     if(this->Compatibility_1_6)
1202       {
1203       // Listfiles may use the capitalized version of the name.
1204       // Remove any previously added watch.
1205       this->Makefile->GetVariableWatch()->RemoveWatch(
1206         upperDir.c_str(),
1207         cmFindPackageNeedBackwardsCompatibility
1208         );
1209       }
1210     else
1211       {
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(
1215         upperDir.c_str(),
1216         cmFindPackageNeedBackwardsCompatibility
1217         );
1218       }
1219     }
1220 #endif
1221
1222   std::string consideredConfigsVar = this->Name;
1223   consideredConfigsVar += "_CONSIDERED_CONFIGS";
1224   std::string consideredVersionsVar = this->Name;
1225   consideredVersionsVar += "_CONSIDERED_VERSIONS";
1226
1227   std::string consideredConfigFiles;
1228   std::string consideredVersions;
1229
1230   const char* sep = "";
1231   for(std::vector<ConfigFileInfo>::size_type i=0;
1232       i<this->ConsideredConfigs.size(); i++)
1233     {
1234     consideredConfigFiles += sep;
1235     consideredVersions += sep;
1236     consideredConfigFiles += this->ConsideredConfigs[i].filename;
1237     consideredVersions += this->ConsideredConfigs[i].version;
1238     sep = ";";
1239     }
1240
1241   this->Makefile->AddDefinition(consideredConfigsVar.c_str(),
1242                                 consideredConfigFiles.c_str());
1243
1244   this->Makefile->AddDefinition(consideredVersionsVar.c_str(),
1245                                 consideredVersions.c_str());
1246
1247   return result;
1248 }
1249
1250 //----------------------------------------------------------------------------
1251 bool cmFindPackageCommand::FindConfig()
1252 {
1253   // Compute the set of search prefixes.
1254   this->ComputePrefixes();
1255
1256   // Look for the project's configuration file.
1257   bool found = false;
1258
1259   // Search for frameworks.
1260   if(!found && (this->SearchFrameworkFirst || this->SearchFrameworkOnly))
1261     {
1262     found = this->FindFrameworkConfig();
1263     }
1264
1265   // Search for apps.
1266   if(!found && (this->SearchAppBundleFirst || this->SearchAppBundleOnly))
1267     {
1268     found = this->FindAppBundleConfig();
1269     }
1270
1271   // Search prefixes.
1272   if(!found && !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
1273     {
1274     found = this->FindPrefixedConfig();
1275     }
1276
1277   // Search for frameworks.
1278   if(!found && this->SearchFrameworkLast)
1279     {
1280     found = this->FindFrameworkConfig();
1281     }
1282
1283   // Search for apps.
1284   if(!found && this->SearchAppBundleLast)
1285     {
1286     found = this->FindAppBundleConfig();
1287     }
1288
1289   // Store the entry in the cache so it can be set by the user.
1290   std::string init;
1291   if(found)
1292     {
1293     init = cmSystemTools::GetFilenamePath(this->FileFound);
1294     }
1295   else
1296     {
1297     init = this->Variable + "-NOTFOUND";
1298     }
1299   std::string help =
1300     "The directory containing a CMake configuration file for ";
1301   help += this->Name;
1302   help += ".";
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);
1307   return found;
1308 }
1309
1310 //----------------------------------------------------------------------------
1311 bool cmFindPackageCommand::FindPrefixedConfig()
1312 {
1313   std::vector<std::string>& prefixes = this->SearchPaths;
1314   for(std::vector<std::string>::const_iterator pi = prefixes.begin();
1315       pi != prefixes.end(); ++pi)
1316     {
1317     if(this->SearchPrefix(*pi))
1318       {
1319       return true;
1320       }
1321     }
1322   return false;
1323 }
1324
1325 //----------------------------------------------------------------------------
1326 bool cmFindPackageCommand::FindFrameworkConfig()
1327 {
1328   std::vector<std::string>& prefixes = this->SearchPaths;
1329   for(std::vector<std::string>::const_iterator i = prefixes.begin();
1330       i != prefixes.end(); ++i)
1331     {
1332     if(this->SearchFrameworkPrefix(*i))
1333       {
1334       return true;
1335       }
1336     }
1337   return false;
1338 }
1339
1340 //----------------------------------------------------------------------------
1341 bool cmFindPackageCommand::FindAppBundleConfig()
1342 {
1343   std::vector<std::string>& prefixes = this->SearchPaths;
1344   for(std::vector<std::string>::const_iterator i = prefixes.begin();
1345       i != prefixes.end(); ++i)
1346     {
1347     if(this->SearchAppBundlePrefix(*i))
1348       {
1349       return true;
1350       }
1351     }
1352   return false;
1353 }
1354
1355 //----------------------------------------------------------------------------
1356 bool cmFindPackageCommand::ReadListFile(const char* f, PolicyScopeRule psr)
1357 {
1358   if(this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), f, 0,
1359                                   !this->PolicyScope || psr == NoPolicyScope))
1360     {
1361     return true;
1362     }
1363   std::string e = "Error reading CMake code from \"";
1364   e += f;
1365   e += "\".";
1366   this->SetError(e.c_str());
1367   return false;
1368 }
1369
1370 //----------------------------------------------------------------------------
1371 void cmFindPackageCommand::AppendToFoundProperty(bool found)
1372 {
1373   std::vector<std::string> foundContents;
1374   const char *foundProp =
1375              this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_FOUND");
1376   if (foundProp && *foundProp)
1377     {
1378     std::string tmp = foundProp;
1379
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())
1384       {
1385       foundContents.erase(nameIt);
1386       }
1387     }
1388
1389   std::vector<std::string> notFoundContents;
1390   const char *notFoundProp =
1391          this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_NOT_FOUND");
1392   if (notFoundProp && *notFoundProp)
1393     {
1394     std::string tmp = notFoundProp;
1395
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())
1400       {
1401       notFoundContents.erase(nameIt);
1402       }
1403     }
1404
1405   if(found)
1406     {
1407     foundContents.push_back(this->Name);
1408     }
1409   else
1410     {
1411     notFoundContents.push_back(this->Name);
1412     }
1413
1414
1415   std::string tmp;
1416   const char* sep ="";
1417   for(size_t i=0; i<foundContents.size(); i++)
1418     {
1419     tmp += sep;
1420     tmp += foundContents[i];
1421     sep = ";";
1422     }
1423
1424   this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_FOUND",
1425                                                   tmp.c_str());
1426
1427   tmp = "";
1428   sep = "";
1429   for(size_t i=0; i<notFoundContents.size(); i++)
1430     {
1431     tmp += sep;
1432     tmp += notFoundContents[i];
1433     sep = ";";
1434     }
1435   this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_NOT_FOUND",
1436                                                   tmp.c_str());
1437 }
1438
1439 //----------------------------------------------------------------------------
1440 void cmFindPackageCommand::AppendSuccessInformation()
1441 {
1442   std::string found = this->Name;
1443   found += "_FOUND";
1444   std::string upperFound = cmSystemTools::UpperCase(found);
1445
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)));
1450
1451   this->AppendToFoundProperty(packageFound);
1452
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");
1460
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())
1467     {
1468     versionInfo = this->VersionExact ? "==" : ">=";
1469     versionInfo += " ";
1470     versionInfo += this->Version;
1471     }
1472   this->Makefile->GetCMakeInstance()->SetProperty(versionInfoPropName.c_str(),
1473                                                   versionInfo.c_str());
1474   if (this->Required)
1475     {
1476     std::string requiredInfoPropName = "_CMAKE_";
1477     requiredInfoPropName += this->Name;
1478     requiredInfoPropName += "_TYPE";
1479     this->Makefile->GetCMakeInstance()->SetProperty(
1480                                      requiredInfoPropName.c_str(), "REQUIRED");
1481     }
1482
1483
1484   // Restore original state of "_FIND_" variables we set.
1485   this->RestoreFindDefinitions();
1486 }
1487
1488 //----------------------------------------------------------------------------
1489 void cmFindPackageCommand::ComputePrefixes()
1490 {
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();
1501 }
1502
1503 //----------------------------------------------------------------------------
1504 void cmFindPackageCommand::AddPrefixesCMakeEnvironment()
1505 {
1506   if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath)
1507     {
1508     // Check the environment variable with the same name as the cache
1509     // entry.
1510     std::string env;
1511     if(cmSystemTools::GetEnv(this->Variable.c_str(), env) && env.length() > 0)
1512       {
1513       cmSystemTools::ConvertToUnixSlashes(env);
1514       this->AddPathInternal(env, EnvPath);
1515       }
1516
1517     this->AddEnvPath("CMAKE_PREFIX_PATH");
1518     this->AddEnvPath("CMAKE_FRAMEWORK_PATH");
1519     this->AddEnvPath("CMAKE_APPBUNDLE_PATH");
1520     }
1521 }
1522
1523 //----------------------------------------------------------------------------
1524 void cmFindPackageCommand::AddPrefixesCMakeVariable()
1525 {
1526   if(!this->NoCMakePath && !this->NoDefaultPath)
1527     {
1528     this->AddCMakePath("CMAKE_PREFIX_PATH");
1529     this->AddCMakePath("CMAKE_FRAMEWORK_PATH");
1530     this->AddCMakePath("CMAKE_APPBUNDLE_PATH");
1531     }
1532 }
1533
1534 //----------------------------------------------------------------------------
1535 void cmFindPackageCommand::AddPrefixesSystemEnvironment()
1536 {
1537   if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
1538     {
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)
1546       {
1547       std::string const& d = *i;
1548
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))
1552         {
1553         this->AddPathInternal(cmSystemTools::GetFilenamePath(d), EnvPath);
1554         }
1555       else
1556         {
1557         this->AddPathInternal(d, EnvPath);
1558         }
1559       }
1560     }
1561 }
1562
1563 //----------------------------------------------------------------------------
1564 void cmFindPackageCommand::AddPrefixesUserRegistry()
1565 {
1566   if(this->NoUserRegistry || this->NoDefaultPath)
1567     {
1568     return;
1569     }
1570
1571 #if defined(_WIN32) && !defined(__CYGWIN__)
1572   this->LoadPackageRegistryWinUser();
1573 #elif defined(__HAIKU__)
1574   BPath dir;
1575   if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK)
1576     {
1577     dir.Append("cmake/packages");
1578     dir.Append(this->Name.c_str());
1579     this->LoadPackageRegistryDir(dir.Path());
1580     }
1581 #else
1582   if(const char* home = cmSystemTools::GetEnv("HOME"))
1583     {
1584     std::string dir = home;
1585     dir += "/.cmake/packages/";
1586     dir += this->Name;
1587     this->LoadPackageRegistryDir(dir);
1588     }
1589 #endif
1590 }
1591
1592 //----------------------------------------------------------------------------
1593 void cmFindPackageCommand::AddPrefixesSystemRegistry()
1594 {
1595   if(this->NoSystemRegistry || this->NoDefaultPath)
1596     {
1597     return;
1598     }
1599
1600 #if defined(_WIN32) && !defined(__CYGWIN__)
1601   this->LoadPackageRegistryWinSystem();
1602 #endif
1603 }
1604
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
1611 # endif
1612 # if !defined(KEY_WOW64_64KEY)
1613 #  define KEY_WOW64_64KEY 0x0100
1614 # endif
1615 //----------------------------------------------------------------------------
1616 void cmFindPackageCommand::LoadPackageRegistryWinUser()
1617 {
1618   // HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
1619   this->LoadPackageRegistryWin(true, 0);
1620 }
1621
1622 //----------------------------------------------------------------------------
1623 void cmFindPackageCommand::LoadPackageRegistryWinSystem()
1624 {
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())
1628     {
1629     this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
1630     this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
1631     }
1632   else
1633     {
1634     this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
1635     this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
1636     }
1637 }
1638
1639 //----------------------------------------------------------------------------
1640 void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
1641                                                   unsigned int view)
1642 {
1643   std::string key = "Software\\Kitware\\CMake\\Packages\\";
1644   key += this->Name;
1645   std::set<cmStdString> bad;
1646   HKEY hKey;
1647   if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
1648                   0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
1649     {
1650     DWORD valueType = REG_NONE;
1651     char name[16384];
1652     std::vector<char> data(512);
1653     bool done = false;
1654     DWORD index = 0;
1655     while(!done)
1656       {
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))
1661         {
1662         case ERROR_SUCCESS:
1663           ++index;
1664           if(valueType == REG_SZ)
1665             {
1666             data[dataSize] = 0;
1667             cmsys_ios::stringstream ss(&data[0]);
1668             if(!this->CheckPackageRegistryEntry(ss))
1669               {
1670               // The entry is invalid.
1671               bad.insert(name);
1672               }
1673             }
1674           break;
1675         case ERROR_MORE_DATA:
1676           data.resize(dataSize+1);
1677           break;
1678         case ERROR_NO_MORE_ITEMS: default: done = true; break;
1679         }
1680       }
1681     RegCloseKey(hKey);
1682     }
1683
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)
1688     {
1689     for(std::set<cmStdString>::const_iterator vi = bad.begin();
1690         vi != bad.end(); ++vi)
1691       {
1692       RegDeleteValue(hKey, vi->c_str());
1693       }
1694     RegCloseKey(hKey);
1695     }
1696 }
1697 #else
1698 //----------------------------------------------------------------------------
1699 class cmFindPackageCommandHoldFile
1700 {
1701   const char* File;
1702 public:
1703   cmFindPackageCommandHoldFile(const char* f): File(f) {}
1704   ~cmFindPackageCommandHoldFile()
1705     { if(this->File) { cmSystemTools::RemoveFile(this->File); } }
1706   void Release() { this->File = 0; }
1707 };
1708
1709 //----------------------------------------------------------------------------
1710 void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
1711 {
1712   cmsys::Directory files;
1713   if(!files.Load(dir.c_str()))
1714     {
1715     return;
1716     }
1717
1718   std::string fname;
1719   for(unsigned long i=0; i < files.GetNumberOfFiles(); ++i)
1720     {
1721     fname = dir;
1722     fname += "/";
1723     fname += files.GetFile(i);
1724
1725     if(!cmSystemTools::FileIsDirectory(fname.c_str()))
1726       {
1727       // Hold this file hostage until it behaves.
1728       cmFindPackageCommandHoldFile holdFile(fname.c_str());
1729
1730       // Load the file.
1731       std::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary);
1732       if(fin && this->CheckPackageRegistryEntry(fin))
1733         {
1734         // The file references an existing package, so release it.
1735         holdFile.Release();
1736         }
1737       }
1738     }
1739
1740   // TODO: Wipe out the directory if it is empty.
1741 }
1742 #endif
1743
1744 //----------------------------------------------------------------------------
1745 bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is)
1746 {
1747   // Parse the content of one package registry entry.
1748   std::string fname;
1749   if(cmSystemTools::GetLineFromStream(is, fname) &&
1750      cmSystemTools::FileIsFullPath(fname.c_str()))
1751     {
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()))
1755       {
1756       // The path exists.  Look for the package here.
1757       if(!cmSystemTools::FileIsDirectory(fname.c_str()))
1758         {
1759         fname = cmSystemTools::GetFilenamePath(fname);
1760         }
1761       this->AddPathInternal(fname, FullPath);
1762       return true;
1763       }
1764     else
1765       {
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.
1769       return false;
1770       }
1771     }
1772   else
1773     {
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.
1777     return true;
1778     }
1779 }
1780
1781 //----------------------------------------------------------------------------
1782 void cmFindPackageCommand::AddPrefixesBuilds()
1783 {
1784   if(!this->NoBuilds && !this->NoDefaultPath)
1785     {
1786     // It is likely that CMake will have recently built the project.
1787     for(int i=0; i <= 10; ++i)
1788       {
1789       cmOStringStream r;
1790       r <<
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()))
1798         {
1799         this->AddPathInternal(f, FullPath);
1800         }
1801       }
1802     }
1803 }
1804
1805 //----------------------------------------------------------------------------
1806 void cmFindPackageCommand::AddPrefixesCMakeSystemVariable()
1807 {
1808   if(!this->NoCMakeSystemPath && !this->NoDefaultPath)
1809     {
1810     this->AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
1811     this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
1812     this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
1813     }
1814 }
1815
1816 //----------------------------------------------------------------------------
1817 void cmFindPackageCommand::AddPrefixesUserGuess()
1818 {
1819   // Add guesses specified by the caller.
1820   this->AddPathsInternal(this->UserPaths, CMakePath);
1821 }
1822
1823 //----------------------------------------------------------------------------
1824 void cmFindPackageCommand::AddPrefixesUserHints()
1825 {
1826   // Add hints specified by the caller.
1827   this->AddPathsInternal(this->UserHints, CMakePath);
1828 }
1829
1830 //----------------------------------------------------------------------------
1831 bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
1832 {
1833   assert(!dir.empty() && dir[dir.size()-1] == '/');
1834
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)
1839     {
1840     std::string d = dir;
1841     if(!si->empty())
1842       {
1843       d += *si;
1844       d += "/";
1845       }
1846     if(this->CheckDirectory(d))
1847       {
1848       return true;
1849       }
1850     }
1851   return false;
1852 }
1853
1854 //----------------------------------------------------------------------------
1855 bool cmFindPackageCommand::CheckDirectory(std::string const& dir)
1856 {
1857   assert(!dir.empty() && dir[dir.size()-1] == '/');
1858
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))
1862     {
1863     // Remove duplicate slashes.
1864     cmSystemTools::ConvertToUnixSlashes(this->FileFound);
1865     return true;
1866     }
1867   return false;
1868 }
1869
1870 //----------------------------------------------------------------------------
1871 bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
1872                                           std::string& file)
1873 {
1874   if (this->IgnoredPaths.count(dir))
1875     {
1876     return false;
1877     }
1878
1879   for(std::vector<std::string>::const_iterator ci = this->Configs.begin();
1880       ci != this->Configs.end(); ++ci)
1881     {
1882     file = dir;
1883     file += "/";
1884     file += *ci;
1885     if(this->DebugMode)
1886       {
1887       fprintf(stderr, "Checking file [%s]\n", file.c_str());
1888       }
1889     if(cmSystemTools::FileExists(file.c_str(), true) &&
1890        this->CheckVersion(file))
1891       {
1892       return true;
1893       }
1894     }
1895   return false;
1896 }
1897
1898 //----------------------------------------------------------------------------
1899 bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
1900 {
1901   bool result = false; // by default, assume the version is not ok.
1902   bool haveResult = false;
1903   std::string version = "unknown";
1904
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);
1908
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)))
1914     {
1915     result = this->CheckVersionFile(version_file, version);
1916     haveResult = true;
1917     }
1918
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)))
1924     {
1925     result = this->CheckVersionFile(version_file, version);
1926     haveResult = true;
1927     }
1928
1929
1930   // If no version was requested a versionless package is acceptable.
1931   if ((haveResult == false) && (this->Version.empty()))
1932     {
1933     result = true;
1934     haveResult = true;
1935     }
1936
1937   ConfigFileInfo configFileInfo;
1938   configFileInfo.filename = config_file;
1939   configFileInfo.version = version;
1940   this->ConsideredConfigs.push_back(configFileInfo);
1941
1942   return result;
1943 }
1944
1945 //----------------------------------------------------------------------------
1946 bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
1947                                             std::string& result_version)
1948 {
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);
1954
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");
1960
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());
1965   char buf[64];
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);
1976
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))
1981     {
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)
1986       {
1987       okay = this->Makefile->IsOn("PACKAGE_VERSION_COMPATIBLE");
1988       }
1989
1990     // The package is suitable if the version is okay and not
1991     // explicitly unsuitable.
1992     suitable = !unsuitable && (okay || this->Version.empty());
1993     if(suitable)
1994       {
1995       // Get the version found.
1996       this->VersionFound =
1997         this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
1998
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)
2010         {
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!
2015         default: break;
2016         }
2017       }
2018     }
2019
2020   result_version = this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
2021   if (result_version.empty())
2022     {
2023     result_version = "unknown";
2024     }
2025
2026   // Succeed if the version is suitable.
2027   return suitable;
2028 }
2029
2030 //----------------------------------------------------------------------------
2031 void cmFindPackageCommand::StoreVersionFound()
2032 {
2033   // Store the whole version string.
2034   std::string ver = this->Name;
2035   ver += "_VERSION";
2036   if(this->VersionFound.empty())
2037     {
2038     this->Makefile->RemoveDefinition(ver.c_str());
2039     }
2040   else
2041     {
2042     this->Makefile->AddDefinition(ver.c_str(), this->VersionFound.c_str());
2043     }
2044
2045   // Store the version components.
2046   char buf[64];
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);
2057 }
2058
2059 //----------------------------------------------------------------------------
2060 #include <cmsys/Glob.hxx>
2061 #include <cmsys/String.h>
2062 #include <cmsys/auto_ptr.hxx>
2063
2064 class cmFileList;
2065 class cmFileListGeneratorBase
2066 {
2067 public:
2068   virtual ~cmFileListGeneratorBase() {}
2069 protected:
2070   bool Consider(std::string const& fullPath, cmFileList& listing);
2071 private:
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;
2078 };
2079
2080 class cmFileList
2081 {
2082 public:
2083   cmFileList(): First(), Last(0) {}
2084   virtual ~cmFileList() {}
2085   cmFileList& operator/(cmFileListGeneratorBase const& rhs)
2086     {
2087     if(this->Last)
2088       {
2089       this->Last = this->Last->SetNext(rhs);
2090       }
2091     else
2092       {
2093       this->First = rhs.Clone();
2094       this->Last = this->First.get();
2095       }
2096     return *this;
2097     }
2098   bool Search()
2099     {
2100     if(this->First.get())
2101       {
2102       return this->First->Search(*this);
2103       }
2104     return false;
2105     }
2106 private:
2107   virtual bool Visit(std::string const& fullPath) = 0;
2108   friend class cmFileListGeneratorBase;
2109   cmsys::auto_ptr<cmFileListGeneratorBase> First;
2110   cmFileListGeneratorBase* Last;
2111 };
2112
2113 class cmFindPackageFileList: public cmFileList
2114 {
2115 public:
2116   cmFindPackageFileList(cmFindPackageCommand* fpc,
2117                         bool use_suffixes = true):
2118     cmFileList(), FPC(fpc), UseSuffixes(use_suffixes) {}
2119 private:
2120   bool Visit(std::string const& fullPath)
2121     {
2122     if(this->UseSuffixes)
2123       {
2124       return this->FPC->SearchDirectory(fullPath);
2125       }
2126     else
2127       {
2128       return this->FPC->CheckDirectory(fullPath);
2129       }
2130     }
2131   cmFindPackageCommand* FPC;
2132   bool UseSuffixes;
2133 };
2134
2135 bool cmFileListGeneratorBase::Search(cmFileList& listing)
2136 {
2137   return this->Search("", listing);
2138 }
2139
2140 cmFileListGeneratorBase*
2141 cmFileListGeneratorBase::SetNext(cmFileListGeneratorBase const& next)
2142 {
2143   this->Next = next.Clone();
2144   return this->Next.get();
2145 }
2146
2147 bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
2148                                        cmFileList& listing)
2149 {
2150   if(this->Next.get())
2151     {
2152     return this->Next->Search(fullPath + "/", listing);
2153     }
2154   else
2155     {
2156     return listing.Visit(fullPath + "/");
2157     }
2158 }
2159
2160 class cmFileListGeneratorFixed: public cmFileListGeneratorBase
2161 {
2162 public:
2163   cmFileListGeneratorFixed(std::string const& str):
2164     cmFileListGeneratorBase(), String(str) {}
2165   cmFileListGeneratorFixed(cmFileListGeneratorFixed const& r):
2166     cmFileListGeneratorBase(), String(r.String) {}
2167 private:
2168   std::string String;
2169   virtual bool Search(std::string const& parent, cmFileList& lister)
2170     {
2171     std::string fullPath = parent + this->String;
2172     return this->Consider(fullPath, lister);
2173     }
2174   virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2175     {
2176     cmsys::auto_ptr<cmFileListGeneratorBase>
2177       g(new cmFileListGeneratorFixed(*this));
2178     return g;
2179     }
2180 };
2181
2182 class cmFileListGeneratorEnumerate: public cmFileListGeneratorBase
2183 {
2184 public:
2185   cmFileListGeneratorEnumerate(std::vector<std::string> const& v):
2186     cmFileListGeneratorBase(), Vector(v) {}
2187   cmFileListGeneratorEnumerate(cmFileListGeneratorEnumerate const& r):
2188     cmFileListGeneratorBase(), Vector(r.Vector) {}
2189 private:
2190   std::vector<std::string> const& Vector;
2191   virtual bool Search(std::string const& parent, cmFileList& lister)
2192     {
2193     for(std::vector<std::string>::const_iterator i = this->Vector.begin();
2194         i != this->Vector.end(); ++i)
2195       {
2196       if(this->Consider(parent + *i, lister))
2197         {
2198         return true;
2199         }
2200       }
2201     return false;
2202     }
2203   virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2204     {
2205     cmsys::auto_ptr<cmFileListGeneratorBase>
2206       g(new cmFileListGeneratorEnumerate(*this));
2207     return g;
2208     }
2209 };
2210
2211 class cmFileListGeneratorProject: public cmFileListGeneratorBase
2212 {
2213 public:
2214   cmFileListGeneratorProject(std::vector<std::string> const& names):
2215     cmFileListGeneratorBase(), Names(names) {}
2216   cmFileListGeneratorProject(cmFileListGeneratorProject const& r):
2217     cmFileListGeneratorBase(), Names(r.Names) {}
2218 private:
2219   std::vector<std::string> const& Names;
2220   virtual bool Search(std::string const& parent, cmFileList& lister)
2221     {
2222     // Construct a list of matches.
2223     std::vector<std::string> matches;
2224     cmsys::Directory d;
2225     d.Load(parent.c_str());
2226     for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
2227       {
2228       const char* fname = d.GetFile(i);
2229       if(strcmp(fname, ".") == 0 ||
2230          strcmp(fname, "..") == 0)
2231         {
2232         continue;
2233         }
2234       for(std::vector<std::string>::const_iterator ni = this->Names.begin();
2235           ni != this->Names.end(); ++ni)
2236         {
2237         if(cmsysString_strncasecmp(fname, ni->c_str(),
2238                                    ni->length()) == 0)
2239           {
2240           matches.push_back(fname);
2241           }
2242         }
2243       }
2244
2245     for(std::vector<std::string>::const_iterator i = matches.begin();
2246         i != matches.end(); ++i)
2247       {
2248       if(this->Consider(parent + *i, lister))
2249         {
2250         return true;
2251         }
2252       }
2253     return false;
2254     }
2255   virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2256     {
2257     cmsys::auto_ptr<cmFileListGeneratorBase>
2258       g(new cmFileListGeneratorProject(*this));
2259     return g;
2260     }
2261 };
2262
2263 class cmFileListGeneratorMacProject: public cmFileListGeneratorBase
2264 {
2265 public:
2266   cmFileListGeneratorMacProject(std::vector<std::string> const& names,
2267                                 const char* ext):
2268     cmFileListGeneratorBase(), Names(names), Extension(ext) {}
2269   cmFileListGeneratorMacProject(cmFileListGeneratorMacProject const& r):
2270     cmFileListGeneratorBase(), Names(r.Names), Extension(r.Extension) {}
2271 private:
2272   std::vector<std::string> const& Names;
2273   std::string Extension;
2274   virtual bool Search(std::string const& parent, cmFileList& lister)
2275     {
2276     // Construct a list of matches.
2277     std::vector<std::string> matches;
2278     cmsys::Directory d;
2279     d.Load(parent.c_str());
2280     for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
2281       {
2282       const char* fname = d.GetFile(i);
2283       if(strcmp(fname, ".") == 0 ||
2284          strcmp(fname, "..") == 0)
2285         {
2286         continue;
2287         }
2288       for(std::vector<std::string>::const_iterator ni = this->Names.begin();
2289           ni != this->Names.end(); ++ni)
2290         {
2291         std::string name = *ni;
2292         name += this->Extension;
2293         if(cmsysString_strcasecmp(fname, name.c_str()) == 0)
2294           {
2295           matches.push_back(fname);
2296           }
2297         }
2298       }
2299
2300     for(std::vector<std::string>::const_iterator i = matches.begin();
2301         i != matches.end(); ++i)
2302       {
2303       if(this->Consider(parent + *i, lister))
2304         {
2305         return true;
2306         }
2307       }
2308     return false;
2309     }
2310   virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2311     {
2312     cmsys::auto_ptr<cmFileListGeneratorBase>
2313       g(new cmFileListGeneratorMacProject(*this));
2314     return g;
2315     }
2316 };
2317
2318 class cmFileListGeneratorCaseInsensitive: public cmFileListGeneratorBase
2319 {
2320 public:
2321   cmFileListGeneratorCaseInsensitive(std::string const& str):
2322     cmFileListGeneratorBase(), String(str) {}
2323   cmFileListGeneratorCaseInsensitive(
2324     cmFileListGeneratorCaseInsensitive const& r):
2325     cmFileListGeneratorBase(), String(r.String) {}
2326 private:
2327   std::string String;
2328   virtual bool Search(std::string const& parent, cmFileList& lister)
2329     {
2330     // Look for matching files.
2331     std::vector<std::string> matches;
2332     cmsys::Directory d;
2333     d.Load(parent.c_str());
2334     for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
2335       {
2336       const char* fname = d.GetFile(i);
2337       if(strcmp(fname, ".") == 0 ||
2338          strcmp(fname, "..") == 0)
2339         {
2340         continue;
2341         }
2342       if(cmsysString_strcasecmp(fname, this->String.c_str()) == 0)
2343         {
2344         if(this->Consider(parent + fname, lister))
2345           {
2346           return true;
2347           }
2348         }
2349       }
2350     return false;
2351     }
2352   virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2353     {
2354     cmsys::auto_ptr<cmFileListGeneratorBase>
2355       g(new cmFileListGeneratorCaseInsensitive(*this));
2356     return g;
2357     }
2358 };
2359
2360 class cmFileListGeneratorGlob: public cmFileListGeneratorBase
2361 {
2362 public:
2363   cmFileListGeneratorGlob(std::string const& str):
2364     cmFileListGeneratorBase(), Pattern(str) {}
2365   cmFileListGeneratorGlob(cmFileListGeneratorGlob const& r):
2366     cmFileListGeneratorBase(), Pattern(r.Pattern) {}
2367 private:
2368   std::string Pattern;
2369   virtual bool Search(std::string const& parent, cmFileList& lister)
2370     {
2371     // Glob the set of matching files.
2372     std::string expr = parent;
2373     expr += this->Pattern;
2374     cmsys::Glob g;
2375     if(!g.FindFiles(expr))
2376       {
2377       return false;
2378       }
2379     std::vector<std::string> const& files = g.GetFiles();
2380
2381     // Look for directories among the matches.
2382     for(std::vector<std::string>::const_iterator fi = files.begin();
2383         fi != files.end(); ++fi)
2384       {
2385       if(cmSystemTools::FileIsDirectory(fi->c_str()))
2386         {
2387         if(this->Consider(*fi, lister))
2388           {
2389           return true;
2390           }
2391         }
2392       }
2393     return false;
2394     }
2395   virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
2396     {
2397     cmsys::auto_ptr<cmFileListGeneratorBase>
2398       g(new cmFileListGeneratorGlob(*this));
2399     return g;
2400     }
2401 };
2402
2403 //----------------------------------------------------------------------------
2404 bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
2405 {
2406   assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
2407   if(this->DebugMode)
2408     {
2409     fprintf(stderr, "Checking prefix [%s]\n", prefix_in.c_str());
2410     }
2411
2412   // Skip this if the prefix does not exist.
2413   if(!cmSystemTools::FileIsDirectory(prefix_in.c_str()))
2414     {
2415     return false;
2416     }
2417
2418   //  PREFIX/ (useful on windows or in build trees)
2419   if(this->SearchDirectory(prefix_in))
2420     {
2421     return true;
2422     }
2423
2424   // Strip the trailing slash because the path generator is about to
2425   // add one.
2426   std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
2427
2428   //  PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
2429   {
2430   cmFindPackageFileList lister(this);
2431   lister
2432     / cmFileListGeneratorFixed(prefix)
2433     / cmFileListGeneratorCaseInsensitive("cmake");
2434   if(lister.Search())
2435     {
2436     return true;
2437     }
2438   }
2439
2440   //  PREFIX/(Foo|foo|FOO).*/
2441   {
2442   cmFindPackageFileList lister(this);
2443   lister
2444     / cmFileListGeneratorFixed(prefix)
2445     / cmFileListGeneratorProject(this->Names);
2446   if(lister.Search())
2447     {
2448     return true;
2449     }
2450   }
2451
2452   //  PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
2453   {
2454   cmFindPackageFileList lister(this);
2455   lister
2456     / cmFileListGeneratorFixed(prefix)
2457     / cmFileListGeneratorProject(this->Names)
2458     / cmFileListGeneratorCaseInsensitive("cmake");
2459   if(lister.Search())
2460     {
2461     return true;
2462     }
2463   }
2464
2465   // Construct list of common install locations (lib and share).
2466   std::vector<std::string> common;
2467   if(!this->LibraryArchitecture.empty())
2468     {
2469     common.push_back("lib/"+this->LibraryArchitecture);
2470     }
2471   if(this->UseLib64Paths)
2472     {
2473     common.push_back("lib64");
2474     }
2475   common.push_back("lib");
2476   common.push_back("share");
2477
2478   //  PREFIX/(lib/ARCH|lib|share)/cmake/(Foo|foo|FOO).*/
2479   {
2480   cmFindPackageFileList lister(this);
2481   lister
2482     / cmFileListGeneratorFixed(prefix)
2483     / cmFileListGeneratorEnumerate(common)
2484     / cmFileListGeneratorFixed("cmake")
2485     / cmFileListGeneratorProject(this->Names);
2486   if(lister.Search())
2487     {
2488     return true;
2489     }
2490   }
2491
2492   //  PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/
2493   {
2494   cmFindPackageFileList lister(this);
2495   lister
2496     / cmFileListGeneratorFixed(prefix)
2497     / cmFileListGeneratorEnumerate(common)
2498     / cmFileListGeneratorProject(this->Names);
2499   if(lister.Search())
2500     {
2501     return true;
2502     }
2503   }
2504
2505   //  PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/(cmake|CMake)/
2506   {
2507   cmFindPackageFileList lister(this);
2508   lister
2509     / cmFileListGeneratorFixed(prefix)
2510     / cmFileListGeneratorEnumerate(common)
2511     / cmFileListGeneratorProject(this->Names)
2512     / cmFileListGeneratorCaseInsensitive("cmake");
2513   if(lister.Search())
2514     {
2515     return true;
2516     }
2517   }
2518
2519   return false;
2520 }
2521
2522 //----------------------------------------------------------------------------
2523 bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
2524 {
2525   assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
2526   if(this->DebugMode)
2527     {
2528     fprintf(stderr, "Checking framework prefix [%s]\n", prefix_in.c_str());
2529     }
2530
2531   // Strip the trailing slash because the path generator is about to
2532   // add one.
2533   std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
2534
2535   // <prefix>/Foo.framework/Resources/
2536   {
2537   cmFindPackageFileList lister(this);
2538   lister
2539     / cmFileListGeneratorFixed(prefix)
2540     / cmFileListGeneratorMacProject(this->Names, ".framework")
2541     / cmFileListGeneratorFixed("Resources");
2542   if(lister.Search())
2543     {
2544     return true;
2545     }
2546   }
2547   // <prefix>/Foo.framework/Resources/CMake/
2548   {
2549   cmFindPackageFileList lister(this);
2550   lister
2551     / cmFileListGeneratorFixed(prefix)
2552     / cmFileListGeneratorMacProject(this->Names, ".framework")
2553     / cmFileListGeneratorFixed("Resources")
2554     / cmFileListGeneratorCaseInsensitive("cmake");
2555   if(lister.Search())
2556     {
2557     return true;
2558     }
2559   }
2560
2561   // <prefix>/Foo.framework/Versions/*/Resources/
2562   {
2563   cmFindPackageFileList lister(this);
2564   lister
2565     / cmFileListGeneratorFixed(prefix)
2566     / cmFileListGeneratorMacProject(this->Names, ".framework")
2567     / cmFileListGeneratorFixed("Versions")
2568     / cmFileListGeneratorGlob("*/Resources");
2569   if(lister.Search())
2570     {
2571     return true;
2572     }
2573   }
2574
2575   // <prefix>/Foo.framework/Versions/*/Resources/CMake/
2576   {
2577   cmFindPackageFileList lister(this);
2578   lister
2579     / cmFileListGeneratorFixed(prefix)
2580     / cmFileListGeneratorMacProject(this->Names, ".framework")
2581     / cmFileListGeneratorFixed("Versions")
2582     / cmFileListGeneratorGlob("*/Resources")
2583     / cmFileListGeneratorCaseInsensitive("cmake");
2584   if(lister.Search())
2585     {
2586     return true;
2587     }
2588   }
2589
2590   return false;
2591 }
2592
2593 //----------------------------------------------------------------------------
2594 bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
2595 {
2596   assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
2597   if(this->DebugMode)
2598     {
2599     fprintf(stderr, "Checking bundle prefix [%s]\n", prefix_in.c_str());
2600     }
2601
2602   // Strip the trailing slash because the path generator is about to
2603   // add one.
2604   std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
2605
2606   // <prefix>/Foo.app/Contents/Resources
2607   {
2608   cmFindPackageFileList lister(this);
2609   lister
2610     / cmFileListGeneratorFixed(prefix)
2611     / cmFileListGeneratorMacProject(this->Names, ".app")
2612     / cmFileListGeneratorFixed("Contents/Resources");
2613   if(lister.Search())
2614     {
2615     return true;
2616     }
2617   }
2618
2619   // <prefix>/Foo.app/Contents/Resources/CMake
2620   {
2621   cmFindPackageFileList lister(this);
2622   lister
2623     / cmFileListGeneratorFixed(prefix)
2624     / cmFileListGeneratorMacProject(this->Names, ".app")
2625     / cmFileListGeneratorFixed("Contents/Resources")
2626     / cmFileListGeneratorCaseInsensitive("cmake");
2627   if(lister.Search())
2628     {
2629     return true;
2630     }
2631   }
2632
2633   return false;
2634 }
2635
2636 // TODO: Debug cmsys::Glob double slash problem.