编译后的现代 C++ 程序缺少 libc++ .so 如何静态链接

文章导读
当编译后的现代 C++ 程序缺少 libc++.so 时,意味着运行环境未安装 LLVM 的 C++ 标准库动态链接文件。解决方案是在编译阶段通过链接器参数强制静态链接该库,例如使用 Clang 编译器时添加 -static-libc++ 标志,或在 CMake 中设置 target_link_options。若无法重新编译,可尝试将对应版本的 libc++.so 文件部署至程序运行目录或系统库路
📋 目录
  1. linux 编译链接静态,Linux 环境下如何静态链接 C++ 库-CSDN 博客
  2. C/C++ 编程笔记:C++ 的链接问题,如何链接动态库和静态库
  3. C/C++ 中关于静态链接库 (.a)、动态链接库 (.so) 的编译与使用
  4. 静态链接 glibc,嫁接 c++11/c++17 到低版本编译器生成的程序上
  5. FAQ
A A

当编译后的现代 C++ 程序缺少 libc++.so 时,意味着运行环境未安装 LLVM 的 C++ 标准库动态链接文件。解决方案是在编译阶段通过链接器参数强制静态链接该库,例如使用 Clang 编译器时添加 -static-libc++ 标志,或在 CMake 中设置 target_link_options。若无法重新编译,可尝试将对应版本的 libc++.so 文件部署至程序运行目录或系统库路径,并通过 LD_LIBRARY_PATH 环境变量指定加载路径。静态链接可避免依赖问题,但会增加可执行文件体积,需权衡分发便利性与文件大小。

linux 编译链接静态,Linux 环境下如何静态链接 C++ 库-CSDN 博客

日常工作中,考虑到如下原因,可能会升级编译器如 GCC 的版本:使用新版本 C++ 的特性,比如 C++17。使用新的硬件引入的特性,比如 AVX 指令等。GCC 升级完成后,满足了我们的诉求,但同样的引入一个额外的问题,即目标程序或者目标库依赖的 C++ 库的版本号也会同步发生变化。查看 C++ 库的实际版本号,当升级 GCC 的版本号,如下符号链接对应的具体文件,将会发生变化。# ll /usr/lib/x86_64-linux-gnu/libstdc++.so.6 lrwxrwxrwx 1 root root 19 5 月 8 2019 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -> libstdc++.so.6.0.25 对于稍微大一点的系统而言,所有使用到目标程序或者库的主机,都需要同步安装新的 C++ 库,这是体力活,还能接受,但同样让人头痛。对于这个困境,有一个简单的处理办法,即将 C++ 库静态链接至目标程序或者目标库文件,这样就不存在分发 C++ 库的问题了。对于使用 CMake 来管理项目的团队,可以修改项目的 CMakeLists.txt 文件,样例如下:# 这里以动态库为例,增加静态链接 C++ 库和 GCC 库的选项。target_link_libraries(abc -static-libgcc -static-libstdc++) 修改前,使用 ldd 命令检查目标动态库的依赖。# ldd libabc.so linux-vdso.so.1 (0x00007ffc838a7000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7b4c054000) # 这里是对 C++ 库的依赖。libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7b4bcb6000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7b4ba9e000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7b4b6ad000) /lib64/ld-linux-x86-64.so.2 (0x00007f7b4c60b000) 修改 CMakeLists.txt 后,使用 ldd 命令检查目标动态库的依赖,显然,已经无法找到对 C++ 库的依赖了。# ldd libabc.so linux-vdso.so.1 (0x00007ffe687e4000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fafb601c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fafb5c2b000) /lib64/ld-linux-x86-64.so.2 (0x00007fafb661d000)

C/C++ 编程笔记:C++ 的链接问题,如何链接动态库和静态库

C++ 的链接分为两部分,一个是编译时,一个是运行时。但运行时的行为也收到编译参数的影响。1. 编译时链接 基本就两个参数,-l 和-L: -l 编译时要链接的库 (包括动态链接库.so 和静态链接库.a ),注意库的顺序,被依赖的放在后面。-L 查询链接库的位置,编译器将依次查找。(/usr/lib 之类的系统位置不用写)。一个例子:g++ -lfolly-lboost_system -L /opt/lib 2. 运行时链接 编译时,静态链接库.a 文件将直接被合并,因此运行时链接只涉及动态链接库.so 文件。执行 ldd your_file 可以查看指定文件运行时所需要链接的文件以及是否链接到指定位置。如果出现 Not found 或者链接到不正确位置,需要考察以下两个设置对象。2.1. 系统环境变量 LD_LIBRARY_PATH 链接程序首先考虑系统的环境变量 LD_LIBRARY_PATH ,从这里面设置的目录列表依次查找所需要的库文件。下面命令可以查看当前设置的 (用:隔开的) 目录列表:echo$ LD_LIBRARY_PATH 下面命令可以设置该列表:export LD_LIBRARY_PATH=~/lib:$LD_LIBRARY_PATH 注意将自己的目录放在最前面,多个目录用:隔开,并且包含原有的$LD_LIBRARY_PATH ,以免破坏其它程序的设置。该命令设置只会对当前窗口有效,新开窗口需要重新设置。

C/C++ 中关于静态链接库 (.a)、动态链接库 (.so) 的编译与使用

一、从动态库的编译说起 下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h, 三个.c 文件:test_a.c、test_b.c、test_c.c, 我们将这几个文件编译成一个动态库:libtest.so。将这几个文件编译成一个动态库:libtest.so 关于 gcc 编译的这几个参数后面会再说明的。二、动态链接库的使用 在上面的一中,我们已经成功生成了一个自己的动态链接库 libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。将 test.c 与动态库 libtest.so 链接生成执行文件 test: 现在生成了一个可执行文件 test,那么这个可执行文件到底有没有成功链接到动态链接库呢?我么可以使用下面的命令来查看:测试是否动态连接,如果列出 libtest.so,那么应该是连接正常了 执行 test,可以看到它是如何调用动态库中的函数的。关于 ldd 命令后面也会有所总结,这是一个专门查看应用程序中使用了哪一些动态链接库的程序。3.1 动态编译 最主要的是 GCC 命令行的一个选项:(1)-shared。该选项指定 gcc 编译器生成动态连接库,而不是可执行文件 (2)-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。正是使用这个,使得动态链接库不用再编译时拷贝库函数的完整代码,实现真正的动态链接。

编译后的现代 C++ 程序缺少 libc++ .so 如何静态链接

静态链接 glibc,嫁接 c++11/c++17 到低版本编译器生成的程序上

本文介绍了如何将 C++11 动态库在 gcc-4.1.2 和 glibc-2.5 的老旧环境中静态链接,并解决符号冲突,包括升级 glibc、使用 uclibc-ng 替换、以及处理不同版本的符号和链接策略。 本文将讲给您:1.怎样把 libc 静态链接到程序中。2.怎样把程序打包成"不调用"glibc 动态库的模块。3.怎样把 c++11/c++17 的程序嫁接到 gcc4.8.5 甚至更低版本编译器生成的程序上。1、问题出现的场景 2、解决方法的探索 2.1 升级 libc 2.2 另装高版本 libc 2.3 如何解决不同版本符号重定义 2.3.1 研究一个技术点 2.4 静态链接 libc.a 2.5 可否考虑换一个开源的 libc 2.6 继续尝试,来看一下 gcc 3、解决办法 3.1 选用第三方 libc: 3.2 链接一个 c 程序的示例:3.3 链接 c++11 程序的示例:4、补充 1、问题出现的场景 我们用 c++11(c++17) 实现了一个动态库 (libA.so) 并交给客户,客户要将这个动态库在 10 年前的老系统中进行链接。老系统使用 gcc-4.1.2,glibc-2.5,不支持 c++11 标准。用 gcc-9 编译好 libA.so,拿给老系统去链接,会直接报出类似下边的错误 ld:对符号'clock_gettime@@GLIBC_2.31'的未定义引用 一键获取完整项目代码 1 下图可表示当前遇到的问题:目标机 GCC4.1.2/c++98 客户开发环境 客户运行环境 GCC9.0/c++17 我方编译环境 链接成 链接成 glibc-2.5 可执行程序 glibc-2.5 主程序 glibc-2.31 功能模块

FAQ

静态链接和动态链接的主要区别是什么?

静态链接在编译期将库代码嵌入程序,生成独立可执行文件,分发时无需额外库文件;动态链接在程序运行时加载共享库,节省内存但需确保环境存在对应库。

如何检查程序依赖哪些动态库?

编译后的现代 C++ 程序缺少 libc++ .so 如何静态链接

在 Linux 环境下,可以使用 ldd 命令查看指定文件运行时所需要链接的文件以及是否链接到指定位置,如果出现 Not found 则表示缺失依赖。

缺少 libc++.so 是否可以用 libstdc++.so 替代?

不可以,libc++ 是 LLVM 项目的 C++ 标准库实现,而 libstdc++ 是 GCC 的实现,二者二进制接口不兼容,混用会导致未定义行为或崩溃。