我想要运行一些代码的服务器在标准位置安装了旧版本的 gcc(gmp、mpc、mpfr),例如/usr*
管理员不愿意更新,但允许我在我的/home/username
目录中安装较新版本的 gcc。我已经完成了此操作,现在g++d46
gcc 4.6.3 安装在我的主目录中/home/myusername/opt2/gcc-4.6.3
。我还安装了 gmp、mpfr、mpc /home/myusername/tmp/gcc/{include,lib,share}
。
我已经导出了{LD_LIBRARY_PATH, LIBRARY_PATH,LD_RUN_PATH}=/home/myusername/tmp2/gcc/lib:/home/myusername/opt2/gcc-4.6.3/lib/gcc/x86_64-unknown-linux-gnu/4.6.3:/home/myusername/opt2/gcc-4.6.3/lib64:
并且PATH=/bin:/usr/bin:/home/myusername/opt2/gcc-4.6.3/bin:
还{C_INCLUDE_PATH,CPLUS_INCLUDE_PATH}=/home/myusername/tmp2/gcc/include:/home/myusername/opt2/gcc-4.6.3/include/c++/4.6.3:
然后我编译一些测试代码
g++d46 -g -O3 -I/home/myusername/tmp2/gcc/include -L/home/myusername
/tmp2/gcc/lib -Wall testMPFR3.cpp -o myBin -lgmp -lgmpxx -lmpfr
它编译并执行正常,但是在执行后ldd myBin
我发现尽管大部分与我的正确库链接主目录, 我们还有:
libm.so.6 => /lib64/libm.so.6 (0x0000003917e00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003917a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003917600000)
-I
哪些不在我的主目录中,考虑到我导出的环境变量以及我的和标志,它如何知道去其他地方查找-L
?
另外,如果我确实g++ -H
看到标头来自哪里,那么大多数(谢天谢地包括新的 gmp、mpfr)都来自我的主目录,但有一些:
..... /usr/include/sys/cdefs.h
...... /usr/include/bits/wordsize.h
..... /usr/include/gnu/stubs.h
...... /usr/include/bits/wordsize.h
...... /usr/include/gnu/stubs-64.h
........ /usr/include/stdio.h
........ /usr/include/bits/wchar.h
........ /usr/include/xlocale.h
....... /usr/include/locale.h
..... /usr/include/ctype.h
....... /usr/include/bits/types.h
........ /usr/include/bits/wordsize.h
........ /usr/include/bits/typesizes.h
....... /usr/include/endian.h
........ /usr/include/bits/endian.h
........ /usr/include/pthread.h
......... /usr/include/sched.h
.......... /usr/include/time.h
.......... /usr/include/bits/sched.h
......... /usr/include/time.h
.......... /usr/include/bits/time.h
......... /usr/include/signal.h
.......... /usr/include/bits/sigset.h
......... /usr/include/bits/pthreadtypes.h
.......... /usr/include/bits/wordsize.h
......... /usr/include/bits/setjmp.h
.......... /usr/include/bits/wordsize.h
我不明白为什么我本地的 gcc-4.6.3 缺少这些?/usr/*
如果链接器在主目录中找不到它们,链接器又如何知道要恢复到它们?
我也许可以在编译时使用该标志--nostdinc
,但这可能无法解决由于某种原因无法在本地找到上述标头的问题。
答案1
您提到的标头以及/lib64/libc.so
和/lib64/libm.so
属于 glibc (因为 中的位置/lib64
已经表明这些是核心系统文件(否则它们将位于/usr/lib64
)。如果您编译自己的副本,您当然可以将您的程序链接到它。但除非这对你来说真的很重要,否则尽量不要 - 基本上所有东西都与 libc 链接,这意味着你应该重新编译所有东西(包括你的 GCC 和可能它依赖的任何东西)以确保你不会得到一个二进制文件,与 lib-xyz 和你的 glibc 安装链接,而 lib-xyz 将使用系统 glibc,这可能会产生一些令人讨厌的副作用。
如果您有兴趣构建更新的工具链,这当然可以完成,但要正确执行,您可能应该看看从零开始的Linux并撕掉适用于您的用例的部分。
至于动态链接器如何工作 - 检查man ld.so
(正如我在上一个问题中建议的那样)。要了解 GCC 如何搜索包含的标头,您可能需要阅读有关-I
和--sysroot
的内容man gcc
。