Getting access to a 'bare' unwrapped compiler?

When I put gcc and clang in my pkg list the gcc/clang “binaries” are actually shell scripts that inject a ton of stuff. I’m building a fully statically linked binary (even libc) where all dependencies are vendored inside my source tree, so I actually don’t want to use anything from the nix store, and I don’t want any extra options I didn’t specify injected into the build.

How can I get access to the “bare” gcc and clang?

You can use gcc.cc or clang.cc to get the unwrapped compiler, however if you just want statically compiled programs, using pkgsStatic.callPackage is typically what you need and if you need access to the programs for static compilation they’re under pkgsStatic.buildPackages.

1 Like

This seems to be too bare. Now when I try to use musl, I get errors about stdatomic.h missing, which musl expects to be provided by the compiler :stuck_out_tongue:

$ echo '#include <stdatomic.h>' | clang -H -E -x c - -v >/dev/null

clang version 19.1.7
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/krcdrv2q2y67qzpzfggkwir0fl2ynq3w-clang-19.1.7/bin
 (in-process)
 "/nix/store/krcdrv2q2y67qzpzfggkwir0fl2ynq3w-clang-19.1.7/bin/clang-19" -cc1 -triple x86_64-unknown-linux-gnu -E -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/prophet/ssc -v -H -sys-header-deps -fcoverage-compilation-dir=/home/prophet/ssc -nostdsysteminc -resource-dir /nix/store/krcdrv2q2y67qzpzfggkwir0fl2ynq3w-clang-19.1.7/lib/clang/19 -internal-isystem /nix/store/krcdrv2q2y67qzpzfggkwir0fl2ynq3w-clang-19.1.7/lib/clang/19/include -source-date-epoch 315532800 -ferror-limit 19 -fmessage-length=98 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o - -x c -
clang -cc1 version 19.1.7 based upon LLVM 19.1.7 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/nix/store/krcdrv2q2y67qzpzfggkwir0fl2ynq3w-clang-19.1.7/lib/clang/19/include"
#include "..." search starts here:
End of search list.
<stdin>:1:10: fatal error: 'stdatomic.h' file not found
    1 | #include <stdatomic.h>
      |          ^~~~~~~~~~~~~
1 error generated.

If I switch to wrapped clang and check where it gets the header, it’s from the wrapped package:

. /nix/store/ydlsxccaypd968jxkkbb266g934pp0y7-clang-wrapper-19.1.7/resource-root/include/stdatomic.h

So I seem to be between a rock and a hard place, use the wrapper and get conflicts because the wrapper tries to include and link things from the store that I don’t want, or don’t use the wrapper and lose access to the headers that musl assumes the compiler provides :stuck_out_tongue:

pkgsStatic.buildPackages.clang and pkgsStatic.buildPackages.gcc should include all the necessary stuff to do static compilation or if you’re using callPackage, swapping it with pkgsStatic.callPackage should make your program statically compiled.

1 Like

I’m not sure what you mean. I only use nix packages to get access to a compiler, then I control the entire process myself (all vendored libraries, no nix store use). So there’s no callPackage anywhere, I just put llvmPackages_19.clang.cc in my flake’s package list so that an instance of clang is in my path so make can find it.

Ok, so add pkgsStatic.buildPackages.llvmPackages_19.clang to your package list and run x86_64-unknown-linux-musl-clang to compile your programs.

If you’re not on x86-64 run nix eval nixpkgs#pkgsStatic.buildPackages.llvmPackages_19.clang.meta.mainProgram to find which program you need to run.

1 Like

Same behavior from that version, you can see it complains that it’s configured to use an include directory that doesn’t exist:

$ echo '#include <stdatomic.h>' | clang -H -E -x c - -v >/dev/null
clang version 19.1.7
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/cbq33j3kg0wa2k7alxypdml3vfb8z7jp-clang-19.1.7/bin
 (in-process)
 "/nix/store/cbq33j3kg0wa2k7alxypdml3vfb8z7jp-clang-19.1.7/bin/clang-19" -cc1 -triple x86_64-unknown-linux-gnu -E -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/prophet/ssc -v -H -sys-header-deps -fcoverage-compilation-dir=/home/prophet/ssc -nostdsysteminc -resource-dir /nix/store/cbq33j3kg0wa2k7alxypdml3vfb8z7jp-clang-19.1.7/lib/clang/19 -internal-isystem /nix/store/cbq33j3kg0wa2k7alxypdml3vfb8z7jp-clang-19.1.7/lib/clang/19/include -source-date-epoch 315532800 -ferror-limit 19 -fmessage-length=75 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o - -x c -
clang -cc1 version 19.1.7 based upon LLVM 19.1.7 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/nix/store/cbq33j3kg0wa2k7alxypdml3vfb8z7jp-clang-19.1.7/lib/clang/19/include"
#include "..." search starts here:
End of search list.
<stdin>:1:10: fatal error: 'stdatomic.h' file not found
    1 | #include <stdatomic.h>
      |          ^~~~~~~~~~~~~
1 error generated.

Ok, try running x86_64-unknown-linux-musl-clang.

1 Like

Oops sorry I glossed over that part of your response. That worked! I can see it pull in /nix/store/54jpfpf7v9b8rkv49vib83zfgdzw34ap-x86_64-unknown-linux-musl-clang-wrapper-19.1.7/resource-root/include/stdatomic.h.

Summary:

  • Use the pkgsStatic.buildPackages.llvmPackages_19.clang package
  • Use the x86_64-unknown-linux-musl-clang binary in PATH instead of clang
1 Like