From 829b0c4cbabbe5056b79a8a1ec4cd9e9d928a5fb Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Thu, 20 Dec 2018 09:00:38 +0000 Subject: [PATCH] Driver: Provide a spec to insert rpaths for compiler lib dirs. This provides a spec to insert "-rpath DDD" for each DDD corresponding to a compiler startfile directory. This allows a target to use @rpath as the install path for libraries, and have the compiler provide the necessary rpath to handle this. Embed real paths, not relative ones. We embed a runpath for every path in which libraries might be found. This change ensures that we embed the actual real path and not a relative one from the compiler's version-specific directory. e.g. /opt/distro/gcc-11-3Dr0/lib instead of: /opt/distro/gcc-11-3Dr0/lib/gcc/x86_64-apple-darwin19/11.3.0/../../.. This ensures that if we install, for example, 11.4.0 (and delete the 11.3.0 installation) exes built by 11.3 would continue to function (providing, of course that 11.4 does not bump any SO names). gcc/ChangeLog: * gcc.cc (RUNPATH_OPTION): New. (do_spec_1): Provide '%P' as a spec to insert rpaths for each compiler startfile path. --- gcc/gcc.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/gcc/gcc.cc b/gcc/gcc.cc index c6e600fa0d3..884284e66b4 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -580,6 +580,7 @@ or with constant text in a single argument. %l process LINK_SPEC as a spec. %L process LIB_SPEC as a spec. %M Output multilib_os_dir. + %P Output a RUNPATH_OPTION for each directory in startfile_prefixes. %G process LIBGCC_SPEC as a spec. %R Output the concatenation of target_system_root and target_sysroot_suffix. @@ -1183,6 +1184,10 @@ proper position among the other output files. */ # define SYSROOT_HEADERS_SUFFIX_SPEC "" #endif +#ifndef RUNPATH_OPTION +# define RUNPATH_OPTION "-rpath" +#endif + static const char *asm_debug = ASM_DEBUG_SPEC; static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC; static const char *cpp_spec = CPP_SPEC; @@ -5929,6 +5934,7 @@ struct spec_path_info { size_t append_len; bool omit_relative; bool separate_options; + bool realpaths; }; static void * @@ -5938,6 +5944,16 @@ spec_path (char *path, void *data) size_t len = 0; char save = 0; + /* The path must exist; we want to resolve it to the realpath so that this + can be embedded as a runpath. */ + if (info->realpaths) + path = lrealpath (path); + + /* However, if we failed to resolve it - perhaps because there was a bogus + -B option on the command line, then punt on this entry. */ + if (!path) + return NULL; + if (info->omit_relative && !IS_ABSOLUTE_PATH (path)) return NULL; @@ -6169,6 +6185,22 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) info.omit_relative = false; #endif info.separate_options = false; + info.realpaths = false; + + for_each_path (&startfile_prefixes, true, 0, spec_path, &info); + } + break; + + case 'P': + { + struct spec_path_info info; + + info.option = RUNPATH_OPTION; + info.append_len = 0; + info.omit_relative = false; + info.separate_options = true; + /* We want to embed the actual paths that have the libraries. */ + info.realpaths = true; for_each_path (&startfile_prefixes, true, 0, spec_path, &info); } @@ -6495,6 +6527,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) info.append_len = strlen (info.append); info.omit_relative = false; info.separate_options = true; + info.realpaths = false; for_each_path (&include_prefixes, false, info.append_len, spec_path, &info);