skip to Main Content

Xcode 13 gives me a hard time building my project which consists of targets with build phases that generate code.

E.g. one build phase generates the file Secrets+Generated.swift by simply using a shell script that echoes some code into that file.

enter image description here

The build phase defines that file as an output file. No input file, no input file list and no output file list, as only that one file is created/modified.

Almost all the time when building the project, the build fails:

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

Has anyone encountered that issue or knows what to do? I tried toggling the checkbox "Based on dependency analysis", but that didn’t help. I didn’t have that issue when using Xcode 12. Interesting to note is the duplicate error message despite having only one build phase generating that particular file.

Btw. I get the same problem when using code generation tools like swiftgen, Sourcery or Cuckoo.

Edit: Here are my build phases:
enter image description here
The three marked build phases all generate one such file. All of them fail occasionally. I do not know if that makes a difference, but these are defined for only one target (Notification Service Extension) which is a dependency of my main app target, so it gets triggered only once when I build the app.

5

Answers


  1. Had the exact same problem. I was able to solve it by changing the used shell from /bin/sh to /bin/zsh. Don’t ask me why that works, though.

    setting the shell

    Login or Signup to reply.
  2. EDIT 2:
    Tom Lokhorst’s solution above seems to be the right way to resolve this: https://stackoverflow.com/a/69481200/12117100

    EDIT:
    There is an issue with the original solution. Xcode 12.5 users who try to build the test target will get the error Build input file cannot be found... as the script that generates GeneratedMocks.swift might be run after the build starts.

    Something that seems to work for both Xcode 12.5 and Xcode 13 is to add this to a cuckoo-output.xcfilelist (name it whatever you want) file:

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

    and add that xcfilelist to the Run Script’s Output File Lists instead of adding the path to GeneratedMocks.swift directly in Output Files.

    Original:

    I had this issue after setting up Cuckoo for the first time in Xcode 13 and including ${PROJECT_DIR}/${PROJECT_NAME}Tests/GeneratedMocks.swift in the Output Files section of the Run script.

    Removing the path from Output Files seems to do the trick for now.

    Login or Signup to reply.
  3. I’ve experienced the same issue in the WooCommerce iOS project the aggregate target we use to generate a .swift file with secrets at build time.

    This PR seems to fix the issue. I say seems because I haven’t experienced it since, but I am also not 100% sure that the issue is gone, because it wasn’t occurring 100% of the builds for me.

    What I think might have done the trick was making the build phase run script input and output files definition homogeneous. Previously, we set the inputs via .xcfilelist and outputs via the Xcode UI. Now we use a .xcfilelist for both.

    Honestly, this seems like an Xcode bug to me 🙊

    Login or Signup to reply.
  4. Unfortunately the proposed workaround by Copripop does not work at least for the setup with Cuckoo. But the compile error occurs much more seldom now.

    But I got an official answer from apple that this error occurs as expected because the input file is modified during the build job. As I understood that happens because the build phases can run in parallel. Before Xcode 13 the parallel execution was avoided when the output file definition fit to the input file of the next phase with the same file. This seems to be broken in Xcode 13.

    Nevertheless the answer contained a hint about how to solve the problem for not Cuckoo setups. It recommends to use build rules, which are executed during the compile build phase. Here the link with a time marker for this topic: https://developer.apple.com/videos/play/wwdc2021/10210/?time=379

    The build rule can be defined as matching the source file by naming convention and then run the script correctly. The output files from the build rules are automatically set to the compile build phase. So this should not be defined there.

    Hopefully this helps some people to solve the problem, when they are able to define a match by naming convention. I did not find a good approach for Cuckoo.

    Btw: There is already an issue opened for Cuckoo: https://github.com/Brightify/Cuckoo/issues/400

    Login or Signup to reply.
  5. I’m debugging a similar issue in R.swift, I think I’ve found the cause of the issue.

    Xcode 13 appears to execute Run Script build phases during index builds. This can cause a file to be written to by an index pass, in parallel with a build.

    To check if this is happening for you, add this to your build script: say $ACTION
    On Xcode 12, it only says "build", but in Xcode 13 I hear it saying "indexbuild" during compilation, whenever I save .swift files or otherwise navigate through my code.

    To prevent your script from running during indexing, add this check:

    if [ $ACTION != "indexbuild" ]; then
      # your script here 
    fi
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search