Skip to content

Commit 2c4b767

Browse files
committed
[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.
1 parent e3a0775 commit 2c4b767

File tree

14 files changed

+171
-2
lines changed

14 files changed

+171
-2
lines changed

clang/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ endif()
216216

217217
set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
218218

219+
set(ENABLE_LINKER_RPATH_BY_DEFAULT OFF CACHE BOOL "pass -rpath to the linker by default")
220+
219221
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL
220222
"enable x86 relax relocations by default")
221223

clang/include/clang/Config/config.h.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969
/* pass --build-id to ld */
7070
#cmakedefine ENABLE_LINKER_BUILD_ID
7171

72+
/* pass -rpath to the linker by default */
73+
#cmakedefine ENABLE_LINKER_RPATH_BY_DEFAULT
74+
7275
/* enable x86 relax relocations by default */
7376
#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
7477

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,11 @@ void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
11831183
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
11841184
ArgStringList &CmdArgs) {
11851185
if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
1186+
#ifdef ENABLE_LINKER_RPATH_BY_DEFAULT
1187+
options::OPT_fno_rtlib_add_rpath, true))
1188+
#else
11861189
options::OPT_fno_rtlib_add_rpath, false))
1190+
#endif
11871191
return;
11881192

11891193
SmallVector<std::string> CandidateRPaths(TC.getArchSpecificLibPaths());

clang/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ llvm_canonicalize_cmake_booleans(
1111
CLANG_SPAWN_CC1
1212
CLANG_ENABLE_CIR
1313
ENABLE_BACKTRACES
14+
ENABLE_LINKER_RPATH_BY_DEFAULT
1415
LLVM_BUILD_EXAMPLES
1516
LLVM_BYE_LINK_INTO_TOOLS
1617
LLVM_ENABLE_PLUGINS
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Test that the driver adds an arch-specific subdirectory in
2+
// {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
3+
//
4+
// REQUIRES: enable_rpath_by_default
5+
//
6+
// Test the default behavior when neither -frtlib-add-rpath nor
7+
// -fno-rtlib-add-rpath is specified, which is to add -rpath
8+
// RUN: %clang %s -### --target=x86_64-linux \
9+
// RUN: -fsanitize=address -shared-libasan \
10+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
11+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
12+
//
13+
// Test that -rpath is not added under -fno-rtlib-add-rpath even if other
14+
// conditions are met.
15+
// RUN: %clang %s -### --target=x86_64-linux \
16+
// RUN: -fsanitize=address -shared-libasan \
17+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
18+
// RUN: -fno-rtlib-add-rpath 2>&1 \
19+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
20+
//
21+
// Test that -rpath is added only under the right circumstance even if
22+
// -frtlib-add-rpath is specified.
23+
//
24+
// Add LIBPATH but no RPATH for -fsanitizer=address w/o -shared-libasan
25+
// RUN: %clang %s -### --target=x86_64-linux -fsanitize=undefined \
26+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
27+
// RUN: -frtlib-add-rpath 2>&1 \
28+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
29+
//
30+
// Add LIBPATH but no RPATH for -fsanitizer=address w/o -shared-libasan
31+
// RUN: %clang %s -### --target=x86_64-linux -fsanitize=undefined \
32+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
33+
// RUN: -frtlib-add-rpath 2>&1 \
34+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
35+
//
36+
// Add LIBPATH, RPATH for -fsanitize=address -shared-libasan
37+
// RUN: %clang %s -### --target=x86_64-linux \
38+
// RUN: -fsanitize=address -shared-libasan \
39+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
40+
// RUN: -frtlib-add-rpath 2>&1 \
41+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
42+
//
43+
// Add LIBPATH, RPATH for -fsanitize=address -shared-libasan on aarch64
44+
// RUN: %clang %s -### --target=aarch64-linux \
45+
// RUN: -fsanitize=address -shared-libasan \
46+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
47+
// RUN: -frtlib-add-rpath 2>&1 \
48+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-AARCH64,RPATH-AARCH64 %s
49+
//
50+
// Add LIBPATH, RPATH with -fsanitize=address for Android
51+
// RUN: %clang %s -### --target=x86_64-linux-android -fsanitize=address \
52+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
53+
// RUN: -frtlib-add-rpath 2>&1 \
54+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
55+
//
56+
// Add LIBPATH, RPATH for OpenMP
57+
// RUN: %clang %s -### --target=x86_64-linux -fopenmp \
58+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
59+
// RUN: -frtlib-add-rpath 2>&1 \
60+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
61+
//
62+
// Add LIBPATH but no RPATH for ubsan (or any other sanitizer)
63+
// RUN: %clang %s -### -fsanitize=undefined --target=x86_64-linux \
64+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
65+
// RUN: -frtlib-add-rpath 2>&1 \
66+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
67+
//
68+
// Add LIBPATH but no RPATH if no sanitizer or runtime is specified
69+
// RUN: %clang %s -### --target=x86_64-linux \
70+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
71+
// RUN: -frtlib-add-rpath 2>&1 \
72+
// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
73+
//
74+
// Do not add LIBPATH or RPATH if arch-specific subdir doesn't exist
75+
// RUN: %clang %s -### --target=x86_64-linux \
76+
// RUN: -resource-dir=%S/Inputs/resource_dir \
77+
// RUN: -frtlib-add-rpath 2>&1 \
78+
// RUN: | FileCheck --check-prefixes=RESDIR,NO-LIBPATH,NO-RPATH %s
79+
80+
// Test that the driver adds an per-target arch-specific subdirectory in
81+
// {RESOURCE_DIR}/lib/{triple} to the linker search path and to '-rpath'
82+
//
83+
// RUN: %clang %s -### 2>&1 --target=x86_64-linux-gnu \
84+
// RUN: -fsanitize=address -shared-libasan \
85+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
86+
// RUN: -frtlib-add-rpath \
87+
// RUN: | FileCheck --check-prefixes=PERTARGET %s
88+
89+
// RESDIR: "-resource-dir" "[[RESDIR:[^"]*]]"
90+
//
91+
// LIBPATH-X86_64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}
92+
// RPATH-X86_64: "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
93+
//
94+
// NO-LIBPATH-X86_64-NOT: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}
95+
// NO-RPATH-X86_64-NOT: "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
96+
//
97+
// LIBPATH-AARCH64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)aarch64}}
98+
// RPATH-AARCH64: "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)aarch64}}"
99+
//
100+
// NO-LIBPATH-NOT: "-L{{[^"]*Inputs(/|\\\\)resource_dir}}"
101+
// NO-RPATH-NOT: "-rpath" {{.*(/|\\\\)Inputs(/|\\\\)resource_dir}}
102+
103+
// PERTARGET: "-resource-dir" "[[PTRESDIR:[^"]*]]"
104+
// PERTARGET: -L[[PTRESDIR]]{{(/|\\\\)lib(/|\\\\)x86_64-unknown-linux-gnu}}
105+
// PERTARGET: "-rpath" "[[PTRESDIR]]{{(/|\\\\)lib(/|\\\\)x86_64-unknown-linux-gnu}}"

clang/test/Driver/arch-specific-libdir-rpath.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Test that the driver adds an arch-specific subdirectory in
22
// {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
33
//
4+
// UNSUPPORTED: enable_rpath_by_default
5+
//
46
// Test the default behavior when neither -frtlib-add-rpath nor
57
// -fno-rtlib-add-rpath is specified, which is to skip -rpath
68
// RUN: %clang %s -### --target=x86_64-linux \

clang/test/lit.cfg.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ def calculate_arch_features(arch_string):
328328
if config.enable_shared:
329329
config.available_features.add("enable_shared")
330330

331+
if config.enable_rpath_by_default:
332+
config.available_features.add("enable_rpath_by_default")
333+
331334
# Add a vendor-specific feature.
332335
if config.clang_vendor_uti:
333336
config.available_features.add("clang-vendor=" + config.clang_vendor_uti)

clang/test/lit.site.cfg.py.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ config.clang_staticanalyzer_z3 = @LLVM_WITH_Z3@
3030
config.clang_enable_cir = @CLANG_ENABLE_CIR@
3131
config.clang_examples = @CLANG_BUILD_EXAMPLES@
3232
config.enable_shared = @ENABLE_SHARED@
33+
config.enable_rpath_by_default = @ENABLE_LINKER_RPATH_BY_DEFAULT@
3334
config.enable_backtrace = @ENABLE_BACKTRACES@
3435
config.enable_threads = @LLVM_ENABLE_THREADS@
3536
config.reverse_iteration = @LLVM_ENABLE_REVERSE_ITERATION@

flang/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
add_subdirectory(lib)
44

55
llvm_canonicalize_cmake_booleans(
6+
ENABLE_LINKER_RPATH_BY_DEFAULT
67
FLANG_STANDALONE_BUILD
78
LLVM_BUILD_EXAMPLES
89
LLVM_BYE_LINK_INTO_TOOLS
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
! Test that the driver adds an arch-specific subdirectory in
2+
! {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath'
3+
!
4+
! REQUIRES: enable_rpath_by_default
5+
!
6+
! Test the default behavior when neither -frtlib-add-rpath nor
7+
! -fno-rtlib-add-rpath is specified, which is to add -rpath
8+
! RUN: %flang %s -### --target=x86_64-linux \
9+
! RUN: -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir 2>&1 \
10+
! RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
11+
!
12+
! Test that -rpath is not added under -fno-rtlib-add-rpath
13+
! RUN: %flang %s -### --target=x86_64-linux \
14+
! RUN: -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir \
15+
! RUN: -fno-rtlib-add-rpath 2>&1 \
16+
! RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH-X86_64 %s
17+
!
18+
! Test that -rpath is added
19+
!
20+
! Add LIBPATH, RPATH
21+
!
22+
! RUN: %flang %s -### --target=x86_64-linux \
23+
! RUN: -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir \
24+
! RUN: -frtlib-add-rpath 2>&1 \
25+
! RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
26+
!
27+
! Add LIBPATH, RPATH for OpenMP
28+
!
29+
! RUN: %flang %s -### --target=x86_64-linux -fopenmp \
30+
! RUN: -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir \
31+
! RUN: -frtlib-add-rpath 2>&1 \
32+
! RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s
33+
!
34+
!
35+
! RESDIR: "-resource-dir" "[[RESDIR:[^"]*]]"
36+
!
37+
! LIBPATH-X86_64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}
38+
! RPATH-X86_64: "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"
39+
!
40+
! NO-RPATH-X86_64-NOT: "-rpath" "[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}}"

0 commit comments

Comments
 (0)