""" Abstract base class for compilers. This module defines the interface that all compiler implementations must follow. """ from abc import ABC, abstractmethod from pathlib import Path from typing import List, Optional class Compiler(ABC): """ Abstract base class for all compiler implementations. Subclasses must implement compile() and link() methods with compiler-specific logic. """ def __init__(self, executable: str): """ Initialize the compiler. Args: executable: Name or path to the compiler executable """ self.executable = executable @abstractmethod def compile( self, source: Path, output: Path, *, includes: Optional[List[Path]] = None, defines: Optional[dict] = None, flags: Optional[List[str]] = None, generate_deps: bool = True, is_test: bool = False ) -> Path: """ Compile a single source file to an object file. Args: source: Path to source file (.c) output: Path to output object file (.o or .obj) includes: List of include directories defines: Dictionary of preprocessor defines {name: value} flags: Additional compiler flags generate_deps: Whether to generate dependency files is_test: Whether this is a test compilation (may affect optimization) Returns: Path to the compiled object file """ pass @abstractmethod def link( self, objects: List[Path], output: Path, *, libraries: Optional[List[str]] = None, library_paths: Optional[List[Path]] = None, flags: Optional[List[str]] = None ) -> Path: """ Link object files into an executable. Args: objects: List of object files to link output: Path to output executable libraries: List of libraries to link against (e.g., ['m', 'pthread']) library_paths: List of library search paths flags: Additional linker flags Returns: Path to the linked executable """ pass @abstractmethod def get_object_extension(self) -> str: """ Get the object file extension for this compiler. Returns: Object file extension (e.g., '.o' or '.obj') """ pass @abstractmethod def get_executable_extension(self) -> str: """ Get the executable extension for this compiler/platform. Returns: Executable extension (e.g., '' for Unix, '.exe' for Windows) """ pass def get_dependency_file(self, object_file: Path) -> Path: """ Get the dependency file path for an object file. Args: object_file: Path to object file Returns: Path to dependency file (usually .d extension) """ return object_file.with_suffix('.d') def is_available(self) -> bool: """ Check if this compiler is available on the system. Returns: True if compiler executable exists in PATH """ import shutil return shutil.which(self.executable) is not None def __repr__(self) -> str: return f"{self.__class__.__name__}(executable='{self.executable}')"