use*_*269 3 c++ linux ubuntu gcc
我正在使用gcc(Ubuntu 5.2.1-22ubuntu2)5.2.1 20151010进行编译,但我也尝试了gcc 4.1.2并且我得到了同样的错误.
对于gcc 5.2.1
字符串/usr/lib/x86_64-linux-gnu/libstdc++.so.6|grep CXXABI给出
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.2
CXXABI_1.3.3
CXXABI_1.3.4
CXXABI_1.3.5
CXXABI_1.3.6
CXXABI_1.3.7
CXXABI_1.3.8
CXXABI_1.3.9
CXXABI_TM_1
CXXABI_FLOAT128
Run Code Online (Sandbox Code Playgroud)
对于正在编译的编译器gcc 4.8.3
strings gcc-build/build/x86_64-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6|grep CXXABI
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.2
CXXABI_1.3.3
CXXABI_1.3.4
CXXABI_1.3.5
CXXABI_1.3.6
CXXABI_1.3.7
CXXABI_TM_1
CXXABI_1.3
CXXABI_1.3.2
CXXABI_1.3.6
CXXABI_1.3.1
CXXABI_1.3.5
CXXABI_1.3.4
CXXABI_TM_1
CXXABI_1.3.7
CXXABI_1.3.3
Run Code Online (Sandbox Code Playgroud)
即没有1.3.8
在运行configure之前我也尝试过:
export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:$LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH
../gcc-4.8.3/configure --build=x86_64-linux-gnu
make
Run Code Online (Sandbox Code Playgroud)
错误信息:
msgfmt -o fr.mo ../../../../gcc-4.8.3/libstdc++-v3/po/fr.po
msgfmt: gcc-build/build/x86_64-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/lib/x86_64-linux-gnu/libicuuc.so.55)
msgfmt: Makefile:460: recipe for target 'de.mo' failed
Run Code Online (Sandbox Code Playgroud)
使用gcc 4.1.2进行编译时,我得到了同样的错误:
msgfmt -o fr.mo ../../../../libstdc++-v3/po/fr.po
gcc-build/gcc-4.8.3/build/x86_64-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/lib/x86_64-linux-gnu/libicuuc.so.55)
Makefile:460: recipe for target 'de.mo' failed
Run Code Online (Sandbox Code Playgroud)
使用gcc 4.1.2进行编译时,我在配置和make之前执行了以下操作
#where libraries i have compiled with gcc 4.1.2 are located i.e
export LD_LIBRARY_PATH=/opt/devtools/gcc-4.1.2/lib
#where libstdc++.so.6 is
export LIBRARY_PATH=/opt/gcc-4.1.2/lib64
strings /opt/gcc-4.1.2/lib64/libstdc++.so.6|grep CXXABI
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.1
CXXABI_1.3
Run Code Online (Sandbox Code Playgroud)
这让我想知道CXXABI_1.3.8来自哪里.我也在改变编译器之间做了'make distclean'
我在一个较新的编译器组合中偶然发现了同样的问题,即在构建GCC 4.8.5时使用gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609.到目前为止,解决方案显然已经完成了工作,并对问题给出了有价值的一般性解释.我在下面提供了更多细节和替代解决方案.
有问题的错误消息来自msgfmt程序 - gettext的一部分,国际化和本地化系统:
$ which msgfmt
/usr/bin/msgfmt
$ dpkg -S /usr/bin/msgfmt
gettext: /usr/bin/msgfmt
Run Code Online (Sandbox Code Playgroud)
msgfmt由GCC构建系统调用,以编译由当前正在构建的C++标准库(libstdc ++)发出的消息.msgfmt是一个动态链接的可执行文件,链接(以及其他)libicuuc.so.55- 一个跨平台的基于Unicode的全球化库:
$ ldd /usr/bin/msgfmt
libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007ff133f47000)
Run Code Online (Sandbox Code Playgroud)
(为清楚起见,未显示其他依赖项)
icuuc库是一个动态链接的共享对象本身,它依赖于stdc ++库:
$ ldd /usr/lib/x86_64-linux-gnu/libicuuc.so.55
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff688a16000)
Run Code Online (Sandbox Code Playgroud)
(为清楚起见,未显示其他依赖项)
上面的清单是使用我的交互式shell环境生成的,该环境解决了对libstdc++.so.6位于的系统级C++库的依赖性/usr/lib/x86_64-linux-gnu.但是,GCC构建环境显然将此依赖关系解析为在当前构建过程的早期阶段生成的C++库,即位于其中的C++库$TOP_BUILD_DIR/x86_64-linux-gnu/libstdc++-v3/src/.libs- 调用最初发布的错误消息:
msgfmt: gcc-build/build/x86_64-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/lib/x86_64-linux-gnu/libicuuc.so.55)
Run Code Online (Sandbox Code Playgroud)
我得到一个相当类似的输出:
msgfmt: /opt/build/gcc/gcc-4.8.4/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/lib/x86_64-linux-gnu/libicuuc.so.55)
Run Code Online (Sandbox Code Playgroud)
现在,回答原始问题,字符串'CXXABI_1.3.8'来自libicuuc.so.55库,它要求libstdc++.so.6它依赖的库提供特定的ABI版本:
$ strings /usr/lib/x86_64-linux-gnu/libicuuc.so.55 | grep CXXABI
CXXABI_1.3.8
CXXABI_1.3
Run Code Online (Sandbox Code Playgroud)
总而言之,GCC构建系统创建了一个循环依赖,它将系统范围的二进制文件与本地库混合:
libstdc++ (currenlty built) > msgfmt > libicuuc.so.55 > libstdc++.so.6
Run Code Online (Sandbox Code Playgroud)
通过解析libstdc++.so.6它自己的库结构而不是系统范围的版本.
Mats Petersson提出的解决方案涉及重建libicuuc.so.55库,使其依赖于旧版本libstdc++.so.6(希望与GCC构建系统兼容),这当然是有效的.然而,对我来说似乎有点不自然,因为它需要玩系统范围的二进制文件的依赖关系,这对任何非root用户都是无法控制的.
我的替代解决方案涉及构建gettext包的自定义版本,这样msgfmt二进制文件是自包含的,其依赖关系不会干扰GCC构建系统.可以通过在自定义版本的gettext中安装/opt并使用环境模块调整相关路径来实现.
当我尝试在带有 GCC 5.4.0 的 Ubuntu 16.04.3 LTS 上从源代码构建 GCC 4.8.5 时遇到了同样的问题。
作为一种解决方法,我只是为 makefile 中的 msgfmt 命令删除了 LD_LIBRARY_PATH。准确地说,我给出了我为使构建成功而执行的确切命令:
1 - 提取来源
tar zxfv gcc-4.8.5.tar.gz
cd gcc-4.8.5
Run Code Online (Sandbox Code Playgroud)
2 - 修改 msgfmt 的调用(添加 LD_LIBRARY_PATH= )并确保它是正确的
vi ./libstdc++-v3/po/Makefile.in
vi ./libstdc++-v3/po/Makefile.am
grep "MSGFMT =" ./libstdc++-v3/po/Makefile.in ./libstdc++-v3/po/Makefile.am
./libstdc++-v3/po/Makefile.in:MSGFMT = LD_LIBRARY_PATH= msgfmt
./libstdc++-v3/po/Makefile.am:MSGFMT = LD_LIBRARY_PATH= msgfmt
Run Code Online (Sandbox Code Playgroud)
3 - 配置(我只将 multilib 限制为 64 位,因为我的 64 位主机上没有安装 libc6-dev-i386 并且不想只为这个构建做),构建和安装
./configure --prefix=$HOME/gcc-4.8.5 --with-multilib-list=m64
make
make install
Run Code Online (Sandbox Code Playgroud)
因此,当使用较新的编译器构建的库与较旧版本的 C++ 库链接时,或者有时使用较新的头文件编译某些内容,然后链接到较旧的 C++ 库时,就会出现此问题。
如果“新系统”上安装的共享库比构建代码的共享库旧,则在将二进制文件从一个系统移动到另一个系统时也可能会出现类似的问题。
通常有三种可行的解决方案: 1. 使用较旧的编译器重新编译有问题的库。2. 安装新版本的 C++ 库。3. 从源代码重建 C++ 库(使用足够新的编译器)。