'Excluding files in Swift Packages
To exclude entire sections of a file, I can use macros to target platforms such as #if os(iOS) || os(watchOS)
.
Is there a way to do this in Package.swift
, or another way to target a few files for specific platforms in Swift Package Manager?
Solution 1:[1]
Is there a way to do this in
Package.swift
... ?
Swifty stuff also works in Package.swift
since the package declaration file is itself a .swift
file.
Here are some examples which use Swift 5.3 Package Manager Conditional Target Dependencies SE-0273 condition
and when
.
// swift-tools-version:5.3
import PackageDescription
// ...
targets: [
.target(
name: "BKSecurity",
dependencies: [
.product(name: "Crypto", condition: .when(platforms: [.linux])),
"BKFoundation"
]),
// swift-tools-version:5.3
import PackageDescription
// ...
targets: [
.target(
name: "CombineShim",
dependencies: [
.product(name: "OpenCombine",
package: "OpenCombine",
condition: .when(platforms: [.wasi, .linux])
)]
),
.target(
name: "TokamakShim",
dependencies: [
.target(name: "TokamakDOM", condition: .when(platforms: [.wasi])),
"SomeCommonDependency"
]
),
// swift-tools-version:5.3
import PackageDescription
let supportsCoreAudio: BuildSettingCondition =
.when(platforms: [.iOS, .macOS, .tvOS, .watchOS])
let supportsALSA: BuildSettingCondition =
.when(platforms: [.linux])
let package = Package(
name: "portaudio",
// ...
targets: [
.target(
name: "libportaudio",
dependencies: [],
cSettings: [
.define("PA_USE_COREAUDIO", supportsCoreAudio),
.define("PA_USE_ALSA", supportsALSA)
],
linkerSettings: [
.linkedLibrary("asound", supportsALSA),
.linkedFramework("CoreAudio", supportsCoreAudio),
.linkedFramework("CoreServices", supportsCoreAudio),
.linkedFramework("CoreFoundation", supportsCoreAudio),
.linkedFramework("AudioUnit", supportsCoreAudio),
.linkedFramework("AudioToolbox", supportsCoreAudio)
]),
]
//...
)
Note that #if os(…)
can be used in Package.swift
. However, Package.swift
is evaluated, built and executed in the context of the build platform. So, #if os(…)
is useful in the context when the target platform is the same as the build platform e.g. macOS, Linux or Windows.
Package.swift
import PackageDescription
let package = Package(
// ...
targets: {
var targets: [Target] = [
.testTarget(
name: "QuickTests",
dependencies: [ "Quick", "Nimble" ],
exclude: ["SomeFile.ext"]
),
]
#if os(macOS)
// macOS build platform
targets.append(contentsOf: [
.target(name: "QuickSpecBase", dependencies: []),
.target(name: "Quick", dependencies: [ "QuickSpecBase" ]),
])
#else
// not macOS build platform, e.g. linux
targets.append(contentsOf: [
.target(name: "Quick", dependencies: []),
])
#endif
return targets
}(),
)
See Also
- The Swift Programming Language: Statements > Conditional Compilation Block
- GitHub/Apple/swift: lib/Basic/LangOptions.cpp
- Currently supported compilation OSs:
macOS
,tvOS
,watchOS
,iOS
,Linux
,FreeBSD
,OpenBSD
,Windows
,Android
,PS4
,Cygwin
,Haiku
,WASI
- Currently supported compilation OSs:
- GitHub/Apple/swift-evolution: SE-0273 Package Manager Conditional Target Dependencies
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |