ndk编译c++如何使用Android系统库

解决链接时的std::__ndk1未定义符号问题,其实是统一ndk STL命名空间问题(2023-11-30)

一、定位过程:

问题报错如图:

部分定位过程:

网上截图,STL命名空间差异对比:

直接导出Android的libc++.so和ndk libc++_shared.so符号对比:

对比可以看到:系统库是std::___1命名,ndk是std::__ndk1
这里不赘述定位过程,太漫长,直接放结论:


Android系统的STL基础库是libc++.so
ndk cmake编译时入参了CMAKE_ANDROID_STL_TYPE=c++_shared,STL是libc++_shared.so。默认也
是c++_shared
这两个基础库的命名空间有差异,导致无法直接相互链接

二、 解决思路

描述思路过程会有点繁琐,要结论小伙伴直接跳转 标题终极方案

  • 修改ndk的STL命名空间,也就是libc++_shared.so的符号变更
  • 使用ndk的STL编译Android系统库
  • 直接修改libc++_shared.so动态库符号
  • 系统中的libc++.so替换libc++_shared.so(前两个失败后,想到的)
     

 第一种Android源码的ndk的cxx-stl中没有libcxx的源码,只有头文件,libcxx直接下载了对应版本的源码,在ndk编译后缺少了很多符号,失败;
第二种直接在Android.bp中修改stl,非常复杂,各种报错无法解决,失败;
第三种STL命名符号非常多,更换符号地址非常复杂,有限工作量下不可能实现;
第四种直接替换后,cmake出现Unwind未定义符号,如下图,ndk中没有这个符号,在aosp/external/libcxx下修改libcxx的编译Android.bp,参考ndk stl下的Android.mk,补充ldflags,等
各种方法,失败;

 所有可能思路都做了很多次尝试,没有一个可以行得通,可谓山穷水尽

三、终极方案

山穷水尽后必然是柳暗花明了,最佳修改ndk stl符号的方法:
方案一:
将Android源码中的ndk cxx-stl头文件__config导入cmake编译工程
 

#${AOSP_PATH}/include/llvm/inclue 目录下是__config,只需要__config,其他都不需要,否则可
能报错
include_directories(BEFORE
${AOSP_PATH}/include/llvm/inclue
)

 注意:拷贝头文件下的_LIBCPP_ABI_VERSION是1,和系统libcxx一样,ndk编译中符号才能一致

 方案二:直接在ndk目录修改
如下__config修改同样可以修ndk STL识别符号,这两个目录的去掉ndk字段,第二个c++/v1下配置没有验证,有需要的小伙伴自行类比尝试。

建议方案一,这样可以不用变更ndk工具链

 

耗时一周,翻墙查阅几乎全网相关资料,头脑风暴尝试不下千次,最终质变为源码头文件导入的一次无
脑尝试,感谢Android新手光环。
ndk官网,各平台都在说明Android源码和ndk的基础库STL如何如何不同,不能直接调用,缺没有一篇
行之有效的解决方法,所以这次记录过程是有意义的。
谁会想到源码控制编译的头文件,可以动态变更基础库的符号呢,存在即合理,认知+1。
拿走不谢,也种一棵树
 

转载转述请标注出处,尊重来之不易的成果
更新日志:
2023.12.1:第一版,只有方案一
2023.12.5:更新标题三的方案二
部分参考链接(无翻墙代理访问的链接)
https://developer.android.google.cn/ndk/guides/cpp-support?hl=zh-cn#selecting_a_c_runtime
https://zhuanlan.zhihu.com/p/31025055
https://blog.csdn.net/thl789/article/details/109864831#%E4%B8%80%E3%80%81STL%E7%9B%B8%E5%85%B3%E7%9A%84%E6%A8%A1%E5%9D%97
https://haili-tian.blog.csdn.net/article/details/109920740?dreferer=aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3RobDc4OS9hcnRpY2xlL2RldGFpbHMvMTA5ODY0ODMx
https://blog.csdn.net/thl789/article/details/110148527
https://blog.csdn.net/roland_sun/article/details/49475969
https://releases.llvm.org/
 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值