Nixでderivationを定義して、簡単なCプログラムをbuildしてみる
Nixさえあれば、local環境にgccやbashがなくてもbuildできる
すごいmrsekut.icon
方法としては2種類ある
普通は後者しかやらないと思うmrsekut.icon
上の記事では、説明のためにnix repl上でやっているだけだと思うmrsekut.icon
①と②の共通でやること
適当にC言語コードを用意する
code:simple.c(cpp)
void main() {
puts("Simple!");
}
code:builder.sh
export PATH="$coreutils/bin:$gcc/bin"
mkdir $out
gcc -o $out/simple $src
なぜならbuilder.shを記述しているときは、nix storeのbashのpathが確定していないから
envの方も、build時にPATHがクリアされるため無理
coreutilsとgccのbinをPATHに入れることで、コマンドを実行できるようにしている
これらは、buildする時に何らかの方法でnixpkgsから取って来る必要がある(後述)
$srcはderivationに渡す引数
つまり./simple.cになる
code:nix-repl
nix-repl> :l <nixpkgs>
nix-repl> simple = derivation { name = "simple"; builder = "${bash}/bin/bash"; args = ./builder.sh ; gcc = gcc; coreutils = coreutils; src = ./simple.c; system = builtins.currentSystem; } builder.sh内の$gccなどを読み込む為に、:l <nixpkgs>を実行している
その後、:bを使ってbuildする
code:nix-repl
nix-repl> :b simple
this derivation produced the following outputs:
out -> /nix/store/ni66p4jfqksbmsl616llx3fbs1d232d4-simple
これでもう実行できる
$ /nix/store/ni66p4jfqksbmsl616llx3fbs1d232d4-simple/simple
上のsimple.cとbuilder.shのあるdirの中に以下のdefault.nixを用意する
code:default.nix
with (import <nixpkgs> {});
derivation {
name = "simple";
builder = "${bash}/bin/bash";
inherit gcc coreutils;
src = ./simple.c;
system = builtins.currentSystem;
}
$ nix-build
引数を指定しないと自動的にdefault.nixという名前のファイルを探してくれる
するとresultという名前のdirectoryが作成される
なので$ ./result/bin/simpleで実行できるし、
readlinkコマンドで辿った先の/nix/store/<hash-name>/bin/simpeを直接実行しても良い 参考
尚、8でもっと良い方法があると言っているのでそちらも参考にすると良い