Install executable at /usr/bin

I am trying to package my own hello package, below is main.c

#include <stdio.h>

int main() {
  printf("this is myhello!\n");
  return 0;
}

Then in default.nix

{ pkgs ? import <nixpkgs> {} }:
pkgs.stdenv.mkDerivation {
  buildInputs = [ pkgs.gcc ];
  name = "myhello";
  version = "0.0.1";
  src = ./.;
  buildPhase = "gcc -omyhello main.c";
  installPhase = ''
    mkdir -p $out
    install -m755 myhello $out/
  '';
}

So I can build it and run it,

$ nix-build 
...
/nix/store/b5gypqfwrh74hz9089pp8vyvv9qmczq1-myhello
$ ./result/myhello 
this is myhello!

But how do I make it available across the system, similar to nixpkgs.hello?

$ myhello
bash: myhello: command not found

The direct answer to you question is nix-env -f. -i.
I’d still recommend reading the manual chapter about package management, especially if you’re using NixOS.

I can’t find in docs how to specify where to place the executable.
Still not getting executable added to some binary location like /usr/bin

$ nix-env -f. -i
replacing old 'myhello-0.0.1'
installing 'myhello'
this derivation will be built:
  /nix/store/1dqkadbir5kxp968pincdpg2qldspf7h-myhello.drv
building '/nix/store/1dqkadbir5kxp968pincdpg2qldspf7h-myhello.drv'...
unpacking sources
unpacking source archive /nix/store/ja1m30maw0d7b88qkak60ihlqfvm04x3-myhello
source root is myhello
patching sources
configuring
no configure script, doing nothing
building
installing
post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/3lybcfms3savz1akwglmrlwlhla5l38p-myhello
shrinking /nix/store/3lybcfms3savz1akwglmrlwlhla5l38p-myhello/myhello
strip is /nix/store/n95cd4q1dqzdvsiy1hmrkx9shwi3n4sh-gcc-wrapper-11.3.0/bin/strip
strip is /nix/store/n95cd4q1dqzdvsiy1hmrkx9shwi3n4sh-gcc-wrapper-11.3.0/bin/strip
patching script interpreter paths in /nix/store/3lybcfms3savz1akwglmrlwlhla5l38p-myhello
checking for references to /build/ in /nix/store/3lybcfms3savz1akwglmrlwlhla5l38p-myhello...
building '/nix/store/k8f840jpqxzz1wch60vcpjsdb3g34amd-user-environment.drv'...
$ myhello
bash: myhello: command not found

You’re installing myhello into $out/, but an executable should be in $out/bin/ to show up on the PATH.

1 Like

Are there docs that tells where the artifacts should be placed after build to install them?

The build artifacts are always stored inside the Nix store (/nix/store if you haven’t changed the default location), specifically at /nix/store/<hash>-<name>. Nix won’t allow touching any file outside that path, so you can’t install files in the conventional sense.

The way Nix works is that programs are “installed” by symlinking their path under the Nix store into a profile, which is just a directory that is added to variables such as $PATH, so your shell can find binaries, manual pages, icons, themes, etc.

I think this roughly follows a pattern of using an FHS-like path relative to each package ($out/bin, $out/lib, $out/etc, $out/share, and so on).

I looked in the manual and I definitely see examples of the most common locations in there, but I don’t see a terse, explicit reference that covers everything in one place.