From 43195ba94d55f59760e769b3cba270c4175da3c7 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 11 Aug 2025 08:35:18 +0200 Subject: [PATCH 1/3] Fix f-string in rpath check --- easybuild/framework/easyblock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index 5ceea98920..ae7d8605f9 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -3804,7 +3804,7 @@ def sanity_check_rpath(self, rpath_dirs=None, check_readelf_rpath=None): out = get_linked_libs_raw(path) if out is None: - msg = "Failed to determine dynamically linked libraries for {path}, " + msg = f"Failed to determine dynamically linked libraries for {path}, " msg += "so skipping it in RPATH sanity check" self.log.debug(msg) else: From 4646ae143066439c80886b51a445ba6d2b898d57 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 11 Aug 2025 08:41:35 +0200 Subject: [PATCH 2/3] Skip check for linked libs on symlinks `file` will return "symbolic link to libxxx" which will then skip the remaining checks. So do not bother running `file` on it which is much slower than an `islink` check. --- easybuild/tools/systemtools.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/tools/systemtools.py b/easybuild/tools/systemtools.py index f62144b9f4..3fefc1f95e 100644 --- a/easybuild/tools/systemtools.py +++ b/easybuild/tools/systemtools.py @@ -1118,6 +1118,9 @@ def get_linked_libs_raw(path): or None for other types of files. """ + if os.path.islink(path): + _log.debug(f"{path} is a symbolic link, so skipping check for linked libs") + return None res = run_shell_cmd("file %s" % path, fail_on_error=False, hidden=True, output_file=False, stream_output=False) if res.exit_code != EasyBuildExit.SUCCESS: fail_msg = "Failed to run 'file %s': %s" % (path, res.output) From 1d657f23f7cdfd35bb936e421d5231468eb53a02 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 27 Aug 2025 15:21:38 +0200 Subject: [PATCH 3/3] add test for get_linked_libs_raw --- test/framework/systemtools.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/test/framework/systemtools.py b/test/framework/systemtools.py index b73443947c..cfdaba177f 100644 --- a/test/framework/systemtools.py +++ b/test/framework/systemtools.py @@ -54,7 +54,7 @@ from easybuild.tools.systemtools import get_cpu_architecture, get_cpu_family, get_cpu_features, get_cpu_model from easybuild.tools.systemtools import get_cpu_speed, get_cpu_vendor, get_gcc_version, get_glibc_version, get_os_type from easybuild.tools.systemtools import get_os_name, get_os_version, get_platform_name, get_shared_lib_ext -from easybuild.tools.systemtools import get_system_info, get_total_memory +from easybuild.tools.systemtools import get_system_info, get_total_memory, get_linked_libs_raw from easybuild.tools.systemtools import find_library_path, locate_solib, pick_dep_version, pick_system_specific_value @@ -1453,6 +1453,34 @@ def test_get_cuda_architectures(self): # Restore original environment modify_env(os.environ, start_env, verbose=False) + def test_get_linked_libs_raw(self): + """ + Test get_linked_libs_raw function. + """ + bin_ls = which('ls') + linked_libs_out = get_linked_libs_raw(bin_ls) + os_type = get_os_type() + if os_type == LINUX: + libname = 'libc.so.6' + elif os_type == DARWIN: + libname = 'libSystem.B.dylib' + else: + self.fail(f"Unknown OS: {os_type}") + + # check whether expected pattern is found + self.assertIn(libname, linked_libs_out) + + # when specified path is a symlink or a non-binary file, None is the result + symlinked_ls = os.path.join(self.test_prefix, 'ls') + symlink(bin_ls, symlinked_ls) + res = get_linked_libs_raw(symlinked_ls) + self.assertEqual(res, None) + + txt_file = os.path.join(self.test_prefix, 'test.txt') + write_file(txt_file, 'not-a-binary') + res = get_linked_libs_raw(txt_file) + self.assertEqual(res, None) + def suite(loader=None): """ returns all the testcases in this module """