使用Xcode 13在iOS 15编译Cronet时出现shrink_to_fit()未定义符号错误
问题原因
该链接报错是Xcode 13自带的libc标准库与Cronet依赖的base模块string16实现的兼容性问题:Xcode 13的libc默认移除了非char/wchar_t类型实例化的basic_string类的shrink_to_fit()符号导出,而Cronet的base模块自定义了以unsigned short为字符类型的string16,在UTF8/宽字符转UTF16的逻辑中调用了该方法,导致链接时找不到对应符号。
可行解决方案
- 方案1:新增预编译宏强制兼容旧符号
在Cronet编译配置的args.gn文件中添加如下编译参数,重新生成编译配置后再编译即可:
该宏会让Xcode 13的libc++重新导出自定义字符类型的basic_string成员函数符号,直接解决未定义符号问题。extra_cflags = ["-D_LIBCPP_ENABLE_NONSTANDARD_STRING_INSTANTIATIONS=1"] - 方案2:修改base模块代码避开问题接口
找到base模块下的base/strings/utf_string_conversions.cc文件,将UTF8ToUTF16、WideToUTF16两个函数末尾的result->shrink_to_fit()调用替换为以下逻辑,用移动构造实现相同的内存收缩效果,避开对shrink_to_fit()的直接调用:if (result->capacity() > result->size()) { *result = std::move(*result); } - 方案3:调高最小部署版本
如果你的应用不需要兼容iOS 12及更低版本,将编译参数中的miphoneos-version-min从8.0调整为13.0及以上,高版本部署目标下libc++会内联shrink_to_fit()的实现,不会产生外部符号依赖。
注意事项
修改配置后需要先清空之前的编译缓存,再重新执行全量编译流程,避免缓存的旧目标文件导致报错复发。
内容的提问来源于stack exchange,提问作者yfainaer
相关产品推荐
相关产品推荐

