128 lines
3.5 KiB
Python
128 lines
3.5 KiB
Python
"""
|
|
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}')"
|
|
|