一个因为swift name mangled符号不一致导致的错误:
dispatch thunk of Alamofire.MultipartFormData.append(_: Foundation.Data, withName: Swift.String, fileName: Swift.String?, mimeType: Swift.String?) -> ()", referenced from:
先说工程结构
工程A有一个静态framework target a,通过cocoapods以源码方式集成了封装Alamofire,封装Alamofire的一些能力。
workspace A
|____ a (源码)
|____Alamofire (源码)
构建输出静态framework a。
工程B有一个App Target,通过cocoapods以源码方式集成封装Alamofire,以静态库方式集成了 a。
workspace B
|___App
|____ a (静态库)
|____ Alamofire (源码)
```
在同一电脑,用同一个Xcode,设置了相同的swift version,结果App构建失败,找不到Alamofire里的符号。
经过一番观察,发现 "dispatch thunk of Alamofire.MultipartFormData.append(...)"是 Swift 编译器为带有默认参数、可变签名或需要方法桥接的函数生成的“thunk”符号。也就是说静态库a引用了这些由 Alamofire 生成的编译器私有符号,但最终链接器没有在任何被链接的库/框架中找到对应实现。
检查工程配置,首先排除Alamofire 的实现没有被链接到最终可执行文件(常见:静态库a引用但 App 没把 Alamofire 链接上)。
那么,最有可能的情况就是:工程B的Alamofire 与 工程A 使用不同的 Swift 编译环境/选项,导致 thunk 的名称/生成方式不一致,最终没有可匹配的符号。虽然Alamofire代码一摸一样,但是编译后的符号修饰方式不一样。
示意例子,例如同样是方法 test,
工程A中被修饰为 _$s12Alamofire4testtKF
工程B中被修饰为 $s12Alamofire4test_tKj
有了排查方向,经过对比工程A和工程B的配置,最终发现cocoapods自动生成target Alamofire的配置有些许不一致
Build Libraries for Distribution 这个配置不一样,一个是YES,一个是NO。
又经实验,发现如果依赖Alamofire的target的 Build Libraries for Distribution 配置为YES,那么cocoapods自动生成的Alamofire对应的配置也是YES。
最后,只要将Alamofire对应Build Libraries for Distribution设置为NO(保持一致)就解决了Undefined symbols问题。
发表回复
要发表评论,您必须先登录。