1

I was trying to compile GCC 9.2 against a custom built GLIBC 2.30. I have installed GLIBC in a non-standard location. Then I have followed these steps to compile 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}"

The compilation was successful but the problem is GCC is still picking up the old library:

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)

Output of 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

Though this approach is working for other programs I am compiling myself for testing:

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)

What am I missing? How can I compile GCC against a custom GLIBC? How can I pass compiler and linker flags?

7
  • Can you edit the output of readelf -d programming/repos/gcc/gcc-install/bin/gcc-9.2 into the question? Note also for your working example you have glibc-install/lib (i.e. the install directory) but for the non-working case you have root/lib so maybe you didn't specify the correct directory. I know these are just examples but it shows how helpful it is to say exactly what you did rather than try and obscure details.
    – icarus
    Feb 3, 2020 at 20:26
  • Hi! I have updated the question with exact commands I have executed during compilation from bash history. I have also added the output of readelf -d programming/repos/gcc/gcc-install/bin/gcc-9.2. Feb 3, 2020 at 20:52
  • OK. There is no RPATH or RUNPATH entry in the readelf output, so this explains why the run time linker is using the default value. )You can run the readelf -d on your working example to see one of these, probably RUNPATH). So the invocation of the linker to build the gcc-9.2 binary is not being passed the CFLAGS you are using. To figure out why will require examining the Makefile.
    – icarus
    Feb 3, 2020 at 23:55
  • Yes, I have seen the RUNPATH entry in other binary's dynamic section. My guess was that the Makefile was not passing the CFLAGS I am providing but I wasn't sure. I have also tried to follow the Makefile but it is huge and I think auto generated. I am not very familiar with the build system of GNU tools other than make && make install. So I am waiting for a person to answer who has experience with this. Feb 4, 2020 at 0:22
  • 1
    Maybe stackoverflow.com/questions/13769141/… will help, using the suggested patchelf command?
    – icarus
    Feb 4, 2020 at 1:07

2 Answers 2

1

Answer to the question as asked.

Without seeing the Makefile it is not possible to say what variables, if any, are used in the final link step. CFLAGS and LDFLAGS are a widely supported convention but is not required. The OP tells us in comments that the Makefile is "huge" and possibly automatically generated. GNU Make has -O --trace options these days so it might be possible to find the command used to do the final link from that and either run the step manually with the desired modifications or else use the information to see where in the makefile the command is invoked from and work from there to find what needs to be edited or set to get the desired link step.

An alternative approach

The output of readelf -d shows us that the executable is missing a RPATH or RUNPATH to point to the desired libraries. As the libraries it is desired to link against are a custom version of glibc, it is probable (but not certain) that they will have the same API as the glibc that is actually being used for the link. With this assumption then the binary can be edited to add the missing RUNPATH. A suitable program to do this is patchelf which is packaged for various linux distributions.

The OP reported success with

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

According to Autoconf Manual in GNU build system compiler/linker flags/options are passed through configure script. So in my case, I should configure, compile and install in the following way:

$ 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

In the configure script I have only passed the variables/options that are relevant to the question asked. You may want to pass more options according to your specific needs. You can see all the options and accepted variables by running ~/gcc-src/configure --help. You can also pass flags through environment variables but you have to set them before running configure script.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .