How do I use CollectionsBenchmark from an Xcode project?

I wrote an algorithm that I want to benchmark, and I am having difficulty adding CollectionsBenchmark to the project.

My algorithm is in an Xcode project as a command-line utility, so I followed Apple’s instructions for adding a package dependency. Specifically, in Xcode I chose the menu item “File > Swift Packages > Add Package Dependency…”

At the “Choose Package Repository” prompt I copy-pasted the URL for CollectionsBenchmark:

https://github.com/apple/swift-collections-benchmark

I clicked “Next”, and the “Verifying” step succeeded after a few seconds. Then at the “Rules” prompt I selected “Version: Up to Next Major 0.0.2 ..< 1.0.0” and clicked “Next” again.

The “Resolving” step failed almost immediately with the error:

The package dependency graph can not be resolved; unable find any available tag for the following requirements:

https://github.com/apple/swift-collections-benchmark — 0.0.2..<1.0.0

This seems odd, as the tags page in the CollectionsBenchmark repository shows that tag 0.0.2 not only exists, but is the most recent available tag.

I tried a few more times with identical results.

What am I doing wrong here?

I just tried without Xcode, and I’m getting the same error.

I created a new library with swift package init, then edited its Package.swift file by adding as a dependency:

.package(url: "https://github.com/apple/swift-collections-benchmark", from: "0.0.2")

I ran swift build, and got the error:

error: the package dependency graph could not be resolved; unable to find any available tag for the following requirements:
    https://github.com/apple/swift-collections-benchmark @ 0.0.2..<1.0.0

• • •

Edit:

Okay, I’m beginning to suspect this is actually down to my machine being on MacOS 10.14, thus Xcode 11 and Swift 5.1.3.

The error messages do not give any hint toward this, and the CollectionsBenchmark readme does not advertise any minimum version requirements, but nonetheless I’m pretty sure that’s the issue.

It was only when I looked at the Package.swift file for CollectionsBenchmark itself that I noticed it starts with the line:

// swift-tools-version:5.3

• • •

Is there any way to use this package on an older Mac?

No. You need macOS 10.15 for swift 5.3. Why can't you update your OS?

First, I did not ask if there is a way to use Swift 5.3 on an older Mac.

I asked if there is a way to use this package (meaning CollectionsBenchmark) on an older Mac.

Second, this package does not appear have a documented minimum Swift version requirement. There is certainly not a prominently-placed statement of any such requirement in its readme.

Third, the error message produced by both Xcode and the Swift package manager when attempting to use this package as a dependency on an older Mac does not mention anything about version numbers.

Irrelevant.

There are many reasons why someone might use a computer on an older operating system. Here are a few examples:

• Perhaps the hardware does not support the new OS.
• Perhaps an application the person uses does not support the new OS.
• Perhaps the new OS has dropped features the person uses.
• Perhaps the person prefers the “look and feel” of the old OS.
• Perhaps the person has previously experienced problems after updating their OS, and the OS makes it difficult to downgrade to a previous version, so the person prefers to stay on a known-good version for as long as possible.
• Perhaps the person does not see any compelling reason to upgrade, and is happy with the OS they are using.

Regardless of the reason, I hope it is clear that “Upgrade your entire operating system” is a heavy ask.

This package uses swift tools 5.3—as you mentioned—which requires swift 5.3, so you need swift 5.3 in order to use this package.

That's a fair criticism. The README should mention the minimum supported version of Swift. I suggest you open an issue about this.

It looks like this has been fixed as of Xcode 12.5. You now get the following error message when you try to add a package with an unsupported swift tools version:

Dependencies could not be resolved because root depends on 'swiftTools55' 1.0.0..<2.0.0.
'swiftTools55' >= 1.0.0 cannot be used because no versions of 'swiftTools55' match the requirement 1.0.1..<2.0.0 and 'swiftTools55' 1.0.0 contains incompatible tools version (5.5.0).

It's not irrelevant because if you did update your OS, then you wouldn't have this problem.

One thing you could do is fork the repository and try to modify it so that it is supported on older versions of Swift. This will be difficult though, as its dependencies require swift 5.2.

You asked a “why” question. The “why” is irrelevant.

My reasons for using this OS have no bearing on whether this package can work on this OS.

At first blush, the compilation errors that occur when changing the tools-version of swift-collections-benchmark to 5.2 don't look major (mostly using #filePath). I expect that it was set to 5.3 because swift-collections requires 5.3 (it specifically supports OpenBSD with #if os(OpenBSD) and uses a manifest feature from Swift 5.3)

2 Likes

Like Swift Collections, the benchmarking package requires Swift 5.3. Supporting earlier toolchains wouldn’t be practical for us — we need to be able to adopt new language/stdlib/swiftpm features as soon as they become available.

Yep, it’s a bug that the readme doesn’t spell this out. There is also another issue here, which is that the version of SwiftPM you’re using (and/or its Xcode integration) doesn’t make it clear why the dependency graph couldn’t be satisfied. The first bug is really easy to fix; the second is impossible, since the SwiftPM release you are using is already out, and you aren’t willing to upgrade.

The good news is that this package does not limit the deployment target — binaries built with this package are able to run on every macOS/iOS/watchOS/tvOS version that Swift can run on. (Note though that we do not test these packages on every supported OS release — if you find issues, please report them, or file a PR!)

Going forward, we expect to regularly upgrade the required toolchain version of these stdlib-adjacent packages to the latest public Swift release. We do not expect to bump the minimum deployment target; but in the unlikely case that ever becomes necessary, it would require a new major release.

2 Likes

The why feels very much like a relevant question to me. These fora are about the future evolution of the Swift ecosystem. By not using the latest available toolchain, you’re opting out of this evolution process, including all language/stdlib/swiftpm improvements we’ve worked on these last couple years. If you have good reasons to do this, I’d be very much interested to learn them.

(One reason this is hugely relevant is that if a significant portion of package adopters refuse to upgrade their toolchain, then that will have important consequences to the package release strategy.)

6 Likes