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} :
    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";
    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

import click, numpy, 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.