Fil-C on Nix

Filnix wiki

mbrock/filnix

flake.nix

2description=

Fil-C wrapped as a Nix stdenv

4inputs=

Modified nixpkgs with Fil-C cross-compilation support filc-aarch64: 118d872 plus aarch64 in the gnufilc0 ABI assertion.

7nixpkgs.url=
"github:lessrest/filnixpkgs/e63c68034d742160a48ca80640442337e6356cf4"
8nixpkgs.flake=
false

For the example finix machine and its test (finix/demo.nix). The last revision before finix required finit 5; filnix's Nixpkgs has finit 4.17.

11finix.url=
"github:finix-community/finix/9fafdc3f091e963585a0dd4df028d58c2d66d815"
12finix.flake=
false
15outputs=
λself, nixpkgs, finix, …
let

The system-independent outputs (overlays, NixOS modules and machines) come from x86_64-linux; everything keyed by system comes from both.

26perSystem=
λsystem
let
31filcc=
import./toolchain.nix inherit pkgs;
used by cc
32stagingSources=
33inherit
pkgs
34variant=
"staging"
used by filcc-staging
36filcc-staging=
37inherit
pkgs
uses stagingSources used by cc
40sarcasm=
import./packages/sarcasm.nix inherit pkgs;
41sarcasm-prolog=
42inherit
pkgs filcc
43trealla=
pkgsFilc.trealla
uses pkgsFilc
45zstd-sarcasm=
46inherit
pkgs
47zstd=
uses pkgsFilc
49projeny=
uses pkgs
50runfilc=
import./tools/runfilc.nix inherit pkgs filcc;

The Fil-C package set. blockRustGo marks Rust and Go packages broken (lib/block-rust-go.nix); crossOverlays apply after the ports.

54mkPkgsFilc=
λstaging?, blockRustGo?, crossOverlays?, permittedInsecurePackages?
stagingdefault false
blockRustGodefault false
crossOverlaysdefault [ ]
permittedInsecurePackagesdefault [ ]
let
in
importnixpkgs
65localSystem=
66crossSystem.config=
"${pkgs.stdenv.hostPlatform.parsed.cpu.name}-unknown-linux-gnufilc0"
67config.permittedInsecurePackages=
68config.replaceCrossStdenv=
λbuildPackages, baseStdenv
let
71stdenv=
baseStdenv.overrideinherit cc;
in
→
import./lib/block-rust-go.nix inherit buildPackages lib stdenvAdapters; stdenv
else
81crossOverlays=
final: prev: gnufilc0 = cc; import./ports/overlay.nix pkgs ++ final: prev: tzdata = prev.tzdata.overrideAttrscheckTarget = "check_mild back.ck";; ++ crossOverlays

tzdata's now.ck compares zones from the build date on, so 2026c fails it from 2026-11-01 (Vancouver and Phoenix agree from then). It lints the data, not zic or zdump; run the rest.

The package set of a whole Fil-C system (lib/filc-system.nix): Rust and Go refused, and the native exceptions taken from a native Nixpkgs, the built-in ones for os and those native picks from it.

108mkPkgsFilcSystem=
λos, native?, nativePackages?, nativeNix?
os
nativedefault _: { }
nativePackagesdefault pkgs
nativeNixdefault true
let
116builtin=
nixlib.filterAttrsname: e: nixlib.elemos e.os ∧ name ≢ "nix" ∨ nativeNix import./lib/native-exceptions.nix
uses nixlib
in
121blockRustGo=
true
122crossOverlays=
final: prev: nixlib.mapAttrsname: _: nativePackages.${name} builtin // nativenativePackages

Shared by every system that adds no exceptions of its own.

131pkgsFilcSystem=
nixlib.genAttrs"nixos" "finix" os: mkPkgsFilcSysteminherit os;

Explicit reproduction outputs only; the ordinary package set still refuses this vulnerable PHP unless the caller opts in.

137pkgsFilcPhp84_25=
mkPkgsFilcpermittedInsecurePackages = "php-8.4.25" "php-with-extensions-8.4.25";
143optfil=
import./packages/optfil inherit pkgs pkgsFilc filcc sarcasm;

On staging, the PostgreSQL server marks its main segment with zmark_shared and is built with -fzmark-shared (docs/zmark-shared.md). Release systems still refuse it (lib/block-rust-go.nix).

154pkgsFilcStaging=
155staging=
true
156crossOverlays=
λfinal prev
158postgresql_18=
prev.postgresql_18.overrideAttrs
λold
160env=
old.env // CFLAGS = old.env.CFLAGS + " -fzmark-shared";
168filc-shell-stuff=
169inherit
pkgs filcc runfilc
177filc-world-shell=
filc-shell-stuff.filc-world-shell
178baseline=
179inherit
pkgs filcc sarcasm projeny
uses pkgsFilc
188virt=
189inherit
pkgs filcc
world-pkgs
194emacs-safe=
import./emacs/emacs.nix inherit pkgs pkgsFilc;
used by demo
198emacs-unsafe=
199inherit
pkgs
200pkgsFilc=
uses pkgs
203makeLibei=
erlang: pkgsFilc.callPackage./packages/libei.nix inherit erlang;
205libei=
206libei_27=
makeLibeipkgs.erlang_27
207libei_28=
makeLibeipkgs.erlang_28
209demo=
210inherit
pkgs pkgsFilc filcc libei
216filc-emacs=
emacs-safe.filc-emacs
219nixosImage=
220inherit
pkgs
221inherit self.nixosConfigurations.base
config

Ruby with individual gems for testing - auto-generated for all available gems

225rubyWithGem=
pkgs.lib.mapAttrsname: _: pkgsFilc.ruby.withPackagesps: ps.${name} pkgsFilc.rubyPackages
in
230lib.${system}=
232inherit
mkPkgsFilc mkPkgsFilcSystem

The native Nixpkgs that a Fil-C system's exceptions come from.

234nativePackages=

Fil-C docs, pass and runtime at the pin, for reading (lib/sources.nix): nix build .#lib.x86_64-linux.filc-ref-src

237filc-ref-src=
import./lib/sources.nix inherit pkgs;.filc-ref-src
238filc-staging-ref-src=
import./lib/sources.nix inherit pkgs; variant = "staging";.filc-ref-src

checks.nanofil with arguments, such as { shard = "2/6"; } or { withTrealla = true; } (scripts/nanofil-fleet).

245nanofil-check=
λargs
256checks.${system}=

Bare ports that land on another attribute than the one written.

258port-names=
import./tests/port-names.nix inherit pkgs pkgsFilc;
259port-version-refresh=
import./tests/port-version-refresh.nix inherit pkgs pkgsFilc;
262pipewire=
import./tests/pipewire.nix inherit pkgs pkgsFilc filcc;.pipewire
264pipewire-runtime=
import./tests/pipewire.nix inherit pkgs pkgsFilc filcc;.runtime
266staging-fork-regressions=
269staging-llvm-jit=
272staging-sealed-closures=
275staging-cxx-coroutines=
278staging-fenv=
281staging-gc-local-arrays=
284staging-link-hygiene=
287staging-wrapper-roles=
290staging-zmark-shared=
294staging-sarcasm=
298staging-sarcasm-fixes=
302unsafe-call-boundary=
import./tests/unsafe-call-boundary.nix inherit pkgs filcc;
305nanofil=
309nanofil-rocq=
313nanofil-rocq-full=
314inherit
pkgs
316full=
true
318nanofil-hello=
322nanofil-zlib=
326nanofil-lua=
330nanofil-bzip2=
334nanofil-lz4=
338nanofil-sqlite=
342nanofil-sed=
346nanofil-jq=
350nanofil-dash=
354nanofil-xz=
358nanofil-make=
362nanofil-coreutils=
366nanofil-bash=
370nanofil-swipl=
375inherit import./nanofil/nix/python.nix inherit pkgs; filcc = filcc-staging;
nanofil-python nanofil-python-regrtest-plain
383sarcasm-prolog=
384inherit
pkgs filcc sarcasm-prolog
385trealla=
pkgsFilc.trealla
387trealla=
388inherit
pkgs filcc
389trealla=
pkgsFilc.trealla
391zstd-sarcasm=
392inherit
pkgs filcc
395baseline=
baseline.baseline
396openssl-sarcasm=
397inherit
pkgs filcc
398openssl=
pkgsFilc.openssl-sarcasm
400sarcasm=
import./tests/sarcasm.nix inherit pkgs filcc;
401sarcasm-fixes=
import./tests/sarcasm-fixes.nix inherit pkgs filcc;
404libtool-symbols=
import./tests/libtool-symbols.nix inherit pkgs filcc;
407inherit
projeny
408libffi=
409inherit
pkgs filcc
410inherit pkgsFilc
libffi
412gtk2-runtime=
import./tests/gtk2-runtime.nix inherit pkgs pkgsFilc;
415gtk3-runtime=
416inherit
pkgs pkgsFilc
417major=
3
419gnutls-tls=
import./tests/gnutls-tls.nix inherit pkgs pkgsFilc;

The StealMyBitcoin exploit works end to end on the unstripped Nixpkgs PHP 8.4.25 and is thwarted by pkgsFilc.php84_25, the same vulnerable release under Fil-C (docs/php.md).

425php-stealmybitcoin=
426inherit
pkgs
427native=
pkgs.php84.overrideAttrs
λold
428dontStrip=
true
429separateDebugInfo=
false
431filc=
433utf8-locale=
import./tests/locale.nix inherit pkgsFilc;
434pthread-pi=
import./tests/pthread-pi.nix inherit pkgsFilc;
435pthread-spin=
import./tests/pthread-spin.nix inherit pkgsFilc;
436fenv=
import./tests/fenv.nix inherit pkgsFilc;
437glibc-dirwalk=
import./tests/glibc-dirwalk.nix inherit pkgsFilc;
438glibc-settimezone=
import./tests/glibc-settimezone.nix inherit pkgsFilc;
441glibc-syscall-fallbacks=
import./tests/glibc-syscall-fallbacks.nix inherit pkgsFilc;
444runtime-prctl-caps=
import./tests/runtime-prctl-caps.nix inherit pkgsFilc;

Boots the exact nixos-image file and checks its userland.

448nixos-image-boot=
449native-exceptions-table=

Boots finixConfigurations.filc-demo; see finix/test.nix.

453finix-filc-demo=
454inherit
pkgs finix
455filnix=
457wrapper-roles=
import./tests/wrapper-roles.nix inherit pkgsFilc;
458gc-local-arrays=
import./tests/gc-local-arrays.nix inherit pkgsFilc;
459pch-union=
import./tests/pch-union.nix inherit pkgsFilc;
460nix-eval=
import./tests/nix-eval.nix inherit pkgsFilc;
461perl-xs-pointers=
import./tests/perl-xs-pointers.nix inherit pkgsFilc;
462python-decimal=
import./tests/python-decimal.nix inherit pkgsFilc;
463python-protobuf=
import./tests/python-protobuf.nix inherit pkgs pkgsFilc;
466cxx-coroutines=
import./tests/cxx-coroutines.nix inherit pkgsFilc;
467pointer-tagging=
import./tests/pointer-tagging.nix inherit pkgsFilc;
468link-hygiene=
import./tests/link-hygiene.nix inherit pkgsFilc;
469fork-regressions=
import./tests/fork-regressions.nix inherit pkgsFilc;
470icu=
import./tests/icu.nix inherit pkgs pkgsFilc;
473boost-context=
import./tests/boost-context.nix inherit pkgsFilc;
474qnode=
import./tests/qnode.nix inherit pkgs pkgsFilc;
475protobuf=
import./tests/protobuf.nix inherit pkgs pkgsFilc;
476protobuf_33=
477inherit
pkgs pkgsFilc
478protobuf=
pkgsFilc.protobuf_33
480protobuf_21=
481inherit
pkgs pkgsFilc
482protobuf=
pkgsFilc.protobuf_21
484re2=
import./tests/re2.nix inherit pkgs pkgsFilc;
485emacs-treesit=
import./tests/emacs-treesit.nix inherit pkgs pkgsFilc;
488libsoup3-runtime=
import./tests/libsoup.nix inherit pkgs pkgsFilc;
491gi-link-environment=
import./tests/gi-link-environment.nix inherit pkgs pkgsFilc;
494generator-precedence=
import./tests/generator-precedence.nix inherit pkgs pkgsFilc;
497media-foundations=
import./tests/media-foundations.nix inherit pkgs pkgsFilc;
500graphite2-runtime=
import./tests/graphite2.nix inherit pkgs pkgsFilc;
503glib-atomic=
import./tests/glib-atomic.nix inherit pkgs pkgsFilc;
504glib-gtype=
import./tests/glib-gtype.nix inherit pkgs pkgsFilc;
505glib-enums=
import./tests/glib-enums.nix inherit pkgs pkgsFilc;
506dbus-glib=
import./tests/dbus-glib.nix inherit pkgs pkgsFilc;
507glibmm=
import./tests/glibmm.nix inherit pkgs pkgsFilc;.glibmm
508glibmm_2_68=
import./tests/glibmm.nix inherit pkgs pkgsFilc;.glibmm_2_68
510gtkmm3-runtime=
511inherit
pkgs pkgsFilc
512major=
3
514gtkmm4-runtime=
515inherit
pkgs pkgsFilc
516major=
4
518glib-networking=
import./tests/glib-networking.nix inherit pkgs pkgsFilc;
521pygobject=
import./tests/pygobject.nix inherit pkgs pkgsFilc;
524gtk4-runtime=
525inherit
pkgs pkgsFilc
526major=
4
530overlays.default=

A NixOS or finix system whose pkgs is the Fil-C package set; see lib/filc-system.nix and docs/nixos.md.

534nixosModules.default=
import./nixos filnix = self;
535finixModules.default=
import./finix filnix = self;

A Fil-C NixOS, with the NixOS modules of filnix's own Nixpkgs: the Fil-C ports (systemd's above all) are built and tested against those, not against another release's.

539lib.nixosSystem=
args: import"${nixpkgs}/nixos/lib/eval-config.nix" system = null; // args // modules = self.nixosModules.default filc.enable = nixlib.mkDefaulttrue; ++ args.modules or [ ];

The base machine of the images; see nixos/base.nix.

556nixosModules.base=
import./nixos/base.nix filnix = self;
557nixosConfigurations.base=
self.lib.nixosSystemmodules = self.nixosModules.base;

The same machine on EC2, for the public AMI; see nixos/amazon.nix.

561nixosConfigurations.amazon=
self.lib.nixosSystemmodules = import./nixos/amazon.nix filnix = self;;

https://filc.less.rest, on that AMI; see nixos/demo-wiki.nix.

565nixosConfigurations.demo-wiki=
self.lib.nixosSystemmodules = import./nixos/demo-wiki.nix filnix = self;;

The finix machine with a Fil-C userland; see finix/demo.nix.

570finixConfigurations.filc-demo=
importfinix.lib.finixSystem
572modules=
self.finixModules.default "${finix}/modules/virtualisation/qemu.nix" ./finix/demo.nix filc.system = system;

Export the full cross-compiled package sets

581legacyPackages.${system}=
582inherit
pkgsFilc pkgsFilcStaging pkgsFilcSystem

NixOS VM tests of Fil-C systems; see tests/nixos/default.nix.

584nixosTests=
585inherit
pkgs pkgsFilc
586filcModule=
self.nixosModules.default
587filnix=
591packages.${system}=
nixlib.optionalAttrssystem ≡ "x86_64-linux"

The base Fil-C NixOS as a compressed qcow2, and a VM that boots it (nixos/image.nix).

595nixos-image=
596nixos-vm=

Its EC2 variant as a VHD, which .github/workflows/ami.yml imports.

598nixos-ami=
self.nixosConfigurations.amazon.config.system.build.ami
//
601default=
602baseline=
baseline.baseline

Fil-C, runtime and native ELF files in a closure (docs/nixos.md).

604filc-audit=
pkgs.writeShellApplication
605name=
"filc-audit"
606runtimeInputs=
pkgs.binutils-unwrapped pkgs.findutils
610text=
builtins.readFile./lib/filc-audit.sh
612baseline-shell=
baseline.shell
613inherit
filcc filcc-staging projeny sarcasm sarcasm-prolog zstd-sarcasm
621inherit sarcasm
minilute
622inherit pkgsFilc
openssl-sarcasm
623php-dist=
import./packages/php-dist inherit pkgs pkgsFilc;

Vulnerable PHP for reproductions, never the default or :latest.

625php84_25=
626php84_25-dist=
627inherit
pkgs
629base=
631php84_25-docker=
632inherit
pkgs
633dist=
self.packages.${system}.php84_25-dist

Experimental: opcache's JIT, compiled through C (docs/php.md).

636php-jit=
pkgsFilc.php84-jit

Native against Fil-C PHP 8.5 on real applications (bench/php).

638php-bench=
import./bench/php inherit pkgs pkgsFilc pkgsFilcStaging;

PHP 8.5 with the same JIT, on the staging toolchain.

640php85-jit=
pkgsFilcStaging.php85-jit
641php74-dist=
642inherit
pkgs pkgsFilc
643php=
pkgsFilc.php74.withExtensionsenabled, all: enabled ++ with all; bz2 shmop sysvmsg sysvshm
654inherit
optfil
655filroot=
import./packages/filroot inherit pkgs optfil;

The GitHub Pages site: pages/ and the rendered docs/.

657site=
658inherit
pkgs nixpkgs
660filnix=

The site's SWI-Prolog 10, which nixpkgs does not have; ship publishes it so the Pages build substitutes it.

664site-swipl=
import./nanofil/web/play/swipl.nix inherit pkgs;

The site's nanofil playground, built with the staging toolchain; ship publishes it so Pages does not rebuild staging clang.

667site-play=
self.packages.${system}.site.play
668php-docker=
669inherit
pkgs
670dist=
import./packages/php-dist inherit pkgs pkgsFilc;
672bind-dist=
import./packages/bind-dist inherit pkgs pkgsFilc;
673bind-docker=
674inherit
pkgs
675dist=
import./packages/bind-dist inherit pkgs pkgsFilc;

The PostgreSQL server with -fzmark-shared (docs/zmark-shared.md), staging only; the campaign builds it (scripts/ci-outputs.txt).

679postgresql-staging-zmark=
pkgsFilcStaging.postgresql_18

Release alternates on the staging toolchain: unreleased compiler and runtime changes, faster but less reviewed (docs/php.md).

682php85-staging-dist=
683inherit
pkgs
686suffix=
"-staging"
688php85-staging-docker=
689inherit
pkgs
690dist=
691inherit
pkgs
694suffix=
"-staging"
697bind-staging-dist=
698inherit
pkgs
700suffix=
"-staging"
702bind-staging-docker=
703inherit
pkgs
704dist=
705inherit
pkgs
707suffix=
"-staging"
710inherit
libei libei_27 libei_28
716inherit
filc-world-shell
717inherit virt
filc-nspawn filc-qemu filc-docker
718inherit demo
lighttpd-demo ttyd-emacs-demo lua-with-stuff python-with-stuff python-web-demo perl-demos perl-with-stuff libei-ping-demo sinatra-demo
730push-baseline=
pkgs.writeShellApplication
731name=
"filc-push-baseline"
732runtimeInputs=
pkgs.nix pkgs.cachix pkgs.coreutils pkgs.writeScriptBin"filc-verify-cache" "#!${pkgs.python3}/bin/python3\n" + builtins.readFile./scripts/verify-cache.py
741text=
746push-filcc=
pkgs.writeShellScriptBin"push-filcc"
${pkgs.cachix}/bin/cachix push filc ${filcc}
750push-pkg=
pkgs.writeShellScriptBin"push-pkg"
for pkg in "$@"; do
${pkgs.cachix}/bin/cachix push filc $(${pkgs.nix}/bin/nix build .#"$pkg" --print-out-paths --no-link)
done
756inherit
runfilc
758inherit
rubyWithGem
filc-emacs
761emacs30=
pkgsFilc.emacs30
762emacs=
emacs-safe.filc-emacs
763emacs-unsafe=
emacs-unsafe.filc-emacs
766apps.${system}=
virt.apps
//
767zstd-sarcasm=
768type=
"app"
769program=
"${zstd-sarcasm.bin}/bin/zstd"
771baseline=
772type=
"app"
773program=
"${baseline.shell}/bin/filc-baseline-shell"
775openssl-sarcasm=
776type=
"app"
777program=
"${pkgsFilc.openssl-sarcasm.bin}/bin/openssl"
779filcc=
780type=
"app"
781program=
"${filcc}/bin/clang"
783filcc-staging=
784type=
"app"
785program=
"${filcc-staging}/bin/clang"
788"filc++"=
789type=
"app"
790program=
"${filcc}/bin/clang++"
792"filc++-staging"=
793type=
"app"
794program=
"${filcc-staging}/bin/clang++"
798formatter.${system}=
pkgs.nixfmt
800devShells.${system}=

Full Fil-C compilation environment (opt-in with 'nix develop .#world')

Incremental Fil-C LLVM hacking; see docs/llvm-dev.md

807filc-llvm=
import./shells/filc-llvm.nix inherit pkgs;
808filc-llvm-staging=

Fil-C is Linux-only, but Macs still run the git hooks and scripts/ship (which builds through a Linux builder or the publisher host), so they get the host tools those need and the default dev shell.

818hostTools=
λsystem
let
821pkgs=
importnixpkgs inherit system;
used by projeny
822projeny=
uses pkgs
in
825packages.${system}=
826inherit
projeny
829formatter.${system}=
pkgs.nixfmt
830devShells.${system}.default=

What scripts/git-hooks and scripts/ship run, so that they work without nix develop.

835devtoolsFor=
λpkgs
pkgs.buildEnv
838name=
"filnix-devtools"
839paths=
with pkgs; treefmt nixfmt actionlint shellcheck python3 git
849devShellFor=
λpkgs projeny
pkgs.mkShell
852name=
"filnix-dev"
853packages=
with pkgs

Nix development tools

nixfmt
treefmt
nixd
nil
python3

General development tools

git
direnv
nix-direnv
869shellHook=
git config core.hooksPath scripts/git-hooks
in
nixlib.foldl'nixlib.recursiveUpdate { } hostTools"aarch64-darwin" hostTools"x86_64-darwin" builtins.removeAttrsperSystem"aarch64-linux" "overlays" "nixosModules" "nixosConfigurations" "finixModules" "finixConfigurations" perSystem"x86_64-linux"