BuildTool Plug-in. SPM Build Tool Plugin Issue in Xcode – Generated Files Not Found

Help Needed:

Hi everyone,

I've run into a frustrating issue while trying to create a build tool plugin for some targets in SPM that have associated resource bundles. I'm using Xcode, and things go wrong when I try to build the project for testing. The error I keep encountering is:

Build input file cannot be found: 'derived-data/BuildPluginExample-<hash>/SourcePackages/plugins/common.output/Common/PackageBundlePlugin/ResourceBundle.g.swift'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it? (in target 'Common' from project 'Common')

What's Happening

From my investigation (using build logs and Assistant in Xcode), it looks like the build graph is getting calculated incorrectly. Even though I’ve double-checked all the dependencies (which seem correct), one of the dependent targets (Common) tries to build before the build plugin has finished generating the necessary files. Naturally, this causes the build to fail.

Reproduction Sample

I’ve created a sample project that reproduces this behavior. Through testing, I’ve noticed a few things:

  1. Common package can be built successfully on its own
    When building the Common package individually using swift build or xcodebuild (in Xcode), the build tool plugin works as expected and the generated file is created.

  2. Fails only on the first build
    After the first successful execution of the build tool plugin, subsequent builds work fine, and the project compiles without issues. However, if the derived data folder is cleared, the problem reappears, which makes this approach unsuitable for CI pipelines or when working across different developer environments.

  3. Only happens when building for testing
    The issue occurs only when building for testing. When building the app to run (not for testing), the generated file is correctly created, and the build completes without errors. The generated resource bundle paths work as expected.

  4. Linking behavior differs between build types
    Due to differences in how dependencies are handled, the behavior of the Common target can become unpredictable. During a release build, Common is linked statically, but during testing, it is linked dynamically. This seems to affect the behavior of the build tool plugin, resulting in inconsistent builds depending on whether the library is statically or dynamically linked.

    I’ve found that setting the Common library to be linked dynamically resolves the issue with the build tool plugin. However, this change could introduce other problems, such as regressions in the application’s bootstrap process in production environments.

What I Need Help With

I'm looking for any advice or guidance on how to resolve or work around this issue.

Specifically:

  • How can I ensure the generated file from the build tool plugin is always produced before dependent targets are built?
  • Is there a better way to handle dynamic/static linking in this context to prevent these inconsistencies?

Additional Context

The original issue I was trying to solve with the build tool plugin was related to incorrect or missing resource bundle paths in the generated Bundle.module definition.

Any help would be greatly appreciated!

Thanks in advance!

1 Like