Compiled binary from github; how to install?

I’m trying to install rofi from the latest commit as the version in nixpkgs is from the last release 6 months ago.

I created a file and managed to hobble together a script that compiles a binary that ends up in /nix/store/XXX-rofi-1.0/bin/. I can run rofi from there.

What would be the next step so that I can run it with just “rofi” without using an alias?

Is there a better/easier way to do what I’m trying to do?

The script you created results in a derivation; i.e. the result of pkgs.stdenv { /* ... */ } is a derivation, just like how pkgs.hello is a derivation. Inside your configuration.nix, you can install that derivation the same way as you would go about installing pkgs.hello.

One way to install a program is by adding it to environment.systemPackages. An example configuration could look something like this:

{ pkgs, ... }: {
  environment.systemPackages = [
    (import ./path/to/your/script.nix pkgs)

    # rest of your packages...
  ];
}

Note how I use a pair of parentheses to ensure that import ./path/to/your/script.nix is evaluated as a function call (that returns a derivatino) rather than being treated as two separate items in the list. If we didn’t have those parentheses, we would get an obscure error, because import is a function, instead of a derivation.

You also need to make some changes to your script to make it more suitable for inclusion in your configuration:

  1. You should get the source via a fetcher like pkgs.fetchFromGitHub rather than hardcoding it. This makes your configuration not rely on random files being present on the file system.
  2. Rather than taking importing <nixpkgs>, you should take a pkgs input to your function. That way you avoid accidentally using two different versions of nixpkgs. (Ideally you would use the callPackage pattern, but that’s a separate issue.)

Hope this helps. Feel free to ask follow-up questions if my explanation was unclear :^)

1 Like

This was brilliantly explained! Thank you so much for the help; it’s working perfectly!

That’s great! Here are a few things you can do if you would like to go the extra mile:

  1. Use the callPackage pattern that I linked above. Your config would then end up looking something more like this:
environment.systemPackages = [
  (pkgs.callPackage ./path/to/your/script.nix { })
];
  1. Split your build into multiple phases. The way stdenv.mkDerivation works, you define each phase of your build separately. Right now you are doing all of your work in the “build” phase, but it should be split into the “configure”, “build” and “install” phases.
  2. Split your dependencies into different categories based on how they are used. This section of the nixpkgs manual tells you which categories to use. Proper categorization helps with closure size and makes the intention of the code easier to use.
  3. Add metadata in stdenv.mkDerivation { meta = { /* ... */ }; }.

If you make these changes, I think your package will be of comparable quality to the ones found in nixpkgs! (4) is probably a bit overkill unless you are actually thinking about upstreaming your derivation :^)