122
									
								
								flake.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								flake.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| { | ||||
|   description = "My flake"; | ||||
|  | ||||
|   inputs = { | ||||
|     nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1"; | ||||
|     flake-utils.url = "github:numtide/flake-utils"; | ||||
|   }; | ||||
|  | ||||
|   outputs = | ||||
|     { | ||||
|       self, | ||||
|       nixpkgs, | ||||
|       flake-utils, | ||||
|     }: | ||||
|     flake-utils.lib.eachDefaultSystem ( | ||||
|       system: | ||||
|       let | ||||
|         pkgs = import nixpkgs { inherit system; }; | ||||
|       in | ||||
|       { | ||||
|         bundlers = rec { | ||||
|           proot-bundler = | ||||
|             drv: | ||||
|             pkgs.stdenvNoCC.mkDerivation { | ||||
|               name = "myApp.run"; | ||||
|               nativeBuildInputs = [ | ||||
|                 pkgs.nix | ||||
|                 pkgs.coreutils | ||||
|                 pkgs.findutils | ||||
|                 pkgs.gnutar | ||||
|                 pkgs.gzip | ||||
|                 pkgs.patchelf | ||||
|               ]; | ||||
|               # patch proot as you described | ||||
|               prootPatched = pkgs.proot.overrideAttrs (_: { | ||||
|                 postFixup = '' | ||||
|                   exe=$out/bin/proot | ||||
|                   ${pkgs.patchelf}/bin/patchelf \ | ||||
|                     --set-interpreter ."$(${pkgs.patchelf}/bin/patchelf --print-interpreter $exe)" \ | ||||
|                     --set-rpath "$(${pkgs.patchelf}/bin/patchelf --print-rpath $exe | sed 's|/nix/store/|./nix/store/|g')" \ | ||||
|                     $exe | ||||
|                 ''; | ||||
|               }); | ||||
|  | ||||
|               buildCommand = '' | ||||
|                 set -euo pipefail | ||||
|                 # 1) Make payload dir that mirrors the bundle runtime layout | ||||
|                 PAY="$PWD/payload" | ||||
|                 mkdir -p "$PAY/nix/store" | ||||
|  | ||||
|                 # include app + patched proot in the payload closure | ||||
|                 app=${drv} | ||||
|                 proot=${ | ||||
|                   self.bundlers.${system}.selfExtracting.prootPatched or "" | ||||
|                 } # not callable; we want the attr above | ||||
|                 proot=${ | ||||
|                   pkgs.proot.overrideAttrs (_: { | ||||
|                     postFixup = "${pkgs.patchelf}/bin/patchelf --set-interpreter .\"$(${pkgs.patchelf}/bin/patchelf --print-interpreter $out/bin/proot)\" --set-rpath \"$( ${pkgs.patchelf}/bin/patchelf --print-rpath $out/bin/proot | sed 's|/nix/store/|./nix/store/|g')\" $out/bin/proot"; | ||||
|                   }) | ||||
|                 } | ||||
|  | ||||
|                 # copy closure of app + proot into ./nix/store | ||||
|                 paths=$( ${pkgs.nix}/bin/nix-store --query --requisites "$app" "$proot" ) | ||||
|                 for p in $paths; do | ||||
|                   cp -a --no-preserve=ownership "$p" "$PAY/nix/store/" | ||||
|                 done | ||||
|  | ||||
|                 # discover targets for the launcher | ||||
|                 APP_BIN=$(find "$app/bin" -maxdepth 1 -type f -perm -111 | head -n1) | ||||
|                 APP_REL="/nix/store/$(basename "$(dirname "$APP_BIN")")/$(basename "$APP_BIN")" | ||||
|                 PROOT_REL="/nix/store/$(basename "$proot")/bin/proot" | ||||
|  | ||||
|                 # 2) Tar.gz the payload | ||||
|                 ( cd "$PAY" && tar -czf "$PWD/payload.tar.gz" . ) | ||||
|  | ||||
|                 # 3) Assemble a self-extracting script at $out | ||||
|                 cat > $out <<'SH' | ||||
|                 #!/bin/sh | ||||
|                 set -euf | ||||
|                 # extract to temp dir | ||||
|                 : "''${TMPDIR:=/tmp}" | ||||
|                 EXTRACT_DIR="$(mktemp -d "''${TMPDIR%/}/nxbdl.XXXXXX")" | ||||
|                 cleanup() { [ -n "''${KEEP_BUNDLE:-}" ] || rm -rf "$EXTRACT_DIR"; } | ||||
|                 trap cleanup EXIT INT TERM | ||||
|  | ||||
|                 # locate embedded archive (line after marker) | ||||
|                 ARCHIVE_LINE=$(awk '/^__ARCHIVE_BELOW__/ {print NR+1; exit 0}' "$0") | ||||
|                 tail -n +$ARCHIVE_LINE "$0" | tar -xzf - -C "$EXTRACT_DIR" | ||||
|  | ||||
|                 cd "$EXTRACT_DIR" | ||||
|                 # vars substituted by bundler at build time: | ||||
|                 APP_REL='__APP_REL__' | ||||
|                 PROOT_REL='__PROOT_REL__' | ||||
|  | ||||
|                 # run via proot | ||||
|                 BUNDLE_PWD="''${BUNDLE_PWD:-$PWD}" | ||||
|                 exec ".$PROOT_REL" \ | ||||
|                   -b ./nix:nix \ | ||||
|                   -R / \ | ||||
|                   -w "$BUNDLE_PWD" \ | ||||
|                   ".$APP_REL" "$@" | ||||
|  | ||||
|                 __ARCHIVE_BELOW__ | ||||
|                 SH | ||||
|  | ||||
|                 # substitute the program + proot paths into the stub | ||||
|                 sed -i \ | ||||
|                   -e "s|__APP_REL__|$APP_REL|g" \ | ||||
|                   -e "s|__PROOT_REL__|$PROOT_REL|g" \ | ||||
|                   $out | ||||
|                 chmod +x $out | ||||
|  | ||||
|                 # 4) Append the payload bytes after the marker | ||||
|                 cat payload.tar.gz >> $out | ||||
|               ''; | ||||
|             }; | ||||
|  | ||||
|           default = proot-bundler; | ||||
|         }; | ||||
|       } | ||||
|     ); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user