How to prevent a header-only library (msgpack-cxx) from being captured as a runtime dependency?

I’m currently packaging a C++ project using stdenv.mkDerivation and I am using msgpack-cxx as a dependency.Since it is a header-only library, I’ve placed it under nativeBuildInputs. However, the resulting build still contains a runtime reference to the msgpack-cxx store path.

Because msgpack-cxx depends on Boost, this adds over 130MB to my closure size, which is unacceptable for my specific deployment.

Here is my Minimum code demon:

typedef enum
{
    TCP = 0,
    UDP,
} SIMPLE_TYPE;
MSGPACK_ADD_ENUM(SIMPLE_TYPE);

typedef struct
{
    SIMPLE_TYPE type;
    std::string name;
    MSGPACK_DEFINE_MAP(type, name)
} SIMPLE_OBJ;

SIMPLE_OBJ simpleObj;
simpleObj.name = "test";
simpleObj.type = TCP;

printf("%s", simpleObj.name.c_str());

msgpack::sbuffer sbuf;
msgpack::pack(sbuf, simpleObj);
std::string dataPack = std::string(sbuf.data(), sbuf.size());
  • If I only use MSGPACK_DEFINE_MAP to define my structures, there is no runtime reference.

  • As soon as I call msgpack::pack(...) in my code, the resulting binary references the Nix store path of the headers, and I can’t seem to get rid of it.

1 Like

I can’t reproduce your issue, I’ve built the following derivation (where foo.cpp is your snippet) and the result only depends on glibc.

{
  stdenv,
  msgpack-cxx,
}:
stdenv.mkDerivation (finalAttrs: {
  pname = "foo";
  version = "0-dev";
  src = ./.;

  strictDeps = true;
  buildInputs = [ msgpack-cxx ];

  dontConfigure = true;

  buildPhase = ''
    $CXX foo.cpp -o foo
  '';

  installPhase = ''
    install -Dm755 foo $out/bin/foo
  '';
})

It shouldn’t affect anything in this case but it should go into buildInputs regardless of whether it’s header-only or not.

Maybe debug info isn’t being stripped, and it’s retaining the header filename/linenos for later debugging? are you setting dontStrip = true in your derivation?