129 lines
3.5 KiB
Python
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
|
|
)
|
|
|