BuildInputs not propagating to the derivation

For practice, I’m trying to package a very simple bash script with two dependencies (https://github.com/fcambus/ansiweather/blob/ed4e421e76effe7e6c64eb89ad4e46a043e5dbd7/ansiweather). It depends runtime on jq and bc, so these need to go in buildInputs. Unfortunately, when I build the package and run the result, the script cannot see jq or bc. I’m building the derivation by adding it to nixpkgs via an overlay, and then running nix-build '<nixpkgs>' -A ansiweather. Then running ./result/bin/ansiweather results in ERROR: Cannot find jq binary. Can someone point out where the error is? Below is my derivation:

{ stdenv, fetchFromGitHub, jq, bc }:

stdenv.mkDerivation rec {
  pname = "ansiweather";
  version = "1.15.0";
  src = fetchFromGitHub {
    owner = "fcambus";
    repo = "ansiweather";
    rev = version;
    sha256 = "148x881xjhw2ws1xs3m0xb30xv1s1q3bn40j0knl3z3sav75qzz7";
  };

  buildInputs = [
    jq
    bc
  ];

  installPhase = ''
    mkdir -p $out/bin
    cp ansiweather $out/bin/
  '';
}

buildInputs only make the dependencies visible at compile time. E.g., if you compile a C program, the headers and libraries of the derivations in buildInputs are made available when building the derivation. Then during linking the full library paths (e.g. /nix/[hash]-name-version/lib/libblah.so) are added to the binary. After building a derivation, buildInputs are not otherwise visible to the program anymore. There are two straightforward solutions to your problem:

  1. Replace occurrences of jq and bc by ${jq}/bin/jq and ${bc}/bin/bc when building the derivation, so that the script of the instantiated derivation contains the full path to these binaries.

  2. Make a wrapper for the script that adds jq and bc to the path. See the pass derivation for an example: https://github.com/NixOS/nixpkgs/blob/4e76dff4b469172f6b083543c7686759a5155222/pkgs/tools/security/pass/default.nix

If I understand correctly, you can try propagatedBuildInputs ?

propagatedBuildInputs won’t work here. It is meant to be used for transitive build time dependencies.

Many thanks for the responses! I used approach 2 since in seemed to be more robust. I didn’t manage to find any documentation for stdenv.lib.makeBinPath. It’s an useful tool and should be documented somewhere.

1 Like