在Xcode 11上,我的.xcassets在Xcode 10上没有引起任何问题,导致编译失败并显示以下消息:
错误:多个命令产生了'/Users/user/Library/Developer/Xcode/DerivedData/project-enjiypsgxtcdbnaripixgtnjlagx/Build/Products/Debug-iphonesimulator/project.app/Assets.car':
1)目标“项目”(项目“项目”)具有带有输入“ /Users/user/sandbox/project/Resources/buttons.xcassets”的编译命令
2)该命令取决于目标“项目”(项目“项目”)中的命令:脚本阶段“ [CP]复制容器资源”
我能够编译项目的唯一方法是从目标中删除.xcassets,明显的缺点是它们在构建中不可用。
PS:这发生在2个ObjC项目中。
答案 0 :(得分:14)
答案 1 :(得分:6)
answer above仅部分正确:是的,这是因为pod阶段会生成 Assets.car 作为输出文件,该文件与您的 xcassets的输出名称一致-从而出现Multiple commands produce...
错误:一个命令是脚本阶段[CP] Copy Pods Resources
,另一个是您自己项目的compile命令。
但是从输出文件中删除 Assets.car 会导致构建系统无法看到脚本正在处理该文件,因此会跳过该文件(更多信息,请阅读this)。因此,我们可以做的是将 add Assets.car 添加到 input 文件-这将为脚本创建一个依赖项,告诉构建系统执行以下操作:等待文件,然后再执行脚本。
注意:与上述解决方案一样,您每次更新pod后都必须执行此操作,因为每次运行[CP] Copy Pods Resources
或pod install
都会生成pod update
答案 2 :(得分:2)
如果有一些pod使用'resources'(不是'resources_bundle')链接到podspec中自己的xcasset,请检查您的依赖项。 不建议使用这种方法,因为其输出文件名为“ Assets.car”。与项目xcassets的编译输出名称相同。
答案 3 :(得分:1)
Xcode->文件->工作区设置->构建系统->旧版构建系统
答案 4 :(得分:1)
在您的库项目(例如“ LADetailPage”)中,打开Targets的“ Build Phases”,创建一个名为“ Copy Files”的预定义阶段,然后将* .xcassets拖到新阶段。
该库不会创建“ Assets.car”,而是将* .xcassets复制到您的项目中,然后主项目将构建* .xcassets并将所有* .xcassets集成到单个{{1} }文件。
答案 5 :(得分:0)
为确保所有构建步骤均以正确的顺序执行,而又要尽可能多地并行执行,Xcode需要为每个构建步骤都知道它依赖于哪些输入文件以及它将生成哪些输出文件。 >
例如如果步骤A依赖于输入文件,而该输入文件是步骤B的输出文件,则肯定必须在步骤A之前运行步骤B。如果两个步骤都不需要另一步骤的输出文件,则它们都可以并行运行。
尽管几个步骤可以肯定地依赖于同一个输入文件,但不可能有多个步骤生成相同的输出文件,无论哪个步骤最后执行都会覆盖第一个步骤的输出文件,这意味着结果输出文件的内容将是不可预测的,这是在构建过程中将产生可预测结果的错误!
对于您而言,问题是您的“复制资源”构建阶段包含一个(或多个).xcassets
捆绑包。 Xcode不仅会复制这些捆绑包,还会将它们组合,转换和优化其内容,并创建一个名为Assets.car
的文件,其中包含项目中所有资产目录的内容。
但是,如果您集成Pod并且该Pod也具有资产目录,则将发生完全相同的事情,并且创建了第二个Assets.car
文件,现在Xcode出现了问题:两个构建步骤都说他们创建了一个Assets.car
个文件。哪一个赢?这两个文件中的哪一个将在最终应用程序中结束?那么依赖此文件的其他步骤又如何呢?在必须执行哪些构建步骤之后?这是Xcode无法解决的严重问题。
目前有两种可能的解决方案:
使用框架。当您使用框架而不是静态库时,Pods的资源不会最终位于主应用程序的resources文件夹中,而是最终位于已构建框架的resources文件夹中。您需要做的就是将use_frameworks!
添加到Podfile中,无论是顶层的还是针对特定目标的。缺点是您的整体应用程序大小会增加一点,而应用程序启动时间则会减少一点。
让Pod作者修复Pod。他/她应使用resources
而不是resources_bundle
,因为Podspec文档也强烈建议使用。使用resources
实际上还有其他缺点(未优化资源文件,不同Pod之间可能会发生名称冲突),而使用资源包是安全的,无论Pod是作为静态库还是作为动态框架嵌入的。但是请注意,仅仅改变Podspec是不够的,必须采用所有加载bundle资源的代码来从正确的bundle中加载资源(在Podspec文件中使用resources_bundle
时,名称将被称为您还必须给捆绑包起一个名字)。
有关此问题的持续错误报告,可以在这里找到:
https://github.com/CocoaPods/CocoaPods/issues/8122
当前的问题是,除了上述两种解决方案之外,每种可能的解决方案基本上都是丑陋的,而Cocoapods开发人员并不乐于实现丑陋的hack。似乎很难解决的最佳解决方案可能是根本不解决该问题,而是停止在Podspec文件中支持resources
,并使resources_bundle
对包含自己资源的Pod成为必需。