cmFindPackageCommand.cxx 82.8 KB
Newer Older
1 2 3
/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4

5 6
  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.
7

8 9 10 11
  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
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 22 23 24
#if defined(__HAIKU__)
#include <StorageKit.h>
#endif

25
void cmFindPackageNeedBackwardsCompatibility(const std::string& variable,
26 27
  int access_type, void*, const char* newValue,
  const cmMakefile*)
28
{
29
  (void)newValue;
30
#ifdef CMAKE_BUILD_WITH_CMAKE
31 32 33 34 35 36 37 38 39 40 41 42 43 44
  if(access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
    {
    std::string message = "An attempt was made to access a variable: ";
    message += variable;
    message +=
      " that has not been defined. This variable is created by the "
      "FIND_PACKAGE command. CMake version 1.6 always converted the "
      "variable name to upper-case, but this behavior is no longer the "
      "case.  To fix this you might need to set the cache value of "
      "CMAKE_BACKWARDS_COMPATIBILITY to 1.6 or less.  If you are writing a "
      "CMake listfile, you should change the variable reference to use "
      "the case of the argument to FIND_PACKAGE.";
    cmSystemTools::Error(message.c_str());
    }
45 46 47 48
#else
  (void)variable;
  (void)access_type;
#endif
49 50
}

51 52 53 54 55 56
//----------------------------------------------------------------------------
cmFindPackageCommand::cmFindPackageCommand()
{
  this->CMakePathName = "PACKAGE";
  this->Quiet = false;
  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 66 67
  this->VersionMajor = 0;
  this->VersionMinor = 0;
  this->VersionPatch = 0;
68
  this->VersionTweak = 0;
69
  this->VersionCount = 0;
70 71 72 73
  this->VersionExact = false;
  this->VersionFoundMajor = 0;
  this->VersionFoundMinor = 0;
  this->VersionFoundPatch = 0;
74
  this->VersionFoundTweak = 0;
75
  this->VersionFoundCount = 0;
76
  this->RequiredCMakeVersion = 0;
Brad King's avatar
Brad King committed
77 78 79 80 81 82 83 84 85 86 87 88 89
}

//----------------------------------------------------------------------------
void cmFindPackageCommand::GenerateDocumentation()
{
  this->cmFindCommon::GenerateDocumentation();
  cmSystemTools::ReplaceString(this->GenericDocumentationRootPath,
                               "CMAKE_FIND_ROOT_PATH_MODE_XXX",
                               "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE");
  cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
                               "FIND_ARGS_XXX", "<package>");
  cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
                               "FIND_XXX", "find_package");
90
  this->CommandDocumentation =
91
    "  find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n"
92 93
    "               [[REQUIRED|COMPONENTS] [components...]]\n"
    "               [NO_POLICY_SCOPE])\n"
94 95 96 97 98
    "Finds and loads settings from an external project.  "
    "<package>_FOUND will be set to indicate whether the package was found.  "
    "When the package is found package-specific information is provided "
    "through variables documented by the package itself.  "
    "The QUIET option disables messages if the package cannot be found.  "
99
    "The MODULE option disables the second signature documented below.  "
100 101 102 103 104
    "The REQUIRED option stops processing with an error message if the "
    "package cannot be found.  "
    "A package-specific list of components may be listed after the "
    "REQUIRED option or after the COMPONENTS option if no REQUIRED "
    "option is given.  "
105 106
    "The [version] argument requests a version with which the package found "
    "should be compatible (format is major[.minor[.patch[.tweak]]]).  "
107
    "The EXACT option requests that the version be matched exactly.  "
108 109 110 111
    "If no [version] and/or component list is given to a recursive "
    "invocation inside a find-module, the corresponding arguments "
    "are forwarded automatically from the outer call (including the "
    "EXACT flag for [version]).  "
112
    "Version support is currently provided only on a package-by-package "
113
    "basis (details below).\n"
114 115 116 117 118 119 120 121 122 123 124 125
    "User code should generally look for packages using the above simple "
    "signature.  The remainder of this command documentation specifies the "
    "full command signature and details of the search process.  Project "
    "maintainers wishing to provide a package to be found by this command "
    "are encouraged to read on.\n"
    "The command has two modes by which it searches for packages: "
    "\"Module\" mode and \"Config\" mode.  "
    "Module mode is available when the command is invoked with the above "
    "reduced signature.  "
    "CMake searches for a file called \"Find<package>.cmake\" in "
    "the CMAKE_MODULE_PATH followed by the CMake installation.  "
    "If the file is found, it is read and processed by CMake.  "
126 127 128 129
    "It is responsible for finding the package, checking the version, "
    "and producing any needed messages.  "
    "Many find-modules provide limited or no support for versioning; "
    "check the module documentation.  "
130 131
    "If no module is found and the MODULE option is not given the command "
    "proceeds to Config mode.\n"
132
    "The complete Config mode command signature is:\n"
133
    "  find_package(<package> [version] [EXACT] [QUIET]\n"
134 135
    "               [[REQUIRED|COMPONENTS] [components...]]\n"
    "               [CONFIG|NO_MODULE]\n"
136
    "               [NO_POLICY_SCOPE]\n"
137 138
    "               [NAMES name1 [name2 ...]]\n"
    "               [CONFIGS config1 [config2 ...]]\n"
139
    "               [HINTS path1 [path2 ... ]]\n"
140 141 142 143 144 145
    "               [PATHS path1 [path2 ... ]]\n"
    "               [PATH_SUFFIXES suffix1 [suffix2 ...]]\n"
    "               [NO_DEFAULT_PATH]\n"
    "               [NO_CMAKE_ENVIRONMENT_PATH]\n"
    "               [NO_CMAKE_PATH]\n"
    "               [NO_SYSTEM_ENVIRONMENT_PATH]\n"
146
    "               [NO_CMAKE_PACKAGE_REGISTRY]\n"
147 148
    "               [NO_CMAKE_BUILDS_PATH]\n"
    "               [NO_CMAKE_SYSTEM_PATH]\n"
149
    "               [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]\n"
150 151 152
    "               [CMAKE_FIND_ROOT_PATH_BOTH |\n"
    "                ONLY_CMAKE_FIND_ROOT_PATH |\n"
    "                NO_CMAKE_FIND_ROOT_PATH])\n"
153 154 155 156
    "The CONFIG option may be used to skip Module mode explicitly and "
    "switch to Config mode.  It is synonymous to using NO_MODULE.  "
    "Config mode is also implied by use of options not specified in the "
    "reduced signature.  "
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    "\n"
    "Config mode attempts to locate a configuration file provided by the "
    "package to be found.  A cache entry called <package>_DIR is created to "
    "hold the directory containing the file.  "
    "By default the command searches for a package with the name <package>.  "
    "If the NAMES option is given the names following it are used instead "
    "of <package>.  "
    "The command searches for a file called \"<name>Config.cmake\" or "
    "\"<lower-case-name>-config.cmake\" for each name specified.  "
    "A replacement set of possible configuration file names may be given "
    "using the CONFIGS option.  "
    "The search procedure is specified below.  Once found, the configuration "
    "file is read and processed by CMake.  Since the file is provided by the "
    "package it already knows the location of package contents.  "
    "The full path to the configuration file is stored in the cmake "
    "variable <package>_CONFIG."
    "\n"
174 175 176 177 178
    "All configuration files which have been considered by CMake while "
    "searching for an installation of the package with an appropriate "
    "version are stored in the cmake variable <package>_CONSIDERED_CONFIGS, "
    "the associated versions in <package>_CONSIDERED_VERSIONS. "
    "\n"
179 180 181 182 183
    "If the package configuration file cannot be found CMake "
    "will generate an error describing the problem unless the QUIET "
    "argument is specified.  If REQUIRED is specified and the package "
    "is not found a fatal error is generated and the configure step stops "
    "executing.  If <package>_DIR has been set to a directory not containing "
184
    "a configuration file CMake will ignore it and search from scratch."
185
    "\n"
186 187 188
    "When the [version] argument is given Config mode will only find a "
    "version of the package that claims compatibility with the requested "
    "version (format is major[.minor[.patch[.tweak]]]).  "
189 190 191 192 193 194
    "If the EXACT option is given only a version of the package claiming "
    "an exact match of the requested version may be found.  "
    "CMake does not establish any convention for the meaning of version "
    "numbers.  "
    "Package version numbers are checked by \"version\" files provided by "
    "the packages themselves.  "
195
    "For a candidate package configuration file \"<config-file>.cmake\" the "
196 197 198 199
    "corresponding version file is located next to it and named either "
    "\"<config-file>-version.cmake\" or \"<config-file>Version.cmake\".  "
    "If no such version file is available then the configuration file "
    "is assumed to not be compatible with any requested version.  "
200
    "A basic version file containing generic version matching code can be "
201
    "created using the macro write_basic_package_version_file(), see its "
202
    "documentation for more details.  "
203 204 205 206 207 208
    "When a version file is found it is loaded to check the requested "
    "version number.  "
    "The version file is loaded in a nested scope in which the following "
    "variables have been defined:\n"
    "  PACKAGE_FIND_NAME          = the <package> name\n"
    "  PACKAGE_FIND_VERSION       = full requested version string\n"
209 210 211 212 213
    "  PACKAGE_FIND_VERSION_MAJOR = major version if requested, else 0\n"
    "  PACKAGE_FIND_VERSION_MINOR = minor version if requested, else 0\n"
    "  PACKAGE_FIND_VERSION_PATCH = patch version if requested, else 0\n"
    "  PACKAGE_FIND_VERSION_TWEAK = tweak version if requested, else 0\n"
    "  PACKAGE_FIND_VERSION_COUNT = number of version components, 0 to 4\n"
214 215
    "The version file checks whether it satisfies the requested version "
    "and sets these variables:\n"
216
    "  PACKAGE_VERSION            = full provided version string\n"
217 218
    "  PACKAGE_VERSION_EXACT      = true if version is exact match\n"
    "  PACKAGE_VERSION_COMPATIBLE = true if version is compatible\n"
219
    "  PACKAGE_VERSION_UNSUITABLE = true if unsuitable as any version\n"
220 221 222 223
    "These variables are checked by the find_package command to determine "
    "whether the configuration file provides an acceptable version.  "
    "They are not available after the find_package call returns.  "
    "If the version is acceptable the following variables are set:\n"
224 225 226 227 228 229
    "  <package>_VERSION       = full provided version string\n"
    "  <package>_VERSION_MAJOR = major version if provided, else 0\n"
    "  <package>_VERSION_MINOR = minor version if provided, else 0\n"
    "  <package>_VERSION_PATCH = patch version if provided, else 0\n"
    "  <package>_VERSION_TWEAK = tweak version if provided, else 0\n"
    "  <package>_VERSION_COUNT = number of version components, 0 to 4\n"
230 231 232 233 234
    "and the corresponding package configuration file is loaded.  "
    "When multiple package configuration files are available whose version "
    "files claim compatibility with the version requested it is unspecified "
    "which one is chosen.  "
    "No attempt is made to choose a highest or closest version number."
235
    "\n"
236 237 238 239
    "Config mode provides an elaborate interface and search procedure.  "
    "Much of the interface is provided for completeness and for use "
    "internally by find-modules loaded by Module mode.  "
    "Most user code should simply call\n"
240
    "  find_package(<package> [major[.minor]] [EXACT] [REQUIRED|QUIET])\n"
241 242 243 244 245
    "in order to find a package.  Package maintainers providing CMake "
    "package configuration files are encouraged to name and install "
    "them such that the procedure outlined below will find them "
    "without requiring use of additional options."
    "\n"
246
    "CMake constructs a set of possible installation prefixes for the "
247 248 249 250
    "package.  Under each prefix several directories are searched for a "
    "configuration file.  The tables below show the directories searched.  "
    "Each entry is meant for installation trees following Windows (W), "
    "UNIX (U), or Apple (A) conventions.\n"
251 252
    "  <prefix>/                                               (W)\n"
    "  <prefix>/(cmake|CMake)/                                 (W)\n"
253 254
    "  <prefix>/<name>*/                                       (W)\n"
    "  <prefix>/<name>*/(cmake|CMake)/                         (W)\n"
255 256 257
    "  <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/          (U)\n"
    "  <prefix>/(lib/<arch>|lib|share)/<name>*/                (U)\n"
    "  <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/  (U)\n"
258 259 260 261 262 263 264 265 266 267 268
    "On systems supporting OS X Frameworks and Application Bundles "
    "the following directories are searched for frameworks or bundles "
    "containing a configuration file:\n"
    "  <prefix>/<name>.framework/Resources/                    (A)\n"
    "  <prefix>/<name>.framework/Resources/CMake/              (A)\n"
    "  <prefix>/<name>.framework/Versions/*/Resources/         (A)\n"
    "  <prefix>/<name>.framework/Versions/*/Resources/CMake/   (A)\n"
    "  <prefix>/<name>.app/Contents/Resources/                 (A)\n"
    "  <prefix>/<name>.app/Contents/Resources/CMake/           (A)\n"
    "In all cases the <name> is treated as case-insensitive and corresponds "
    "to any of the names specified (<package> or names given by NAMES).  "
269
    "Paths with lib/<arch> are enabled if CMAKE_LIBRARY_ARCHITECTURE is set.  "
270
    "If PATH_SUFFIXES is specified the suffixes are appended to each "
271
    "(W) or (U) directory entry one-by-one.\n"
272 273 274 275
    "This set of directories is intended to work in cooperation with "
    "projects that provide configuration files in their installation trees.  "
    "Directories above marked with (W) are intended for installations on "
    "Windows where the prefix may point at the top of an application's "
276 277 278
    "installation directory.  Those marked with (U) are intended for "
    "installations on UNIX platforms where the prefix is shared by "
    "multiple packages.  This is merely a convention, so all (W) and (U) "
279 280 281 282 283 284
    "directories are still searched on all platforms.  "
    "Directories marked with (A) are intended for installations on "
    "Apple platforms.  The cmake variables CMAKE_FIND_FRAMEWORK and "
    "CMAKE_FIND_APPBUNDLE determine the order of preference "
    "as specified below.\n"
    "The set of installation prefixes is constructed using the following "
285 286 287 288
    "steps.  If NO_DEFAULT_PATH is specified all NO_* options are enabled.\n"
    "1. Search paths specified in cmake-specific cache variables.  "
    "These are intended to be used on the command line with a -DVAR=value.  "
    "This can be skipped if NO_CMAKE_PATH is passed.\n"
289 290 291
    "   CMAKE_PREFIX_PATH\n"
    "   CMAKE_FRAMEWORK_PATH\n"
    "   CMAKE_APPBUNDLE_PATH\n"
292 293 294
    "2. Search paths specified in cmake-specific environment variables.  "
    "These are intended to be set in the user's shell configuration.  "
    "This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.\n"
295
    "   <package>_DIR\n"
296 297 298
    "   CMAKE_PREFIX_PATH\n"
    "   CMAKE_FRAMEWORK_PATH\n"
    "   CMAKE_APPBUNDLE_PATH\n"
299 300 301 302 303
    "3. Search paths specified by the HINTS option.  "
    "These should be paths computed by system introspection, such as a "
    "hint provided by the location of another item already found.  "
    "Hard-coded guesses should be specified with the PATHS option.\n"
    "4. Search the standard system environment variables. "
304 305 306 307
    "This can be skipped if NO_SYSTEM_ENVIRONMENT_PATH is passed.  "
    "Path entries ending in \"/bin\" or \"/sbin\" are automatically "
    "converted to their parent directories.\n"
    "   PATH\n"
308
    "5. Search project build trees recently configured in a CMake GUI.  "
309 310 311
    "This can be skipped if NO_CMAKE_BUILDS_PATH is passed.  "
    "It is intended for the case when a user is building multiple "
    "dependent projects one after another.\n"
312 313
    "6. Search paths stored in the CMake user package registry.  "
    "This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed.  "
314 315 316 317 318 319 320 321 322 323
    "On Windows a <package> may appear under registry key\n"
    "  HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Packages\\<package>\n"
    "as a REG_SZ value, with arbitrary name, that specifies the directory "
    "containing the package configuration file.  "
    "On UNIX platforms a <package> may appear under the directory\n"
    "  ~/.cmake/packages/<package>\n"
    "as a file, with arbitrary name, whose content specifies the directory "
    "containing the package configuration file.  "
    "See the export(PACKAGE) command to create user package registry entries "
    "for project build trees."
324 325
    "\n"
    "7. Search cmake variables defined in the Platform files "
326 327 328 329 330
    "for the current system.  This can be skipped if NO_CMAKE_SYSTEM_PATH "
    "is passed.\n"
    "   CMAKE_SYSTEM_PREFIX_PATH\n"
    "   CMAKE_SYSTEM_FRAMEWORK_PATH\n"
    "   CMAKE_SYSTEM_APPBUNDLE_PATH\n"
331 332 333 334 335 336 337 338 339
    "8. Search paths stored in the CMake system package registry.  "
    "This can be skipped if NO_CMAKE_SYSTEM_PACKAGE_REGISTRY is passed.  "
    "On Windows a <package> may appear under registry key\n"
    "  HKEY_LOCAL_MACHINE\\Software\\Kitware\\CMake\\Packages\\<package>\n"
    "as a REG_SZ value, with arbitrary name, that specifies the directory "
    "containing the package configuration file.  "
    "There is no system package registry on non-Windows platforms."
    "\n"
    "9. Search paths specified by the PATHS option.  "
340
    "These are typically hard-coded guesses.\n"
341 342 343 344
    ;
  this->CommandDocumentation += this->GenericDocumentationMacPolicy;
  this->CommandDocumentation += this->GenericDocumentationRootPath;
  this->CommandDocumentation += this->GenericDocumentationPathsOrder;
345 346
  this->CommandDocumentation +=
    "\n"
347 348 349 350
    "Every non-REQUIRED find_package() call can be disabled by setting the "
    "variable CMAKE_DISABLE_FIND_PACKAGE_<package> to TRUE. See the "
    "documentation for the CMAKE_DISABLE_FIND_PACKAGE_<package> variable for "
    "more information.\n"
351 352 353
    "See the cmake_policy() command documentation for discussion of the "
    "NO_POLICY_SCOPE option."
    ;
354 355 356
}

//----------------------------------------------------------------------------
357
const char* cmFindPackageCommand::GetFullDocumentation() const
358
{
Brad King's avatar
Brad King committed
359 360
  if(this->CommandDocumentation.empty())
    {
361
    const_cast<cmFindPackageCommand *>(this)->GenerateDocumentation();
Brad King's avatar
Brad King committed
362
    }
363 364 365
  return this->CommandDocumentation.c_str();
}

366
//----------------------------------------------------------------------------
367 368
bool cmFindPackageCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
369 370 371 372 373 374
{
  if(args.size() < 1)
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
375

376 377 378 379 380 381 382 383 384
  // Lookup required version of CMake.
  if(const char* rv =
     this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"))
    {
    unsigned int v[3] = {0,0,0};
    sscanf(rv, "%u.%u.%u", &v[0], &v[1], &v[2]);
    this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0],v[1],v[2]);
    }

385 386 387
  // Check for debug mode.
  this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");

388 389 390 391 392 393 394
  // Lookup target architecture, if any.
  if(const char* arch =
     this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
    {
    this->LibraryArchitecture = arch;
    }

395
  // Lookup whether lib64 paths should be used.
396 397 398
  if(this->Makefile->PlatformIs64Bit() &&
     this->Makefile->GetCMakeInstance()
     ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
399
    {
400
    this->UseLib64Paths = true;
401 402
    }

403 404 405 406 407 408
  // Find the current root path mode.
  this->SelectDefaultRootPathMode();

  // Find the current bundle/framework search policy.
  this->SelectDefaultMacMode();

409
  // Record options.
410
  this->Name = args[0];
411 412 413
  std::string components;
  const char* components_sep = "";

414 415 416 417 418 419 420 421
  // Check ancient compatibility.
  this->Compatibility_1_6 =
    this->Makefile->GetLocalGenerator()
    ->NeedBackwardsCompatibility(1, 6);

  // Always search directly in a generated path.
  this->SearchPathSuffixes.push_back("");

422
  // Parse the arguments.
423
  enum Doing { DoingNone, DoingComponents, DoingNames, DoingPaths,
424
               DoingPathSuffixes, DoingConfigs, DoingHints };
425
  Doing doing = DoingNone;
426 427
  cmsys::RegularExpression version("^[0-9.]+$");
  bool haveVersion = false;
428 429
  std::set<unsigned int> configArgs;
  std::set<unsigned int> moduleArgs;
430
  for(unsigned int i=1; i < args.size(); ++i)
431
    {
432
    if(args[i] == "QUIET")
433
      {
434 435
      this->Quiet = true;
      doing = DoingNone;
436
      }
437 438 439 440 441 442
    else if(args[i] == "EXACT")
      {
      this->VersionExact = true;
      this->Compatibility_1_6 = false;
      doing = DoingNone;
      }
443 444
    else if(args[i] == "MODULE")
      {
445
      moduleArgs.insert(i);
446 447
      doing = DoingNone;
      }
448 449
    else if(args[i] == "CONFIG")
      {
450
      configArgs.insert(i);
451 452
      doing = DoingNone;
      }
453 454
    else if(args[i] == "NO_MODULE")
      {
455
      configArgs.insert(i);
456
      doing = DoingNone;
457 458 459
      }
    else if(args[i] == "REQUIRED")
      {
460 461
      this->Required = true;
      doing = DoingComponents;
462 463 464
      }
    else if(args[i] == "COMPONENTS")
      {
465 466 467 468 469
      this->Compatibility_1_6 = false;
      doing = DoingComponents;
      }
    else if(args[i] == "NAMES")
      {
470
      configArgs.insert(i);
471 472
      this->Compatibility_1_6 = false;
      doing = DoingNames;
473
      }
474 475
    else if(args[i] == "PATHS")
      {
476
      configArgs.insert(i);
477 478 479
      this->Compatibility_1_6 = false;
      doing = DoingPaths;
      }
480 481
    else if(args[i] == "HINTS")
      {
482
      configArgs.insert(i);
483 484 485
      this->Compatibility_1_6 = false;
      doing = DoingHints;
      }
486 487
    else if(args[i] == "PATH_SUFFIXES")
      {
488
      configArgs.insert(i);
489 490 491 492 493
      this->Compatibility_1_6 = false;
      doing = DoingPathSuffixes;
      }
    else if(args[i] == "CONFIGS")
      {
494
      configArgs.insert(i);
495 496 497
      this->Compatibility_1_6 = false;
      doing = DoingConfigs;
      }
498 499 500 501 502 503
    else if(args[i] == "NO_POLICY_SCOPE")
      {
      this->PolicyScope = false;
      this->Compatibility_1_6 = false;
      doing = DoingNone;
      }
504 505
    else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
      {
506
      this->NoUserRegistry = true;
507
      configArgs.insert(i);
508 509 510
      this->Compatibility_1_6 = false;
      doing = DoingNone;
      }
511 512 513
    else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
      {
      this->NoSystemRegistry = true;
514
      configArgs.insert(i);
515 516 517
      this->Compatibility_1_6 = false;
      doing = DoingNone;
      }
518 519 520
    else if(args[i] == "NO_CMAKE_BUILDS_PATH")
      {
      this->NoBuilds = true;
521
      configArgs.insert(i);
522 523 524 525 526
      this->Compatibility_1_6 = false;
      doing = DoingNone;
      }
    else if(this->CheckCommonArgument(args[i]))
      {
527
      configArgs.insert(i);
528 529 530 531
      this->Compatibility_1_6 = false;
      doing = DoingNone;
      }
    else if(doing == DoingComponents)
532 533 534
      {
      // Set a variable telling the find script this component
      // is required.
535
      std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
536
      this->AddFindDefinition(req_var.c_str(), "1");
537

538 539 540 541 542
      // Append to the list of required components.
      components += components_sep;
      components += args[i];
      components_sep = ";";
      }
543 544 545 546 547 548
    else if(doing == DoingNames)
      {
      this->Names.push_back(args[i]);
      }
    else if(doing == DoingPaths)
      {
549 550 551 552 553
      this->AddUserPath(args[i], this->UserPaths);
      }
    else if(doing == DoingHints)
      {
      this->AddUserPath(args[i], this->UserHints);
554 555 556 557 558 559 560
      }
    else if(doing == DoingPathSuffixes)
      {
      this->AddPathSuffix(args[i]);
      }
    else if(doing == DoingConfigs)
      {
561 562 563 564 565 566 567
      if(args[i].find_first_of(":/\\") != args[i].npos ||
         cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake")
        {
        cmOStringStream e;
        e << "given CONFIGS option followed by invalid file name \""
          << args[i] << "\".  The names given must be file names without "
          << "a path and with a \".cmake\" extension.";
568
        this->SetError(e.str().c_str());
569 570
        return false;
        }
571 572
      this->Configs.push_back(args[i]);
      }
573 574 575
    else if(!haveVersion && version.find(args[i].c_str()))
      {
      haveVersion = true;
576
      this->Version = args[i];
577 578 579 580 581 582 583 584
      }
    else
      {
      cmOStringStream e;
      e << "called with invalid argument \"" << args[i].c_str() << "\"";
      this->SetError(e.str().c_str());
      return false;
      }
585
    }
586

587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
  // Maybe choose one mode exclusively.
  this->UseFindModules = configArgs.empty();
  this->UseConfigFiles = moduleArgs.empty();
  if(!this->UseFindModules && !this->UseConfigFiles)
    {
    cmOStringStream e;
    e << "given options exclusive to Module mode:\n";
    for(std::set<unsigned int>::const_iterator si = moduleArgs.begin();
        si != moduleArgs.end(); ++si)
      {
      e << "  " << args[*si] << "\n";
      }
    e << "and options exclusive to Config mode:\n";
    for(std::set<unsigned int>::const_iterator si = configArgs.begin();
        si != configArgs.end(); ++si)
      {
      e << "  " << args[*si] << "\n";
      }
    e << "The options are incompatible.";
    this->SetError(e.str().c_str());
    return false;
    }

610 611 612 613 614 615 616 617
  // Ignore EXACT with no version.
  if(this->Version.empty() && this->VersionExact)
    {
    this->VersionExact = false;
    this->Makefile->IssueMessage(
      cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested.");
    }

618
  if(this->Version.empty() || components.empty())
619 620 621 622 623 624 625
    {
    // Check whether we are recursing inside "Find<name>.cmake" within
    // another find_package(<name>) call.
    std::string mod = this->Name;
    mod += "_FIND_MODULE";
    if(this->Makefile->IsOn(mod.c_str()))
      {
626 627 628 629 630 631 632
      if(this->Version.empty())
        {
        // Get version information from the outer call if necessary.
        // Requested version string.
        std::string ver = this->Name;
        ver += "_FIND_VERSION";
        this->Version = this->Makefile->GetSafeDefinition(ver.c_str());
633

634 635 636 637 638 639 640 641 642 643
        // Whether an exact version is required.
        std::string exact = this->Name;
        exact += "_FIND_VERSION_EXACT";
        this->VersionExact = this->Makefile->IsOn(exact.c_str());
        }
      if(components.empty())
        {
        std::string components_var = this->Name + "_FIND_COMPONENTS";
        components = this->Makefile->GetSafeDefinition(components_var.c_str());
        }
644 645 646
      }
    }

647 648 649 650 651 652 653
  if(!this->Version.empty())
    {
    // Try to parse the version number and store the results that were
    // successfully parsed.
    unsigned int parsed_major;
    unsigned int parsed_minor;
    unsigned int parsed_patch;
654 655 656 657
    unsigned int parsed_tweak;
    this->VersionCount = sscanf(this->Version.c_str(), "%u.%u.%u.%u",
                                &parsed_major, &parsed_minor,
                                &parsed_patch, &parsed_tweak);
658 659
    switch(this->VersionCount)
      {
660
      case 4: this->VersionTweak = parsed_tweak; // no break!
661 662 663 664 665 666 667
      case 3: this->VersionPatch = parsed_patch; // no break!
      case 2: this->VersionMinor = parsed_minor; // no break!
      case 1: this->VersionMajor = parsed_major; // no break!
      default: break;
      }
    }

668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
  std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_";
  disableFindPackageVar += this->Name;
  if(this->Makefile->IsOn(disableFindPackageVar.c_str()))
    {
    if (this->Required)
      {
      cmOStringStream e;
      e << "for module " << this->Name << " called with REQUIRED, but "
        << disableFindPackageVar
        << " is enabled. A REQUIRED package cannot be disabled.";
      this->SetError(e.str().c_str());
      return false;
      }

    return true;
    }


686
  this->SetModuleVariables(components);
687

688
  // See if there is a Find<package>.cmake module.
689
  if(this->UseFindModules)
690
    {
691
    bool foundModule = false;
692
    if(!this->FindModule(foundModule))
693
      {
694
      this->AppendSuccessInformation();
695 696 697 698
      return false;
      }
    if(foundModule)
      {
699
      this->AppendSuccessInformation();
700 701
      return true;
      }
702
    }
703

704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
  if(this->UseFindModules && this->UseConfigFiles &&
     this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE"))
    {
    cmOStringStream aw;
    if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8))
      {
      aw << "find_package called without either MODULE or CONFIG option and "
        "no Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH.  "
        "Add MODULE to exclusively request Module mode and fail if "
        "Find" << this->Name << ".cmake is missing.  "
        "Add CONFIG to exclusively request Config mode and search for a "
        "package configuration file provided by " << this->Name <<
        " (" << this->Name << "Config.cmake or " <<
        cmSystemTools::LowerCase(this->Name) << "-config.cmake).  ";
      }
    else
      {
      aw << "find_package called without NO_MODULE option and no "
        "Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH.  "
        "Add NO_MODULE to exclusively request Config mode and search for a "
        "package configuration file provided by " << this->Name <<
        " (" << this->Name << "Config.cmake or " <<
        cmSystemTools::LowerCase(this->Name) << "-config.cmake).  "
        "Otherwise make Find" << this->Name << ".cmake available in "
        "CMAKE_MODULE_PATH.";
      }
    aw << "\n"
      "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)";
    this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str());
    }

735
  // No find module.  Assume the project has a CMake config file.  Use
736
  // a <package>_DIR cache variable to locate it.
737
  this->Variable = this->Name;
738
  this->Variable += "_DIR";
739

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
  // Add the default name.
  if(this->Names.empty())
    {
    this->Names.push_back(this->Name);
    }

  // Add the default configs.
  if(this->Configs.empty())
    {
    for(std::vector<std::string>::const_iterator ni = this->Names.begin();
        ni != this->Names.end(); ++ni)
      {
      std::string config = *ni;
      config += "Config.cmake";
      this->Configs.push_back(config);

      config = cmSystemTools::LowerCase(*ni);
      config += "-config.cmake";
      this->Configs.push_back(config);
      }
    }

762 763 764 765 766 767 768 769 770
  // get igonored paths from vars and reroot them.
  std::vector<std::string> ignored;
  this->GetIgnoredPaths(ignored);
  this->RerootPaths(ignored);

  // Construct a set of ignored paths
  this->IgnoredPaths.clear();
  this->IgnoredPaths.insert(ignored.begin(), ignored.end());

771 772 773 774 775 776
  // Find and load the package.
  bool result = this->HandlePackageMode();
  this->AppendSuccessInformation();
  return result;
}

777

778
//----------------------------------------------------------------------------
779
void cmFindPackageCommand::SetModuleVariables(const std::string& components)
780
{
781 782
  // Store the list of components.
  std::string components_var = this->Name + "_FIND_COMPONENTS";
783
  this->AddFindDefinition(components_var.c_str(), components.c_str());
784

785
  if(this->Quiet)
786
    {
787 788 789 790
    // Tell the module that is about to be read that it should find
    // quietly.
    std::string quietly = this->Name;
    quietly += "_FIND_QUIETLY";
791
    this->AddFindDefinition(quietly.c_str(), "1");
792
    }
793

794 795 796 797 798 799
  if(this->Required)
    {
    // Tell the module that is about to be read that it should report
    // a fatal error if the package is not found.
    std::string req = this->Name;
    req += "_FIND_REQUIRED";
800
    this->AddFindDefinition(req.c_str(), "1");
801
    }
802

803 804 805 806 807 808
  if(!this->Version.empty())
    {
    // Tell the module that is about to be read what version of the
    // package has been requested.
    std::string ver = this->Name;
    ver += "_FIND_VERSION";
809
    this->AddFindDefinition(ver.c_str(), this->Version.c_str());
810
    char buf[64];
811
    sprintf(buf, "%u", this->VersionMajor);
812
    this->AddFindDefinition((ver+"_MAJOR").c_str(), buf);
813
    sprintf(buf, "%u", this->VersionMinor);
814
    this->AddFindDefinition((ver+"_MINOR").c_str(), buf);
815
    sprintf(buf, "%u", this->VersionPatch);
816
    this->AddFindDefinition((ver+"_PATCH").c_str(), buf);
817
    sprintf(buf, "%u", this->VersionTweak);
818
    this->AddFindDefinition((ver+"_TWEAK").c_str(), buf);
819
    sprintf(buf, "%u", this->VersionCount);
820
    this->AddFindDefinition((ver+"_COUNT").c_str(), buf);
821

822 823 824
    // Tell the module whether an exact version has been requested.
    std::string exact = this->Name;
    exact += "_FIND_VERSION_EXACT";
825
    this->AddFindDefinition(exact.c_str(), this->VersionExact? "1":"0");
826 827 828
   }
}

829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
//----------------------------------------------------------------------------
void cmFindPackageCommand::AddFindDefinition(const char* var, const char* val)
{
  if(const char* old = this->Makefile->GetDefinition(var))
    {
    this->OriginalDefs[var].exists = true;
    this->OriginalDefs[var].value = old;
    }
  else
    {
    this->OriginalDefs[var].exists = false;
    }
  this->Makefile->AddDefinition(var, val);
}

//----------------------------------------------------------------------------
void cmFindPackageCommand::RestoreFindDefinitions()
{
  for(std::map<cmStdString, OriginalDef>::iterator
        i = this->OriginalDefs.begin(); i != this->OriginalDefs.end(); ++i)
    {
    OriginalDef const& od = i->second;
    if(od.exists)
      {
      this->Makefile->AddDefinition(i->first.c_str(), od.value.c_str());
      }
    else
      {
      this->Makefile->RemoveDefinition(i->first.c_str());
      }
    }
}
861 862 863 864 865 866 867 868 869 870

//----------------------------------------------------------------------------
bool cmFindPackageCommand::FindModule(bool& found)
{
  std::string module = "Find";
  module += this->Name;
  module += ".cmake";
  std::string mfile = this->Makefile->GetModulesFile(module.c_str());
  if ( mfile.size() )
    {
871 872
    // Load the module we found, and set "<name>_FIND_MODULE" to true
    // while inside it.
873
    found = true;
874 875 876
    std::string var = this->Name;
    var += "_FIND_MODULE";
    this->Makefile->AddDefinition(var.c_str(), "1");
877
    bool result = this->ReadListFile(mfile.c_str(), DoPolicyScope);
878 879
    this->Makefile->RemoveDefinition(var.c_str());
    return result;
880 881 882 883 884 885 886
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFindPackageCommand::HandlePackageMode()
{
887
  this->ConsideredConfigs.clear();
888

889 890 891 892 893
  // Support old capitalization behavior.
  std::string upperDir = cmSystemTools::UpperCase(this->Name);
  std::string upperFound = cmSystemTools::UpperCase(this->Name);
  upperDir += "_DIR";
  upperFound += "_FOUND";
894
  if(upperDir == this->Variable)
895
    {
896
    this->Compatibility_1_6 = false;
897
    }
898

899
  // Try to find the config file.
Ken Martin's avatar
Ken Martin committed
900
  const char* def = this->Makefile->GetDefinition(this->Variable.c_str());
901
  if(this->Compatibility_1_6 && cmSystemTools::IsOff(def))
902 903 904
    {
    // Use the setting of the old name of the variable to provide the
    // value of the new.
Ken Martin's avatar
Ken Martin committed
905
    const char* oldDef = this->Makefile->GetDefinition(upperDir.c_str());
906 907
    if(!cmSystemTools::IsOff(oldDef))
      {
Ken Martin's avatar
Ken Martin committed
908 909
      this->Makefile->AddDefinition(this->Variable.c_str(), oldDef);
      def = this->Makefile->GetDefinition(this->Variable.c_str());
910
      }
911
    }
912

913
  // Try to load the config file if the directory is known
914
  bool fileFound = false;
915
  if (this->UseConfigFiles)
916
    {
917
    if(!cmSystemTools::IsOff(def))
Alexander Neundorf's avatar
 
Alexander Neundorf committed
918
      {
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
      // Get the directory from the variable value.
      std::string dir = def;
      cmSystemTools::ConvertToUnixSlashes(dir);

      // Treat relative paths with respect to the current source dir.
      if(!cmSystemTools::FileIsFullPath(dir.c_str()))
        {
        dir = "/" + dir;
        dir = this->Makefile->GetCurrentDirectory() + dir;
        }
      // The file location was cached.  Look for the correct file.
      std::string file;
      if (this->FindConfigFile(dir, file))
        {
        this->FileFound = file;
        fileFound = true;
        }
      def = this->Makefile->GetDefinition(this->Variable.c_str());
Alexander Neundorf's avatar
 
Alexander Neundorf committed
937
      }
938 939 940

    // Search for the config file if it is not already found.
    if(cmSystemTools::IsOff(def) || !fileFound)
941
      {
942 943
      fileFound = this->FindConfig();
      def = this->Makefile->GetDefinition(this->Variable.c_str());
944 945
      }

946 947 948 949 950 951 952
    // Sanity check.
    if(fileFound && this->FileFound.empty())
      {
      this->Makefile->IssueMessage(
        cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!");
      fileFound = false;
      }
953 954
    }

955 956 957
  std::string foundVar = this->Name;
  foundVar += "_FOUND";

958 959 960
  // If the directory for the config file was found, try to read the file.
  bool result = true;
  bool found = false;
961 962
  bool configFileSetFOUNDFalse = false;

963
  if(fileFound)
964
    {
965 966 967 968 969 970 971 972 973 974
    if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
      && (this->Makefile->IsOn(foundVar.c_str()) == false))
      {
      // by removing Foo_FOUND here if it is FALSE, we don't really change
      // the situation for the Config file which is about to be included,
      // but we make it possible to detect later on whether the Config file
      // has set Foo_FOUND to FALSE itself:
      this->Makefile->RemoveDefinition(foundVar.c_str());
      }

975 976 977 978 979
    // Set the version variables before loading the config file.
    // It may override them.
    this->StoreVersionFound();

    // Parse the configuration file.
980
    if(this->ReadListFile(this->FileFound.c_str(), DoPolicyScope))
981 982 983
      {
      // The package has been found.
      found = true;
984 985 986 987 988 989 990 991 992

      // Check whether the Config file has set Foo_FOUND to FALSE:
      if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
           && (this->Makefile->IsOn(foundVar.c_str()) == false))
        {
        // we get here if the Config file has set Foo_FOUND actively to FALSE
        found = false;
        configFileSetFOUNDFalse = true;
        }
993 994 995
      }
    else
      {
996
      // The configuration file is invalid.
997
      result = false;
998 999
      }
    }
1000 1001

  if (result && !found && (!this->Quiet || this->Required))
1002
    {
1003
    // The variable is not set.
1004
    cmOStringStream e;
1005
    cmOStringStream aw;
1006 1007 1008 1009 1010 1011 1012
    if (configFileSetFOUNDFalse)
      {
      e << "Found package configuration file:\n"
        "  " << this->FileFound << "\n"
        "but it set " << foundVar << " to FALSE so package \"" <<
        this->Name << "\" is considered to be NOT FOUND.";
      }
1013 1014
    // If there are files in ConsideredConfigs, it means that FooConfig.cmake
    // have been found, but they didn't have appropriate versions.
1015
    else if (this->ConsideredConfigs.size() > 0)
1016
      {
1017 1018 1019 1020 1021 1022
      e << "Could not find a configuration file for package \""
        << this->Name << "\" that "
        << (this->VersionExact? "exactly matches" : "is compatible with")
        << " requested version \"" << this->Version << "\".\n"
        << "The following configuration files were considered but not "
           "accepted:\n";
1023 1024
      for(std::vector<ConfigFileInfo>::size_type i=0;
          i<this->ConsideredConfigs.size(); i++)
1025
        {
1026 1027
        e << "  " << this->ConsideredConfigs[i].filename
          << ", version: " << this->ConsideredConfigs[i].version << "\n";
1028
        }
1029 1030 1031
      }
    else
      {
1032 1033 1034 1035 1036 1037 1038 1039
      std::string requestedVersionString;
      if(!this->Version.empty())
        {
        requestedVersionString = " (requested version ";
        requestedVersionString += this->Version;
        requestedVersionString += ")";
        }

1040
      if (this->UseConfigFiles)
1041
        {
1042 1043 1044 1045 1046 1047 1048
        if(this->UseFindModules)
          {
          e << "By not providing \"Find" << this->Name << ".cmake\" in "
               "CMAKE_MODULE_PATH this project has asked CMake to find a "
               "package configuration file provided by \""<<this->Name<< "\", "
               "but CMake did not find one.\n";
          }
1049

1050
        if(this->Configs.size() == 1)
1051
          {
1052 1053
          e << "Could not find a package configuration file named \""
            << this->Configs[0] << "\" provided by package \""
1054
            << this->Name << "\"" << requestedVersionString <<".\n";
1055
          }
1056 1057 1058
        else
          {
          e << "Could not find a package configuration file provided by \""
1059 1060
            << this->Name << "\"" << requestedVersionString
            << " with any of the following names:\n";
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
          for(std::vector<std::string>::const_iterator ci =
                this->Configs.begin();
              ci != this->Configs.end(); ++ci)
            {
            e << "  " << *ci << "\n";