浏览代码

Merge topic 'ImproveFindPackageConfigMode'

5cdfc9c Improve wording of the error message of find_package() in config-mode
4969c3b Improve version notice in the generated message
e8ae504 Add option CONFIG_MODE to FPHSA()
b4b8f96 Don't create an empty element at the end of Foo_CONSIDERED_CONFIGS/VERSIONS
cc955a0 Small cleanup of FindPackageHandleStandardArgs.cmake
0367245 Replace the two vector<string,string> with one vector<struct{string,string}>
130b0e2 Improve error message in Config-mode when no appropriate version was found
dfe9c95 Record all considered Config files and their versions.
Brad King 15 年之前
父节点
当前提交
4ea441eaf9
共有 3 个文件被更改,包括 225 次插入96 次删除
  1. 111 61
      Modules/FindPackageHandleStandardArgs.cmake
  2. 109 34
      Source/cmFindPackageCommand.cxx
  3. 5 1
      Source/cmFindPackageCommand.h

+ 111 - 61
Modules/FindPackageHandleStandardArgs.cmake

@@ -20,18 +20,24 @@
 # The second mode is more powerful and also supports version checking:
 #    FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>]
 #                                           [VERSION_VAR   <versionvar>
+#                                           [CONFIG_MODE]
 #                                           [FAIL_MESSAGE "Custom failure message"] )
 #
 # As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_FOUND
 # will be set to TRUE.
-# Via FAIL_MESSAGE a custom failure message can be specified, if this is not
-# used, the default message will be displayed.
+# After REQUIRED_VARS the variables which are required for this package are listed.
 # Following VERSION_VAR the name of the variable can be specified which holds
 # the version of the package which has been found. If this is done, this version
 # will be checked against the (potentially) specified required version used
 # in the find_package() call. The EXACT keyword is also handled. The default
 # messages include information about the required version and the version
 # which has been actually found, both if the version is ok or not.
+# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for
+# a find_package(... NO_MODULE) call, in this case all the information
+# provided by the config-mode of find_package() will be evaluated
+# automatically.
+# Via FAIL_MESSAGE a custom failure message can be specified, if this is not
+# used, the default message will be displayed.
 #
 # Example for mode 1:
 #
@@ -53,6 +59,15 @@
 # Also the version of BISON will be checked by using the version contained
 # in BISON_VERSION.
 # Since no FAIL_MESSAGE is given, the default messages will be printed.
+#
+# Another example for mode 2:
+#
+#    FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
+#    FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4  CONFIG_MODE)
+# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE)
+# and adds an additional search directory for automoc4.
+# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
+# success/error message.
 
 #=============================================================================
 # Copyright 2007-2009 Kitware, Inc.
@@ -70,12 +85,50 @@
 INCLUDE(FindPackageMessage)
 INCLUDE(CMakeParseArguments)
 
-
-FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG _VAR1)
+# internal helper macro
+MACRO(_FPHSA_FAILURE_MESSAGE _msg)
+  IF (${_NAME}_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "${_msg}")
+  ELSE (${_NAME}_FIND_REQUIRED)
+    IF (NOT ${_NAME}_FIND_QUIETLY)
+      MESSAGE(STATUS "${_msg}")
+    ENDIF (NOT ${_NAME}_FIND_QUIETLY)
+  ENDIF (${_NAME}_FIND_REQUIRED)
+ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg)
+
+
+# internal helper macro to generate the failure message when used in CONFIG_MODE:
+MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
+  # <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
+  IF(${_NAME}_CONFIG)
+    _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
+  ELSE(${_NAME}_CONFIG)
+    # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
+    # List them all in the error message:
+    IF(${_NAME}_CONSIDERED_CONFIGS)
+      SET(configsText "")
+      LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
+      MATH(EXPR configsCount "${configsCount} - 1")
+      FOREACH(currentConfigIndex RANGE ${configsCount})
+        LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
+        LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
+        SET(configsText "${configsText}    ${filename} (version ${version})\n")
+      ENDFOREACH(currentConfigIndex)
+      _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
+
+    ELSE(${_NAME}_CONSIDERED_CONFIGS)
+      # Simple case: No Config-file was found at all:
+      _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
+    ENDIF(${_NAME}_CONSIDERED_CONFIGS)
+  ENDIF(${_NAME}_CONFIG)
+ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
+
+
+FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
 
 # set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
 # new extended or in the "old" mode:
-  SET(options) # none
+  SET(options CONFIG_MODE)
   SET(oneValueArgs FAIL_MESSAGE VERSION_VAR)
   SET(multiValueArgs REQUIRED_VARS)
   SET(_KEYWORDS_FOR_EXTENDED_MODE  ${options} ${oneValueArgs} ${multiValueArgs} )
@@ -83,11 +136,11 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG _VAR1)
 
   IF(${INDEX} EQUAL -1)
     SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
-    SET(FPHSA_REQUIRED_VARS ${_VAR1} ${ARGN})
+    SET(FPHSA_REQUIRED_VARS ${ARGN})
     SET(FPHSA_VERSION_VAR)
   ELSE(${INDEX} EQUAL -1)
 
-    CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${_FIRST_ARG} ${_VAR1} ${ARGN})
+    CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${_FIRST_ARG} ${ARGN})
 
     IF(FPHSA_UNPARSED_ARGUMENTS)
       MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
@@ -104,6 +157,14 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG _VAR1)
     SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
   ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
 
+  # In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
+  # when it successfully found the config-file, including version checking:
+  IF(FPHSA_CONFIG_MODE)
+    LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
+    LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
+    SET(FPHSA_VERSION_VAR ${_NAME}_VERSION)
+  ENDIF(FPHSA_CONFIG_MODE)
+
   IF(NOT FPHSA_REQUIRED_VARS)
     MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
   ENDIF(NOT FPHSA_REQUIRED_VARS)
@@ -111,8 +172,9 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG _VAR1)
   LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
 
   STRING(TOUPPER ${_NAME} _NAME_UPPER)
+  STRING(TOLOWER ${_NAME} _NAME_LOWER)
 
-  # collect all variables which were not found, so they can be printed, so the 
+  # collect all variables which were not found, so they can be printed, so the
   # user knows better what went wrong (#6375)
   SET(MISSING_VARS "")
   SET(DETAILS "")
@@ -131,44 +193,42 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG _VAR1)
   # version handling:
   SET(VERSION_MSG "")
   SET(VERSION_OK TRUE)
+  SET(VERSION ${${FPHSA_VERSION_VAR}} )
   IF (${_NAME}_FIND_VERSION)
 
-    # if the package was found, check for the version using <NAME>_FIND_VERSION
-    IF (${_NAME_UPPER}_FOUND)
-      SET(VERSION ${${FPHSA_VERSION_VAR}} )
-
-      IF(VERSION)
-
-        IF(${_NAME}_FIND_VERSION_EXACT)       # exact version required
-          IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
-            SET(VERSION_MSG " Found version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
-            SET(VERSION_OK FALSE)
-          ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
-            SET(VERSION_MSG " (found exact version \"${VERSION}\")")
-          ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
-
-        ELSE(${_NAME}_FIND_VERSION_EXACT)     # minimum version specified:
-          IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
-            SET(VERSION_MSG " Found version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
-            SET(VERSION_OK FALSE)
-          ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
-            SET(VERSION_MSG " (found version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")")
-          ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
-        ENDIF(${_NAME}_FIND_VERSION_EXACT)
-
-# Uncomment the following two lines to see to which Find-modules the VERSION_VAR keywords still need to be added:
-#      ELSE(VERSION)
-#        SET(VERSION_MSG " (WARNING: Required version is \"${${_NAME}_FIND_VERSION}\", but version of ${_NAME} is unknown)")
-      ENDIF(VERSION)
-
-    # if the package was not found, but a version was given, add that to the output:
-    ELSE (${_NAME_UPPER}_FOUND)
+    IF(VERSION)
+
+      IF(${_NAME}_FIND_VERSION_EXACT)       # exact version required
+        IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
+          SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
+          SET(VERSION_OK FALSE)
+        ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
+          SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+        ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
+
+      ELSE(${_NAME}_FIND_VERSION_EXACT)     # minimum version specified:
+        IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
+          SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
+          SET(VERSION_OK FALSE)
+        ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
+          SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")")
+        ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
+      ENDIF(${_NAME}_FIND_VERSION_EXACT)
+
+    ELSE(VERSION)
+
+      # if the package was not found, but a version was given, add that to the output:
       IF(${_NAME}_FIND_VERSION_EXACT)
-         SET(VERSION_MSG " (Required is exact version \"${${_NAME}_FIND_VERSION}\")")
+         SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
       ELSE(${_NAME}_FIND_VERSION_EXACT)
-         SET(VERSION_MSG " (Required is at least version \"${${_NAME}_FIND_VERSION}\")")
+         SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
       ENDIF(${_NAME}_FIND_VERSION_EXACT)
-    ENDIF (${_NAME_UPPER}_FOUND)
+
+    ENDIF(VERSION)
+  ELSE (${_NAME}_FIND_VERSION)
+    IF(VERSION)
+      SET(VERSION_MSG "(found version \"${VERSION}\")")
+    ENDIF(VERSION)
   ENDIF (${_NAME}_FIND_VERSION)
 
   IF(VERSION_OK)
@@ -182,26 +242,16 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG _VAR1)
   IF (${_NAME_UPPER}_FOUND)
     FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}")
   ELSE (${_NAME_UPPER}_FOUND)
-    IF(NOT VERSION_OK)
-
-      IF (${_NAME}_FIND_REQUIRED)
-          MESSAGE(FATAL_ERROR "${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
-      ELSE (${_NAME}_FIND_REQUIRED)
-        IF (NOT ${_NAME}_FIND_QUIETLY)
-          MESSAGE(STATUS "${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
-        ENDIF (NOT ${_NAME}_FIND_QUIETLY)
-      ENDIF (${_NAME}_FIND_REQUIRED)
-
-    ELSE(NOT VERSION_OK)
-
-      IF (${_NAME}_FIND_REQUIRED)
-          MESSAGE(FATAL_ERROR "${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
-      ELSE (${_NAME}_FIND_REQUIRED)
-        IF (NOT ${_NAME}_FIND_QUIETLY)
-          MESSAGE(STATUS "${FPHSA_FAIL_MESSAGE}  (missing: ${MISSING_VARS}) ${VERSION_MSG}")
-        ENDIF (NOT ${_NAME}_FIND_QUIETLY)
-      ENDIF (${_NAME}_FIND_REQUIRED)
-    ENDIF(NOT VERSION_OK)
+
+    IF(FPHSA_CONFIG_MODE)
+      _FPHSA_HANDLE_FAILURE_CONFIG_MODE()
+    ELSE(FPHSA_CONFIG_MODE)
+      IF(NOT VERSION_OK)
+        _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
+      ELSE(NOT VERSION_OK)
+        _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
+      ENDIF(NOT VERSION_OK)
+    ENDIF(FPHSA_CONFIG_MODE)
 
   ENDIF (${_NAME_UPPER}_FOUND)
 

+ 109 - 34
Source/cmFindPackageCommand.cxx

@@ -156,6 +156,11 @@ cmFindPackageCommand::cmFindPackageCommand()
     "The full path to the configuration file is stored in the cmake "
     "variable <package>_CONFIG."
     "\n"
+    "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"
     "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 "
@@ -618,7 +623,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
   // Store the list of components.
   std::string components_var = this->Name + "_FIND_COMPONENTS";
   this->AddFindDefinition(components_var.c_str(), components.c_str());
-   
+
   if(this->Quiet)
     {
     // Tell the module that is about to be read that it should find
@@ -721,6 +726,8 @@ bool cmFindPackageCommand::FindModule(bool& found)
 //----------------------------------------------------------------------------
 bool cmFindPackageCommand::HandlePackageMode()
 {
+  this->ConsideredConfigs.clear();
+
   // Support old capitalization behavior.
   std::string upperDir = cmSystemTools::UpperCase(this->Name);
   std::string upperFound = cmSystemTools::UpperCase(this->Name);
@@ -809,36 +816,58 @@ bool cmFindPackageCommand::HandlePackageMode()
     {
     // The variable is not set.
     cmOStringStream e;
-    e << "Could not find ";
-    if(!this->NoModule)
-      {
-      e << "module Find" << this->Name << ".cmake or ";
-      }
-    e << "a configuration file for package " << this->Name << ".\n";
-    if(!this->NoModule)
-      {
-      e << "Adjust CMAKE_MODULE_PATH to find Find"
-        << this->Name << ".cmake or set ";
-      }
-    else
-      {
-      e << "Set ";
-      }
-    e << this->Variable << " to the directory containing a CMake "
-      << "configuration file for " << this->Name << ".  ";
-    if(this->Configs.size() == 1)
-      {
-      e << "The file will be called " << this->Configs[0];
+    // If there are files in ConsideredConfigs, it means that FooConfig.cmake
+    // have been found, but they didn't have appropriate versions.
+    if (this->ConsideredConfigs.size() > 0)
+      {
+      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";
+      for(std::vector<ConfigFileInfo>::size_type i=0;
+          i<this->ConsideredConfigs.size(); i++)
+        {
+        e << "  " << this->ConsideredConfigs[i].filename
+          << ", version: " << this->ConsideredConfigs[i].version << "\n";
+        }
       }
     else
       {
-      e << "The file will have one of the following names:\n";
-      for(std::vector<std::string>::const_iterator ci = this->Configs.begin();
-          ci != this->Configs.end(); ++ci)
+      e << "Could not find ";
+      if(!this->NoModule)
+        {
+        e << "module Find" << this->Name << ".cmake or ";
+        }
+      e << "a configuration file for package " << this->Name << ".\n";
+      if(!this->NoModule)
+        {
+        e << "Adjust CMAKE_MODULE_PATH to find Find"
+          << this->Name << ".cmake or set ";
+        }
+      else
+        {
+        e << "Set ";
+        }
+      e << this->Variable << " to the directory containing a CMake "
+        << "configuration file for " << this->Name << ".  ";
+      if(this->Configs.size() == 1)
+        {
+        e << "The file will be called " << this->Configs[0];
+        }
+      else
         {
-        e << "  " << *ci << "\n";
+        e << "The file will have one of the following names:\n";
+        for(std::vector<std::string>::const_iterator ci=this->Configs.begin();
+            ci != this->Configs.end(); ++ci)
+          {
+          e << "  " << *ci << "\n";
+          }
         }
       }
+
+
     this->Makefile->IssueMessage(
       this->Required? cmake::FATAL_ERROR : cmake::WARNING, e.str());
     }
@@ -897,6 +926,31 @@ bool cmFindPackageCommand::HandlePackageMode()
     }
 #endif
 
+  std::string consideredConfigsVar = this->Name;
+  consideredConfigsVar += "_CONSIDERED_CONFIGS";
+  std::string consideredVersionsVar = this->Name;
+  consideredVersionsVar += "_CONSIDERED_VERSIONS";
+
+  std::string consideredConfigFiles;
+  std::string consideredVersions;
+
+  const char* sep = "";
+  for(std::vector<ConfigFileInfo>::size_type i=0;
+      i<this->ConsideredConfigs.size(); i++)
+    {
+    consideredConfigFiles += sep;
+    consideredVersions += sep;
+    consideredConfigFiles += this->ConsideredConfigs[i].filename;
+    consideredVersions += this->ConsideredConfigs[i].version;
+    sep = ";";
+    }
+
+  this->Makefile->AddDefinition(consideredConfigsVar.c_str(),
+                                consideredConfigFiles.c_str());
+
+  this->Makefile->AddDefinition(consideredVersionsVar.c_str(),
+                                consideredVersions.c_str());
+
   return result;
 }
 
@@ -1481,6 +1535,10 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
 //----------------------------------------------------------------------------
 bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
 {
+  bool result = false; // by default, assume the version is not ok.
+  bool haveResult = false;
+  std::string version = "unknown";
+
   // Get the filename without the .cmake extension.
   std::string::size_type pos = config_file.rfind('.');
   std::string version_file_base = config_file.substr(0, pos);
@@ -1488,31 +1546,42 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
   // Look for foo-config-version.cmake
   std::string version_file = version_file_base;
   version_file += "-version.cmake";
-  if(cmSystemTools::FileExists(version_file.c_str(), true))
+  if ((haveResult == false)
+       && (cmSystemTools::FileExists(version_file.c_str(), true)))
     {
-    return this->CheckVersionFile(version_file);
+    result = this->CheckVersionFile(version_file, version);
+    haveResult = true;
     }
 
   // Look for fooConfigVersion.cmake
   version_file = version_file_base;
   version_file += "Version.cmake";
-  if(cmSystemTools::FileExists(version_file.c_str(), true))
+  if ((haveResult == false)
+       && (cmSystemTools::FileExists(version_file.c_str(), true)))
     {
-    return this->CheckVersionFile(version_file);
+    result = this->CheckVersionFile(version_file, version);
+    haveResult = true;
     }
 
+
   // If no version was requested a versionless package is acceptable.
-  if(this->Version.empty())
+  if ((haveResult == false) && (this->Version.empty()))
     {
-    return true;
+    result = true;
+    haveResult = true;
     }
 
-  // No version file found.  Assume the version is incompatible.
-  return false;
+  ConfigFileInfo configFileInfo;
+  configFileInfo.filename = config_file;
+  configFileInfo.version = version;
+  this->ConsideredConfigs.push_back(configFileInfo);
+
+  return result;
 }
 
 //----------------------------------------------------------------------------
-bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file)
+bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
+                                            std::string& result_version)
 {
   // The version file will be loaded in an isolated scope.
   cmMakefile::ScopePushPop varScope(this->Makefile);
@@ -1585,6 +1654,12 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file)
       }
     }
 
+  result_version = this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
+  if (result_version.empty())
+    {
+    result_version = "unknown";
+    }
+
   // Succeed if the version is suitable.
   return suitable;
 }

+ 5 - 1
Source/cmFindPackageCommand.h

@@ -98,7 +98,8 @@ private:
   bool CheckDirectory(std::string const& dir);
   bool FindConfigFile(std::string const& dir, std::string& file);
   bool CheckVersion(std::string const& config_file);
-  bool CheckVersionFile(std::string const& version_file);
+  bool CheckVersionFile(std::string const& version_file,
+                        std::string& result_version);
   bool SearchPrefix(std::string const& prefix);
   bool SearchFrameworkPrefix(std::string const& prefix_in);
   bool SearchAppBundlePrefix(std::string const& prefix_in);
@@ -137,6 +138,9 @@ private:
   std::vector<std::string> Names;
   std::vector<std::string> Configs;
   std::set<std::string> IgnoredPaths;
+
+  struct ConfigFileInfo { std::string filename; std::string version; };
+  std::vector<ConfigFileInfo> ConsideredConfigs;
 };
 
 #endif