|
8 | 8 | import easybuild.tools.environment as env |
9 | 9 | from easybuild.easyblocks.generic.configuremake import obtain_config_guess |
10 | 10 | from easybuild.framework.easyconfig.constants import EASYCONFIG_CONSTANTS |
| 11 | +from easybuild.framework.easyconfig.easyconfig import get_toolchain_hierarchy |
11 | 12 | from easybuild.tools import config |
12 | 13 | from easybuild.tools.build_log import EasyBuildError, print_msg, print_warning |
13 | 14 | from easybuild.tools.config import build_option, install_path, update_build_option |
14 | 15 | from easybuild.tools.filetools import apply_regex_substitutions, copy_dir, copy_file, remove_file, symlink, which |
15 | 16 | from easybuild.tools.run import run_cmd |
16 | 17 | from easybuild.tools.systemtools import AARCH64, POWER, X86_64, get_cpu_architecture, get_cpu_features |
17 | 18 | from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC |
| 19 | +from easybuild.tools.toolchain.toolchain import is_system_toolchain |
18 | 20 | from easybuild.tools.version import VERSION as EASYBUILD_VERSION |
19 | 21 | from easybuild.tools.modules import get_software_root_env_var_name |
20 | 22 |
|
|
50 | 52 |
|
51 | 53 | STACK_REPROD_SUBDIR = 'reprod' |
52 | 54 |
|
| 55 | +EESSI_SUPPORTED_TOP_LEVEL_TOOLCHAINS = { |
| 56 | + '2023.06': [ |
| 57 | + {'name': 'foss', 'version': '2022b'}, |
| 58 | + {'name': 'foss', 'version': '2023a'}, |
| 59 | + {'name': 'foss', 'version': '2023b'}, |
| 60 | + ], |
| 61 | + '2025.06': [ |
| 62 | + {'name': 'foss', 'version': '2024a'}, |
| 63 | + {'name': 'foss', 'version': '2025a'}, |
| 64 | + ], |
| 65 | +} |
| 66 | + |
53 | 67 |
|
54 | 68 | def is_gcccore_1220_based(**kwargs): |
55 | 69 | # ecname, ecversion, tcname, tcversion): |
@@ -128,14 +142,45 @@ def parse_hook(ec, *args, **kwargs): |
128 | 142 | ec = inject_gpu_property(ec) |
129 | 143 |
|
130 | 144 |
|
| 145 | +def verify_toolchains_supported_by_eessi_version(easyconfigs): |
| 146 | + """Each EESSI version supports a limited set of toolchains, sanity check the easyconfigs for toolchain support.""" |
| 147 | + eessi_version = get_eessi_envvar('EESSI_VERSION') |
| 148 | + supported_eessi_toolchains = [] |
| 149 | + for top_level_toolchain in EESSI_SUPPORTED_TOP_LEVEL_TOOLCHAINS[eessi_version]: |
| 150 | + supported_eessi_toolchains += get_toolchain_hierarchy(top_level_toolchain) |
| 151 | + for ec in easyconfigs: |
| 152 | + toolchain = ec['ec']['toolchain'] |
| 153 | + # if it is a system toolchain or appears in the list, we are all good |
| 154 | + if is_system_toolchain(toolchain['name']): |
| 155 | + continue |
| 156 | + elif not any(toolchain.items() <= supported.items() for supported in supported_eessi_toolchains): |
| 157 | + raise EasyBuildError( |
| 158 | + f"Toolchain {toolchain} (required by {ec['full_mod_name']}) is not supported in EESSI/{eessi_version}\n" |
| 159 | + f"Supported toolchains are:\n" + "\n".join(sorted(" " + str(tc) for tc in supported_eessi_toolchains)) |
| 160 | + ) |
| 161 | + |
| 162 | + |
| 163 | +def pre_build_and_install_loop_hook(easyconfigs): |
| 164 | + """Main pre_build_and_install_loop hook: trigger custom functions before beginning installation loop.""" |
| 165 | + |
| 166 | + # Always check that toolchain supported by the EESSI version (unless overridden) |
| 167 | + if os.getenv("EESSI_OVERRIDE_TOOLCHAIN_CHECK"): |
| 168 | + print_warning("Overriding the check that the toolchains are supported by the EESSI version.") |
| 169 | + else: |
| 170 | + verify_toolchains_supported_by_eessi_version(easyconfigs) |
| 171 | + |
| 172 | + |
131 | 173 | def post_ready_hook(self, *args, **kwargs): |
132 | 174 | """ |
133 | 175 | Post-ready hook: limit parallellism for selected builds based on software name and CPU target. |
134 | 176 | parallelism needs to be limited because some builds require a lot of memory per used core. |
135 | 177 | """ |
136 | 178 | # 'parallel' easyconfig parameter (EB4) or the parallel property (EB5) is set via EasyBlock.set_parallel |
137 | 179 | # in ready step based on available cores |
138 | | - parallel = getattr(self, 'parallel', self.cfg['parallel']) |
| 180 | + if hasattr(self, 'parallel'): |
| 181 | + parallel = self.parallel |
| 182 | + else: |
| 183 | + parallel = self.cfg['parallel'] |
139 | 184 |
|
140 | 185 | if parallel == 1: |
141 | 186 | return # no need to limit if already using 1 core |
@@ -167,8 +212,8 @@ def post_ready_hook(self, *args, **kwargs): |
167 | 212 |
|
168 | 213 | # apply the limit if it's different from current |
169 | 214 | if new_parallel != parallel: |
170 | | - if EASYBUILD_VERSION >= '5': |
171 | | - self.cfg.parallel = new_parallel |
| 215 | + if hasattr(self, 'parallel'): |
| 216 | + self.parallel = new_parallel |
172 | 217 | else: |
173 | 218 | self.cfg['parallel'] = new_parallel |
174 | 219 | msg = "limiting parallelism to %s (was %s) for %s on %s to avoid out-of-memory failures during building/testing" |
@@ -394,7 +439,7 @@ def parse_hook_freeimage_aarch64(ec, *args, **kwargs): |
394 | 439 | https://github.com/EESSI/software-layer/pull/736#issuecomment-2373261889 |
395 | 440 | """ |
396 | 441 | if ec.name == 'FreeImage' and ec.version in ('3.18.0',): |
397 | | - if os.getenv('EESSI_CPU_FAMILY') == 'aarch64': |
| 442 | + if get_eessi_envvar('EESSI_CPU_FAMILY') == 'aarch64': |
398 | 443 | # Make sure the toolchainopts key exists, and the value is a dict, |
399 | 444 | # before we add the option to enable PIC and disable PNG_ARM_NEON_OPT |
400 | 445 | if 'toolchainopts' not in ec or ec['toolchainopts'] is None: |
@@ -1230,7 +1275,7 @@ def replace_non_distributable_files_with_symlinks(log, install_dir, pkg_name, al |
1230 | 1275 | # CUDA and cu* libraries themselves don't care about compute capability so remove this |
1231 | 1276 | # duplication from under host_injections (symlink to a single CUDA or cu* library |
1232 | 1277 | # installation for all compute capabilities) |
1233 | | - accel_subdir = os.getenv("EESSI_ACCELERATOR_TARGET") |
| 1278 | + accel_subdir = get_eessi_envvar("EESSI_ACCELERATOR_TARGET") |
1234 | 1279 | if accel_subdir: |
1235 | 1280 | host_inj_path = host_inj_path.replace("/accel/%s" % accel_subdir, '') |
1236 | 1281 | # make sure source and target of symlink are not the same |
@@ -1326,7 +1371,7 @@ def post_easyblock_hook(self, *args, **kwargs): |
1326 | 1371 |
|
1327 | 1372 | # Always trigger this one for EESSI CVMFS/site installations and version 2025.06 or newer, regardless of self.name |
1328 | 1373 | if os.getenv('EESSI_CVMFS_INSTALL') or os.getenv('EESSI_SITE_INSTALL'): |
1329 | | - if os.getenv('EESSI_VERSION') and LooseVersion(os.getenv('EESSI_VERSION')) >= '2025.06': |
| 1374 | + if get_eessi_envvar('EESSI_VERSION') and LooseVersion(get_eessi_envvar('EESSI_VERSION')) >= '2025.06': |
1330 | 1375 | post_easyblock_hook_copy_easybuild_subdir(self, *args, **kwargs) |
1331 | 1376 | else: |
1332 | 1377 | self.log.debug("No CVMFS/site installation requested, not running post_easyblock_hook_copy_easybuild_subdir.") |
|
0 commit comments