`makeWrapper` vs `buildInputs`


I am packaging software (unflac) that has a runtime dependency (ffmpeg; ffprobe to be specific). I always thought that it is enough to use buildInputs (or the derivations thereof) for runtime dependencies. However, unflac does not find ffprobe when putting ffmpeg into buildInputs.

The package works fine when using

  postInstall = ''
    wrapProgram $out/bin/unflac \
      --prefix PATH : ${lib.getBin ffmpeg}/bin

Is this the correct way to package such requirements? Are the buildInputs (and derivations thereof) only available during build time (I think they are not, but why is ffmpeg then not available?). I guess buildInputs does not work with binaries, is that so? What does buildInputs do exactly then? I think this could be discussed in the Nixpkgs manual.

buildInputs simply make the listed packages available to the build environment. It is up to the individual build systems to ensure that runtime dependencies are available at runtime. The ld wrapper included in the standard environment does this automatically for ELF libraries but for programs, you may need to do it manually using a wrapper or by hardcoding the path into the executable using a patch.

Sometimes there is an configure flag to specify where to find ffmpeg. That way the path can be hard-coded into the binary. Otherwise, you can wrap it like your example shows.

Small suggestion: you can use --prefix PATH : "${lib.makeBinPath [ ffmpeg ]}. Most other packages do it this way it seems: GitHub Code Search (Preview)