#!/usr/bin/env python3 """Intel oneAPI Fortran discovery helpers for no-Abaqus validation.""" from __future__ import annotations import os import shutil import subprocess from pathlib import Path from typing import Iterable COMPILER_CANDIDATES = ("ifx", "ifort") ONEAPI_VARS_CANDIDATES = [ Path(r"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat"), Path(r"C:\Program Files\Intel\oneAPI\compiler\latest\env\vars.bat"), Path(r"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"), Path(r"C:\Program Files\Intel\oneAPI\setvars.bat"), ] class FortranToolchain: def __init__(self, *, name: str, executable: str, env_script: Path | None): self.name = name self.executable = executable self.env_script = env_script def compiler_candidates(preference: str | None = None) -> list[str]: preference = (preference or os.environ.get("HARNESS_FORTRAN_COMPILER") or "auto").lower() if preference == "auto": return list(COMPILER_CANDIDATES) if preference not in COMPILER_CANDIDATES: raise ValueError(f"Unsupported HARNESS_FORTRAN_COMPILER: {preference}") return [preference] def discover_oneapi_env_script(env: dict[str, str] | None = None) -> Path | None: env = env or os.environ configured = env.get("HARNESS_ONEAPI_VARS_BAT") if configured: path = Path(configured) return path if path.exists() else None for path in ONEAPI_VARS_CANDIDATES: if path.exists(): return path return None def resolve_toolchain(env: dict[str, str] | None = None) -> FortranToolchain | None: env = env or os.environ candidates = compiler_candidates(env.get("HARNESS_FORTRAN_COMPILER")) for compiler in candidates: resolved = shutil.which(compiler) if resolved: return FortranToolchain(name=compiler, executable=resolved, env_script=None) env_script = discover_oneapi_env_script(env) if env_script is None: return None compiler = candidates[0] return FortranToolchain(name=compiler, executable=compiler, env_script=env_script) def shell_join(args: Iterable[str | Path]) -> str: return subprocess.list2cmdline([str(arg) for arg in args]) def quote_path(path: str | Path) -> str: return shell_join([path]) def wrap_command(toolchain: FortranToolchain, args: list[str | Path]) -> str: command = shell_join(args) if toolchain.env_script is None: return command env_script = quote_path(toolchain.env_script) return f'cmd /d /s /c "call {env_script} intel64 >nul && {command}"'