I am packaging the following derivations.
- A C++ library named
amazingthat has a header-only C++ dependency (nlohmann_json for this example). The library must be dynamic (shared ELF file). Theamazinglibrary requires thenlohmann_jsondependency at build-time but not as run-time (asnlohmann_jsonis header-only). The users ofamazingalso requirenlohmann_jsonat build-time, otherwise they will have a compilation error. But users do not neednlohmann_jsonat run-time. - A C++ executable named
examplethat uses theamazinglibrary. - A docker container named
example-dockerthat just wraps a compiled version ofexample. I want the container to contain all needed run-time dependencies ofexamplebut to remain minimal — i.e., it should not containnlohmann_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?
I don't have a complete answer, but you might look at
disallowedReferences(see here). This andnixpkgs.removeReferenceToare 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/allowedReferencesand remove-reference-to in your example derivation, along with various places to putnlohmann_jsonin the dependencies foramazing. I couldn't get it to work.nlohmann_jsonwas always included, or Meson would complain that it couldn't findamazing. So something about removing the references tonlohmann_jsonended up throwing out all ofamazing.