Home Explore Blog CI



nixpkgs

3rd chunk of `doc/languages-frameworks/swift.section.md`
32b76eb31df8c28b913e9272602e3f0be4a28c741b5bf3d90000000100000bd9
  # The helper provides a configure snippet that will prepare all dependencies
  # in the correct place, where SwiftPM expects them.
  configurePhase = ''
    runHook preConfigure

    ${generated.configure}

    runHook postConfigure
  '';

  installPhase = ''
    runHook preInstall

    # This is a special function that invokes swiftpm to find the location
    # of the binaries it produced.
    binPath="$(swiftpmBinPath)"
    # Now perform any installation steps.
    mkdir -p $out/bin
    cp $binPath/myproject $out/bin/

    runHook postInstall
  '';
})
```

### Custom build flags {#ssec-swiftpm-custom-build-flags}

If you'd like to build a different configuration than `release`:

```nix
{
  swiftpmBuildConfig = "debug";
}
```

It is also possible to provide additional flags to `swift build`:

```nix
{
  swiftpmFlags = [ "--disable-dead-strip" ];
}
```

The default `buildPhase` already passes `-j` for parallel building.

If these two customization options are insufficient, provide your own
`buildPhase` that invokes `swift build`.

### Running tests {#ssec-swiftpm-running-tests}

Including `swiftpm` in your `nativeBuildInputs` also provides a default
`checkPhase`, but it must be enabled with:

```nix
{
  doCheck = true;
}
```

This essentially runs: `swift test -c release`

### Patching dependencies {#ssec-swiftpm-patching-dependencies}

In some cases, it may be necessary to patch a SwiftPM dependency. SwiftPM
dependencies are located in `.build/checkouts`, but the `swiftpm2nix` helper
provides these as symlinks to read-only `/nix/store` paths. In order to patch
them, we need to make them writable.

A special function `swiftpmMakeMutable` is available to replace the symlink
with a writable copy:

```nix
{
  configurePhase = ''
    runHook preConfigure

    ${generated.configure}

    # Replace the dependency symlink with a writable copy.
    swiftpmMakeMutable swift-crypto
    # Now apply a patch.
    patch -p1 -d .build/checkouts/swift-crypto -i ${./some-fix.patch}

    runHook postConfigure
  '';
}
```

## Considerations for custom build tools {#ssec-swift-considerations-for-custom-build-tools}

### Linking the standard library {#ssec-swift-linking-the-standard-library}

The `swift` package has a separate `lib` output containing just the Swift
standard library, to prevent Swift applications needing a dependency on the
full Swift compiler at run-time. Linking with the Nixpkgs Swift toolchain
already ensures binaries correctly reference the `lib` output.

Sometimes, Swift is used only to compile part of a mixed codebase, and the
link step is manual. Custom build tools often locate the standard library
relative to the `swift` compiler executable, and while the result will work,
when this path ends up in the binary, it will have the Swift compiler as an
unintended dependency.

In this case, you should investigate how your build process discovers the
standard library, and override the path. The correct path will be something
like: `"${swift.swift.lib}/${swift.swiftModuleSubdir}"`

Title: SwiftPM Nix Packaging: Customization, Testing, Patching, and Build Tool Considerations
Summary
This section covers advanced topics for packaging SwiftPM projects with Nix, including customizing build flags and configurations, running tests, patching dependencies using `swiftpmMakeMutable` to modify dependencies in `.build/checkouts`, and considerations for custom build tools, particularly how to correctly link the Swift standard library to avoid unnecessary dependencies on the full Swift compiler.