Using a "raw" `gcc` inside `buildFHSUserEnv`

I would like to have a buildFHSUserEnv-shell in which I can use a “raw” gcc that picks up libraries from system-locations like /usr/lib etc. to build things.

So far I have this shell.nix:

{ pkgs ? import <nixpkgs> { } }:

(pkgs.buildFHSUserEnv.override { stdenv = pkgs.stdenvNoCC; } {
  name = "fhs";

  targetPkgs = pkgs: (with pkgs; [
    gcc-unwrapped
    binutils-unwrapped
  ]);

  multiPkgs = null;
}).env

Entering this shell gives me:

these 6 derivations will be built:
  /nix/store/8jl4fgm5mrv3xgrdy75lzfgclhsnvfy9-profile.drv
  /nix/store/1l7qh9p856b3pibrgvnk59ys9i2n1sqx-fhs-chrootenv-etc.drv
  /nix/store/7zw4ijckcacgij9jqfa9wjinh7qa7b7v-builder.pl.drv
  /nix/store/vlklkhis1p4wd4l9r8r8ydcxdfp4b345-fhs-usr-target.drv
  /nix/store/q9z97giwiiz4agxd6jqqm7kzrsinkf0l-fhs-fhs.drv
  /nix/store/pqw56xqy7xyyqni1a9cqslsibsyr7qv5-fhs-init.drv
these 4 paths will be fetched (0.08 MiB download, 0.37 MiB unpacked):
  /nix/store/4y965wrv3shgg2s1ca431qpbrsb4dbag-stdenv-linux
  /nix/store/a9g7p6fwanw66j5djzila7ql1hky759z-bash-interactive-4.4-p23-dev
  /nix/store/j5cv3kba4cwx4dcnmsmhb25lfla0snzq-chrootenv
  /nix/store/wgap303sj9zqz63gw7nqxvf4dqz2hgai-stdenv-linux
copying path '/nix/store/j5cv3kba4cwx4dcnmsmhb25lfla0snzq-chrootenv' from 'https://cache.nixos.org'...
copying path '/nix/store/a9g7p6fwanw66j5djzila7ql1hky759z-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...
copying path '/nix/store/4y965wrv3shgg2s1ca431qpbrsb4dbag-stdenv-linux' from 'https://cache.nixos.org'...
copying path '/nix/store/wgap303sj9zqz63gw7nqxvf4dqz2hgai-stdenv-linux' from 'https://cache.nixos.org'...
building '/nix/store/7zw4ijckcacgij9jqfa9wjinh7qa7b7v-builder.pl.drv'...
building '/nix/store/8jl4fgm5mrv3xgrdy75lzfgclhsnvfy9-profile.drv'...
building '/nix/store/1l7qh9p856b3pibrgvnk59ys9i2n1sqx-fhs-chrootenv-etc.drv'...
building '/nix/store/vlklkhis1p4wd4l9r8r8ydcxdfp4b345-fhs-usr-target.drv'...
collision between `/nix/store/0c7c96gikmzv87i7lv3vq5s1cmfjd6zf-glibc-2.31-74/lib/locale/locale-archive' and `/nix/store/20dyxqvd9rnwzdnpdzb8vnv8w3vwa8wx-glibc-locales-2.31-74/lib/locale/locale-archive'
collision between `/nix/store/c10296m7xgm3ksibcklb2xf48jr635x3-gcc-9.3.0-lib/lib/libgcc_s.so' and `/nix/store/0c7c96gikmzv87i7lv3vq5s1cmfjd6zf-glibc-2.31-74/lib/libgcc_s.so'
collision between `/nix/store/c10296m7xgm3ksibcklb2xf48jr635x3-gcc-9.3.0-lib/lib/libgcc_s.so.1' and `/nix/store/0c7c96gikmzv87i7lv3vq5s1cmfjd6zf-glibc-2.31-74/lib/libgcc_s.so.1'
collision between `/nix/store/c10296m7xgm3ksibcklb2xf48jr635x3-gcc-9.3.0-lib/lib64/libgcc_s.so' and `/nix/store/0c7c96gikmzv87i7lv3vq5s1cmfjd6zf-glibc-2.31-74/lib64/libgcc_s.so'
collision between `/nix/store/c10296m7xgm3ksibcklb2xf48jr635x3-gcc-9.3.0-lib/lib64/libgcc_s.so.1' and `/nix/store/0c7c96gikmzv87i7lv3vq5s1cmfjd6zf-glibc-2.31-74/lib64/libgcc_s.so.1'
Use of uninitialized value in string eq at /nix/store/w3awmn2x43g2yymp7yzb3985r3b89f3i-builder.pl line 133.
collision between `/nix/store/jki00pcw0npk9hfmxc5ln41003225b1h-shadow-4.8.1/etc/pam.d' and `/nix/store/m267yyzj9y73827wh3wjgy02nv2b9pxz-fhs-chrootenv-etc/etc/pam.d'
Use of uninitialized value in string eq at /nix/store/w3awmn2x43g2yymp7yzb3985r3b89f3i-builder.pl line 133.
collision between `/nix/store/jki00pcw0npk9hfmxc5ln41003225b1h-shadow-4.8.1/etc/login.defs' and `/nix/store/m267yyzj9y73827wh3wjgy02nv2b9pxz-fhs-chrootenv-etc/etc/login.defs'
created 1332 symlinks in user environment
building '/nix/store/q9z97giwiiz4agxd6jqqm7kzrsinkf0l-fhs-fhs.drv'...
building '/nix/store/pqw56xqy7xyyqni1a9cqslsibsyr7qv5-fhs-init.drv'...

So there are at least some collisions because I think buildFHSUserEnv pulls in glibc by itself.

But the actual problem is that this gcc/ld doesn’t work:

$ gcc test.c
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find crtn.o: No such file 

(test.c is a simple “Hello, World!”)

But all of these, i.e., crt1.o, crti.o, libgcc_s.so, libc.so and crtn.o do exist in /usr/lib inside the FHS-env.

Output of gcc -print-search-dirs:

$ gcc -print-search-dirs
install: /nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/
programs: =/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/libexec/gcc/x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/libexec/gcc/x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/libexec/gcc/x86_64-unknown-linux-gnu/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../x86_64-unknown-linux-gnu/bin/
libraries: =/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../x86_64-unknown-linux-gnu/lib/x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../x86_64-unknown-linux-gnu/lib/../lib64/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../x86_64-unknown-linux-gnu/9.3.0/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../lib64/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../x86_64-unknown-linux-gnu/lib/:/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../

So these actually still point into /nix/store, and locations like /usr/lib don’t seem to be part of it?

Thanks!

Edit: Okay, the following actually kind of works, but I don’t really like it:

  runScript = ''
    env LIBRARY_PATH=/usr/lib C_INCLUDE_PATH=/usr/include CPLUS_INCLUDE_PATH=/usr/include CMAKE_LIBRARY_PATH=/usr/lib CMAKE_INCLUDE_PATH=/usr/include bash
  '';

I’d like it if “normal” paths would be searched by default, and I wouldn’t need to specify this again for individual build-tools etc. What’s the magic that makes this work in “other” distros, and where does nix remove this magic?

1 Like

Another option would be to use the wrapped compilers, and just use NIX_CFLAGS_COMPILE and NIX_LDFLAGS to reference the fhs paths. Then you can mix nix and other packages.

1 Like

Edit: Okay, the following actually kind of works, but I don’t really like it:

You can also define the env’s under profile, this way the runScript stays clear.

{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
  name = "fhs";
  targetPkgs = pkgs: (with pkgs; [ ... ]);
  multiPkgs = pkgs: with pkgs; [ ... ];
  profile = ''
    export LIBRARY_PATH=/usr/lib
    export C_INCLUDE_PATH=/usr/include
    export CPLUS_INCLUDE_PATH=/usr/include
    export CMAKE_LIBRARY_PATH=/usr/lib
    export CMAKE_INCLUDE_PATH=/usr/include bash
  '';
  runScript = "bash";
}).env

However, this does not solve the initial problem of that you have to set them manually. I do not know whats cause of this, but i guess it has to do with the FHS, so normally it works but with FHS you have to define it manually.

2 Likes