使用 Guix 针对旧的 glibc 进行构建
Build against an old glibc with Guix
假设你有一个 c 程序,但几乎任何程序都可以,并将它放在一个文件中:
#include <stdio.h>
#include <gnu/libc-version.h>
int main (void) {
puts (gnu_get_libc_version ());
return 0;
}
并说出于某种原因,您想针对特定版本的 glibc 构建它。我最初的尝试是创建一个 Guix 环境,其中包含 glibc
的旧版本以及 gcc
(对于像 ls
这样的程序,coreutils
)。
$ guix environment --pure --ad-hoc glibc@2.29 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
不幸的是,这似乎不起作用。生成的程序链接到比我预期的更新的 glibc
版本,2.31 而不是 2.29。但这可能是由于 gcc
本身被链接到 glibc
2.31 并且最终污染了环境,可以这么说。
$ 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)
我从这里去哪里?我试过使用 Guix 中打包的旧版本 gcc
,但它们似乎都是针对 glibc
2.31 构建的。我也尝试将 -L /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib
添加到我的 gcc
-invocation 但无济于事。
我能够弄清楚,或者更确切地说:#guix@freenode 上的 cbaines 将我指向函数 make-gcc-toolchain
,它允许我设置我想要的环境。通过将以下代码放入名为 development-environment.scm
:
的文件中
(use-modules (gnu packages base)
(gnu packages commencement)
(gnu packages gcc)
(gnu packages version-control))
(define-public gcc-glibc-2.29-toolchain
(make-gcc-toolchain gcc glibc-2.29))
(list gcc-glibc-2.29-toolchain git coreutils)
然后 运行宁 guix environment --pure --ad-hoc --load=development-environment.scm
我能够使用我想要的 glibc 版本构建我的程序:
$ rm a.out && gcc printer.c && ldd a.out && ./a.out
linux-vdso.so.1 (0x00007fff7e17c000)
libgcc_s.so.1 => /gnu/store/71rcc4qxfgyzr0qphkh9adjsqsb999zk-gcc-glibc-2.29-7.5.0-lib/lib/libgcc_s.so.1 (0x00007f2c8adc9000)
libc.so.6 => /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib/libc.so.6 (0x00007f2c8ac0f000)
/gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib/ld-linux-x86-64.so.2 (0x00007f2c8ade4000)
2.29
后人的热点提示:将以下内容放入名为 .envrc
的文件中,安装包 direnv
并将其插入到您的 shell rc 中,并在其中填充以下内容:
use guix --ad-hoc --load=development-environment.scm
这样,每次您使用 shell 进入该文件夹时,都会为您加载开发环境。 glibc/gcc 的正确版本将是 运行 即使没有 --pure
标志。
假设你有一个 c 程序,但几乎任何程序都可以,并将它放在一个文件中:
#include <stdio.h>
#include <gnu/libc-version.h>
int main (void) {
puts (gnu_get_libc_version ());
return 0;
}
并说出于某种原因,您想针对特定版本的 glibc 构建它。我最初的尝试是创建一个 Guix 环境,其中包含 glibc
的旧版本以及 gcc
(对于像 ls
这样的程序,coreutils
)。
$ guix environment --pure --ad-hoc glibc@2.29 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
不幸的是,这似乎不起作用。生成的程序链接到比我预期的更新的 glibc
版本,2.31 而不是 2.29。但这可能是由于 gcc
本身被链接到 glibc
2.31 并且最终污染了环境,可以这么说。
$ 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)
我从这里去哪里?我试过使用 Guix 中打包的旧版本 gcc
,但它们似乎都是针对 glibc
2.31 构建的。我也尝试将 -L /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib
添加到我的 gcc
-invocation 但无济于事。
我能够弄清楚,或者更确切地说:#guix@freenode 上的 cbaines 将我指向函数 make-gcc-toolchain
,它允许我设置我想要的环境。通过将以下代码放入名为 development-environment.scm
:
(use-modules (gnu packages base)
(gnu packages commencement)
(gnu packages gcc)
(gnu packages version-control))
(define-public gcc-glibc-2.29-toolchain
(make-gcc-toolchain gcc glibc-2.29))
(list gcc-glibc-2.29-toolchain git coreutils)
然后 运行宁 guix environment --pure --ad-hoc --load=development-environment.scm
我能够使用我想要的 glibc 版本构建我的程序:
$ rm a.out && gcc printer.c && ldd a.out && ./a.out
linux-vdso.so.1 (0x00007fff7e17c000)
libgcc_s.so.1 => /gnu/store/71rcc4qxfgyzr0qphkh9adjsqsb999zk-gcc-glibc-2.29-7.5.0-lib/lib/libgcc_s.so.1 (0x00007f2c8adc9000)
libc.so.6 => /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib/libc.so.6 (0x00007f2c8ac0f000)
/gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib/ld-linux-x86-64.so.2 (0x00007f2c8ade4000)
2.29
后人的热点提示:将以下内容放入名为 .envrc
的文件中,安装包 direnv
并将其插入到您的 shell rc 中,并在其中填充以下内容:
use guix --ad-hoc --load=development-environment.scm
这样,每次您使用 shell 进入该文件夹时,都会为您加载开发环境。 glibc/gcc 的正确版本将是 运行 即使没有 --pure
标志。