skip to Main Content

I am packaging the following derivations.

  • A C++ library named amazing that has a header-only C++ dependency (nlohmann_json for this example).
    The library must be dynamic (shared ELF file).
    The amazing library requires the nlohmann_json dependency at build-time but not as run-time (as nlohmann_json is header-only).
    The users of amazing also require nlohmann_json at build-time, otherwise they will have a compilation error.
    But users do not need nlohmann_json at run-time.
  • A C++ executable named example that uses the amazing library.
  • A docker container named example-docker that just wraps a compiled version of example.
    I want the container to contain all needed run-time dependencies of example but to remain minimal — i.e., it should not contain nlohmann_json.

I have created a self-contained minimal git repository for this example.

My current Nix setup looks like this.

{ pkgs ? import (fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/21.11.tar.gz";
    sha256 = "162dywda2dvfj1248afxc45kcrg83appjd0nmdb541hl7rnncf02";
  }) {}
}:

let
  self = rec {
    nlohmann_json = pkgs.nlohmann_json;
    amazing = pkgs.stdenv.mkDerivation rec {
      pname = "amazing";
      version = "local";
      src = pkgs.lib.sourceByRegex ./lib [
        "amazing..pp"
        "meson.build"
      ];
      nativeBuildInputs = with pkgs; [ meson ninja pkgconfig ];
      propagatedBuildInputs = [ nlohmann_json ];
    };
    example = pkgs.stdenv.mkDerivation rec {
      pname = "example";
      version = "local";
      src = pkgs.lib.sourceByRegex ./example [
        "example.cpp"
        "meson.build"
      ];
      nativeBuildInputs = with pkgs; [ meson ninja pkgconfig amazing ];
    };
    example-docker = pkgs.dockerTools.buildImage {
      name = "example";
      tag = "latest";
      contents = [ example ];
      config = {
        Entrypoint = [ "${example}/bin/example" ];
      };
    };
  };
in
  self

The Nix setup works (all derivations build correctly and the container runs fine),
but the container is not minimal: nlohmann_json is in the container.

I tried several ways to define the nlohmann_json input of amazing so that
derivations that use amazing have nlohmann_json at build-time but without forcing the presence of nlohmann_json in the final container (propagatedNativeBuildInputs, depsBuildBuildPropagated from the nixpkgs manual),
but I could not achieve the desired result.
I also tried to use strictDeps = true; but I could not build my derivations in this case.

Is it possible to achieve what I want with Nix?

2

Answers


  1. I don’t have a complete answer, but you might look at disallowedReferences (see here). This and nixpkgs.removeReferenceTo are meant for this situation. Here are a couple of examples I found of it in use.

    But I messed around with your example for a while with various combinations of disallowedReferences/allowedReferences and remove-reference-to in your example derivation, along with various places to put nlohmann_json in the dependencies for amazing. I couldn’t get it to work. nlohmann_json was always included, or Meson would complain that it couldn’t find amazing. So something about removing the references to nlohmann_json ended up throwing out all of amazing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search