針對定制的 GLIBC 編譯 GCC
我試圖針對定制的 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?如何傳遞編譯器和連結器標誌?
根據GNU 建構系統中的Autoconf 手冊,編譯器/連結器標誌/選項通過配置腳本傳遞。所以就我而言,我應該通過以下方式配置、編譯和安裝:
$ 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
。您還可以通過環境變數傳遞標誌,但您必須在執行配置腳本之前設置它們。
按要求回答問題。
在沒有看到的
Makefile
情況下,無法說出最終連結步驟中使用了哪些變數(如果有)。CFLAGS
並且LDFLAGS
是廣泛支持的約定,但不是必需的。OP 在評論中告訴我們這Makefile
是“巨大的”並且可能是自動生成的。現在 GNU Make 有-O --trace
一些選項,因此可能會找到用於執行最終連結的命令,然後手動執行該步驟並進行所需的修改,或者使用該資訊查看在 makefile 中呼叫命令的位置,以及從那裡開始工作以找到需要編輯或設置的內容以獲得所需的連結步驟。另一種方法
的輸出
readelf -d
向我們顯示執行檔缺少一個RPATH
或RUNPATH
指向所需庫。由於需要連結的庫是 glibc 的自定義版本,因此很可能(但不確定)它們將具有與實際用於連結的 glibc 相同的 API。有了這個假設,就可以編輯二進製文件以添加缺失的RUNPATH
. 一個合適的程序是patchelf,它為各種 linux 發行版打包。OP報告成功
patchelf --set-rpath ${GLIBCDIR}/lib --set-interpreter ${GLIBCDIR}/lib/ld-linux-x86-64.so.2 ${GCCDIR}/bin/gcc-9.2