From: Gabe Black Date: Thu, 21 Feb 2019 01:43:15 +0000 (-0800) Subject: scons: Add a convenience method to set RPATH for local libraries. X-Git-Tag: v19.0.0.0~1113 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0a7372633a9542cf5ed6709ac87f1adfe9e87171;p=gem5.git scons: Add a convenience method to set RPATH for local libraries. When linking in a dynamic library which is in the gem5 build directory, it's useful to set RPATH so that you don't have to set LD_LIBRARY_PATH when you run gem5 so that the dynamic linker can find it. Since it's tricky and not entirely obvious how to set up those paths correctly, this change adds a small convenience function which does that for you. It also handles situations where the same dynamic library may be linked into different binaries in different directories which each need a different relative RPATH. It does that by letting the environment for each binary set a construction variable which says how to get from that particular binary back to the build directory. This helper method then sets RPATH to start at $ORIGIN (the binary), to follow that relative path to the variant build directory, and then the per-library but not per-binary path to the library's directory. This change also adds the -z origin linker flag which makes the linker handle $ORIGIN properly. Change-Id: I45f4d72cd14396a73e0b963cea6a39d9bfb7f984 Reviewed-on: https://gem5-review.googlesource.com/c/16566 Reviewed-by: Andreas Sandberg Maintainer: Gabe Black --- diff --git a/SConstruct b/SConstruct index 5c8f64956..026327c2c 100755 --- a/SConstruct +++ b/SConstruct @@ -1072,6 +1072,27 @@ partial_shared_builder = Builder(action=SCons.Defaults.ShLinkAction, main.Append(BUILDERS = { 'PartialShared' : partial_shared_builder, 'PartialStatic' : partial_static_builder }) +def add_local_rpath(env, *targets): + '''Set up an RPATH for a library which lives in the build directory. + + The construction environment variable BIN_RPATH_PREFIX should be set to + the relative path of the build directory starting from the location of the + binary.''' + for target in targets: + target = env.Entry(target) + if not target.isdir(): + target = target.dir + relpath = os.path.relpath(target.abspath, env['BUILDDIR']) + components = [ + '\\$$ORIGIN', + '${BIN_RPATH_PREFIX}', + relpath + ] + env.Append(RPATH=[env.Literal(os.path.join(*components))]) + +main.Append(LINKFLAGS=Split('-z origin')) +main.AddMethod(add_local_rpath, 'AddLocalRPATH') + # builds in ext are shared across all configs in the build root. ext_dir = abspath(joinpath(str(main.root), 'ext')) ext_build_dirs = [] diff --git a/src/SConscript b/src/SConscript index 81b6cd3f1..ef7e670ab 100644 --- a/src/SConscript +++ b/src/SConscript @@ -449,6 +449,10 @@ class Executable(object): if objs is None: objs = self.srcs_to_objs(env, self.sources) + env = env.Clone() + env['BIN_RPATH_PREFIX'] = os.path.relpath( + env['BUILDDIR'], self.path(env).dir.abspath) + if env['STRIP_EXES']: stripped = self.path(env) unstripped = env.File(str(stripped) + '.unstripped')