refactor(web/tvixbolt): buildRustPackage -> crate2nix

With the recent changes to crate2nix and buildRustCrate in nixpkgs it is
now possible to build tvixbolt via crate2nix like we do for other tvix
crates. We can reuse a lot of the customizations done in //tvix in
tvixbolt to avoid repeating ourselves.

A script for serving tvixbolt locally for testing purposes is also
available now through the .serve attribute of tvixbolt.

This change supersedes https://cl.tvl.fyi/c/depot/+/11821.

Change-Id: I4864df8b75aec73cf5fee2428924ed4cfbb32902
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11952
Tested-by: BuildkiteCI
Autosubmit: Ilan Joselevich <personal@ilanjoselevich.com>
Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
Ilan Joselevich 2024-07-04 21:05:46 +03:00
parent 6a7069904e
commit 7ca32d9f0b
9 changed files with 4595 additions and 122 deletions

View file

@ -25,18 +25,6 @@ sure noone is working on this, or has some specific design in mind already.
with a different level of `--strict`, but the toplevel doc-comment suggests
its generic?
### crate2nix for WASM (@kranzes)
Most of Tvix is living inside a `//tvix` cargo workspace, and we use `crate2nix`
as a build system, to get crate-level build granularity (and caching), keeping
compile times somewhat manageable.
Thanks to the recent crate2nix fixes, we can now use it to build WASM.
We should migrate `//web/tvixbolt` from `rustPlatform.buildRustPackage` to
`crate2nix`.
An initial cl/11821 to move it to the `//tvix` workspace got some pushback, we
should see if it's possible to keep it in a separate directory and still refer
to the (cleaned) sources described in `tvix/default.nix`.
## Perf
- String Contexts currently do a lot of indirections (edef)
(NixString -> NixStringInner -> HashSet[element] -> NixContextElement -> String -> data)

View file

@ -412,9 +412,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "js-sys"
version = "0.3.66"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
@ -727,9 +727,9 @@ checksum = "3ddc765d3410d9f6c6ca071bf0b67f6b01e3ec4595dc3892f02677e75819dddc"
[[package]]
name = "serde"
version = "1.0.195"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
@ -748,9 +748,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.195"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
@ -979,10 +979,7 @@ dependencies = [
name = "tvixbolt"
version = "0.1.0"
dependencies = [
"codemap",
"rnix",
"serde",
"serde_urlencoded",
"tvix-eval",
"wasm-bindgen",
"web-sys",
@ -1088,9 +1085,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "web-sys"
version = "0.3.66"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f"
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
dependencies = [
"js-sys",
"wasm-bindgen",

4531
web/tvixbolt/Cargo.nix Normal file

File diff suppressed because it is too large Load diff

View file

@ -3,24 +3,13 @@ name = "tvixbolt"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
yew = "0.19.3"
yew-router = "0.16"
codemap = "0.1.3"
serde_urlencoded = "*" # pinned by yew
rnix = "0.11.0"
# needs to be in sync with nixpkgs
wasm-bindgen = "= 0.2.92"
[dependencies.tvix-eval]
path = "../../tvix/eval"
default-features = false
[dependencies.serde]
version = "*" # pinned by yew
features = [ "derive" ]
[dependencies.web-sys]
version = "*" # pinned by yew
features = [ "HtmlDetailsElement" ]
tvix-eval = { path = "../../tvix/eval", default-features = false }
serde = { version = "1.0.203", features = ["derive"] }
web-sys = { version = "0.3.69", features = ["HtmlDetailsElement"] }
wasm-bindgen = "0.2.92"

View file

@ -1,74 +1,30 @@
{ depot, lib, pkgs, ... }:
{ pkgs, lib, depot, ... }:
let
wasmRust = pkgs.rust-bin.stable.latest.default.override {
targets = [ "wasm32-unknown-unknown" ];
};
cargoToml = with builtins; fromTOML (readFile ./Cargo.toml);
wasmBindgenMatch =
cargoToml.dependencies.wasm-bindgen == "= ${pkgs.wasm-bindgen-cli.version}";
assertWasmBindgen = assert (lib.assertMsg wasmBindgenMatch ''
Due to instability in the Rust WASM ecosystem, the trunk build
tool enforces that the Cargo-dependency version of `wasm-bindgen`
MUST match the version of the CLI supplied in the environment.
This can get out of sync when nixpkgs is updated. To resolve it,
wasm-bindgen must be bumped in the Cargo.toml file and cargo needs
to be run to resolve the dependencies.
Versions of `wasm-bindgen` in Cargo.toml:
Expected: '= ${pkgs.wasm-bindgen-cli.version}'
Actual: '${cargoToml.dependencies.wasm-bindgen}'
''); pkgs.wasm-bindgen-cli;
deps = [
pkgs.binaryen
pkgs.sass
pkgs.trunk
wasmRust
assertWasmBindgen
];
# Cargo.toml needs to be patched with the /nix/store source path of
# tvix-eval.
cargoTomlPatch = pkgs.writeText "tvix-eval-src.patch" ''
diff --git a/Cargo.toml b/Cargo.toml
index 75006bec18..6ca244bbb2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,7 @@ rnix = "0.11.0"
wasm-bindgen = "= 0.2.83"
[dependencies.tvix-eval]
-path = "../../tvix/eval"
+path = "${../../tvix/eval}"
default-features = false
[dependencies.serde]
'';
pkgsCross = pkgs.pkgsCross.wasm32-unknown-none;
in
pkgs.rustPlatform.buildRustPackage rec {
pname = "tvixbolt";
version = "canon";
src = lib.cleanSource ./.;
(pkgsCross.callPackage ./Cargo.nix {
defaultCrateOverrides = (depot.tvix.utils.defaultCrateOverridesForPkgs pkgsCross) // {
tvixbolt = prev: {
src = depot.tvix.utils.filterRustCrateSrc { root = prev.src.origSrc; };
};
};
}).rootCrate.build.overrideAttrs (oldAttrs: {
installPhase = ''
${lib.getExe pkgs.wasm-bindgen-cli} \
--target web \
--out-dir $out \
--out-name ${oldAttrs.crateName} \
--no-typescript \
target/lib/${oldAttrs.crateName}-${oldAttrs.metadata}.wasm
cargoLock.lockFile = ./Cargo.lock;
patches = [
cargoTomlPatch
];
buildPhase = ''
export PATH=${lib.makeBinPath deps}:$PATH
mkdir home
export HOME=$PWD/home
trunk build --release -d $out
mv src/*.{html,css} $out
'';
dontInstall = true;
}
passthru.serve = pkgs.writeShellScriptBin "tvixbolt-serve" ''
${lib.getExe pkgs.simple-http-server} \
--index \
--nocache \
"$@" \
${depot.web.tvixbolt}
'';
})

View file

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://static.tvl.su/latest/terminal.min.css" />
<link data-trunk rel="inline" href="index.css">
<title>Tvixbolt</title>
</head>
</html>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://static.tvl.su/latest/terminal.min.css">
<link rel="stylesheet" href="index.css">
<title>Tvixbolt</title>
</head>
<body>
<script type="module">
import init, { main } from './tvixbolt.js';
async function run() {
await init();
main();
}
run();
</script>
</body>

View file

@ -7,6 +7,7 @@ use std::fmt::Write;
use serde::{Deserialize, Serialize};
use tvix_eval::observer::{DisassemblingObserver, TracingObserver};
use wasm_bindgen::prelude::wasm_bindgen;
use web_sys::HtmlDetailsElement;
use web_sys::HtmlTextAreaElement;
use yew::prelude::*;
@ -310,6 +311,7 @@ fn eval(model: &Model) -> Output {
out
}
fn main() {
#[wasm_bindgen]
pub fn main() {
yew::start_app::<Model>();
}