Prerequisition
- 开发环境: GLIBC_2.34 + GLIBCXX_3.4.29
- 目标主机: GLIBC_2.16 未提供libstdc++
- 我们需要发行一个 libxxx.so, 以及基于它的小工具 mine.exe
- libxxx.so 在编译时依赖了不可或缺的 libdrv1.so (闭源 外部提供) 这个so依赖了 GLIBC_2.34 + GLIBCXX_3.4.29
- 最终需要打包基于x86_64和arm两个arch
- glibc 位于kernel中,一般生产机不升级,但 libstdc++ 可以随程序发布
综上所述
- 不能在编译 libxxx.so 时用 -static_libstdc++,因为libdrv1.so有强制依赖 libstdc++.so
- 同样的原因 也不用 LLVM libc++
Solution
以目标主机arch=arm,Linux系统自带 GLIBC 2.16 举例(目标主机自带的 libstdc++.so 即使有也不用)
- 下载一套目标主机kernel (内含glibc 2.16)
- 基于以上glibc 在开发机编译 目标主机 libstdc++.so (ELF,ARM, GLIBCXX_3.4.32 + GLIBC_2.16) 和 arm_linux_gcc_15 (cross compile)
- 使用 arm_linux_gcc_15 编译目标主机 libxxx.so,编译出的so依赖 上一步"的libstdc++.so.32"和 第一步的 "glibc.so.16",部署用
- 若本地gcc版本过低,编译一套基于本地 GLIBC_2.34 的 libstdc++.32 和 gcc15,本机调试时用
编译本地和 cross GCC
BTW:g++编译器和libstdc++是同时产生的
网上相关文章很多了,这里引入几个,大概介绍一下概念:
- CROSS-GCC交叉编译target时,需要目标主机的glibc(kernel)和libstdc++和头文件
- CROSS-GCC自己,需要本地主机的glibc(kernel)和libstdc++和头文件
- binutil提供了ld,ar等工具,均区分目标和本地主机
- 交叉编译GCC 和 host-GCC 不是一个 binary,而clang比较简单 可以是一个
- Ref: https://pages.dogdog.run/toolchain/build_gcc.html
- Ref: https://zhuanlan.zhihu.com/p/110402378
和"目标主机"的绑定太深了, 是为了解决个什么问题呢?
- 基于-march=... 做指令集优化
- 使用最新的代码,获得最佳性能
目标主机的glibc在kernel里 无法升级,c++编译出来的程序同时依赖libstdc++和glibc,对他俩分别有最小版本要求。
开发机:libstdc++.so.29 依赖的glibc.so.34
目标主机:glibc 2.16
case1. 目标主机有了 libstdc++.so.29
我主机的libstdc++.29会带出glibc.34的函数 在目标主机运行不了
case2. 我的主机编译了一套极度保守的libstdc++.1 glibc.1
在所有机器上都能运行,但代码不是最新,性能可能不佳(例如调用了旧的为兼容保留下来的函数)
有的函数用不了,C++ standard, C standard, 都随着这些库在升级
Bazel方案
buck 2 看起来简单又规矩,可惜bazel生态好,有protobuf,grpc等开箱即用,希望fb多多努力多搞点周边,bazel历史包袱太大了,现在又走npm路线,为了讨好消费者吧
想想你的文章写的特别好https://www.ea55.com/
看的我热血沸腾啊https://www.237fa.com/
叼茂SEO.bfbikes.com
不错不错,我喜欢看
看的我热血沸腾啊
不错不错,我喜欢看 https://www.jiwenlaw.com/
想想你的文章写的特别好
叼茂SEO.bfbikes.com