Browse Source

Merge topic 'build-install-rpath-genex'

d29ed8a114 BUILD_RPATH/INSTALL_RPATH: Add generator expression support

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3481
Brad King 6 years ago
parent
commit
06f1560a58

+ 3 - 0
Help/prop_tgt/BUILD_RPATH.rst

@@ -8,3 +8,6 @@ tree.  See also the :prop_tgt:`INSTALL_RPATH` target property.
 
 This property is initialized by the value of the variable
 :variable:`CMAKE_BUILD_RPATH` if it is set when a target is created.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 3 - 0
Help/prop_tgt/INSTALL_RPATH.rst

@@ -7,3 +7,6 @@ A semicolon-separated list specifying the rpath to use in installed
 targets (for platforms that support it).  This property is initialized
 by the value of the variable :variable:`CMAKE_INSTALL_RPATH` if it is set when
 a target is created.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 5 - 0
Help/release/dev/build-install-rpath-genex.rst

@@ -0,0 +1,5 @@
+build-install-rpath-genex
+-------------------------
+
+* :prop_tgt:`BUILD_RPATH` and :prop_tgt:`INSTALL_RPATH` now support
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 7 - 5
Source/cmComputeLinkInformation.cxx

@@ -1695,7 +1695,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
     (for_install ||
      this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
   bool use_install_rpath =
-    (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+    (outputRuntime && this->Target->HaveInstallTreeRPATH(this->Config) &&
      linking_for_install);
   bool use_build_rpath =
     (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
@@ -1715,15 +1715,17 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
   // Construct the RPATH.
   std::set<std::string> emitted;
   if (use_install_rpath) {
-    const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
-    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
+    std::string install_rpath;
+    this->Target->GetInstallRPATH(this->Config, install_rpath);
+    cmCLI_ExpandListUnique(install_rpath.c_str(), runtimeDirs, emitted);
   }
   if (use_build_rpath) {
     // Add directories explicitly specified by user
-    if (const char* build_rpath = this->Target->GetProperty("BUILD_RPATH")) {
+    std::string build_rpath;
+    if (this->Target->GetBuildRPATH(this->Config, build_rpath)) {
       // This will not resolve entries to use $ORIGIN, the user is expected to
       // do that if necessary.
-      cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
+      cmCLI_ExpandListUnique(build_rpath.c_str(), runtimeDirs, emitted);
     }
   }
   if (use_build_rpath || use_link_rpath) {

+ 34 - 5
Source/cmGeneratorTarget.cxx

@@ -1612,7 +1612,7 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall(
   // will likely change between the build tree and install tree and
   // this target must be relinked.
   bool have_rpath =
-    this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
+    this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(config);
   bool is_ninja =
     this->LocalGenerator->GetGlobalGenerator()->GetName() == "Ninja";
 
@@ -5479,13 +5479,41 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
   return true;
 }
 
-bool cmGeneratorTarget::HaveInstallTreeRPATH() const
+bool cmGeneratorTarget::HaveInstallTreeRPATH(const std::string& config) const
 {
-  const char* install_rpath = this->GetProperty("INSTALL_RPATH");
-  return (install_rpath && *install_rpath) &&
+  std::string install_rpath;
+  this->GetInstallRPATH(config, install_rpath);
+  return !install_rpath.empty() &&
     !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
 }
 
+bool cmGeneratorTarget::GetBuildRPATH(const std::string& config,
+                                      std::string& rpath) const
+{
+  return this->GetRPATH(config, "BUILD_RPATH", rpath);
+}
+
+bool cmGeneratorTarget::GetInstallRPATH(const std::string& config,
+                                        std::string& rpath) const
+{
+  return this->GetRPATH(config, "INSTALL_RPATH", rpath);
+}
+
+bool cmGeneratorTarget::GetRPATH(const std::string& config,
+                                 const std::string& prop,
+                                 std::string& rpath) const
+{
+  const char* value = this->GetProperty(prop);
+  if (!value) {
+    return false;
+  }
+
+  cmGeneratorExpression ge;
+  rpath = ge.Parse(value)->Evaluate(this->LocalGenerator, config);
+
+  return true;
+}
+
 void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
   const std::string& config, cmOptionalLinkInterface& iface,
   cmGeneratorTarget const* headTarget, bool usage_requirements_only) const
@@ -6085,7 +6113,8 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
   if (this->GetPropertyAsBool("SKIP_BUILD_RPATH")) {
     return false;
   }
-  if (this->GetProperty("BUILD_RPATH")) {
+  std::string build_rpath;
+  if (this->GetBuildRPATH(config, build_rpath)) {
     return true;
   }
   if (cmLinkImplementationLibraries const* impl =

+ 7 - 1
Source/cmGeneratorTarget.h

@@ -674,7 +674,10 @@ public:
 
   class TargetPropertyEntry;
 
-  bool HaveInstallTreeRPATH() const;
+  bool HaveInstallTreeRPATH(const std::string& config) const;
+
+  bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
+  bool GetInstallRPATH(const std::string& config, std::string& rpath) const;
 
   /** Whether this library has \@rpath and platform supports it.  */
   bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
@@ -913,6 +916,9 @@ private:
 
   ManagedType CheckManagedType(std::string const& propval) const;
 
+  bool GetRPATH(const std::string& config, const std::string& prop,
+                std::string& rpath) const;
+
 public:
   const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
     const std::string& config) const;

+ 29 - 0
Tests/RunCMake/RuntimePath/Genex.cmake

@@ -0,0 +1,29 @@
+enable_language(C)
+
+add_library(A STATIC A.c)
+
+add_executable(buildge main.c)
+target_link_libraries(buildge A)
+set_target_properties(buildge PROPERTIES
+  BUILD_RPATH $<1:/opt/foo/lib>
+  )
+
+add_executable(buildnoge main.c)
+target_link_libraries(buildnoge A)
+set_target_properties(buildnoge PROPERTIES
+  BUILD_RPATH /opt/foo/lib
+  )
+
+add_executable(installge main.c)
+target_link_libraries(installge A)
+set_target_properties(installge PROPERTIES
+  INSTALL_RPATH $<1:/opt/foo/lib>
+  BUILD_WITH_INSTALL_RPATH 1
+  )
+
+add_executable(installnoge main.c)
+target_link_libraries(installnoge A)
+set_target_properties(installnoge PROPERTIES
+  INSTALL_RPATH /opt/foo/lib
+  BUILD_WITH_INSTALL_RPATH 1
+  )

+ 7 - 0
Tests/RunCMake/RuntimePath/GenexCheck.cmake

@@ -0,0 +1,7 @@
+file(GLOB_RECURSE files "${dir}/*")
+
+foreach(file IN LISTS files)
+  if(file MATCHES "/(build|install)(no)?ge$")
+    file(RPATH_CHANGE FILE "${file}" OLD_RPATH "/opt/foo/lib" NEW_RPATH "/opt/bar/lib")
+  endif()
+endforeach()

+ 14 - 20
Tests/RunCMake/RuntimePath/RunCMakeTest.cmake

@@ -1,32 +1,26 @@
 include(RunCMake)
 
 
-function(run_SymlinkImplicit)
+function(run_RuntimePath name)
   # Use a single build tree for a few tests without cleaning.
-  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SymlinkImplicit-build)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
   set(RunCMake_TEST_NO_CLEAN 1)
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
     set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-  run_cmake(SymlinkImplicit)
-  run_cmake_command(SymlinkImplicit-build ${CMAKE_COMMAND} --build . --config Debug)
-  run_cmake_command(SymlinkImplicitCheck
-    ${CMAKE_COMMAND} -Ddir=${RunCMake_TEST_BINARY_DIR} -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
+  run_cmake(${name})
+  run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
 endfunction()
-run_SymlinkImplicit()
 
-function(run_Relative)
-  # Use a single build tree for a few tests without cleaning.
-  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Relative-build)
-  set(RunCMake_TEST_NO_CLEAN 1)
-  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
-  endif()
-  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
-  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-  run_cmake(Relative)
-  run_cmake_command(Relative-build ${CMAKE_COMMAND} --build . --config Debug)
-endfunction()
-run_Relative()
+run_RuntimePath(SymlinkImplicit)
+run_cmake_command(SymlinkImplicitCheck
+  ${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/SymlinkImplicit-build -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
+
+run_RuntimePath(Relative)
+# FIXME: Run RelativeCheck (appears to be broken currently)
+
+run_RuntimePath(Genex)
+run_cmake_command(GenexCheck
+  ${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/Genex-build -P ${RunCMake_SOURCE_DIR}/GenexCheck.cmake)