diff --git a/configure/CONFIG_BASE b/configure/CONFIG_BASE index 137ce0098..32349ebd5 100644 --- a/configure/CONFIG_BASE +++ b/configure/CONFIG_BASE @@ -44,6 +44,8 @@ FULLPATHNAME = $(PERL) $(TOOLS)/fullPathName.pl TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl GENVERSIONHEADER = $(PERL) $(TOOLS)/genVersionHeader.pl $(QUIET_FLAG) $(QUESTION_FLAG) +MAKERPATH = $(PYTHON) $(TOOLS)/makeRPath.py + #--------------------------------------------------------------- # tools for installing libraries and products INSTALL = $(PERL) $(TOOLS)/installEpics.pl $(QUIET_FLAG) diff --git a/configure/CONFIG_COMMON b/configure/CONFIG_COMMON index eef4d6745..d7766e50a 100644 --- a/configure/CONFIG_COMMON +++ b/configure/CONFIG_COMMON @@ -38,6 +38,8 @@ BUILD_ARCHS = $(EPICS_HOST_ARCH) $(CROSS1) $(CROSS2) # otherwise override this in os/CONFIG_SITE..Common PERL = perl -CSD +PYTHON = python + #------------------------------------------------------- # Check configure/RELEASE file for consistency CHECK_RELEASE_YES = checkRelease diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index b657f5b65..49f82c7a8 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -169,10 +169,17 @@ EPICS_SITE_VERSION = GCC_PIPE = NO # Set RPATH when linking executables and libraries. -# Must be either YES or NO. If you set this to NO you must also provide a +# Must be either YES, NO, or ORIGIN. If you set this to NO you must also provide a # way for Base executables to find their shared libraries when they are # run at build-time, e.g. set the LD_LIBRARY_PATH environment variable. +# ORIGIN is Linux specific. 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. +# Linking to libraries outside of this root will be absolute. +LINKER_ORIGIN_ROOT = $(INSTALL_LOCATION) + # Overrides for the settings above may appear in a CONFIG_SITE.local file -include $(CONFIG)/CONFIG_SITE.local diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index 21a838790..f2f4d8873 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -194,6 +194,13 @@ ifeq ($(EPICS_HOST_ARCH),$(T_A)) $(info Warning: RELEASE file consistency checks have been disabled) endif +# $(FINAL_DIR) signals eventual install locations to makeRPath script +$(TESTPRODNAME): FINAL_DIR=. +$(PRODNAME): FINAL_DIR=$(INSTALL_BIN) +$(TESTSHRLIBNAME): FINAL_DIR=. +$(SHRLIBNAME): FINAL_DIR=$(INSTALL_SHRLIB) +$(LOADABLE_SHRLIBNAME): FINAL_DIR=$(INSTALL_SHRLIB) + #--------------------------------------------------------------- # The order of the following rules is # VERY IMPORTANT !!!! diff --git a/configure/os/CONFIG.Common.linuxCommon b/configure/os/CONFIG.Common.linuxCommon index 965de09b8..e8e9ab3ca 100644 --- a/configure/os/CONFIG.Common.linuxCommon +++ b/configure/os/CONFIG.Common.linuxCommon @@ -25,11 +25,13 @@ STATIC_LDLIBS_YES= -Wl,-Bdynamic # Set runtime path for shared libraries if USE_RPATH=YES and STATIC_BUILD=NO SHRLIBDIR_RPATH_LDFLAGS_YES_NO = $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%) +SHRLIBDIR_RPATH_LDFLAGS_ORIGIN_NO = $(shell $(MAKERPATH) -O '\$$ORIGIN' -F $(FINAL_DIR) -R $(LINKER_ORIGIN_ROOT) $(SHRLIB_DEPLIB_DIRS)) SHRLIBDIR_LDFLAGS += \ $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) # Set runtime path for products if USE_RPATH=YES and STATIC_BUILD=NO PRODDIR_RPATH_LDFLAGS_YES_NO = $(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%) +PRODDIR_RPATH_LDFLAGS_ORIGIN_NO = $(shell $(MAKERPATH) -O '\$$ORIGIN' -F $(FINAL_DIR) -R $(LINKER_ORIGIN_ROOT) $(PROD_DEPLIB_DIRS)) PRODDIR_LDFLAGS += \ $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) diff --git a/src/tools/Makefile b/src/tools/Makefile index 39497a417..8c4f25adc 100644 --- a/src/tools/Makefile +++ b/src/tools/Makefile @@ -39,6 +39,8 @@ PERL_SCRIPTS += tap-to-junit-xml.pl PERL_SCRIPTS += useManifestTool.pl PERL_SCRIPTS += genVersionHeader.pl +PERL_SCRIPTS += makeRPath.py + HTMLS = style.css HTMLS += EPICS/Getopts.html HTMLS += EPICS/Path.html diff --git a/src/tools/makeRPath.py b/src/tools/makeRPath.py new file mode 100644 index 000000000..edad80085 --- /dev/null +++ b/src/tools/makeRPath.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import sys +import os + +from argparse import ArgumentParser + +if os.environ.get('EPICS_DEBUG_RPATH','')=='YES': + sys.stderr.write('%s'%sys.argv) + +P = ArgumentParser() +P.add_argument('-F','--final',default=os.getcwd(), help='Final install location for ELF file') +P.add_argument('-R','--root',default='/') +P.add_argument('-O', '--origin', default='$ORIGIN') +P.add_argument('path', nargs='*') +args = P.parse_args() + +fdir = os.path.abspath(args.final) + +output = [] +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: + path = os.path.relpath(path, fdir) + + output.append('-Wl,-rpath,'+os.path.join(args.origin, path)) + +print(' '.join(output))