Should SwiftPM diagnose missing dependencies?

i wasted a lot of time today trying to debug an issue, which ended up being because SwiftPM was not actually recompiling my code when performing incremental builds.

this happened because a test target description in Package.swift did not actually declare a (direct) dependency on the library target being tested. i am not sure how this test target could have possibly passed validation in the first place.

should SwiftPM be diagnosing missing dependencies?

4 Likes

There are a number of open issues (and one merged PR) related to this:

To me it looks as if Swift compiler and SwiftPM made no checks for whether an import has a matching dependency declaration in the package file for the current target being built, or even another target that the current one (transitively) depends on!

Instead of checking dependency graph first, the compiler seems to happily continue as long as a previously built module matching that import is found in the build directory.

This lack of discipline in SwiftPM is a constant source of problems for us: things very easily seem to work on my computer, and even a coworker's, until the project's dependency graph is rebuilt in a slightly different order maybe and the missing dependency now causes the import to fail.

12 Likes

so if anyone is stumbling on this, the --explicit-target-dependency-import-check=error option can be used to raise an error when this situation arises.

i now wonder if there is a way to add this setting to the Package.swift, so that it is always enabled. is this possible?

11 Likes

Have you tried?

swiftSettings: [
   .unsafeFlags(["-Xfrontend", "-explicit-target-dependency-import-check"])
]

This fails for me. I get:

<unknown>:0: error: unknown argument: '-explicit-target-dependency-import-check'
Command SwiftEmitModule failed with a nonzero exit code

In my Package.swift:

// swift-tools-version: 5.10
1 Like

I faced the same issue and I decided to create my own swift build plugin that let me know if my source code is using any transitive dependency.