tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

build.nix (5488B)


      1 { pkgs, source, haskellPackages ? pkgs.haskellPackages, archiveHaskell ? false, trimArchive ? archiveHaskell }:
      2 assert !trimArchive || archiveHaskell;
      3 let
      4   libraryName = "tricu-haskell";
      5   entryModule = "Embedding";
      6   dependencies = p: [
      7     p.aeson p.base16-bytestring p.cryptonite p.memory p.vector
      8     p.network p.stm p.temporary p.mtl
      9   ];
     10   ghc = haskellPackages.ghcWithPackages dependencies;
     11 in pkgs.stdenv.mkDerivation {
     12   pname = "${libraryName}${pkgs.lib.optionalString archiveHaskell "-archive"}-embedding";
     13   version = "2026.10.24";
     14   src = source;
     15   outputs = [ "out" "linkEvidence" ];
     16   passthru = {
     17     compiler = haskellPackages.ghc;
     18     haskellLibraries = pkgs.lib.filter (p: p ? isHaskellLibrary && p ? src)
     19       (pkgs.lib.closePropagation (dependencies haskellPackages));
     20   };
     21   nativeBuildInputs = [ ghc pkgs.python3 ]
     22     ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs.patchelf ];
     23   buildPhase = ''
     24     runHook preBuild
     25     mkdir -p objects
     26     # GHC 9.14's executable linker roots the RTS-to-Haskell startup interface;
     27     # shared archive linkage needs the same root to resolve the archive cycle.
     28     ghc -O2 ${if archiveHaskell then "-static" else "-dynamic"} -shared -fPIC -flink-rts -threaded \
     29       ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isLinux "-optl-Wl,-Map,embedding-link.map"} \
     30       ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isLinux "-optl-Wl,-z,nodelete"} \
     31       ${pkgs.lib.optionalString archiveHaskell "-optl-Wl,-z,text -optl-Wl,-z,defs"} \
     32       ${pkgs.lib.optionalString trimArchive "-optl-Wl,--version-script=ext/haskell/src/core.exports -optl-Wl,--gc-sections"} \
     33       ${pkgs.lib.optionalString (archiveHaskell && pkgs.lib.versionAtLeast haskellPackages.ghc.version "9.14") "-optl-Wl,-u,init_ghc_hs_iface"} \
     34       -XOverloadedStrings -XScopedTypeVariables -XMultiWayIf -XLambdaCase \
     35       -Wall -isrc -iext/haskell/src -outputdir objects \
     36       -optc-Iext/haskell/include \
     37       ext/haskell/src/${entryModule}.hs ext/haskell/src/init.c \
     38       -o lib${libraryName}${pkgs.stdenv.hostPlatform.extensions.sharedLibrary}
     39     runHook postBuild
     40   '';
     41   meta = pkgs.lib.optionalAttrs archiveHaskell { platforms = [ "x86_64-linux" ]; };
     42   doCheck = true;
     43   checkPhase = ''
     44     runHook preCheck
     45     ghc -O2 ${if archiveHaskell then "-static" else "-dynamic"} -fPIC -threaded \
     46       -XOverloadedStrings -XScopedTypeVariables -XMultiWayIf -XLambdaCase \
     47       -isrc -iext/haskell/src -outputdir boundary-objects \
     48       ext/haskell/BoundaryTests.hs -o boundary-tests
     49     timeout 30s ./boundary-tests
     50     $CC -Wall -Wextra -Werror ext/haskell/tests.c -Iext/haskell/include \
     51       -L. -l${libraryName} -Wl,-rpath,$PWD -o c-embedding-tests
     52     GHCRTS=--tricu-test-invalid timeout 30s ./c-embedding-tests
     53     ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isLinux ''
     54       $CC -Wall -Wextra -Werror ext/haskell/reload.c -Iext/haskell/include -ldl -o reload-tests
     55       timeout 30s ./reload-tests "$PWD/lib${libraryName}.so"
     56     ''}
     57     python3 ext/haskell/test_exports.py ./lib${libraryName}${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} ${pkgs.lib.optionalString trimArchive "public-only"}
     58     PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=ext/haskell/python timeout 60s python3 ext/haskell/test_embedding.py \
     59       ./lib${libraryName}${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} test/fixtures > embedding-report.json
     60     cat embedding-report.json
     61     PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=ext/haskell/python timeout 30s python3 \
     62       ext/haskell/test_scopes.py ./lib${libraryName}${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} test/fixtures
     63     runHook postCheck
     64   '';
     65   installPhase = ''
     66     runHook preInstall
     67     mkdir -p $out/lib $out/include $out/share/tricu $linkEvidence
     68     ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isLinux "cp embedding-link.map $linkEvidence/"}
     69     ghc-pkg dump > $linkEvidence/ghc-packages.txt
     70     cp lib${libraryName}* $out/lib/
     71     printf '{"ghc_version":"%s","haskell_linkage":"${if archiveHaskell then "archive" else "dynamic"}","public_symbols_only":${if trimArchive then "true" else "false"}}\n' \
     72       "$(ghc --numeric-version)" > $out/share/tricu/build.json
     73     cp ext/haskell/include/tricu.h $out/include/
     74     cp ext/haskell/python/tricu.py $out/share/tricu/
     75     cp embedding-report.json $out/share/tricu/
     76     ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isLinux ''
     77       python3 ext/haskell/package_runtime.py $out/lib/lib${libraryName}.so
     78     ''}
     79     runHook postInstall
     80   '';
     81   # Verify the installed runtime paths in a fresh foreign process, too.
     82   doInstallCheck = true;
     83   installCheckPhase = ''
     84     ${pkgs.lib.optionalString archiveHaskell ''
     85       if ldd $out/lib/lib${libraryName}.so | grep -q libHS; then
     86         echo "archive-linked library retained Haskell shared dependencies" >&2
     87         exit 1
     88       fi
     89     ''}
     90     $CC -Wall -Wextra -Werror ext/haskell/tests.c -I$out/include \
     91       -L$out/lib -l${libraryName} -Wl,-rpath,$out/lib -o installed-embedding-tests
     92     GHCRTS=--tricu-test-invalid timeout 30s ./installed-embedding-tests
     93     python3 ext/haskell/test_exports.py $out/lib/lib${libraryName}${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} ${pkgs.lib.optionalString trimArchive "public-only"}
     94     PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=$out/share/tricu timeout 60s python3 \
     95       ext/haskell/test_embedding.py \
     96       $out/lib/lib${libraryName}${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} test/fixtures
     97   '';
     98 }