如何将gcc约束到特定运行时环境

57hvy0tb  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(111)

我们有一个CI管道,它构建了一系列项目。其中一个项目使用了高级C特性(C20),因此我们将gcc版本升级到了gcc-9。
但是,我们有一些目标嵌入式系统运行debian buster,而没有更高版本的libc。为buster映像构建的映像不依赖于C20,它们的Makefile特别指定了std=c17。
所有这些项目都像以前一样工作得很好,但是现在我们得到了这样的错误:

./project: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by ./project)
./project: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./project)
./project: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./project)

当我研究这些符号时,我发现g++“不必要地”链接到那些不应该(据我所知)需要更新版本的东西的新版本:

objdump -T project | egrep "GLIBC_2.3[2-6]"
00000000      DF *UND*  00000000  GLIBC_2.33  lstat
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_once
00000000      DF *UND*  00000000  GLIBC_2.36  arc4random
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_detach
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_join
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_setspecific
00000000  w   DF *UND*  00000000  GLIBC_2.34  __pthread_key_create
00000000      DF *UND*  00000000  GLIBC_2.33  fstat64
00000000      DO *UND*  00000000  GLIBC_2.32  __libc_single_threaded
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_key_create
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_key_delete
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_getspecific
00000000      DF *UND*  00000000  GLIBC_2.34  pthread_create
00000000      DF *UND*  00000000  GLIBC_2.34  __libc_start_main

当然,我不需要在我的边缘设备上做一个buster->bookworm升级,这样我就可以得到一个新的和改进的bad_array_thrower?!
有没有一种方法可以通知gcc不要错误地使用新的符号,除非它们实现了新的特性?
再一次:正在构建的项目没有使用c++20,它们在gcc-8上编译和运行良好。这只是新的工具链,使它不可能建立在现场设备。

**编辑:**所以很清楚:我完全理解工具链不能混合和匹配。我只是希望能够在buster系统上使用C++20特性,而无需将其升级到bullseye+(因为gcc-8是buster上最高的可用软件包)。

envsm3lx

envsm3lx1#

TL;DR:与GLIBC不同,在任何操作系统上使用较新版本的libsdtdc++.so.6都很简单,Buster不会阻止您使用libstdc++.so.6版本2.36。
所以你确认的是:gcc不允许在buster上添加任何新的C++20特性--这是毫无疑问的。
这是 * 不正确的 *:你可以在Buster上使用gcc-10编译的二进制文件,但是你 * 必须 * 为这样的二进制文件提供一个合适的libstdc++版本。
与GLIBC不同,将二进制文件指向备用libstdc++.so.6是很简单的-只需在目标系统上的某个地方复制工具链的libstdc++.so.6,并设置-rpath,以便二进制文件在运行时使用备用libstdc++.so.6
事实上,libstdc++.so.6版本2.36 * 可能 * 是向后兼容的,你可以用更新后的版本替换系统版本(/usr/lib/arm-linux-gnueabihf/libstdc++.so.6),事情将继续工作。

相关问题