질문에 답하십시오.

질문에 답하십시오.

나는 사용자 정의된 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를 가질 가능성이 높습니다(확실하지는 않음). 이러한 가정을 통해 바이너리를 편집하여 누락된 항목을 추가하는 것이 가능합니다 . 이를 수행하는 데 적합한 프로그램은 다음과 같습니다.RPATHRUNPATHRUNPATH파헬프다양한 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. 환경 변수를 통해 플래그를 전달할 수도 있지만 구성 스크립트를 실행하기 전에 설정해야 합니다.

관련 정보