Swift Package依赖XCFramework及关联Xcode项目Target的自动化实现问题
嘿,我来帮你理清楚这个问题。首先先给你明确一个关键限制:目前Swift Package Manager(SPM)没办法直接引用Xcode项目(.xcproj)里的Target,所以你原来想在Package.swift里直接依赖CopyFramework Target的思路走不通,得换个方向。不过针对你的场景,有两个靠谱的解决方案,能帮你实现自动化,不用手动跑CopyFramework Target。
方案1:让SPM直接处理Tools.xcframework(推荐)
你原来的CopyFramework Target本质上就是调用builtin-process-xcframework来提取对应平台的XCFramework切片,而SPM本身就原生支持导入XCFramework并自动处理平台适配,完全可以跳过Xcode的这个Target,让SPM自己搞定。
具体操作就是在你的Package.swift里添加一个binaryTarget指向你的Tools.xcframework,然后让CoreObjC Target依赖这个binary target就行。这样SPM会在构建时自动根据当前平台(比如iOS真机/模拟器)提取对应的XCFramework切片,不用再管DerivedData的复制逻辑。
修改后的Package.swift示例:
let package = Package( name: "CoreObjC", platforms: [.iOS(.v17), .macCatalyst(.v17)], products: [ .library(name: "CoreObjC", targets: ["CoreObjC"]), ], dependencies: [], targets: [ // 直接导入本地的Tools.xcframework .binaryTarget( name: "Tools", path: "../testBuild/DynamicToolFrameworks/Tools.xcframework" ), .target( name: "CoreObjC", // 依赖上面定义的binary target dependencies: [.target(name: "Tools")], path: "CoreObjC", publicHeadersPath: "Headers", linkerSettings: [ // 这里不需要再手动linkedFramework("Tools")了,依赖binary target会自动处理 .linkedLibrary("c++") ] ), ], cxxLanguageStandard: CXXLanguageStandard.gnucxx14 )
这个方案的好处是完全复用SPM的原生能力,没有额外的脚本或Xcode依赖,构建逻辑更简洁,跨平台(比如以后加macCatalyst适配)也能自动处理。
方案2:如果必须复用原CopyFramework逻辑,让SPM触发Xcode构建
如果你因为某些原因必须保留原来的CopyFramework Target(比如里面有额外的定制处理步骤),那可以让SPM在构建CoreObjC之前,自动调用xcodebuild命令来构建CopyFramework Target,确保DerivedData里有处理好的Tools.framework。
你可以在Package.swift的CoreObjC Target里添加preBuildCommands,在构建前执行xcodebuild命令:
let package = Package( name: "CoreObjC", platforms: [.iOS(.v17), .macCatalyst(.v17)], products: [ .library(name: "CoreObjC", targets: ["CoreObjC"]), ], dependencies: [], targets: [ .target( name: "CoreObjC", dependencies: [], path: "CoreObjC", publicHeadersPath: "Headers", linkerSettings: [ .linkedFramework("Tools", .when(platforms: [.iOS])), .linkedLibrary("c++") ], // 构建前先触发CopyFramework Target的构建 preBuildCommands: [ #""" xcodebuild -project ../testBuild/testBuild.xcodeproj -scheme CopyFramework -configuration Debug -destination 'platform=iOS' build """# ] ), ], cxxLanguageStandard: CXXLanguageStandard.gnucxx14 )
注意这里的xcodebuild参数要根据你的实际情况调整:
-project后面是你的Xcode项目的路径(相对于Package.swift的位置)-scheme是你的CopyFrameworkTarget对应的scheme-configuration和-destination要和你构建CoreObjC的配置/平台匹配,比如如果要支持模拟器,得加对应的destination参数,或者写脚本判断当前构建平台。
这个方案的缺点是依赖Xcode的xcodebuild命令,跨平台兼容性会差一些,但能完全复用你原来的CopyFramework逻辑。
最后再明确一遍:SPM目前不支持直接依赖Xcode项目里的Target,所以上面两种方案是当前可行的替代思路,其中方案1是更推荐的原生SPM方式。
内容来源于stack exchange

