34

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

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

在此处输入图像描述

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

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

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等代码生成工具时,我遇到了同样的问题。

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

4

5 回答 5

37

在 R.swift 中调试了一个类似的问题,我想我已经找到了问题的原因。

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

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

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

if [ $ACTION != "indexbuild" ]; then
  # your script here 
fi
于 2021-10-07T12:31:21.657 回答
3

编辑 2: Tom Lokhorst 的上述解决方案似乎是解决此问题的正确方法:https ://stackoverflow.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_NAME}Tests/GeneratedMocks.swift

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

原来的:

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

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

于 2021-09-27T11:47:56.920 回答
2

不幸的是, 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

于 2021-10-01T07:25:41.580 回答
0

有完全相同的问题。我能够通过将使用的外壳从 更改为 来解决/bin/sh/bin/zsh。不过,不要问我为什么会这样。

设置外壳

于 2021-09-24T07:19:47.643 回答
-2

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

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

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

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

于 2021-09-29T06:35:23.573 回答