[clang] [flang] [clang][Driver] Add the ability to specify that RPATH should be added by default (PR #115163)
Paul Osmialowski via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 6 09:05:02 PST 2024
https://github.com/pawosm-arm updated https://github.com/llvm/llvm-project/pull/115163
>From 2c4b767437c55245391eb15da94a97b34a63f834 Mon Sep 17 00:00:00 2001
From: Paul Osmialowski <pawel.osmialowski at arm.com>
Date: Tue, 5 Nov 2024 16:38:22 +0000
Subject: [PATCH] [clang][Driver] Add the ability to specify that RPATH should
be added by default
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.
---
clang/CMakeLists.txt | 2 +
clang/include/clang/Config/config.h.cmake | 3 +
clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 +
clang/test/CMakeLists.txt | 1 +
.../arch-specific-libdir-rpath-by-default.c | 105 ++++++++++++++++++
.../test/Driver/arch-specific-libdir-rpath.c | 2 +
clang/test/lit.cfg.py | 3 +
clang/test/lit.site.cfg.py.in | 1 +
flang/test/CMakeLists.txt | 1 +
.../arch-specific-libdir-rpath-by-default.f95 | 40 +++++++
.../Driver/arch-specific-libdir-rpath.f95 | 3 +-
flang/test/Driver/linker-flags.f90 | 3 +-
flang/test/lit.cfg.py | 4 +
flang/test/lit.site.cfg.py.in | 1 +
14 files changed, 171 insertions(+), 2 deletions(-)
create mode 100644 clang/test/Driver/arch-specific-libdir-rpath-by-default.c
create mode 100644 flang/test/Driver/arch-specific-libdir-rpath-by-default.f95
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..a347fa940c6c64
--- /dev/null
+++ b/flang/test/Driver/arch-specific-libdir-rpath-by-default.f95
@@ -0,0 +1,40 @@
+! 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
+!
+! RUN: %flang %s -### --target=x86_64-linux \
+! 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
+!
+! 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..0d33dc18190fdb 100644
--- a/flang/test/Driver/arch-specific-libdir-rpath.f95
+++ b/flang/test/Driver/arch-specific-libdir-rpath.f95
@@ -1,7 +1,8 @@
-! 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'
!
+! 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:
More information about the cfe-commits
mailing list