From 7a7b1de8d5dfc4f726b59f5b72ba325f0ca62c3a Mon Sep 17 00:00:00 2001
From: Martin Lang <martin.lang@mpsd.mpg.de>
Date: Mon, 2 Dec 2024 12:50:30 +0100
Subject: [PATCH] Autoload GCC as a dependency of intel modules

---
 src/mpsd_software_manager/spack.py | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/mpsd_software_manager/spack.py b/src/mpsd_software_manager/spack.py
index a8167eb..f8bd3b9 100644
--- a/src/mpsd_software_manager/spack.py
+++ b/src/mpsd_software_manager/spack.py
@@ -307,7 +307,7 @@ def spack_install_package(package: str) -> None:
         raise SpackInstallationError() from e
 
 
-def refresh_modules() -> None:
+def refresh_modules(compilers: dict[str, Any] | None = None) -> None:
     """Create lmod modules and change family of intel compiler modules."""
     logger.info("refreshing lmod modules")
     try:
@@ -315,14 +315,29 @@ def refresh_modules() -> None:
     except sp.CalledProcessError as e:
         raise ModuleGenerationError() from e
 
-    # patch intel modules
-    # to allow loading gcc and intel compiler simultaneously, we replace
-    # 'family("compiler")' in the intel/oneapi lmod files
-    for module_file in (Config().lmod_root / "Core").glob("*intel*/*.lua"):
-        logger.debug("Updating family(...) in '%s'", module_file)
+    # patch intel module
+    # - to allow loading gcc and intel compiler simultaneously, we replace
+    #   'family("compiler")' in the intel/oneapi lmod files
+    # - add gcc as dependent module to intel compilers
+    if compilers and "intel" in compilers["default"]["package"]:
+        intel_module = (
+            compilers["default"]["package"].split("%")[0].replace("@", "/") + ".lua"
+        )
+        gcc_module = compilers["fallback"]["package"].split("%")[0].replace("@", "/")
+        module_file = Config().lmod_root / "Core" / intel_module
+        logger.debug(
+            "Updating family(...) in '%s' (make '%s' depend on '%s')",
+            module_file,
+            intel_module,
+            gcc_module,
+        )
         with module_file.open() as f:
             content = f.read()
         content = content.replace('family("compiler")', 'family("intel_compiler")')
+        # insert gcc as dependency before other dependencies
+        content = content.replace(
+            "depends_on(", f'depends_on("{gcc_module}")\ndepends_on(', 1
+        )
         with module_file.open("w") as f:
             f.write(content)
 
@@ -366,7 +381,7 @@ def install_package_set_from_environment(spack_environment: str) -> None:
     except sp.CalledProcessError as e:
         raise SpackInstallationError() from e
 
-    refresh_modules()
+    refresh_modules(compilers)
     generate_meta_modules(spack_environment, compilers)
 
 
-- 
GitLab