Created
October 1, 2020 21:48
-
-
Save arifd/fb4ebd4d9995ddf02bc6016690a225b6 to your computer and use it in GitHub Desktop.
Miniquad, Rust, WASM, Web, build script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#===========================================================================================# | |
# Miniquad WASM/Web Builder # | |
# # | |
# Put this script at the base of your cargo project and run it to quickly build and test # | |
# your miniquad project in a WASM/Web environment. # | |
# # | |
# It creates and pulls in all the necessary files into a directory called 'www/' leaving # | |
# the originals intact. Just delete the www folder to undo its effect. # | |
# # | |
# Default mode (without arguments) is debug. Pass in --release for release mode. # | |
# # | |
# If your project runs in the browser in debug but not in release, it's likely due to # | |
# an incompatible optimisation. Head over to that section and comment out the culprit. # | |
# # | |
# This script uses Python3 for the Web Server. # | |
#===========================================================================================# | |
### Setup ### | |
bold=$(tput bold) | |
normal=$(tput sgr0) | |
### Check supplied arguments ### | |
if [[ "$1" == "--release" ]] ; then | |
MODE="release" | |
else | |
MODE="debug" | |
fi | |
### Check build configurations ### | |
grep -q "lto = true" Cargo.toml || echo "hint: add ${bold}lto = true${normal} under ${bold}[profile.release]${normal} for futher optimisation" | |
# grep -q "debug = true" Cargo.toml || echo "hint: wasm-snip needs debug symbols to effectively stnip dead-code. Add ${bold}debug = true${normal} under ${bold}[profile.release]${normal} for futher optimisation" | |
### Get name of project ### | |
NAME=$(grep "name =" Cargo.toml | cut -d' ' -f3- | tr -d '"') | |
if [[ -z "$NAME" ]] ; then | |
echo "Abort! Can't deduce name from Cargo.toml file" | |
exit 1 | |
fi | |
### Build your WASM file ### | |
if [[ "$MODE" == "release" ]] ; then | |
cargo build --release --target wasm32-unknown-unknown || exit 1 | |
else | |
cargo build --target wasm32-unknown-unknown || exit 1 | |
fi | |
### Create www dir with necessary files (if not already present) ### | |
if [ ! -d www ]; then | |
HTML=$(awk '/~HTML~/{flag=1; i++; next}/~END~/{flag=0}flag && i > 1' $0 | sed "s/~NAME~/$NAME/g") | |
PYSERVER=$(awk '/~PYSERVER~/{flag=1; i++; next}/~END~/{flag=0}flag && i > 1' $0) | |
mkdir www | |
echo "$HTML" > www/index.html | |
echo "$PYSERVER" > www/server.py | |
fi | |
### Check and copy any files detected in source code ### | |
ASSETS=($(grep -Erho --include \*.rs '"(.*?)"' src/ | grep "/" | grep "." | tr -d '"')) | |
for ASSET in ${ASSETS[@]}; do | |
cp --parents $ASSET www/ | |
done | |
### Copy WASM file over ### | |
cp "target/wasm32-unknown-unknown/$MODE/$NAME.wasm" www/. | |
### Optimisations ### | |
if [[ "$MODE" == "release" ]] ; then | |
NUM_OPTS=4 | |
# If you're using std heavy code. It's possible that wasm-snip could break your WASM file. | |
wasm-snip "www/$NAME.wasm" --snip-rust-fmt-code --snip-rust-panicking-code -o "www/$NAME.wasm" || NUM_OPTS=$((NUM_OPTS-1)) | |
wasm-gc "www/$NAME.wasm" || NUM_OPTS=$((NUM_OPTS-1)) | |
wasm-strip "www/$NAME.wasm" || NUM_OPTS=$((NUM_OPTS-1)) | |
wasm-opt "www/$NAME.wasm" -O4 -o "www/$NAME.wasm" || NUM_OPTS=$((NUM_OPTS-1)) | |
else | |
NUM_OPTS=0 | |
fi | |
### display results ### | |
echo "===========================" | |
echo "$NUM_OPTS / 4 OPTIMISATIONS ENGAGED" | |
echo "===========================" | |
echo "Final file sizes:" | |
ls -lh www/ | |
### serve ### | |
python3 www/server.py | |
############################################################################ | |
exit 0 # END OF SCRIPT. EVERYTHING BELOW IS DATA NEEDED FOR THE ABOVE SCRIPT | |
############################################################################ | |
~HTML~ | |
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>TITLE</title> | |
<style> | |
html, | |
body, | |
canvas { | |
margin: 0px; | |
padding: 0px; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
position: absolute; | |
background: black; | |
z-index: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<canvas id="glcanvas" tabindex='1'></canvas> | |
<!-- Minified and statically hosted version of https://github.com/not-fl3/miniquad/blob/master/native/sapp-wasm/js/gl.js --> | |
<script src="https://not-fl3.github.io/miniquad-samples/gl.js"></script> | |
<script>load("~NAME~.wasm");</script> <!-- Your compiled wasm file --> | |
</body> | |
</html> | |
~END~ | |
~PYSERVER~ | |
import http.server | |
import socketserver | |
import os | |
PORT = 8000 | |
os.chdir(os.path.dirname(__file__)) | |
Handler = http.server.SimpleHTTPRequestHandler | |
Handler.extensions_map.update({ | |
'.wasm': 'application/wasm', | |
}) | |
socketserver.TCPServer.allow_reuse_address = True | |
with socketserver.TCPServer(("", PORT), Handler) as httpd: | |
httpd.allow_reuse_address = True | |
print("serving at port", PORT) | |
httpd.serve_forever() | |
~END~ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment