swiftlang / swift-package-manager

The Package Manager for the Swift Programming Language
Apache License 2.0
9.72k stars 1.34k forks source link

The Swift build system can sometimes skip necessary rebuilds and result in link errors when using local packages. #7715

Open omochi opened 3 months ago

omochi commented 3 months ago

Is it reproducible with SwiftPM command-line tools: swift build, swift test, swift package etc?

Description

The conditions under which this issue occurs are complex, but we were able to create a project that reproduces it. You can reproduce it with the following repository:

https://github.com/omochi/swift-deps-rebuild-bug

Follow these steps to reproduce the issue:

$ git clone https://github.com/omochi/swift-deps-rebuild-bug
$ cd swift-deps-rebuild-bug
$ ./repro.bash

If a link error appears at the end of the script execution, the issue has occurred.

Below, the repository structure and the script’s process are explained.

This project consists of two packages: the AppPackage package, which implements the main application, and the ToyboxPackage package, which is referenced as a dependency via a local relative path.

Initially, AppPackage can be built with $ swift build.

Next, add b: Int = 0 as an argument to ToyboxCore.toyDebug. Since this is a source-compatible change, it is expected that AppPackage can be built again without modification using $ swift build.

However, in practice, a link error occurs as shown below:

error: link command failed with exit code 1 (use -v to see invocation)
Undefined symbols for architecture arm64:
  "ToyboxCore.toyDebug(a: Swift.Int) -> ()", referenced from:
      AppModule.App.main() -> () in App.swift.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: fatalError
[9/14] Linking app

In this state, you cannot proceed without performing $ swift package clean. In a practical setting, this breaks incremental builds and forces a rebuild of thousands of files, which is very inconvenient.

Expected behavior

In an originally buildable project, after making source-compatible changes, running $ swift build again should succeed.

Actual behavior

Link errors may occur.

Steps to reproduce

$ git clone https://github.com/omochi/swift-deps-rebuild-bug
$ cd swift-deps-rebuild-bug
$ ./repro.bash

Swift Package Manager version/commit hash

Swift Package Manager - Swift 5.10.0-dev

Swift & OS version (output of swift --version ; uname -a)

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: arm64-apple-macosx14.0

Darwin omochi-mbp.local 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:14:38 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6020 arm64