私はカスタマイズされた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
を示しています。リンクする必要があるライブラリはglibcのカスタムバージョンであるため、実際に接続するために使用されるglibcと同じAPIを持つ可能性が高くなります(わかりません)。これらの仮定を使用すると、バイナリを編集して不足している項目を追加することができます。これを行うのに適したプログラムは次のとおりです。RPATH
RUNPATH
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
。環境変数を介してフラグを渡すこともできますが、構成スクリプトを実行する前に設定する必要があります。