Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/tools/build-wasm-example/src/main.rs
6595 views
1
//! Tool used to build Bevy examples for wasm.
2
3
use std::{fs::File, io::Write};
4
5
use clap::{Parser, ValueEnum};
6
use xshell::{cmd, Shell};
7
8
#[derive(Debug, Copy, Clone, ValueEnum)]
9
enum WebApi {
10
Webgl2,
11
Webgpu,
12
}
13
14
#[derive(Parser, Debug)]
15
struct Args {
16
/// Examples to build
17
examples: Vec<String>,
18
19
#[arg(short, long)]
20
/// Run tests
21
test: bool,
22
23
#[arg(short, long)]
24
/// Run on the given browsers. By default, chromium, firefox, webkit
25
browsers: Vec<String>,
26
27
#[arg(short, long)]
28
/// Stop after this number of frames
29
frames: Option<usize>,
30
31
#[arg(value_enum, short, long, default_value_t = WebApi::Webgl2)]
32
/// Browser API to use for rendering
33
api: WebApi,
34
35
#[arg(short, long)]
36
/// Optimize the wasm file for size with wasm-opt
37
optimize_size: bool,
38
39
#[arg(long)]
40
/// Additional features to enable
41
features: Vec<String>,
42
43
#[arg(long)]
44
/// Build the example in debug mode instead of release
45
debug: bool,
46
}
47
48
fn main() {
49
let cli = Args::parse();
50
51
assert!(!cli.examples.is_empty(), "must have at least one example");
52
53
let default_features = true;
54
let mut features: Vec<&str> = cli.features.iter().map(String::as_str).collect();
55
if let Some(frames) = cli.frames {
56
let mut file = File::create("ci_testing_config.ron").unwrap();
57
file.write_fmt(format_args!("(events: [({frames}, AppExit)])"))
58
.unwrap();
59
features.push("bevy_ci_testing");
60
}
61
62
match cli.api {
63
WebApi::Webgl2 => (),
64
WebApi::Webgpu => {
65
features.push("webgpu");
66
}
67
}
68
69
for example in cli.examples {
70
let sh = Shell::new().unwrap();
71
let features_string = features.join(",");
72
let mut parameters = vec![];
73
if !default_features {
74
parameters.push("--no-default-features");
75
}
76
if !features.is_empty() {
77
parameters.push("--features");
78
parameters.push(&features_string);
79
}
80
81
let profile = if cli.debug {
82
"debug"
83
} else if cli.optimize_size {
84
"wasm-release"
85
} else {
86
"release"
87
};
88
89
let cmd = cmd!(
90
sh,
91
"cargo build {parameters...} --profile {profile} --target wasm32-unknown-unknown --example {example}"
92
);
93
cmd.env("RUSTFLAGS", "--cfg getrandom_backend=\"wasm_js\"")
94
.run()
95
.expect("Error building example");
96
97
cmd!(
98
sh,
99
"wasm-bindgen --out-dir examples/wasm/target --out-name wasm_example --target web target/wasm32-unknown-unknown/{profile}/examples/{example}.wasm"
100
)
101
.run()
102
.expect("Error creating wasm binding");
103
104
if cli.optimize_size {
105
cmd!(sh, "wasm-opt -Oz --output examples/wasm/target/wasm_example_bg.wasm.optimized examples/wasm/target/wasm_example_bg.wasm")
106
.run().expect("Failed to optimize for size. Do you have wasm-opt correctly set up?");
107
}
108
109
if cli.test {
110
let _dir = sh.push_dir(".github/start-wasm-example");
111
let mut browsers = cli.browsers.clone();
112
if !browsers.is_empty() {
113
browsers.insert(0, "--project".to_string());
114
}
115
cmd!(sh, "npx playwright test --headed {browsers...}")
116
.env("SCREENSHOT_PREFIX", format!("screenshot-{example}"))
117
.run()
118
.expect("Error running playwright test");
119
}
120
}
121
}
122
123