diff --git a/src/xtc/runtimes/host/runtime.py b/src/xtc/runtimes/host/runtime.py index 17cf41db..87941346 100644 --- a/src/xtc/runtimes/host/runtime.py +++ b/src/xtc/runtimes/host/runtime.py @@ -3,7 +3,6 @@ # Copyright (c) 2024-2026 The XTC Project Authors # import ctypes -import ctypes.util import tempfile import subprocess import threading @@ -14,7 +13,7 @@ from typing import Any from enum import Enum -from xtc.utils.tools import get_mlir_prefix, get_cuda_prefix +from xtc.utils.tools import get_mlir_prefix, get_cuda_prefix, check_compile __all__ = ["runtime_funcs", "resolve_runtime", "RuntimeType"] @@ -147,7 +146,9 @@ def from_param(obj: str | bytes): def _compile_runtime(out_dll: str, tdir: str, runtime_type: RuntimeType): - has_pfm = ctypes.util.find_library("pfm") is not None + has_pfm = check_compile( + "#include \nint main() { return 0; }\n", libs="pfm" + ) pfm_opts = "-DHAS_PFM=1" if has_pfm else "" pfm_libs = "-lpfm" if has_pfm else "" has_gpu = runtime_type == RuntimeType.GPU diff --git a/src/xtc/utils/tools.py b/src/xtc/utils/tools.py index 3370d9ba..5356dd8c 100644 --- a/src/xtc/utils/tools.py +++ b/src/xtc/utils/tools.py @@ -5,6 +5,8 @@ import os import shutil from pathlib import Path +import subprocess +import tempfile def get_mlir_prefix(prefix: Path | str | None = None): @@ -102,3 +104,28 @@ def get_cuda_prefix(prefix: Path | str | None = None): if not prefix.exists(): raise RuntimeError(f"could not find CUDA installation dir at: {prefix}") return prefix + + +def check_compile(code: str, libs: str | list[str] | None = None): + """ + Attempt to compile (and link) a small C program. + """ + compiler = shutil.which("cc") or shutil.which("gcc") + if compiler is None: + return False + + if isinstance(libs, str): + libs = [libs] + libs = libs or [] + + with tempfile.TemporaryDirectory() as tmpdir: + src_path = os.path.join(tmpdir, "test.c") + exe_path = os.path.join(tmpdir, "test") + + with open(src_path, "w") as f: + f.write(code) + + cmd = [compiler, src_path, "-o", exe_path] + [f"-l{lib}" for lib in libs] + + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return result.returncode == 0