Skip to content

Latest commit

 

History

History
85 lines (69 loc) · 5.14 KB

File metadata and controls

85 lines (69 loc) · 5.14 KB

iOS 构建错误:__swift_FORCE_LOAD_$_swiftCompatibility56 未定义符号(arm64)

本文记录在 iOS 工程(常见于集成 Firebase 时)出现如下链接错误的根因、最优解与临时修复步骤:

Undefined symbols for architecture arm64:
  "__swift_FORCE_LOAD_$_swiftCompatibility56", referenced from:
      __swift_FORCE_LOAD_$_swiftCompatibility56_$_FirebaseCoreInternal in FirebaseCoreInternal[...]
ld: symbol(s) not found for architecture arm64

适用范围

  • Xcode/Swift 版本高于部分三方库(例如旧版 FirebaseCoreInternal)的编译版本。
  • 工程在最终链接阶段没有自动把 Swift 兼容库拉入,导致缺失 libswiftCompatibility56

根因分析(Root Cause)

  • 依赖中包含以 Swift 5.6 构建/要求的目标,其对象文件内含强制加载符号 __swift_FORCE_LOAD_$_swiftCompatibility56
  • 当前工具链(Xcode/Swift)更高,需通过“Swift 兼容库”来保证运行时 ABI 行为一致。
  • 当主 Target 没有触发 Swift 驱动的自动链接(或相关设置不当)时,libswiftCompatibility56 未被加入链接,导致未定义符号错误。

常见触发条件:

  • 使用较旧的 Firebase 组件(如 FirebaseCoreInternal
  • 主 App Target 含 Objective‑C/纯 C++,缺少 Swift 文件,未触发自动链接
  • Always Embed Swift Standard Libraries 未开启

最优解决方案(推荐)

以“消除对兼容库的需求”为目标,统一工具链与依赖的 Swift 版本:

  • 升级 Xcode 至当前稳定版
  • 升级 Firebase 至与该 Xcode 兼容的最新版本
    • CocoaPods:pod repo update && pod update
    • SwiftPM:更新到最新版本
  • 清理并全量重建(删除 DerivedData 或 Product → Clean Build Folder)

说明:新版 Firebase 通常不再触发对 swiftCompatibility56 的强制加载,升级后问题即可自然消失。

临时修复(无法立即升级时)

目标:让链接器既“找到”又“链接进来” libswiftCompatibility56

  1. 使用 Linker Flags:
  • Target → Build Settings → Other Linker Flags,添加:
    • -L$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)
    • -lswiftCompatibility56
  • 若仍出现相近符号缺失,可按需补充:
    • -lswiftCompatibilityConcurrency
    • -lswiftCompatibilityDynamicReplacements
  1. 直接添加 .tbd:
  • Target → Build Phases → Link Binary With Libraries → “+”
    • 添加 libswiftCompatibility56.tbd
    • 必要时再加 libswiftCompatibilityConcurrency.tbdlibswiftCompatibilityDynamicReplacements.tbd
  1. 其他建议:
  • Target → Build Settings:Always Embed Swift Standard Libraries = YES(Debug/Release 均设)
  • 若使用 CocoaPods,确保改动作用于“App 主 Target”(最终链接处),而非 Pods 子目标
  • 执行 Product → Clean Build Folder 后重编译

路径与占位符说明

  • $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) 比硬编码 $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/... 更稳健
  • 设备:$(PLATFORM_NAME)=iphoneos
  • 模拟器(Apple Silicon):$(PLATFORM_NAME)=iphonesimulator

常见误区

  • 在 Other Linker Flags 中写成 L=... 或缺少连字符,正确应为:-L...
  • 只添加搜索路径并不会自动链接库本身,仍需 -lswiftCompatibility56 或显式添加对应 .tbd

排查 Checklist

  • Xcode、Firebase 是否为最新兼容版本
  • Always Embed Swift Standard Libraries = YES
  • Other Linker Flags 是否包含:-L$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)-lswiftCompatibility56
  • 是否已在“Link Binary With Libraries”中添加 libswiftCompatibility56.tbd(若使用该方式)
  • 已清理构建缓存并重新编译

FAQ:为何 s.swift_version = 5.9 仍出现 swiftCompatibility56?

  • swiftCompatibility56 是自 Swift 5.6 起引入的“兼容垫片”库名称,后续的 5.7/5.8/5.9 仍沿用这一命名;看到它并不代表库是用 Swift 5.6 编译的。
  • 报错里的 __swift_FORCE_LOAD_$_swiftCompatibility56 来自某些桥接/混编的对象文件(例如 _ObjC_*.o),用于“强制链接”该兼容库,确保在更高 Swift 工具链下保持 ABI/运行时行为一致。
  • 因此,即便 Podspec 中 s.swift_version = '5.9',只要最终链接阶段没有把 libswiftCompatibility56 加入,依然会出现未定义符号错误。
  • 处理方式不变:
    • 优先升级 Xcode 与 Firebase,使工程不再需要该兼容垫片;
    • 无法升级时,在 App 主 Target 开启 Always Embed Swift Standard Libraries,并通过 -L$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)-lswiftCompatibility56 或添加 libswiftCompatibility56.tbd 完成手动链接;
    • 主 Target 若为纯 ObjC/Cpp,可添加一个空 Swift 文件以触发 Xcode 自动注入 Swift 运行时与兼容库路径。

结论

  • 根因:链接阶段缺失 libswiftCompatibility56(Swift 5.6 兼容库),由依赖与工具链版本不一致且未自动链接导致。
  • 最优解:升级 Xcode 与 Firebase,使工程不再依赖该兼容库。
  • 临时解:通过 -L-l 或直接添加 .tbd 手动完成链接,并启用 Swift 标准库嵌入。