iOS开发:Xcode10兼容libstdc++

Xcode10正式版已发布,苹果在Xcode10中已移除了对libstdc++的支持。本文主要介绍临时处理方案。

编译失败,会提示:

library not found for -libstdc++.6.0.9

解决编译的问题,主要是解决符号搜索路径的问题。

10.0版本之前Xcode支持libstdc++,可以将旧版本的libstdc++的tbd拷贝到新Xcode的SDK目录下即可通过编译。
其中,ARM架构SDK目录是/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/,x86架构SDK目录是/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/。将两个SDK目录下的libstdc++相关tbd文件拷贝到新Xcode目录下即可编译成功。

此时运行iOS12模拟器,会提示:

1
2
3
4
dyld: Library not loaded: /usr/lib/libstdc++.6.dylib
Referenced from: /Users/Jetsam/Library/Developer/CoreSimulator/Devices/C9E3FE9D-8B51-48A9-AFD6-D72BBA24B1A3/data/Containers/Bundle/Application/F179D341-324B-4D84-BDC3-A96FA82FD993/Demo.app/Demo
Reason: no suitable image found. Did find:
/usr/lib/libstdc++.6.dylib: mach-o, but not built for iOS simulator

这是因为iOS12的模拟器运行时找不到libstdc++动态库,其路径为链接时所指定的/usr/lib/libstdc++.6.dylib。
解决方法是,将x86架构的dylib拷贝到新Xcode的iOS12模拟器运行时相应目录下即可。具体目录是:/Users/Jetsam/Downloads/Software/Xcode/10.0/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib(请替换Xcode10安装路径)。

上述处理之后,重新运行即可。
建议先clean一下工程并删除模拟器上旧包。否则可能会出现类似这样的报错(报错为开启了address sanitize):

1
2
3
4
5
dyld: lazy symbol binding failed: Symbol not found: ___asan_version_mismatch_check_apple_1000
Referenced from: /Users/Jetsam/Library/Developer/CoreSimulator/Devices/C9E3FE9D-8B51-48A9-AFD6-D72BBA24B1A3/data/Containers/Bundle/Application/FFFF8E2F-6C9D-4A9E-9BC5-AA2B489E5E9A/Demo.app/Demo
Expected in: /Users/Jetsam/Library/Developer/CoreSimulator/Devices/C9E3FE9D-8B51-48A9-AFD6-D72BBA24B1A3/data/Containers/Bundle/Application/FFFF8E2F-6C9D-4A9E-9BC5-AA2B489E5E9A/Demo.app/Frameworks/libclang_rt.asan_iossim_dynamic.dylib

...

当然了,最好是及时从libstdc++迁移到libc++了,具体步骤不赘述。附苹果的Xcode发布日志:

Building with libstdc++ was deprecated with Xcode 8 and is not supported in Xcode 10 when targeting iOS. C++ projects must now migrate to libc++ and are recommended to set a deployment target of iOS 7 or later. Besides changing the C++ Standard Library build setting, developers should audit hard-coded linker flags and target dependencies to remove references to libstdc++ (including -lstdc++, -lstdc++.6.0.9, libstdc++.6.0.9.tbd, and libstdc++.6.0.9.dylib). Project dependencies such as static archives that were built against libstdc++ will also need to be rebuilt against libc++. (40885260)

对于本文的trick,苹果的工程师这样说:

libstdc++ was deprecated 5 years ago. Apple’s more recent platforms (tvOS and watchOS) don’t support it.
Support was removed from the iOS 12.0 Simulator runtime, but it remains in the iOS 12.0 (device) runtime for binary compatibility with shipping apps.
You should update your project to use libc++ rather than libstdc++ by setting the CLANG_CXX_LIBRARY build setting (“C++ Standard Library”) to libc++.
If you have any static libraries that depend on libstdc++.tbd, you can workaround it for now by copying the file from the SDKs in Xcode 9.4 (and libstdc++.*.dylib in the iOS simulator runtime), but that is not a long term solution. You should contact the provider of those libraries and request versions built using libc++.

最后附上脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/sh

# 请替换新旧版本Xcode安装路径
XCODE_9_PATH="/Users/cc/Downloads/Software/Xcode/9.1/Xcode9.1.app"
XCODE_10_PATH="/Users/cc/Downloads/Software/Xcode/Xcode.app"

IPHONE_SDK_SUFFIX="/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib"
SIMULATOR_SDK_SUFFIX="/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib"
RUNTIME_SUFFIX="/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib"

cp -R "${XCODE_9_PATH}${IPHONE_SDK_SUFFIX}/"libstdc++.* "${XCODE_10_PATH}${IPHONE_SDK_SUFFIX}/"
cp -R "${XCODE_9_PATH}${SIMULATOR_SDK_SUFFIX}"/libstdc++.* "${XCODE_10_PATH}${SIMULATOR_SDK_SUFFIX}/"
cp -R "${XCODE_9_PATH}${RUNTIME_SUFFIX}"/libstdc++.* "${XCODE_10_PATH}${RUNTIME_SUFFIX}/"

对于一些旧项目,或所依赖的第三方库有链接libstdc++动态库的项目,必须替换为libc++才可正常编译运行。
还是建议及时跟进更新。

Author: Jason

Permalink: http://blog.knpc21.com/ios/xcode10-adaption-libstdcpp/

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。

Comments