flake.nix (11088B)
1 { 2 description = "tricu"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs"; 6 flake-utils.url = "github:numtide/flake-utils"; 7 }; 8 9 outputs = { self, nixpkgs, flake-utils }: 10 flake-utils.lib.eachDefaultSystem (system: 11 let 12 pkgs = nixpkgs.legacyPackages.${system}; 13 packageName = "tricu"; 14 containerPackageName = "${packageName}-container"; 15 16 haskellPackages = pkgs.haskellPackages; 17 hsLib = pkgs.haskell.lib; 18 19 staticPkgs = pkgs.pkgsStatic; 20 staticHaskellPackages = staticPkgs.haskellPackages; 21 staticHsLib = staticPkgs.haskell.lib; 22 23 tricuMuslStatic = 24 staticHsLib.justStaticExecutables ( 25 staticHsLib.dontCheck ( 26 staticHaskellPackages.callCabal2nix packageName self {} 27 ) 28 ); 29 30 tricuStatic = pkgs.runCommand "${packageName}-static-upx" { 31 nativeBuildInputs = [ pkgs.upx ]; 32 } '' 33 mkdir -p $out/bin 34 cp ${tricuMuslStatic}/bin/tricu $out/bin/tricu 35 chmod +w $out/bin/tricu 36 37 # Good compression, slower build. 38 upx --best --lzma $out/bin/tricu 39 40 chmod 755 $out/bin/tricu 41 ''; 42 43 tricuPackageTests = 44 haskellPackages.callCabal2nix packageName self {}; 45 46 tricuPackage = 47 hsLib.dontCheck ( 48 haskellPackages.callCabal2nix packageName self {} 49 ); 50 51 tricuBench = 52 hsLib.overrideCabal 53 (hsLib.doBenchmark ( 54 haskellPackages.callCabal2nix packageName self {} 55 )) 56 (oldAttrs: { 57 postInstall = (oldAttrs.postInstall or "") + '' 58 mkdir -p $out/bin 59 cp dist/build/tricu-bench/tricu-bench $out/bin/ 60 ''; 61 }); 62 63 customGHC = haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [ 64 megaparsec 65 ]); 66 67 # ------------------------------------------------------------------ 68 # Zig Arboricx host 69 # ------------------------------------------------------------------ 70 tricuZig = pkgs.stdenv.mkDerivation { 71 pname = "tricu-zig"; 72 version = "0.1.0"; 73 src = ./ext/zig; 74 nativeBuildInputs = [ pkgs.zig pkgs.pkg-config ]; 75 buildInputs = [ pkgs.libuv ]; 76 buildPhase = '' 77 export ZIG_GLOBAL_CACHE_DIR=$TMPDIR/zig-cache 78 zig build 79 ''; 80 installPhase = '' 81 mkdir -p $out/bin $out/lib $out/include 82 cp zig-out/bin/* $out/bin/ 2>/dev/null || true 83 cp zig-out/lib/* $out/lib/ 2>/dev/null || true 84 cp include/arboricx.h $out/include/ 85 ''; 86 }; 87 88 tricuZigTests = pkgs.stdenv.mkDerivation { 89 pname = "tricu-zig-tests"; 90 version = "0.1.0"; 91 src = ./.; 92 nativeBuildInputs = [ pkgs.gcc pkgs.python3 tricuZig ]; 93 buildInputs = [ pkgs.libuv ]; 94 buildPhase = "true"; 95 doCheck = true; 96 checkPhase = '' 97 export LD_LIBRARY_PATH=${tricuZig}/lib:$LD_LIBRARY_PATH 98 ulimit -s 32768 99 100 cd ext/zig 101 102 # C ABI smoke test 103 gcc -o /tmp/c_abi_test tests/c_abi_test.c \ 104 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 105 -Wl,-rpath,${tricuZig}/lib 106 /tmp/c_abi_test 107 108 # IO protocol shape test 109 gcc -o /tmp/io_protocol_test tests/io_protocol_test.c \ 110 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 111 -Wl,-rpath,${tricuZig}/lib 112 /tmp/io_protocol_test 113 114 # IO run test (synchronous driver) 115 gcc -o /tmp/io_run_test tests/io_run_test.c \ 116 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 117 -Wl,-rpath,${tricuZig}/lib 118 /tmp/io_run_test 119 120 # Kernel path append test 121 gcc -o /tmp/c_abi_append_test tests/c_abi_append_test.c \ 122 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 123 -Wl,-rpath,${tricuZig}/lib 124 /tmp/c_abi_append_test 125 126 # Native bundle tests 127 gcc -o /tmp/native_bundle_append_test tests/native_bundle_append_test.c \ 128 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 129 -Wl,-rpath,${tricuZig}/lib 130 /tmp/native_bundle_append_test 131 132 gcc -o /tmp/native_bundle_id_test tests/native_bundle_id_test.c \ 133 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 134 -Wl,-rpath,${tricuZig}/lib 135 /tmp/native_bundle_id_test 136 137 gcc -o /tmp/native_bundle_bools_test tests/native_bundle_bools_test.c \ 138 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 139 -Wl,-rpath,${tricuZig}/lib 140 /tmp/native_bundle_bools_test 141 142 # Python FFI test 143 ARBORICX_LIB=${tricuZig}/lib/libarboricx.so \ 144 python3 tests/python_ffi_test.py 145 146 mkdir -p $out 147 echo "All Zig tests passed" > $out/result 148 ''; 149 }; 150 151 # ------------------------------------------------------------------ 152 # PHP FFI host 153 # ------------------------------------------------------------------ 154 tricuPhp = pkgs.stdenv.mkDerivation { 155 pname = "tricu-php"; 156 version = "0.1.0"; 157 src = ./ext/php; 158 nativeBuildInputs = [ pkgs.makeWrapper phpWithFfi tricuZig ]; 159 buildPhase = "true"; 160 installPhase = '' 161 mkdir -p $out/share/tricu-php $out/lib $out/bin 162 cp -r src public run.php $out/share/tricu-php/ 163 cp ${tricuZig}/lib/libarboricx.so $out/lib/ 164 cp ${tricuZig}/include/arboricx.h $out/share/tricu-php/ 165 166 makeWrapper ${phpWithFfi}/bin/php $out/bin/tricu-php \ 167 --add-flags "$out/share/tricu-php/run.php" \ 168 --set ARBORICX_LIB "$out/lib/libarboricx.so" \ 169 --prefix LD_LIBRARY_PATH : "$out/lib" 170 ''; 171 }; 172 173 # ------------------------------------------------------------------ 174 # JS FFI host 175 # ------------------------------------------------------------------ 176 tricuJs = pkgs.buildNpmPackage { 177 pname = "tricu-js"; 178 version = "0.1.0"; 179 src = ./ext/js; 180 npmDepsHash = "sha256-81C7tsNcbyZVhm3uqiWdDQxp5LAXXO9aueHdMDztCfM="; 181 nativeBuildInputs = [ pkgs.nodejs tricuZig ]; 182 dontNpmBuild = true; 183 installPhase = '' 184 mkdir -p $out/lib/ 185 cp -r . $out/lib/ 186 cp ${tricuZig}/lib/libarboricx.so $out/lib/src 187 ''; 188 }; 189 190 # ------------------------------------------------------------------ 191 # JS FFI host tests (separate target) 192 # ------------------------------------------------------------------ 193 tricuJsTests = pkgs.stdenv.mkDerivation { 194 pname = "tricu-js-tests"; 195 version = "0.1.0"; 196 src = ./.; 197 nativeBuildInputs = [ pkgs.nodejs tricuZig ]; 198 buildPhase = "true"; 199 doCheck = true; 200 checkPhase = '' 201 export ARBORICX_LIB=${tricuZig}/lib/libarboricx.so 202 export LD_LIBRARY_PATH=${tricuZig}/lib:$LD_LIBRARY_PATH 203 ulimit -s 32768 204 205 cd ext/js 206 # node_modules are pre-fetched by buildNpmPackage; copy them in 207 cp -r ${tricuJs}/lib/tricu-js/node_modules . 208 npm test 209 210 mkdir -p $out 211 echo "All JS tests passed" > $out/result 212 ''; 213 }; 214 215 # ------------------------------------------------------------------ 216 # PHP FFI tests (separate target) 217 # ------------------------------------------------------------------ 218 phpWithFfi = pkgs.php.withExtensions (exts: [ pkgs.phpExtensions.ffi ]); 219 220 tricuPhpTests = pkgs.stdenv.mkDerivation { 221 pname = "tricu-php-tests"; 222 version = "0.1.0"; 223 src = ./.; 224 nativeBuildInputs = [ phpWithFfi tricuPhp ]; 225 buildPhase = "true"; 226 doCheck = true; 227 checkPhase = '' 228 export ARBORICX_LIB=${tricuPhp}/lib/libarboricx.so 229 export LD_LIBRARY_PATH=${tricuPhp}/lib:$LD_LIBRARY_PATH 230 ulimit -s 32768 231 232 # Run PHP host against fixture bundles 233 php ext/php/run.php run test/fixtures/id.arboricx hello 234 php ext/php/run.php run test/fixtures/append.arboricx "Hello, " "world!" 235 php ext/php/run.php run test/fixtures/true.arboricx 236 php ext/php/run.php run test/fixtures/false.arboricx 237 php ext/php/run.php run test/fixtures/notQ.arboricx "t t t" 238 239 mkdir -p $out 240 echo "All PHP tests passed" > $out/result 241 ''; 242 }; 243 in { 244 packages.${packageName} = tricuPackage; 245 packages.default = tricuPackage; 246 packages.tricu-static = tricuMuslStatic; 247 packages.tricu-static-upx = tricuStatic; 248 packages.tricu-bench = tricuBench; 249 packages.tricu-zig = tricuZig; 250 packages.tricu-zig-tests = tricuZigTests; 251 packages.tricu-php = tricuPhp; 252 packages.tricu-php-tests = tricuPhpTests; 253 packages.tricu-js = tricuJs; 254 packages.tricu-js-tests = tricuJsTests; 255 256 checks.${packageName} = tricuPackageTests; 257 checks.default = tricuPackageTests; 258 259 devShells.default = pkgs.mkShell { 260 buildInputs = with pkgs; [ 261 haskellPackages.cabal-install 262 haskellPackages.ghc-events 263 haskellPackages.ghcid 264 customGHC 265 upx 266 gcc 267 python3 268 ]; 269 270 inputsFrom = [ 271 tricuPackage 272 tricuZig 273 tricuPhp 274 ]; 275 }; 276 277 packages.${containerPackageName} = pkgs.dockerTools.buildImage { 278 name = "tricu"; 279 tag = "latest"; 280 281 copyToRoot = pkgs.buildEnv { 282 name = "image-root"; 283 paths = [ tricuStatic ]; 284 pathsToLink = [ "/bin" ]; 285 }; 286 287 config = { 288 Cmd = [ "/bin/tricu" ]; 289 WorkingDir = "/app"; 290 }; 291 }; 292 293 packages.arboricxServer = pkgs.dockerTools.buildImage { 294 name = "arboricxServer"; 295 tag = "latest"; 296 297 copyToRoot = pkgs.runCommand "arboricxServer" {} '' 298 mkdir -p $out/app/bin $out/app/lib $out/app/tricu-apps $out/app/store 299 cp ${tricuStatic}/bin/tricu $out/app/bin/ 300 cp -r ${./lib}/* $out/app/lib/ 301 cp ${./tricu.workspace} $out/app/tricu.workspace 302 cp ${./tricu-apps/arboricxServer.tri} $out/app/tricu-apps/arboricxServer.tri 303 ''; 304 305 config = { 306 Entrypoint = [ "/app/bin/tricu" "eval" "tricu-apps/arboricxServer.tri" "--io" "--allow-read" "./store" "--allow-write" "./store" "-f" "decode" ]; 307 WorkingDir = "/app"; 308 ExposedPorts = { "8080/tcp" = {}; }; 309 }; 310 }; 311 }); 312 }