排除 Swift 个包中的文件
Excluding files in Swift Packages
要排除文件的整个部分,我可以使用宏来定位 #if os(iOS) || os(watchOS)
等平台。
有没有办法在 Package.swift
中执行此操作,或者有其他方法可以在 Swift 包管理器中为特定平台定位一些文件?
Is there a way to do this in Package.swift
... ?
Swifty 东西 在 Package.swift
中也有效 因为包声明文件本身就是一个 .swift
文件。
这里有一些使用 Swift 5.3 Package Manager Conditional Target Dependencies SE-0273 condition
和 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)
]),
]
//...
)
注意#if os(…)
可以用在Package.swift
中。但是,Package.swift
是在构建平台 的上下文中评估、构建和执行的。因此,#if os(…)
在 目标平台 与构建平台 相同 的上下文中很有用,例如macOS,Linux 或 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
}(),
)
另请参阅
- The Swift Programming Language: Statements > Conditional Compilation Block
- GitHub/Apple/swift: lib/Basic/LangOptions.cpp
- 目前支持的编译操作系统:
macOS
、tvOS
、watchOS
、iOS
、Linux
、FreeBSD
、OpenBSD
, Windows
, Android
, PS4
, Cygwin
, Haiku
, WASI
- GitHub/Apple/swift-evolution: SE-0273 Package Manager Conditional Target Dependencies
要排除文件的整个部分,我可以使用宏来定位 #if os(iOS) || os(watchOS)
等平台。
有没有办法在 Package.swift
中执行此操作,或者有其他方法可以在 Swift 包管理器中为特定平台定位一些文件?
Is there a way to do this in
Package.swift
... ?
Swifty 东西 在 Package.swift
中也有效 因为包声明文件本身就是一个 .swift
文件。
这里有一些使用 Swift 5.3 Package Manager Conditional Target Dependencies SE-0273 condition
和 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)
]),
]
//...
)
注意#if os(…)
可以用在Package.swift
中。但是,Package.swift
是在构建平台 的上下文中评估、构建和执行的。因此,#if os(…)
在 目标平台 与构建平台 相同 的上下文中很有用,例如macOS,Linux 或 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
}(),
)
另请参阅
- The Swift Programming Language: Statements > Conditional Compilation Block
- GitHub/Apple/swift: lib/Basic/LangOptions.cpp
- 目前支持的编译操作系统:
macOS
、tvOS
、watchOS
、iOS
、Linux
、FreeBSD
、OpenBSD
,Windows
,Android
,PS4
,Cygwin
,Haiku
,WASI
- 目前支持的编译操作系统:
- GitHub/Apple/swift-evolution: SE-0273 Package Manager Conditional Target Dependencies