[clang] [flang] [clang][Driver] Add the ability to specify that RPATH should be added by default (PR #115163)

via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 6 06:30:25 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-driver

@llvm/pr-subscribers-clang

Author: Paul Osmialowski (pawosm-arm)

<details>
<summary>Changes</summary>

The `-frtlib-add-rpath` is very convenient when linking against various runtimes (OpenMP, Fortran, sanitizers), so much so we could argue that this should be a default behavior.

This patch adds the ability to specify (at CMake level) that RPATH should be added by default.

---
Full diff: https://github.com/llvm/llvm-project/pull/115163.diff


14 Files Affected:

- (modified) clang/CMakeLists.txt (+2) 
- (modified) clang/include/clang/Config/config.h.cmake (+3) 
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+4) 
- (modified) clang/test/CMakeLists.txt (+1) 
- (added) clang/test/Driver/arch-specific-libdir-rpath-by-default.c (+105) 
- (modified) clang/test/Driver/arch-specific-libdir-rpath.c (+2) 
- (modified) clang/test/lit.cfg.py (+3) 
- (modified) clang/test/lit.site.cfg.py.in (+1) 
- (modified) flang/test/CMakeLists.txt (+1) 
- (added) flang/test/Driver/arch-specific-libdir-rpath-by-default.f95 (+34) 
- (modified) flang/test/Driver/arch-specific-libdir-rpath.f95 (+2) 
- (modified) flang/test/Driver/linker-flags.f90 (+2-1) 
- (modified) flang/test/lit.cfg.py (+4) 
- (modified) flang/test/lit.site.cfg.py.in (+1) 


``````````diff
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index 27e8095534a65c..fb902cd65a31da 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -216,6 +216,8 @@ endif()
 
 set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
 
+set(ENABLE_LINKER_RPATH_BY_DEFAULT OFF CACHE BOOL "pass -rpath to the linker by default")
+
 set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL
     "enable x86 relax relocations by default")
 
diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake
index 27ed69e21562bf..a7f185d88c68cc 100644
--- a/clang/include/clang/Config/config.h.cmake
+++ b/clang/include/clang/Config/config.h.cmake
@@ -69,6 +69,9 @@
 /* pass --build-id to ld */
 #cmakedefine ENABLE_LINKER_BUILD_ID
 
+/* pass -rpath to the linker by default */
+#cmakedefine ENABLE_LINKER_RPATH_BY_DEFAULT
+
 /* enable x86 relax relocations by default */
 #cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
 
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index ca06fb115dfa11..e62f59f56241cd 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1183,7 +1183,11 @@ void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
 void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
                                  ArgStringList &CmdArgs) {
   if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
+#ifdef ENABLE_LINKER_RPATH_BY_DEFAULT
+                    options::OPT_fno_rtlib_add_rpath, true))
+#else
                     options::OPT_fno_rtlib_add_rpath, false))
+#endif
     return;
 
   SmallVector<std::string> CandidateRPaths(TC.getArchSpecificLibPaths());
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index 5369dc92f69e8a..e439e973ce6f81 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -11,6 +11,7 @@ llvm_canonicalize_cmake_booleans(
   CLANG_SPAWN_CC1
   CLANG_ENABLE_CIR
   ENABLE_BACKTRACES
+  ENABLE_LINKER_RPATH_BY_DEFAULT
   LLVM_BUILD_EXAMPLES
   LLVM_BYE_LINK_INTO_TOOLS
   LLVM_ENABLE_PLUGINS
diff --git a/clang/test/Driver/arch-specific-libdir-rpath-by-default.c b/clang/test/Driver/arch-specific-libdir-rpath-by-default.c
new file mode 100644
index 00000000000000..20c3f2fa560905
--- /dev/null
+++ b/clang/test/Driver/arch-specific-libdir-rpath-by-default.c
@@ -0,0 +1,105 @@
+// Test that the driver adds an arch-specific subdirectory in
+// {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
+//
+// REQUIRES: enable_rpath_by_default
+//
+// Test the default behavior when neither -frtlib-add-rpath nor
+// -fno-rtlib-add-rpath is specified, which is to add -rpath
+// RUN: %clang %s -### --target=x86_64-linux \
+// RUN:     -fsanitize=address -shared-libasan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
+//
+// Test that -rpath is not added under -fno-rtlib-add-rpath even if other
+// conditions are met.
+// RUN: %clang %s -### --target=x86_64-linux \
+// RUN:     -fsanitize=address -shared-libasan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -fno-rtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
+//
+// Test that -rpath is added only under the right circumstance even if
+// -frtlib-add-rpath is specified.
+//
+// Add LIBPATH but no RPATH for -fsanitizer=address w/o -shared-libasan
+// RUN: %clang %s -### --target=x86_64-linux -fsanitize=undefined \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
+//
+// Add LIBPATH but no RPATH for -fsanitizer=address w/o -shared-libasan
+// RUN: %clang %s -### --target=x86_64-linux -fsanitize=undefined \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
+//
+// Add LIBPATH, RPATH for -fsanitize=address -shared-libasan
+// RUN: %clang %s -### --target=x86_64-linux \
+// RUN:     -fsanitize=address -shared-libasan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
+//
+// Add LIBPATH, RPATH for -fsanitize=address -shared-libasan on aarch64
+// RUN: %clang %s -### --target=aarch64-linux \
+// RUN:     -fsanitize=address -shared-libasan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-AARCH64,RPATH-AARCH64 %s
+//
+// Add LIBPATH, RPATH with -fsanitize=address for Android
+// RUN: %clang %s -### --target=x86_64-linux-android -fsanitize=address \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
+//
+// Add LIBPATH, RPATH for OpenMP
+// RUN: %clang %s -### --target=x86_64-linux -fopenmp \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
+//
+// Add LIBPATH but no RPATH for ubsan (or any other sanitizer)
+// RUN: %clang %s -### -fsanitize=undefined --target=x86_64-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
+//
+// Add LIBPATH but no RPATH if no sanitizer or runtime is specified
+// RUN: %clang %s -### --target=x86_64-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
+//
+// Do not add LIBPATH or RPATH if arch-specific subdir doesn't exist
+// RUN: %clang %s -### --target=x86_64-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     -frtlib-add-rpath 2>&1 \
+// RUN:   | FileCheck --check-prefixes=RESDIR,NO-LIBPATH,NO-RPATH %s
+
+// Test that the driver adds an per-target arch-specific subdirectory in
+// {RESOURCE_DIR}/lib/{triple} to the linker search path and to '-rpath'
+//
+// RUN: %clang %s -### 2>&1 --target=x86_64-linux-gnu \
+// RUN:     -fsanitize=address -shared-libasan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -frtlib-add-rpath \
+// RUN:   | FileCheck --check-prefixes=PERTARGET %s
+
+// RESDIR: "-resource-dir" "[[RESDIR:[^"]*]]"
+//
+// LIBPATH-X86_64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}
+// RPATH-X86_64:   "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
+//
+// NO-LIBPATH-X86_64-NOT: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}
+// NO-RPATH-X86_64-NOT:   "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
+//
+// LIBPATH-AARCH64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)aarch64}}
+// RPATH-AARCH64:   "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)aarch64}}"
+//
+// NO-LIBPATH-NOT: "-L{{[^"]*Inputs(/|\\\\)resource_dir}}"
+// NO-RPATH-NOT:   "-rpath" {{.*(/|\\\\)Inputs(/|\\\\)resource_dir}}
+
+// PERTARGET: "-resource-dir" "[[PTRESDIR:[^"]*]]"
+// PERTARGET: -L[[PTRESDIR]]{{(/|\\\\)lib(/|\\\\)x86_64-unknown-linux-gnu}}
+// PERTARGET:   "-rpath" "[[PTRESDIR]]{{(/|\\\\)lib(/|\\\\)x86_64-unknown-linux-gnu}}"
diff --git a/clang/test/Driver/arch-specific-libdir-rpath.c b/clang/test/Driver/arch-specific-libdir-rpath.c
index 1e6bbbc5929ac2..ecedb474d7045c 100644
--- a/clang/test/Driver/arch-specific-libdir-rpath.c
+++ b/clang/test/Driver/arch-specific-libdir-rpath.c
@@ -1,6 +1,8 @@
 // Test that the driver adds an arch-specific subdirectory in
 // {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
 //
+// UNSUPPORTED: enable_rpath_by_default
+//
 // Test the default behavior when neither -frtlib-add-rpath nor
 // -fno-rtlib-add-rpath is specified, which is to skip -rpath
 // RUN: %clang %s -### --target=x86_64-linux \
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index 4d3469aba4bb8d..07068ab1b09d56 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -328,6 +328,9 @@ def calculate_arch_features(arch_string):
 if config.enable_shared:
     config.available_features.add("enable_shared")
 
+if config.enable_rpath_by_default:
+    config.available_features.add("enable_rpath_by_default")
+
 # Add a vendor-specific feature.
 if config.clang_vendor_uti:
     config.available_features.add("clang-vendor=" + config.clang_vendor_uti)
diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in
index 1cbd876ac5bb93..4630ec53b68daa 100644
--- a/clang/test/lit.site.cfg.py.in
+++ b/clang/test/lit.site.cfg.py.in
@@ -30,6 +30,7 @@ config.clang_staticanalyzer_z3 = @LLVM_WITH_Z3@
 config.clang_enable_cir = @CLANG_ENABLE_CIR@
 config.clang_examples = @CLANG_BUILD_EXAMPLES@
 config.enable_shared = @ENABLE_SHARED@
+config.enable_rpath_by_default = @ENABLE_LINKER_RPATH_BY_DEFAULT@
 config.enable_backtrace = @ENABLE_BACKTRACES@
 config.enable_threads = @LLVM_ENABLE_THREADS@
 config.reverse_iteration = @LLVM_ENABLE_REVERSE_ITERATION@
diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt
index cab214c2ef4c8c..2eccfc7d3ca3af 100644
--- a/flang/test/CMakeLists.txt
+++ b/flang/test/CMakeLists.txt
@@ -3,6 +3,7 @@
 add_subdirectory(lib)
 
 llvm_canonicalize_cmake_booleans(
+  ENABLE_LINKER_RPATH_BY_DEFAULT
   FLANG_STANDALONE_BUILD
   LLVM_BUILD_EXAMPLES
   LLVM_BYE_LINK_INTO_TOOLS
diff --git a/flang/test/Driver/arch-specific-libdir-rpath-by-default.f95 b/flang/test/Driver/arch-specific-libdir-rpath-by-default.f95
new file mode 100644
index 00000000000000..3630bd8101b8cc
--- /dev/null
+++ b/flang/test/Driver/arch-specific-libdir-rpath-by-default.f95
@@ -0,0 +1,34 @@
+! REQUIRES: x86-registered-target
+! Test that the driver adds an arch-specific subdirectory in
+! {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
+!
+! REQUIRES: enable_rpath_by_default
+!
+! Test the default behavior when neither -frtlib-add-rpath nor
+! -fno-rtlib-add-rpath is specified, which is to add -rpath
+! RUN: %flang %s -### --target=x86_64-linux \
+! RUN:     -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir 2>&1 \
+! RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
+!
+! Test that -rpath is not added under -fno-rtlib-add-rpath
+! RUN: %flang %s -### --target=x86_64-linux \
+! RUN:     -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir \
+! RUN:     -fno-rtlib-add-rpath 2>&1 \
+! RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
+!
+! Test that -rpath is added
+!
+! Add LIBPATH, RPATH for OpenMP
+!
+! RUN: %flang %s -### --target=x86_64-linux -fopenmp \
+! RUN:     -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir \
+! RUN:     -frtlib-add-rpath 2>&1 \
+! RUN:   | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
+!
+!
+! RESDIR: "-resource-dir" "[[RESDIR:[^"]*]]"
+!
+! LIBPATH-X86_64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}
+! RPATH-X86_64:   "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
+!
+! NO-RPATH-X86_64-NOT:   "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
diff --git a/flang/test/Driver/arch-specific-libdir-rpath.f95 b/flang/test/Driver/arch-specific-libdir-rpath.f95
index 23fb52abfbd574..6e1a8f5212f0b9 100644
--- a/flang/test/Driver/arch-specific-libdir-rpath.f95
+++ b/flang/test/Driver/arch-specific-libdir-rpath.f95
@@ -2,6 +2,8 @@
 ! Test that the driver adds an arch-specific subdirectory in
 ! {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
 !
+! UNSUPPORTED: enable_rpath_by_default
+!
 ! Test the default behavior when neither -frtlib-add-rpath nor
 ! -fno-rtlib-add-rpath is specified, which is to skip -rpath
 ! RUN: %flang %s -### --target=x86_64-linux \
diff --git a/flang/test/Driver/linker-flags.f90 b/flang/test/Driver/linker-flags.f90
index ac9500d7c45cec..c4ee26c5dacab8 100644
--- a/flang/test/Driver/linker-flags.f90
+++ b/flang/test/Driver/linker-flags.f90
@@ -33,7 +33,8 @@
 ! SOLARIS-F128NONE-NOT: FortranFloat128Math
 ! UNIX-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed"
 ! SOLARIS-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "-z" "ignore" "-lquadmath" "-z" "record"
-! UNIX-SAME: "-lFortranRuntime" "-lFortranDecimal" "-lm"
+! UNIX-SAME: "-lFortranRuntime" "-lFortranDecimal"
+! UNIX-SAME: "-lm"
 ! COMPILER-RT: "{{.*}}{{\\|/}}libclang_rt.builtins.a"
 
 ! DARWIN-LABEL:  "{{.*}}ld{{(\.exe)?}}"
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index f43234fb125b7e..5e61b454832363 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -227,3 +227,7 @@
     )
 else:
     config.substitutions.append(("%f128-lib", "NONE"))
+
+# Pass -rpath to the linker by default.
+if config.enable_rpath_by_default:
+    config.available_features.add("enable_rpath_by_default")
diff --git a/flang/test/lit.site.cfg.py.in b/flang/test/lit.site.cfg.py.in
index d1a0ac763cf8a0..d5ee2a670dc7c2 100644
--- a/flang/test/lit.site.cfg.py.in
+++ b/flang/test/lit.site.cfg.py.in
@@ -26,6 +26,7 @@ config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")
 config.targets_to_build = "@TARGETS_TO_BUILD@"
 config.default_sysroot = "@DEFAULT_SYSROOT@"
 config.have_openmp_rtl = ("@LLVM_TOOL_OPENMP_BUILD@" == "TRUE") or ("openmp" in "@LLVM_ENABLE_RUNTIMES@".lower().split(";"))
+config.enable_rpath_by_default = @ENABLE_LINKER_RPATH_BY_DEFAULT@
 if "openmp" in "@LLVM_ENABLE_RUNTIMES@".lower().split(";"):
     config.openmp_module_dir = "@CMAKE_BINARY_DIR@/runtimes/runtimes-bins/openmp/runtime/src"
 else:

``````````

</details>


https://github.com/llvm/llvm-project/pull/115163


More information about the cfe-commits mailing list