What's new in Swift Package Manager in Swift 5.4
Along with the brand new Xcode 12.5, Swift 5.4 and its associated Swift Package Manager (SPM from now on) are now officially released. While 5.4 might look like a small release for SPM, there are actually a lot of changes, in this article let's have a look at the main ones.
The biggest release so far (?)
Even before talking about the actual changes, this release is one of the biggest (if not the biggest) for SPM to date, this is also justified by the recent expansion of the dedicated team at Apple and the new support for Windows.
Here are all the stats of the most recent releases:
- Swift 5.4 vs 5.3: 527 changed files with 34,434 additions and 36,806 deletions.
- Swift 5.3 vs 5.2: 411 changed files with 19,920 additions and 8,186 deletions.
- Swift 5.2 vs 5.1: 441 changed files with 21,714 additions and 11,442 deletions.
- Swift 5.1 vs 5.0: 169 changed files with 8,560 additions and 4,276 deletions.
- Swift 5.0 vs 4.2: 420 changed files with 23,256 additions and 11,635 deletions.
- Swift 4.2 vs 4.1: 232 changed files with 6,831 additions and 2,117 deletions.
- Swift 4.1 vs 4.0: 326 changed files with 7,286 additions and 4,344 deletions.
- Swift 4.0 vs 3.1: 319 changed files with 25,852 additions and 11,848 deletions.
- Swift 3.1 vs 3.0: 331 changed files with 28,945 additions and 5,210 deletions.
Since we're at it, here's a sneak peek at SPM 5.5, which is still a few months away:
- Swift 5.5 vs 5.4: 374 changed files with 28,185 additions and 6,539 deletions (at the time of writing).
While these stats alone don't mean much, it's clear that a lot is happening on this project, let's have a look at the actual changes next.
Up to Swift 5.3 targets declarations were separated in:
.target(...)for regular and executable targets
.binaryTarget(...)for binary targets that reference an artifact on disk
.testTarget(...)for testing targets
.systemLibrary(...)for system library targets
Where the difference between a regular target and an executable one was the presence (or not) of a
main.swift file, which was then used as the entry point for an executable target.
In Swift 5.3 we've seen the introduction of the
@main attribute, explicitly defining a new application entry point, regardless of the where its declaration is located.
In Swift 5.4 SPM gains a new
.executableTarget(...) target, exclusively dedicated to executables, where SPM will support either having a
main.swift entry point or a
@main declaration (at any location).
From now on
.target(...) will be used only for regular targets and nothing else, improving the package manifest readability.
(Linux) Test discovery
Until Swift 5.3 every package supporting Linux needed to have a
LinuxMain.swift file in the
Tests folder root: this file was needed to explicitly declare/list all the tests to be executed. From SPM 5.4 this
LinuxMain.swift is no longer necessary.
This same file was previously not needed/used in macOS platforms, as macOS relies on the Objective-C runtime for such discovery, like it does for
.xcodeproj test suites.
This functionality was previously available via a
--enable-test-discoveryflag to be passed on a
$ swift testcommand, it's now enabled by default.
Package dependency cache
Prior to Swift 5.4, if we had two completely separate packages with the same dependency, that dependency would have been downloaded twice and put in the
.build folder of each of our packages.
From Swift 5.4 SPM keeps a per-user cache in a new
~/.swiftpm/cache folder (or equivalent in other platforms), which will then be queried before fetching anything from the Internet: this will be a huge time/data saver, especially when using the same dependency in multiple, independent packages.
ArgumentParser has been released a little over an year ago, during this time it became the de-facto standard for every swift CLI tool out there: it should come with no surprise that SPM has now adopted it.
Good bye swift-tools-support-core
New module: Basics
Basics is a new module that contains SPM specific utilities that shouldn't be part of
swift-tools-support-core. For example the per-user cache location can be found in this module.
This module name is a blast from the past:
TSCBasic was originally called
New module: PackageCollections
Package Collections is the first module out of three of a new package discovery functionality being added into SPM, the other two being Package Registry and Package Index.
Package Collections focuses on handpicked packages lists, and provides a CLI tool,
$ swift package-collection, in order to read and explore such lists.
While this functionality is officially being added in Swift 5.5, the ground work is already part of SPM as of Swift 5.4 (note that
$ swift package-collection is not exposed in 5.4, making it inaccessible)
SPM has gotten a lot of attention in the last couple of years, and its development pace seems to be only increasing!
In this article we took a sneak peek to its main changes of the upcoming release, however there are many other changes not highlighted here: feel free to explore them yourself!