排除 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 conditionwhen.

的例子
// 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
    }(),
)

另请参阅