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; } (.github/workflows/nanofil.yml).

245nanofil-check=
λargs

Unsupported ports and known release gaps stay strict and opt-in, outside the ordinary passing contract of flake check.

256diagnostics=
257pipewire=
import./tests/pipewire.nix inherit pkgs pkgsFilc filcc;.pipewire
259pipewire-runtime=
import./tests/pipewire.nix inherit pkgs pkgsFilc filcc;.runtime
261release-fork-known-gaps=
262inherit
pkgsFilc
263suite=
"release-known-gaps"
268checks.${system}=

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

270port-names=
import./tests/port-names.nix inherit pkgs pkgsFilc;
271port-version-refresh=
import./tests/port-version-refresh.nix inherit pkgs pkgsFilc;
274staging-fork-regressions=
277staging-llvm-jit=
280staging-sealed-closures=
283staging-cxx-coroutines=
286staging-fenv=
289staging-gc-local-arrays=
292staging-link-hygiene=
295staging-wrapper-roles=
298staging-zmark-shared=
302staging-sarcasm=
306staging-sarcasm-fixes=
310unsafe-call-boundary=
import./tests/unsafe-call-boundary.nix inherit pkgs filcc;
313nanofil=
317nanofil-rocq=
321nanofil-rocq-full=
322inherit
pkgs
324full=
true
326nanofil-logic-spikes=
327inherit
pkgs
329model=
import./nanofil/nix/rocq.nix inherit pkgs; filcc = filcc-staging;.model
335nanofil-backend=
339nanofil-backend-full=
340inherit
pkgs
342full=
true
344nanofil-hello=

Hello's linked checked module, the Iris proof's fixture.

349nanofil-hello-fixture=
353nanofil-zlib=
357nanofil-lua=
361nanofil-bzip2=
365nanofil-lz4=
369nanofil-sqlite=
373nanofil-sed=
377nanofil-jq=
381nanofil-dash=
385nanofil-xz=
389nanofil-make=
393nanofil-coreutils=
397nanofil-bash=
401nanofil-swipl=
406inherit import./nanofil/nix/python.nix inherit pkgs; filcc = filcc-staging;
nanofil-python nanofil-python-regrtest-plain
414sarcasm-prolog=
415inherit
pkgs filcc sarcasm-prolog
416trealla=
pkgsFilc.trealla
418trealla=
419inherit
pkgs filcc
420trealla=
pkgsFilc.trealla
422zstd-sarcasm=
423inherit
pkgs filcc
426baseline=
baseline.baseline
427openssl-sarcasm=
428inherit
pkgs filcc
429openssl=
pkgsFilc.openssl-sarcasm
431sarcasm=
import./tests/sarcasm.nix inherit pkgs filcc;
432sarcasm-fixes=
import./tests/sarcasm-fixes.nix inherit pkgs filcc;
435libtool-symbols=
import./tests/libtool-symbols.nix inherit pkgs filcc;
438inherit
projeny
439libffi=
440inherit
pkgs filcc
441inherit pkgsFilc
libffi
443gtk2-runtime=
import./tests/gtk2-runtime.nix inherit pkgs pkgsFilc;
446gtk3-runtime=
447inherit
pkgs pkgsFilc
448major=
3
450gnutls-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).

456php-stealmybitcoin=
457inherit
pkgs
458native=
pkgs.php84.overrideAttrsold: dontStrip = true; separateDebugInfo = false;.withExtensions
λenabled, …
map
λext
ext.extensionName ≡ "pcntl"
→
ext.overrideAttrs
λold

Nix sandboxes may exclude CPU 0. Exercise affinity on allowed CPUs rather than assuming CPUs 0 and 1 exist.

471postPatch=
old.postPatch or ""
+
substituteInPlace ext/pcntl/tests/pcntl_cpuaffinity.phpt \
--replace-fail '$mask = [0, 1];' \
'$mask = array_slice(pcntl_getcpuaffinity(), 0, 2);' \
--replace-fail '["0", "1"]' 'array_map("strval", $mask)'
else
482filc=
484utf8-locale=
import./tests/locale.nix inherit pkgsFilc;
485pthread-pi=
import./tests/pthread-pi.nix inherit pkgsFilc;
486pthread-spin=
import./tests/pthread-spin.nix inherit pkgsFilc;
487fenv=
import./tests/fenv.nix inherit pkgsFilc;
488glibc-dirwalk=
import./tests/glibc-dirwalk.nix inherit pkgsFilc;
489glibc-settimezone=
import./tests/glibc-settimezone.nix inherit pkgsFilc;
492glibc-syscall-fallbacks=
import./tests/glibc-syscall-fallbacks.nix inherit pkgsFilc;
495runtime-prctl-caps=
import./tests/runtime-prctl-caps.nix inherit pkgsFilc;

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

499nixos-image-boot=
500native-exceptions-table=

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

504finix-filc-demo=
505inherit
pkgs finix
506filnix=
508wrapper-roles=
import./tests/wrapper-roles.nix inherit pkgsFilc;
509gc-local-arrays=
import./tests/gc-local-arrays.nix inherit pkgsFilc;
510pch-union=
import./tests/pch-union.nix inherit pkgsFilc;
511nix-eval=
import./tests/nix-eval.nix inherit pkgsFilc;
512perl-xs-pointers=
import./tests/perl-xs-pointers.nix inherit pkgsFilc;
513python-decimal=
import./tests/python-decimal.nix inherit pkgsFilc;
514python-protobuf=
import./tests/python-protobuf.nix inherit pkgs pkgsFilc;
517cxx-coroutines=
import./tests/cxx-coroutines.nix inherit pkgsFilc;
518pointer-tagging=
import./tests/pointer-tagging.nix inherit pkgsFilc;
519link-hygiene=
import./tests/link-hygiene.nix inherit pkgsFilc;
520fork-regressions=
521inherit
pkgsFilc
522suite=
"release"
524icu=
import./tests/icu.nix inherit pkgs pkgsFilc;
527boost-context=
import./tests/boost-context.nix inherit pkgsFilc;
528qnode=
import./tests/qnode.nix inherit pkgs pkgsFilc;
529protobuf=
import./tests/protobuf.nix inherit pkgs pkgsFilc;
530protobuf_33=
531inherit
pkgs pkgsFilc
532protobuf=
pkgsFilc.protobuf_33
534protobuf_21=
535inherit
pkgs pkgsFilc
536protobuf=
pkgsFilc.protobuf_21
538re2=
import./tests/re2.nix inherit pkgs pkgsFilc;
539emacs-treesit=
import./tests/emacs-treesit.nix inherit pkgs pkgsFilc;
542libsoup3-runtime=
import./tests/libsoup.nix inherit pkgs pkgsFilc;
545gi-link-environment=
import./tests/gi-link-environment.nix inherit pkgs pkgsFilc;
548generator-precedence=
import./tests/generator-precedence.nix inherit pkgs pkgsFilc;
551media-foundations=
import./tests/media-foundations.nix inherit pkgs pkgsFilc;
554graphite2-runtime=
import./tests/graphite2.nix inherit pkgs pkgsFilc;
557glib-atomic=
import./tests/glib-atomic.nix inherit pkgs pkgsFilc;
558glib-gtype=
import./tests/glib-gtype.nix inherit pkgs pkgsFilc;
559glib-enums=
import./tests/glib-enums.nix inherit pkgs pkgsFilc;
560dbus-glib=
import./tests/dbus-glib.nix inherit pkgs pkgsFilc;
561glibmm=
import./tests/glibmm.nix inherit pkgs pkgsFilc;.glibmm
562glibmm_2_68=
import./tests/glibmm.nix inherit pkgs pkgsFilc;.glibmm_2_68
564gtkmm3-runtime=
565inherit
pkgs pkgsFilc
566major=
3
568gtkmm4-runtime=
569inherit
pkgs pkgsFilc
570major=
4
572glib-networking=
import./tests/glib-networking.nix inherit pkgs pkgsFilc;
575pygobject=
import./tests/pygobject.nix inherit pkgs pkgsFilc;
578gtk4-runtime=
579inherit
pkgs pkgsFilc
580major=
4
584overlays.default=

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

588nixosModules.default=
import./nixos filnix = self;
589finixModules.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.

593lib.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.

610nixosModules.base=
import./nixos/base.nix filnix = self;
611nixosConfigurations.base=
self.lib.nixosSystemmodules = self.nixosModules.base;

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

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

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

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

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

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

Export the full cross-compiled package sets

635legacyPackages.${system}=
636inherit
pkgsFilc pkgsFilcStaging pkgsFilcSystem

A package set, not a derivation; .#rubyWithGem.<gem> still works.

638inherit
rubyWithGem

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

640nixosTests=
641inherit
pkgs pkgsFilc
642filcModule=
self.nixosModules.default
643filnix=
647packages.${system}=
nixlib.optionalAttrssystem ≡ "x86_64-linux"

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

651nixos-image=
652nixos-vm=

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

654nixos-ami=
self.nixosConfigurations.amazon.config.system.build.ami
//
657default=
658baseline=
baseline.baseline

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

660filc-audit=
pkgs.writeShellApplication
661name=
"filc-audit"
662runtimeInputs=
pkgs.binutils-unwrapped pkgs.findutils
666text=
builtins.readFile./lib/filc-audit.sh
668baseline-shell=
baseline.shell
669inherit
filcc filcc-staging projeny sarcasm sarcasm-prolog zstd-sarcasm
677inherit sarcasm
minilute
678inherit pkgsFilc
openssl-sarcasm
679php-dist=
import./packages/php-dist inherit pkgs pkgsFilc;

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

681php84_25=
682php84_25-dist=
683inherit
pkgs
685base=
687php84_25-docker=
688inherit
pkgs
689dist=
self.packages.${system}.php84_25-dist

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

692php-jit=
pkgsFilc.php84-jit

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

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

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

696php85-jit=
pkgsFilcStaging.php85-jit
697php74-dist=
698inherit
pkgs pkgsFilc
699php=
pkgsFilc.php74.withExtensionsenabled, all: enabled ++ with all; bz2 shmop sysvmsg sysvshm
710inherit
optfil
711filroot=
import./packages/filroot inherit pkgs optfil;

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

713site=
714inherit
pkgs nixpkgs
716filnix=

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

720site-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.

723site-play=
self.packages.${system}.site.play
724php-docker=
725inherit
pkgs
726dist=
import./packages/php-dist inherit pkgs pkgsFilc;
728bind-dist=
import./packages/bind-dist inherit pkgs pkgsFilc;
729bind-docker=
730inherit
pkgs
731dist=
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).

735postgresql-staging-zmark=
pkgsFilcStaging.postgresql_18

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

738php85-staging-dist=
739inherit
pkgs
742suffix=
"-staging"
744php85-staging-docker=
745inherit
pkgs
746dist=
747inherit
pkgs
750suffix=
"-staging"
753bind-staging-dist=
754inherit
pkgs
756suffix=
"-staging"
758bind-staging-docker=
759inherit
pkgs
760dist=
761inherit
pkgs
763suffix=
"-staging"
766inherit
libei libei_27 libei_28
772inherit
filc-world-shell
773inherit virt
filc-nspawn filc-qemu filc-docker
774inherit 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
786push-baseline=
pkgs.writeShellApplication
787name=
"filc-push-baseline"
788runtimeInputs=
pkgs.nix pkgs.cachix pkgs.coreutils pkgs.writeScriptBin"filc-verify-cache" "#!${pkgs.python3}/bin/python3\n" + builtins.readFile./scripts/verify-cache.py
797text=
802push-filcc=
pkgs.writeShellScriptBin"push-filcc"
${pkgs.cachix}/bin/cachix push filc ${filcc}
806push-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
812inherit
runfilc
filc-emacs
815emacs30=
pkgsFilc.emacs30
816emacs=
emacs-safe.filc-emacs
817emacs-unsafe=
emacs-unsafe.filc-emacs
820apps.${system}=
virt.apps
//
821zstd-sarcasm=
822type=
"app"
823program=
"${zstd-sarcasm.bin}/bin/zstd"
825baseline=
826type=
"app"
827program=
"${baseline.shell}/bin/filc-baseline-shell"
829openssl-sarcasm=
830type=
"app"
831program=
"${pkgsFilc.openssl-sarcasm.bin}/bin/openssl"
833filcc=
834type=
"app"
835program=
"${filcc}/bin/clang"
837filcc-staging=
838type=
"app"
839program=
"${filcc-staging}/bin/clang"
842"filc++"=
843type=
"app"
844program=
"${filcc}/bin/clang++"
846"filc++-staging"=
847type=
"app"
848program=
"${filcc-staging}/bin/clang++"
852formatter.${system}=
pkgs.nixfmt
854devShells.${system}=

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

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

861filc-llvm=
import./shells/filc-llvm.nix inherit pkgs;
862filc-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.

872hostTools=
λsystem
let
875pkgs=
importnixpkgs inherit system;
used by projeny
876projeny=
uses pkgs
in
879packages.${system}=
880inherit
projeny
883formatter.${system}=
pkgs.nixfmt
884devShells.${system}.default=

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

889devtoolsFor=
λpkgs
pkgs.buildEnv
892name=
"filnix-devtools"
893paths=
with pkgs; treefmt nixfmt actionlint shellcheck python3 git
903devShellFor=
λpkgs projeny
pkgs.mkShell
906name=
"filnix-dev"
907packages=
with pkgs

Nix development tools

nixfmt
treefmt
nixd
nil
python3

General development tools

git
direnv
nix-direnv
923shellHook=
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"