I’m working on a Swift project and would like to create two builds of my package:
Here’s what I have so far is two separate Package.swift
files:
...
targets: [
.executableTarget(
name: "macSubtitleOCR",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser")
]),
...
and:
...
targets: [
.systemLibrary(
name: "CFFmpeg",
pkgConfig: "libavformat libavcodec libavutil",
providers: [
.brew(["ffmpeg"])
]),
.executableTarget(
name: "macSubtitleOCR",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
"CFFmpeg"
]),
...
I've tried adding compile flags like #if FFMPEG
and then running swift build -Xswiftc -DFFMPEG
which works for the source files, but compile flags don't work properly, and understandably so, in Package.swift
.
My question is:
Package.swift
based on build flags or any other approach?I’m relatively new to Swift development, so any guidance or alternative approaches would be greatly appreciated!
Swift Package Manager (SwiftPM) doesn’t directly support conditional dependencies, but you can manage optional dependencies using environment variables. This approach enables conditional inclusion of a dependency in a single Package.swift file.
Solution
Define an environment variable and use conditional logic in Package.swift to include the CFFmpeg target only when needed:
import PackageDescription
let hasFFmpeg = ProcessInfo.processInfo.environment["USE_FFMPEG"] == "1"
let package = Package(
name: "macSubtitleOCR",
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0")
],
targets: [
.executableTarget(
name: "macSubtitleOCR",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser")
] + (hasFFmpeg ? ["CFFmpeg"] : [])
)
] + (hasFFmpeg ? [
.systemLibrary(
name: "CFFmpeg",
pkgConfig: "libavformat libavcodec libavutil",
providers: [
.brew(["ffmpeg"])
]
)
] : [])
)