我试图针对定制的 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?如何传递编译器和链接器标志?
答案1
按要求回答问题。
如果没有看到,Makefile
就不可能说出最终链接步骤中使用了哪些变量(如果有)。CFLAGS
并LDFLAGS
得到广泛支持习俗但不是必需的。 OP 在评论中告诉我们,它Makefile
是“巨大的”并且可能是自动生成的。 GNU Make-O --trace
现在有选项,因此可以从中找到用于执行最终链接的命令,然后手动运行该步骤并进行所需的修改,或者使用该信息来查看在 makefile 中调用该命令的位置,然后从那里找到需要编辑或设置的内容以获得所需的链接步骤。
另一种方法
的输出向readelf -d
我们表明可执行文件缺少指向所需库的RPATH
或。RUNPATH
由于需要链接的库是 glibc 的自定义版本,因此它们很可能(但不确定)具有与实际用于链接的 glibc 相同的 API。有了这个假设,就可以编辑二进制文件以添加缺失的RUNPATH
.执行此操作的合适程序是帕切尔夫它是为各种 Linux 发行版打包的。
OP 报告成功
patchelf --set-rpath ${GLIBCDIR}/lib --set-interpreter ${GLIBCDIR}/lib/ld-linux-x86-64.so.2 ${GCCDIR}/bin/gcc-9.2
答案2
根据自动配置手册在 GNU 构建系统中,编译器/链接器标志/选项通过配置脚本传递。所以就我而言,我应该按以下方式配置、编译和安装:
$ GLIBCDIR=/home/sfinix/programming/repos/glibc/glibc-install/
$ LDFLAGS="-Wl,-q"
$ CFLAGS="-L ${GLIBCDIR}/lib -I ${GLIBCDIR}/include -Wl,--rpath=${GLIBCDIR}/lib -Wl,--dynamic-linker=${GLIBCDIR}/lib/ld-linux-x86-64.so.2"
$ mkdir ~/gcc-build
$ cd ~/gcc-build'
$ ~/gcc-src/configure --prefix=~/gcc-install CFLAGS=${CFLAGS} CXXFLAGS=${CFLAGS} LDFLAGS=${LDFLAGS}
$ make && make install
在配置脚本中,我只传递了与所问问题相关的变量/选项。您可能希望根据您的具体需求传递更多选项。您可以通过运行来查看所有选项和接受的变量~/gcc-src/configure --help
。您还可以通过环境变量传递标志,但必须在运行配置脚本之前设置它们。