Skip to content

Commit

Permalink
[clang][Driver] Add the ability to specify that RPATH should be added…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
pawosm-arm committed Nov 6, 2024
1 parent e3a0775 commit 6a63fbe
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 1 deletion.
2 changes: 2 additions & 0 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Config/config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
1 change: 1 addition & 0 deletions clang/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
105 changes: 105 additions & 0 deletions clang/test/Driver/arch-specific-libdir-rpath-by-default.c
Original file line number Diff line number Diff line change
@@ -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}}"
2 changes: 2 additions & 0 deletions clang/test/Driver/arch-specific-libdir-rpath.c
Original file line number Diff line number Diff line change
@@ -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 \
Expand Down
3 changes: 3 additions & 0 deletions clang/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions clang/test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@
Expand Down
1 change: 1 addition & 0 deletions flang/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions flang/test/Driver/arch-specific-libdir-rpath-by-default.f95
Original file line number Diff line number Diff line change
@@ -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}}"
2 changes: 2 additions & 0 deletions flang/test/Driver/arch-specific-libdir-rpath.f95
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
3 changes: 2 additions & 1 deletion flang/test/Driver/linker-flags.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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)?}}"
Expand Down
4 changes: 4 additions & 0 deletions flang/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
1 change: 1 addition & 0 deletions flang/test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 6a63fbe

Please sign in to comment.