Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,8 @@ def prepare_step(self, start_dir=True):
self.rpath_filter_dirs.append(self.builddir)

# 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=self.cfg['rpath'],
rpath_filter_dirs=self.rpath_filter_dirs)

# handle allowed system dependencies
for (name, version) in self.cfg['allow_system_deps']:
Expand Down Expand Up @@ -1818,7 +1819,7 @@ def extensions_step(self, fetch=False):
# don't reload modules for toolchain, there is no need since they will be loaded already;
# the (fake) module for the parent software gets loaded before installing extensions
inst.toolchain.prepare(onlymod=self.cfg['onlytcmod'], silent=True, loadmod=False,
rpath_filter_dirs=self.rpath_filter_dirs)
rpath=self.cfg['rpath'], rpath_filter_dirs=self.rpath_filter_dirs)

# real work
inst.prerun()
Expand Down
1 change: 1 addition & 0 deletions easybuild/framework/easyconfig/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
'preconfigopts': ['', 'Extra options pre-passed to configure.', BUILD],
'preinstallopts': ['', 'Extra prefix options for installation.', BUILD],
'postinstallcmds': [[], 'Commands to run after the install step.', BUILD],
'rpath': [False, "Use RPATH linking (regardless of --rpath configuration option)", BUILD],
'runtest': [None, ('Indicates if a test should be run after make; should specify argument '
'after make (for e.g.,"test" for make test)'), BUILD],
'sanity_check_commands': [[], ("format: [(name, options)] e.g. [('gzip','-h')]. "
Expand Down
17 changes: 13 additions & 4 deletions easybuild/tools/toolchain/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ def compilers(self):

return (c_comps, fortran_comps)

def prepare(self, onlymod=None, silent=False, loadmod=True, rpath_filter_dirs=None):
def prepare(self, onlymod=None, silent=False, loadmod=True, rpath=None, rpath_filter_dirs=None):
"""
Prepare a set of environment parameters based on name/version of toolchain
- load modules for toolchain and dependencies
Expand All @@ -648,6 +648,7 @@ def prepare(self, onlymod=None, silent=False, loadmod=True, rpath_filter_dirs=No
(If string: comma separated list of variables that will be ignored).
:param silent: keep quiet, or not (mostly relates to extended dry run output)
:param loadmod: whether or not to (re)load the toolchain module, and the modules for the dependencies
:param rpath: enable RPATH linking (regardless of 'rpath' configuration option)
:param rpath_filter_dirs: extra directories to include in RPATH filter (e.g. build dir, tmpdir, ...)
"""
if loadmod:
Expand Down Expand Up @@ -679,12 +680,20 @@ def prepare(self, onlymod=None, silent=False, loadmod=True, rpath_filter_dirs=No
if build_option('use_%s' % cache_tool):
self.prepare_compiler_cache(cache_tool)

if build_option('rpath'):
if rpath:
self.use_rpath = True
self.log.info("Enabling RPATH linking, as explicitely specified for this installation")
elif build_option('rpath'):
if self.options.get('rpath', True):
self.prepare_rpath_wrappers()
self.use_rpath = True
self.log.info("Enabling RPATH linking, as configured")
else:
self.log.info("Not putting RPATH wrappers in place, disabled via 'rpath' toolchain option")
self.log.info("Not enabling use of RPATH linking, disabled via 'rpath' toolchain option")
else:
self.log.info("Not enabling use of RPATH linking, not requested")

if self.use_rpath:
self.prepare_rpath_wrappers()

def comp_cache_compilers(self, cache_tool):
"""
Expand Down
29 changes: 26 additions & 3 deletions test/framework/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1276,21 +1276,43 @@ def test_toolchain_prepare_rpath(self):
fake_gcc = os.path.join(self.test_prefix, 'fake', 'gcc')
write_file(fake_gcc, '#!/bin/bash\necho "$@"')
adjust_permissions(fake_gcc, stat.S_IXUSR)
os.environ['PATH'] = '%s:%s' % (os.path.join(self.test_prefix, 'fake'), os.getenv('PATH', ''))
path = '%s:%s' % (os.path.join(self.test_prefix, 'fake'), os.getenv('PATH', ''))
os.environ['PATH'] = path

# enable --rpath and prepare toolchain
init_config(build_options={'rpath': True, 'rpath_filter': ['/ba.*']})
tc = self.get_toolchain('gompi', version='1.3.12')

# preparing RPATH wrappers requires --experimental, need to bypass that here
tc.log.experimental = lambda x: x

# by default, RPATH linking is not enabled
tc.prepare()
res = which('gcc', retain_all=True)
self.assertTrue(len(res) >= 1)
self.assertFalse(tc.is_rpath_wrapper(res[0]))
self.assertFalse(any(tc.is_rpath_wrapper(x) for x in res[1:]))
self.assertTrue(os.path.samefile(res[0], fake_gcc))

# use of RPATH wrapper can be enabled regardless of configuration (via 'rpath' easyconfig parameter)
os.environ['PATH'] = path
tc.prepare(rpath=True)
res = which('gcc', retain_all=True)
self.assertTrue(len(res) >= 2)
self.assertTrue(tc.is_rpath_wrapper(res[0]))
self.assertFalse(any(tc.is_rpath_wrapper(x) for x in res[1:]))
self.assertTrue(os.path.samefile(res[1], fake_gcc))

# enable --rpath and prepare toolchain
init_config(build_options={'rpath': True, 'rpath_filter': ['/ba.*']})
tc = self.get_toolchain('gompi', version='1.3.12')
tc.log.experimental = lambda x: x

# 'rpath' toolchain option gives control to disable use of RPATH wrappers
tc.set_options({})
self.assertTrue(tc.options['rpath']) # enabled by default

# setting 'rpath' toolchain option to false implies no RPATH wrappers being used
tc.set_options({'rpath': False})
os.environ['PATH'] = path
tc.prepare()
res = which('gcc', retain_all=True)
self.assertTrue(len(res) >= 1)
Expand All @@ -1300,6 +1322,7 @@ def test_toolchain_prepare_rpath(self):

# enable 'rpath' toolchain option again (equivalent to the default setting)
tc.set_options({'rpath': True})
os.environ['PATH'] = path
tc.prepare()

# check that wrapper is indeed in place
Expand Down
12 changes: 10 additions & 2 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1436,14 +1436,22 @@ def test_toy_rpath(self):
# also test use of --rpath-filter
self.test_toy_build(extra_args=['--rpath', '--rpath-filter=/test.*,/foo.*', '--experimental'], raise_error=True)

# test use of rpath toolchain option
# test use of rpath toolchain option to selectively disable use of RPATH
test_ecs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
toy_ec_txt = read_file(os.path.join(test_ecs, 't', 'toy', 'toy-0.0.eb'))
toy_ec = os.path.join(test_ecs, 't', 'toy', 'toy-0.0.eb')
toy_ec_txt = read_file(toy_ec)
toy_ec_txt += "\ntoolchainopts = {'rpath': False}\n"
toy_ec = os.path.join(self.test_prefix, 'toy.eb')
write_file(toy_ec, toy_ec_txt)
self.test_toy_build(ec_file=toy_ec, extra_args=['--rpath', '--experimental'], raise_error=True)

# test use of rpath easyconfig parameter to selectively enable use of RPATH regardless of configuration
toy_ec_txt = read_file(toy_ec)
toy_ec_txt += "\nrpath = True\n"
toy_ec = os.path.join(self.test_prefix, 'toy.eb')
write_file(toy_ec, toy_ec_txt)
self.test_toy_build(ec_file=toy_ec, extra_args=['--experimental'], raise_error=True)

def test_toy_modaltsoftname(self):
"""Build two dependent toys as in test_toy_toy but using modaltsoftname"""
topdir = os.path.dirname(os.path.abspath(__file__))
Expand Down