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?

  • 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 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. – Ashfaqur Rahman Feb 3 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 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. – Ashfaqur Rahman Feb 4 at 0:22
  • 1
    Maybe stackoverflow.com/questions/13769141/… will help, using the suggested patchelf command? – icarus Feb 4 at 1:07

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

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.