Runtime Dependency

I am trying to write a derivation hello-loud that utilizes another derivation hello-world, in order to learn how derivations can be composed.

The hello-world derivation works fine. (Here is the nix expression and here is the referenced builder).

I have a derivation (nix expression here and referenced builder here) that utilizes the hello-world package at build time. This works, but it uses the hello-world package at build time.

What I would like to do is to use the hello-world package at run time. In other words, turn the line in the builder from:

echo "echo '$(hello-world)' | tr [:lower:] [:upper:]" >> $PROGRAM_OUT

Into:

echo "hello-world | tr [:lower:] [:upper:]" >> $PROGRAM_OUT
1 Like

You need the absolute path one way or another. Something like:

1 Like

@abathur thank you, that was exactly what I needed! Now, the program generated by the derivation contains:

#!/bin/bash

set -e

/nix/store/m5qr2mn1nwz18gbahbc5fyrf4i8vnvaq-hello-world-0.0.1/bin/hello-world | tr [:lower:] [:upper:]

That’s exactly what I wanted to see!

I have two follow-up questions:

  1. Is this an idiomatic way to do what I originally intended - i.e., create a derivation that depends on another derivation?

  2. Is there a way to use nix-store --query ... to ask "what are the run time dependencies of `?

I want to make sure that nix “sees” `hello-world" as a runtime dependency of “hello-loud”.

1 Like

I just realized that I could run:

nix-store --query --references <path to executable in the nix store>

And that will list all the run time dependencies.

1 Like

You are already on the right track. By providing buildInputs you define build-time dependencies. stdenv sets these up in the environment for you. That’s why hello-world is available in your PATH and you can use the code from @abathur to get the actual store path. When Nix adds the package to the store after it has run the builder, it will essentially grep for store paths from the inputs in the output and adds those being found as runtime dependencies.

So you can add a runtime dependency by creating a file in the output containing the store path of the runtime dependency. This is the normal way to add a runtime dependency in a Nix build. The file could be a script, a binary, a config file or whatever you could imagine. Though a plain file only containing the store path is enough, it’s not very useful by itself of course. :wink:

That’s also why helpers like removeReferencesTo or nukeReferences exist to remove store path references in the output if there are somehow mentioned but actually not needed at runtime.

Also see the section in the Nix Pills about runtime dependencies to find out more.

You already found nix-store --query --references. I also use --requisites to get the whole closure and --referrers to get all store paths depending on a given path. To dig deeper into large closures, I tend to use nix-tree these days for an interactive view of the dependency tree instead of the --graph or --tree options to nix-store.

2 Likes