From bde88a27ce09d62acf3038e36742b349164fef9c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 8 Oct 2023 10:34:55 +0300 Subject: [PATCH] aedi: add fix for xcode 15.0 linker issue https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#Known-Issues --- aedi/target/base.py | 31 ++++++++++++++++++++++++++++++- aedi/target/library_tier1.py | 8 ++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/aedi/target/base.py b/aedi/target/base.py index 8710dcef..a95ac023 100644 --- a/aedi/target/base.py +++ b/aedi/target/base.py @@ -96,7 +96,8 @@ class BuildTarget(Target): 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('LDFLAGS', f'-L{state.lib_path}') + ldflags = f'-L{state.lib_path} {self.extra_linker_flags()}' + state.update_flags_environment_variable('LDFLAGS', ldflags) # Avoid timestamp only differences in static libraries env['ZERO_AR_DATE'] = '1' @@ -259,6 +260,30 @@ 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, 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): @@ -392,6 +417,10 @@ class CMakeTarget(BuildTarget): f'-DCMAKE_PREFIX_PATH={state.prefix_path}', ] + if ldflags := self.extra_linker_flags(): + args.append(f'-DCMAKE_EXE_LINKER_FLAGS={ldflags}') + args.append(f'-DCMAKE_SHARED_LINKER_FLAGS={ldflags}') + if state.xcode: args.append('-GXcode') else: diff --git a/aedi/target/library_tier1.py b/aedi/target/library_tier1.py index cc232cb1..e749da9c 100644 --- a/aedi/target/library_tier1.py +++ b/aedi/target/library_tier1.py @@ -271,7 +271,7 @@ class MoltenVKTarget(base.MakeTarget): dynamic_lib_time = os.stat(dynamic_lib_path).st_mtime if os.path.exists(dynamic_lib_path) else 0 if static_lib_time != dynamic_lib_time: - args = ( + args = [ 'clang++', '-stdlib=libc++', '-dynamiclib', @@ -290,7 +290,11 @@ class MoltenVKTarget(base.MakeTarget): '-framework', 'Foundation', '-o', dynamic_lib_path, '-force_load', static_lib_path - ) + ] + + if ldflags := self.extra_linker_flags(): + args.append(ldflags) + subprocess.run(args, check=True, env=state.environment) os.utime(dynamic_lib_path, (static_lib_time, static_lib_time))