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

129 lines
3.5 KiB
Python

"""
Clang compiler implementation.
This module implements the Compiler interface specifically for Clang,
with any Clang-specific features or flags that differ from GCC.
"""
from pathlib import Path
from typing import List, Optional
from .gcc import GCCCompiler
class ClangCompiler(GCCCompiler):
"""
Clang compiler implementation.
Clang uses a GCC-compatible command-line interface, so most functionality
is inherited from GCCCompiler. This class adds Clang-specific features:
1. macOS version targeting
2. Sanitizer support
3. Future Clang-specific optimizations
"""
def __init__(self, executable: str = "clang"):
"""
Initialize Clang compiler.
Args:
executable: Clang executable name (default: "clang")
"""
# Call parent with is_clang=True
super().__init__(executable=executable, is_clang=True)
self.macos_min_version = None
self.sanitizers = []
def set_macos_version(self, min_version: str = "10.13"):
"""
Set minimum macOS version for cross-compilation or macOS builds.
This is a Clang-specific feature commonly used on macOS.
Args:
min_version: Minimum macOS version (e.g., "10.13")
Returns:
Self for method chaining
"""
self.macos_min_version = min_version
return self
def enable_sanitizers(self, sanitizers: List[str]):
"""
Enable Clang sanitizers (address, thread, undefined, memory, etc.).
Args:
sanitizers: List of sanitizers to enable (e.g., ['address', 'undefined'])
Returns:
Self for method chaining
"""
self.sanitizers = sanitizers
return self
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 using Clang with optional sanitizers and macOS flags.
Extends GCCCompiler.compile() with Clang-specific features.
"""
flags = flags or []
# Add macOS version flag if set
if self.macos_min_version:
flags.append(f"-mmacosx-version-min={self.macos_min_version}")
# Add sanitizers if enabled
for san in self.sanitizers:
flags.append(f"-fsanitize={san}")
return super().compile(
source,
output,
includes=includes,
defines=defines,
flags=flags,
generate_deps=generate_deps,
is_test=is_test
)
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 using Clang with optional sanitizer support.
Sanitizers need to be enabled at link time as well.
"""
flags = flags or []
# Add sanitizers at link time
for san in self.sanitizers:
flags.append(f"-fsanitize={san}")
return super().link(
objects,
output,
libraries=libraries,
library_paths=library_paths,
flags=flags
)