swiftlang / swift-package-manager

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

`moduleAliases` feature is flaky #6913

Open fumoboy007 opened 9 months ago

fumoboy007 commented 9 months ago

Description

My package has a target named MessagePack. I am writing benchmarks to compare my package with other packages, so I need to add those other packages as dependencies of my package.

One of those dependencies also has a target named MessagePack. To avoid the naming conflict, I am attempting to use the moduleAliases feature to rename the dependency’s MessagePack target to FlightSchoolMessagePack:

.product(name: "MessagePack", package: "MessagePack", moduleAliases: [
   "MessagePack": "FlightSchoolMessagePack",
]),

This works sometimes but other times, Swift package manager complains about duplicate target names:

error: multiple targets named 'MessagePack' in: 'messagepack', 'msgpack-swift'; consider using the moduleAliases parameter in manifest to provide unique names

Expected behavior

The feature should work 100% of the time.

Actual behavior

The feature is flaky.

Steps to reproduce

  1. Download my package.
  2. Switch to the with-flight-school-dep branch.
  3. Run the reproduce-duplicate-targets-issue.sh script.

Example result:

% ./reproduce-duplicate-targets-issue.sh
Reproduced after 2 iterations. See `duplicate-targets-issue.log`.

Swift Package Manager version/commit hash

swift-5.8.1-RELEASE

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

swift-driver version: 1.75.2 Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
Target: arm64-apple-macosx13.0
Darwin Darrens-Mac.momahome 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000 arm64
fumoboy007 commented 9 months ago

@elsh @tomerd My wildly uninformed guess would be: this is caused by a bug that depends on a specific dictionary/set iteration order and the bug is only triggered some of the time because the Swift dictionary/set iteration order is randomized per process. 😀

elsh commented 9 months ago

I don't think swift package clean actually deletes the build directory; you might have to add rm -rf .build to get a more consistent behavior.

fumoboy007 commented 9 months ago

I don't think swift package clean actually deletes the build directory; you might have to add rm -rf .build to get a more consistent behavior.

Oh, TIL! swift package reset deletes the .build directory (which includes caches) whereas swift package clean only deletes build artifacts.

Both swift package clean and swift package reset reproduce the issue for me though.

It is interesting that this flakiness issue is reproducible with just swift package clean. I wouldn’t have thought it was related to build artifacts. Maybe that’s a good clue to help investigate the root cause?

coenttb commented 4 months ago

@Elsh, I am also struggling with using moduleAliases and I would be incredibly thankful if you could take a look at this.

I have three packages, A & B and C.

Both A and B have a target named X.

C has both A and B as dependency, and because both A and B have a target named X, there is the 'Multiple targets named...' error in Xcode.

The following is in C's Package.swift.

extension Target.Dependency {
    static let A: Self = .product(
        name: "X",
        package: "A",
        moduleAliases: [
            "X" : "X_one",
        ]
    )
    static let B: Self = .product(
        name: "X",
        package: "B",
        moduleAliases: [
            "X" : "X_two",
        ]
    )
}

However, this doesn't fix the issue and the error ('multiple targets..') persists. Could you please help me identify where I'm going wrong?