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

add support for disabling strict RPATH sanity check + print a warning when mixing of non-RPATH and RPATH installations was detected #4475

Open
wants to merge 1 commit into
base: 5.0.x
Choose a base branch
from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 30 additions & 3 deletions easybuild/framework/easyblock.py
Expand Up @@ -3118,16 +3118,23 @@ def sanity_check_rpath(self, rpath_dirs=None, check_readelf_rpath=True):
self.log.info("Checking RPATH linkage for binaries/libraries...")

fails = []
mixed_stack = False

# hard reset $LD_LIBRARY_PATH before running RPATH sanity check
orig_env = env.unset_env_vars(['LD_LIBRARY_PATH'])
if build_option('strict_rpath_sanity_check'):
self.log.info("Unsetting $LD_LIBRARY_PATH since strict RPATH sanity check is enabled...")
# hard reset $LD_LIBRARY_PATH before running RPATH sanity check
orig_env = env.unset_env_vars(['LD_LIBRARY_PATH'])
else:
self.log.info("Not unsetting $LD_LIBRARY_PATH since strict RPATH sanity check is disabled...")
orig_env = None

ld_library_path = os.getenv('LD_LIBRARY_PATH', '(empty)')
self.log.debug(f"$LD_LIBRARY_PATH during RPATH sanity check: {ld_library_path}")
modules_list = self.modules_tool.list()
self.log.debug(f"List of loaded modules: {modules_list}")

not_found_regex = re.compile(r'(\S+)\s*\=\>\s*not found')
lib_path_regex = re.compile(r'\S+\s*\=\>\s*(\S+)')
readelf_rpath_regex = re.compile('(RPATH)', re.M)

# List of libraries that should be exempt from the RPATH sanity check;
Expand Down Expand Up @@ -3173,6 +3180,17 @@ def sanity_check_rpath(self, rpath_dirs=None, check_readelf_rpath=True):
fail_msg = f"Library {match} not found for {path}"
self.log.warning(fail_msg)
fails.append(fail_msg)

# inject suggestion to disable strict RPATH sanity check if one or more dependency libraries
# were not installed with RPATH linking enabled (so we're in a "mixed stack" situation)
if fails:
lib_paths = re.findall(lib_path_regex, out)
for lib_path in lib_paths:
self.log.info(f"Checking whether dependency library {lib_path} has RPATH section")
res = run_shell_cmd(f"readelf -d {lib_path}", fail_on_error=False)
if res.exit_code:
self.log.info(f"No RPATH section found in {lib_path}")
mixed_stack = True
else:
self.log.debug(f"Output of 'ldd {path}' checked, looks OK")

Expand All @@ -3195,7 +3213,16 @@ def sanity_check_rpath(self, rpath_dirs=None, check_readelf_rpath=True):
else:
self.log.debug(f"Not sanity checking files in non-existing directory {dirpath}")

env.restore_env_vars(orig_env)
if orig_env:
env.restore_env_vars(orig_env)

if mixed_stack:
msg = "\nNo RPATH section found in one or more dependency libraries, "
msg += "so you should probably change your EasyBuild configuration to disable "
msg += "the strict RPATH sanity check that involves unsetting $LD_LIBRARY_PATH "
msg += "when checking for required libraries; "
msg += "see also https://docs.easybuild.io/easybuild-v5/strict-rpath-sanity-check"
fails.append(msg)

return fails

Expand Down
1 change: 1 addition & 0 deletions easybuild/tools/config.py
Expand Up @@ -329,6 +329,7 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
'mpi_tests',
'pre_create_installdir',
'show_progress_bar',
'strict_rpath_sanity_check',
'trace',
],
EMPTY_LIST: [
Expand Down
3 changes: 3 additions & 0 deletions easybuild/tools/options.py
Expand Up @@ -510,6 +510,9 @@ def override_options(self):
'skip-test-cases': ("Skip running test cases", None, 'store_true', False, 't'),
'skip-test-step': ("Skip running the test step (e.g. unit tests)", None, 'store_true', False),
'sticky-bit': ("Set sticky bit on newly created directories", None, 'store_true', False),
'strict-rpath-sanity-check': ("Perform strict RPATH sanity check, which involces unsetting "
"$LD_LIBRARY_PATH before checking whether all required libraries are found",
None, 'store_true', True),
'sysroot': ("Location root directory of system, prefix for standard paths like /usr/lib and /usr/include",
None, 'store', None),
'trace': ("Provide more information in output to stdout on progress", None, 'store_true', True, 'T'),
Expand Down