diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index a39911783..c46703f84 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -176,9 +176,10 @@ GCC_PIPE = NO LINKER_USE_RPATH = YES # Only used when LINKER_USE_RPATH=ORIGIN -# The build time root of the relocatable tree. -# Linking to libraries under this root directory will be relative. +# The build time root(s) of the relocatable tree (separate multiple w/ ':'). +# Linking to libraries under any root directory will be relative. # Linking to libraries outside of this root will be absolute. +# All root directories are considered to be the same. LINKER_ORIGIN_ROOT = $(INSTALL_LOCATION) # Overrides for the settings above may appear in a CONFIG_SITE.local file diff --git a/src/tools/makeRPath.py b/src/tools/makeRPath.py index eeda8ab55..000b8b450 100644 --- a/src/tools/makeRPath.py +++ b/src/tools/makeRPath.py @@ -4,6 +4,7 @@ from __future__ import print_function import sys import os +from collections import OrderedDict # used as OrderedSet from argparse import ArgumentParser @@ -20,26 +21,60 @@ eg. A library to be placed in /build/lib and linked against libraries in which prints "-Wl,-rpath,$ORIGIN/. -Wl,-rpath,$ORIGIN/../module/lib -Wl,-rpath,/other/lib" ''') P.add_argument('-F','--final',default=os.getcwd(), help='Final install location for ELF file') -P.add_argument('-R','--root',default='/', help='Root of relocatable tree.') +P.add_argument('-R','--root',default='', help='Root(s) of relocatable tree. Separate with :') P.add_argument('-O', '--origin', default='$ORIGIN') P.add_argument('path', nargs='*') args = P.parse_args() -fdir = os.path.abspath(args.final) +# eg. +# target to be installed as: /build/bin/blah +# +# post-install will copy as: /install/bin/blah +# +# Need to link against: +# /install/lib/libA.so +# /build/lib/libB.so +# /other/lib/libC.so +# +# Want final result to be: +# -rpath $ORIGIN/../lib -rpath /other/lib \ +# -rpath-link /build/lib -rpath-link /install/lib -output = [] +fdir = os.path.abspath(args.final) +roots = [os.path.abspath(root) for root in args.root.split(':') if len(root)] + +# find the root which contains the final location +froot = None +for root in roots: + frel = os.path.relpath(fdir, root) + if not frel.startswith('..'): + # final dir is under this root + froot = root + break + +if froot is None: + sys.stderr.write("makeRPath: Final location %s\nNot under any of: %s\n"%(fdir, roots)) + sys.exit(1) + +output = OrderedDict() for path in args.path: path = os.path.abspath(path) - if args.root and os.path.relpath(path, args.root).startswith('../'): - pass # absolute rpath - else: - # some older binutils don't seem to handle $ORIGIN correctly - # when locating dependencies of libraries. So also provide - # the absolute path for internal use by 'ld' only. - output.append('-Wl,-rpath-link,'+path) - path = os.path.relpath(path, fdir) + for root in roots: + rrel = os.path.relpath(path, root) + if not rrel.startswith('..'): + # path is under this root - output.append('-Wl,-rpath,'+os.path.join(args.origin, path)) + # some older binutils don't seem to handle $ORIGIN correctly + # when locating dependencies of libraries. So also provide + # the absolute path for internal use by 'ld' only. + output['-Wl,-rpath-link,'+path] = True + + # frel is final location relative to enclosing root + # rrel is target location relative to enclosing root + path = os.path.relpath(rrel, frel) + break + + output['-Wl,-rpath,'+os.path.join(args.origin, path)] = True print(' '.join(output))