Преглед изворни кода

find_package: optionally resolve symlinks when discovering packages

Teach find_package() to resolve symlinks when constructing
relocatable prefix paths from discovered cmake config files.
The `CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS` variable enables
this behavior when set to `TRUE`.

Fixes: #18704
David Aguilar пре 6 година
родитељ
комит
a5e948a36f

+ 5 - 0
Help/command/find_package.rst

@@ -354,6 +354,11 @@ enabled.
 .. include:: FIND_XXX_ROOT.txt
 .. include:: FIND_XXX_ORDER.txt
 
+By default the value stored in the result variable will be the path at
+which the file is found.  The :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS`
+variable may be set to ``TRUE`` before calling ``find_package`` in order
+to resolve symbolic links and store the real path to the file.
+
 Every non-REQUIRED ``find_package`` call can be disabled by setting the
 :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``.
 

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -170,6 +170,7 @@ Variables that Change Behavior
    /variable/CMAKE_FIND_NO_INSTALL_PREFIX
    /variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
    /variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
+   /variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
    /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
    /variable/CMAKE_FIND_ROOT_PATH
    /variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE

+ 6 - 0
Help/release/dev/find-package-resolve-symlinks.rst

@@ -0,0 +1,6 @@
+find-package-resolve-symlinks
+-----------------------------
+
+* The :command:`find_package` command learned to optionally resolve
+  symbolic links in the paths to package configuration files.
+  See the :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS` variable.

+ 10 - 0
Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst

@@ -0,0 +1,10 @@
+CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
+-----------------------------------
+
+Set to ``TRUE`` to tell :command:`find_package` calls to resolve symbolic
+links in the value of ``<PackageName>_DIR``.
+
+This is helpful in use cases where the package search path points at a
+proxy directory in which symlinks to the real package locations appear.
+This is not enabled by default because there are also common use cases
+in which the symlinks should be preserved.

+ 10 - 0
Source/cmFindPackageCommand.cxx

@@ -95,6 +95,7 @@ cmFindPackageCommand::cmFindPackageCommand()
   this->UseLib32Paths = false;
   this->UseLib64Paths = false;
   this->UseLibx32Paths = false;
+  this->UseRealPath = false;
   this->PolicyScope = true;
   this->VersionMajor = 0;
   this->VersionMinor = 0;
@@ -195,6 +196,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
     this->NoSystemRegistry = true;
   }
 
+  // Check whether we should resolve symlinks when finding packages
+  if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS")) {
+    this->UseRealPath = true;
+  }
+
   // Check if Sorting should be enabled
   if (const char* so =
         this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
@@ -1502,6 +1508,10 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
       fprintf(stderr, "Checking file [%s]\n", file.c_str());
     }
     if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) {
+      // Allow resolving symlinks when the config file is found through a link
+      if (this->UseRealPath) {
+        file = cmSystemTools::GetRealPath(file);
+      }
       return true;
     }
   }

+ 1 - 0
Source/cmFindPackageCommand.h

@@ -178,6 +178,7 @@ private:
   bool UseLib32Paths;
   bool UseLib64Paths;
   bool UseLibx32Paths;
+  bool UseRealPath;
   bool PolicyScope;
   std::string LibraryArchitecture;
   std::vector<std::string> Names;