Skip to main content

How to Write a Simple, Cross-Platform Nix Derivation (with Flake Example)

·256 words·2 mins·
Srini
Author
Srini

Nix makes packaging software reproducible and portable. Here’s how to create a minimal derivation for a C program, and how to modernize it with flakes for automatic platform detection.

  1. Write Your Program Suppose you have a simple C file, simple.c:

    #include <stdio.h>
    int main() {
        puts("🐧 Hello! allo, allo!");
        return 0;
    }
    
  2. Write a Build Script Create simple_builder.sh:

    export PATH="$coreutils/bin:$gcc/bin"
    mkdir -p $out/bin
    gcc -o $out/bin/simple $src
    
  3. Write a Platform-Aware Derivation Create simple.nix that takes system as an argument:

    { pkgs ? import <nixpkgs> { }, system ? builtins.currentSystem }:
    
    pkgs.stdenv.mkDerivation {
    name = "simple";
    src = ./simple.c;
    builder = "${pkgs.bash}/bin/bash";
    args = [ ./simple_builder.sh ];
    inherit (pkgs) gcc coreutils;
    system = system;
    }
    

    Build with:

    nix-build simple.nix
    ./result/bin/simple
    

    Or override the platform:

    nix-build simple.nix --argstr system x86_64-linux
    
  4. Use Flakes for Maximum Portability
    Tip: Flakes require your project to be in a git repo.

    Create flake.nix:

    {
    description = "Simple C program";
    inputs.nixpkgs.url = "github:NixOS/nixpkgs";
    outputs = { self, nixpkgs }: {
        packages = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system:
        let pkgs = nixpkgs.legacyPackages.${system}; in
        pkgs.stdenv.mkDerivation {
            name = "simple";
            src = ./simple.c;
            builder = "${pkgs.bash}/bin/bash";
            args = [ ./simple_builder.sh ];
            inherit (pkgs) gcc coreutils;
            system = system;
        }
        );
    };
    }
    

    Initialize git and build:

    git init  # if not already a git repo
    nix build .#simple
    ./result/bin/simple
    

Summary
#

  • Use system to make your derivation portable.
  • With flakes, your build will work on any supported platform—just keep your project in a git repo.
  • Nix ensures your builds are reproducible and cross-platform, with minimal boilerplate.