我试图针对定制的 GLIBC 2.30 编译 GCC 9.2。我在非标准位置安装了 GLIBC。然后我按照以下步骤编译 GCC:
sfinix@multivac:~$ GLIBCDIR=/home/sfinix/programming/repos/glibc/glibc-install/
sfinix@multivac:~$ export LDFLAGS="-Wl,-q"
sfinix@multivac:~$ CFLAGS="-L "${GLIBCDIR}/lib" -I "${GLIBCDIR}/include" -Wl,--rpath="${GLIBCDIR}/lib" -Wl,--dynamic-linker="${GLIBCDIR}/lib/ld-linux-x86-64.so.2""
sfinix@multivac:~$ cd ${GCC_BUILD_DIR}
sfinix@multivac:~$ make -j 4 CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}"
编译成功,但问题是 GCC 仍在拾取旧库:
sfinix@multivac:~$ ldd programming/repos/gcc/gcc-install/bin/gcc-9.2
linux-vdso.so.1 (0x00007ffc3b7cb000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f177772f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f177733e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1777acd000)
输出readelf -d programming/repos/gcc/gcc-install/bin/gcc-9.2
:
Dynamic section at offset 0x113dd8 contains 27 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
0x000000000000000c (INIT) 0x402a80
0x000000000000000d (FINI) 0x488440
0x0000000000000019 (INIT_ARRAY) 0x712de8
0x000000000000001b (INIT_ARRAYSZ) 48 (bytes)
0x000000000000001a (FINI_ARRAY) 0x712e18
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x4002b0
0x000000006ffffef5 (GNU_HASH) 0x400728
0x0000000000000005 (STRTAB) 0x4015f0
0x0000000000000006 (SYMTAB) 0x400798
0x000000000000000a (STRSZ) 1373 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x714000
0x0000000000000002 (PLTRELSZ) 3264 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x401dc0
0x0000000000000007 (RELA) 0x401d00
0x0000000000000008 (RELASZ) 192 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x401c80
0x000000006fffffff (VERNEEDNUM) 2
0x000000006ffffff0 (VERSYM) 0x401b4e
0x0000000000000000 (NULL) 0x0
虽然这种方法适用于其他程序,但我正在编译自己进行测试:
sfinix@multivac:~$ GLIBDIR=/home/sfinix/programming/repos/glibc/glibc-install/
sfinix@multivac:~$ vim test.c
sfinix@multivac:~$ CFLAGS="-L ${GLIBDIR}/lib -I ${GLIBDIR}/include -Wl,--rpath=${GLIBDIR}/lib -Wl,--dynamic-linker=${GLIBDIR}/lib/ld-linux-x86-64.so.2"
sfinix@multivac:~$ gcc -Wall -g ${CFLAGS} test.c -o run
sfinix@multivac:~$ ldd run
linux-vdso.so.1 (0x00007ffd616d5000)
libc.so.6 => /home/sfinix/programming/repos/glibc/glibc-install//lib/libc.so.6 (0x00007f5fcdc6e000)
/home/sfinix/programming/repos/glibc/glibc-install//lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f5fce22a000)
我错过了什么?如何针对自定义 GLIBC 编译 GCC?如何传递编译器和链接器标志?
按要求回答问题。
在没有看到的
Makefile
情况下,无法说出最终链接步骤中使用了哪些变量(如果有)。CFLAGS
并且LDFLAGS
是广泛支持的约定,但不是必需的。OP 在评论中告诉我们这Makefile
是“巨大的”并且可能是自动生成的。现在 GNU Make 有-O --trace
一些选项,因此可以从中找到用于执行最终链接的命令,然后手动运行该步骤并进行所需的修改,或者使用这些信息来查看在 makefile 中的哪个位置调用了该命令,并且从那里开始工作以找到需要编辑或设置的内容以获得所需的链接步骤。另一种方法
的输出
readelf -d
向我们显示可执行文件缺少一个RPATH
或RUNPATH
指向所需库。由于需要链接的库是 glibc 的自定义版本,因此很可能(但不确定)它们将具有与实际用于链接的 glibc 相同的 API。有了这个假设,就可以编辑二进制文件以添加缺失的RUNPATH
. 一个合适的程序是patchelf,它为各种 linux 发行版打包。OP报告成功
根据GNU 构建系统中的Autoconf 手册,编译器/链接器标志/选项通过配置脚本传递。所以就我而言,我应该通过以下方式配置、编译和安装:
在配置脚本中,我只传递了与所问问题相关的变量/选项。您可能希望根据您的特定需求传递更多选项。您可以通过运行查看所有选项和接受的变量
~/gcc-src/configure --help
。您还可以通过环境变量传递标志,但您必须在运行配置脚本之前设置它们。