From 696ac930815bcbea6cc155534c5edfb4d09c29b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Andr=C3=A9=20Reuter?= Date: Fri, 6 Mar 2026 09:20:23 +0100 Subject: [PATCH 1/4] do not set LIBRARY_PATH for LLVM and adapt compiler config to insert paths instead --- easybuild/easyblocks/l/llvm.py | 55 ++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/easybuild/easyblocks/l/llvm.py b/easybuild/easyblocks/l/llvm.py index d52cc894527..e3afb701af0 100644 --- a/easybuild/easyblocks/l/llvm.py +++ b/easybuild/easyblocks/l/llvm.py @@ -1145,29 +1145,39 @@ def configure_step3(self): def _create_compiler_config_file(self, installdir): """Create a config file for the compiler to point to the correct GCC installation.""" - - # This is only needed for LLVM >= 19, as the --gcc-install-dir option was introduced then - if LooseVersion(self.version) < '19': + if self.cfg['minimal']: return - bin_dir = os.path.join(installdir, 'bin') - opts = [f'--gcc-install-dir={self.gcc_prefix}'] - - if self.dynamic_linker: - opts.append(f'-Wl,-dynamic-linker={self.dynamic_linker}') - # The --dyld-prefix flag exists, but beside being poorly documented it is also not supported by flang - # https://reviews.llvm.org/D851 - # prefix = self.sysroot.rstrip('/') - # opts.append(f'--dyld-prefix={prefix}') - - # For a non `full_llvm` build, always add GCCcore with a -L in the config file - # This is needed even if GCCcore is in the LIBRARY_PATH as some tests will filter it out; - # This is needed as the runtimes tests will not add the -L option to the linker command line for GCCcore - # otherwise - if not self.full_llvm: - gcc_lib = self._get_gcc_libpath(strict=True) - self.log.info("Adding GCCcore libraries location `%s` the config files", gcc_lib) - opts.append(f'-L{gcc_lib}') + opts = [] + # Let the compilers pick up the correct GCC via --gcc-install-dir + # This is only needed for LLVM >= 19, as the --gcc-install-dir option was introduced then + if LooseVersion(self.version) >= '19': + bin_dir = os.path.join(installdir, 'bin') + opts.append(f'--gcc-install-dir={self.gcc_prefix}') + if self.dynamic_linker: + opts.append(f'-Wl,-dynamic-linker={self.dynamic_linker}') + # The --dyld-prefix flag exists, but beside being poorly documented it is also not supported by flang + # https://reviews.llvm.org/D851 + # prefix = self.sysroot.rstrip('/') + # opts.append(f'--dyld-prefix={prefix}') + + # For a non `full_llvm` build, always add GCCcore with a -L in the config file + # This is needed even if GCCcore is in the LIBRARY_PATH as some tests will filter it out; + # This is needed as the runtimes tests will not add the -L option to the linker command line for GCCcore + # otherwise + if not self.full_llvm: + gcc_lib = self._get_gcc_libpath(strict=True) + self.log.info("Adding GCCcore libraries location `%s` the config files", gcc_lib) + opts.append(f'-L{gcc_lib}') + + # Add flags to make sure LLVM picks up its own directories correctly. + # This ensures that LLVM finds it own stuff, even when LIBRARY_PATH is not set. + opts.append(f'-L{installdir}/lib') + opts.append(f'-Wl,-rpath={installdir}/lib') + if self.final_runtimes or (LooseVersion(self.version) >= 19 and self.cfg['openmp']): + runtime_libdir = self.get_runtime_lib_path(installdir) + opts.append(f'-L{runtime_libdir}') + opts.append(f'-Wl,-rpath={runtime_libdir}') for comp in self.cfg_compilers: write_file(os.path.join(bin_dir, f'{comp}.cfg'), ' '.join(opts)) @@ -1860,9 +1870,8 @@ def make_module_step(self, *args, **kwargs): runtime_lib_path = self.get_runtime_lib_path(self.installdir) lib_dirs.append(runtime_lib_path) - self.log.debug(f"List of subdirectories for libraries to add to $LD_LIBRARY_PATH + $LIBRARY_PATH: {lib_dirs}") + self.log.debug(f"List of subdirectories for libraries to add to $LD_LIBRARY_PATH: {lib_dirs}") self.module_load_environment.LD_LIBRARY_PATH = lib_dirs - self.module_load_environment.LIBRARY_PATH = lib_dirs return super().make_module_step(*args, **kwargs) def make_module_extra(self): From 3e778c80179190161d2ba7d7b5df5bd3f3819f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Andr=C3=A9=20Reuter?= Date: Mon, 9 Mar 2026 12:36:41 +0100 Subject: [PATCH 2/4] LLVM: Only add libdir runtime path to search paths if found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan André Reuter --- easybuild/easyblocks/l/llvm.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/l/llvm.py b/easybuild/easyblocks/l/llvm.py index e3afb701af0..d96ddf2380a 100644 --- a/easybuild/easyblocks/l/llvm.py +++ b/easybuild/easyblocks/l/llvm.py @@ -1175,9 +1175,10 @@ def _create_compiler_config_file(self, installdir): opts.append(f'-L{installdir}/lib') opts.append(f'-Wl,-rpath={installdir}/lib') if self.final_runtimes or (LooseVersion(self.version) >= 19 and self.cfg['openmp']): - runtime_libdir = self.get_runtime_lib_path(installdir) - opts.append(f'-L{runtime_libdir}') - opts.append(f'-Wl,-rpath={runtime_libdir}') + runtime_libdir = self.get_runtime_lib_path(installdir, fail_ok=True) + if os.path.exists(runtime_libdir): + opts.append(f'-L{runtime_libdir}') + opts.append(f'-Wl,-rpath={runtime_libdir}') for comp in self.cfg_compilers: write_file(os.path.join(bin_dir, f'{comp}.cfg'), ' '.join(opts)) From b3ce2b08dbf6f1729e74f7f24c590416fc67e023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Andr=C3=A9=20Reuter?= Date: Wed, 11 Mar 2026 09:52:19 +0100 Subject: [PATCH 3/4] LLVM: Only add paths during test and install step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan André Reuter --- easybuild/easyblocks/l/llvm.py | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/easybuild/easyblocks/l/llvm.py b/easybuild/easyblocks/l/llvm.py index d96ddf2380a..bc75ea58585 100644 --- a/easybuild/easyblocks/l/llvm.py +++ b/easybuild/easyblocks/l/llvm.py @@ -1143,16 +1143,24 @@ def configure_step3(self): if self.full_llvm: self._cmakeopts.update(self.remove_gcc_dependency_opts) - def _create_compiler_config_file(self, installdir): - """Create a config file for the compiler to point to the correct GCC installation.""" + def _create_compiler_config_file(self, installdir, add_lib_path=False): + """ + Create a config file for the compiler to point to the correct GCC installation. + + :param installdir: Installation directory for the LLVM installation. Used to determine bin/ directory. + :param add_lib_path: Add -L and -rpath flags to lib/ directory and runtime library directory, if found. + This is required, since the LLVM module filters LIBRARY_PATH otherwise. Default is + False. Should be enabled for the test and final installation step. + """ if self.cfg['minimal']: return opts = [] + bin_dir = os.path.join(installdir, 'bin') + # Let the compilers pick up the correct GCC via --gcc-install-dir # This is only needed for LLVM >= 19, as the --gcc-install-dir option was introduced then if LooseVersion(self.version) >= '19': - bin_dir = os.path.join(installdir, 'bin') opts.append(f'--gcc-install-dir={self.gcc_prefix}') if self.dynamic_linker: opts.append(f'-Wl,-dynamic-linker={self.dynamic_linker}') @@ -1170,15 +1178,16 @@ def _create_compiler_config_file(self, installdir): self.log.info("Adding GCCcore libraries location `%s` the config files", gcc_lib) opts.append(f'-L{gcc_lib}') - # Add flags to make sure LLVM picks up its own directories correctly. - # This ensures that LLVM finds it own stuff, even when LIBRARY_PATH is not set. - opts.append(f'-L{installdir}/lib') - opts.append(f'-Wl,-rpath={installdir}/lib') - if self.final_runtimes or (LooseVersion(self.version) >= 19 and self.cfg['openmp']): - runtime_libdir = self.get_runtime_lib_path(installdir, fail_ok=True) - if os.path.exists(runtime_libdir): - opts.append(f'-L{runtime_libdir}') - opts.append(f'-Wl,-rpath={runtime_libdir}') + if add_lib_path: + # Add flags to make sure LLVM picks up its own directories correctly. + # This ensures that LLVM finds it own stuff, even when LIBRARY_PATH is not set. + opts.append(f'-L{installdir}/lib') + opts.append(f'-Wl,-rpath={installdir}/lib') + if self.final_runtimes or (LooseVersion(self.version) >= 19 and self.cfg['openmp']): + runtime_libdir = self.get_runtime_lib_path(installdir, fail_ok=True) + if os.path.exists(runtime_libdir): + opts.append(f'-L{runtime_libdir}') + opts.append(f'-Wl,-rpath={runtime_libdir}') for comp in self.cfg_compilers: write_file(os.path.join(bin_dir, f'{comp}.cfg'), ' '.join(opts)) @@ -1465,7 +1474,7 @@ def test_step(self): """Run tests on final stage (unless disabled).""" if not self.cfg['skip_all_tests']: # Also runs of test suite compilers should be made aware of the GCC installation - self._create_compiler_config_file(self.final_dir) + self._create_compiler_config_file(self.final_dir, add_lib_path=True) # For nvptx64 tests, find out if 'ptxas' exists in $PATH. If not, ignore all nvptx64 test failures if not which('ptxas', on_error=IGNORE): @@ -1525,7 +1534,8 @@ def install_step(self): # For GCC aware installation create config files in order to point to the correct GCC installation # Required as GCC_INSTALL_PREFIX was removed (see https://github.com/llvm/llvm-project/pull/87360) - self._create_compiler_config_file(self.installdir) + # Also add the library and runtime directory, if present. + self._create_compiler_config_file(self.installdir, add_lib_path=True) # This is needed as some older build system will select a different naming scheme for the library leading to # The correct target <__config_site> and libclang_rt.builtins.a not being found From de52663be5d0e4d8a74af0877da414edb69ed8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Andr=C3=A9=20Reuter?= Date: Wed, 11 Mar 2026 16:47:00 +0100 Subject: [PATCH 4/4] LLVM: Pass full runtime dir and use comma instead of = MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan André Reuter --- easybuild/easyblocks/l/llvm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/l/llvm.py b/easybuild/easyblocks/l/llvm.py index bc75ea58585..d046e405445 100644 --- a/easybuild/easyblocks/l/llvm.py +++ b/easybuild/easyblocks/l/llvm.py @@ -1186,8 +1186,8 @@ def _create_compiler_config_file(self, installdir, add_lib_path=False): if self.final_runtimes or (LooseVersion(self.version) >= 19 and self.cfg['openmp']): runtime_libdir = self.get_runtime_lib_path(installdir, fail_ok=True) if os.path.exists(runtime_libdir): - opts.append(f'-L{runtime_libdir}') - opts.append(f'-Wl,-rpath={runtime_libdir}') + opts.append(f'-L{installdir}/{runtime_libdir}') + opts.append(f'-Wl,-rpath,{installdir}/{runtime_libdir}') for comp in self.cfg_compilers: write_file(os.path.join(bin_dir, f'{comp}.cfg'), ' '.join(opts))