Post

Swift Settings in Package.swift: Compilation Flags Guide

Configure Swift Package targets with swiftSettings for platform conditionals, upcoming features, and compiler flags.

Swift Settings in Package.swift: Compilation Flags Guide

The swiftSettings parameter in Package.swift lets you configure compilation behavior per target—platform-specific code, upcoming Swift features, and compiler flags.

Basic Structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "MyPackage",
    targets: [
        .target(
            name: "MyLibrary",
            swiftSettings: [
                .define("DEBUG_MODE", .when(configuration: .debug)),
                .enableUpcomingFeature("StrictConcurrency")
            ]
        )
    ]
)

Platform Conditionals

Use .define() with .when(platforms:) to create compile-time flags:

1
2
3
4
5
6
7
8
9
.target(
    name: "CrossPlatformLib",
    swiftSettings: [
        .define("IOS", .when(platforms: [.iOS])),
        .define("MACOS", .when(platforms: [.macOS])),
        .define("LINUX", .when(platforms: [.linux])),
        .define("WINDOWS", .when(platforms: [.windows]))
    ]
)

Then use in Swift code:

1
2
3
4
5
6
7
8
9
10
11
func platformName() -> String {
    #if IOS
    return "iOS"
    #elseif MACOS
    return "macOS"
    #elseif LINUX
    return "Linux"
    #else
    return "Unknown"
    #endif
}

Configuration-Based Flags

Define flags that only apply in debug or release builds:

1
2
3
4
swiftSettings: [
    .define("ENABLE_LOGGING", .when(configuration: .debug)),
    .define("ENABLE_ANALYTICS", .when(configuration: .release))
]

Usage:

1
2
3
4
5
func log(_ message: String) {
    #if ENABLE_LOGGING
    print("[DEBUG] \(message)")
    #endif
}

Upcoming Features

Enable Swift evolution features before they become default:

1
2
3
4
5
6
swiftSettings: [
    .enableUpcomingFeature("StrictConcurrency"),
    .enableUpcomingFeature("ExistentialAny"),
    .enableUpcomingFeature("BareSlashRegexLiterals"),
    .enableUpcomingFeature("InferSendableFromCaptures")
]

Check available features with:

1
swift build --help | grep -i upcoming

Memory Safety

Enforce strict memory safety checking:

1
2
3
swiftSettings: [
    .strictMemorySafety()
]

This enables additional compile-time checks for memory safety violations.

Unsafe Flags

Pass raw compiler flags (use sparingly):

1
2
3
swiftSettings: [
    .unsafeFlags(["-Xfrontend", "-warn-long-expression-type-checking=100"])
]

Warning: Targets using .unsafeFlags() cannot be used as dependencies by other packages.

Complete Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// swift-tools-version: 6.0
import PackageDescription

let applePlatforms: [Platform] = [.iOS, .macOS, .tvOS, .watchOS, .visionOS]

let package = Package(
    name: "CrossPlatformKit",
    platforms: [.iOS(.v18), .macOS(.v15)],
    products: [
        .library(name: "CrossPlatformKit", targets: ["CrossPlatformKit"])
    ],
    targets: [
        .target(
            name: "CrossPlatformKit",
            swiftSettings: [
                // Platform detection
                .define("DARWIN", .when(platforms: applePlatforms)),
                .define("IOS", .when(platforms: [.iOS])),
                .define("LINUX", .when(platforms: [.linux])),

                // Configuration flags
                .define("DEBUG_MODE", .when(configuration: .debug)),

                // Swift 6 preparation
                .enableUpcomingFeature("StrictConcurrency")
            ]
        )
    ]
)

When to Use Each Setting

SettingUse Case
.define()Platform-specific code paths, debug toggles
.enableUpcomingFeature()Adopt Swift evolution features early
.strictMemorySafety()Enforce memory safety in Swift 6+
.unsafeFlags()Debugging, diagnostics (not for distributed packages)

Important Notes

  • Platform conditionals compile out unused code paths
  • Upcoming features help migrate to new Swift versions incrementally
  • .unsafeFlags() breaks package distribution—use only for local development
  • Combine .when(platforms:) and .when(configuration:) for granular control

☕ Support My Work

If you found this post helpful and want to support more content like this, you can buy me a coffee!

Your support helps me continue creating useful articles and tips for fellow developers. Thank you! 🙏

This post is licensed under CC BY 4.0 by the author.