web-dev-qa-db-ja.com

カスタムビルドされた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をコンパイルするにはどうすればよいですか?コンパイラとリンカーのフラグを渡すにはどうすればよいですか?

1
Ashfaqur Rahman

Autoconf Manual によるとGNUビルドシステムコンパイラ/リンカーフラグ/オプションはconfigureスクリプトを介して渡されます。そのため、私の場合は、次の方法:

$ 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を実行すると、すべてのオプションと受け入れられる変数を確認できます。フラグを環境変数を介して渡すこともできますが、configureスクリプトを実行する前にフラグを設定する必要があります。

0
Ashfaqur Rahman

尋ねられた質問に答えます。

Makefileを確認しないと、最後のリンク手順でどの変数が使用されているかを示すことはできません。 CFLAGSLDFLAGSは広くサポートされている規約ですが、必須ではありません。 OPは、Makefileが「巨大」であり、おそらく自動的に生成されることをコメントで教えてくれます。 GNU Makeは最近-O --traceオプションを持っているので、そこから最終的なリンクを行うために使用されるコマンドを見つけ、必要な変更を加えて手動でステップを実行するか、または使用することができるかもしれません。 makefileのどこからコマンドが呼び出され、そこから機能して、目的のリンクステップを取得するために編集または設定する必要があるものを見つけるための情報。

代替アプローチ

readelf -dの出力は、実行可能ファイルに、目的のライブラリを指すRPATHまたはRUNPATHがないことを示しています。リンク先のライブラリはglibcのカスタムバージョンであるため、実際にリンクに使用されているglibcと同じAPIを持つ可能性があります(ただし、確実ではありません)。この前提の下で、バイナリを編集して、不足しているRUNPATHを追加できます。これを行うのに適したプログラムは、さまざまなLinuxディストリビューション用にパッケージ化された patchelf です。

OPは成功を報告しました

patchelf --set-rpath ${GLIBCDIR}/lib --set-interpreter ${GLIBCDIR}/lib/ld-linux-x86-64.so.2 ${GCCDIR}/bin/gcc-9.2
1
icarus