소스 검색

ENH: Refactor find_* command framework/appbundle search order impl.

  - CMAKE_FIND_FRAMEWORK and CMAKE_FIND_APPBUNDLE are supposed to specify
    whether to find frameworks/appbundles FIRST, LAST, ONLY, or NEVER.
  - Previously this affected only the placement of CMAKE_FRAMEWORK_PATH
    and CMAKE_APPBUNDLE_PATH with respect to the other path specifiers.
  - Now it behaves as documented.  The entire search path is inspected for
    each kind of program, library, or header before trying the next kind.
  - Additionally the ONLY mode is now honored for headers so that users
    do not end up with a library in framework and a header from elsewhere.
Brad King 17 년 전
부모
커밋
6706f84cd9
7개의 변경된 파일195개의 추가작업 그리고 183개의 파일을 삭제
  1. 35 72
      Source/cmFindBase.cxx
  2. 0 3
      Source/cmFindBase.h
  3. 66 51
      Source/cmFindLibraryCommand.cxx
  4. 4 1
      Source/cmFindLibraryCommand.h
  5. 79 52
      Source/cmFindPathCommand.cxx
  6. 6 2
      Source/cmFindPathCommand.h
  7. 5 2
      Source/cmFindProgramCommand.cxx

+ 35 - 72
Source/cmFindBase.cxx

@@ -282,31 +282,10 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
 
 
 void cmFindBase::ExpandPaths()
 void cmFindBase::ExpandPaths()
 {
 {
-  // if NO Default paths was not specified add the
-  // standard search paths.
-  if(!this->NoDefaultPath)
-    {
-    if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
-      {
-      this->AddFrameworkPath();
-      }
-    if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
-      {
-      this->AddAppBundlePath();
-      }
-    this->AddCMakeEnvironmentPath();
-    this->AddCMakeVariablePath();
-    this->AddSystemEnvironmentPath();
-    this->AddCMakeSystemVariablePath();
-    if(this->SearchAppBundleLast)
-      {
-      this->AddAppBundlePath();
-      }
-    if(this->SearchFrameworkLast)
-      {
-      this->AddFrameworkPath();
-      }
-    }
+  this->AddCMakeEnvironmentPath();
+  this->AddCMakeVariablePath();
+  this->AddSystemEnvironmentPath();
+  this->AddCMakeSystemVariablePath();
 
 
   // Add paths specified by the caller.
   // Add paths specified by the caller.
   this->AddPathsInternal(this->UserPaths, CMakePath);
   this->AddPathsInternal(this->UserPaths, CMakePath);
@@ -380,50 +359,10 @@ void cmFindBase::AddEnvPrefixPath(const char* variable)
   this->AddPrefixPaths(tmp, EnvPath);
   this->AddPrefixPaths(tmp, EnvPath);
 }
 }
 
 
-//----------------------------------------------------------------------------
-void cmFindBase::AddMacPath(const char* var, const char* sysvar)
-{
-  if(this->NoDefaultPath)
-    {
-    return;
-    }
-
-  // first environment variables
-  if(!this->NoCMakeEnvironmentPath)
-    {
-    this->AddEnvPath(var);
-    }
-
-  // add cmake variables
-  if(!this->NoCMakePath)
-    {
-    this->AddCMakePath(var);
-    }
-
-  // add cmake system variables
-  if(!this->NoCMakeSystemPath)
-    {
-    this->AddCMakePath(sysvar);
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddFrameworkPath()
-{
-  this->AddMacPath("CMAKE_FRAMEWORK_PATH", "CMAKE_SYSTEM_FRAMEWORK_PATH");
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddAppBundlePath()
-{
-  this->AddMacPath("CMAKE_APPBUNDLE_PATH", "CMAKE_SYSTEM_APPBUNDLE_PATH");
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmFindBase::AddCMakeEnvironmentPath()
 void cmFindBase::AddCMakeEnvironmentPath()
 {
 {
-  if(!this->NoCMakeEnvironmentPath &&
-     !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
+  if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath)
     {
     {
     // Add CMAKE_*_PATH environment variables
     // Add CMAKE_*_PATH environment variables
     std::string var = "CMAKE_";
     std::string var = "CMAKE_";
@@ -431,14 +370,22 @@ void cmFindBase::AddCMakeEnvironmentPath()
     var += "_PATH";
     var += "_PATH";
     this->AddEnvPrefixPath("CMAKE_PREFIX_PATH");
     this->AddEnvPrefixPath("CMAKE_PREFIX_PATH");
     this->AddEnvPath(var.c_str());
     this->AddEnvPath(var.c_str());
+
+    if(this->CMakePathName == "PROGRAM")
+      {
+      this->AddEnvPath("CMAKE_APPBUNDLE_PATH");
+      }
+    else
+      {
+      this->AddEnvPath("CMAKE_FRAMEWORK_PATH");
+      }
     }
     }
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmFindBase::AddCMakeVariablePath()
 void cmFindBase::AddCMakeVariablePath()
 {
 {
-  if(!this->NoCMakePath &&
-     !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
+  if(!this->NoCMakePath && !this->NoDefaultPath)
     {
     {
     // Add CMake varibles of the same name as the previous environment
     // Add CMake varibles of the same name as the previous environment
     // varibles CMAKE_*_PATH to be used most of the time with -D
     // varibles CMAKE_*_PATH to be used most of the time with -D
@@ -448,14 +395,22 @@ void cmFindBase::AddCMakeVariablePath()
     var += "_PATH";
     var += "_PATH";
     this->AddCMakePrefixPath("CMAKE_PREFIX_PATH");
     this->AddCMakePrefixPath("CMAKE_PREFIX_PATH");
     this->AddCMakePath(var.c_str());
     this->AddCMakePath(var.c_str());
+
+    if(this->CMakePathName == "PROGRAM")
+      {
+      this->AddCMakePath("CMAKE_APPBUNDLE_PATH");
+      }
+    else
+      {
+      this->AddCMakePath("CMAKE_FRAMEWORK_PATH");
+      }
     }
     }
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmFindBase::AddSystemEnvironmentPath()
 void cmFindBase::AddSystemEnvironmentPath()
 {
 {
-  if(!this->NoSystemEnvironmentPath &&
-     !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
+  if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
     {
     {
     // Add LIB or INCLUDE
     // Add LIB or INCLUDE
     if(!this->EnvironmentPath.empty())
     if(!this->EnvironmentPath.empty())
@@ -470,14 +425,22 @@ void cmFindBase::AddSystemEnvironmentPath()
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmFindBase::AddCMakeSystemVariablePath()
 void cmFindBase::AddCMakeSystemVariablePath()
 {
 {
-  if(!this->NoCMakeSystemPath &&
-     !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
+  if(!this->NoCMakeSystemPath && !this->NoDefaultPath)
     {
     {
     std::string var = "CMAKE_SYSTEM_";
     std::string var = "CMAKE_SYSTEM_";
     var += this->CMakePathName;
     var += this->CMakePathName;
     var += "_PATH";
     var += "_PATH";
     this->AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
     this->AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
     this->AddCMakePath(var.c_str());
     this->AddCMakePath(var.c_str());
+
+    if(this->CMakePathName == "PROGRAM")
+      {
+      this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+      }
+    else
+      {
+      this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
+      }
     }
     }
 }
 }
 
 

+ 0 - 3
Source/cmFindBase.h

@@ -62,15 +62,12 @@ protected:
   bool AlreadyInCacheWithoutMetaInfo;
   bool AlreadyInCacheWithoutMetaInfo;
 private:
 private:
   // Add pieces of the search.
   // Add pieces of the search.
-  void AddFrameworkPath();
-  void AddAppBundlePath();
   void AddCMakeEnvironmentPath();
   void AddCMakeEnvironmentPath();
   void AddCMakeVariablePath();
   void AddCMakeVariablePath();
   void AddSystemEnvironmentPath();
   void AddSystemEnvironmentPath();
   void AddCMakeSystemVariablePath();
   void AddCMakeSystemVariablePath();
 
 
   // Helpers.
   // Helpers.
-  void AddMacPath(const char* var, const char* sysvar);
   void AddCMakePrefixPath(const char* variable);
   void AddCMakePrefixPath(const char* variable);
   void AddEnvPrefixPath(const char* variable);
   void AddEnvPrefixPath(const char* variable);
   void AddPrefixPaths(std::vector<std::string> const& in_paths,
   void AddPrefixPaths(std::vector<std::string> const& in_paths,

+ 66 - 51
Source/cmFindLibraryCommand.cxx

@@ -96,19 +96,15 @@ bool cmFindLibraryCommand
     this->AddLib64Paths();
     this->AddLib64Paths();
     }
     }
 
 
-  std::string library;
-  for(std::vector<std::string>::iterator i = this->Names.begin();
-      i != this->Names.end() ; ++i)
+  std::string library = this->FindLibrary();
+  if(library != "")
     {
     {
-    library = this->FindLibrary(i->c_str());
-    if(library != "")
-      {
-      this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
-                                         library.c_str(),
-                                         this->VariableDocumentation.c_str(),
-                                         cmCacheManager::FILEPATH);
-      return true;
-      } 
+    // Save the value in the cache
+    this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+                                       library.c_str(),
+                                       this->VariableDocumentation.c_str(),
+                                       cmCacheManager::FILEPATH);
+    return true;
     }
     }
   std::string notfound = this->VariableName + "-NOTFOUND";
   std::string notfound = this->VariableName + "-NOTFOUND";
   this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
   this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
@@ -211,21 +207,29 @@ void cmFindLibraryCommand::AddLib64Paths()
     }
     }
 }
 }
 
 
-std::string cmFindLibraryCommand::FindLibrary(const char* name)
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindLibrary()
 {
 {
-  bool supportFrameworks = false;
-  bool onlyFrameworks = false;
-  std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK");
-  if(ff == "FIRST" || ff == "LAST")
+  std::string library;
+  if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
     {
     {
-    supportFrameworks = true;
+    library = this->FindFrameworkLibrary();
     }
     }
-  if(ff == "ONLY")
+  if(library.empty() && !this->SearchFrameworkOnly)
     {
     {
-    onlyFrameworks = true;
-    supportFrameworks = true;
+    library = this->FindNormalLibrary();
     }
     }
-  
+  if(library.empty() && this->SearchFrameworkLast)
+    {
+    library = this->FindFrameworkLibrary();
+    }
+  return library;
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindNormalLibrary()
+{
+  // Collect the list of library name prefixes/suffixes to try.
   const char* prefixes_list =
   const char* prefixes_list =
     this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
     this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
   const char* suffixes_list =
   const char* suffixes_list =
@@ -235,41 +239,29 @@ std::string cmFindLibraryCommand::FindLibrary(const char* name)
   cmSystemTools::ExpandListArgument(prefixes_list, prefixes, true);
   cmSystemTools::ExpandListArgument(prefixes_list, prefixes, true);
   cmSystemTools::ExpandListArgument(suffixes_list, suffixes, true);
   cmSystemTools::ExpandListArgument(suffixes_list, suffixes, true);
 
 
-  // If the original library name provided by the user matches one of
-  // the suffixes, try it first.
-  bool tryOrig = false;
-  {
-  std::string nm = name;
-  for(std::vector<std::string>::const_iterator si = suffixes.begin();
-      !tryOrig && si != suffixes.end(); ++si)
-    {
-    std::string const& suffix = *si;
-    if(nm.length() > suffix.length() &&
-       nm.substr(nm.size()-suffix.length()) == suffix)
-      {
-      tryOrig = true;
-      }
-    }
-  }
-
+  // Search the entire path for each name.
   std::string tryPath;
   std::string tryPath;
-  for(std::vector<std::string>::const_iterator p = this->SearchPaths.begin();
-      p != this->SearchPaths.end(); ++p)
+  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+      ni != this->Names.end() ; ++ni)
     {
     {
-    if(supportFrameworks)
+    // If the original library name provided by the user matches one of
+    // the suffixes, try it first.
+    bool tryOrig = false;
+    std::string const& name = *ni;
+    for(std::vector<std::string>::const_iterator si = suffixes.begin();
+        !tryOrig && si != suffixes.end(); ++si)
       {
       {
-      tryPath = *p;
-      tryPath += name;
-      tryPath += ".framework";
-      if(cmSystemTools::FileExists(tryPath.c_str())
-         && cmSystemTools::FileIsDirectory(tryPath.c_str()))
+      std::string const& suffix = *si;
+      if(name.length() > suffix.length() &&
+         name.substr(name.size()-suffix.length()) == suffix)
         {
         {
-        tryPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
-        cmSystemTools::ConvertToUnixSlashes(tryPath);
-        return tryPath;
+        tryOrig = true;
         }
         }
       }
       }
-    if(!onlyFrameworks)
+
+    for(std::vector<std::string>::const_iterator
+          p = this->SearchPaths.begin();
+        p != this->SearchPaths.end(); ++p)
       {
       {
       // Try the original library name as specified by the user.
       // Try the original library name as specified by the user.
       if(tryOrig)
       if(tryOrig)
@@ -309,3 +301,26 @@ std::string cmFindLibraryCommand::FindLibrary(const char* name)
   // Couldn't find the library.
   // Couldn't find the library.
   return "";
   return "";
 }
 }
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindFrameworkLibrary()
+{
+  // Search for a framework of each name in the entire search path.
+  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+      ni != this->Names.end() ; ++ni)
+    {
+    // Search the paths for a framework with this name.
+    std::string fwName = *ni;
+    fwName += ".framework";
+    std::string fwPath = cmSystemTools::FindDirectory(fwName.c_str(),
+                                                      this->SearchPaths,
+                                                      true);
+    if(!fwPath.empty())
+      {
+      return fwPath;
+      }
+    }
+
+  // No framework found.
+  return "";
+}

+ 4 - 1
Source/cmFindLibraryCommand.h

@@ -68,7 +68,10 @@ public:
 protected:
 protected:
   void AddArchitecturePaths(const char* suffix);
   void AddArchitecturePaths(const char* suffix);
   void AddLib64Paths();
   void AddLib64Paths();
-  std::string FindLibrary(const char* name);
+  std::string FindLibrary();
+private:
+  std::string FindNormalLibrary();
+  std::string FindFrameworkLibrary();
 };
 };
 
 
 
 

+ 79 - 52
Source/cmFindPathCommand.cxx

@@ -95,57 +95,16 @@ bool cmFindPathCommand
       }
       }
     return true;
     return true;
     }
     }
-  std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK");
-  bool supportFrameworks = true;
-  if( ff.size() == 0 || ff == "NEVER" )
-    {
-    supportFrameworks = false;
-    }
-  std::string framework;
-  // Use the search path to find the file.
-  unsigned int k;
-  std::string result;
-  for(k=0; k < this->SearchPaths.size(); k++)
+
+  std::string result = this->FindHeader();
+  if(result.size() != 0)
     {
     {
-    for(unsigned int j =0; j < this->Names.size(); ++j)
-      {
-      // if frameworks are supported try to find the header in a framework
-      std::string tryPath;
-      if(supportFrameworks)
-        {
-        tryPath = this->FindHeaderInFramework(this->Names[j],
-                                              this->SearchPaths[k]);
-        if(tryPath.size())
-          {
-          result = tryPath;
-          }
-        }
-      if(result.size() == 0)
-        {
-        tryPath = this->SearchPaths[k];
-        tryPath += this->Names[j];
-        if(cmSystemTools::FileExists(tryPath.c_str()))
-          {
-          if(this->IncludeFileInPath)
-            {
-            result = tryPath;
-            }
-          else
-            {
-            result = this->SearchPaths[k];
-            }
-          }
-        }
-      if(result.size() != 0)
-        {
-        this->Makefile->AddCacheDefinition
-          (this->VariableName.c_str(), result.c_str(),
-           this->VariableDocumentation.c_str(),
-           (this->IncludeFileInPath) ? 
-           cmCacheManager::FILEPATH :cmCacheManager::PATH);
-        return true;
-        }
-      }
+    this->Makefile->AddCacheDefinition
+      (this->VariableName.c_str(), result.c_str(),
+       this->VariableDocumentation.c_str(),
+       (this->IncludeFileInPath) ?
+       cmCacheManager::FILEPATH :cmCacheManager::PATH);
+    return true;
     }
     }
   this->Makefile->AddCacheDefinition
   this->Makefile->AddCacheDefinition
     (this->VariableName.c_str(),
     (this->VariableName.c_str(),
@@ -156,8 +115,28 @@ bool cmFindPathCommand
   return true;
   return true;
 }
 }
 
 
-std::string cmFindPathCommand::FindHeaderInFramework(std::string& file,
-                                                     std::string& dir)
+//----------------------------------------------------------------------------
+std::string cmFindPathCommand::FindHeader()
+{
+  std::string header;
+  if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
+    {
+    header = this->FindFrameworkHeader();
+    }
+  if(header.empty() && !this->SearchFrameworkOnly)
+    {
+    header = this->FindNormalHeader();
+    }
+  if(header.empty() && this->SearchFrameworkLast)
+    {
+    header = this->FindFrameworkHeader();
+    }
+  return header;
+}
+
+std::string
+cmFindPathCommand::FindHeaderInFramework(std::string const& file,
+                                         std::string const& dir)
 {
 {
   cmStdString fileName = file;
   cmStdString fileName = file;
   cmStdString frameWorkName;
   cmStdString frameWorkName;
@@ -217,3 +196,51 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string& file,
   return "";
   return "";
 }
 }
 
 
+//----------------------------------------------------------------------------
+std::string cmFindPathCommand::FindNormalHeader()
+{
+  std::string tryPath;
+  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+      ni != this->Names.end() ; ++ni)
+    {
+    for(std::vector<std::string>::const_iterator
+          p = this->SearchPaths.begin();
+        p != this->SearchPaths.end(); ++p)
+      {
+      tryPath = *p;
+      tryPath += *ni;
+      if(cmSystemTools::FileExists(tryPath.c_str()))
+        {
+        if(this->IncludeFileInPath)
+          {
+          return tryPath;
+          }
+        else
+          {
+          return *p;
+          }
+        }
+      }
+    }
+  return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindPathCommand::FindFrameworkHeader()
+{
+  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+      ni != this->Names.end() ; ++ni)
+    {
+    for(std::vector<std::string>::const_iterator
+          p = this->SearchPaths.begin();
+        p != this->SearchPaths.end(); ++p)
+      {
+      std::string fwPath = this->FindHeaderInFramework(*ni, *p);
+      if(!fwPath.empty())
+        {
+        return fwPath;
+        }
+      }
+    }
+  return "";
+}

+ 6 - 2
Source/cmFindPathCommand.h

@@ -64,12 +64,16 @@ public:
     return "Find the directory containing a file.";
     return "Find the directory containing a file.";
     }
     }
 
 
-  std::string FindHeaderInFramework( std::string& file,
-                                     std::string& dir);
   virtual const char* GetFullDocumentation();
   virtual const char* GetFullDocumentation();
   cmTypeMacro(cmFindPathCommand, cmFindBase);
   cmTypeMacro(cmFindPathCommand, cmFindBase);
   bool IncludeFileInPath;
   bool IncludeFileInPath;
   bool ExtraDocAdded;
   bool ExtraDocAdded;
+private:
+  std::string FindHeaderInFramework(std::string const& file,
+                                    std::string const& dir);
+  std::string FindHeader();
+  std::string FindNormalHeader();
+  std::string FindFrameworkHeader();
 };
 };
 
 
 
 

+ 5 - 2
Source/cmFindProgramCommand.cxx

@@ -97,8 +97,7 @@ std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
 {
 {
   std::string program = "";
   std::string program = "";
 
 
-  // First/last order taken care of in cmFindBase when the paths are setup.
-  if(this->SearchAppBundleFirst || this->SearchAppBundleLast)
+  if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
     {
     {
     program = FindAppBundle(names);
     program = FindAppBundle(names);
     }
     }
@@ -107,6 +106,10 @@ std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
     program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
     program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
     }
     }
 
 
+  if(program.empty() && this->SearchAppBundleLast)
+    {
+    program = this->FindAppBundle(names);
+    }
   return program;
   return program;
 }
 }