diff --git a/easyblocks/a/aocl.py b/easyblocks/a/aocl.py
new file mode 100644
index 0000000000000000000000000000000000000000..53e0f4781a7aa98922317176b9247e62971fc6cd
--- /dev/null
+++ b/easyblocks/a/aocl.py
@@ -0,0 +1,93 @@
+##
+# Copyright 2009-2021 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 <http://www.gnu.org/licenses/>.
+##
+"""
+EasyBuild support for AMD Core Math Library (AOCL), implemented as an easyblock
+
+@author: Lukas Krupcik (IT4Innovations)
+"""
+
+import os
+from distutils.version import LooseVersion
+
+from easybuild.framework.easyblock import EasyBlock
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools.run import run_cmd_qa
+from easybuild.tools.systemtools import get_shared_lib_ext
+
+
+class EB_AOCL(EasyBlock):
+
+    def __init__(self, *args, **kwargs):
+        """Constructor, adds extra class variables."""
+        super(EB_AOCL, self).__init__(*args, **kwargs)
+
+        self.basedir = '%s' % (self.version)
+
+    def configure_step(self):
+        """No custom configure step for AOCL."""
+        pass
+
+    def build_step(self):
+        """No custom build step for AOCL."""
+        pass
+
+    def install_step(self):
+        """Install by running install script."""
+
+        cmd = "./install.sh -t %s" % (self.installdir)
+
+        qa = {'The directory will be created if it does not already exist. >': self.installdir}
+
+        run_cmd_qa(cmd, qa, log_all=True, simple=True)
+
+    def make_module_extra(self):
+        """Add extra entries in module file (various paths)."""
+
+        txt = super(EB_AOCL, self).make_module_extra()
+
+        basepaths = ["%s" % (self.basedir)]
+
+        txt += self.module_generator.set_environment('AOCL_ROOT', "%s/%s" % (self.installdir, self.basedir))
+
+        for path in basepaths:
+            txt += self.module_generator.prepend_paths('PATH', os.path.join(path, 'amd-fftw/bin'))
+
+        for path in basepaths:
+            txt += self.module_generator.prepend_paths('CPATH', os.path.join(path, 'include'))
+
+        for key in ['LD_LIBRARY_PATH', 'LIBRARY_PATH']:
+            for path in basepaths:
+                txt += self.module_generator.prepend_paths(key, os.path.join(path, 'lib'))
+
+        return txt
+
+    def sanity_check_step(self):
+        """Custom sanity check for AOCL."""
+
+        custom_paths = {
+            'files': [],
+            'dirs': ['%s/aocc/include' % (self.version), '%s/aocc/lib' % (self.version), '%s/aocc/amd-fftw' % (self.version)]
+        }
+        super(EB_AOCL, self).sanity_check_step(custom_paths=custom_paths)
diff --git a/easyblocks/i/impi.py b/easyblocks/i/impi.py
new file mode 100644
index 0000000000000000000000000000000000000000..df0a804636509153fba451bcbb6c6a156c42784e
--- /dev/null
+++ b/easyblocks/i/impi.py
@@ -0,0 +1,377 @@
+# #
+# Copyright 2009-2023 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 <http://www.gnu.org/licenses/>.
+# #
+"""
+EasyBuild support for installing the Intel MPI library, implemented as an easyblock
+
+@author: Stijn De Weirdt (Ghent University)
+@author: Dries Verdegem (Ghent University)
+@author: Kenneth Hoste (Ghent University)
+@author: Pieter De Baets (Ghent University)
+@author: Jens Timmerman (Ghent University)
+@author: Damian Alvarez (Forschungszentrum Juelich GmbH)
+@author: Alex Domingo (Vrije Universiteit Brussel)
+"""
+import os
+from distutils.version import LooseVersion
+
+import easybuild.tools.toolchain as toolchain
+from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.config import build_option
+from easybuild.tools.filetools import apply_regex_substitutions, change_dir, extract_file, mkdir, write_file
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.run import run_cmd
+from easybuild.tools.systemtools import get_shared_lib_ext
+from easybuild.tools.toolchain.mpi import get_mpi_cmd_template
+
+
+class EB_impi(IntelBase):
+    """
+    Support for installing Intel MPI library
+    """
+    @staticmethod
+    def extra_options():
+        extra_vars = {
+            'libfabric_configopts': ['', 'Configure options for the provided libfabric', CUSTOM],
+            'libfabric_rebuild': [True, 'Try to rebuild internal libfabric instead of using provided binary', CUSTOM],
+            'ofi_internal': [True, 'Use internal shipped libfabric instead of external libfabric', CUSTOM],
+            'set_mpi_wrappers_compiler': [False, 'Override default compiler used by MPI wrapper commands', CUSTOM],
+            'set_mpi_wrapper_aliases_gcc': [False, 'Set compiler for mpigcc/mpigxx via aliases', CUSTOM],
+            'set_mpi_wrapper_aliases_intel': [False, 'Set compiler for mpiicc/mpiicpc/mpiifort via aliases', CUSTOM],
+            'set_mpi_wrappers_all': [False, 'Set (default) compiler for all MPI wrapper commands', CUSTOM],
+        }
+        return IntelBase.extra_options(extra_vars)
+
+    def prepare_step(self, *args, **kwargs):
+        if LooseVersion(self.version) >= LooseVersion('2017.2.174'):
+            kwargs['requires_runtime_license'] = False
+            super(EB_impi, self).prepare_step(*args, **kwargs)
+        else:
+            super(EB_impi, self).prepare_step(*args, **kwargs)
+
+    def install_step(self):
+        """
+        Actual installation
+        - create silent cfg file
+        - execute command
+        """
+        impiver = LooseVersion(self.version)
+
+        if impiver >= LooseVersion('2021'):
+            super(EB_impi, self).install_step()
+
+        elif impiver >= LooseVersion('4.0.1'):
+            # impi starting from version 4.0.1.x uses standard installation procedure.
+
+            silent_cfg_names_map = {}
+
+            if impiver < LooseVersion('4.1.1'):
+                # since impi v4.1.1, silent.cfg has been slightly changed to be 'more standard'
+                silent_cfg_names_map.update({
+                    'activation_name': ACTIVATION_NAME_2012,
+                    'license_file_name': LICENSE_FILE_NAME_2012,
+                })
+
+            super(EB_impi, self).install_step(silent_cfg_names_map=silent_cfg_names_map)
+
+            # impi v4.1.1 and v5.0.1 installers create impi/<version> subdir, so stuff needs to be moved afterwards
+            if impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'):
+                super(EB_impi, self).move_after_install()
+        else:
+            # impi up until version 4.0.0.x uses custom installation procedure.
+            silent = """[mpi]
+INSTALLDIR=%(ins)s
+LICENSEPATH=%(lic)s
+INSTALLMODE=NONRPM
+INSTALLUSER=NONROOT
+UPDATE_LD_SO_CONF=NO
+PROCEED_WITHOUT_PYTHON=yes
+AUTOMOUNTED_CLUSTER=yes
+EULA=accept
+[mpi-rt]
+INSTALLDIR=%(ins)s
+LICENSEPATH=%(lic)s
+INSTALLMODE=NONRPM
+INSTALLUSER=NONROOT
+UPDATE_LD_SO_CONF=NO
+PROCEED_WITHOUT_PYTHON=yes
+AUTOMOUNTED_CLUSTER=yes
+EULA=accept
+
+""" % {'lic': self.license_file, 'ins': self.installdir}
+
+            # already in correct directory
+            silentcfg = os.path.join(os.getcwd(), "silent.cfg")
+            write_file(silentcfg, silent)
+            self.log.debug("Contents of %s: %s", silentcfg, silent)
+
+            tmpdir = os.path.join(os.getcwd(), self.version, 'mytmpdir')
+            mkdir(tmpdir, parents=True)
+
+            cmd = "./install.sh --tmp-dir=%s --silent=%s" % (tmpdir, silentcfg)
+            run_cmd(cmd, log_all=True, simple=True)
+
+        # recompile libfabric (if requested)
+        # some Intel MPI versions (like 2019 update 6) no longer ship libfabric sources
+        libfabric_path = os.path.join(self.installdir, 'libfabric')
+        if impiver >= LooseVersion('2019') and self.cfg['libfabric_rebuild']:
+            if self.cfg['ofi_internal']:
+                libfabric_src_tgz_fn = 'src.tgz'
+                if os.path.exists(os.path.join(libfabric_path, libfabric_src_tgz_fn)):
+                    change_dir(libfabric_path)
+                    srcdir = extract_file(libfabric_src_tgz_fn, os.getcwd(), change_into_dir=False)
+                    change_dir(srcdir)
+                    libfabric_installpath = os.path.join(self.installdir, 'intel64', 'libfabric')
+
+                    make = 'make'
+                    if self.cfg['parallel']:
+                        make += ' -j %d' % self.cfg['parallel']
+
+                    cmds = [
+                        './configure --prefix=%s %s' % (libfabric_installpath, self.cfg['libfabric_configopts']),
+                        make,
+                        'make install'
+                    ]
+                    for cmd in cmds:
+                        run_cmd(cmd, log_all=True, simple=True)
+                else:
+                    self.log.info("Rebuild of libfabric is requested, but %s does not exist, so skipping...",
+                                  libfabric_src_tgz_fn)
+            else:
+                raise EasyBuildError("Rebuild of libfabric is requested, but ofi_internal is set to False.")
+
+    def post_install_step(self):
+        """Custom post install step for IMPI, fix broken env scripts after moving installed files."""
+        super(EB_impi, self).post_install_step()
+
+        impiver = LooseVersion(self.version)
+
+        if impiver >= LooseVersion('2021'):
+            self.log.info("No post-install action for impi v%s", self.version)
+
+        elif impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'):
+            if impiver >= LooseVersion('2018.0.128'):
+                script_paths = [os.path.join('intel64', 'bin')]
+            else:
+                script_paths = [os.path.join('intel64', 'bin'), os.path.join('mic', 'bin')]
+            # fix broken env scripts after the move
+            regex_subs = [(r"^setenv I_MPI_ROOT.*", r"setenv I_MPI_ROOT %s" % self.installdir)]
+            for script in [os.path.join(script_path, 'mpivars.csh') for script_path in script_paths]:
+                apply_regex_substitutions(os.path.join(self.installdir, script), regex_subs)
+            regex_subs = [(r"^(\s*)I_MPI_ROOT=[^;\n]*", r"\1I_MPI_ROOT=%s" % self.installdir)]
+            for script in [os.path.join(script_path, 'mpivars.sh') for script_path in script_paths]:
+                apply_regex_substitutions(os.path.join(self.installdir, script), regex_subs)
+
+            # fix 'prefix=' in compiler wrapper scripts after moving installation (see install_step)
+            wrappers = ['mpif77', 'mpif90', 'mpigcc', 'mpigxx', 'mpiicc', 'mpiicpc', 'mpiifort']
+            regex_subs = [(r"^prefix=.*", r"prefix=%s" % self.installdir)]
+            for script_dir in script_paths:
+                for wrapper in wrappers:
+                    wrapper_path = os.path.join(self.installdir, script_dir, wrapper)
+                    if os.path.exists(wrapper_path):
+                        apply_regex_substitutions(wrapper_path, regex_subs)
+
+    def sanity_check_step(self):
+        """Custom sanity check paths for IMPI."""
+
+        impi_ver = LooseVersion(self.version)
+
+        suff = '64'
+        if self.cfg['m32']:
+            suff = ''
+
+        mpi_mods = ['mpi.mod']
+        if impi_ver > LooseVersion('4.0'):
+            mpi_mods.extend(['mpi_base.mod', 'mpi_constants.mod', 'mpi_sizeofs.mod'])
+
+        if impi_ver >= LooseVersion('2021'):
+            mpi_subdir = os.path.join('mpi', self.version)
+            bin_dir = os.path.join(mpi_subdir, 'bin')
+            include_dir = os.path.join(mpi_subdir, 'include')
+            lib_dir = os.path.join(mpi_subdir, 'lib', 'release')
+
+        elif impi_ver >= LooseVersion('2019'):
+            bin_dir = os.path.join('intel64', 'bin')
+            include_dir = os.path.join('intel64', 'include')
+            lib_dir = os.path.join('intel64', 'lib', 'release')
+        else:
+            bin_dir = 'bin%s' % suff
+            include_dir = 'include%s' % suff
+            lib_dir = 'lib%s' % suff
+            mpi_mods.extend(['i_malloc.h'])
+
+        shlib_ext = get_shared_lib_ext()
+        custom_paths = {
+            'files': [os.path.join(bin_dir, 'mpi%s' % x) for x in ['icc', 'icpc', 'ifort']] +
+            [os.path.join(include_dir, 'mpi%s.h' % x) for x in ['cxx', 'f', '', 'o', 'of']] +
+            [os.path.join(include_dir, x) for x in mpi_mods] +
+            [os.path.join(lib_dir, 'libmpi.%s' % shlib_ext)] +
+            [os.path.join(lib_dir, 'libmpi.a')],
+            'dirs': [],
+        }
+
+        custom_commands = []
+
+        if build_option('mpi_tests'):
+            if impi_ver >= LooseVersion('2017'):
+                # Add minimal test program to sanity checks
+                if impi_ver >= LooseVersion('2021'):
+                    impi_testsrc = os.path.join(self.installdir, 'mpi', self.version, 'test', 'test.c')
+                else:
+                    impi_testsrc = os.path.join(self.installdir, 'test', 'test.c')
+
+                impi_testexe = os.path.join(self.builddir, 'mpi_test')
+                self.log.info("Adding minimal MPI test program to sanity checks: %s", impi_testsrc)
+
+                # Build test program with appropriate compiler from current toolchain
+                comp_fam = self.toolchain.comp_family()
+                if comp_fam == toolchain.INTELCOMP:
+                    build_comp = 'mpiicc'
+                else:
+                    build_comp = 'mpicc'
+                build_cmd = "%s %s -o %s" % (build_comp, impi_testsrc, impi_testexe)
+
+                # Execute test program with appropriate MPI executable for target toolchain
+                params = {'nr_ranks': self.cfg['parallel'], 'cmd': impi_testexe}
+                mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.INTELMPI, params, mpi_version=self.version)
+
+                custom_commands.extend([
+                    build_cmd,  # build test program
+                    #mpi_cmd_tmpl % params,  # run test program
+                ])
+
+        super(EB_impi, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
+
+    def make_module_req_guess(self):
+        """
+        A dictionary of possible directories to look for
+        """
+        guesses = super(EB_impi, self).make_module_req_guess()
+        if self.cfg['m32']:
+            lib_dirs = ['lib', 'lib/ia32', 'ia32/lib']
+            guesses.update({
+                'PATH': ['bin', 'bin/ia32', 'ia32/bin'],
+                'LD_LIBRARY_PATH': lib_dirs,
+                'LIBRARY_PATH': lib_dirs,
+                'MIC_LD_LIBRARY_PATH': ['mic/lib'],
+            })
+        else:
+            manpath = 'man'
+
+            impi_ver = LooseVersion(self.version)
+            if impi_ver >= LooseVersion('2021'):
+                mpi_subdir = os.path.join('mpi', self.version)
+                lib_dirs = [
+                    os.path.join(mpi_subdir, 'lib'),
+                    os.path.join(mpi_subdir, 'lib', 'release'),
+                    os.path.join(mpi_subdir, 'libfabric', 'lib'),
+                ]
+                include_dirs = [os.path.join(mpi_subdir, 'include')]
+                path_dirs = [
+                    os.path.join(mpi_subdir, 'bin'),
+                    os.path.join(mpi_subdir, 'libfabric', 'bin'),
+                ]
+                manpath = os.path.join(mpi_subdir, 'man')
+
+                if self.cfg['ofi_internal']:
+                    libfabric_dir = os.path.join('mpi', self.version, 'libfabric')
+                    lib_dirs.append(os.path.join(libfabric_dir, 'lib'))
+                    path_dirs.append(os.path.join(libfabric_dir, 'bin'))
+                    guesses['FI_PROVIDER_PATH'] = [os.path.join(libfabric_dir, 'lib', 'prov')]
+
+            elif impi_ver >= LooseVersion('2019'):
+                # The "release" library is default in v2019. Give it precedence over intel64/lib.
+                # (remember paths are *prepended*, so the last path in the list has highest priority)
+                lib_dirs = [os.path.join('intel64', x) for x in ['lib', os.path.join('lib', 'release')]]
+                include_dirs = [os.path.join('intel64', 'include')]
+                path_dirs = [os.path.join('intel64', 'bin')]
+                if self.cfg['ofi_internal']:
+                    lib_dirs.append(os.path.join('intel64', 'libfabric', 'lib'))
+                    path_dirs.append(os.path.join('intel64', 'libfabric', 'bin'))
+                    guesses['FI_PROVIDER_PATH'] = [os.path.join('intel64', 'libfabric', 'lib', 'prov')]
+            else:
+                lib_dirs = [os.path.join('lib', 'em64t'), 'lib64']
+                include_dirs = ['include64']
+                path_dirs = [os.path.join('bin', 'intel64'), 'bin64']
+                guesses['MIC_LD_LIBRARY_PATH'] = [os.path.join('mic', 'lib')]
+
+            guesses.update({
+                'PATH': path_dirs,
+                'LD_LIBRARY_PATH': lib_dirs,
+                'LIBRARY_PATH': lib_dirs,
+                'MANPATH': [manpath],
+                'CPATH': include_dirs,
+            })
+
+        return guesses
+
+    def make_module_extra(self, *args, **kwargs):
+        """Overwritten from Application to add extra txt"""
+
+        if LooseVersion(self.version) >= LooseVersion('2021'):
+            mpiroot = os.path.join(self.installdir, 'mpi', self.version)
+        else:
+            mpiroot = self.installdir
+
+        txt = super(EB_impi, self).make_module_extra(*args, **kwargs)
+        txt += self.module_generator.set_environment('I_MPI_ROOT', mpiroot)
+        if self.cfg['set_mpi_wrappers_compiler'] or self.cfg['set_mpi_wrappers_all']:
+            for var in ['CC', 'CXX', 'F77', 'F90', 'FC']:
+                if var == 'FC':
+                    # $FC isn't defined by EasyBuild framework, so use $F90 instead
+                    src_var = 'F90'
+                else:
+                    src_var = var
+
+                target_var = 'I_MPI_%s' % var
+
+                val = os.getenv(src_var)
+                if val:
+                    txt += self.module_generator.set_environment(target_var, val)
+                else:
+                    raise EasyBuildError("Environment variable $%s not set, can't define $%s", src_var, target_var)
+
+        if self.cfg['set_mpi_wrapper_aliases_gcc'] or self.cfg['set_mpi_wrappers_all']:
+            # force mpigcc/mpigxx to use GCC compilers, as would be expected based on their name
+            txt += self.module_generator.set_alias('mpigcc', 'mpigcc -cc=gcc')
+            txt += self.module_generator.set_alias('mpigxx', 'mpigxx -cxx=g++')
+
+        if self.cfg['set_mpi_wrapper_aliases_intel'] or self.cfg['set_mpi_wrappers_all']:
+            # do the same for mpiicc/mpiipc/mpiifort to be consistent, even if they may not exist
+            txt += self.module_generator.set_alias('mpiicc', 'mpiicc -cc=icc')
+            txt += self.module_generator.set_alias('mpiicpc', 'mpiicpc -cxx=icpc')
+            # -fc also works, but -f90 takes precedence
+            txt += self.module_generator.set_alias('mpiifort', 'mpiifort -f90=ifort')
+
+        # set environment variable UCX_TLS to 'all', this works in all hardware configurations
+        # needed with UCX regardless of the transports available (even without a Mellanox HCA)
+        # more information in easybuilders/easybuild-easyblocks#2253
+        if get_software_root('UCX'):
+            # do not overwrite settings in the easyconfig
+            if 'UCX_TLS' not in self.cfg['modextravars']:
+                txt += self.module_generator.set_environment('UCX_TLS', 'all')
+
+        return txt
diff --git a/easyblocks/o/openmpi.py b/easyblocks/o/openmpi.py
new file mode 100644
index 0000000000000000000000000000000000000000..11870c6730988e741dc365ab035072910ee66d5a
--- /dev/null
+++ b/easyblocks/o/openmpi.py
@@ -0,0 +1,243 @@
+##
+# Copyright 2019-2023 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 <http://www.gnu.org/licenses/>.
+##
+"""
+EasyBuild support for OpenMPI, implemented as an easyblock
+
+@author: Kenneth Hoste (Ghent University)
+@author: Robert Mijakovic (LuxProvide)
+"""
+import os
+import re
+from easybuild.tools import LooseVersion
+
+import easybuild.tools.toolchain as toolchain
+from easybuild.easyblocks.generic.configuremake import ConfigureMake
+from easybuild.framework.easyconfig.constants import EASYCONFIG_CONSTANTS
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.config import build_option
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.systemtools import check_os_dependency, get_shared_lib_ext
+from easybuild.tools.toolchain.mpi import get_mpi_cmd_template
+
+
+class EB_OpenMPI(ConfigureMake):
+    """OpenMPI easyblock."""
+
+    def configure_step(self):
+        """Custom configuration step for OpenMPI."""
+
+        def config_opt_used(key, enable_opt=False):
+            """Helper function to check whether a configure option is already specified in 'configopts'."""
+            if enable_opt:
+                regex = '--(disable|enable)-%s' % key
+            else:
+                regex = '--(with|without)-%s' % key
+
+            return bool(re.search(regex, self.cfg['configopts']))
+
+        config_opt_names = [
+            # suppress failure modes in relation to mpirun path
+            'mpirun-prefix-by-default',
+            # build shared libraries
+            'shared',
+        ]
+
+        for key in config_opt_names:
+            if not config_opt_used(key, enable_opt=True):
+                self.cfg.update('configopts', '--enable-%s' % key)
+
+        # List of EasyBuild dependencies for which OMPI has known options
+        known_dependencies = ('CUDA', 'hwloc', 'libevent', 'libfabric', 'PMIx', 'UCX', 'UCC')
+        # Value to use for `--with-<dep>=<value>` if the dependency is not specified in the easyconfig
+        # No entry is interpreted as no option added at all
+        # This is to make builds reproducible even when the system libraries are changed and avoids failures
+        # due to e.g. finding only PMIx but not libevent on the system
+        unused_dep_value = dict()
+        # Known options since version 3.0 (no earlier ones checked)
+        if LooseVersion(self.version) >= LooseVersion('3.0'):
+            # Default to disable the option with "no"
+            unused_dep_value = {dep: 'no' for dep in known_dependencies}
+            # For these the default is to use an internal copy and not using any is not supported
+            for dep in ('hwloc', 'libevent', 'PMIx'):
+                unused_dep_value[dep] = 'internal'
+
+        # handle dependencies
+        for dep in known_dependencies:
+            opt_name = dep.lower()
+            # If the option is already used, don't add it
+            if config_opt_used(opt_name):
+                continue
+
+            # libfabric option renamed in OpenMPI 3.1.0 to ofi
+            if dep == 'libfabric' and LooseVersion(self.version) >= LooseVersion('3.1'):
+                opt_name = 'ofi'
+                # Check new option name. They are synonyms since 3.1.0 for backward compatibility
+                if config_opt_used(opt_name):
+                    continue
+
+            dep_root = get_software_root(dep)
+            # If the dependency is loaded, specify its path, else use the "unused" value, if any
+            if dep_root:
+                opt_value = dep_root
+            else:
+                opt_value = unused_dep_value.get(dep)
+            if opt_value is not None:
+                self.cfg.update('configopts', '--with-%s=%s' % (opt_name, opt_value))
+
+        if bool(get_software_root('PMIx')) != bool(get_software_root('libevent')):
+            raise EasyBuildError('You must either use both PMIx and libevent as dependencies or none of them. '
+                                 'This is to enforce the same libevent is used for OpenMPI as for PMIx or '
+                                 'the behavior may be unpredictable.')
+
+        # check whether VERBS support should be enabled
+        if not config_opt_used('verbs'):
+
+            # for OpenMPI v4.x, the openib BTL should be disabled when UCX is used;
+            # this is required to avoid "error initializing an OpenFabrics device" warnings,
+            # see also https://www.open-mpi.org/faq/?category=all#ofa-device-error
+            is_ucx_enabled = ('--with-ucx' in self.cfg['configopts'] and
+                              '--with-ucx=no' not in self.cfg['configopts'])
+            if LooseVersion(self.version) >= LooseVersion('4.0.0') and is_ucx_enabled:
+                verbs = False
+            else:
+                # auto-detect based on available OS packages
+                os_packages = EASYCONFIG_CONSTANTS['OS_PKG_IBVERBS_DEV'][0]
+                verbs = any(check_os_dependency(osdep) for osdep in os_packages)
+            # for OpenMPI v5.x, the verbs support is removed, only UCX is available
+            # see https://github.com/open-mpi/ompi/pull/6270
+            if LooseVersion(self.version) <= LooseVersion('5.0.0'):
+                if verbs:
+                    self.cfg.update('configopts', '--with-verbs')
+                else:
+                    self.cfg.update('configopts', '--without-verbs')
+
+        super(EB_OpenMPI, self).configure_step()
+
+    def test_step(self):
+        """Test step for OpenMPI"""
+        # Default to `make check` if nothing is set. Disable with "runtest = False" in the EC
+        if self.cfg['runtest'] is None:
+            self.cfg['runtest'] = 'check'
+
+        super(EB_OpenMPI, self).test_step()
+
+    def load_module(self, *args, **kwargs):
+        """
+        Load (temporary) module file, after resetting to initial environment.
+
+        Also put RPATH wrappers back in place if needed, to ensure that sanity check commands work as expected.
+        """
+        super(EB_OpenMPI, self).load_module(*args, **kwargs)
+
+        # ensure RPATH wrappers are in place, otherwise compiling minimal test programs will fail
+        if build_option('rpath'):
+            if self.toolchain.options.get('rpath', True):
+                self.toolchain.prepare_rpath_wrappers(rpath_filter_dirs=self.rpath_filter_dirs,
+                                                      rpath_include_dirs=self.rpath_include_dirs)
+
+    def sanity_check_step(self):
+        """Custom sanity check for OpenMPI."""
+
+        bin_names = ['mpicc', 'mpicxx', 'mpif90', 'mpifort', 'mpirun', 'ompi_info', 'opal_wrapper']
+        if LooseVersion(self.version) >= LooseVersion('5.0.0'):
+            bin_names.append('prterun')
+        else:
+            bin_names.append('orterun')
+        bin_files = [os.path.join('bin', x) for x in bin_names]
+
+        shlib_ext = get_shared_lib_ext()
+        lib_names = ['mpi_mpifh', 'mpi', 'open-pal']
+        if LooseVersion(self.version) >= LooseVersion('5.0.0'):
+            lib_names.append('prrte')
+        else:
+            lib_names.extend(['ompitrace', 'open-rte'])
+        lib_files = [os.path.join('lib', 'lib%s.%s' % (x, shlib_ext)) for x in lib_names]
+
+        inc_names = ['mpi-ext', 'mpif-config', 'mpif', 'mpi', 'mpi_portable_platform']
+        if LooseVersion(self.version) >= LooseVersion('5.0.0'):
+            inc_names.append('prte')
+        inc_files = [os.path.join('include', x + '.h') for x in inc_names]
+
+        custom_paths = {
+            'files': bin_files + inc_files + lib_files,
+            'dirs': [],
+        }
+
+        # make sure MPI compiler wrappers pick up correct compilers
+        expected = {
+            'mpicc': os.getenv('CC', 'gcc'),
+            'mpicxx': os.getenv('CXX', 'g++'),
+            'mpifort': os.getenv('FC', 'gfortran'),
+            'mpif90': os.getenv('F90', 'gfortran'),
+        }
+        # actual pattern for gfortran is "GNU Fortran"
+        for key in ['mpifort', 'mpif90']:
+            if expected[key] == 'gfortran':
+                expected[key] = "GNU Fortran"
+        # for PGI, correct pattern is "pgfortran" with mpif90
+        if expected['mpif90'] == 'pgf90':
+            expected['mpif90'] = 'pgfortran'
+        # for Clang the pattern is always clang
+        for key in ['mpicxx', 'mpifort', 'mpif90']:
+            if expected[key] in ['clang++', 'flang']:
+                expected[key] = 'clang'
+
+        custom_commands = ["%s --version | grep '%s'" % (key, expected[key]) for key in sorted(expected.keys())]
+
+        # Add minimal test program to sanity checks
+        # Run with correct MPI launcher
+        mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.OPENMPI, dict(), mpi_version=self.version)
+        # Limit number of ranks to 8 to avoid it failing due to hyperthreading
+        ranks = min(8, self.cfg['parallel'])
+        for srcdir, src, compiler in (
+            ('examples', 'hello_c.c', 'mpicc'),
+            ('examples', 'hello_mpifh.f', 'mpifort'),
+            ('examples', 'hello_usempi.f90', 'mpif90'),
+            ('examples', 'ring_c.c', 'mpicc'),
+            ('examples', 'ring_mpifh.f', 'mpifort'),
+            #('examples', 'ring_usempi.f90', 'mpif90'),
+            ('test/simple', 'thread_init.c', 'mpicc'),
+            ('test/simple', 'intercomm1.c', 'mpicc'),
+            ('test/simple', 'mpi_barrier.c', 'mpicc'),
+        ):
+            src_path = os.path.join(self.cfg['start_dir'], srcdir, src)
+            if os.path.exists(src_path):
+                test_exe = os.path.join(self.builddir, 'mpi_test_' + os.path.splitext(src)[0])
+                self.log.info("Adding minimal MPI test program to sanity checks: %s", test_exe)
+
+                # Build test binary
+                custom_commands.append("%s %s -o %s" % (compiler, src_path, test_exe))
+
+                # Run the test if chosen
+                if build_option('mpi_tests'):
+                    params.update({'nr_ranks': ranks, 'cmd': test_exe})
+                    # Allow oversubscription for this test (in case of hyperthreading)
+                    custom_commands.append("OMPI_MCA_rmaps_base_oversubscribe=1 " + mpi_cmd_tmpl % params)
+                    # Run with 1 process which may trigger other bugs
+                    # See https://github.com/easybuilders/easybuild-easyconfigs/issues/12978
+                    params['nr_ranks'] = 1
+                    custom_commands.append(mpi_cmd_tmpl % params)
+
+        super(EB_OpenMPI, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
diff --git a/easyblocks/o/orca.py b/easyblocks/o/orca.py
new file mode 100644
index 0000000000000000000000000000000000000000..67b786e8d0be80ab2cedec1b53ed83db7c2cf1a3
--- /dev/null
+++ b/easyblocks/o/orca.py
@@ -0,0 +1,177 @@
+##
+# Copyright 2021-2024 Vrije Universiteit Brussel
+#
+# 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 <http://www.gnu.org/licenses/>.
+##
+"""
+EasyBuild support for ORCA, implemented as an easyblock
+
+@author: Alex Domingo (Vrije Universiteit Brussel)
+"""
+import glob
+import os
+
+from easybuild.tools import LooseVersion
+from easybuild.easyblocks.generic.makecp import MakeCp
+from easybuild.easyblocks.generic.packedbinary import PackedBinary
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.filetools import write_file
+from easybuild.tools.py2vs3 import string_type
+from easybuild.tools.systemtools import X86_64, get_cpu_architecture
+
+
+class EB_ORCA(PackedBinary, MakeCp):
+    """
+    ORCA installation files are extracted and placed in standard locations using 'files_to_copy' from MakeCp.
+    Sanity checks on files are automatically generated based on the contents of 'files_to_copy' by gathering
+    the target files in the build directory and checking their presence in the installation directory.
+    Sanity checks also include a quick test calculating the HF energy of a water molecule.
+    """
+
+    @staticmethod
+    def extra_options(extra_vars=None):
+        """Extra easyconfig parameters for ORCA."""
+        extra_vars = MakeCp.extra_options()
+        extra_vars.update(PackedBinary.extra_options())
+
+        # files_to_copy is not mandatory here, since we set it by default in install_step
+        extra_vars['files_to_copy'][2] = CUSTOM
+
+        return extra_vars
+
+    def __init__(self, *args, **kwargs):
+        """Init and validate easyconfig parameters and system architecture"""
+        super(EB_ORCA, self).__init__(*args, **kwargs)
+
+        # If user overwrites 'files_to_copy', custom 'sanity_check_paths' must be present
+        if self.cfg['files_to_copy'] and not self.cfg['sanity_check_paths']:
+            raise EasyBuildError("Found 'files_to_copy' option in easyconfig without 'sanity_check_paths'")
+
+        # Add orcaarch template for supported architectures
+        myarch = get_cpu_architecture()
+        if myarch == X86_64:
+            orcaarch = 'x86-64'
+        else:
+            raise EasyBuildError("Architecture %s is not supported by ORCA on EasyBuild", myarch)
+
+        self.cfg.template_values['orcaarch'] = orcaarch
+        self.cfg.generate_template_values()
+
+    def install_step(self):
+        """Install ORCA with MakeCp easyblock"""
+
+        if not self.cfg['files_to_copy']:
+            # Put installation files in standard locations
+            files_to_copy = [
+                (['auto*', 'orca*', 'otool*'], 'bin'),
+                (['*.pdf'], 'share'),
+            ]
+            # Version 5 extra files
+            if LooseVersion('5.0.0') <= LooseVersion(self.version) < LooseVersion('6.0.0'):
+                compoundmethods = (['ORCACompoundMethods'], 'bin')
+                files_to_copy.append(compoundmethods)
+            # Shared builds have additional libraries
+            libs_to_copy = (['liborca*'], 'lib')
+            if all([glob.glob(p) for p in libs_to_copy[0]]):
+                files_to_copy.append(libs_to_copy)
+
+            self.cfg['files_to_copy'] = files_to_copy
+
+        MakeCp.install_step(self)
+
+    def sanity_check_step(self):
+        """Custom sanity check for ORCA"""
+        custom_paths = None
+
+        if not self.cfg['sanity_check_paths']:
+            custom_paths = {'files': [], 'dirs': []}
+
+            if self.cfg['files_to_copy']:
+                # Convert 'files_to_copy' to list of files in build directory
+                for spec in self.cfg['files_to_copy']:
+                    if isinstance(spec, tuple):
+                        file_pattern = spec[0]
+                        dest_dir = spec[1]
+                    elif isinstance(spec, string_type):
+                        file_pattern = spec
+                        dest_dir = ''
+                    else:
+                        raise EasyBuildError(
+                            "Found neither string nor tuple as file to copy: '%s' (type %s)", spec, type(spec)
+                        )
+
+                    if isinstance(file_pattern, string_type):
+                        file_pattern = [file_pattern]
+
+                    source_files = []
+                    for pattern in file_pattern:
+                        source_files.extend(glob.glob(pattern))
+
+                    # Add files to custom sanity checks
+                    for source in source_files:
+                        if os.path.isfile(source):
+                            custom_paths['files'].append(os.path.join(dest_dir, source))
+                        else:
+                            custom_paths['dirs'].append(os.path.join(dest_dir, source))
+            else:
+                # Minimal check of files (needed by --module-only)
+                custom_paths['files'] = ['bin/orca']
+
+#        # Simple test: HF energy of water molecule
+#        test_input_content = """
+#!HF DEF2-SVP
+#%%PAL NPROCS %(nprocs)s END
+#* xyz 0 1
+#O   0.0000   0.0000   0.0626
+#H  -0.7920   0.0000  -0.4973
+#H   0.7920   0.0000  -0.4973
+#*
+#"""
+#        nprocs = self.cfg.get('parallel', 1)
+#        test_input_content = test_input_content % {'nprocs': nprocs}
+#        test_input_path = os.path.join(self.builddir, 'eb_test_hf_water.inp')
+#        write_file(test_input_path, test_input_content)
+#
+#        # Reference total energy
+#        test_output_energy = '-75.95934031'
+#        test_output_regex = 'FINAL SINGLE POINT ENERGY[ \t]*%s' % test_output_energy
+#
+#        # Instruct openmpi to treat hardware threads as slot
+#        test_ompi_env = 'env OMPI_MCA_hwloc_base_use_hwthreads_as_cpus=1'
+#
+#        # ORCA has to be executed using its full path to run in parallel
+#        if os.path.isdir(os.path.join(self.installdir, 'bin')):
+#            orca_bin = '$EBROOTORCA/bin/orca'
+#        else:
+#            orca_bin = '$(which orca)'
+#
+#        test_orca_cmd = "%s %s %s" % (test_ompi_env, orca_bin, test_input_path)
+#
+#        custom_commands = [
+#            # Execute test in ORCA
+#            test_orca_cmd,
+#            # Repeat test and check total energy
+#            "%s | grep -c '%s'" % (test_orca_cmd, test_output_regex),
+#        ]
+#
+#        super(EB_ORCA, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
diff --git a/easyblocks/v/visit.py b/easyblocks/v/visit.py
index 47f1c18e435b8e578519249f0578a9415d70938d..0efa00e2fb6c1a108788699e8c1a92a38ab8e431 100644
--- a/easyblocks/v/visit.py
+++ b/easyblocks/v/visit.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 """
-EasyBuild support for building and installing VisIt 3.1.0,
+EasyBuild support for building and installing VisIt 3.3.3,
 implemented as an easyblock.
 
 @author: Lukas Krupcik (IT4Innovations)
@@ -31,9 +31,11 @@ class EB_VisIt(EasyBlock):
         """Simply run installation script with configuration options"""
         self.log.info("Changing VisIt installer permission")
         os.chdir(self.cfg['start_dir'])
-        chmod_cmd = "chmod 755 visit-install3_1_0"
+        #chmod_cmd = "chmod 755 visit-install3_3_3"
+        chmod_cmd = "chmod 755 visit-install2_13_3"
         run_cmd(chmod_cmd, log_all=True)
-        install_cmd = "./visit-install3_1_0 -c none 3.1.0 \
+        #install_cmd = "./visit-install3_3_3 -c none 3.3.3 \
+        install_cmd = "./visit-install2_13_3 -c none 2.13.3 \
                        linux-x86_64-rhel7 %s" % self.installdir
         self.log.info("Running VisIt installer")
         run_cmd(install_cmd, log_all=True)
diff --git a/w/wrf_sfire.py b/w/wrf_sfire.py
new file mode 100644
index 0000000000000000000000000000000000000000..29f2058d932444a00292655d49128a6d9f1b3cfd
--- /dev/null
+++ b/w/wrf_sfire.py
@@ -0,0 +1,233 @@
+##
+# Copyright 2009-2023 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 <http://www.gnu.org/licenses/>.
+##
+"""
+EasyBuild support for building and installing WRF-Fire, implemented as an easyblock
+
+author: Kenneth Hoste (HPC-UGent)
+"""
+import os
+
+import easybuild.tools.environment as env
+import easybuild.tools.toolchain as toolchain
+from easybuild.framework.easyblock import EasyBlock
+from easybuild.framework.easyconfig import CUSTOM, MANDATORY
+from easybuild.tools.filetools import apply_regex_substitutions, change_dir, patch_perl_script_autoflush
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.run import run_cmd, run_cmd_qa
+from easybuild.tools.build_log import EasyBuildError
+
+
+class EB_WRF_minus_Sfire(EasyBlock):
+    """Support for building/installing WRF-Sfire."""
+
+    @staticmethod
+    def extra_options():
+        """Custom easyconfig parameters for WRF-Sfire."""
+        extra_vars = {
+            'buildtype': [None, "Specify the type of build (serial, smpar (OpenMP), "
+                                "dmpar (MPI), dm+sm (hybrid OpenMP/MPI)).", MANDATORY],
+            'runtest': [True, "Build and run WRF tests", CUSTOM],
+        }
+        return EasyBlock.extra_options(extra_vars)
+
+    def __init__(self, *args, **kwargs):
+        """Add extra config options specific to WRF."""
+        super(EB_WRF_minus_Sfire, self).__init__(*args, **kwargs)
+
+        self.build_in_installdir = True
+
+    def extract_step(self):
+        """Extract WRF-Sfire sources."""
+        self.cfg.update('unpack_options', '--strip-components=1')
+        super(EB_WRF_minus_Sfire, self).extract_step()
+
+    def configure_step(self):
+        """Custom configuration procedure for WRF-Sfire."""
+
+        comp_fam = self.toolchain.comp_family()
+
+        # define $NETCDF* for netCDF dependency
+        netcdf_fortran = get_software_root('netCDF-Fortran')
+        if netcdf_fortran:
+            env.setvar('NETCDF', netcdf_fortran)
+        else:
+            raise EasyBuildError("Required dependendy netCDF-Fortran is missing")
+
+        # define $PHDF5 for parallel HDF5 dependency
+        hdf5 = get_software_root('HDF5')
+        if hdf5 and os.path.exists(os.path.join(hdf5, 'bin', 'h5pcc')):
+            env.setvar('PHDF5', hdf5)
+
+        # first, configure WRF part
+        change_dir(os.path.join(self.cfg['start_dir'], 'WRFV3'))
+
+        # instruct WRF-Sfire to create netCDF v4 output files
+        env.setvar('WRFIO_NETCDF4_FILE_SUPPORT', '1')
+
+        # patch arch/Config_new.pl script, so that run_cmd_qa receives all output to answer questions
+        patch_perl_script_autoflush(os.path.join('arch', 'Config_new.pl'))
+
+        # determine build type option to look for
+        known_build_type_options = {
+            toolchain.INTELCOMP: "Linux x86_64 i486 i586 i686, ifort compiler with icc",
+            toolchain.GCC: "x86_64 Linux, gfortran compiler with gcc",
+            toolchain.PGI: "Linux x86_64, PGI compiler with pgcc",
+        }
+        build_type_option = known_build_type_options.get(comp_fam)
+        if build_type_option is None:
+            raise EasyBuildError("Don't know which WPS configure option to select for compiler family %s", comp_fam)
+
+        build_type_question = r"\s*(?P<nr>[0-9]+).\s*%s\s*\(%s\)" % (build_type_option, self.cfg['buildtype'])
+        qa = {
+            "Compile for nesting? (1=basic, 2=preset moves, 3=vortex following) [default 1]:": '1',
+        }
+        std_qa = {
+            # named group in match will be used to construct answer
+            r"%s.*\n(.*\n)*Enter selection\s*\[[0-9]+-[0-9]+\]\s*:" % build_type_question: '%(nr)s',
+        }
+        run_cmd_qa('./configure', qa, std_qa=std_qa, log_all=True, simple=True)
+
+        cpp_flag = None
+        if comp_fam == toolchain.INTELCOMP:
+            cpp_flag = '-fpp'
+        elif comp_fam == toolchain.GCC:
+            cpp_flag = '-cpp'
+        else:
+            raise EasyBuildError("Don't know which flag to use to specify that Fortran files were preprocessed")
+
+        # patch configure.wrf to get things right
+        comps = {
+            'CFLAGS_LOCAL': os.getenv('CFLAGS'),
+            'DM_FC': os.getenv('MPIF90'),
+            'DM_CC': "%s -DMPI2_SUPPORT" % os.getenv('MPICC'),
+            'FCOPTIM': os.getenv('FFLAGS'),
+            # specify that Fortran files have been preprocessed with cpp,
+            # see http://forum.wrfforum.com/viewtopic.php?f=5&t=6086
+            'FORMAT_FIXED': "-FI %s" % cpp_flag,
+            'FORMAT_FREE': "-FR %s" % cpp_flag,
+        }
+        regex_subs = [(r"^(%s\s*=\s*).*$" % k, r"\1 %s" % v) for (k, v) in comps.items()]
+        apply_regex_substitutions('configure.wrf', regex_subs)
+
+        # also configure WPS part
+        change_dir(os.path.join(self.cfg['start_dir'], 'WPS'))
+
+        # patch arch/Config_new.pl script, so that run_cmd_qa receives all output to answer questions
+        patch_perl_script_autoflush(os.path.join('arch', 'Config.pl'))
+
+        # determine build type option to look for
+        known_build_type_options = {
+            toolchain.INTELCOMP: "PC Linux x86_64, Intel compiler",
+            toolchain.GCC: "PC Linux x86_64, g95 compiler",
+            toolchain.PGI: "PC Linux x86_64 (IA64 and Opteron), PGI compiler 5.2 or higher",
+        }
+        build_type_option = known_build_type_options.get(comp_fam)
+        if build_type_option is None:
+            raise EasyBuildError("Don't know which WPS configure option to select for compiler family %s", comp_fam)
+
+        known_wps_build_types = {
+            'dmpar': 'DM parallel',
+            'smpar': 'serial',
+        }
+        wps_build_type = known_wps_build_types.get(self.cfg['buildtype'])
+        if wps_build_type is None:
+            raise EasyBuildError("Don't know which WPS build type to pick for '%s'", self.cfg['builddtype'])
+
+        build_type_question = r"\s*(?P<nr>[0-9]+).\s*%s.*%s(?!NO GRIB2)" % (build_type_option, wps_build_type)
+        std_qa = {
+            # named group in match will be used to construct answer
+            r"%s.*\n(.*\n)*Enter selection\s*\[[0-9]+-[0-9]+\]\s*:" % build_type_question: '%(nr)s',
+        }
+        run_cmd_qa('./configure', {}, std_qa=std_qa, log_all=True, simple=True)
+
+        # patch configure.wps to get things right
+        comps = {
+            'CC': '%s %s' % (os.getenv('MPICC'), os.getenv('CFLAGS')),
+            'FC': '%s %s' % (os.getenv('MPIF90'), os.getenv('F90FLAGS'))
+        }
+        regex_subs = [(r"^(%s\s*=\s*).*$" % k, r"\1 %s" % v) for (k, v) in comps.items()]
+        # specify that Fortran90 files have been preprocessed with cpp
+        regex_subs.extend([
+            (r"^(F77FLAGS\s*=\s*)", r"\1 %s " % cpp_flag),
+            (r"^(FFLAGS\s*=\s*)", r"\1 %s " % cpp_flag),
+        ])
+        apply_regex_substitutions('configure.wps', regex_subs)
+
+    def build_step(self):
+        """Custom build procedure for WRF-Sfire."""
+
+        cmd = './compile'
+        if self.cfg['parallel']:
+            cmd += " -j %d" % self.cfg['parallel']
+
+        # first, build WRF part
+        change_dir(os.path.join(self.cfg['start_dir'], 'WRFV3'))
+        (out, ec) = run_cmd(cmd + ' em_fire', log_all=True, simple=False, log_ok=True)
+
+        # next, build WPS part
+        change_dir(os.path.join(self.cfg['start_dir'], 'WPS'))
+        (out, ec) = run_cmd('./compile', log_all=True, simple=False, log_ok=True)
+
+    def test_step(self):
+        """Custom built-in test procedure for WRF-Sfire."""
+        if self.cfg['runtest']:
+            change_dir(os.path.join(self.cfg['start_dir'], 'WRFV3', 'test', 'em_fire', 'hill'))
+
+            if self.cfg['buildtype'] in ['dmpar', 'smpar', 'dm+sm']:
+                test_cmd = "ulimit -s unlimited && %s && %s" % (self.toolchain.mpi_cmd_for("./ideal.exe", 1),
+                                                                self.toolchain.mpi_cmd_for("./wrf.exe", 2))
+            else:
+                test_cmd = "ulimit -s unlimited && ./ideal.exe && ./wrf.exe"
+            run_cmd(test_cmd, simple=True, log_all=True, log_ok=True)
+
+    # building/installing is done in build_step, so we can run tests
+    def install_step(self):
+        """Building was done in install dir, so nothing to do in install_step."""
+        pass
+
+    def sanity_check_step(self):
+        """Custom sanity check for WRF-Sfire."""
+        custom_paths = {
+            'files': [os.path.join('WRFV3', 'main', f) for f in ['ideal.exe', 'libwrflib.a', 'wrf.exe']] +
+            [os.path.join('WPS', f) for f in ['geogrid.exe', 'metgrid.exe', 'ungrib.exe']],
+            'dirs': [os.path.join('WRFV3', d) for d in ['main', 'run']],
+        }
+        super(EB_WRF_minus_Sfire, self).sanity_check_step(custom_paths=custom_paths)
+
+    def make_module_req_guess(self):
+        """Custom guesses for generated WRF-Sfire module file."""
+        wrf_maindir = os.path.join('WRFV3', 'main')
+        return {
+            'LD_LIBRARY_PATH': [wrf_maindir],
+            'PATH': [wrf_maindir, 'WPS'],
+        }
+
+    def make_module_extra(self):
+        """Add netCDF environment variables to module file."""
+        txt = super(EB_WRF_minus_Sfire, self).make_module_extra()
+        netcdf_fortran = get_software_root('netCDF-Fortran')
+        if netcdf_fortran:
+            txt += self.module_generator.set_environment('NETCDF', netcdf_fortran)
+        return txt