彭某的技术折腾笔记

彭某的技术折腾笔记

Conda 找不到 GLIBCXX

2024-05-13

Conda 找不到 GLIBCXX

2024年5月13日

摘要

在 Anaconda 中,安装和使用一些第三方库时,有时会遇到一类报错,大概意思是说某个 C 或者 C++ 的动态链接库中找不到某个版本的 GLIBCXX,本文将介绍原因及解决方案。

问题及原因

**首先,最常见的报错形式是:**conda: /lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found。关于标准库的问题一向分析起来非常棘手,因为涉及的问题深浅都有可能,不好定位。

**对于本文所述的报错,主要原因如下:虽然 **Anaconda 是一个 Python 的工具,但是大量的 Python 的库底层都是 C 或 C++ 编写的,只是提供了一个 Python 的接口封装。在 C/C++ 的库中,时长会为了缩减二进制文件的大小而选择使用动态链接的方式生成目标,动态链接库在 Linux 中的常见后缀名为 .so,在 Windows 中为 .dll,就算没有深入了解编译原理,应该也对这两个后缀名比较眼熟(具体如何生成动态链接库,此文并不涉及)。

在使用动态链接库时,最为重要的一点是 ABI(Application Binary Interface)兼容,也就是两个要链接的文件,必须使用同样的符号(编译生成的文件的关键字),且二进制接口必须相同。然而,在一些函数库甚至标准库在经历某些版本升级时,ABI 层面会发生一些变化,导致失去互相兼容的能力(C 和 C++ 的符号生成规则也有所不同,所以二者也不能直接互相调用对方的库)。

**此问题的原因可能就出自于,系统自带的标准库,和 Anaconda 中某个虚拟环境的标准库版本有差异,无法做到 ABI 兼容。我们可以通过 **string 命令显示两个标准库所能兼容的版本:

 strings [SOME_STD_LIB] | grep GLIBCXX

可以得到类似如下的结果:

 GLIBCXX_3.4
 GLIBCXX_3.4.1
 GLIBCXX_3.4.2
 GLIBCXX_3.4.3
 GLIBCXX_3.4.4
 GLIBCXX_3.4.5
 GLIBCXX_3.4.6
 GLIBCXX_3.4.7
 GLIBCXX_3.4.8
 GLIBCXX_3.4.9
 GLIBCXX_3.4.10
 GLIBCXX_3.4.11
 GLIBCXX_3.4.12
 GLIBCXX_3.4.13
 GLIBCXX_3.4.14
 GLIBCXX_3.4.15
 GLIBCXX_3.4.16
 GLIBCXX_3.4.17
 GLIBCXX_3.4.18
 GLIBCXX_3.4.19
 GLIBCXX_DEBUG_MESSAGE_LENGTH

后面的数字则代表了此标准库支持的版本。

解决方案

常见的解决方案有两个:

添加链接库环境变量

有时是因为动态链接器没有识别到虚拟环境中的标准库,此时可以通过添加环境变量解决:

 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${CONDA_PREFIX}/lib

将当前虚拟环境的库目录追加到原本的链接库环境变量中。

手动链接系统库

如果上一个方法不生效,则大概率是标准库版本冲突,我们可以手动将系统自带的标准库创建软链接至 Anaconda 虚拟环境:

 ln -sf /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ${CONDA_PREFIX}/lib

即可强制当前虚拟环境使用系统库,从而解决冲突。

  • 0