Browse Source

ENH: Improved support for user-configured search paths. Paths given in the CMAKE_LIBRARY_PATH cmake variable are searched first, then those in the CMAKE_LIBRARY_PATH environment variable, then those listed in the call to the FIND_LIBRARY command and finally those listed in the PATH environment variable. The support is similar for finding include files with FIND_PATH, but the variable is CMAKE_INCLUDE_PATH.

Brad King 20 years ago
parent
commit
938890757a

+ 6 - 8
Source/cmFindFileCommand.cxx

@@ -60,20 +60,18 @@ bool cmFindFileCommand::InitialPass(std::vector<std::string> const& argsIn)
     {
     return true;
     }
-  // if it is not in the cache, then search the system path
-  std::vector<std::string> path;
 
-  // add any user specified paths
+  // The location is not in the cache.  Create a search path.
+  std::vector<std::string> path;
+  std::vector<std::string> callPaths;
   for (unsigned int j = 2; j < args.size(); j++)
     {
     // Glob the entry in case of wildcards.
-    cmSystemTools::GlobDirs(args[j].c_str(), path);
+    cmSystemTools::GlobDirs(args[j].c_str(), callPaths);
     }
+  m_Makefile->GetLibrarySearchPath(callPaths, path);
 
-  cmSystemTools::GetPath(path, "CMAKE_LIBRARY_PATH");
-
-  // add the standard path
-  cmSystemTools::GetPath(path);
+  // Use the search path to find the file.
   for(unsigned int k=0; k < path.size(); k++)
     {
     std::string tryPath = path[k];

+ 7 - 4
Source/cmFindLibraryCommand.h

@@ -72,8 +72,7 @@ public:
       "               [PATHS path1 path2 ...]\n"
       "               [DOC \"docstring\"])\n"
       "Find a library named by one of the names given after the NAMES "
-      "argument.  Paths specified after the PATHS argument are searched "
-      "in the order specified.  A cache entry named by <VAR> is created "
+      "argument.  A cache entry named by <VAR> is created "
       "to store the result.  If the library is not found, the result "
       "will be <VAR>-NOTFOUND.  If DOC is specified then the next "
       "argument is treated as a documentation string for the cache "
@@ -81,8 +80,12 @@ public:
       "  FIND_LIBRARY(VAR libraryName [path1 path2 ...])\n"
       "Find a library with the given name by searching in the specified "
       "paths.  This is a short-hand signature for the command that is "
-      "sufficient in many cases.  The environment variable CMAKE_LIBRARY_PATH "
-      "is searched as well as the PATH variable.\n";
+      "sufficient in many cases.  "
+      "The search proceeds first in paths listed in the CMAKE_LIBRARY_PATH "
+      "CMake variable (which is generally set by the user on the command line), "
+      "then in paths listed in the CMAKE_LIBRARY_PATH environment variable, "
+      "then in paths given to the PATHS option of the command, "
+      "and finally in paths listed in the PATH environment variable.";
     }
   
   cmTypeMacro(cmFindLibraryCommand, cmCommand);

+ 8 - 6
Source/cmFindPathCommand.cxx

@@ -64,20 +64,22 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
       helpString = hs?hs:"(none)";
       }
     }
+
+  // Construct a search path.
   std::vector<std::string> path;
-  // add any user specified paths
+  std::vector<std::string> callPaths;
   for (unsigned int j = 2; j < args.size(); j++)
     {
     // expand variables
     std::string exp = args[j];
-    cmSystemTools::ExpandRegistryValues(exp);      
+    cmSystemTools::ExpandRegistryValues(exp);
 
     // Glob the entry in case of wildcards.
-    cmSystemTools::GlobDirs(exp.c_str(), path);
+    cmSystemTools::GlobDirs(exp.c_str(), callPaths);
     }
-  cmSystemTools::GetPath(path, "CMAKE_INCLUDE_PATH");
-  // add the standard path
-  cmSystemTools::GetPath(path);
+  m_Makefile->GetIncludeSearchPath(callPaths, path);
+
+  // Use the search path to find the file.
   unsigned int k;
   for(k=0; k < path.size(); k++)
     {

+ 8 - 4
Source/cmFindPathCommand.h

@@ -70,13 +70,17 @@ public:
     return
       "  FIND_PATH(<VAR> fileName path1 [path2 ...]\n"
       "            [DOC \"docstring\"])\n"
-      "Find the directory containing a file named by fileName.  Paths "
-      "are searched in the order specified.  A cache entry named by "
+      "Find the directory containing a file named by fileName.  "
+      "A cache entry named by "
       "<VAR> is created to store the result.  If the file is not "
       "found, the result will be <VAR>-NOTFOUND.  If DOC is specified "
       "then the next argument is treated as a documentation string for "
-      "the cache entry <VAR>.  The environment variable CMAKE_INCLUDE_PATH "
-      "is searched as well as the PATH variable.\n";
+      "the cache entry <VAR>.  "
+      "The search proceeds first in paths listed in the CMAKE_INCLUDE_PATH "
+      "CMake variable (which is generally set by the user on the command line), "
+      "then in paths listed in the CMAKE_INCLUDE_PATH environment variable, "
+      "then in paths given to the command, and finally in paths listed in the "
+      "PATH environment variable.";
     }
   cmStdString FindHeaderInFrameworks( std::vector<std::string> path,
                                       const char* var, const char* file);

+ 49 - 6
Source/cmMakefile.cxx

@@ -2195,18 +2195,17 @@ std::string cmMakefile::FindLibrary(const char* name,
     {
     return cmSystemTools::CollapseFullPath(name);
     }
-  // Add the system search path to our path.
+
+  // Construct a search path.
   std::vector<std::string> path;
-  cmSystemTools::GetPath(path, "CMAKE_LIBRARY_PATH");
-  cmSystemTools::GetPath(path, "LIB");
-  cmSystemTools::GetPath(path);
+  this->GetLibrarySearchPath(userPaths, path);
+
   bool supportFrameworks = false;
   if(this->GetDefinition("APPLE"))
     {
     supportFrameworks = true;
     }
-  // now add the path
-  path.insert(path.end(), userPaths.begin(), userPaths.end());
+
   // Add some lib directories specific to compilers, depending on the
   // current generator, so that library that might have been stored here
   // can be found too.
@@ -2309,6 +2308,50 @@ std::string cmMakefile::FindLibrary(const char* name,
   return tmp;
 }
 
+//----------------------------------------------------------------------------
+void
+cmMakefile::GetIncludeSearchPath(const std::vector<std::string>& callerPaths,
+                                 std::vector<std::string>& path)
+{
+  // Add paths configured into the cache for this project.
+  if(const char* cmakeIncludePath = this->GetDefinition("CMAKE_INCLUDE_PATH"))
+    {
+    cmSystemTools::ExpandListArgument(cmakeIncludePath, path);
+    }
+
+  // Add paths in the user's environment.
+  cmSystemTools::GetPath(path, "CMAKE_INCLUDE_PATH");
+  cmSystemTools::GetPath(path, "INCLUDE");
+
+  // Add paths given by the caller.
+  path.insert(path.end(), callerPaths.begin(), callerPaths.end());
+
+  // Add standard system paths.
+  cmSystemTools::GetPath(path);
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefile::GetLibrarySearchPath(const std::vector<std::string>& callerPaths,
+                                 std::vector<std::string>& path)
+{
+  // Add paths configured into the cache for this project.
+  if(const char* cmakeLibPath = this->GetDefinition("CMAKE_LIBRARY_PATH"))
+    {
+    cmSystemTools::ExpandListArgument(cmakeLibPath, path);
+    }
+
+  // Add paths in the user's environment.
+  cmSystemTools::GetPath(path, "CMAKE_LIBRARY_PATH");
+  cmSystemTools::GetPath(path, "LIB");
+
+  // Add paths given by the caller.
+  path.insert(path.end(), callerPaths.begin(), callerPaths.end());
+
+  // Add standard system paths.
+  cmSystemTools::GetPath(path);
+}
+
 std::string cmMakefile::GetModulesFile(const char* filename)
 {
   std::vector<std::string> modulePath;

+ 8 - 0
Source/cmMakefile.h

@@ -235,6 +235,14 @@ public:
   std::string FindLibrary(const char* name,
                           const std::vector<std::string>& path);
 
+  /**
+   * Get the include file or library search path.
+   */
+  void GetIncludeSearchPath(const std::vector<std::string>& callerPaths,
+                            std::vector<std::string>& path);
+  void GetLibrarySearchPath(const std::vector<std::string>& callerPaths,
+                            std::vector<std::string>& path);
+
   /**
    * Add a variable definition to the build. This variable
    * can be used in CMake to refer to lists, directories, etc.