ricochetrobots 0.0.0

A game for modeling and solving Ricochet Robots puzzles.
Documentation
{
	nixpkgs ? import <nixpkgs> {
		overlays = [
			(self: super: {
				rustc = (super.rustc.override {
					stdenv = self.stdenv.override {
						targetPlatform = super.stdenv.targetPlatform // {
							parsed = {
								cpu = { name = "wasm32"; };
								vendor = {name = "unknown";};
								kernel = {name = "unknown";};
								abi = {name = "unknown";};
							};
						};
					};
				}).overrideAttrs (attrs: {
					configureFlags = attrs.configureFlags ++ ["--set=build.docs=false"];
				});
			})
		];
	},
	naersk ? nixpkgs.pkgs.callPackage (fetchTarball "https://github.com/nmattia/naersk/archive/master.tar.gz") {},
	kevincox-web-compiler ? builtins.storePath (nixpkgs.lib.fileContents (builtins.fetchurl  "https://kevincox.gitlab.io/kevincox-web-compiler/bin.nixpath")),
	# kevincox-web-compiler ? (import ../kevincox-web-compiler {}).bin,
}: with nixpkgs; let
	render-svg = svg: {width, format ? "svg"}: let
		basename = lib.removeSuffix ".svg" (baseNameOf svg);
		width-str = toString width;
	in pkgs.runCommand "${basename}-${width-str}.png" {} ''
		${pkgs.librsvg}/bin/rsvg-convert -w ${width-str} -a ${svg} >$out
	'';
	root = pkgs.nix-gitignore.gitignoreSource
		[
			"*"
			"!src/"
			"!Cargo.*"
			"!benches/"
			"!tests/"
		]
		./.;
in rec {
	instrumented = naersk.buildPackage {
		inherit root;
		doCheck = true;
		RUSTFLAGS = "-Cprofile-generate=/tmp/llvm-profile";
	};

	profile-data = pkgs.runCommand "ricochetrobots.profdata" {} ''
		find ${./games} -name '*.txt' -print0 \
			| xargs -0n1 -P$NIX_BUILD_CORES ${instrumented}/bin/solve --animate=false
		${pkgs.rustc.llvm}/bin/llvm-profdata merge -o $out /tmp/llvm-profile
	'';

	native = naersk.buildPackage {
		inherit root;
		# LTO fails with PGO: https://github.com/llvm/llvm-project/issues/57501
		RUSTFLAGS = "-Cprofile-use=${profile-data} -Clto=false";
	};

	build = naersk.buildPackage {
		inherit root;
		buildInputs = with pkgs; [
			lld
		];
		RUSTFLAGS = "-Clinker=lld";
		cargoBuildOptions = def: def ++ ["--target=wasm32-unknown-unknown"];
		copyLibs = true;
	};

	opt = pkgs.runCommand "ricochetrobots-opt.wasm" {} ''
		${pkgs.binaryen}/bin/wasm-opt ${build}/lib/ricochetrobots.wasm -o $out -O4
	'';
	wasm-bindgen = pkgs.runCommand "ricochetrobots-wasm-bindgen" {} ''
		${pkgs.wasm-bindgen-cli}/bin/wasm-bindgen ${opt} --target=web --out-name=ricochetrobots --out-dir=$out
	'';

	typescript = pkgs.runCommand "ricochetrobots-ts" {} ''
		ln -vs ${./tsconfig.json} tsconfig.json
		ln -vs ${./typescript} typescript
		ln -vs ${wasm-bindgen} wasm

		${pkgs.typescript}/bin/tsc --outDir "$out"
	'';

	unoptimized = pkgs.runCommandLocal "ricochetrobots-unoptimized" {} ''
		cp -vr --no-preserve=mode ${./web} $out

		cp -vr ${typescript} "$out/a/typescript"
		cp -vr --no-preserve=mode ${wasm-bindgen} $out/a/wasm
		rm -vr $out/a/wasm/**.ts

		cp -v ${render-svg ./web/a/logo.svg {width=192;}} $out/a/logo-192.png
		cp -v ${render-svg ./web/a/logo.svg {width=512;}} $out/a/logo-512.png
		cp -v ${render-svg ./web/a/logo.svg {width=1024;}} $out/a/logo-1024.png
	'';

	www = pkgs.runCommandLocal "ricochetrobots-www" {} ''
		${kevincox-web-compiler}/bin/kevincox-web-compiler \
			--asset-mode=hash \
			--no-analytics \
			${unoptimized} $out
	'';
}