From 1fc59fbe5e45380e9c72f73fad2630c8d742ce42 Mon Sep 17 00:00:00 2001 From: zhusy54 Date: Thu, 2 Apr 2026 14:08:19 +0800 Subject: [PATCH] Fix: resolve compiler paths from env vars with flags Added _resolve_compiler() helper to properly extract and resolve compiler executables from environment variables that may contain compiler flags (e.g., 'gcc -pthread -B /path' from sysconfig). Updated Gxx15Toolchain and GxxToolchain to resolve CC/CXX in __init__ so all usages (CMake and direct subprocess invocations via KernelCompiler) benefit from the resolution. - Handle compiler env vars with embedded flags by splitting and extracting exe name - Use shutil.which() to resolve exe name to full path via PATH - Fix IndexError when CC/CXX contains only whitespace - Resolve CC/CXX in __init__ so KernelCompiler direct calls also use resolved paths - Gxx15Toolchain defaults to gcc-15/g++-15 for c++23 consistency - GxxToolchain uses self.cc_path/self.cxx_path in get_cmake_args for simplicity --- python/toolchain.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/python/toolchain.py b/python/toolchain.py index ca44c4db8..1cb984ce8 100644 --- a/python/toolchain.py +++ b/python/toolchain.py @@ -10,11 +10,25 @@ from __future__ import annotations import os +import shutil from enum import IntEnum import env_manager +def _resolve_compiler(env_var: str, default: str) -> str: + """Resolve a compiler from an environment variable to a full path. + + Handles the case where the env var contains flags (e.g. sysconfig-derived + 'gcc -pthread -B /path') by extracting only the executable name and resolving + it via PATH. + """ + raw = os.environ.get(env_var, "") + parts = raw.split() + exe = parts[0] if parts else default + return shutil.which(exe) or exe + + # Must match compile_strategy.h class ToolchainType(IntEnum): """Toolchain types matching the C enum in compile_strategy.h.""" @@ -117,7 +131,8 @@ class Gxx15Toolchain(Toolchain): def __init__(self): super().__init__() - self.cxx_path = "g++-15" + self.cc_path = _resolve_compiler("CC", "gcc-15") + self.cxx_path = _resolve_compiler("CXX", "g++-15") def get_compile_flags(self, core_type: str = "", **kwargs) -> list[str]: flags = [ @@ -141,12 +156,9 @@ def get_compile_flags(self, core_type: str = "", **kwargs) -> list[str]: return flags def get_cmake_args(self) -> list[str]: - # Respect CC/CXX environment variables (e.g., CXX=g++-15 on macOS CI) - cc = os.environ.get("CC", "gcc") - cxx = os.environ.get("CXX", "g++") return [ - f"-DCMAKE_C_COMPILER={cc}", - f"-DCMAKE_CXX_COMPILER={cxx}", + f"-DCMAKE_C_COMPILER={self.cc_path}", + f"-DCMAKE_CXX_COMPILER={self.cxx_path}", ] @@ -155,18 +167,16 @@ class GxxToolchain(Toolchain): def __init__(self): super().__init__() - self.cxx_path = "g++" + self.cc_path = _resolve_compiler("CC", "gcc") + self.cxx_path = _resolve_compiler("CXX", "g++") def get_compile_flags(self, **kwargs) -> list[str]: return ["-shared", "-fPIC", "-O3", "-g", "-std=c++17"] def get_cmake_args(self) -> list[str]: - # Respect CC/CXX environment variables (e.g., CXX=g++-15 on macOS CI) - cc = os.environ.get("CC", "gcc") - cxx = os.environ.get("CXX", "g++") args = [ - f"-DCMAKE_C_COMPILER={cc}", - f"-DCMAKE_CXX_COMPILER={cxx}", + f"-DCMAKE_C_COMPILER={self.cc_path}", + f"-DCMAKE_CXX_COMPILER={self.cxx_path}", ] if self.ascend_home_path: args.append(f"-DASCEND_HOME_PATH={self.ascend_home_path}")