Swift Package Manager如何按平台条件引入或排除指定源文件?
完全可以实现,Swift Package Manager 从 5.3 版本开始就支持源文件粒度的条件引入控制,你当前使用的 5.4 工具链版本完全支持该特性。
你只需要把原来的 sources 配置替换为带条件的写法即可,参考修改后的完整配置:
// swift-tools-version:5.4 import PackageDescription let package = Package( name: "ResultingTarget", platforms: [ .iOS(.v13), .macOS(.v10_15) ], products: [ .library( name: "ResultingTarget", targets: ["ResultingTarget"]), ], targets: [ .target( name: "ResultingTarget", sources: [ // 仅iOS平台引入该文件 .source("File_for_iOS.mm", condition: .when(platforms: [.iOS])), // 仅macOS平台引入该文件 .source("File_for_macOS.mm", condition: .when(platforms: [.macOS])), "Other_file.mm" ], publicHeadersPath: "Headers", cxxSettings: [ .headerSearchPath("headers"), ]), ], cxxLanguageStandard: .cxx14 )
补充说明
- 如果某一平台的专属实现文件较多,可以将其统一放到单独的目录下,直接对整个目录设置条件即可,无需逐个文件声明,示例:
sources: [ .source("iOSImpl", condition: .when(platforms: [.iOS])), // 整个iOSImpl目录仅iOS平台编译 .source("macOSImpl", condition: .when(platforms: [.macOS])), // 整个macOSImpl目录仅macOS平台编译 "Common" // 通用代码目录,全平台编译 ]
- 除了平台维度,还可以按构建配置维度条件引入文件,比如仅Debug模式引入调试工具代码:
.source("DebugUtils.mm", condition: .when(configuration: .debug))
该方案相比编译期宏实现有明显优势:不同平台的实现代码物理隔离,维护更清晰;最终编译产物不会包含无用平台的代码,包体积更优;无需依赖宏判断,避免宏写错导致的逻辑错误。
内容的提问来源于stack exchange,提问作者Richard Topchii
相关产品推荐
相关产品推荐

