diff --git a/aedi/state.py b/aedi/state.py index 5eb0e99c..0c3d5deb 100644 --- a/aedi/state.py +++ b/aedi/state.py @@ -51,6 +51,9 @@ class BuildState: self.output_path = None self.install_path = None + self._compiler_flags = None + self._linker_flags = None + self.platform = None self.xcode = False self.verbose = False @@ -87,6 +90,33 @@ class BuildState: def cxx_compiler(self) -> Path: return self.platform.cxx_compiler if self.platform else None + def compiler_flags(self) -> str: + if not self._compiler_flags: + self._compiler_flags = f'-I{self.include_path} -ffile-prefix-map={self.source}/=' + + return self._compiler_flags + + def linker_flags(self) -> str: + if not self._linker_flags: + self._linker_flags = f'-L{self.lib_path}' + + # Fix for Xcode 15.0 known issue with the new linker + # https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#Known-Issues + # Binaries using symbols with a weak definition crash at runtime on iOS 14/macOS 12 or older. + # This impacts primarily C++ projects due to their extensive use of weak symbols. (114813650) (FB13097713) + # Workaround: Bump the minimum deployment target to iOS 15, macOS 12, watchOS 8 or tvOS 15, + # or add -Wl,-ld_classic to the OTHER_LDFLAGS build setting. + + ld_classic_arg = '-Wl,-ld_classic' + check_args = ('clang', '-xc++', ld_classic_arg, '-') + check_code = b'int main() {}' + + if subprocess.run(check_args, capture_output=True, input=check_code).returncode == 0: + self._linker_flags += f' {ld_classic_arg}' + os.unlink('a.out') + + return self._linker_flags + def checkout_git(self, url: str, branch: typing.Optional[str] = None): if self.source.exists(): return diff --git a/aedi/target/base.py b/aedi/target/base.py index 01c640a7..f22cdbce 100644 --- a/aedi/target/base.py +++ b/aedi/target/base.py @@ -94,10 +94,9 @@ class BuildTarget(Target): env['CXX'] = str(cxx_compiler) for prefix in ('C', 'CPP', 'CXX', 'OBJC', 'OBJCXX'): - state.update_flags_environment_variable(f'{prefix}FLAGS', f'-I{state.include_path}') + state.update_flags_environment_variable(f'{prefix}FLAGS', state.compiler_flags()) - ldflags = f'-L{state.lib_path} {self.extra_linker_flags()}' - state.update_flags_environment_variable('LDFLAGS', ldflags) + state.update_flags_environment_variable('LDFLAGS', state.linker_flags()) # Avoid timestamp only differences in static libraries env['ZERO_AR_DATE'] = '1' @@ -260,30 +259,6 @@ Cflags: -I${{includedir}} {cflags} dst_path = bin_path / new_filename shutil.copy(src_path, dst_path) - @staticmethod - def extra_linker_flags(): - # Fix for Xcode 15.0 known issue with the new linker - # https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#Known-Issues - # Binaries using symbols with a weak definition crash at runtime on iOS 14/macOS 12 or older. - # This impacts primarily C++ projects due to their extensive use of weak symbols. (114813650) (FB13097713) - # Workaround: Bump the minimum deployment target to iOS 15, macOS 12, watchOS 8 or tvOS 15, - # or add -Wl,-ld_classic to the OTHER_LDFLAGS build setting. - - this = BuildTarget.extra_linker_flags - - if not hasattr(this, "flags"): - ld_classic_arg = '-Wl,-ld_classic' - check_args = ('clang', '-xc++', ld_classic_arg, '-') - check_code = b'int main() {}' - - if subprocess.run(check_args, capture_output=True, input=check_code).returncode == 0: - this.flags = ld_classic_arg - os.unlink('a.out') - else: - this.flags = '' - - return this.flags - class MakeTarget(BuildTarget): def __init__(self, name=None): @@ -415,14 +390,11 @@ class CMakeTarget(BuildTarget): f'-DCMAKE_PREFIX_PATH={state.prefix_path}', ] - prefix_map = f'-ffile-prefix-map={state.source}/=' opts = state.options - opts['CMAKE_C_FLAGS'] += prefix_map - opts['CMAKE_CXX_FLAGS'] += prefix_map - - if ldflags := self.extra_linker_flags(): - opts['CMAKE_EXE_LINKER_FLAGS'] += ldflags - opts['CMAKE_SHARED_LINKER_FLAGS'] += ldflags + opts['CMAKE_C_FLAGS'] += state.compiler_flags() + opts['CMAKE_CXX_FLAGS'] += state.compiler_flags() + opts['CMAKE_EXE_LINKER_FLAGS'] += state.linker_flags() + opts['CMAKE_SHARED_LINKER_FLAGS'] += state.linker_flags() if state.xcode: args.append('-GXcode') diff --git a/aedi/target/library_tier1.py b/aedi/target/library_tier1.py index e8589da1..0296ab43 100644 --- a/aedi/target/library_tier1.py +++ b/aedi/target/library_tier1.py @@ -17,6 +17,7 @@ # import os +import shlex import shutil import subprocess from pathlib import Path @@ -290,9 +291,7 @@ class MoltenVKTarget(base.MakeTarget): '-o', dynamic_lib_path, '-force_load', static_lib_path ] - - if ldflags := self.extra_linker_flags(): - args.append(ldflags) + args += shlex.split(state.linker_flags()) subprocess.run(args, check=True, env=state.environment) os.utime(dynamic_lib_path, (static_lib_time, static_lib_time))