YREA-SLS/SLS_C/build_system/compilers/__init__.py

144 lines
3.9 KiB
Python

"""
Compiler module for the build system.
This module provides compiler implementations for various toolchains:
- GCC (Unix/Linux)
- Clang (macOS/Unix)
- MSVC (Windows)
- ARM GCC (embedded ARM targets)
Usage:
from compilers import GCCCompiler, ClangCompiler, MSVCCompiler
compiler = GCCCompiler()
compiler.compile(source, output, includes=[...], defines={...})
"""
from typing import Optional
from .base import Compiler
from .gcc import GCCCompiler
from .clang import ClangCompiler
from .msvc import MSVCCompiler
from .arm_gcc import ARMGCCCompiler, RP2040Compiler
__all__ = [
'Compiler',
'GCCCompiler',
'ClangCompiler',
'MSVCCompiler',
'ARMGCCCompiler',
'RP2040Compiler',
]
def detect_compiler(platform: Optional[str] = None):
"""
Detect and return an appropriate compiler for the given platform.
Args:
platform: Target platform ('linux', 'windows', 'darwin'/'macos', 'rp2040', etc.)
If None, detects current platform.
Returns:
An instance of the appropriate Compiler subclass
Raises:
RuntimeError: If no suitable compiler is found
"""
import platform as plat
import shutil
# Detect current platform if not specified
if platform is None:
system = plat.system().lower()
if system == "darwin":
platform = "macos"
else:
platform = system
platform = platform.lower()
# Try to find appropriate compiler
if platform in ("linux", "unix"):
# Prefer GCC on Linux
if shutil.which("gcc"):
return GCCCompiler("gcc")
elif shutil.which("clang"):
return ClangCompiler("clang")
else:
raise RuntimeError("No suitable compiler found (tried gcc, clang)")
elif platform in ("macos", "darwin"):
# Prefer Clang on macOS (default compiler)
if shutil.which("clang"):
return ClangCompiler("clang")
elif shutil.which("gcc"):
return GCCCompiler("gcc")
else:
raise RuntimeError("No suitable compiler found (tried clang, gcc)")
elif platform == "windows":
# Try MSVC first, then MinGW GCC
if shutil.which("cl"):
return MSVCCompiler("cl")
elif shutil.which("gcc"):
return GCCCompiler("gcc")
else:
raise RuntimeError("No suitable compiler found (tried cl, gcc)")
elif platform == "rp2040":
# RP2040 needs ARM toolchain
if shutil.which("arm-none-eabi-gcc"):
return RP2040Compiler()
else:
raise RuntimeError(
"ARM GCC toolchain not found. Please install arm-none-eabi-gcc:\n"
" Ubuntu/Debian: sudo apt install gcc-arm-none-eabi\n"
" macOS: brew install arm-none-eabi-gcc"
)
else:
raise ValueError(f"Unknown platform: {platform}")
def get_available_compilers():
"""
Get a list of all compilers available on the current system.
Returns:
Dictionary mapping compiler names to Compiler instances
"""
import shutil
available = {}
# Check GCC
if shutil.which("gcc"):
available['gcc'] = GCCCompiler()
# Check Clang
if shutil.which("clang"):
available['clang'] = ClangCompiler()
# Check MSVC
if shutil.which("cl"):
available['msvc'] = MSVCCompiler()
# Check ARM GCC
if shutil.which("arm-none-eabi-gcc"):
available['arm-gcc'] = ARMGCCCompiler()
available['rp2040'] = RP2040Compiler()
return available
def print_available_compilers():
"""Print all available compilers on the system."""
compilers = get_available_compilers()
if not compilers:
print("No compilers found on this system.")
return
print("Available compilers:")
for name, compiler in compilers.items():
print(f" - {name}: {compiler.executable}")