Files
AbaqusSubroutineDev/scripts/fortran_toolchain.py
T
2026-06-09 12:27:22 +09:00

82 lines
2.5 KiB
Python

#!/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}"'