使用Swift CLI构建含xcframework的Swift包时测试报错求助
swift test链接错误的问题 问题描述
开发的Swift包依赖XCFramework二进制文件,在Xcode中能正常构建和测试,swift build也能成功执行,但运行swift test时出现链接错误:
Undefined symbols for architecture x86_64:
ld: symbol(s) not found for architecture x86_64
[0/1] Linking PolywrapClientPackageTests
error: fatalError
排查后确认是无法找到二进制文件的实现,尝试修改Package.swift的linkerSettings添加-F参数指定Frameworks路径,问题未解决;将该Swift包导入其他Swift包时也会出现相同错误。
解决方案
1. 确认XCFramework包含测试所需架构
XCFramework需要同时包含**x86_64(模拟器)和arm64(真机/Apple Silicon)**架构,确保测试目标能匹配对应架构的二进制。可以用以下命令检查架构:
lipo -info ./Path/To/Your.xcframework/macos-x86_64/Your.framework/Your lipo -info ./Path/To/Your.xcframework/macos-arm64/Your.framework/Your
如果缺少测试用架构,需要重新构建XCFramework,覆盖所有所需架构。
2. 为测试目标同步配置链接参数
在Package.swift中,主目标和测试目标都需要配置XCFramework的链接规则,不能只给主目标加配置。示例代码如下:
let package = Package( name: "PolywrapClientPackage", products: [ .library(name: "PolywrapClientPackage", targets: ["PolywrapClientPackage"]), ], dependencies: [], targets: [ .target( name: "PolywrapClientPackage", dependencies: [], linkerSettings: [ .unsafeFlags(["-F", "./Frameworks"]), .linkedFramework("YourXCFrameworkName", .when(platforms: [.macOS, .iOS])) ] ), .testTarget( name: "PolywrapClientPackageTests", dependencies: ["PolywrapClientPackage"], linkerSettings: [ .unsafeFlags(["-F", "./Frameworks"]), .linkedFramework("YourXCFrameworkName", .when(platforms: [.macOS, .iOS])) ] ), ] )
注意:./Frameworks是XCFramework所在的相对路径,需根据项目实际结构调整。
3. 使用binaryTarget引入XCFramework(推荐)
Swift Package Manager支持通过binaryTarget直接导入XCFramework,这种方式能自动处理多平台和架构的依赖,比手动配置linkerSettings更可靠。修改Package.swift如下:
let package = Package( name: "PolywrapClientPackage", products: [ .library(name: "PolywrapClientPackage", targets: ["PolywrapClientPackage"]), ], dependencies: [], targets: [ .binaryTarget( name: "YourXCFrameworkName", path: "./Frameworks/YourXCFrameworkName.xcframework" ), .target( name: "PolywrapClientPackage", dependencies: [.target(name: "YourXCFrameworkName")] ), .testTarget( name: "PolywrapClientPackageTests", dependencies: ["PolywrapClientPackage"] ), ] )
这种配置下,测试目标通过依赖主目标间接获取二进制依赖,无需重复设置链接参数。
4. 清理缓存后重新构建
如果配置修改后问题仍存在,清理SPM缓存并重新执行构建:
rm -rf .build swift package clean swift build swift test
内容的提问来源于stack exchange,提问作者Cesar

