What’s NIX ?
Nix is a functional package manager that guarantees reproducible independent and isolated builds for each package. It’s portable across operating systems. Long story short, it’s a greate package for your next software project. It was designed as part of a PhD thesis and it grew from there to be the system it is today.
However there are a few issues that a lot of people have complained about. The top issue I have seen is the learning curve for it. So we will be going through an example step by step now. Compiling the FFmpeg 4.0 is something I have chosen since it contains all the basic concepts to compile a nix package and should be good to give you a good idea how to compile other packages on your own.
Compiling FFmpeg 4.0
Let’s get started by creating our nix expressions.
1 2 | |
We will be working on these files as we progress.
Importing the source files
Nix imports the sources for your package by itself, you can have them in a compressed file. A git repository, or a git repo on Github.
1 2 3 4 5 6 7 8 9 10 | |
You can see stdenv and fetchurl at the top. This is the way nix declares its dependencies, stdenv and fetchurl are derivations in nix world. And we will need to use them, you can see that we use stdenv.mkDerivation to create the current ffmpeg derivation. We use fetchurl to fetch the sources from Github. We are choosing to pull a compressed archive.
One question you might have now, is that how can you know the sha256 beforehead. Nix got you covered, there’s a utility that comes with nix called nix-prefetch-url. It will fetch the file and give you the hash for it.
Now, let’s say you don’t want to fetch the archive and want to fetch the git repo.
1 2 3 4 5 6 7 8 9 10 11 | |
To know the hash for this, there’s a nix utility also, but you have to install it this time. nix-env -i nix-prefetch-git and nix-prefetch-git --rev ace829cb45cff530b8a0aed6adf18f329d7a98f6 https://git.ffmpeg.org/ffmpeg.git
Adding other ffmpeg dependencies
In order to compile ffmpeg we will of course need a lot of other libraries that ffmpeg depends on. And choose to enable or disable ffmpeg own libraries. We set which ffmpeg internal libraries to build next.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
You can notice we are using enableFeature, it’s just a simple function that takes a boolean value and library name and generates the configuration flag.
For the first case, it will take true (avcodecLibrary value) and avcodec and generate –enable-avcodec.
Now, we add some external dependencies, please note that all dependencies you mention need to have already existing nix expressions and you will be calling that nix expression name. To find if your requirement exists or not, you can check all-packages.nix
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
Now the configuration is all set. Let’s move to the building step, We specify two types of build inputs here.
nativeBuildInputs: those dependencies that are only used at build time to generate our code to run at run time.
buildInputs: those are used by the derivation at run-time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
Now that should be enough for us to go now. But not really, FFmpeg 4.0 comes with initial support for AV1, which uses libaom. Unfortunately, there’s no already existing nix expression for libaom, so we will write it ourselves. You should be able to understand the next nix expression on your own.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Next we go to our default.nix file. And we explicitly import the nix expression dependency for libaom into our ffmpeg expression since it doesn’t exist in the nix expressions. Now using libaom inside ffmpeg.nix won’t error.
1 2 3 4 5 6 | |
Let’s install it finally.
1
| |
NOTE: Credit to ffmpeg-full that I used (and edited to be beginner friendly).
Got any feedback? Let me know, please.