diff --git a/easybuild/toolchains/compiler/llvm.py b/easybuild/toolchains/compiler/llvm.py
new file mode 100644
index 0000000000..895b386791
--- /dev/null
+++ b/easybuild/toolchains/compiler/llvm.py
@@ -0,0 +1,187 @@
+##
+# Copyright 2013-2025 Ghent University
+#
+# This file is triple-licensed under GPLv2 (see below), MIT, and
+# BSD three-clause licenses.
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild. If not, see .
+##
+"""
+EasyBuild support for Clang + Flang compiler toolchain.
+
+Authors:
+
+* Dmitri Gribenko (National Technical University of Ukraine "KPI")
+* Davide Grassano (CECAM EPFL)
+"""
+
+from easybuild.tools import LooseVersion
+import easybuild.tools.systemtools as systemtools
+from easybuild.tools.toolchain.compiler import Compiler, DEFAULT_OPT_LEVEL
+from easybuild.tools.toolchain.toolchain import SYSTEM_TOOLCHAIN_NAME
+
+TC_CONSTANT_LLVM = "LLVM"
+
+
+class LLVM(Compiler):
+ """Compiler toolchain with Clang and GFortran compilers."""
+ # NAME = 'LLVMcore'
+ # COMPILER_MODULE_NAME = [NAME]
+ COMPILER_FAMILY = TC_CONSTANT_LLVM
+ SUBTOOLCHAIN = SYSTEM_TOOLCHAIN_NAME
+
+ # List of flags that are supported by Clang but not yet by Flang and should be filtered out
+ # The element of the list are tuples with the following structure:
+ # (min_version, max_version, [list of flags])
+ # Where min_version and max_version are strings representing a left-inclusive and right-exclusive version range,
+ # [min_version, max_version) respectively.
+ # This is used to specify general `clang`-accepted flags and remove them from `flang` compiler flags if
+ # not supported for a particular version of LLVM
+ FLANG_UNSUPPORTED_VARS = [
+ ('19', '21', [
+ '-fmath-errno', '-fno-math-errno',
+ '-fslp-vectorize',
+ '-fvectorize', '-fno-vectorize',
+ '-fno-unsafe-math-optimizations',
+ ])
+ ]
+
+ FORTRAN_FLAGS = ['FCFLAGS', 'FFLAGS', 'F90FLAGS']
+
+ COMPILER_UNIQUE_OPTS = {
+ 'loop-vectorize': (False, "Loop vectorization"),
+ 'basic-block-vectorize': (False, "Basic block vectorization"),
+
+ # https://github.com/madler/zlib/issues/856
+ 'lld_undefined_version': (True, "-Wl,--undefined-version - Allow unused version in version script"),
+ 'no_unused_args': (
+ True,
+ (
+ "-Wno-unused-command-line-argument - Avoid some failures in CMake correctly recognizing "
+ "feature due to linker warnings"
+ )
+ ),
+ 'no_int_conversion_error': (
+ True,
+ "-Wno-error=int-conversion - Avoid some failures that are normally ignored by GCC"
+ ),
+ }
+
+ COMPILER_UNIQUE_OPTION_MAP = {
+ 'unroll': '-funroll-loops',
+ 'loop-vectorize': ['-fvectorize'],
+ 'basic-block-vectorize': ['-fslp-vectorize'],
+ 'optarch': '',
+ # 'optarch': '-march=native',
+ # Clang's options do not map well onto these precision modes. The flags enable and disable certain classes of
+ # optimizations.
+ #
+ # -fassociative-math: allow re-association of operands in series of floating-point operations, violates the
+ # ISO C and C++ language standard by possibly changing computation result.
+ # -freciprocal-math: allow optimizations to use the reciprocal of an argument rather than perform division.
+ # -fsigned-zeros: do not allow optimizations to treat the sign of a zero argument or result as insignificant.
+ # -fhonor-infinities: disallow optimizations to assume that arguments and results are not +/- Infs.
+ # -fhonor-nans: disallow optimizations to assume that arguments and results are not +/- NaNs.
+ # -ffinite-math-only: allow optimizations for floating-point arithmetic that assume that arguments and results
+ # are not NaNs or +-Infs (equivalent to -fno-honor-nans -fno-honor-infinities)
+ # -funsafe-math-optimizations: allow unsafe math optimizations (implies -fassociative-math, -fno-signed-zeros,
+ # -freciprocal-math).
+ # -ffast-math: an umbrella flag that enables all optimizations listed above, provides preprocessor macro
+ # __FAST_MATH__.
+ #
+ # Using -fno-fast-math is equivalent to disabling all individual optimizations, see
+ # http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?view=markup (lines 2100 and following)
+ #
+ # 'strict', 'precise' and 'defaultprec' are all ISO C++ and IEEE complaint, but we explicitly specify details
+ # flags for strict and precise for robustness against future changes.
+ 'strict': ['-fno-fast-math'],
+ 'precise': ['-fno-unsafe-math-optimizations'],
+ 'defaultprec': [],
+ 'loose': ['-ffast-math', '-fno-unsafe-math-optimizations'],
+ 'veryloose': ['-ffast-math'],
+ 'vectorize': {False: '-fno-vectorize', True: '-fvectorize'},
+ DEFAULT_OPT_LEVEL: ['-O2'],
+
+ 'lld_undefined_version': ['-Wl,--undefined-version'],
+ 'no_unused_args': ['-Wno-unused-command-line-argument'],
+ 'no_int_conversion_error': ['-Wno-error=int-conversion'],
+ }
+
+ COMPILER_OPTIONS = [
+ 'lld_undefined_version',
+ ]
+
+ # Options only available for Clang compiler
+ COMPILER_C_OPTIONS = [
+ 'no_unused_args',
+ 'no_int_conversion_error'
+ ]
+
+ # Options only available for Flang compiler
+ COMPILER_F_OPTIONS = []
+
+ # used when 'optarch' toolchain option is enabled (and --optarch is not specified)
+ COMPILER_OPTIMAL_ARCHITECTURE_OPTION = {
+ (systemtools.POWER, systemtools.POWER): '-mcpu=native', # no support for march=native on POWER
+ (systemtools.POWER, systemtools.POWER_LE): '-mcpu=native', # no support for march=native on POWER
+ (systemtools.X86_64, systemtools.AMD): '-march=native',
+ (systemtools.X86_64, systemtools.INTEL): '-march=native',
+ }
+ # used with --optarch=GENERIC
+ COMPILER_GENERIC_OPTION = {
+ (systemtools.RISCV64, systemtools.RISCV): '-march=rv64gc -mabi=lp64d', # default for -mabi is system-dependent
+ (systemtools.X86_64, systemtools.AMD): '-march=x86-64 -mtune=generic',
+ (systemtools.X86_64, systemtools.INTEL): '-march=x86-64 -mtune=generic',
+ }
+
+ COMPILER_CC = 'clang'
+ COMPILER_CXX = 'clang++'
+ COMPILER_C_UNIQUE_OPTIONS = []
+
+ COMPILER_F77 = 'flang'
+ COMPILER_F90 = 'flang'
+ COMPILER_FC = 'flang'
+ COMPILER_F_UNIQUE_OPTIONS = []
+
+ LIB_MULTITHREAD = ['pthread']
+ LIB_MATH = ['m']
+
+ def _set_compiler_flags(self):
+ super()._set_compiler_flags()
+
+ unsupported_fortran_flags = None
+ for v_min, v_max, flags in self.FLANG_UNSUPPORTED_VARS:
+ if LooseVersion(self.version) >= LooseVersion(v_min) and LooseVersion(self.version) < LooseVersion(v_max):
+ unsupported_fortran_flags = flags
+ break
+ else:
+ self.log.debug("No unsupported flags found for LLVM version %s", self.version)
+
+ if unsupported_fortran_flags is not None:
+ self.log.debug(
+ f"Ensuring usupported Fortran flags `{unsupported_fortran_flags}` are removed from variables"
+ )
+ for key, lst in self.variables.items():
+ if key not in self.FORTRAN_FLAGS:
+ continue
+ for item in lst:
+ item.try_remove(unsupported_fortran_flags)
diff --git a/easybuild/toolchains/lfbf.py b/easybuild/toolchains/lfbf.py
new file mode 100644
index 0000000000..0c4fa89289
--- /dev/null
+++ b/easybuild/toolchains/lfbf.py
@@ -0,0 +1,44 @@
+##
+# Copyright 2021-2025 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild. If not, see .
+##
+"""
+EasyBuild support for gfbf compiler toolchain (includes GCC, FlexiBLAS and FFTW)
+
+Authors:
+
+* Kenneth Hoste (Ghent University)
+* Bart Oldeman (McGill University, Calcul Quebec, Compute Canada)
+* Davide Grassano (CECAM EPFL)
+"""
+
+from easybuild.toolchains.llvm import LLVMtc
+from easybuild.toolchains.fft.fftw import Fftw
+from easybuild.toolchains.linalg.flexiblas import FlexiBLAS
+
+
+class Lfbf(LLVMtc, FlexiBLAS, Fftw):
+ """Compiler toolchain with GCC, FlexiBLAS and FFTW."""
+ NAME = 'lfbf'
+ SUBTOOLCHAIN = LLVMtc.NAME
+ OPTIONAL = True
diff --git a/easybuild/toolchains/lfoss.py b/easybuild/toolchains/lfoss.py
new file mode 100644
index 0000000000..584c48c0b7
--- /dev/null
+++ b/easybuild/toolchains/lfoss.py
@@ -0,0 +1,90 @@
+##
+# Copyright 2013-2025 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild. If not, see .
+##
+"""
+EasyBuild support for foss compiler toolchain (includes GCC, OpenMPI, OpenBLAS, LAPACK, ScaLAPACK and FFTW).
+
+Authors:
+
+* Kenneth Hoste (Ghent University)
+* Davide Grassano (CECAM EPFL)
+"""
+from easybuild.toolchains.lompi import Lompi
+from easybuild.toolchains.lfbf import Lfbf
+from easybuild.toolchains.lolf import Lolf
+from easybuild.toolchains.fft.fftw import Fftw
+from easybuild.toolchains.linalg.flexiblas import FlexiBLAS
+from easybuild.toolchains.linalg.scalapack import ScaLAPACK
+from easybuild.tools import LooseVersion
+
+
+class LFoss(Lompi, FlexiBLAS, ScaLAPACK, Fftw):
+ """Compiler toolchain with GCC, OpenMPI, FlexiBLAS, ScaLAPACK and FFTW."""
+ NAME = 'lfoss'
+ SUBTOOLCHAIN = [
+ Lompi.NAME,
+ Lolf.NAME,
+ Lfbf.NAME
+ ]
+
+ def __init__(self, *args, **kwargs):
+ """Toolchain constructor."""
+ super(LFoss, self).__init__(*args, **kwargs)
+
+ # need to transform a version like '2018b' with something that is safe to compare with '2019'
+ # comparing subversions that include letters causes TypeErrors in Python 3
+ # 'a' is assumed to be equivalent with '.01' (January), and 'b' with '.07' (June) (good enough for this purpose)
+ version = self.version.replace('a', '.01').replace('b', '.07')
+
+ self.looseversion = LooseVersion(version)
+
+ constants = ('BLAS_MODULE_NAME', 'BLAS_LIB', 'BLAS_LIB_MT', 'BLAS_FAMILY',
+ 'LAPACK_MODULE_NAME', 'LAPACK_IS_BLAS', 'LAPACK_FAMILY')
+
+ for constant in constants:
+ setattr(self, constant, getattr(FlexiBLAS, constant))
+
+ def banned_linked_shared_libs(self):
+ """
+ List of shared libraries (names, file names, paths) which are
+ not allowed to be linked in any installed binary/library.
+ """
+ res = []
+ res.extend(Lompi.banned_linked_shared_libs(self))
+ res.extend(FlexiBLAS.banned_linked_shared_libs(self))
+ res.extend(ScaLAPACK.banned_linked_shared_libs(self))
+ res.extend(Fftw.banned_linked_shared_libs(self))
+
+ return res
+
+ def is_deprecated(self):
+ """Return whether or not this toolchain is deprecated."""
+
+ # lfoss toolchains older than 2023b should not exist (need GCC >= 13)
+ if self.looseversion < LooseVersion('2023'):
+ deprecated = True
+ else:
+ deprecated = False
+
+ return deprecated
diff --git a/easybuild/toolchains/llvm.py b/easybuild/toolchains/llvm.py
new file mode 100644
index 0000000000..ac1d5c8695
--- /dev/null
+++ b/easybuild/toolchains/llvm.py
@@ -0,0 +1,45 @@
+##
+# Copyright 2013-2025 Ghent University
+#
+# This file is triple-licensed under GPLv2 (see below), MIT, and
+# BSD three-clause licenses.
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild. If not, see .
+##
+"""
+EasyBuild support for Clang + Flang compiler toolchain.
+
+Authors:
+
+* Davide Grassano (CECAM EPFL)
+"""
+
+from easybuild.toolchains.gcccore import GCCcore
+from easybuild.toolchains.compiler.llvm import LLVM
+from easybuild.tools.toolchain.toolchain import SYSTEM_TOOLCHAIN_NAME
+
+
+class LLVMtc(LLVM):
+ """Compiler toolchain with Clang and Flang compilers."""
+ NAME = 'LLVMtc' # Using `...tc` to distinguish toolchain from package
+ COMPILER_MODULE_NAME = [NAME]
+ SUBTOOLCHAIN = [GCCcore.NAME, SYSTEM_TOOLCHAIN_NAME]
diff --git a/easybuild/toolchains/lolf.py b/easybuild/toolchains/lolf.py
new file mode 100644
index 0000000000..a9509a6383
--- /dev/null
+++ b/easybuild/toolchains/lolf.py
@@ -0,0 +1,44 @@
+##
+# Copyright 2013-2025 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild. If not, see .
+##
+"""
+EasyBuild support for golf compiler toolchain (includes GCC, OpenBLAS, LAPACK, and FFTW).
+
+Authors:
+
+* Kenneth Hoste (Ghent University)
+* Bart Oldeman (McGill University, Calcul Quebec, Compute Canada)
+* Davide Grassano (CECAM EPFL)
+"""
+
+from easybuild.toolchains.llvm import LLVMtc
+from easybuild.toolchains.fft.fftw import Fftw
+from easybuild.toolchains.linalg.openblas import OpenBLAS
+
+
+class Lolf(LLVMtc, OpenBLAS, Fftw):
+ """Compiler toolchain with LLVM, OpenBLAS, and FFTW."""
+ NAME = 'lolf'
+ SUBTOOLCHAIN = LLVMtc.NAME
+ OPTIONAL = True
diff --git a/easybuild/toolchains/lompi.py b/easybuild/toolchains/lompi.py
new file mode 100644
index 0000000000..ed06cb3dd6
--- /dev/null
+++ b/easybuild/toolchains/lompi.py
@@ -0,0 +1,60 @@
+##
+# Copyright 2012-2025 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild. If not, see .
+##
+"""
+EasyBuild support for lompi compiler toolchain (includes LLVM and OpenMPI).
+
+Authors:
+
+* Kenneth Hoste (Ghent University)
+* Davide Grassano (CECAM EPFL)
+"""
+from easybuild.tools import LooseVersion
+import re
+
+from easybuild.toolchains.llvm import LLVMtc
+from easybuild.toolchains.mpi.openmpi import OpenMPI
+
+
+class Lompi(LLVMtc, OpenMPI):
+ """Compiler toolchain with GCC and OpenMPI."""
+ NAME = 'lompi'
+ SUBTOOLCHAIN = LLVMtc.NAME
+
+ def is_deprecated(self):
+ """Return whether or not this toolchain is deprecated."""
+ # need to transform a version like '2018b' with something that is safe to compare with '2019'
+ # comparing subversions that include letters causes TypeErrors in Python 3
+ # 'a' is assumed to be equivalent with '.01' (January), and 'b' with '.07' (June) (good enough for this purpose)
+ version = self.version.replace('a', '.01').replace('b', '.07')
+
+ deprecated = False
+
+ # make sure a non-symbolic version (e.g., 'system') is used before making comparisons using LooseVersion
+ if re.match('^[0-9]', version):
+ # lompi toolchains older than 2023b should not exist (need GCC >= 13)
+ if LooseVersion(version) < LooseVersion('2023'):
+ deprecated = True
+
+ return deprecated
diff --git a/test/framework/easyconfigversion.py b/test/framework/easyconfigversion.py
index 59cf051a42..68c4aa1b07 100644
--- a/test/framework/easyconfigversion.py
+++ b/test/framework/easyconfigversion.py
@@ -190,9 +190,10 @@ def test_parser_toolchain_regex(self):
self.assertEqual(tcversop.as_dict(), as_dict)
# only accept known toolchain names
+ RANDOM_BIT = 'ShouldNotMatch___'
fail_tests = [
- "x%s >= 1.2.3" % tc,
- "%sx >= 1.2.3" % tc,
+ f"{RANDOM_BIT}{tc} >= 1.2.3",
+ f"{tc}{RANDOM_BIT} >= 1.2.3",
"foo",
">= 1.2.3",
]
@@ -205,6 +206,7 @@ def test_parser_toolchain_regex(self):
def test_toolchain_versop_test(self):
"""Test the ToolchainVersionOperator test"""
_, tcs = search_toolchain('')
+ RANDOM_BIT = 'ShouldNotMatch___'
tc_names = [x.NAME for x in tcs]
for tc in tc_names: # test all known toolchain names
# test version expressions with optional version operator
@@ -213,8 +215,8 @@ def test_toolchain_versop_test(self):
(tc, '1.2.3', True), # version ok, name ok
(tc, '1.2.4', True), # version ok, name ok
(tc, '1.2.2', False), # version not ok, name ok
- ('x' + tc, '1.2.3', False), # version ok, name not ok
- ('x' + tc, '1.2.2', False), # version not ok, name not ok
+ (RANDOM_BIT + tc, '1.2.3', False), # version ok, name not ok
+ (RANDOM_BIT + tc, '1.2.2', False), # version not ok, name not ok
)),
]
for txt, subtests in tests: