Say that you got a c program, but almost any program will do, and put it in a file:
#include <stdio.h>
#include <gnu/libc-version.h>
int main (void) {
puts (gnu_get_libc_version ());
return 0;
}
And say that you want to build it against a specific version of glibc, for some reason. My initial attempt at doing this would be to create a Guix environment containing that old version of glibc
along with gcc
(and coreutils
for programs like ls
).
$ guix environment --pure --ad-hoc [email protected] gcc-toolchain coreutils
$ rm a.out && gcc printer.c && ldd a.out && a.out
linux-vdso.so.1 (0x00007ffd2cd0c000)
libgcc_s.so.1 => /gnu/store/jlrfl1ss3b4xjggvajwffa9zppfcxksf-gcc-5.5.0-lib/lib/libgcc_s.so.1 (0x00007fcefd7b6000)
libc.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libc.so.6 (0x00007fcefd5f9000)
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 (0x00007fcefd7d1000)
2.31
Unfortunately this doesn't seem to work. The resulting program is linked against a newer version of glibc
than I expected, 2.31 rather than 2.29. But this may be due to gcc
itself being linked against linked against glibc
2.31 and that ends up polluting the environment, so to speak.
$ ldd $(which gcc)
linux-vdso.so.1 (0x00007fff7cfc5000)
libm.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libm.so.6 (0x00007ff842b93000)
libc.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libc.so.6 (0x00007ff8429d6000)
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 (0x00007ff842cd6000)
Where do I go from here? I've tried using older versions of gcc
packaged in Guix, but they all seem to be built against glibc
2.31. I also tried adding -L /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib
to my gcc
-invocation but to no avail.
I was able to figure it out, or rather: cbaines on #guix@freenode pointed me towards the function
make-gcc-toolchain
which allowed me to set up the environment I wanted. By placing the following code into a file calleddevelopment-environment.scm
:and then running
guix environment --pure --ad-hoc --load=development-environment.scm
I was able to build my program using the version of glibc that I wanted:Hot tip for posterity: put the following in a file called
.envrc
, install the packagedirenv
and insert it into your shell rc, and fill it with the following content:That way, every time you enter that folder with your shell the development environment will be loaded for you. The right version of glibc/gcc will be run even without the
--pure
flag.