Weekly Swift articles, podcasts and tips by John Sundell.

Combined Swift packages

Published on 12 Apr 2019

If we want to distribute a Swift package as both a library that other tools can import, and as a command line tool, all we have to do is to define two separate targets and products.

Here’s an example Package.swift file in which we’re doing exactly that:

// swift-tools-version:5.0

import PackageDescription

let package = Package(
    name: "Plot",
    products: [
        // If we want to distribute a Swift package as both a
        // library and a command line tool, one way to do that
        // is to simply use lower case characters for the CLI.
        .library(name: "Plot", targets: ["Plot"]),
        .executable(name: "plot", targets: ["PlotCLI"])
    ],
    dependencies: [
        .package(url: "https://github.com/johnsundell/files.git", from: "3.1.0"),
        .package(url: "https://github.com/johnsundell/sweep.git", from: "0.2.1"),
        .package(url: "https://github.com/johnsundell/codextended.git", from: "0.2.0")
    ],
    targets: [
        .target(
            name: "Plot",
            dependencies: ["Files", "Sweep", "Codextended"]
        ),
        .target(
            // We can still name our target "CLI", to make it
            // easier to see the difference between our CLI
            // and our library in Xcode.
            name: "PlotCLI",
            dependencies: ["Plot"]
        ),
        .testTarget(
            name: "PlotTests",
            dependencies: ["Plot", "Codextended"]
        )
    ]
)