We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
intel-compiler fails sanity check on Debian/Ubuntu
With the recent changes to gcc easyblock #3254 and the older change to intel_compiler easyblock #1237 and its followups, intel-compiler now fails sanity check due to an incorrect module file being generated.

```
multiarch_inc_dir, ec = run_cmd("gcc -E -Wp,-v -xc /dev/null 2>&1 | grep %s$" % multiarch_out)
```
returns
```
easybuild@b-cn1615:~$ gcc -E -Wp,-v -xc /dev/null 2>&1 | grep  x86_64-linux-gnu'$'
 /cvmfs/ebsw.hpc2n.umu.se/amd64_ubuntu2204_icelake/software/GCCcore/13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed/x86_64-linux-gnu
 /usr/include/x86_64-linux-gnu
```

resulting in an malformed CPATH being added to the module file:
```
append_path("CPATH", "/cvmfs/ebsw.hpc2n.umu.se/amd64_ubuntu2204_icelake/software/GCCcore/13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed/x86_64-linux-gnu
 /usr/include/x86_64-linux-gnu")
```

Simple fix is to do ```grep -v GCCcore``` at the and of the command.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `easybuild/easyblocks/i/intel_compilers.py`
Content:
```
1 # #
2 # Copyright 2021-2024 Ghent University
3 #
4 # This file is part of EasyBuild,
5 # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
6 # with support of Ghent University (http://ugent.be/hpc),
7 # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
8 # Flemish Research Foundation (FWO) (http://www.fwo.be/en)
9 # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
10 #
11 # https://github.com/easybuilders/easybuild
12 #
13 # EasyBuild is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation v2.
16 #
17 # EasyBuild is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
24 # #
25 """
26 EasyBuild support for installing Intel compilers, implemented as an easyblock
27 
28 @author: Kenneth Hoste (Ghent University)
29 """
30 import os
31 from easybuild.tools import LooseVersion
32 
33 from easybuild.easyblocks.generic.intelbase import IntelBase
34 from easybuild.easyblocks.t.tbb import get_tbb_gccprefix
35 from easybuild.tools.build_log import EasyBuildError, print_msg
36 from easybuild.tools.run import run_cmd
37 
38 
39 class EB_intel_minus_compilers(IntelBase):
40     """
41     Support for installing Intel compilers, starting with verion 2021.x (oneAPI)
42     """
43 
44     def __init__(self, *args, **kwargs):
45         """
46         Easyblock constructor: check version
47         """
48         super(EB_intel_minus_compilers, self).__init__(*args, **kwargs)
49 
50         # this easyblock is only valid for recent versions of the Intel compilers (2021.x, oneAPI)
51         if LooseVersion(self.version) < LooseVersion('2021'):
52             raise EasyBuildError("Invalid version %s, should be >= 2021.x" % self.version)
53 
54     @property
55     def compilers_subdir(self):
56         compilers_subdir = self.get_versioned_subdir('compiler')
57         if LooseVersion(self.version) < LooseVersion('2024'):
58             compilers_subdir = os.path.join(compilers_subdir, 'linux')
59         return compilers_subdir
60 
61     @property
62     def tbb_subdir(self):
63         return self.get_versioned_subdir('tbb')
64 
65     def prepare_step(self, *args, **kwargs):
66         """
67         Prepare environment for installing.
68 
69         Specify that oneAPI versions of Intel compilers don't require a runtime license.
70         """
71         # avoid that IntelBase trips over not having license info specified
72         kwargs['requires_runtime_license'] = False
73 
74         super(EB_intel_minus_compilers, self).prepare_step(*args, **kwargs)
75 
76     def configure_step(self):
77         """Configure installation."""
78 
79         # redefine $HOME for install step, to avoid that anything is stored in $HOME/intel
80         # (like the 'installercache' database)
81         self.cfg['preinstallopts'] += " HOME=%s " % self.builddir
82 
83     def install_step(self):
84         """
85         Install step: install each 'source file' one by one.
86         Installing the Intel compilers could be done via a single installation file (HPC Toolkit),
87         or with separate installation files (patch releases of the C++ and Fortran compilers).
88         """
89         srcs = self.src[:]
90         cnt = len(srcs)
91         for idx, src in enumerate(srcs):
92             print_msg("installing part %d/%s (%s)..." % (idx + 1, cnt, src['name']))
93             self.src = [src]
94             super(EB_intel_minus_compilers, self).install_step()
95 
96     def sanity_check_step(self):
97         """
98         Custom sanity check for Intel compilers.
99         """
100 
101         oneapi_compiler_cmds = [
102             'dpcpp',  # Intel oneAPI Data Parallel C++ compiler
103             'icx',  # oneAPI Intel C compiler
104             'icpx',  # oneAPI Intel C++ compiler
105             'ifx',  # oneAPI Intel Fortran compiler
106         ]
107         bindir = os.path.join(self.compilers_subdir, 'bin')
108         oneapi_compiler_paths = [os.path.join(bindir, x) for x in oneapi_compiler_cmds]
109         if LooseVersion(self.version) >= LooseVersion('2024'):
110             classic_compiler_cmds = ['ifort']
111             classic_bindir = bindir
112         else:
113             classic_compiler_cmds = ['icc', 'icpc', 'ifort']
114             classic_bindir = os.path.join(bindir, 'intel64')
115         classic_compiler_paths = [os.path.join(classic_bindir, x) for x in classic_compiler_cmds]
116 
117         custom_paths = {
118             'files': classic_compiler_paths + oneapi_compiler_paths,
119             'dirs': [self.compilers_subdir],
120         }
121 
122         all_compiler_cmds = classic_compiler_cmds + oneapi_compiler_cmds
123         custom_commands = ["which %s" % c for c in all_compiler_cmds]
124 
125         # only for 2021.x versions do all compiler commands have the expected version;
126         # for example: for 2022.0.1, icc has version 2021.5.0, icpx has 2022.0.0
127         if LooseVersion(self.version) >= LooseVersion('2022.0'):
128             custom_commands.extend("%s --version" % c for c in all_compiler_cmds)
129         else:
130             custom_commands.extend("%s --version | grep %s" % (c, self.version) for c in all_compiler_cmds)
131 
132         super(EB_intel_minus_compilers, self).sanity_check_step(custom_paths=custom_paths,
133                                                                 custom_commands=custom_commands)
134 
135     def make_module_req_guess(self):
136         """
137         Paths to consider for prepend-paths statements in module file
138         """
139         libdirs = [
140             'lib',
141             os.path.join('lib', 'x64'),
142             os.path.join('compiler', 'lib', 'intel64_lin'),
143         ]
144         libdirs = [os.path.join(self.compilers_subdir, x) for x in libdirs]
145         tbb_subdir = self.tbb_subdir
146         tbb_libsubdir = os.path.join(tbb_subdir, 'lib', 'intel64')
147         libdirs.append(os.path.join(tbb_libsubdir,
148                                     get_tbb_gccprefix(os.path.join(self.installdir, tbb_libsubdir))))
149         guesses = {
150             'PATH': [
151                 os.path.join(self.compilers_subdir, 'bin'),
152                 os.path.join(self.compilers_subdir, 'bin', 'intel64'),
153             ],
154             'LD_LIBRARY_PATH': libdirs,
155             'LIBRARY_PATH': libdirs,
156             'MANPATH': [
157                 os.path.join(os.path.dirname(self.compilers_subdir), 'documentation', 'en', 'man', 'common'),
158                 os.path.join(self.compilers_subdir, 'share', 'man'),
159             ],
160             'OCL_ICD_FILENAMES': [
161                 os.path.join(self.compilers_subdir, 'lib', 'x64', 'libintelocl.so'),
162                 os.path.join(self.compilers_subdir, 'lib', 'libintelocl.so'),
163             ],
164             'CPATH': [
165                 os.path.join(tbb_subdir, 'include'),
166             ],
167             'TBBROOT': [tbb_subdir],
168         }
169         return guesses
170 
171     def make_module_extra(self):
172         """Additional custom variables for intel-compiler"""
173         txt = super(EB_intel_minus_compilers, self).make_module_extra()
174 
175         # On Debian/Ubuntu, /usr/include/x86_64-linux-gnu, or whatever dir gcc uses, needs to be included
176         # in $CPATH for Intel C compiler
177         multiarch_out, ec = run_cmd("gcc -print-multiarch", simple=False)
178         multiarch_out = multiarch_out.strip()
179         if ec == 0 and multiarch_out:
180             multiarch_inc_dir, ec = run_cmd("gcc -E -Wp,-v -xc /dev/null 2>&1 | grep %s$" % multiarch_out)
181             if ec == 0 and multiarch_inc_dir:
182                 multiarch_inc_dir = multiarch_inc_dir.strip()
183                 self.log.info("Adding multiarch include path %s to $CPATH in generated module file", multiarch_inc_dir)
184                 # system location must be appended at the end, so use append_paths
185                 txt += self.module_generator.append_paths('CPATH', [multiarch_inc_dir], allow_abs=True)
186 
187         return txt
188
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/easybuild/easyblocks/i/intel_compilers.py b/easybuild/easyblocks/i/intel_compilers.py
--- a/easybuild/easyblocks/i/intel_compilers.py
+++ b/easybuild/easyblocks/i/intel_compilers.py
@@ -177,7 +177,12 @@
         multiarch_out, ec = run_cmd("gcc -print-multiarch", simple=False)
         multiarch_out = multiarch_out.strip()
         if ec == 0 and multiarch_out:
-            multiarch_inc_dir, ec = run_cmd("gcc -E -Wp,-v -xc /dev/null 2>&1 | grep %s$" % multiarch_out)
+            multi_arch_inc_dir_cmd = '|'.join([
+                "gcc -E -Wp,-v -xc /dev/null 2>&1",
+                "grep %s$" % multiarch_out,
+                "grep -v /include-fixed/",
+            ])
+            multiarch_inc_dir, ec = run_cmd(multi_arch_inc_dir_cmd)
             if ec == 0 and multiarch_inc_dir:
                 multiarch_inc_dir = multiarch_inc_dir.strip()
                 self.log.info("Adding multiarch include path %s to $CPATH in generated module file", multiarch_inc_dir)

{"golden_diff": "diff --git a/easybuild/easyblocks/i/intel_compilers.py b/easybuild/easyblocks/i/intel_compilers.py\n--- a/easybuild/easyblocks/i/intel_compilers.py\n+++ b/easybuild/easyblocks/i/intel_compilers.py\n@@ -177,7 +177,12 @@\n         multiarch_out, ec = run_cmd(\"gcc -print-multiarch\", simple=False)\n         multiarch_out = multiarch_out.strip()\n         if ec == 0 and multiarch_out:\n-            multiarch_inc_dir, ec = run_cmd(\"gcc -E -Wp,-v -xc /dev/null 2>&1 | grep %s$\" % multiarch_out)\n+            multi_arch_inc_dir_cmd = '|'.join([\n+                \"gcc -E -Wp,-v -xc /dev/null 2>&1\",\n+                \"grep %s$\" % multiarch_out,\n+                \"grep -v /include-fixed/\",\n+            ])\n+            multiarch_inc_dir, ec = run_cmd(multi_arch_inc_dir_cmd)\n             if ec == 0 and multiarch_inc_dir:\n                 multiarch_inc_dir = multiarch_inc_dir.strip()\n                 self.log.info(\"Adding multiarch include path %s to $CPATH in generated module file\", multiarch_inc_dir)\n", "issue": "intel-compiler fails sanity check on Debian/Ubuntu\nWith the recent changes to gcc easyblock #3254 and the older change to intel_compiler easyblock #1237 and its followups, intel-compiler now fails sanity check due to an incorrect module file being generated.\r\n\r\n```\r\nmultiarch_inc_dir, ec = run_cmd(\"gcc -E -Wp,-v -xc /dev/null 2>&1 | grep %s$\" % multiarch_out)\r\n```\r\nreturns\r\n```\r\neasybuild@b-cn1615:~$ gcc -E -Wp,-v -xc /dev/null 2>&1 | grep  x86_64-linux-gnu'$'\r\n /cvmfs/ebsw.hpc2n.umu.se/amd64_ubuntu2204_icelake/software/GCCcore/13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed/x86_64-linux-gnu\r\n /usr/include/x86_64-linux-gnu\r\n```\r\n\r\nresulting in an malformed CPATH being added to the module file:\r\n```\r\nappend_path(\"CPATH\", \"/cvmfs/ebsw.hpc2n.umu.se/amd64_ubuntu2204_icelake/software/GCCcore/13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed/x86_64-linux-gnu\r\n /usr/include/x86_64-linux-gnu\")\r\n```\r\n\r\nSimple fix is to do ```grep -v GCCcore``` at the and of the command.\n", "before_files": [{"content": "# #\n# Copyright 2021-2024 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n# #\n\"\"\"\nEasyBuild support for installing Intel compilers, implemented as an easyblock\n\n@author: Kenneth Hoste (Ghent University)\n\"\"\"\nimport os\nfrom easybuild.tools import LooseVersion\n\nfrom easybuild.easyblocks.generic.intelbase import IntelBase\nfrom easybuild.easyblocks.t.tbb import get_tbb_gccprefix\nfrom easybuild.tools.build_log import EasyBuildError, print_msg\nfrom easybuild.tools.run import run_cmd\n\n\nclass EB_intel_minus_compilers(IntelBase):\n    \"\"\"\n    Support for installing Intel compilers, starting with verion 2021.x (oneAPI)\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Easyblock constructor: check version\n        \"\"\"\n        super(EB_intel_minus_compilers, self).__init__(*args, **kwargs)\n\n        # this easyblock is only valid for recent versions of the Intel compilers (2021.x, oneAPI)\n        if LooseVersion(self.version) < LooseVersion('2021'):\n            raise EasyBuildError(\"Invalid version %s, should be >= 2021.x\" % self.version)\n\n    @property\n    def compilers_subdir(self):\n        compilers_subdir = self.get_versioned_subdir('compiler')\n        if LooseVersion(self.version) < LooseVersion('2024'):\n            compilers_subdir = os.path.join(compilers_subdir, 'linux')\n        return compilers_subdir\n\n    @property\n    def tbb_subdir(self):\n        return self.get_versioned_subdir('tbb')\n\n    def prepare_step(self, *args, **kwargs):\n        \"\"\"\n        Prepare environment for installing.\n\n        Specify that oneAPI versions of Intel compilers don't require a runtime license.\n        \"\"\"\n        # avoid that IntelBase trips over not having license info specified\n        kwargs['requires_runtime_license'] = False\n\n        super(EB_intel_minus_compilers, self).prepare_step(*args, **kwargs)\n\n    def configure_step(self):\n        \"\"\"Configure installation.\"\"\"\n\n        # redefine $HOME for install step, to avoid that anything is stored in $HOME/intel\n        # (like the 'installercache' database)\n        self.cfg['preinstallopts'] += \" HOME=%s \" % self.builddir\n\n    def install_step(self):\n        \"\"\"\n        Install step: install each 'source file' one by one.\n        Installing the Intel compilers could be done via a single installation file (HPC Toolkit),\n        or with separate installation files (patch releases of the C++ and Fortran compilers).\n        \"\"\"\n        srcs = self.src[:]\n        cnt = len(srcs)\n        for idx, src in enumerate(srcs):\n            print_msg(\"installing part %d/%s (%s)...\" % (idx + 1, cnt, src['name']))\n            self.src = [src]\n            super(EB_intel_minus_compilers, self).install_step()\n\n    def sanity_check_step(self):\n        \"\"\"\n        Custom sanity check for Intel compilers.\n        \"\"\"\n\n        oneapi_compiler_cmds = [\n            'dpcpp',  # Intel oneAPI Data Parallel C++ compiler\n            'icx',  # oneAPI Intel C compiler\n            'icpx',  # oneAPI Intel C++ compiler\n            'ifx',  # oneAPI Intel Fortran compiler\n        ]\n        bindir = os.path.join(self.compilers_subdir, 'bin')\n        oneapi_compiler_paths = [os.path.join(bindir, x) for x in oneapi_compiler_cmds]\n        if LooseVersion(self.version) >= LooseVersion('2024'):\n            classic_compiler_cmds = ['ifort']\n            classic_bindir = bindir\n        else:\n            classic_compiler_cmds = ['icc', 'icpc', 'ifort']\n            classic_bindir = os.path.join(bindir, 'intel64')\n        classic_compiler_paths = [os.path.join(classic_bindir, x) for x in classic_compiler_cmds]\n\n        custom_paths = {\n            'files': classic_compiler_paths + oneapi_compiler_paths,\n            'dirs': [self.compilers_subdir],\n        }\n\n        all_compiler_cmds = classic_compiler_cmds + oneapi_compiler_cmds\n        custom_commands = [\"which %s\" % c for c in all_compiler_cmds]\n\n        # only for 2021.x versions do all compiler commands have the expected version;\n        # for example: for 2022.0.1, icc has version 2021.5.0, icpx has 2022.0.0\n        if LooseVersion(self.version) >= LooseVersion('2022.0'):\n            custom_commands.extend(\"%s --version\" % c for c in all_compiler_cmds)\n        else:\n            custom_commands.extend(\"%s --version | grep %s\" % (c, self.version) for c in all_compiler_cmds)\n\n        super(EB_intel_minus_compilers, self).sanity_check_step(custom_paths=custom_paths,\n                                                                custom_commands=custom_commands)\n\n    def make_module_req_guess(self):\n        \"\"\"\n        Paths to consider for prepend-paths statements in module file\n        \"\"\"\n        libdirs = [\n            'lib',\n            os.path.join('lib', 'x64'),\n            os.path.join('compiler', 'lib', 'intel64_lin'),\n        ]\n        libdirs = [os.path.join(self.compilers_subdir, x) for x in libdirs]\n        tbb_subdir = self.tbb_subdir\n        tbb_libsubdir = os.path.join(tbb_subdir, 'lib', 'intel64')\n        libdirs.append(os.path.join(tbb_libsubdir,\n                                    get_tbb_gccprefix(os.path.join(self.installdir, tbb_libsubdir))))\n        guesses = {\n            'PATH': [\n                os.path.join(self.compilers_subdir, 'bin'),\n                os.path.join(self.compilers_subdir, 'bin', 'intel64'),\n            ],\n            'LD_LIBRARY_PATH': libdirs,\n            'LIBRARY_PATH': libdirs,\n            'MANPATH': [\n                os.path.join(os.path.dirname(self.compilers_subdir), 'documentation', 'en', 'man', 'common'),\n                os.path.join(self.compilers_subdir, 'share', 'man'),\n            ],\n            'OCL_ICD_FILENAMES': [\n                os.path.join(self.compilers_subdir, 'lib', 'x64', 'libintelocl.so'),\n                os.path.join(self.compilers_subdir, 'lib', 'libintelocl.so'),\n            ],\n            'CPATH': [\n                os.path.join(tbb_subdir, 'include'),\n            ],\n            'TBBROOT': [tbb_subdir],\n        }\n        return guesses\n\n    def make_module_extra(self):\n        \"\"\"Additional custom variables for intel-compiler\"\"\"\n        txt = super(EB_intel_minus_compilers, self).make_module_extra()\n\n        # On Debian/Ubuntu, /usr/include/x86_64-linux-gnu, or whatever dir gcc uses, needs to be included\n        # in $CPATH for Intel C compiler\n        multiarch_out, ec = run_cmd(\"gcc -print-multiarch\", simple=False)\n        multiarch_out = multiarch_out.strip()\n        if ec == 0 and multiarch_out:\n            multiarch_inc_dir, ec = run_cmd(\"gcc -E -Wp,-v -xc /dev/null 2>&1 | grep %s$\" % multiarch_out)\n            if ec == 0 and multiarch_inc_dir:\n                multiarch_inc_dir = multiarch_inc_dir.strip()\n                self.log.info(\"Adding multiarch include path %s to $CPATH in generated module file\", multiarch_inc_dir)\n                # system location must be appended at the end, so use append_paths\n                txt += self.module_generator.append_paths('CPATH', [multiarch_inc_dir], allow_abs=True)\n\n        return txt\n", "path": "easybuild/easyblocks/i/intel_compilers.py"}], "after_files": [{"content": "# #\n# Copyright 2021-2024 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n# #\n\"\"\"\nEasyBuild support for installing Intel compilers, implemented as an easyblock\n\n@author: Kenneth Hoste (Ghent University)\n\"\"\"\nimport os\nfrom easybuild.tools import LooseVersion\n\nfrom easybuild.easyblocks.generic.intelbase import IntelBase\nfrom easybuild.easyblocks.t.tbb import get_tbb_gccprefix\nfrom easybuild.tools.build_log import EasyBuildError, print_msg\nfrom easybuild.tools.run import run_cmd\n\n\nclass EB_intel_minus_compilers(IntelBase):\n    \"\"\"\n    Support for installing Intel compilers, starting with verion 2021.x (oneAPI)\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Easyblock constructor: check version\n        \"\"\"\n        super(EB_intel_minus_compilers, self).__init__(*args, **kwargs)\n\n        # this easyblock is only valid for recent versions of the Intel compilers (2021.x, oneAPI)\n        if LooseVersion(self.version) < LooseVersion('2021'):\n            raise EasyBuildError(\"Invalid version %s, should be >= 2021.x\" % self.version)\n\n    @property\n    def compilers_subdir(self):\n        compilers_subdir = self.get_versioned_subdir('compiler')\n        if LooseVersion(self.version) < LooseVersion('2024'):\n            compilers_subdir = os.path.join(compilers_subdir, 'linux')\n        return compilers_subdir\n\n    @property\n    def tbb_subdir(self):\n        return self.get_versioned_subdir('tbb')\n\n    def prepare_step(self, *args, **kwargs):\n        \"\"\"\n        Prepare environment for installing.\n\n        Specify that oneAPI versions of Intel compilers don't require a runtime license.\n        \"\"\"\n        # avoid that IntelBase trips over not having license info specified\n        kwargs['requires_runtime_license'] = False\n\n        super(EB_intel_minus_compilers, self).prepare_step(*args, **kwargs)\n\n    def configure_step(self):\n        \"\"\"Configure installation.\"\"\"\n\n        # redefine $HOME for install step, to avoid that anything is stored in $HOME/intel\n        # (like the 'installercache' database)\n        self.cfg['preinstallopts'] += \" HOME=%s \" % self.builddir\n\n    def install_step(self):\n        \"\"\"\n        Install step: install each 'source file' one by one.\n        Installing the Intel compilers could be done via a single installation file (HPC Toolkit),\n        or with separate installation files (patch releases of the C++ and Fortran compilers).\n        \"\"\"\n        srcs = self.src[:]\n        cnt = len(srcs)\n        for idx, src in enumerate(srcs):\n            print_msg(\"installing part %d/%s (%s)...\" % (idx + 1, cnt, src['name']))\n            self.src = [src]\n            super(EB_intel_minus_compilers, self).install_step()\n\n    def sanity_check_step(self):\n        \"\"\"\n        Custom sanity check for Intel compilers.\n        \"\"\"\n\n        oneapi_compiler_cmds = [\n            'dpcpp',  # Intel oneAPI Data Parallel C++ compiler\n            'icx',  # oneAPI Intel C compiler\n            'icpx',  # oneAPI Intel C++ compiler\n            'ifx',  # oneAPI Intel Fortran compiler\n        ]\n        bindir = os.path.join(self.compilers_subdir, 'bin')\n        oneapi_compiler_paths = [os.path.join(bindir, x) for x in oneapi_compiler_cmds]\n        if LooseVersion(self.version) >= LooseVersion('2024'):\n            classic_compiler_cmds = ['ifort']\n            classic_bindir = bindir\n        else:\n            classic_compiler_cmds = ['icc', 'icpc', 'ifort']\n            classic_bindir = os.path.join(bindir, 'intel64')\n        classic_compiler_paths = [os.path.join(classic_bindir, x) for x in classic_compiler_cmds]\n\n        custom_paths = {\n            'files': classic_compiler_paths + oneapi_compiler_paths,\n            'dirs': [self.compilers_subdir],\n        }\n\n        all_compiler_cmds = classic_compiler_cmds + oneapi_compiler_cmds\n        custom_commands = [\"which %s\" % c for c in all_compiler_cmds]\n\n        # only for 2021.x versions do all compiler commands have the expected version;\n        # for example: for 2022.0.1, icc has version 2021.5.0, icpx has 2022.0.0\n        if LooseVersion(self.version) >= LooseVersion('2022.0'):\n            custom_commands.extend(\"%s --version\" % c for c in all_compiler_cmds)\n        else:\n            custom_commands.extend(\"%s --version | grep %s\" % (c, self.version) for c in all_compiler_cmds)\n\n        super(EB_intel_minus_compilers, self).sanity_check_step(custom_paths=custom_paths,\n                                                                custom_commands=custom_commands)\n\n    def make_module_req_guess(self):\n        \"\"\"\n        Paths to consider for prepend-paths statements in module file\n        \"\"\"\n        libdirs = [\n            'lib',\n            os.path.join('lib', 'x64'),\n            os.path.join('compiler', 'lib', 'intel64_lin'),\n        ]\n        libdirs = [os.path.join(self.compilers_subdir, x) for x in libdirs]\n        tbb_subdir = self.tbb_subdir\n        tbb_libsubdir = os.path.join(tbb_subdir, 'lib', 'intel64')\n        libdirs.append(os.path.join(tbb_libsubdir,\n                                    get_tbb_gccprefix(os.path.join(self.installdir, tbb_libsubdir))))\n        guesses = {\n            'PATH': [\n                os.path.join(self.compilers_subdir, 'bin'),\n                os.path.join(self.compilers_subdir, 'bin', 'intel64'),\n            ],\n            'LD_LIBRARY_PATH': libdirs,\n            'LIBRARY_PATH': libdirs,\n            'MANPATH': [\n                os.path.join(os.path.dirname(self.compilers_subdir), 'documentation', 'en', 'man', 'common'),\n                os.path.join(self.compilers_subdir, 'share', 'man'),\n            ],\n            'OCL_ICD_FILENAMES': [\n                os.path.join(self.compilers_subdir, 'lib', 'x64', 'libintelocl.so'),\n                os.path.join(self.compilers_subdir, 'lib', 'libintelocl.so'),\n            ],\n            'CPATH': [\n                os.path.join(tbb_subdir, 'include'),\n            ],\n            'TBBROOT': [tbb_subdir],\n        }\n        return guesses\n\n    def make_module_extra(self):\n        \"\"\"Additional custom variables for intel-compiler\"\"\"\n        txt = super(EB_intel_minus_compilers, self).make_module_extra()\n\n        # On Debian/Ubuntu, /usr/include/x86_64-linux-gnu, or whatever dir gcc uses, needs to be included\n        # in $CPATH for Intel C compiler\n        multiarch_out, ec = run_cmd(\"gcc -print-multiarch\", simple=False)\n        multiarch_out = multiarch_out.strip()\n        if ec == 0 and multiarch_out:\n            multi_arch_inc_dir_cmd = '|'.join([\n                \"gcc -E -Wp,-v -xc /dev/null 2>&1\",\n                \"grep %s$\" % multiarch_out,\n                \"grep -v /include-fixed/\",\n            ])\n            multiarch_inc_dir, ec = run_cmd(multi_arch_inc_dir_cmd)\n            if ec == 0 and multiarch_inc_dir:\n                multiarch_inc_dir = multiarch_inc_dir.strip()\n                self.log.info(\"Adding multiarch include path %s to $CPATH in generated module file\", multiarch_inc_dir)\n                # system location must be appended at the end, so use append_paths\n                txt += self.module_generator.append_paths('CPATH', [multiarch_inc_dir], allow_abs=True)\n\n        return txt\n", "path": "easybuild/easyblocks/i/intel_compilers.py"}]}