makeRPath allow multiple root directories

Allows handling of complex situations like a package
build where some libraries are in a staging area,
but will be copied to the same final location.

eg.

LINKER_ORIGIN_ROOT=/usr/lib/epics:/build/mymodule

Where build TOP is /build/mymodule
This commit is contained in:
Michael Davidsaver
2019-06-24 15:41:48 -07:00
parent ea1b208c33
commit 784d619bde
2 changed files with 50 additions and 14 deletions
+3 -2
View File
@@ -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
+47 -12
View File
@@ -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))