I’m trying to learn how to package software with Nix. The software I want to package targets small routers, relies on shell scripting quite a bit, and uses tr
that is a part of coreutils
. The derivation is pretty run-of-the-mill:
{ lib, pkgs, stdenv, fetchFromGitHub, ... }:
stdenv.mkDerivation rec {
pname = "zapret";
src = fetchFromGitHub { owner = "bol-van"; repo = pname; };
propagatedBuildInputs = with pkgs; [ libcap zlib libnetfilter_queue libnfnetlink coreutils ];
buildPhase = ''
# copy some files
# replace hardcoded paths with ${placeholder "out"} using substituteInPlace
make all -C ${placeholder "out"}/
'';
installPhase = ''
# copy some files
'';
}
However, the package doesn’t have access to coreutils
at runtime when installed as systemd.packages
, because Nix determines runtime dependencies automatically and there’s no reference to ${pkgs.coreutils}/bin/tr
anywhere in the derived result.
What’s the generic way to deal with this? Patching all shell scripts to replace tr
with ${pkgs.coreutils}/bin/tr
seems extremely fragile and feels like a whack-a-mole (what if tr
is replaced in the future? Does it reference another shell command I didn’t happen to test for? tr
is too small of an anchor, etc).