Fil-C on Nix

Filnix wiki

mbrock/filnix

lib/block-rust-go.nix

A stdenv adapter that marks Rust and Go derivations broken.

Fil-C compiles C and C++. Rust and Go bring their own compilers and runtimes, so a Fil-C build of them is either impossible or not memory safe in the Fil-C sense. With this adapter such packages fail evaluation with a "broken" problem that says why, instead of reaching a confusing error deep in rustc's or Go's platform tables. Native tools used at build time are unaffected: they come from buildPackages, whose stdenv this adapter does not touch.

Servers whose processes share memory that holds pointers are refused the same way: the PostgreSQL server here, nginx in ports.nix. Fil-C keeps each pointer's capability in the process's own shadow memory, so a pointer one process stores in shared memory has none in another (docs/nixos-userland.md). Their client libraries, such as libpq, are separate packages and stay Fil-C.

λlib, stdenvAdapters
let
19compiler=
λattrs
let
22names=
maplib.getName lib.filterlib.isDerivation attrs.nativeBuildInputs or [ ]
25isRust=
n: n ≡ "rustc" ∨ n ≡ "cargo" ∨ lib.hasSuffix"-cargo" n
in
attrs.pname or null ≡ "postgresql"
→
"PostgreSQL"
lib.anyisRust names ∨ attrs.cargoDeps or null ≢ null
→
"Rust"
lib.elem"go" names
→
"Go"
else
null
used by blocked
in
stdenvAdapters.overrideMkDerivationArgs
λold
let
39blocked=
uses compiler used by name why
in

Only the problem's presence depends on the inputs, not the shape of meta: deciding the shape from nativeBuildInputs recurses.

44meta=
old.meta or { }
//
45problems=
old.meta.problems or { }
//
lib.optionalAttrsblocked ≢ null
48filc=
49kind=
"broken"
50message=
let
52name=
blocked ≡ "PostgreSQL"
→
"postgresql_${lib.versions.majorold.version}"
else
old.pname or lib.getNameold.name or "it"
uses blocked
57why=
blocked ≡ "PostgreSQL"
→
"${blocked} cannot be Fil-C: its processes share memory that holds pointers, and a Fil-C pointer's capability does not cross processes."
else
"${blocked} has no Fil-C target."
uses blocked
in
"${why} Take the native build instead, with filc.native = native: { inherit (native) ${name}; }; in your system's configuration, or leave it out."