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).
Theamazing
library requires thenlohmann_json
dependency at build-time but not as run-time (asnlohmann_json
is header-only).
The users ofamazing
also requirenlohmann_json
at build-time, otherwise they will have a compilation error.
But users do not neednlohmann_json
at run-time. - A C++ executable named
example
that uses theamazing
library. - A docker container named
example-docker
that just wraps a compiled version ofexample
.
I want the container to contain all needed run-time dependencies ofexample
but 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?
2
Answers
I don’t have a complete answer, but you might look at
disallowedReferences
(see here). This andnixpkgs.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 putnlohmann_json
in the dependencies foramazing
. I couldn’t get it to work.nlohmann_json
was always included, or Meson would complain that it couldn’t findamazing
. So something about removing the references tonlohmann_json
ended up throwing out all ofamazing
.Sounds to me like you want to use propagatedNativeBuildInputs. See https://github.com/NixOS/nixpkgs/blob/master/doc/stdenv/stdenv.chapter.md#propagatednativebuildinputs-var-stdenv-propagatednativebuildinputs for the doc.