I’ve been meaning to give Nix a try for a while. I’m somewhat convinced that the declarative, reproducible-build approach it suggests is very promising. Getting started is not trivial tough. There’s a lot of vocabulary and things.
Julia Evans wrote about some of her first steps. Here are some of mine: using nix to compile a small C++ program, with an external library.
External dependencies are usually a PITA with C/C++ programs. Even though you can something more complex with cmake
(here is an example with sdl+opengl), that’s for another day : before we compile a complex project we need to be able to build a simple one.
Here is how we want to lay the code out:
default.nix
file with the build details: the dependencies, where the code is stored, how to compile.src
directory contains the C++ coderesult/
, which is in fact a symlink to the nix store directory. With nix a lot of things are taken care of with symlinks.├── default.nix
├── result -> /nix/store/74gp7qalrqxh11pzqqrdhl2hi18q09ri-sdl-sample
└── src
└── main.cpp
First, here is the code. A minimalistic, black window opens. It relies on SDL2 being present.
// src/main.cpp
#include <SDL2/SDL.h>
int main(int arc, char ** argv) {
if (SDL_Init( SDL_INIT_VIDEO ) < 0) {
printf("SDL could not initialize!\n");
} else {
SDL_CreateWindow(
"SDL2 Demo",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
800, 600,
SDL_WINDOW_SHOWN
);
SDL_Delay(2000);
}
return 0;
}
Now for the build script. Here is what I understand:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "sdl-sample";
src = ./src;
buildInputs = [ gcc SDL2 SDL2.dev ];
buildPhase = "c++ -o main main.cpp -lSDL2";
installPhase = ''
mkdir -p $out/bin
cp main $out/bin/
'';
}
Now we can :
nix-build
. It assumes the build script is default.nix
../program/bin/main
)There are a lot of other features we did not cover, but we got it to work \o/