How to prevent a library's closure from including the compiler?

I am building gRPC (a C++ library) with Nix, and its closure includes the whole compiler. This shouldn’t happen.

This seems to be a relatively common issue judging by the Nixpkgs issue tracker, but I don’t know how to debug it. Any help?

The derivation is here: grpc.nix. I’m building like this:

git clone https://github.com/juspay/fencer && cd fencer
git checkout 7893ec9f73f60fd9fa268ea5147d71f4183d0a41
grpcpath=$(nix-build -E '(import (import ./nixpkgs.nix) { }).callPackage ./nix/grpc.nix { }')

Dependencies include clang (or gcc when building on Linux):

nix path-info -r $grpcpath

[...]
/nix/store/cwrk2vqzxjrx0rbcbiwwjzchqcryy403-clang-wrapper-7.1.0
/nix/store/dknqnzw03h8xsg9j01wl1p6nyijsx0d3-clang-7.1.0-lib
/nix/store/dl6zhysp7jgbc6xlrs7bisxzr234zjya-llvm-7.1.0-lib
/nix/store/gcvgcshff3i25kab2wcs07knh6ja8sk3-llvm-7.1.0
/nix/store/izvqz6bqil7z05b55qdqqd3z5sa7s65r-clang-7.1.0

A bit more information from nix why-depends:

nix why-depends $grpcpath /nix/store/izvqz6bqil7z05b55qdqqd3z5sa7s65r-clang-7.1.0

/nix/store/spmy7g2ika6l8569a8gcdvzv4ib5izd8-grpc-1.2.0-e2cfe9d
╚═══lib/libgrpc++.a: …...................../nix/store/cwrk2vqzxjrx0rbcbiwwjzchqcryy403-c
    => /nix/store/cwrk2vqzxjrx0rbcbiwwjzchqcryy403-clang-wrapper-7.1.0
    ╚═══bin/clang: …k disable=SC2193.[[ "/nix/store/izvqz6bqil7z05b55qdqqd3z5sa7s65r-cla
        => /nix/store/izvqz6bqil7z05b55qdqqd3z5sa7s65r-clang-7.1.0

I tried strip-ping generated binaries, but it didn’t help.

One thing I can probably do is excluding clang with disallowedReferences and doing post-hoc patching (like here) – but I don’t want to blindly patch things without knowing what I’m doing.

1 Like

The only thing i can think of is fixDarwinDylibNames.

But some notes about your expression, anything that is only to help with the build process should go into nativeBuildInputs, so autoconf and automake should go there.

you can also take a look at the official dervation located at pkgs/development/libraries/grpc/default.nix in the repo

fixDarwinDylibNames won’t do anything on Linux though, right? And the same problem occurs on Linux, just with gcc instead of clang.

on linux, generally you will see things linked again “gcc-lib” because that has libc in it.

On Linux I see both gcc-lib and wr5dlcw1asw8dwgm4bwjmga8f52m5lfx-gcc-7.4.0.

The only way to go is by investigation, a.k.a. trial and error. In you case the build depends on clang-wrapper, which is the compiler as been by the build system. the compiler itself does not see this wrapper.

The most probable reason for that string to be included in the build is in some kind of debug string kept around by the application. The reason it is not stripped is because it is not a debug info, but a real string.

Try to look around that string in the binary to see if it contains more debug info like that, and then try to find in the sources where that information is gathered and stored. Usually this occurs trough macros and defines.

Then you can patch the build to fake or dismiss that part. See for example how buildconfig file had to be disabled on firefox: https://github.com/NixOS/nixpkgs/commit/c03326445b067dca37ea323d998ffa3d520adb6d#diff-eaa73dcf578fe90b731a033ae775750e

Thanks! This was the crucial part. It turned out that clang -g was to blame for the debug info – I patched it out of the makefile and now my closure does not include the compiler anymore.

My patch is at https://github.com/juspay/fencer/pull/71.

2 Likes

Hmm… This is weird. Debug info should be stripped by the fixup phase. It would be interesting to see what sections where not stripped.

I’ll be happy to run some commands for you if you tell me how to look at the sections.