NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.44k stars 13.65k forks source link

GCC with -r fails on gcc 8 and earlier #101956

Open tsmanner opened 3 years ago

tsmanner commented 3 years ago

Describe the bug When compiling using versions of gcc older than gcc9 with the -r flag, the compile fails with ld reporting missing libraries.

To Reproduce Steps to reproduce the behavior:

  1. Create a simple nix file (i.e. foo.nix that will compile a minimal c++ program, like the following
    let
    source = (builtins.toFile "foo.cpp" ''
    int main() { return 0; }
    '');
    in with import <nixpkgs> {};
    stdenv.mkDerivation rec {
    name = "foo-relocatableObject";
    command = ''
    ${gcc}/bin/g++ -r ${source} -o $out
    '';
    buildCommand = ''
    echo ${command}
    ${command}
    '';
    }
  2. nix-build foo.nix and it should succeed
  3. Modify foo.nix to use pkgs.gcc8
    let
    source = (builtins.toFile "foo.cpp" ''
    int main() { return 0; }
    '');
    in with import <nixpkgs> {};
    stdenv.mkDerivation rec {
    name = "foo-relocatableObject";
    command = ''
    ${gcc8}/bin/g++ -r ${source} -o $out
    '';
    buildCommand = ''
    echo ${command}
    ${command}
    '';
    }
  4. nix-build with pkgs.gcc8 and it will fail with linker errors
    $ nix-build failing.nix
    these derivations will be built:
    /nix/store/4g345548c5sx270v7jacbmmd2fxjv9d1-foo-relocatableObject.drv
    building '/nix/store/4g345548c5sx270v7jacbmmd2fxjv9d1-foo-relocatableObject.drv'...
    /nix/store/l2abq8hpgdjc4x7dwdps7zqcnxmjmjp4-gcc-wrapper-8.3.0/bin/g++ -r /nix/store/dj1w2f5vdvlfmrhgiqq8sk9mlgpmns1h-foo.cpp -o /nix/store/9g836w4h4h6829ziwwvrc08qs2zf4hnw-foo-relocatableObject
    /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lm
    /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lgcc_s
    /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lc
    /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lgcc_s
    collect2: error: ld returned 1 exit status
    builder for '/nix/store/4g345548c5sx270v7jacbmmd2fxjv9d1-foo-relocatableObject.drv' failed with exit code 1
    error: build of '/nix/store/4g345548c5sx270v7jacbmmd2fxjv9d1-foo-relocatableObject.drv' failed
    Exception: nix-build exited with 100

Expected behavior The result link should exist and point to an object file that represents the relocatable (a.k.a. partially linked) object, under all versions of gcc that support the -r flag.

Additional context This behavior is consistent in my WSL2 Debian (x86_64 Intel) environment and on my NixOS (x86_64 AMD) server. It doesn't seem to have anything to do with the platform as far as I can tell. I also see the same failure using pkgs.gcc7 and pkgs.gcc48.

I do see, when NIX_DEBUG is enabled, that there are -L and -rpath flags being set in the wrapper that seem to point to the correct library directories:

initial path: /nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/bin:/nix/store/dqq1bvpi3g0h4v05111b3i0ymqj4v5x1-diffutils-3.7/bin:/nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/bin:/nix/store/b0vjq4r4sp9z4l2gbkc5dyyw5qfgyi3r-gnugrep-3.4/bin:/nix/store/c8balm59sxfkw9ik1fqbkadsvjqhmbx4-gawk-5.0.1/bin:/nix/store/g7dr83wnkx4gxa5ykcljc5jg04416z60-gnutar-1.32/bin:/nix/store/kkvgr3avpp7yd5hzmc4syh43jqj03sgb-gzip-1.10/bin:/nix/store/rw96psqzgyqrcd12qr6ivk9yiskjm3ab-bzip2-1.0.6.0.1-bin/bin:/nix/store/dp6y0n9cba79wwc54n1brg7xbjsq5hka-gnumake-4.2.1/bin:/nix/store/hrpvwkjz04s9i4nmli843hyw9z4pwhww-bash-4.4-p23/bin:/nix/store/xac1zfclx1xxgcd84vqb6hy3apl171n8-patch-2.7.6/bin:/nix/store/mm0w8jc58rn01c4kz2n9jvwd6bibcihs-xz-5.2.4-bin/bin
final path: /nix/store/71n1xcigc00w3z7yc836jqcx9cb2dys8-patchelf-0.9/bin:/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin:/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/bin:/nix/store/0k65d30z9xsixil10yw3bwajbdk4yskv-glibc-2.30-bin/bin:/nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/n48b8n251dwwb04q7f3fwxdmirsakllz-binutils-wrapper-2.31.1/bin:/nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin:/nix/store/0k65d30z9xsixil10yw3bwajbdk4yskv-glibc-2.30-bin/bin:/nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/bin:/nix/store/dqq1bvpi3g0h4v05111b3i0ymqj4v5x1-diffutils-3.7/bin:/nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/bin:/nix/store/b0vjq4r4sp9z4l2gbkc5dyyw5qfgyi3r-gnugrep-3.4/bin:/nix/store/c8balm59sxfkw9ik1fqbkadsvjqhmbx4-gawk-5.0.1/bin:/nix/store/g7dr83wnkx4gxa5ykcljc5jg04416z60-gnutar-1.32/bin:/nix/store/kkvgr3avpp7yd5hzmc4syh43jqj03sgb-gzip-1.10/bin:/nix/store/rw96psqzgyqrcd12qr6ivk9yiskjm3ab-bzip2-1.0.6.0.1-bin/bin:/nix/store/dp6y0n9cba79wwc54n1brg7xbjsq5hka-gnumake-4.2.1/bin:/nix/store/hrpvwkjz04s9i4nmli843hyw9z4pwhww-bash-4.4-p23/bin:/nix/store/xac1zfclx1xxgcd84vqb6hy3apl171n8-patch-2.7.6/bin:/nix/store/mm0w8jc58rn01c4kz2n9jvwd6bibcihs-xz-5.2.4-bin/bin
final host path: /nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/bin:/nix/store/dqq1bvpi3g0h4v05111b3i0ymqj4v5x1-diffutils-3.7/bin:/nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/bin:/nix/store/b0vjq4r4sp9z4l2gbkc5dyyw5qfgyi3r-gnugrep-3.4/bin:/nix/store/c8balm59sxfkw9ik1fqbkadsvjqhmbx4-gawk-5.0.1/bin:/nix/store/g7dr83wnkx4gxa5ykcljc5jg04416z60-gnutar-1.32/bin:/nix/store/kkvgr3avpp7yd5hzmc4syh43jqj03sgb-gzip-1.10/bin:/nix/store/rw96psqzgyqrcd12qr6ivk9yiskjm3ab-bzip2-1.0.6.0.1-bin/bin:/nix/store/dp6y0n9cba79wwc54n1brg7xbjsq5hka-gnumake-4.2.1/bin:/nix/store/hrpvwkjz04s9i4nmli843hyw9z4pwhww-bash-4.4-p23/bin:/nix/store/xac1zfclx1xxgcd84vqb6hy3apl171n8-patch-2.7.6/bin:/nix/store/mm0w8jc58rn01c4kz2n9jvwd6bibcihs-xz-5.2.4-bin/bin
/nix/store/l2abq8hpgdjc4x7dwdps7zqcnxmjmjp4-gcc-wrapper-8.3.0/bin/g++ -r /nix/store/dj1w2f5vdvlfmrhgiqq8sk9mlgpmns1h-foo.cpp -o /nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject
HARDENING: disabled flags: pie
HARDENING: Is active (not completely disabled with "all" flag)
HARDENING: enabling fortify
HARDENING: enabling stackprotector
HARDENING: enabling strictoverflow
HARDENING: enabling format
HARDENING: enabling pic
extra flags before to /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/bin/g++:
  -O2
  -D_FORTIFY_SOURCE=2
  -fstack-protector-strong
  --param
  ssp-buffer-size=4
  -fno-strict-overflow
  -Wformat
  -Wformat-security
  -Werror=format-security
  -fPIC
  -Wl\,-dynamic-linker
  -Wl\,/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/ld-linux-x86-64.so.2
original flags to /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/bin/g++:
  -r
  /nix/store/dj1w2f5vdvlfmrhgiqq8sk9mlgpmns1h-foo.cpp
  -o
  /nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject
extra flags after to /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/bin/g++:
  -B/nix/store/h53vw6vl9xq19x5y4prlwlfbpvnzh46s-gcc-8.3.0-lib/lib
  -B/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/
  -idirafter
  /nix/store/fwpn2f7a4iqszyydw7ag61zlnp6xk5d3-glibc-2.30-dev/include
  -idirafter
  /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/lib/gcc/x86_64-unknown-linux-gnu/8.3.0/include-fixed
  -B/nix/store/l2abq8hpgdjc4x7dwdps7zqcnxmjmjp4-gcc-wrapper-8.3.0/bin/
  -Wl\,-rpath
  -Wl\,/nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject/lib64
  -Wl\,-rpath
  -Wl\,/nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject/lib
  -L/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib
  -L/nix/store/h53vw6vl9xq19x5y4prlwlfbpvnzh46s-gcc-8.3.0-lib/lib
HARDENING: disabled flags: pie
HARDENING: Is active (not completely disabled with "all" flag)
HARDENING: enabling bindnow
HARDENING: enabling relro
extra flags before to /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld:
  -z
  now
  -z
  relro
original flags to /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld:
  -plugin
  /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/libexec/gcc/x86_64-unknown-linux-gnu/8.3.0/liblto_plugin.so
  -plugin-opt=/nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/libexec/gcc/x86_64-unknown-linux-gnu/8.3.0/lto-wrapper
  -plugin-opt=-fresolution=/build/ccTSTjMB.res
  -plugin-opt=-pass-through=-lgcc_s
  -plugin-opt=-pass-through=-lgcc
  -plugin-opt=-pass-through=-lc
  -plugin-opt=-pass-through=-lgcc_s
  -plugin-opt=-pass-through=-lgcc
  --eh-frame-hdr
  -m
  elf_x86_64
  -dynamic-linker
  /nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib64/ld-linux-x86-64.so.2
  -o
  /nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject
  -r
  /nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/crt1.o
  /nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/crti.o
  /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/lib/gcc/x86_64-unknown-linux-gnu/8.3.0/crtbegin.o
  -L/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib
  -L/nix/store/h53vw6vl9xq19x5y4prlwlfbpvnzh46s-gcc-8.3.0-lib/lib
  -L/nix/store/h53vw6vl9xq19x5y4prlwlfbpvnzh46s-gcc-8.3.0-lib/lib
  -L/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib
  -L/nix/store/l2abq8hpgdjc4x7dwdps7zqcnxmjmjp4-gcc-wrapper-8.3.0/bin
  -L/nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/lib/gcc/x86_64-unknown-linux-gnu/8.3.0
  -L/nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/lib/gcc/x86_64-unknown-linux-gnu/8.3.0/../../../../lib64
  -L/nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/lib/gcc/x86_64-unknown-linux-gnu/8.3.0/../../..
  -dynamic-linker
  /nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/ld-linux-x86-64.so.2
  /build/ccKUSohB.o
  -rpath
  /nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject/lib64
  -rpath
  /nix/store/kyw8ysa9hbmr7fnl6w340h09r0xbzhi7-foo-relocatableObject/lib
  -lstdc++
  -lm
  -lgcc_s
  -lgcc
  -lc
  -lgcc_s
  -lgcc
  /nix/store/cc0lmsl3b94xj5wcvm3h34qdcy8z2kzc-gcc-8.3.0/lib/gcc/x86_64-unknown-linux-gnu/8.3.0/crtend.o
  /nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/crtn.o
extra flags after to /nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld:
  -rpath
  /nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib
  -rpath
  /nix/store/h53vw6vl9xq19x5y4prlwlfbpvnzh46s-gcc-8.3.0-lib/lib
/nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lm
/nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lgcc_s
/nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lc
/nix/store/hrkc2sf2883l16d5yq3zg0y339kfw4xv-binutils-2.31.1/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
builder for '/nix/store/gf69i7xw2dr9g6548gl94x3813sc0hxn-foo-relocatableObject.drv' failed with exit code 1
error: build of '/nix/store/gf69i7xw2dr9g6548gl94x3813sc0hxn-foo-relocatableObject.drv' failed

Notify maintainers

Metadata Please run nix-shell -p nix-info --run "nix-info -m" and paste the result. Results from WSL:

 - system: `"x86_64-linux"`
 - host os: `Linux 4.19.128-microsoft-standard, Debian GNU/Linux, 10 (buster)`
 - multi-user?: `no`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3.7`
 - channels(tsmanner): `"nixpkgs-20.09pre242495.3c0e3697520"`
 - nixpkgs: `/home/tsmanner/.nix-defexpr/channels/nixpkgs`

Results from NixOS:

 - system: `"x86_64-linux"`
 - host os: `Linux 5.4.72, NixOS, 20.03.3158.7c2a362b58a (Markhor)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3.6`
 - channels(root): `"nixos-20.03.3158.7c2a362b58a"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

Maintainer information: NOTE: I suspect this is really an issue with the cc-wrapper or something similar.

# a list of nixpkgs attributes affected by the problem
attribute:
  - gcc8
  - gcc7
  - gcc6
  - gcc5
  - gcc49
  - gcc48
# a list of nixos modules affected by the problem
module:
tsmanner commented 3 years ago

One more thought on this, is it possible that this derivation is just missing the buildInput for those gcc-X.Y.Z-lib paths, so they're not accessible at build time? If so, then I would argue the statement we use a wrapper script that sets up the right environment variables so that the compiler and the linker just "work" seems at worst incorrect, and at best misleading.

veprbl commented 3 years ago

Why are you using "-o" flag instead of "-c"?

https://stackoverflow.com/questions/6570034/why-does-the-r-option-relocatable-make-ld-not-find-any-libraries

tsmanner commented 3 years ago

The -c flag works as long as there is only one source file per object file. My real-world use case is an environment where multiple .cpp files are used to define functions in a single .h. At some point, before the end of compilation, I would like to be able to describe intermediate object files that contain one class, so that large implementation files can be easily split apart.

More to the point, using just -c and creating separate .o files for each source file and then only linking one time at the very end would be a hack to get me going, and not a solution to the problem. The fact is that gcc9 from nixpkgs works, and invoking impure g++ on a Debian system in this way also works.

tsmanner commented 3 years ago

Doing some more digging and experimenting: it looks like including pkgs.glibc.static helps ld find libc and libm, but libgcc_s is still missing. Doing a diff of the output of g++ -v in each environment, to inspect the search paths, it looks like pkgs.glibc.static included the following new path there, which contains libm.a and libc.a.

/nix/store/621bazyaka30fnswdni4a4qr4x0zxa1f-glibc-2.30-static/lib

Is there some equivalent derivation that yields a libgcc_s.a? It seems, at the moment, like this may be solvable by just adding some buildInputs for these static libraries. I am not certain whether I can complete the compile with these versions of the static libraries, as I will eventually need to run this on pre-ABI change gcc4.8, since it's in use in some development environments at $dayjob, and I fear I'll need non-standard, or locally compiled, versions of those static libraries in order to link.

veprbl commented 3 years ago

Is there some equivalent derivation that yields a libgcc_s.a?

You might be able to get it from gcc.override { enableShared = false; }

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info