Bug: Linking multiple dynamic libraries that depend on the same target fails with ld failing due to missing files

Below is an example of a package that uses RxSwift for demonstration purposes. A library within a package depends on RxSwift-Dynamic and RxCocoa-Dynamic that are defined as dynamic in RxSwift package.

let package = Package(
    name: "swift-dynamic-test",
    products: [
        .library(
            name: "swift-dynamic-test",
            targets: ["swift-dynamic-test"]),
    ],
    dependencies: [
        .package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.5.0"),
    ],
    targets: [
        .target(
            name: "swift-dynamic-test",
            dependencies: [
                .product(name: "RxSwift-Dynamic", package: "RxSwift"),
                .product(name: "RxCocoa-Dynamic", package: "RxSwift")
            ]
        )
    ]
)

Building of swift-dynamic-test will fail with Command Ld failed with a nonzero exit code, and the actual reason underneath will be that ld uses a path /Build/Products/Debug-iphoneos/PackageFrameworks/RxSwift-Dynamic.framework/RxSwift-Dynamic while there is no RxSwift-Dynamic in RxSwift-Dynamic.framework, meanwhile there is RxSwift in the folder RxSwift.framework folder next to it. Moreover manually moving and renaming the file to the place where ld tries to find it results in a successful build. Note: There is no use of RxSwift product library in the package file and it is unclear how the whole RxSwift.framework is being built as well as why RxSwift-Dynamic.framework exists on a disk but RxSwift-Dynamic is not there, while other things are.

Errors details:

Ld /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/swift-dynamic-testTests.xctest/swift-dynamic-testTests normal (in target 'swift-dynamic-testTests' from project 'swift-dynamic-test')
    cd /Users/nleonov/projects/Temp/swift-dynamic-test
    /Applications/Xcode13.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -target arm64-apple-ios9.0 -bundle -isysroot /Applications/Xcode13.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk -L/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos -L/Applications/Xcode13.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib -F/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks -F/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks -F/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks -F/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks -F/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks -F/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos -F/Applications/Xcode13.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks -iframework /Applications/Xcode13.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks -iframework /Applications/Xcode13.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk/Developer/Library/Frameworks -filelist /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Intermediates.noindex/swift-dynamic-test.build/Debug-iphoneos/swift-dynamic-testTests.build/Objects-normal/arm64/swift-dynamic-testTests.LinkFileList -Xlinker -rpath -Xlinker /usr/lib/swift -Xlinker -rpath -Xlinker @loader_path/Frameworks -Xlinker -rpath -Xlinker @loader_path/../Frameworks -Xlinker -rpath -Xlinker @loader_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Intermediates.noindex/swift-dynamic-test.build/Debug-iphoneos/swift-dynamic-testTests.build/Objects-normal/arm64/swift-dynamic-testTests_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -fobjc-link-runtime -L/Applications/Xcode13.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos -L/usr/lib/swift -Xlinker -add_ast_path -Xlinker /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Intermediates.noindex/swift-dynamic-test.build/Debug-iphoneos/swift-dynamic-testTests.build/Objects-normal/arm64/swift_dynamic_testTests.swiftmodule -framework XCTest /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks/RxSwift-Dynamic.framework/RxSwift-Dynamic /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks/RxCocoa-Dynamic.framework/RxCocoa-Dynamic -Xlinker -dependency_info -Xlinker /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Intermediates.noindex/swift-dynamic-test.build/Debug-iphoneos/swift-dynamic-testTests.build/Objects-normal/arm64/swift-dynamic-testTests_dependency_info.dat -o /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/swift-dynamic-testTests.xctest/swift-dynamic-testTests -Xlinker -add_ast_path -Xlinker /Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Intermediates.noindex/swift-dynamic-test.build/Debug-iphoneos/swift-dynamic-test.build/Objects-normal/arm64/swift_dynamic_test.swiftmodule

clang: error: no such file or directory: '/Users/nleonov/Library/Developer/Xcode/DerivedData/swift-dynamic-test-hjhlavumahezasfjpkyaquybqqke/Build/Products/Debug-iphoneos/PackageFrameworks/RxSwift-Dynamic.framework/RxSwift-Dynamic'
Command Ld failed with a nonzero exit code

I will appreciate any suggestions or explanations why it may happen. Thanks.

I reported the issue to RxSwift project too, although assume I will be sent back to this forum as it seems something SPM-related. Issue link — Linking multiple SPM dynamic libraries towards the same target ends up in failure. · Issue #2424 · ReactiveX/RxSwift · GitHub

It seems it is common for any setup where two libraries from a package are imported, where one is dynamic and another one is not and there is interdependency between them. Here is an example from Apollo with exactly the same error.

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

let package = Package(
  name: "Apollo",
  platforms: [
   //...
  ],
  products: [
    .library(
      name: "Apollo-Dynamic",
      type: .dynamic,
      targets: ["Apollo"]),
   //...
    .library(
      name: "ApolloSQLite",
      targets: ["ApolloSQLite"]),
   //...
  ],
  dependencies: [
   //...
  ],
  targets: [
    .target(
      name: "Apollo",
      dependencies: [
   //...
      ],
    .target(
      name: "ApolloSQLite",
      dependencies: [
        "Apollo",
       //...
      ],
    ),
  ]
)

Importing into both Apollo-Dynamic and ApolloSQLite will end up in similar ld issue as above. :frowning:

Well, guess what. I was on a lab appointment and pulled in my reduced case project to demonstrate the issue and it didn't fail. I guess this could be considered for now as a random blip of the environment until I would be able to reproduce the issue again even though I was reproducing it continuously before.