Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use absolute paths to lib and lib64 icw $ORIGIN for the RPATH #2358

Merged
merged 10 commits into from
Dec 10, 2017

Conversation

jdonners
Copy link

Add %installdir/lib, %installdir/lib64 and $ORIGIN to RPATH. This works much better with shared libraries in non-standard locations, esp. python packages. See the discussion in #2076. This patch has been tested for building Tensorflow+python (using foss-2016b) and VTK (for intel-2016b) from scratch. Works without hacks in the easyconfig.

John Donners added 4 commits November 30, 2017 15:32
… $ORIGIN to RPATH. This works much better with shared libraries in non-standard locations, esp. python packages
…ldir is defined. Shuffled tests to match the changed rpath mechanism.
@easybuilders easybuilders deleted a comment from boegelbot Dec 1, 2017
@easybuilders easybuilders deleted a comment from boegelbot Dec 1, 2017
@boegel boegel added this to the 3.5.0 milestone Dec 1, 2017
# prepare toolchain: load toolchain module and dependencies, set up build environment
self.toolchain.prepare(self.cfg['onlytcmod'], silent=self.silent, rpath_filter_dirs=self.rpath_filter_dirs)
self.toolchain.prepare(self.cfg['onlytcmod'], silent=self.silent, rpath_filter_dirs=self.rpath_filter_dirs, rpath_include_dirs=self.rpath_include_dirs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (max 120 chars), so wrap it, like so:

self.toolchain.prepare(self.cfg['onlytcmod'], silent=self.silent, rpath_filter_dirs=self.rpath_filter_dirs,
                       rpath_include_dirs=self.rpath_include_dirs)

cmd_args_rpath = []
if rpath_include:
for path in rpath_include:
cmd_args_rpath.append(flag_prefix + '-rpath=%s' % path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be collapsed to a single line, since we're sure rpath_include is a list (possibly empty, but that's fine):

cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include]

if not rpath_include:
rpath_include = []
else:
rpath_include = rpath_include.split(',')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

positive logic is easier to follow (and maybe worth a comment to clarify possible None value):

if rpath_include:
    rpath_include = rpath_include.split(',')
else:  # take into account that rpath_include may be None
    rpath_include = []

rpath_include = ','.join(['%s' % d for d in rpath_include_dirs or []])
self.log.debug("Combined RPATH includes: '%s'", rpath_include)


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid duplicate blank line, just one is enough

for path in rpath_include:
cmd_args_rpath.append(flag_prefix + '-rpath=%s' % path)


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid duplicate blank line, just one is enough

@@ -796,6 +797,12 @@ def prepare_rpath_wrappers(self, rpath_filter_dirs=None):
rpath_filter = ','.join(rpath_filter + ['%s.*' % d for d in rpath_filter_dirs or []])
self.log.debug("Combined RPATH filter: '%s'", rpath_filter)

# figure out list of patterns to use in rpath include
# rpath_include = build_option('rpath_include')
rpath_include = ','.join(['%s' % d for d in rpath_include_dirs or []])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'%s' % d doesn't do much, since the directories are already strings, no?

So this is equivalent with:

rpath_include = ','.join(rpath_include_dirs or [])

@@ -824,6 +831,7 @@ def prepare_rpath_wrappers(self, rpath_filter_dirs=None):
'orig_cmd': orig_cmd,
'python': sys.executable,
'rpath_args_py': rpath_args_py,
'rpath_include': rpath_include,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep this sorted alphabetically (i comes after f ;-)).

@@ -796,6 +797,12 @@ def prepare_rpath_wrappers(self, rpath_filter_dirs=None):
rpath_filter = ','.join(rpath_filter + ['%s.*' % d for d in rpath_filter_dirs or []])
self.log.debug("Combined RPATH filter: '%s'", rpath_filter)

# figure out list of patterns to use in rpath include
# rpath_include = build_option('rpath_include')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this commented out line?

self.assertEqual(ec, 0)
expected = '\n'.join([
"CMD_ARGS=('foo.o')",
"RPATH_ARGS='--disable-new-dtags -rpath=$ORIGIN/../lib -rpath=$ORIGIN/../lib64'",
"RPATH_ARGS='--disable-new-dtags -rpath=%s/lib -rpath=%s/lib64 -rpath=$ORIGIN'" % (self.test_prefix, self.test_prefix),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"RPATH_ARGS='--disable-new-dtags -rpath=%(p)s/lib -rpath=%(p)s/lib64 -rpath=$ORIGIN'" % {'p': self.test_prefix},

@@ -1066,61 +1066,66 @@ def test_rpath_args_script(self):
script = find_eb_script('rpath_args.py')

# simplest possible compiler command
out, ec = run_cmd("%s gcc '' -c foo.c" % script, simple=False)
out, ec = run_cmd("%s gcc '' '%s/lib,%s/lib64,$ORIGIN' -c foo.c" % (script, self.test_prefix, self.test_prefix), simple=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Construct the argument separately, since you're using it in multiple tests.
This also avoids making the line too long.

rpath_inc = '%(prefix)s/lib,%(prefix)s/lib64,$ORIGIN' % {'prefix': self.test_prefix}
out, ec = run_cmd("%s gcc '' '%s' -c foo.c" % (script, rpath_inc), simple=False)

And then reuse rpath_inc below too.

@easybuilders easybuilders deleted a comment from boegelbot Dec 7, 2017
# see also https://linux.die.net/man/8/ld-linux;
self.rpath_include_dirs.append(self.installdir+'/lib')
self.rpath_include_dirs.append(self.installdir+'/lib64')
self.rpath_include_dirs.append('$ORIGIN')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdonners Shouldn't we also retain $ORIGIN/../lib and $ORIGIN/../lib64 in here? That's not necessarily the same as <installdir>/lib and <installdir>/lib64, is it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boegel indeed they're not necessarily the same. Conservatively, I thought it's better to add fewer paths to the RPATH. I'd expect that packages that install shared objects in non-standard locations, also somehow make these directories findable in some wrapper scripts. There's no guarantee that that is indeed the case. On the other side, it still is an experimental feature..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, I'd stick to also included $ORIGIIN/../lib and $ORIGIN/../lib64.

It indeed makes sense to limit the amount of paths we inject, but 3 or 5 isn't going to make a big difference I think.

The order may be important though (w.r.t. speeding up the loader): we should probably list the most common locations first?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdonners Fixed in sara-nl#1

@boegel
Copy link
Member

boegel commented Dec 8, 2017

@jdonners Please review/merge sara-nl#1, with that included this is good to go imho.

enhance test to catch fixed bug + re-instate injection of $ORIGIN/../lib and $ORIGIN/../lib64
@boegel
Copy link
Member

boegel commented Dec 10, 2017

Going in, thanks @jdonners!

@boegel boegel merged commit e86fa6f into easybuilders:develop Dec 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants