Back to Swift Package Manager

Adding dependencies to a Swift package

Sources/PackageManagerDocs/Documentation.docc/Dependencies/AddingDependencies.md

0.6.06.5 KB
Original Source

Adding dependencies to a Swift package

Use other Swift packages, system libraries, or binary dependencies in your package.

Overview

To depend on another Swift package, define a dependency and the requirements for its version if it's remote, then add a product of that dependency to one or more of your targets.

A remote dependency requires a location, represented by a URL, and a requirement on the versions the package manager may use.

The following example illustrates a package that depends on PlayingCard, using from to require at least version 4.0.0, and allow any other version up to the next major version that is available at the time of dependency resolution. It then uses the product PlayingCard as a dependency for the target MyPackage:

swift
// swift-tools-version:6.1
import PackageDescription

let package = Package(
    name: "MyPackage",
    dependencies: [
        .package(url: "https://github.com/apple/example-package-playingcard.git", 
                 from: "4.0.0"),
    ],
    targets: [
        .target(
            name: "MyPackage",
            dependencies: [
                .product(name: "PlayingCard", 
                         package: "example-package-playingcard")
            ]
        ),
        .testTarget(
            name: "MyPackageTests",
            dependencies: ["MyPackage"]
        ),
    ]
)

The package manager automatically resolves packages when you invoke doc:SwiftRun or doc:SwiftBuild. You can explicitly resolve the packages with the command doc:PackageResolve. For more information on resolving package versions, see doc:ResolvingPackageVersions.

Constraining dependency versions

Constrain the version of a remote dependency when you declare the dependency. The package manager uses git tags, interpreted as a semantic version, to identify eligible versions of packages.

Note: tags for package versions should include all three components of a semantic version: major, minor, and patch. Tags that only include one or two of those components are not interpreted as semantic versions.

Use the version requirement when you declare the dependency to limit what the package manager can choose. The version requirement can be a range of possible semantic versions, a specific semantic version, a branch name, or a commit hash. The API reference documentation for Package.Dependency defines the methods to use.

Packages with Traits

Traits, introduced with Swift 6.1, allow packages to offer additional API that may include optional dependencies. Packages should offer traits to provide API beyond the core of a package. For example, a package may provide an experimental API, an optional API that requires additional dependencies, or functionality that isn't critical that a developer may want to enable only in specific circumstances.

If a package offers traits and you depend on it without defining the traits to use, the package uses its default set of traits. In the following example, the dependency example-package-playingcard uses its default traits, if it offers any:

swift
dependencies: [
  .package(url: "https://github.com/swiftlang/example-package-playingcard", 
           from: "4.0.0")
]

To determine what traits a package offers, including its defaults, either inspect its Package.swift manifest or use doc:PackageShowDependencies to print out the resolved dependencies and their traits.

Enabling a trait should only expand the API offered by a package. If a package offers default traits, you can choose to not use those traits by declaring an empty set of traits when you declare the dependency. The following example dependency declaration uses the dependency with no traits, even if the package normally provides a set of default traits to enable:

swift
dependencies: [
  .package(url: "https://github.com/swiftlang/example-package-playingcard", 
           from: "4.0.0",
           traits: [])
]

Swift package manager determines the traits to enable using the entire graph of dependencies in a project. The traits enabled for a dependency is the union of all of the traits that for packages that depend upon it. For example, if you opt out of all traits, but a dependency you use uses the same package with some trait enabled, the package will use the depdendency with the requested traits enabled.

Note: By disabling any default traits, you may be removing available APIs from the dependency you use.

To learn how to provide packages with traits, see doc:PackageTraits.

Local Dependencies

To use a local package as a dependency, use either package(name:path:) or package(path:) to define it with the local path to the package. Local dependencies do not enforce version constraints, and instead use the version that is available at the path you provide.

System Library Dependencies

In addition to depending on Swift packages, you can also depend on system libraries or, on Apple platforms, precompiled binary dependencies.

For more information on using a library provided by the system as a dependency, see doc:AddingSystemLibraryDependency.

Precompiled Binary Targets for Apple platforms

To add a dependency on a precompiled binary target, specify a .binaryTarget in your list of targets, using either binarytarget(name:url:checksum:) for a downloadable target, or binarytarget(name:path:) for a local binary. After adding the binary target, you can add it to the list of dependencies for any other target.

For more information on identifying and verifying a binary target, see Identifying binary dependencies. For more information on creating a binary target, see Creating a multiplatform binary framework bundle.

Topics