Open tfc opened 3 years ago
@dtzWill Is there an LLVM version where this is known to work?
pkgsStatic.libcxxStdenv
(as opposed to pkgsStatic.llvmPackages.libcxxStdenv
should work). Unfortunately the static adapters don't get applied to all llvm stdenvs atm.
I marked this as stale due to inactivity. → More info
cc @Ericson2314 @sternenseemann @Mic92 I think I've found a reason why static+llvm stdenvs are broken.
Another issue here is that;
1) The makeStaticBinaries
stdenv (used to implement pkgsStatic
) passes -static
to the linker by setting NIX_CFLAGS_LINK
:
2) GCC's compiler driver or the linker ignores -Wl,-dynamic-linker=...
if you pass -static.
$ nix run nixpkgs#file $(nix build --print-out-paths nixpkgs#pkgsStatic.hello^out)/bin/hello
/nix/store/g6ay1bbrqcli3w51c9ghndw0j1f740ds-hello-static-x86_64-unknown-linux-musl-2.12.1/bin/hello:
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
:point_up: This one, built with the gcc stdenv, does not have a dynamic linker set.
2a) LLVM sets a dynamic linker anyway even if you pass -static
:
$ nix build --keep-failed nixpkgs/0d8145a5d81ebf6698077b21042380a3a66a11c7#pkgsStatic.pkgsLLVM.hello
:point_up: This fails during the check phase, because the produced executable segfault on startup.
:point_down: The reason they segfault is because the dynamic linker is running on the (static) binary, which does not work.
nix run nixpkgs#file /tmp/nix-build-hello-static-x86_64-unknown-linux-musl-*/hello-*/hello
/tmp/nix-build-hello-static-x86_64-unknown-linux-musl-2.12.1.drv-0/hello-2.12.1/hello: \
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, \
interpreter /nix/store/8lqwl0x6194hq7q862w8jn2wdxfb97fl-musl-static-x86_64-unknown-linux-musl-1.2.3/lib/ld-musl-x86_64.so.1, \
with debug_info, not stripped
3) -Wl,-dynamic-linker
, inserted by cc-wrapper
, is intended to be conditionalised on the $linkType
.
4) The $linkType
is inferred from the compiler wrappers arguments, which does not take $NIX_CFLAGS_LINK
into account, resulting in $linkType == dynamic
for pkgsStatic derivations.
I think if this is fixed more things will work. I wonder if GCC and/or LLVM should refuse the combination of -Wl,-dynamic-linker=... -static
in principle.
@pwaller was this fixed by https://github.com/NixOS/nixpkgs/pull/253116 ?
@pwaller was this fixed by #253116 ?
@Artturin I think it should be. I just tried to build the example but I hit https://github.com/NixOS/nixpkgs/issues/177129 in the build of libcxxabi-static-x86_64-unknown-linux-musl, during the configure step to check the compiler is working.
That is, that clang specifies gcc_eh to link, when it shouldn't, but this doesn't exist in a static-target gcc build. This is a clang issue, but clang doesn't have a way to know it shouldn't try to link gcc_eh. A workaround is to create an empty gcc_eh.
For libcxxabi, it could be worked around via CMAKE_C_COMPILER_WORKS, but I think a more general solution is needed. Perhaps to provide an empty gcc_eh in static builds so that clang's linker driver can function.
There is an additional problem. -lc++abi is appearing on the link line before -lc++ which is the root cause of the original messages in this thread. Additionally, -lc needs to appear after both of these. With those changes, I get a binary I can run.
nix-support/libcxx-ldflags
contains: -stdlib=libc++ -lc++abi
. These are the flags clang++ is passing to the linker:
"-lc++abi"
"-lc++"
"-lm"
"--start-group"
"-lgcc"
"-lgcc_eh"
"-lc"
"--end-group"
So as a workaround, I can get a functioning binary by compiling the original example with $CXX $src -o hello -static -lc++
.
Describe the bug
Using
pkgs.pkgsStatic
, it is easily possible to compile static c++ binaries using-static
. The same does not seem to work ifstdenv = pkgsStatic.llvmPackages.libcxxStdenv;
.To Reproduce
Minimal working example:
the gcc derivation works well:
With clang, the following happens:
Looking at
pkgs/development/compilers/llvm/11/libc++/default.nix
andpkgs/development/compilers/llvm/11/libc++abi.nix
i see that there is someenableShared
parametrization which hints at static binaries being possible, but from looking at the code i don't know if that is already supposed to work out of the box or still needs some tweaking.Expected behavior
Using clang with libcxx on c++ programs with
-static
should result in successful compilation of static binaries.Notify maintainers @vlstill @lovek323 @dtzWill @primeos
Metadata Please run
nix-shell -p nix-info --run "nix-info -m"
and paste the result.