Skip to content

Add optimize_wasm build option for Web #105388

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion platform/web/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ js_wrapped = env.NoCache(
env.Textfile("#bin/godot", [env.File(f) for f in wrap_list], TEXTFILESUFFIX="${PROGSUFFIX}.wrapped.js")
)

main_wasm = build[1]
side_wasm = build[2] if len(build) > 2 else None

if env["optimize_wasm"]:
main_wasm = env.OptimizeWASM(main_wasm)
if side_wasm is not None:
side_wasm = env.OptimizeWASM(side_wasm)

# 0 - unwrapped js file (use wrapped one instead)
# 1 - wasm file
# 2 - wasm side (when dlink is enabled).
env.CreateTemplateZip(js_wrapped, build[1], build[2] if len(build) > 2 else None)
env.CreateTemplateZip(js_wrapped, main_wasm, side_wasm)
12 changes: 12 additions & 0 deletions platform/web/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
create_template_zip,
get_template_zip_path,
run_closure_compiler,
run_optimize_wasm,
)
from SCons.Util import WhereIs

Expand Down Expand Up @@ -57,6 +58,11 @@ def get_opts():
"Use Emscripten PROXY_TO_PTHREAD option to run the main application code to a separate thread",
False,
),
BoolVariable(
"optimize_wasm",
"Use binaryen `wasm-opt` to reduce the output .wasm file sizes",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Use binaryen `wasm-opt` to reduce the output .wasm file sizes",
"Use Binaryen `wasm-opt` to reduce the output WebAsssembly file sizes (requires `wasm-opt` in `PATH`)",

False,
),
]


Expand Down Expand Up @@ -303,3 +309,9 @@ def configure(env: "SConsEnvironment"):
# This workaround creates a closure that prevents the garbage collector from freeing the WebGL context.
# We also only use WebGL2, and changing context version is not widely supported anyway.
env.Append(LINKFLAGS=["-sGL_WORKAROUND_SAFARI_GETCONTEXT_BUG=0"])

# Optimize WASM file
if env["optimize_wasm"]:
optimize_wasm_action = env.Action(run_optimize_wasm)
optimize_wasm_builder = env.Builder(action=optimize_wasm_action, suffix=".opt.wasm", src_suffix=".wasm")
env.Append(BUILDERS={"OptimizeWASM": optimize_wasm_builder})
19 changes: 18 additions & 1 deletion platform/web/emscripten_helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import json
import os
import subprocess

from SCons.Util import WhereIs
from SCons.Errors import UserError
from SCons.Util import WhereIs, splitext

from misc.utility.color import print_info
from platform_methods import get_build_version


Expand Down Expand Up @@ -127,3 +130,17 @@ def add_js_pre(env, js_pre):

def add_js_externs(env, externs):
env.Append(JS_EXTERNS=env.File(externs))


def run_optimize_wasm(target, source, env):
wasmopt_bin_path = WhereIs("wasm-opt")
if wasmopt_bin_path is None:
raise UserError('[wasm-opt] Cannot find `wasm-opt`. That binary usually comes with the "binaryen" package.')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise UserError('[wasm-opt] Cannot find `wasm-opt`. That binary usually comes with the "binaryen" package.')
raise UserError('[wasm-opt] Cannot find `wasm-opt` in `PATH`. That binary usually comes with the "binaryen" package.')


for s in source:
source_path = str(s)
target_path = splitext(source_path)[0] + ".opt.wasm"

if target_path in [str(t) for t in target]:
print_info(f"[wasm-opt] Optimizing {source_path}")
subprocess.run([wasmopt_bin_path, source_path, "-o", target_path, "-all", "--post-emscripten", "-Oz"])