Fil-C on Nix

Filnix wiki

mbrock/filnix

ports/pythonPorts-as-overlay.nix

Convert pythonPorts.nix list to packageOverrides function

λpkgs
let

Import pyports.nix - returns a list of port specs

6portList=
import../pyports.nix inherit pkgs;
used by portSpecs

Convert list to attrset keyed by pname (same logic as ports2-as-overlay)

9portSpecs=
builtins.listToAttrs
pkgs.lib.flatten
map
λitem
builtins.isStringitem
→

String means pname is embedded, extract it

16name=
17value=
{ }
item ? pname
→

Direct port spec with pname field

22name=
item.pname
23value=

Attrset with explicit names

else
pkgs.lib.mapAttrsToList
λname spec
28inherit
name
29value=
uses portList

Test suites run under the Fil-C interpreter (pytestCheckHook is not spliced), but nativeCheckInputs resolve to the build platform's Python set, whose extension modules Fil-C Python cannot load (fonttools failed importing a glibc build of zopfli). Take Python modules among the check inputs from the host set; other check tools and all build tools stay native. An overrideAttrs that adds check inputs later bypasses this.

Only for the packages listed here: made global, every check module's runtime closure became a tested Fil-C build (httpcore importing a native rpds, faust-cchardet's C++ against Fil-C's internal headers, ...).

45hostCheckPackages=
"fonttools"
46hostCheckModules=
λstdenv
//
50mkDerivation=
λfnOrAttrs
stdenv.mkDerivation
λfinalAttrs
let
55attrs=
if builtins.isFunctionfnOrAttrs then fnOrAttrsfinalAttrs else fnOrAttrs
57noCheck=
λx
x ? overridePythonAttrs
→
x.overridePythonAttrsdoCheck = false;
else
used by toHost

Rust has no Fil-C target, so a module that is (or requires) a Cargo build stays native, as all check modules were before.

65cargo=
p: p.cargoDeps or null ≢ null
used by fitsFilc
66fitsFilc=
h: ¬pkgs.lib.anycargo h ++ h.requiredPythonModules or [ ]
uses cargo used by toHost
67toHost=
λx
let
70h=
x.__spliced.hostTarget or x
in
x ? pythonModule ∧ ¬builtins.isBoolx.pythonModule ∧ fitsFilch
→

Only the module is needed, not its own test suite, whose inputs would otherwise become Fil-C builds too.

else
in
attrs // pkgs.lib.optionalAttrsattrs ? nativeInstallCheckInputs ∧ builtins.elemattrs.pname or "" hostCheckPackages nativeInstallCheckInputs = maptoHost attrs.nativeInstallCheckInputs;
in
λpyself pyprev
let

Python also forwards packageOverrides to its build-platform interpreter. Splice test inputs only for Fil-C; individual ports can opt out on native.

96inherit pyprev.python.stdenv
hostPlatform buildPlatform
in
pkgs.lib.optionalAttrshostPlatform.config ≢ buildPlatform.config
99buildPythonPackage=
pyprev.buildPythonPackage.overridestdenv = hostCheckModulespyprev.python.stdenv;
102buildPythonApplication=
pyprev.buildPythonApplication.overridestdenv = hostCheckModulespyprev.python.stdenv;
//
pkgs.lib.mapAttrs
λname spec
spec ≡ { }
→
pyprev.${name} or null
spec.filcOnly or false ∧ ¬pyprev.python.stdenv.hostPlatform.isFilc
→

These overrides also reach the build platform's Python.

spec ? __customPython
→
spec.__customPythonpyself

Custom Python package (not in pyprev)

spec ? attrs ∧ builtins.isFunctionspec.attrs
→
let

Normal port - apply overrides

121base=
spec.overrideArgs ≢ { }
→
pyprev.${name}.overridespec.overrideArgs
else
in
base.overrideAttrsspec.attrs
else