Compare commits

...

3 Commits

Author SHA1 Message Date
5d9d321695 Working wasm build! 2025-07-25 00:38:24 +04:00
456fb19829 Update emsdk 2025-07-24 23:47:27 +04:00
ddb78c3ecf Squashed 'libs/emsdk/' changes from 3bcf1dcd0..e062c54f4
e062c54f4 Add bazel feature for wasm-exceptions (#1575)
d49219d03 Release 4.0.11 (#1572)
d845e506c Fix python search path in emsdk launcher scripts (#1571)
62a853cd3 Release 4.0.10 (#1565)
2d480a1b7 Update Node.js to LTS 22.16.0. (#1563)
cfe7ccf16 Update python version note for Linux. (#1562)
d07c79341 Update Python to 3.13.3 and add support to Windows on ARM64. (#1477)

git-subtree-dir: libs/emsdk
git-subtree-split: e062c54f436e58ee102d2d37901cdaa052af249a
2025-07-24 23:47:27 +04:00
21 changed files with 231 additions and 73 deletions

View File

@ -367,7 +367,7 @@ main :: proc() {
"-sWASM_BIGINT", "-sWASM_BIGINT",
"-sWARN_ON_UNDEFINED_SYMBOLS=0", "-sWARN_ON_UNDEFINED_SYMBOLS=0",
"-sALLOW_MEMORY_GROWTH", "-sALLOW_MEMORY_GROWTH",
"-sASSERTIONS=2", // "-sASSERTIONS=2",
"--shell-file", "--shell-file",
"main_web/index_template.html", "main_web/index_template.html",
"--preload-file", "--preload-file",

View File

@ -8,7 +8,8 @@ import "core:sync"
import "libs:tracy" import "libs:tracy"
// When enabled name globals will be initialized automatically // When enabled name globals will be initialized automatically
NAME_STATIC_INIT :: #config(NAME_STATIC_INIT, true) // TODO: this breaks wasm, because it's trying to allocate something before we set up a working allocator...
NAME_STATIC_INIT :: #config(NAME_STATIC_INIT, false)
MAX_STATIC_NAMES :: #config(MAX_STATIC_NAMES, 1024) MAX_STATIC_NAMES :: #config(MAX_STATIC_NAMES, 1024)
Name :: distinct u32 Name :: distinct u32

View File

@ -126,6 +126,9 @@ world_init :: proc(world: ^World) {
physics.scene_init(&world.physics_scene, &g_mem.assetman) physics.scene_init(&world.physics_scene, &g_mem.assetman)
} }
copy_world :: proc(dst, src: ^World) { copy_world :: proc(dst, src: ^World) {
if dst == src {
return
}
copy_track(&dst.track, &src.track) copy_track(&dst.track, &src.track)
physics.copy_physics_scene(&dst.physics_scene, &src.physics_scene) physics.copy_physics_scene(&dst.physics_scene, &src.physics_scene)
scene_copy(&dst.main_scene, &src.main_scene) scene_copy(&dst.main_scene, &src.main_scene)
@ -1483,7 +1486,7 @@ game_init :: proc() {
assets.assetman_init(&g_mem.assetman) assets.assetman_init(&g_mem.assetman)
editor_state_init(&g_mem.es, 100) editor_state_init(&g_mem.es, 100)
runtime_world_init(&g_mem.runtime_world, DEV_BUILD ? 100 : 2) runtime_world_init(&g_mem.runtime_world, DEV_BUILD ? 100 : 1)
g_mem.default_font = rl.GetFontDefault() g_mem.default_font = rl.GetFontDefault()
ui.init(&g_mem.ui_context) ui.init(&g_mem.ui_context)
@ -1546,3 +1549,7 @@ game_force_reload :: proc() -> bool {
game_force_restart :: proc() -> bool { game_force_restart :: proc() -> bool {
return rl.IsKeyPressed(.F6) return rl.IsKeyPressed(.F6)
} }
game_parent_window_size_changed :: proc(w, h: int) {
rl.SetWindowSize(i32(w), i32(h))
}

View File

@ -5,6 +5,7 @@ import "core:container/bit_array"
import "core:log" import "core:log"
import "core:math" import "core:math"
import lg "core:math/linalg" import lg "core:math/linalg"
import "core:sync"
import "game:halfedge" import "game:halfedge"
import rl "libs:raylib" import rl "libs:raylib"
import "libs:raylib/rlgl" import "libs:raylib/rlgl"
@ -37,8 +38,10 @@ box_mesh: Convex
@(private = "file") @(private = "file")
triangle_mesh: Convex triangle_mesh: Convex
@(init) @(private = "file")
init_box_mesh :: proc() { init_globals_once: sync.Once
init_globals :: proc() {
box_mesh = Convex(halfedge.mesh_from_vertex_index_list(box_corners_norm[:], box_indices[:], 4)) box_mesh = Convex(halfedge.mesh_from_vertex_index_list(box_corners_norm[:], box_indices[:], 4))
triangle_mesh = Convex( triangle_mesh = Convex(
@ -50,14 +53,16 @@ init_box_mesh :: proc() {
) )
} }
@(fini) // @(fini)
deinit_box_mesh :: proc() { // deinit_box_mesh :: proc() {
delete(box_mesh.vertices) // delete(box_mesh.vertices)
delete(box_mesh.faces) // delete(box_mesh.faces)
delete(box_mesh.edges) // delete(box_mesh.edges)
} // }
box_to_convex :: proc(box: Box, allocator := context.allocator) -> (convex: Convex) { box_to_convex :: proc(box: Box, allocator := context.allocator) -> (convex: Convex) {
sync.once_do(&init_globals_once, init_globals)
convex = halfedge.copy_mesh(box_mesh, allocator) convex = halfedge.copy_mesh(box_mesh, allocator)
for &v in convex.vertices { for &v in convex.vertices {
@ -73,6 +78,8 @@ double_sided_triangle_to_convex :: proc(
) -> ( ) -> (
convex: Convex, convex: Convex,
) { ) {
sync.once_do(&init_globals_once, init_globals)
convex = halfedge.copy_mesh(triangle_mesh, allocator) convex = halfedge.copy_mesh(triangle_mesh, allocator)
convex.vertices[0].pos = tri[0] convex.vertices[0].pos = tri[0]
convex.vertices[1].pos = tri[1] convex.vertices[1].pos = tri[1]

View File

@ -121,15 +121,21 @@ Sim_State :: struct {
dynamic_tlas: Dynamic_TLAS, dynamic_tlas: Dynamic_TLAS,
} }
DEV_BUILD :: #config(DEV, false)
NUM_SIM_STATES :: 2 when DEV_BUILD else 1
Scene :: struct { Scene :: struct {
assetman: ^assets.Asset_Manager, assetman: ^assets.Asset_Manager,
simulation_states: [2]Sim_State, simulation_states: [NUM_SIM_STATES]Sim_State,
simulation_state_index: i32, simulation_state_index: i32,
solver_state: Solver_State, solver_state: Solver_State,
} }
// Copy current state to next // Copy current state to next
copy_sim_state :: proc(dst: ^Sim_State, src: ^Sim_State) { copy_sim_state :: proc(dst: ^Sim_State, src: ^Sim_State) {
if dst == src {
return
}
tracy.Zone() tracy.Zone()
convex_container_reconcile(&src.convex_container) convex_container_reconcile(&src.convex_container)
@ -176,8 +182,9 @@ copy_physics_scene :: proc(dst, src: ^Scene) {
dst.assetman = src.assetman dst.assetman = src.assetman
dst.simulation_state_index = src.simulation_state_index dst.simulation_state_index = src.simulation_state_index
copy_sim_state(&dst.simulation_states[0], &src.simulation_states[0]) for i in 0 ..< NUM_SIM_STATES {
copy_sim_state(&dst.simulation_states[1], &src.simulation_states[1]) copy_sim_state(&dst.simulation_states[i], &src.simulation_states[i])
}
copy_solver_state(&dst.solver_state, &src.solver_state) copy_solver_state(&dst.solver_state, &src.solver_state)
} }

View File

@ -65,7 +65,7 @@ https://emscripten.org/docs/building_from_source/toolchain_what_is_needed.html.
### Linux ### Linux
- `python`: Version 3.9.2 or above. - `python`: Version 3.8 or above.
- `java`: For running closure compiler (optional) - `java`: For running closure compiler (optional)
The emsdk pre-compiled binaries are built against Ubuntu/Focal 20.04 LTS and The emsdk pre-compiled binaries are built against Ubuntu/Focal 20.04 LTS and

View File

@ -1,6 +1,6 @@
module( module(
name = "emsdk", name = "emsdk",
version = "4.0.9", version = "4.0.11",
) )
bazel_dep(name = "platforms", version = "0.0.11") bazel_dep(name = "platforms", version = "0.0.11")

View File

@ -363,6 +363,9 @@ def _impl(ctx):
# Set if enabling exceptions. # Set if enabling exceptions.
feature(name = "exceptions"), feature(name = "exceptions"),
# Set if enabling wasm_exceptions.
feature(name = "wasm_exceptions"),
# This feature overrides the default optimization to prefer execution speed # This feature overrides the default optimization to prefer execution speed
# over binary size (like clang -O3). # over binary size (like clang -O3).
feature( feature(
@ -515,7 +518,7 @@ def _impl(ctx):
flags = [ flags = [
"-fno-exceptions", "-fno-exceptions",
], ],
not_features = ["exceptions"], not_features = ["exceptions", "wasm_exceptions"],
), ),
flag_set( flag_set(
actions = all_cpp_compile_actions, actions = all_cpp_compile_actions,
@ -524,6 +527,14 @@ def _impl(ctx):
], ],
features = ["exceptions"], features = ["exceptions"],
), ),
flag_set(
actions = all_cpp_compile_actions +
all_link_actions,
flags = [
"-fwasm-exceptions",
],
features = ["wasm_exceptions"],
),
# All compiles (and implicitly link) # All compiles (and implicitly link)
flag_set( flag_set(
actions = all_compile_actions + actions = all_compile_actions +

View File

@ -2,6 +2,22 @@
# DO NOT MODIFY # DO NOT MODIFY
EMSCRIPTEN_TAGS = { EMSCRIPTEN_TAGS = {
"4.0.11": struct(
hash = "7033fec38817ec01909b044ea0193ddd5057255c",
sha_linux = "f38e70b53be587e7c757f375b3452e259c70130d4b40db3213c95b7ae321f5d7",
sha_linux_arm64 = "42020e4db200ac366a3e91ac2fccc04ee0ffc090cd2d5986c892b27f39172bb9",
sha_mac = "4169811f9682f54ae5c9d0662d0a4dd4318abab5d3d0473fa54007f515a8cdea",
sha_mac_arm64 = "09554371e3941306d047d67618532e5366ba6c9b5bda1a504a917bfbabc5d414",
sha_win = "bd2094ca9bde5df25020a46ece7f56b622d1d22214fbd12950b01b952dd40084",
),
"4.0.10": struct(
hash = "8103ffedfb0c42d231c6af6859a5a1a832260b43",
sha_linux = "0183f887b56c3f8d4b45826cb49856a3324afb66236ad3c13944c0fd2550cbbc",
sha_linux_arm64 = "0679f459118d80163d0712b0abda00cbc97a90cddf1dcefa9efb1bf89f67baed",
sha_mac = "02f3179f703b4d196a679897b430c1eeeb1d5f9aeba9b435b04ba3f526f7e8e0",
sha_mac_arm64 = "c744ffe06ffed55cd8dae42862b7646f15550c7decd47a48d09a474af83732b0",
sha_win = "1a66825e85fda039f57d39c98ae2bdb96a18e53745159e9599f69679be18439f",
),
"4.0.9": struct( "4.0.9": struct(
hash = "cb2a69bce627bd2247624c71fc12907cb8785d2f", hash = "cb2a69bce627bd2247624c71fc12907cb8785d2f",
sha_linux = "c6fd245138e6bbdd8349963cb4045c557d657e4be0ea44155375633c689c8be9", sha_linux = "c6fd245138e6bbdd8349963cb4045c557d657e4be0ea44155375633c689c8be9",

View File

@ -19,6 +19,7 @@ emscripten_cache.targets(targets = [
"libdlmalloc", "libdlmalloc",
"libcompiler_rt", "libcompiler_rt",
"libc++-noexcept", "libc++-noexcept",
"libc++-debug-noexcept",
"libc++abi-debug-noexcept", "libc++abi-debug-noexcept",
"libsockets", "libsockets",
"libdlmalloc-debug", "libdlmalloc-debug",

View File

@ -63,7 +63,7 @@ COPY --from=stage_build /emsdk /emsdk
# using `--entrypoint /bin/bash` in CLI). # using `--entrypoint /bin/bash` in CLI).
# This corresponds to the env variables set during: `source ./emsdk_env.sh` # This corresponds to the env variables set during: `source ./emsdk_env.sh`
ENV EMSDK=/emsdk \ ENV EMSDK=/emsdk \
PATH="/emsdk:/emsdk/upstream/emscripten:/emsdk/node/20.18.0_64bit/bin:${PATH}" PATH="/emsdk:/emsdk/upstream/emscripten:/emsdk/node/22.16.0_64bit/bin:${PATH}"
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Create a 'standard` 1000:1000 user # Create a 'standard` 1000:1000 user

View File

@ -1,6 +1,6 @@
{ {
"aliases": { "aliases": {
"latest": "4.0.9", "latest": "4.0.11",
"latest-sdk": "latest", "latest-sdk": "latest",
"latest-arm64-linux": "latest", "latest-arm64-linux": "latest",
"latest-64bit": "latest", "latest-64bit": "latest",
@ -10,6 +10,10 @@
"latest-releases-upstream": "latest" "latest-releases-upstream": "latest"
}, },
"releases": { "releases": {
"4.0.11": "7033fec38817ec01909b044ea0193ddd5057255c",
"4.0.11-asserts": "0eacb0d6",
"4.0.10": "8103ffedfb0c42d231c6af6859a5a1a832260b43",
"4.0.10-asserts": "ccf48a673362f11ddb6c3656405bb6a03b344052",
"4.0.9": "cb2a69bce627bd2247624c71fc12907cb8785d2f", "4.0.9": "cb2a69bce627bd2247624c71fc12907cb8785d2f",
"4.0.9-asserts": "27f1e0801c6ec5ea4d9a9e1d573eb1fead3525f1", "4.0.9-asserts": "27f1e0801c6ec5ea4d9a9e1d573eb1fead3525f1",
"4.0.8": "56f86607aeb458086e72f23188789be2ee0e971a", "4.0.8": "56f86607aeb458086e72f23188789be2ee0e971a",

View File

@ -8,7 +8,10 @@
# First look for python bundled in Emsdk # First look for python bundled in Emsdk
if [ -z "$EMSDK_PYTHON" ]; then if [ -z "$EMSDK_PYTHON" ]; then
PYTHON3="$(dirname "$0")/python/3.9.2-1_64bit/bin/python3" PYTHON3="$(dirname "$0")/python/3.13.3_64bit/bin/python3"
if [ ! -f "$PYTHON3" ]; then
PYTHON3="$(dirname "$0")/python/3.9.2_64bit/bin/python3"
fi
if [ -f "$PYTHON3" ]; then if [ -f "$PYTHON3" ]; then
EMSDK_PYTHON="$PYTHON3" EMSDK_PYTHON="$PYTHON3"

View File

@ -7,8 +7,16 @@ setlocal
:: When using our bundled python we never want the users :: When using our bundled python we never want the users
:: PYTHONHOME or PYTHONPATH :: PYTHONHOME or PYTHONPATH
:: https://github.com/emscripten-core/emsdk/issues/598 :: https://github.com/emscripten-core/emsdk/issues/598
if exist "%~dp0python\3.9.2-1_64bit\python.exe" (
set EMSDK_PY="%~dp0python\3.9.2-1_64bit\python.exe" if exist "%~dp0python\3.13.3_64bit\python.exe" (
set EMSDK_PY="%~dp0python\3.13.3_64bit\python.exe"
set PYTHONHOME=
set PYTHONPATH=
goto end
)
if exist "%~dp0python\3.9.2_64bit\python.exe" (
set EMSDK_PY="%~dp0python\3.9.2_64bit\python.exe"
set PYTHONHOME= set PYTHONHOME=
set PYTHONPATH= set PYTHONPATH=
goto end goto end

View File

@ -1,6 +1,7 @@
$ScriptDirectory = Split-Path -parent $PSCommandPath $ScriptDirectory = Split-Path -parent $PSCommandPath
$PythonLocations = $( $PythonLocations = $(
"python\3.13.3-0_64bit\python.exe",
"python\3.9.2-1_64bit\python.exe", "python\3.9.2-1_64bit\python.exe",
"python\3.9.2-nuget_64bit\python.exe" "python\3.9.2-nuget_64bit\python.exe"
) )

View File

@ -143,10 +143,6 @@ if machine.startswith('x64') or machine.startswith('amd64') or machine.startswit
elif machine.endswith('86'): elif machine.endswith('86'):
ARCH = 'x86' ARCH = 'x86'
elif machine.startswith('aarch64') or machine.lower().startswith('arm64'): elif machine.startswith('aarch64') or machine.lower().startswith('arm64'):
if WINDOWS:
errlog('No support for Windows on Arm, fallback to x64')
ARCH = 'x86_64'
else:
ARCH = 'arm64' ARCH = 'arm64'
elif machine.startswith('arm'): elif machine.startswith('arm'):
ARCH = 'arm' ARCH = 'arm'
@ -988,17 +984,16 @@ def cmake_configure(generator, build_root, src_root, build_type, extra_cmake_arg
generator = [] generator = []
cmdline = ['cmake'] + generator + ['-DCMAKE_BUILD_TYPE=' + build_type, '-DPYTHON_EXECUTABLE=' + sys.executable] cmdline = ['cmake'] + generator + ['-DCMAKE_BUILD_TYPE=' + build_type, '-DPYTHON_EXECUTABLE=' + sys.executable]
# Target macOS 10.14 at minimum, to support widest range of Mac devices # Target macOS 11.0 Big Sur at minimum, to support older Mac devices.
# from "Early 2008" and newer: # See https://en.wikipedia.org/wiki/MacOS#Hardware_compatibility for min-spec details.
# https://en.wikipedia.org/wiki/MacBook_(2006-2012)#Supported_operating_systems cmdline += ['-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0']
cmdline += ['-DCMAKE_OSX_DEPLOYMENT_TARGET=10.14']
cmdline += extra_cmake_args + [src_root] cmdline += extra_cmake_args + [src_root]
print('Running CMake: ' + str(cmdline)) print('Running CMake: ' + str(cmdline))
# Specify the deployment target also as an env. var, since some Xcode versions # Specify the deployment target also as an env. var, since some Xcode versions
# read this instead of the CMake field. # read this instead of the CMake field.
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.14' os.environ['MACOSX_DEPLOYMENT_TARGET'] = '11.0'
def quote_parens(x): def quote_parens(x):
if ' ' in x: if ' ' in x:

View File

@ -156,6 +156,56 @@
}, },
{
"id": "node",
"version": "22.16.0",
"bitness": 32,
"arch": "x86",
"windows_url": "node-v22.16.0-win-x86.zip",
"activated_path": "%installation_dir%/bin",
"activated_path_skip": "node",
"activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
"activated_env": "EMSDK_NODE=%installation_dir%/bin/node%.exe%"
},
{
"id": "node",
"version": "22.16.0",
"arch": "arm",
"bitness": 32,
"linux_url": "node-v22.16.0-linux-armv7l.tar.xz",
"activated_path": "%installation_dir%/bin",
"activated_path_skip": "node",
"activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
"activated_env": "EMSDK_NODE=%installation_dir%/bin/node%.exe%"
},
{
"id": "node",
"version": "22.16.0",
"bitness": 64,
"arch": "x86_64",
"windows_url": "node-v22.16.0-win-x64.zip",
"macos_url": "node-v22.16.0-darwin-x64.tar.gz",
"linux_url": "node-v22.16.0-linux-x64.tar.xz",
"activated_path": "%installation_dir%/bin",
"activated_path_skip": "node",
"activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
"activated_env": "EMSDK_NODE=%installation_dir%/bin/node%.exe%"
},
{
"id": "node",
"version": "22.16.0",
"arch": "arm64",
"bitness": 64,
"windows_url": "node-v22.16.0-win-arm64.zip",
"macos_url": "node-v22.16.0-darwin-arm64.tar.gz",
"linux_url": "node-v22.16.0-linux-arm64.tar.xz",
"activated_path": "%installation_dir%/bin",
"activated_path_skip": "node",
"activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
"activated_env": "EMSDK_NODE=%installation_dir%/bin/node%.exe%"
},
{ {
"id": "python", "id": "python",
"version": "3.9.2-nuget", "version": "3.9.2-nuget",
@ -192,6 +242,44 @@
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'", "activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.9/site-packages/certifi/cacert.pem" "activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.9/site-packages/certifi/cacert.pem"
}, },
{
"id": "python",
"version": "3.13.3",
"bitness": 64,
"arch": "x86_64",
"windows_url": "python-3.13.3-0-win-amd64.zip",
"activated_cfg": "PYTHON='%installation_dir%/python.exe'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
},
{
"id": "python",
"version": "3.13.3",
"bitness": 64,
"arch": "arm64",
"windows_url": "python-3.13.3-0-win-arm64.zip",
"activated_cfg": "PYTHON='%installation_dir%/python.exe'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
},
{
"id": "python",
"version": "3.13.3",
"bitness": 64,
"arch": "x86_64",
"macos_url": "python-3.13.3-0-macos-x86_64.tar.gz",
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.13/site-packages/certifi/cacert.pem"
},
{
"id": "python",
"version": "3.13.3",
"bitness": 64,
"arch": "arm64",
"macos_url": "python-3.13.3-0-macos-arm64.tar.gz",
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.13/site-packages/certifi/cacert.pem"
},
{ {
"id": "emscripten", "id": "emscripten",
"version": "tag-%tag%", "version": "tag-%tag%",
@ -350,19 +438,19 @@
{ {
"version": "main", "version": "main",
"bitness": 64, "bitness": 64,
"uses": ["python-3.9.2-nuget-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"], "uses": ["python-3.13.3-64bit", "llvm-git-main-64bit", "node-22.16.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
"os": "win" "os": "win"
}, },
{ {
"version": "main", "version": "main",
"bitness": 64, "bitness": 64,
"uses": ["python-3.9.2-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"], "uses": ["python-3.13.3-64bit", "llvm-git-main-64bit", "node-22.16.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
"os": "macos" "os": "macos"
}, },
{ {
"version": "main", "version": "main",
"bitness": 64, "bitness": 64,
"uses": ["llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"], "uses": ["llvm-git-main-64bit", "node-22.16.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
"os": "linux" "os": "linux"
}, },
{ {
@ -374,14 +462,14 @@
{ {
"version": "releases-%releases-tag%", "version": "releases-%releases-tag%",
"bitness": 64, "bitness": 64,
"uses": ["node-20.18.0-64bit", "releases-%releases-tag%-64bit"], "uses": ["node-22.16.0-64bit", "releases-%releases-tag%-64bit"],
"os": "linux", "os": "linux",
"custom_install_script": "emscripten_npm_install" "custom_install_script": "emscripten_npm_install"
}, },
{ {
"version": "releases-%releases-tag%", "version": "releases-%releases-tag%",
"bitness": 64, "bitness": 64,
"uses": ["node-20.18.0-64bit", "python-3.9.2-64bit", "releases-%releases-tag%-64bit"], "uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
"os": "macos", "os": "macos",
"arch": "x86_64", "arch": "x86_64",
"custom_install_script": "emscripten_npm_install" "custom_install_script": "emscripten_npm_install"
@ -389,7 +477,7 @@
{ {
"version": "releases-%releases-tag%", "version": "releases-%releases-tag%",
"bitness": 64, "bitness": 64,
"uses": ["node-20.18.0-64bit", "python-3.9.2-64bit", "releases-%releases-tag%-64bit"], "uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
"os": "macos", "os": "macos",
"arch": "arm64", "arch": "arm64",
"custom_install_script": "emscripten_npm_install" "custom_install_script": "emscripten_npm_install"
@ -397,7 +485,7 @@
{ {
"version": "releases-%releases-tag%", "version": "releases-%releases-tag%",
"bitness": 64, "bitness": 64,
"uses": ["node-20.18.0-64bit", "python-3.9.2-nuget-64bit", "releases-%releases-tag%-64bit"], "uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
"os": "win", "os": "win",
"custom_install_script": "emscripten_npm_install" "custom_install_script": "emscripten_npm_install"
} }

View File

@ -18,8 +18,8 @@ import os
import shutil import shutil
from zip import unzip_cmd, zip_cmd from zip import unzip_cmd, zip_cmd
version = '20.18.0' version = '22.16.0'
base = 'https://nodejs.org/dist/v20.18.0/' base = f'https://nodejs.org/dist/v{version}/'
upload_base = 'gs://webassembly/emscripten-releases-builds/deps/' upload_base = 'gs://webassembly/emscripten-releases-builds/deps/'
suffixes = [ suffixes = [

View File

@ -8,12 +8,13 @@
http://storage.google.com/webassembly. http://storage.google.com/webassembly.
We only supply binaries for windows and macOS, but we do it very different ways for those two OSes. We only supply binaries for windows and macOS, but we do it very different ways for those two OSes.
On Linux, we depend on the system version of python.
Windows recipe: Windows recipe:
1. Download the "embeddable zip file" version of python from python.org 1. Download precompiled version of python from NuGet package manager,
2. Remove .pth file to work around https://bugs.python.org/issue34841 either the package "python" for AMD64, or "pythonarm64" for ARM64.
3. Download and install pywin32 in the `site-packages` directory 2. Set up pip and install pywin32 and psutil via pip for emrun to work.
4. Re-zip and upload to storage.google.com 3. Re-zip and upload to storage.google.com
macOS recipe: macOS recipe:
1. Clone cpython 1. Clone cpython
@ -32,27 +33,35 @@ import sys
from subprocess import check_call from subprocess import check_call
from zip import unzip_cmd, zip_cmd from zip import unzip_cmd, zip_cmd
version = '3.9.2' version = '3.13.3'
major_minor_version = '.'.join(version.split('.')[:2]) # e.g. '3.9.2' -> '3.9' major_minor_version = '.'.join(version.split('.')[:2]) # e.g. '3.9.2' -> '3.9'
download_url = 'https://www.nuget.org/api/v2/package/python/%s' % version
# This is not part of official Python version, but a repackaging number appended by emsdk # This is not part of official Python version, but a repackaging number appended by emsdk
# when a version of Python needs to be redownloaded. # when a version of Python needs to be redownloaded.
revision = '4' revision = '0'
pywin32_version = '227' PSUTIL = 'psutil==7.0.0'
pywin32_base = 'https://github.com/mhammond/pywin32/releases/download/b%s/' % pywin32_version
upload_base = 'gs://webassembly/emscripten-releases-builds/deps/' upload_base = 'gs://webassembly/emscripten-releases-builds/deps/'
# Detects whether current python interpreter architecture is ARM64 or AMD64
# If running AMD64 python on an ARM64 Windows, this still intentionally returns AMD64
def find_python_arch():
import sysconfig
arch = sysconfig.get_platform().lower()
if 'amd64' in arch:
return 'amd64'
if 'arm64' in arch:
return 'arm64'
raise f'Unknown Python sysconfig platform "{arch}" (neither AMD64 or ARM64)'
def make_python_patch(): def make_python_patch():
pywin32_filename = 'pywin32-%s.win-amd64-py%s.exe' % (pywin32_version, major_minor_version) python_arch = find_python_arch()
filename = 'python-%s-amd64.zip' % (version) package_name = 'pythonarm64' if python_arch == 'arm64' else 'python'
out_filename = 'python-%s-%s-amd64+pywin32.zip' % (version, revision) download_url = f'https://www.nuget.org/api/v2/package/{package_name}/{version}'
if not os.path.exists(pywin32_filename): filename = f'python-{version}-win-{python_arch}.zip'
url = pywin32_base + pywin32_filename out_filename = f'python-{version}-{revision}-win-{python_arch}.zip'
print('Downloading pywin32: ' + url)
urllib.request.urlretrieve(url, pywin32_filename)
if not os.path.exists(filename): if not os.path.exists(filename):
print(f'Downloading python: {download_url} to {filename}') print(f'Downloading python: {download_url} to {filename}')
@ -62,19 +71,17 @@ def make_python_patch():
check_call(unzip_cmd() + [os.path.abspath(filename)], cwd='python-nuget') check_call(unzip_cmd() + [os.path.abspath(filename)], cwd='python-nuget')
os.remove(filename) os.remove(filename)
os.mkdir('pywin32') src_dir = os.path.join('python-nuget', 'tools')
rtn = subprocess.call(unzip_cmd() + [os.path.abspath(pywin32_filename)], cwd='pywin32') python_exe = os.path.join(src_dir, 'python.exe')
assert rtn in [0, 1] check_call([python_exe, '-m', 'ensurepip', '--upgrade'])
check_call([python_exe, '-m', 'pip', 'install', 'pywin32==310', '--no-warn-script-location'])
check_call([python_exe, '-m', 'pip', 'install', PSUTIL])
os.mkdir(os.path.join('python-nuget', 'lib')) check_call(zip_cmd() + [os.path.join('..', '..', out_filename), '.'], cwd=src_dir)
shutil.move(os.path.join('pywin32', 'PLATLIB'), os.path.join('python-nuget', 'toolss', 'Lib', 'site-packages'))
check_call(zip_cmd() + [os.path.join('..', '..', out_filename), '.'], cwd='python-nuget/tools')
print('Created: %s' % out_filename) print('Created: %s' % out_filename)
# cleanup if everything went fine # cleanup if everything went fine
shutil.rmtree('python-nuget') shutil.rmtree('python-nuget')
shutil.rmtree('pywin32')
if '--upload' in sys.argv: if '--upload' in sys.argv:
upload_url = upload_base + out_filename upload_url = upload_base + out_filename
@ -92,7 +99,7 @@ def build_python():
check_call(['brew', 'install', 'openssl', 'xz', 'pkg-config']) check_call(['brew', 'install', 'openssl', 'xz', 'pkg-config'])
if platform.machine() == 'x86_64': if platform.machine() == 'x86_64':
prefix = '/usr/local' prefix = '/usr/local'
min_macos_version = '10.11' min_macos_version = '11.0'
elif platform.machine() == 'arm64': elif platform.machine() == 'arm64':
prefix = '/opt/homebrew' prefix = '/opt/homebrew'
min_macos_version = '11.0' min_macos_version = '11.0'
@ -113,7 +120,9 @@ def build_python():
osname = 'linux' osname = 'linux'
src_dir = 'cpython' src_dir = 'cpython'
if not os.path.exists(src_dir): if os.path.exists(src_dir):
check_call(['git', 'fetch'], cwd=src_dir)
else:
check_call(['git', 'clone', 'https://github.com/python/cpython']) check_call(['git', 'clone', 'https://github.com/python/cpython'])
check_call(['git', 'checkout', 'v' + version], cwd=src_dir) check_call(['git', 'checkout', 'v' + version], cwd=src_dir)
@ -143,7 +152,7 @@ def build_python():
# Install psutil module. This is needed by emrun to track when browser # Install psutil module. This is needed by emrun to track when browser
# process quits. # process quits.
check_call([pybin, pip, 'install', 'psutil']) check_call([pybin, pip, 'install', PSUTIL])
dirname = 'python-%s-%s' % (version, revision) dirname = 'python-%s-%s' % (version, revision)
if os.path.isdir(dirname): if os.path.isdir(dirname):

View File

@ -176,9 +176,9 @@ int main() {
# Test the normal tools like node don't re-download on re-install # Test the normal tools like node don't re-download on re-install
print('another install must re-download') print('another install must re-download')
checked_call_with_output(emsdk + ' uninstall node-20.18.0-64bit') checked_call_with_output(emsdk + ' uninstall node-22.16.0-64bit')
checked_call_with_output(emsdk + ' install node-20.18.0-64bit', expected='Downloading:', unexpected='already installed') checked_call_with_output(emsdk + ' install node-22.16.0-64bit', expected='Downloading:', unexpected='already installed')
checked_call_with_output(emsdk + ' install node-20.18.0-64bit', unexpected='Downloading:', expected='already installed') checked_call_with_output(emsdk + ' install node-22.16.0-64bit', unexpected='Downloading:', expected='already installed')
def test_tot_upstream(self): def test_tot_upstream(self):
print('test update-tags') print('test update-tags')

View File

@ -25,7 +25,7 @@ main_start :: proc "c" () {
// Since we now use js_wasm32 we should be able to remove this and use // Since we now use js_wasm32 we should be able to remove this and use
// context.logger = log.create_console_logger(). However, that one produces // context.logger = log.create_console_logger(). However, that one produces
// extra newlines on web. So it's a bug in that core lib. // extra newlines on web. So it's a bug in that core lib.
// context.logger = create_emscripten_logger() context.logger = create_emscripten_logger()
web_context = context web_context = context
@ -49,5 +49,5 @@ main_end :: proc "c" () {
@(export) @(export)
web_window_size_changed :: proc "c" (w: c.int, h: c.int) { web_window_size_changed :: proc "c" (w: c.int, h: c.int) {
context = web_context context = web_context
// game.game_parent_window_size_changed(int(w), int(h)) game.game_parent_window_size_changed(int(w), int(h))
} }