Xcode 13 error: input file [...] was modified during the build

Xcode 13 error: input file [...] was modified during the build

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

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

构建阶段将该文件定义为输出文件。没有输入文件,没有输入文件列表,也没有输出文件列表,因为只有一个文件是 created/modified.

几乎每次构建项目时,构建失败:

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.[=14 等代码生成工具时遇到同样的问题=]

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

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

编辑 2: 上面 Tom Lokhorst 的解决方案似乎是解决此问题的正确方法:

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

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

${PROJECT_DIR}/${PROJECT_NAME}Tests/GeneratedMocks.swift

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

原文:

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

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

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

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

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

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

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

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

中被打破了

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

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

希望这能帮助一些人解决问题,当他们能够通过命名约定定义匹配时。我没有找到布谷鸟的好方法。

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

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

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

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

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

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