Xcode 13 错误:输入文件 [...] 在构建期间被修改

Posted

技术标签:

【中文标题】Xcode 13 错误:输入文件 [...] 在构建期间被修改【英文标题】:Xcode 13 error: input file [...] was modified during the build 【发布时间】:2021-11-14 06:27:17 【问题描述】:

Xcode 13 让我很难构建我的项目,该项目由具有生成代码的构建阶段的目标组成。

例如一个构建阶段通过简单地使用一个将一些代码回显到该文件中的 shell 脚本来生成文件Secrets+Generated.swift

构建阶段将该文件定义为输出文件。没有输入文件,没有输入文件列表,也没有输出文件列表,因为只有一个文件被创建/修改。

几乎在构建项目时,构建失败:

error: input file '[ProjectPath]/Secrets+Generated.swift' was modified during the build
error: input file '[ProjectPath]/Secrets+Generated.swift' was modified during the build
Command CompileSwiftSources failed with a nonzero exit code

有没有人遇到过这个问题或知道该怎么做?我尝试切换复选框“基于依赖分析”,但这没有帮助。我在使用 Xcode 12 时没有遇到这个问题。值得注意的是重复的错误消息,尽管只有一个构建阶段生成该特定文件。

顺便说一句。我在使用 swiftgenSourceryCuckoo 等代码生成工具时遇到了同样的问题。

编辑:这是我的构建阶段: 三个标记的构建阶段都会生成一个这样的文件。他们都偶尔失败。我不知道这是否会有所不同,但这些只是为一个目标(通知服务扩展)定义的,它是我的主应用程序目标的依赖项,所以它只会在我构建应用程序时触发一次。

【问题讨论】:

您将运行脚本阶段放在构建阶段的什么位置? @Palle:请看我的编辑。 嗯,我有类似的代码生成阶段,据我所知,Swift 从未抱怨过。唯一的区别是这些脚本都作为主应用程序构建的一个阶段运行。是否可以将文件作为主应用程序构建的一部分编写,并将其目标成员资格也设置为通知服务扩展? 自早期 Xcode 13 测试版以来遇到同样的问题。它仍然在官方版本中发生。在我们的例子中,错误发生在 R.swift。 Xcode 13 版本中仍在发生... 【参考方案1】:

我正在调试similar issue in R.swift,我想我已经找到了问题的原因。

Xcode 13 似乎在索引构建期间执行运行脚本构建阶段。这可能会导致文件被索引传递写入,与构建并行。

要检查您是否正在发生这种情况,请将其添加到您的构建脚本中:say $ACTION 在 Xcode 12 上,它只说“build”,但在 Xcode 13 中,我在编译期间听到它说“indexbuild”,每当我保存 .swift 文件或以其他方式浏览我的代码时。

为防止您的脚本在索引期间运行,请添加此检查:

if [ $ACTION != "indexbuild" ]; then
  # your script here 
fi

【讨论】:

太棒了——这解决了问题!谢谢。 谢谢,它解决了我的构建问题! 为什么不呢? if [ $ACTION == "build"]; then ... 强大的侦探@Tom Lokhorst,我今天在 XC13 中努力摆脱不必要的重建和偶尔的构建失败,这似乎有帮助 @malaba 还有 [ ACTION = "install" ]。当构建由 fastlane 的健身房启动时,它使用“安装”。排除 indexbuild 可能更容易。【参考方案2】:

编辑 2: 上面 Tom Lokhorst 的解决方案似乎是解决此问题的正确方法:https://***.com/a/69481200/12117100

编辑: 原来的解决方案有问题。尝试构建测试目标的 Xcode 12.5 用户将收到错误 Build input file cannot be found...,因为生成 GeneratedMocks.swift 的脚本可能会在构建开始后运行。

似乎对 Xcode 12.5 和 Xcode 13 都有效的方法是将其添加到 cuckoo-output.xcfilelist(随便命名)文件:

$PROJECT_DIR/$PROJECT_NAMETests/GeneratedMocks.swift

并将该 xcfilelist 添加到运行脚本的输出文件列表中,而不是直接在输出文件中添加到 GeneratedMocks.swift 的路径。

原文:

我在 Xcode 13 中首次设置 Cuckoo 并在运行脚本的输出文件部分包含 $PROJECT_DIR/$PROJECT_NAMETests/GeneratedMocks.swift 后遇到了这个问题。

现在从输出文件中删除路径似乎可以解决问题。

【讨论】:

这似乎也适用于我,使用生成文件的自定义脚本,但我担心潜在的副作用。这难道不会破坏某些东西吗? 是的,你是对的,我已经用一个似乎可行的解决方案更新了解决方案,但我们将不胜感激【参考方案3】:

不幸的是,Copripop 提出的解决方法至少不适用于 Cuckoo 的设置。但是现在很少出现编译错误了。

但是我从苹果那里得到了一个官方的回答,这个错误是按预期发生的,因为在构建作业期间修改了输入文件。据我了解,这是因为构建阶段可以并行运行。在 Xcode 13 之前,当输出文件定义适合具有相同文件的下一阶段的输入文件时,避免了并行执行。这似乎在 Xcode 13 中被打破了。

尽管如此,答案包含有关如何解决非 Cuckoo 设置问题的提示。它建议使用在编译构建阶段执行的构建规则。这里是该主题的带有时间标记的链接:https://developer.apple.com/videos/play/wwdc2021/10210/?time=379

构建规则可以定义为通过命名约定匹配源文件,然后正确运行脚本。构建规则的输出文件会自动设置为编译构建阶段。所以这不应该在那里定义。

希望这有助于一些人解决问题,因为他们能够通过命名约定定义匹配。我没有为 Cuckoo 找到好的方法。

顺便说一句:Cuckoo 已经有一个问题:https://github.com/Brightify/Cuckoo/issues/400

【讨论】:

【参考方案4】:

遇到了完全相同的问题。我可以通过将使用的 shell 从 /bin/sh 更改为 /bin/zsh 来解决它。不过,不要问我为什么会这样。

【讨论】:

这似乎对我有用了一段时间,然后就停止了。切换回/bin/sh 又工作了一段时间,然后停止工作。另外,我注意到 Xcode 13 总是执行该步骤,而 Xcode 12 会跳过它(基于输入和输出列表)? 还看到它停止工作。我认为这是 Xcode 和命令行(fastlane)的差异,但无法确认。【参考方案5】:

我在 WooCommerce ios 项目中遇到了同样的问题,我们使用该聚合目标在构建时生成带有机密的 .swift 文件。

This PR 似乎可以解决这个问题。我说这似乎是因为我从那以后就没有经历过,但我也不能 100% 确定问题已经消失,因为它并没有 100% 发生在我的构建中。

我认为可能的诀窍是使构建阶段运行脚本输入和输出文件定义同质化。之前,我们通过.xcfilelist 设置输入,通过 Xcode UI 设置输出。现在我们use a .xcfilelist for both。

老实说,这对我来说似乎是一个 Xcode 错误 ?

【讨论】:

以上是关于Xcode 13 错误:输入文件 [...] 在构建期间被修改的主要内容,如果未能解决你的问题,请参考以下文章

构建 Xcode UITest 失败并出现“打开输入文件时出错”

Xcode 13 和 Flutter 2.5.1 - 致命错误:找不到“Flutter/Flutter.h”文件 #import <Flutter/Flutter.h>

未找到 xcode 13 可执行文件

iOS 13 和 Xcode 11 中的配置文件问题中缺少 NFC 标签协议

Xcode 8.2,Swift 编译器错误:错误:意外的输入文件

Xcode 9.4致命错误:lipo:无法打开输入文件(没有这样的文件或目录)