You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Circle CI中Detox构建iOS(xcodebuild)命令执行失败求助

解决Circle CI上React Native iOS构建时Hermes.framework重复生成问题

问题背景

在Circle CI的Macbook Pro机器运行器上执行React Native iOS项目的Detox构建时,运行以下xcodebuild命令失败:

xcodebuild -workspace ios/MyProduct.xcworkspace -UseNewBuildSystem=YES -scheme MyProduct_Dev -configuration Debug -sdk iphonesimulator clean build

报错核心为重复生成Hermes.framework:

error: Multiple commands produce '/var/opt/circleci/workdir/ios/build/Build/Products/Debug-iphonesimulator/MyProduct.app/Frameworks/hermes.framework'
    note: Target 'MyProduct' (project 'MyProduct') has copy command from '/var/opt/circleci/workdir/ios/Pods/hermes-engine/destroot/Library/Frameworks/universal/hermes.xcframework/ios-arm64_x86_64-simulator/hermes.framework' to '/var/opt/circleci/workdir/ios/build/Build/Products/Debug-iphonesimulator/MyProduct.app/Frameworks/hermes.framework'
    note: That command depends on command in Target 'MyProduct' (project 'MyProduct'): script phase “[CP] Embed Pods Frameworks”

本地环境运行正常,构建机手动通过Xcode移除Build Phases中的重复拷贝行可成功构建,但该配置行不存在于xcproj源码中,且已尝试Pods反集成、清理构建文件夹等操作无效。

解决思路与操作步骤

1. 强制Pods依赖与本地一致

CI环境中Pods拉取可能因版本更新生成与本地不一致的构建配置,可通过锁定Pod版本解决:

  • 将本地的Podfile.lock提交到版本控制库
  • 在CI构建脚本中,替换pod install为:
    pod install --no-repo-update
    
    避免CI拉取最新版本的Pods,确保生成的Build Phases与本地一致。

2. 通过Post Install脚本修正Pods生成的构建阶段

重复拷贝命令通常由Pods自动生成,可在Podfile中添加post_install脚本,移除重复的Hermes拷贝动作:

post_install do |installer|
  # 遍历主项目Target
  installer.pods_project.targets.each do |target|
    next unless target.name == "MyProduct"

    # 查找所有拷贝文件构建阶段
    target.build_phases.each do |phase|
      next unless phase.is_a?(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
      
      # 移除包含hermes.framework的拷贝项
      phase.files.reject! { |file| file.display_name == "hermes.framework" }
    end
  end

  # 保留React Native默认的post_install配置(如果原有)
  react_native_post_install(installer) if defined?(react_native_post_install)
end

修改后,CI中重新执行pod install即可自动修正构建阶段配置。

3. 命令行修改xcproj移除重复拷贝步骤

如果上述方法无效,可使用xcodeproj gem在非GUI环境下直接修改项目文件:

  • 在CI脚本中先安装依赖:
    gem install xcodeproj
    
  • 创建修正脚本fix_hermes_duplicate.rb:
    require 'xcodeproj'
    
    # 路径替换为你的项目xcproj路径
    project_path = 'ios/MyProduct.xcodeproj'
    project = Xcodeproj::Project.open(project_path)
    
    target = project.targets.find { |t| t.name == 'MyProduct' }
    abort "Target MyProduct not found" unless target
    
    # 遍历所有构建阶段,删除重复的Hermes拷贝动作
    target.build_phases.each do |phase|
      next unless phase.is_a?(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
      
      phase.files.each do |file|
        if file.display_name == 'hermes.framework'
          phase.remove_file(file)
          puts "Removed duplicate hermes.framework copy phase"
        end
      end
    end
    
    project.save
    
  • 在CI构建流程中,执行完pod install后运行该脚本:
    ruby ios/fix_hermes_duplicate.rb
    

4. 排查Xcode版本与构建系统差异

  • 检查Circle CI使用的Xcode版本是否与本地一致:在CI脚本中添加xcodebuild -version查看版本,若不一致,切换至与本地相同的Xcode版本(可通过Circle CI的Xcode环境变量配置)。
  • 尝试禁用新构建系统测试:修改xcodebuild命令,移除-UseNewBuildSystem=YES参数,或显式设置为NO:
    xcodebuild -workspace ios/MyProduct.xcworkspace -UseNewBuildSystem=NO -scheme MyProduct_Dev -configuration Debug -sdk iphonesimulator clean build
    

5. 彻底清理CI构建环境

执行更彻底的清理操作,确保无残留构建缓存:

# 删除项目构建文件夹
rm -rf ios/build
# 删除Xcode衍生数据(CI环境路径可能不同,根据实际调整)
rm -rf /var/opt/circleci/Library/Developer/Xcode/DerivedData
# 重新执行Pods安装
pod deintegrate && pod install

内容的提问来源于stack exchange,提问作者fullStackChris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:35:18