Composing buildInputs to reduce code duplication

Hello all,

I am trying to write a flake which defines common build inputs which are used by all output packages and want to add to these common build inputs inside each subsequent derivations.

For example:


{
  description = "A simple flake test.";

  inputs.nixpkgs.url = github:NixOS/nixpkgs?ref=release-22.05;

  outputs = {self, nixpkgs} :
  let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
    # Common packages used by all derivations
    python_pkgs = pkgs.python310.withPackages(ps: with ps; [click numpy]);
    pkg_prefix = "simple-foo";
    pkg_version = "0.1.0";
  in
  {
    packages = {
      x86_64-linux.main= pkgs.stdenv.mkDerivation {
        pname = pkg_prefix;
        version = "v${pkg_version}";

        buildInputs = [python_pkgs];
      };

      x86_64-linux.default = pkgs.stdenv.mkDerivation {
        pname = "${pkg_prefix}-dev";
        version = "v${pkg_version}";

        # Add pytest to the already defined `python_pkgs`
        buildInputs = [python_pkgs python_pkgs.pkgs.pytest];
      };
    };
  };
}

However, this brings in a pytest from another path and not the expected python path

root@53fed3aaf07e:/build/examples/simple-python# which python
/nix/store/msz57gz5gzazq76n0x4gcy0mknk2m72k-python3-3.10.4-env/bin/python

import click, numpy, pytest
click.path
[’/nix/store/msz57gz5gzazq76n0x4gcy0mknk2m72k-python3-3.10.4-env/lib/python3.10/site-packages/click’]

numpy.path
[’/nix/store/msz57gz5gzazq76n0x4gcy0mknk2m72k-python3-3.10.4-env/lib/python3.10/site-packages/numpy’]

pytest.path
[’/nix/store/n8jipzbpivvsa2sxj80y7mbw0kmqh0sf-python3.10-pytest-7.1.1/lib/python3.10/site-packages/pytest’]

If you compare the paths of click and numpy they are basically site-packages belonging to the same path as the Python executable itself. However the pytest python package is from another path.

I know the way I tried to add pytest to the python_pkgs was clearly wrong as python_pkgs.pkgs is probably the defined inside.

Whats the best way to achieve this in nix?

You are describing propagatedBuildInputs.

@Sandro , thanks for your reply.

I think I could use propagatedBuildInputs but there is another question in my post. I think I was lazy in writing an appropriate title for the post.

The other question I have is, assuming the following:

pkgs = nixpkgs.legacyPackages.x86_64-linux;
python_pkgs = pkgs.python310.withPackages(ps: with ps; [click numpy]);

How can I later add pytest to it in a way that it comes from the same path?

Is there a way I could do something like following?


buildInputs = [ python_pkgs + python_pkgs.pkgs.pytest ];

Note, that python_pkgs.pkgs.pytest will simply fetch pytest from nix store instead of from inside the python_pkgs path.

Not sure if you can override it but you could definitely wrap it in a function that allows adding extra packages but I can’t help you with the specific of that.