Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use different artifact names for wasm/js in debug builds #1428

Merged
merged 14 commits into from
Feb 28, 2023
2 changes: 1 addition & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The easiest way to launch the viewer is directly from the logging API with `rr.i
#### Web viewer
You can try running the viewer in a browser using `rr.serve()` in python, or using `rerun --web-viewer mydata.rrd`.

The web viewer consists of just a few small files - a thin `.html`, a `.wasm` blob, and an auto-generated `.js` bridge for the wasm. These files are served using the [`re_web_server`](https://github.com/rerun-io/rerun/tree/latest/crates/re_web_server) crate.
The web viewer consists of just a few small files - a thin `.html`, a `.wasm` blob, and an auto-generated `.js` bridge for the wasm. These files are served using the [`re_web_viewer_server`](https://github.com/rerun-io/rerun/tree/latest/crates/re_web_viewer_server) crate.

The web viewer can load `.rrd` files (just drag-drop them into the browser), or read logging data streamed over WebSockets.

Expand Down
14 changes: 11 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ re_analytics = { path = "crates/re_analytics", version = "0.2.0" }
re_arrow_store = { path = "crates/re_arrow_store", version = "0.2.0" }
re_build_build_info = { path = "crates/re_build_build_info", version = "0.2.0" }
re_build_info = { path = "crates/re_build_info", version = "0.2.0" }
re_build_web_viewer = { path = "crates/re_build_web_viewer", version = "0.2.0" }
re_data_store = { path = "crates/re_data_store", version = "0.2.0" }
re_error = { path = "crates/re_error", version = "0.2.0" }
re_format = { path = "crates/re_format", version = "0.2.0" }
Expand All @@ -43,7 +44,7 @@ re_tensor_ops = { path = "crates/re_tensor_ops", version = "0.2.0" }
re_tuid = { path = "crates/re_tuid", version = "0.2.0" }
re_ui = { path = "crates/re_ui", version = "0.2.0" }
re_viewer = { path = "crates/re_viewer", version = "0.2.0" }
re_web_server = { path = "crates/re_web_server", version = "0.2.0" }
re_web_viewer_server = { path = "crates/re_web_viewer_server", version = "0.2.0" }
re_ws_comms = { path = "crates/re_ws_comms", version = "0.2.0" }
rerun = { path = "crates/rerun", version = "0.2.0" }

Expand Down
20 changes: 20 additions & 0 deletions crates/re_build_web_viewer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "re_build_web_viewer"
authors.workspace = true
description = "Build the rerun web-viewer Wasm from source"
edition.workspace = true
homepage.workspace = true
include.workspace = true
license.workspace = true
publish = true
readme = "README.md"
repository.workspace = true
rust-version.workspace = true
version.workspace = true

[package.metadata.docs.rs]
all-features = true


[dependencies]
cargo_metadata = "0.15"
13 changes: 13 additions & 0 deletions crates/re_build_web_viewer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# `re_build_web_viewer`

Binary and library for building the Rerun web viewer.

This is also called by the `build.rs` of `re_web_viewer_server`.

```
cargo r -p re_build_web_viewer -- --debug
````

```
cargo r -p re_build_web_viewer -- --release
````
148 changes: 148 additions & 0 deletions crates/re_build_web_viewer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
//! Build the Rerun web-viewer .wasm and generate the .js bindings for it.

use cargo_metadata::camino::Utf8PathBuf;

fn target_directory() -> Utf8PathBuf {
let metadata = cargo_metadata::MetadataCommand::new()
.manifest_path("./Cargo.toml")
.features(cargo_metadata::CargoOpt::NoDefaultFeatures)
.exec()
.unwrap();
metadata.target_directory
}

/// Build `re_viewer` as Wasm, generate .js bindings for it, and place it all into the `./web_viewer` folder.
pub fn build(release: bool) {
eprintln!("Building web viewer wasm…");
eprintln!("We assume you've already run ./scripts/setup_web.sh");

let crate_name = "re_viewer";

// Where we tell cargo to build to.
// We want this to be different from the default target folder
// in order to support recursive cargo builds (calling `cargo` from within a `build.rs`).
let target_wasm_dir = Utf8PathBuf::from(format!("{}_wasm", target_directory()));

// Repository root
let root_dir = target_wasm_dir.parent().unwrap();

// Where we will place the final .wasm and .js artifacts.
let build_dir = root_dir.join("web_viewer");

assert!(
build_dir.exists(),
"Failed to find dir {build_dir}. CWD: {:?}, CARGO_MANIFEST_DIR: {:?}",
std::env::current_dir(),
std::env!("CARGO_MANIFEST_DIR")
);

let target_name = if release {
crate_name.to_owned()
} else {
format!("{crate_name}_debug")
};

// The two files we are building:
let wasm_path = build_dir.join(format!("{target_name}_bg.wasm"));
let js_path = build_dir.join(format!("{target_name}.js"));

// Clean old versions:
std::fs::remove_file(wasm_path.clone()).ok();
std::fs::remove_file(js_path).ok();

// --------------------------------------------------------------------------------
eprintln!("Compiling rust to wasm in {target_wasm_dir}…");

let mut cmd = std::process::Command::new("cargo");
cmd.args([
"build",
"--target-dir",
target_wasm_dir.as_str(),
"-p",
crate_name,
"--lib",
"--target",
"wasm32-unknown-unknown",
]);
if release {
cmd.arg("--release");
}

// This is required to enable the web_sys clipboard API which egui_web uses
// https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html
// https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html
cmd.env("RUSTFLAGS", "--cfg=web_sys_unstable_apis");

// When executing this script from a Rust build script, do _not_, under any circumstances,
// allow pre-encoded `RUSTFLAGS` to leak into the current environment.
// These pre-encoded flags are generally generated by Cargo itself when loading its
// configuration from e.g. `$CARGO_HOME/config.toml`; which means they will contain
// values that only make sense for the native target host, not for a wasm build.
cmd.env("CARGO_ENCODED_RUSTFLAGS", "");

eprintln!("> {cmd:?}");
let status = cmd
.current_dir(root_dir)
.status()
.expect("Failed to build Wasm");
assert!(status.success(), "Failed to build Wasm");

// --------------------------------------------------------------------------------
eprintln!("Generating JS bindings for wasm…");

let build = if release { "release" } else { "debug" };

let target_wasm_path = target_wasm_dir
.join("wasm32-unknown-unknown")
.join(build)
.join(format!("{crate_name}.wasm"));

let mut cmd = std::process::Command::new("wasm-bindgen");
cmd.args([
target_wasm_path.as_str(),
"--out-dir",
build_dir.as_str(),
"--out-name",
target_name.as_str(),
"--no-modules",
"--no-typescript",
]);
if !release {
cmd.arg("--debug");
}

eprintln!("> {cmd:?}");
let status = cmd
.current_dir(root_dir)
.status()
.expect("Failed to run wasm-bindgen");
assert!(status.success(), "Failed to run wasm-bindgen");

// --------------------------------------------------------------------------------
// Optimize the wasm

if release {
eprintln!("Optimizing wasm with wasm-opt…");

// to get wasm-opt: apt/brew/dnf install binaryen
let mut cmd = std::process::Command::new("wasm-opt");

// TODO(emilk): add `-g` to keep debug symbols; useful for profiling release builds in the in-browser profiler.
cmd.args([
wasm_path.as_str(),
"-O2",
"--fast-math",
"-o",
wasm_path.as_str(),
]);

eprintln!("> {cmd:?}");
let status = cmd
.current_dir(root_dir)
.status()
.expect("Failed to run wasm-opt");
assert!(status.success(), "Failed to run wasm-opt");
}

eprintln!("Finished {wasm_path}");
}
46 changes: 46 additions & 0 deletions crates/re_build_web_viewer/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use std::process::ExitCode;

fn main() -> ExitCode {
let mut release = None;

for arg in std::env::args().skip(1) {
match arg.as_str() {
"--help" => {
print_help();
return ExitCode::SUCCESS;
}
"--debug" => {
assert!(release.is_none(), "Can't set both --release and --debug");
release = Some(false);
}
"--release" => {
assert!(release.is_none(), "Can't set both --release and --debug");
release = Some(true);
}
_ => {
print_help();
return ExitCode::FAILURE;
}
}
}

let Some(release) = release else {
eprintln!("You need to pass either --debug or --release");
return ExitCode::FAILURE;
};

re_build_web_viewer::build(release);
ExitCode::SUCCESS
}

fn print_help() {
eprintln!(
r"Build the web-viewer.

--help: Print this help text
--debug: Build a debug binary
--release: Compile for release, and run wasm-opt.
NOTE: --release also removes debug symbols which are otherwise useful for in-browser profiling.
"
);
}
6 changes: 3 additions & 3 deletions crates/re_sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ all-features = true
default = ["demo", "glam", "image", "native_viewer"]

## Enable telemetry using our analytics SDK.
analytics = ["re_web_server?/analytics", "re_viewer?/analytics"]
analytics = ["re_web_viewer_server?/analytics", "re_viewer?/analytics"]

## Enable the `demo` module (helpers for Rerun examples).
demo = []
Expand All @@ -41,7 +41,7 @@ native_viewer = ["image", "dep:re_viewer"]
##
## You also need to install some additional tools, which you can do by running
## [`scripts/setup_web.sh`](https://github.com/rerun-io/rerun/blob/main/scripts/setup_web.sh).
web_viewer = ["dep:re_ws_comms", "dep:re_web_server", "dep:webbrowser"]
web_viewer = ["dep:re_ws_comms", "dep:re_web_viewer_server", "dep:webbrowser"]


[dependencies]
Expand All @@ -67,7 +67,7 @@ thiserror.workspace = true
# Optional dependencies:
re_ws_comms = { workspace = true, optional = true, features = ["server"] }
re_viewer = { workspace = true, default-features = false, optional = true }
re_web_server = { workspace = true, optional = true }
re_web_viewer_server = { workspace = true, optional = true }

webbrowser = { version = "0.8", optional = true }

Expand Down
2 changes: 1 addition & 1 deletion crates/re_sdk/src/remote_viewer_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl RemoteViewerServer {

// This is the server that serves the Wasm+HTML:
let web_port = 9090;
let web_server = re_web_server::WebServer::new(web_port);
let web_server = re_web_viewer_server::WebViewerServer::new(web_port);
let web_server_handle = tokio::spawn(async move {
web_server.serve().await.unwrap();
});
Expand Down
2 changes: 1 addition & 1 deletion crates/re_viewer/src/viewer_analytics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! There are two exceptions:
//! * `crates/rerun/src/crash_handler.rs` sends anonymized callstacks on crashes
//! * `crates/re_web_server/src/lib.rs` sends an anonymous event when a `.wasm` web-viewer is served.
//! * `crates/re_web_viewer_server/src/lib.rs` sends an anonymous event when a `.wasm` web-viewer is served.
//!
//! Analytics can be completely disabled with `rerun analytics disable`,
//! or by compiling rerun without the `analytics` feature flag.
Expand Down
9 changes: 0 additions & 9 deletions crates/re_web_server/src/main.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "re_web_server"
name = "re_web_viewer_server"
authors.workspace = true
description = "Serves the Rerun web viewer (Wasm and HTML) over HTTP"
edition.workspace = true
Expand Down Expand Up @@ -54,3 +54,4 @@ re_analytics = { workspace = true, optional = true }
[build-dependencies]
glob = "0.3.0"
cargo_metadata = "0.15"
re_build_web_viewer.workspace = true
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# re_web_server
# re_web_viewer_server

Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates.

[![Latest version](https://img.shields.io/crates/v/re_web_server.svg)](https://crates.io/crates/re_web_server)
[![Documentation](https://docs.rs/re_web_server/badge.svg)](https://docs.rs/re_web_server)
[![Latest version](https://img.shields.io/crates/v/re_web_viewer_server.svg)](https://crates.io/crates/re_web_viewer_server)
[![Documentation](https://docs.rs/re_web_viewer_server/badge.svg)](https://docs.rs/re_web_viewer_server)
![MIT](https://img.shields.io/badge/license-MIT-blue.svg)
![Apache](https://img.shields.io/badge/license-Apache-blue.svg)

Expand Down
Loading