瀏覽代碼

ENH: change find library and find program to look for more than one name

Bill Hoffman 24 年之前
父節點
當前提交
f07ee5b817

+ 2 - 5
Modules/FindFLTK.cmake

@@ -10,10 +10,7 @@ FIND_PATH(FLTK_INCLUDE_PATH FL/FL.H
 H:/usr/local/fltk
 )
 
-FIND_LIBRARY(FLTK_LIB_PATH fltk
-/usr/lib
-/usr/local/lib
-/usr/local/fltk/lib
-H:/usr/local/fltk/lib
+FIND_LIBRARY(FLTK_LIB_PATH  fltk
+PATHS /usr/lib /usr/local/lib /usr/local/fltk/lib H:/usr/local/fltk/lib
 )
 

+ 3 - 6
Modules/FindGTK.cmake

@@ -11,14 +11,11 @@ IF (UNIX)
   /usr/openwin/share/include
   )
 
-  FIND_LIBRARY(GTK_LIB_PATH gtk
-  /usr/lib
-  /usr/local/lib
-  /usr/openwin/lib
-  /usr/X11R6/lib
+  FIND_LIBRARY(GTK_LIB_PATH  gtk
+  PATHS /usr/lib  /usr/local/lib  /usr/openwin/lib  /usr/X11R6/lib
   )
 
-  FIND_LIBRARY(GTK_GLIB_INCLUDE_PATH glibconfig.h
+  FIND_PATH(GTK_GLIB_INCLUDE_PATH glibconfig.h
   /usr/include
   /usr/local/include
   /usr/openwin/share/include

+ 1 - 1
Modules/FindJNI.cmake

@@ -8,7 +8,7 @@
 #  JAVA_AWT_INCLUDE_PATH = the path to where jni.h can be found
 # 
         
-FIND_LIBRARY(JAVA_AWT_LIB_PATH jawt /usr/lib /usr/local/lib)
+FIND_LIBRARY(JAVA_AWT_LIB_PATH jawt PATHS /usr/lib /usr/local/lib)
 
 # add in the include path    
 FIND_PATH(JAVA_INCLUDE_PATH jni.h /usr/include /usr/local/include)

+ 2 - 3
Modules/FindJPEG.cmake

@@ -8,8 +8,7 @@ FIND_PATH(NATIVE_JPEG_INCLUDE_PATH jpeglib.h
 /usr/include
 )
 
-FIND_LIBRARY(NATIVE_JPEG_LIB_PATH jpeg
-/usr/lib
-/usr/local/lib
+FIND_LIBRARY(NATIVE_JPEG_LIB_PATH  jpeg
+PATHS /usr/lib /usr/local/lib
 )
 

+ 3 - 15
Modules/FindMPI.cmake

@@ -3,24 +3,12 @@
 # it will define the following values
 #
 # MPI_INCLUDE_PATH = where mpi.h can be found
-# MPI_LIB_PATH     = path to the mpi library
 # MPI_LIBRARY      = the library to link against (mpi mpich etc)
 #
 
 FIND_PATH(MPI_INCLUDE_PATH mpi.h /usr/local/include /usr/include /usr/local/mpi/include)
 
-# look for the different MPI libs
-IF (NOT MPI_LIB_PATH)
-  FIND_LIBRARY(MPI_LIB_PATH mpi /usr/lib /usr/local/lib /usr/local/mpi/lib)
-  IF (MPI_LIB_PATH)
-    SET (MPI_LIBRARY mpi CACHE)
-  ENDIF (MPI_LIB_PATH)
-ENDIF (NOT MPI_LIB_PATH)
-
-IF (NOT MPI_LIB_PATH)
-  FIND_LIBRARY(MPI_LIB_PATH mpich /usr/lib /usr/local/lib /usr/local/mpi/lib)
-  IF (MPI_LIB_PATH)
-    SET (MPI_LIBRARY mpich CACHE)
-  ENDIF (MPI_LIB_PATH)
-ENDIF (NOT MPI_LIB_PATH)
+FIND_LIBRARY(MPI_LIBRARY 
+             NAMES mpi mpich
+             PATHS /usr/lib /usr/local/lib /usr/local/mpi/lib)
 

+ 8 - 46
Modules/FindTCL.cmake

@@ -3,58 +3,20 @@
 # include files and libraries are. It also determines what the name of
 # the library is. This code sets the following variables:
 #
-#  TCL_LIB_PATH     = the path to where the TCL library is
-#  TCL_LIBRARY      = the name of the tcl library found (tcl tcl80 etc)
+#  TCL_LIBRARY      = the full path to the tcl library found (tcl tcl80 etc)
 #  TCL_INCLUDE_PATH = the path to where tcl.h can be found
-#  TK_LIB_PATH      = the path to where the TK library is
-#  TK_LIBRARY       = the name of the tk library found (tk tk80 etc)
+#  TK_LIBRARY       = the full path to the tk library found (tk tk80 etc)
 #  TK_INCLUDE_PATH  = the path to where tk.h can be found
 #
-# 
 
 # try to find the Tcl libraries in a few places and names
-IF (NOT TCL_LIB_PATH)
-  FIND_LIBRARY(TCL_LIB_PATH tcl "C:/Program Files/Tcl/lib" /usr/lib /usr/local/lib)
-  IF (TCL_LIB_PATH)
-    SET (TCL_LIBRARY tcl CACHE)
-  ENDIF (TCL_LIB_PATH)
-ENDIF (NOT TCL_LIB_PATH)
+FIND_LIBRARY(TCL_LIBRARY
+             NAMES tcl tcl82 tcl80 
+             PATHS  /usr/lib "C:/Program Files/Tcl/lib" /usr/local/lib)
 
-IF (NOT TCL_LIB_PATH)
-  FIND_LIBRARY(TCL_LIB_PATH tcl82 "C:/Program Files/Tcl/lib" /usr/lib /usr/local/lib)
-  IF (TCL_LIB_PATH)
-    SET (TCL_LIBRARY tcl82 CACHE)
-  ENDIF (TCL_LIB_PATH)
-ENDIF (NOT TCL_LIB_PATH)
-
-IF (NOT TCL_LIB_PATH)
-  FIND_LIBRARY(TCL_LIB_PATH tcl80 "C:/Program Files/Tcl/lib" /usr/lib /usr/local/lib)
-  IF (TCL_LIB_PATH)
-    SET (TCL_LIBRARY tcl80 CACHE)
-  ENDIF (TCL_LIB_PATH)
-ENDIF (NOT TCL_LIB_PATH)
-
-# try to find the Tk libraries in a few places and names
-IF (NOT TK_LIB_PATH)
-  FIND_LIBRARY(TK_LIB_PATH tk "C:/Program Files/Tcl/lib" /usr/lib /usr/local/lib)
-  IF (TK_LIB_PATH)
-    SET (TK_LIBRARY tk CACHE)
-  ENDIF (TK_LIB_PATH)
-ENDIF (NOT TK_LIB_PATH)
-
-IF (NOT TK_LIB_PATH)
-  FIND_LIBRARY(TK_LIB_PATH tk82 "C:/Program Files/Tcl/lib" /usr/lib /usr/local/lib)
-  IF (TK_LIB_PATH)
-    SET (TK_LIBRARY tk82 CACHE)
-  ENDIF (TK_LIB_PATH)
-ENDIF (NOT TK_LIB_PATH)
-
-IF (NOT TK_LIB_PATH)
-  FIND_LIBRARY(TK_LIB_PATH tk80 "C:/Program Files/Tcl/lib" /usr/lib /usr/local/lib)
-  IF (TK_LIB_PATH)
-    SET (TK_LIBRARY tk80 CACHE)
-  ENDIF (TK_LIB_PATH)
-ENDIF (NOT TK_LIB_PATH)
+FIND_LIBRARY(TK_LIBRARY 
+             NAMES tk tk82 tk80
+             PATHS /usr/lib "C:/Program Files/Tcl/lib" /usr/local/lib)
 
 # add in the include path    
 FIND_PATH(TCL_INCLUDE_PATH tcl.h "C:/Program Files/Tcl/include" /usr/include /usr/local/include)

+ 1 - 1
Source/cmCommand.h

@@ -148,7 +148,7 @@ public:
     {
       if(m_Error.length() == 0)
         {
-        std::string m_Error = this->GetName();
+        m_Error = this->GetName();
         m_Error += " uknown error.";
         }
       return m_Error.c_str();

+ 57 - 56
Source/cmFindLibraryCommand.cxx

@@ -57,78 +57,79 @@ bool cmFindLibraryCommand::Invoke(std::vector<std::string>& args)
     = cmCacheManager::GetInstance()->GetCacheValue(args[0].c_str());
   if(cacheValue && strcmp(cacheValue, "NOTFOUND"))
     { 
-      m_Makefile->AddDefinition(args[0].c_str(), cacheValue);
-      cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
-                                                   cacheValue,
-                                                   helpString.c_str(),
-                                                   cmCacheManager::PATH);
+    m_Makefile->AddDefinition(args[0].c_str(), cacheValue);
+    cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
+                                                 cacheValue,
+                                                 helpString.c_str(),
+                                                 cmCacheManager::FILEPATH);
     return true;
     }
-
   std::vector<std::string> path;
-  // add any user specified paths
-  for (unsigned int j = 2; j < args.size(); j++)
-    {
-    // expand variables
-    std::string exp = args[j];
-    m_Makefile->ExpandVariablesInString(exp);
-    path.push_back(exp);
-    }
-
-  // add the standard path
-  cmSystemTools::GetPath(path);
-  unsigned int k;
-  for(k=0; k < path.size(); k++)
+  std::vector<std::string> names;
+  bool namePathStyle = false;
+  bool foundName = false;
+  bool foundPath = false;
+  bool doingNames = true;
+  for (unsigned int j = 1; j < args.size(); ++j)
     {
-    std::string tryPath = path[k];
-    tryPath += "/";
-    std::string testF;
-    testF = tryPath + args[1] + ".lib";
-    if(cmSystemTools::FileExists(testF.c_str()))
+    if(args[j] == "NAMES")
       {
-      m_Makefile->AddDefinition(args[0].c_str(), path[k].c_str());  
-      cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
-                                                   path[k].c_str(),
-                                                   helpString.c_str(),
-                                                   cmCacheManager::PATH);
-      return true;
+      doingNames = true;
+      foundName = true;
       }
-    testF = tryPath + "lib" + args[1] + ".so";
-    if(cmSystemTools::FileExists(testF.c_str()))
+    else if (args[j] == "PATHS")
       {
-      m_Makefile->AddDefinition(args[0].c_str(), path[k].c_str());  
-      cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
-                                                   path[k].c_str(),
-                                                   helpString.c_str(),
-                                                   cmCacheManager::PATH);
-      return true;
+      doingNames = false;
+      foundPath = true;
+      }
+    else
+      { 
+      m_Makefile->ExpandVariablesInString(args[j]);
+      if(doingNames)
+        {
+        names.push_back(args[j]);
+        }
+      else
+        {
+        path.push_back(args[j]);
+        }
       }
-    testF = tryPath + "lib" + args[1] + ".a";
-    if(cmSystemTools::FileExists(testF.c_str()))
+    }
+  // old style name path1 path2 path3
+  if(!foundPath && !foundName)
+    {
+    names.clear();
+    path.clear();
+    names.push_back(args[1]);
+    // add any user specified paths
+    for (unsigned int j = 2; j < args.size(); j++)
       {
-      m_Makefile->AddDefinition(args[0].c_str(), path[k].c_str());  
+      // expand variables
+      std::string exp = args[j];
+      m_Makefile->ExpandVariablesInString(exp);
+      path.push_back(exp);
+      }
+    }
+  std::string library;
+  for(std::vector<std::string>::iterator i = names.begin();
+      i != names.end() ; ++i)
+    {
+    library = cmSystemTools::FindLibrary(i->c_str(),
+                                         path);
+    if(library != "")
+      {  
+      m_Makefile->AddDefinition(args[0].c_str(), library.c_str());  
       cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
-                                                   path[k].c_str(),
+                                                   library.c_str(),
                                                    helpString.c_str(),
-                                                   cmCacheManager::PATH);
+                                                   cmCacheManager::FILEPATH);
       return true;
-      }
-    testF = tryPath + "lib" + args[1] + ".sl";
-    if(cmSystemTools::FileExists(testF.c_str()))
-      {
-      m_Makefile->AddDefinition(args[0].c_str(), path[k].c_str());  
-      cmCacheManager::GetInstance()->
-        AddCacheEntry(args[0].c_str(),
-                      path[k].c_str(),
-                      helpString.c_str(),
-                      cmCacheManager::PATH);
-      return true;
-      }
+      } 
     }
   cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
                                                "NOTFOUND",
                                                helpString.c_str(),
-                                               cmCacheManager::PATH);
+                                               cmCacheManager::FILEPATH);
   return true;
 }
 

+ 2 - 2
Source/cmFindLibraryCommand.h

@@ -94,8 +94,8 @@ public:
   virtual const char* GetFullDocumentation()
     {
     return
-      "FIND_LIBRARY(DEFINE_PATH libraryName path1 path2 path3...)\n"
-      "If the library is found, then DEFINE_PATH is set to the path where it was found";
+      "FIND_LIBRARY(DEFINE_PATH libraryName [NAMES] name1 name2 name3 [PATHS path1 path2 path3...])\n"
+      "If the library is found, then DEFINE_PATH is set to the full path where it was found";
     }
   
   cmTypeMacro(cmFindLibraryCommand, cmCommand);

+ 62 - 25
Source/cmFindProgramCommand.cxx

@@ -60,40 +60,77 @@ bool cmFindProgramCommand::Invoke(std::vector<std::string>& args)
   // already, if so use that value and don't look for the program
   const char* cacheValue
     = cmCacheManager::GetInstance()->GetCacheValue(define);
-  if(cacheValue)
+  if(cacheValue && strcmp(cacheValue, "NOTFOUND"))
     {
     m_Makefile->AddDefinition(define, cacheValue);
     return true;
     }
-
-  // if it is not in the cache, then search the system path
-  // add any user specified paths
   std::vector<std::string> path;
-  for (unsigned int j = 2; j < args.size(); j++)
+  std::vector<std::string> names;
+  bool namePathStyle = false;
+  bool foundName = false;
+  bool foundPath = false;
+  bool doingNames = true;
+  for (unsigned int j = 1; j < args.size(); ++j)
     {
-    // expand variables
-    std::string exp = args[j];
-    m_Makefile->ExpandVariablesInString(exp);
-    path.push_back(exp);
+    if(args[j] == "NAMES")
+      {
+      doingNames = true;
+      foundName = true;
+      }
+    else if (args[j] == "PATHS")
+      {
+      doingNames = false;
+      foundPath = true;
+      }
+    else
+      { 
+      m_Makefile->ExpandVariablesInString(args[j]);
+      if(doingNames)
+        {
+        names.push_back(args[j]);
+        }
+      else
+        {
+        path.push_back(args[j]);
+        }
+      }
     }
-  
-  // Try to find the program.
-  std::string result = cmSystemTools::FindProgram(i->c_str(), path);
-  
-  if(result != "")
+  // if it is not in the cache, then search the system path
+  // add any user specified paths 
+  if(!foundPath && !foundName)
     {
-    // Save the value in the cache
-    cmCacheManager::GetInstance()->AddCacheEntry(define,
-                                                 result.c_str(),
-                                                 "Path to a program.",
-                                                 cmCacheManager::FILEPATH);
-    m_Makefile->AddDefinition(define, result.c_str());
-    return true;
+    path.clear();
+    names.clear();
+    names.push_back(args[1]);
+    for (unsigned int j = 2; j < args.size(); j++)
+      {
+      // expand variables
+      std::string exp = args[j];
+      m_Makefile->ExpandVariablesInString(exp);
+      path.push_back(exp);
+      }
+    }
+  for(std::vector<std::string>::iterator i = names.begin();
+      i != names.end() ; ++i)
+    {
+    // Try to find the program.
+    std::string result = cmSystemTools::FindProgram(i->c_str(), path);
+    if(result != "")
+      {
+      // Save the value in the cache
+      cmCacheManager::GetInstance()->AddCacheEntry(define,
+                                                   result.c_str(),
+                                                   "Path to a program.",
+                                                   cmCacheManager::FILEPATH);
+      m_Makefile->AddDefinition(define, result.c_str());
+      return true;
+      }
     }
-  std::string error = "Faild to find program: \"";
-  error += *i;
-  error += "\" ";
-  this->SetError(error.c_str());
+  cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
+                                               "NOTFOUND",
+                                               "Path to a program",
+                                               cmCacheManager::FILEPATH);
   return true;
 }
 

+ 58 - 2
Source/cmSystemTools.cxx

@@ -613,8 +613,6 @@ std::string cmSystemTools::TemporaryFileName()
 {
   return tempnam(0, "cmake");
 }
-
-  
   
 
 
@@ -657,6 +655,63 @@ std::string cmSystemTools::FindProgram(const char* name,
   return "";
 }
 
+
+/**
+ * Find the library with the given name.  Searches the given path and then
+ * the system search path.  Returns the full path to the library if it is
+ * found.  Otherwise, the empty string is returned.
+ */
+std::string cmSystemTools::FindLibrary(const char* name,
+				       const std::vector<std::string>& userPaths)
+{
+  // See if the executable exists as written.
+  if(cmSystemTools::FileExists(name))
+    {
+    return cmSystemTools::CollapseFullPath(name);
+    }
+    
+  // Add the system search path to our path.
+  std::vector<std::string> path = userPaths;
+  cmSystemTools::GetPath(path);
+  std::string tryPath;
+  for(std::vector<std::string>::const_iterator p = path.begin();
+      p != path.end(); ++p)
+    {
+    tryPath = *p;
+    tryPath += "/";
+    tryPath += name;
+    tryPath += ".lib";
+    if(cmSystemTools::FileExists(tryPath.c_str()))
+      {
+      return cmSystemTools::CollapseFullPath(tryPath.c_str());
+      }
+    tryPath = "lib";
+    tryPath += *p;
+    tryPath + ".so";
+    if(cmSystemTools::FileExists(tryPath.c_str()))
+      {
+      return cmSystemTools::CollapseFullPath(tryPath.c_str());
+      }
+    tryPath = "lib";
+    tryPath += *p;
+    tryPath + ".a";
+    if(cmSystemTools::FileExists(tryPath.c_str()))
+      {
+      return cmSystemTools::CollapseFullPath(tryPath.c_str());
+      }
+    tryPath = "lib";
+    tryPath += *p;
+    tryPath + ".sl";
+    if(cmSystemTools::FileExists(tryPath.c_str()))
+      {
+      return cmSystemTools::CollapseFullPath(tryPath.c_str());
+      }
+    }
+  
+  // Couldn't find the library.
+  return "";
+}
+
 bool cmSystemTools::FileIsDirectory(const char* name)
 {  
   struct stat fs;
@@ -737,6 +792,7 @@ void cmSystemTools::SplitProgramPath(const char* in_name,
  */
 std::string cmSystemTools::CollapseFullPath(const char* in_name)
 {
+  std::cerr << "CollapseFullPath " << in_name << "\n";
   std::string dir, file;
   cmSystemTools::SplitProgramPath(in_name, dir, file);
   // Ultra-hack warning:

+ 7 - 3
Source/cmSystemTools.h

@@ -164,11 +164,15 @@ public:
    * IsON and IsOff both returning false. Note that the special path
    * NOTFOUND will cause IsOff to return true. 
    */
-   static bool IsOff(const char* val);
+  static bool IsOff(const char* val);
 
+  ///! Find an executable in the system PATH, with optional extra paths.
   static std::string FindProgram(const char* name,
-				 const std::vector<std::string>& = std::vector<std::string>());
-  
+				 const std::vector<std::string>& path= std::vector<std::string>());
+  ///! Find a library in the system PATH, with optional extra paths.
+  static std::string FindLibrary(const char* name,
+				 const std::vector<std::string>& path);
+  ///! return true if the file is a directory.
   static bool FileIsDirectory(const char* name);
   static std::string GetCurrentWorkingDirectory();
   static std::string GetProgramPath(const char*);

+ 24 - 7
Source/cmUnixMakefileGenerator.cxx

@@ -187,7 +187,7 @@ void cmUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
       {
       linkLibs += "-L";
       }
-    linkLibs += *j;
+    linkLibs += cmSystemTools::EscapeSpaces(j->c_str());
     linkLibs += " ";
     }
   std::string librariesLinked;
@@ -199,14 +199,31 @@ void cmUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
     if(targetLibrary && (j2->first == targetLibrary)) continue;
     // don't look at debug libraries
     if (j2->second == cmTarget::DEBUG) continue;
-    std::string::size_type pos = j2->first.find("-l");
-    if((pos == std::string::npos || pos > 0)
-       && j2->first.find("${") == std::string::npos)
+    std::cerr << j2->first.c_str() << "\n";
+    
+    if(j2->first.find('/') != std::string::npos)
       {
+      std::string dir, file;
+      cmSystemTools::SplitProgramPath(j2->first.c_str(),
+                                      dir, file);
+      linkLibs += "-L";
+      linkLibs += cmSystemTools::EscapeSpaces(dir.c_str());
+      linkLibs += " ";
       librariesLinked += "-l";
+      librariesLinked += file;
+      librariesLinked += " ";
+      }
+    else
+      {
+      std::string::size_type pos = j2->first.find("-l");
+      if((pos == std::string::npos || pos > 0)
+         && j2->first.find("${") == std::string::npos)
+        {
+        librariesLinked += "-l";
+        }
+      librariesLinked += j2->first;
+      librariesLinked += " ";
       }
-    librariesLinked += j2->first;
-    librariesLinked += " ";
     }
   linkLibs += librariesLinked;
 
@@ -325,7 +342,7 @@ void cmUnixMakefileGenerator::OutputMakeFlags(std::ostream& fout)
   for(i = includes.begin(); i != includes.end(); ++i)
     {
     std::string include = *i;
-    fout << "-I" << i->c_str() << " ";
+    fout << "-I" << cmSystemTools::EscapeSpaces(i->c_str()).c_str() << " ";
     }
   fout << m_Makefile->GetDefineFlags();
   fout << " ${LOCAL_INCLUDE_FLAGS} ";