将g++4.8链接到libstdc++

Linking g++ 4.8 to libstdc++

本文关键字:libstdc++ 链接 g++4      更新时间:2023-10-16

我在桌面上下载并构建了gcc 4.8.1,运行64位Ubuntu 12.04。我像文档建议的那样,用命令从源代码构建了它

../../gcc-4.8.1/configure --prefix=$HOME --program-suffix=-4.8
make
make -k check
make install

它似乎通过了所有的测试,我把所有的东西都安装到了我的主目录中,后缀为-4.8,以区别于版本为4.6.3的系统gcc。

不幸的是,当我使用g++-4.8编译c++程序时,它链接到系统libc和libstdc++,而不是从gcc-4.8.1编译的新程序。我下载并构建了gcc 4.8,因为我想在标准库中使用新的C++11功能,所以这种行为绝对不是我想要的。我该怎么做才能让gcc-4.8自动链接到它附带的标准库,而不是系统标准库?

当您链接到自己的gcc时,您需要添加一个额外的带有-Wl,-rpath,$(PREFIX)/lib64的运行时链接器搜索路径,以便在运行时找到与您的gcc对应的共享库。

我通常在与gcc-4.8g++-4.8相同的目录中创建一个名为gccg++的包装器,我调用它而不是gcc-4.8g++-4.8,如动态链接器中所述。无法找到GCC库:

#!/bin/bash
exec ${0}SUFFIX -Wl,-rpath,PREFIX/lib64 "$@"

安装SUFFIXPREFIX时,应将其替换为传递给configure:的内容

cd ${PREFIX}/bin && rm -f gcc g++ c++ gfortran
sed -e 's#PREFIX#${PREFIX}#g' -e 's#SUFFIX#${SUFFIX}#g' gcc-wrapper.sh > ${PREFIX}/bin/gcc
chmod +x ${PREFIX}/bin/gcc
cd ${PREFIX}/bin && ln gcc g++ && ln gcc c++ && ln gcc gfortran

gcc-wrapper.sh就是那个bash片段)。

<小时>

上述解决方案不适用于某些版本的libtool,因为g++ -Wl,... -v采用链接模式,并因错误而失败。

更好的解决方案是使用specs文件。一旦构建了gcc/g++,调用以下命令使gcc/g++-将-rpath添加到链接器命令行(根据需要替换${PREFIX}/lib64):

g++ -dumpspecs | awk '/^*link:/ { print; getline; print "-rpath=${PREFIX}/lib64", $0; next } { print }' > $(dirname $(g++ -print-libgcc-file-name))/specs

我刚刚在构建gcc-4.8.2时遇到了同样的问题。我在那台机器上没有root访问权限,因此需要安装到我的主目录。经过几次尝试,我才发现让它发挥作用所需的魔力,所以我会在这里复制它,这样其他人会过得更轻松。这些是我用来配置gcc:的命令

prefix=/user/grc/packages
export LDFLAGS=-Wl,-rpath,$prefix/lib
export LD_RUN_PATH=$prefix/lib
export LD_LIBRARY_PATH=$prefix/lib
../../src/gmp-4.3.2/configure  --prefix=$prefix
../../src/mpfr-2.4.2/configure --prefix=$prefix
../../src/mpc-0.8.1/configure  --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix
../../src/gcc-4.8.2/configure  --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix --with-mpc=$prefix --enable-languages=c,c++

这给了我一个可工作的二进制文件,但我用那个版本的g++构建的任何程序都不会正确运行,除非我用-Wl、-rpath、$prefix/lib64选项构建它。通过提供规范文件,可以让g++自动添加该选项。如果你运行

strace g++ 2>&1 | grep specs

您可以看到它在哪些目录中检查specs文件。在我的案例中,它是$prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/specs,所以我运行g++-dumpsecs来创建一个新的specs文件:

cd $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2
$prefix/bin/g++ -dumpspecs > xx
mv xx specs

然后编辑该文件以提供-rpath选项。搜索这样的行:

*link_libgcc:
%D

并编辑以添加rpath选项:

*link_libgcc:
%D -rpath /user/grc/packages/lib/%M

%M扩展为/lib或/lib64,这取决于您构建的是32位可执行文件还是64位可执行程序。

请注意,当我在一个旧的gcc-4.7版本上尝试同样的技巧时,它没有起作用,因为它没有扩展%M。对于旧版本,您可以删除%M,只对lib或lib64进行硬编码,但只有当您只构建32位可执行文件(使用lib)或只构建64位可执行程序(使用lib64)时,这才是可行的解决方案。

gcc -print-search-dirs将告诉您编译器在哪里查找运行库等。您可以使用-B<prefix>选项覆盖此项。