I’m very, very new to nix and nixOS both - I come from imperative workflows and very very rarely anything determinative, so this is all brand new to me.
As an example of the kind of thing I don’t understand how to do, let’s take an example repo I’ve been bouncing off: https://github.com/GideonWolfe/Chameleon
On a “normal” system, I can get pip and python ready, and then make install
and I’m off to the races.
With NixOS, I’ve got as far as adding python3 and gnumake to my configuration.nix packages. (I have also discovered that putting python in my system packages was the wrong move, so some advice on how better to go about this would be cool too.)
I can’t for the life of me wrap my head around what I’m supposed to do, and so many people online are using flakes but I’m on stable 23.11 (and quite daunted by flakes) so I’d prefer if this was from that POV.
Can anyone speak to any of these points? I’ve tried reading the docs but it’s very confusing for some reason.
Here are the basic steps though:
- package the target in a derivation aka a recipe to package the thing you like
- test it in a
nix-shell
or add it straight to yourconfiguration.nix
I know it sounds a lot like , but a few pointers:
Derivation basics: This wiki page is the one that helped me understand the basics of derivations. It explains how to package stuff without extra tooling.
stdenv.mkDerivation
from nixpkgs adds a bunch of stuff, but the wiki linked doesn’t explain it (yet?). You might find more information elsewhere.There’s documentation for stdenv.mkDerivation and I apologize in advance for putting this evil upon you, but right now I don’t have any other useful bookmarks. I learned it the hard way, but if you can contribute to the https://nixlang.wiki with what you learned, you could make it easier for the next person.
As for
nix-shell
, once you’ve written yourdefault.nix
, you can wrap it in ashell.nix
and executenix-shell
in the same directory.default.nix
{ pkgs ? import <nixpkgs> {} }: pkgs.stdenv.mkDerivation { pname = "chameleon"; version = "0.0.1"; # Update this to the real version of the package buildInputs = with pkgs; [ gnumake ]; # Add more necessary inputs here # While testing, your default.nix can reside in the checked out git repo src = ./.; # You can of course also start out like this straight away, up to you # Once testing is done, you can point this to a git repo pulled by nix # src = pkgs.fetchFromGitHub { # owner = "GideonWolfe"; # repo = "Chameleon"; # rev = "SOME GIT REVISION"; # hash = ""; # Start with an empty string and let nix complain with the real one, the use it # }; # There's a chance an install phase isn't necessary, but this is a skeleton # The contents are run in bash installPhase = '' runHook preInstall # Do non-standard installation stuff # See https://nixos.org/manual/nixpkgs/stable/#ssec-install-phase # for what is done by default runHook postInstall ''; }
shell.nix
{ pkgs ? import <nixpkgs> {} }: let my-package = (import ./default.nix) { pkgs = pkgs; }; in pkgs.mkShell { inputsFrom = [ my-package ]; }
Then you can run
nix-shell
and see if your expected binary is inPATH
. Once that is confirmed, you can add your package to yourconfiguration.nix
{ config, pkgs, ... }: { # The rest of your configuration.nix environment.systemPackages = with pkgs; [ # Import and call your derivation ((import /path/to/your/default.nix) { inherit pkgs; }) ]; }
Hopefully that helped a little.