Swift与Xcode中重复输出文件警告的抑制及根源问题解决
问题背景
我有两个基于swift-collections(核心使用OrderedDictionary)构建的库,集成到应用后出现以下编译警告:
warning build: duplicate output file '/Users/.../Library/Developer/Xcode/DerivedData/App-cwrrsvcoeaygnffemipxjzcyspgp/Build/Products/Debug/Frameworks/OrderedCollections_1222128174265B56_PackageProduct.framework/Versions/A/_CodeSignature' on task: CodeSign /Users/.../Library/Developer/Xcode/DerivedData/App-cwrrsvcoeaygnffemipxjzcyspgp/Build/Products/Debug/Frameworks/OrderedCollections_1222128174265B56_PackageProduct.framework/Versions/A
原本以为只是警告,查看构建日志后发现应用并未构建成功(使用Xcode 14 beta 3,问题导航器仅显示警告未展示错误),日志中的实际错误为:
Multiple commands produce '/Users/.../Library/Developer/Xcode/DerivedData/App-cwrrsvcoeaygnffemipxjzcyspgp/Build/Products/Debug/Frameworks/OrderedCollections_1222128174265B56_PackageProduct.framework/Versions/A/OrderedCollections_1222128174265B56_PackageProduct'
为复现问题,我创建了新工作区,包含两个库和一个命令行工具,工具调用两个库的方法。Library A和Library B均依赖swift-collections(OrderedDictionary):
复现代码
命令行工具 main.swift
import Foundation import Library_A import Library_B print("Hello, World!") useA() useB()
Library A mainA.swift
import Foundation import OrderedCollections public func useA() { let dictionary: OrderedDictionary<String,String> = [ "a": "A", "b": "B" ] print("hello world from a: \(dictionary.count)") }
Library B mainB.swift
import Foundation import OrderedCollections public func useB() { let dictionary: OrderedDictionary<String,String> = [ "a": "A", "b": "B" ] print("hello world from b: \(dictionary.count)") }
两个库单独编译正常,但构建工具时出现上述警告和错误。
解决方法
1. 统一依赖版本与管理(推荐)
确保两个库和主应用使用同一版本的swift-collections,借助Swift Package Manager(SPM)的依赖合并机制避免重复构建:
- 检查Library A和Library B的
Package.swift文件,将swift-collections的版本约束设置为完全一致(比如都写.upToNextMajor(from: "1.0.0")或指定固定版本)。 - 主应用通过SPM依赖两个库时,SPM会自动合并相同依赖,只构建一次
swift-collections框架,从根源避免冲突。
2. 修改Xcode构建设置(临时规避)
如果使用Xcode项目而非SPM管理依赖,可临时开启允许重复产物的选项:
- 进入主应用的Build Settings,找到Build Options下的Allow Multiple Commands to Produce the Same File,设置为
YES。 - 注意:这只是权宜之计,可能隐藏其他构建问题,不建议长期使用。
3. 切换动态链接方式
将两个库对swift-collections的链接方式改为动态链接,确保主应用只加载一份框架:
- 打开Library A和Library B的项目,进入Build Settings,找到Linking下的Mach-O Type,设置为
Dynamic Library。 - 动态链接会让多个库共享同一份
OrderedCollections框架实例,避免重复签名和构建产物冲突。
4. 清理Xcode缓存
缓存损坏也可能导致这类问题,执行以下操作:
- 关闭Xcode,删除DerivedData目录:
rm -rf ~/Library/Developer/Xcode/DerivedData - 重新打开工作区,执行
Cmd+Shift+K清理构建文件夹,再重新构建项目。
内容的提问来源于stack exchange,提问作者cire1776

