Xcode15及低版本 -ld64适配

3,056 阅读2分钟

1. 背景

升级Xcode15之后,编译报错。具体内容如下:

Showing Recent Errors Only Assertion failed: (false && "compact unwind compressed function offset doesn't fit in 24 bits"), function operator(), file Layout.cpp, line 5758.

2. 原因

在 Xcode 的 Build Setting 中,Other Linker Flags(其他链接器标志)用于向链接器(linker)传递额外的命令行参数。其中 -ld64 是一条特定的链接器标志。

-ld64 是用于指定链接器使用 ld64 替代默认的链接器。ld64 是苹果开发的一个 Mach-O 文件格式的链接器,用于在 macOS 和 iOS 系统上进行可执行文件和动态库的链接。

将 -ld64 添加到 Other Linker Flags 中,告诉 Xcode 使用 ld64 链接器来构建项目。这通常用于特定的需求,例如需要使用 ld64 才能实现的高级功能或特定的优化。

请注意,在大多数情况下,不需要手动添加 -ld64 到 Other Linker Flags 中,因为 Xcode 默认会选择正确的链接器。只有在特定的情况下需要使用 ld64 或需要进行自定义配置时,才需要添加该链接器标志。

源代码 > 预处理器 > 编译器 > 汇编器 > 机器码 > 链接器 > 可执行文件

3. 解决方案

由于大家使用的Xcode版本不一致,Xcode15需要新增配置参数才能编译通过,但是新增配置在低版本的Xcode无法编译通过。所以针对工程podfile进行修改,根据Xcode版本进行动态添加参数,以解决多人协作冲突问题。

post_install do |installer|

  main_project = Xcodeproj::Project.open("xxxxx.xcodeproj") # 替换成你的主工程名称
  xcode_version = `xcrun xcodebuild -version | grep Xcode | cut -d' ' -f2`.to_f
 # 修改主工程的配置
  main_project.targets.each do |target|
    if target.name == 'xxx'  # 替换成你的主工程名称
        target.build_configurations.each do |config|
          target_OtherFlags = config.build_settings["OTHER_LDFLAGS"]
            if xcode_version >= 15
                if target_OtherFlags.include? '-ld64'
                   print("已经包含 -ld64 配置参数")
                else
                   config.build_settings["OTHER_LDFLAGS"] = target_OtherFlags << '-ld64'
                end
            else
              if target_OtherFlags.include? '-ld64'
                target_OtherFlags.delete('-ld64')
              end
            end
            if config.name == 'Debug'
              config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
            else
              config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
            end
        end
    end
  end
  # 保存修改
  main_project.save
end

针对个推崩溃,xcode15上最低支持版本是ios12。这里的解决方案是在debug环境下将最低版本改为12,release保持不变。

4. 推荐阅读

深入 iOS 静态链接器(一)— ld64