Skip to content
Merged
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
47 changes: 24 additions & 23 deletions easybuild/scripts/rpath_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
Utility script used by RPATH wrapper script;
output is statements that define the following environment variables
* $CMD_ARGS: new list of command line arguments to pass
* $RPATH_ARGS: command line option to specify list of paths to RPATH

Usage:
rpath_args.py <cmd> <rpath_filter> <rpath_include> <args...>

author: Kenneth Hoste (HPC-UGent)
"""
Expand All @@ -38,22 +40,17 @@

def is_new_existing_path(new_path, paths):
"""
Check whether specified path exists and is a new path compared to provided list of paths.
Check whether specified path exists and is a new path compared to provided list of paths (that surely exist as they
were checked before).
"""
if not os.path.exists(new_path):
return False

# assume path is new, until proven otherwise
res = True

if os.path.exists(new_path):
for path in paths:
if os.path.exists(path) and os.path.samefile(new_path, path):
res = False
break
else:
# path doesn't exist
res = False
for path in paths:
if os.path.exists(path) and os.path.samefile(new_path, path):
return False

return res
return True


cmd = sys.argv[1]
Expand All @@ -63,9 +60,9 @@ def is_new_existing_path(new_path, paths):

# determine whether or not to use -Wl to pass options to the linker based on name of command
if cmd in ['ld', 'ld.gold', 'ld.bfd']:
flag_prefix = ''
ldflag_prefix = ''
else:
flag_prefix = '-Wl,'
ldflag_prefix = '-Wl,'

rpath_filter = rpath_filter.split(',')
if rpath_filter:
Expand Down Expand Up @@ -124,7 +121,7 @@ def is_new_existing_path(new_path, paths):
if is_new_existing_path(lib_path, rpath_lib_paths):
# inject -rpath flag in front for every -L with an absolute path,
rpath_lib_paths.append(lib_path)
cmd_args_rpath.append(flag_prefix + '-rpath=%s' % lib_path)
cmd_args_rpath.append(ldflag_prefix + '-rpath=%s' % lib_path)

# always retain -L flag (without reordering!)
cmd_args.append('-L%s' % lib_path)
Expand All @@ -135,8 +132,12 @@ def is_new_existing_path(new_path, paths):
# --enable-new-dtags is not removed but replaced to prevent issues when linker flag is forwarded from the compiler
# to the linker with an extra prefixed flag (either -Xlinker or -Wl,).
# In that case, the compiler would erroneously pass the next random argument to the linker.
elif arg == flag_prefix + '--enable-new-dtags':
cmd_args.append(flag_prefix + '--disable-new-dtags')
elif arg == '-Xlinker' and args[idx+1] == '--enable-new-dtags': # detect '-Xlinker --enable-new-dtags'
cmd_args.append(ldflag_prefix + '--disable-new-dtags')
idx += 1
elif arg == ldflag_prefix + '--enable-new-dtags': # detect '--enable-new-dtags' or '-Wl,--enable-new-dtags'
cmd_args.append(ldflag_prefix + '--disable-new-dtags')

else:
cmd_args.append(arg)

Expand All @@ -149,20 +150,20 @@ def is_new_existing_path(new_path, paths):
# avoid using duplicate library paths
if is_new_existing_path(lib_path, rpath_lib_paths):
rpath_lib_paths.append(lib_path)
cmd_args_rpath.append(flag_prefix + '-rpath=%s' % lib_path)
cmd_args_rpath.append(ldflag_prefix + '-rpath=%s' % lib_path)

if add_rpath_args:
# try to make sure that RUNPATH is not used by always injecting --disable-new-dtags
cmd_args_rpath.insert(0, flag_prefix + '--disable-new-dtags')
cmd_args_rpath.insert(0, ldflag_prefix + '--disable-new-dtags')

# add -rpath options for paths listed in rpath_include
cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include] + cmd_args_rpath
cmd_args_rpath = [ldflag_prefix + '-rpath=%s' % inc for inc in rpath_include] + cmd_args_rpath

# add -rpath flags in front
cmd_args = cmd_args_rpath + cmd_args

# wrap all arguments into single quotes to avoid further bash expansion
cmd_args = ["'%s'" % a.replace("'", "''") for a in cmd_args]

# output: statement to define $CMD_ARGS and $RPATH_ARGS
# output: statement to define $CMD_ARGS
print("CMD_ARGS=(%s)" % ' '.join(cmd_args))
16 changes: 16 additions & 0 deletions test/framework/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2546,6 +2546,22 @@ def test_rpath_args_script(self):
]
self.assertEqual(res.output.strip(), "CMD_ARGS=(%s)" % ' '.join(cmd_args))

# compiler command, -Xlinker --enable-new-dtags should be replaced with -Wl,--disable-new-dtags
with self.mocked_stdout_stderr():
res = run_shell_cmd(f"{script} gcc '' '{rpath_inc}' -Xlinker --enable-new-dtags foo.c")
self.assertEqual(res.exit_code, 0)
cmd_args = [
"'-Wl,-rpath=%s/lib'" % self.test_prefix,
"'-Wl,-rpath=%s/lib64'" % self.test_prefix,
"'-Wl,-rpath=$ORIGIN'",
"'-Wl,-rpath=$ORIGIN/../lib'",
"'-Wl,-rpath=$ORIGIN/../lib64'",
"'-Wl,--disable-new-dtags'",
"'-Wl,--disable-new-dtags'",
"'foo.c'",
]
self.assertEqual(res.output.strip(), "CMD_ARGS=(%s)" % ' '.join(cmd_args))

# test passing no arguments
with self.mocked_stdout_stderr():
res = run_shell_cmd(f"{script} gcc '' '{rpath_inc}'")
Expand Down