Skip to content

Commit 4958820

Browse files
authored
[3.11] gh-95853: Add script to automate WASM build (GH-95828, GH-95985, GH-96045, GH-96389, GH-96744) (GH-96749)
Automate WASM build with a new Python script. The script provides several build profiles with configure flags for Emscripten flavors and WASI. The script can detect and use Emscripten SDK and WASI SDK from default locations or env vars. ``configure`` now detects Node arguments and creates HOSTRUNNER arguments for Node 16. It also sets correct arguments for ``wasm64-emscripten``.
1 parent 390123b commit 4958820

16 files changed

+1236
-40
lines changed

Lib/distutils/tests/test_sysconfig.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def test_get_config_vars(self):
4949
self.assertIsInstance(cvars, dict)
5050
self.assertTrue(cvars)
5151

52+
@unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
5253
def test_srcdir(self):
5354
# See Issues #15322, #15364.
5455
srcdir = sysconfig.get_config_var('srcdir')

Lib/test/test_decimal.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
requires_legacy_unicode_capi, check_sanitizer)
3838
from test.support import (TestFailed,
3939
run_with_locale, cpython_only,
40-
darwin_malloc_err_warning)
40+
darwin_malloc_err_warning, is_emscripten)
4141
from test.support.import_helper import import_fresh_module
4242
from test.support import threading_helper
4343
from test.support import warnings_helper
@@ -5623,6 +5623,7 @@ def __abs__(self):
56235623
# Issue 41540:
56245624
@unittest.skipIf(sys.platform.startswith("aix"),
56255625
"AIX: default ulimit: test is flaky because of extreme over-allocation")
5626+
@unittest.skipIf(is_emscripten, "Test is unstable on Emscripten")
56265627
@unittest.skipIf(check_sanitizer(address=True, memory=True),
56275628
"ASAN/MSAN sanitizer defaults to crashing "
56285629
"instead of returning NULL for malloc failure.")

Lib/test/test_sysconfig.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ def test_platform_in_subprocess(self):
439439
self.assertEqual(status, 0)
440440
self.assertEqual(my_platform, test_platform)
441441

442+
@unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
442443
def test_srcdir(self):
443444
# See Issues #15322, #15364.
444445
srcdir = sysconfig.get_config_var('srcdir')

Lib/test/test_unicode_file_functions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import warnings
77
from unicodedata import normalize
88
from test.support import os_helper
9+
from test import support
910

1011

1112
filenames = [
@@ -123,6 +124,10 @@ def test_open(self):
123124
# NFKD in Python is useless, because darwin will normalize it later and so
124125
# open(), os.stat(), etc. don't raise any exception.
125126
@unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')
127+
@unittest.skipIf(
128+
support.is_emscripten or support.is_wasi,
129+
"test fails on Emscripten/WASI when host platform is macOS."
130+
)
126131
def test_normalize(self):
127132
files = set(self.files)
128133
others = set()

Lib/test/test_warnings/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,14 @@ def test_warn_explicit_non_ascii_filename(self):
489489
module=self.module) as w:
490490
self.module.resetwarnings()
491491
self.module.filterwarnings("always", category=UserWarning)
492-
for filename in ("nonascii\xe9\u20ac", "surrogate\udc80"):
492+
filenames = ["nonascii\xe9\u20ac"]
493+
if not support.is_emscripten:
494+
# JavaScript does not like surrogates.
495+
# Invalid UTF-8 leading byte 0x80 encountered when
496+
# deserializing a UTF-8 string in wasm memory to a JS
497+
# string!
498+
filenames.append("surrogate\udc80")
499+
for filename in filenames:
493500
try:
494501
os.fsencode(filename)
495502
except UnicodeEncodeError:

Makefile.pre.in

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,10 +817,11 @@ $(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS)
817817
# wasm assets directory is relative to current build dir, e.g. "./usr/local".
818818
# --preload-file turns a relative asset path into an absolute path.
819819

820+
.PHONY: wasm_stdlib
821+
wasm_stdlib: $(WASM_STDLIB)
820822
$(WASM_STDLIB): $(srcdir)/Lib/*.py $(srcdir)/Lib/*/*.py \
821823
$(srcdir)/Tools/wasm/wasm_assets.py \
822-
Makefile pybuilddir.txt Modules/Setup.local \
823-
python.html python.worker.js
824+
Makefile pybuilddir.txt Modules/Setup.local
824825
$(PYTHON_FOR_BUILD) $(srcdir)/Tools/wasm/wasm_assets.py \
825826
--buildroot . --prefix $(prefix)
826827

@@ -1713,6 +1714,10 @@ buildbottest: all
17131714
fi
17141715
$(TESTRUNNER) -j 1 -u all -W --slowest --fail-env-changed --timeout=$(TESTTIMEOUT) $(TESTOPTS)
17151716

1717+
# Like testall, but run Python tests with HOSTRUNNER directly.
1718+
hostrunnertest: all
1719+
$(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test -u all $(TESTOPTS)
1720+
17161721
pythoninfo: all
17171722
$(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo
17181723

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The new tool ``Tools/wasm/wasm_builder.py`` automates configure, compile, and
2+
test steps for building CPython on WebAssembly platforms.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The ``wasm_build.py`` script now pre-builds Emscripten ports, checks for
2+
broken EMSDK versions, and warns about pkg-config env vars.

Modules/pyexpat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ readinst(char *buf, int buf_size, PyObject *meth)
775775
Py_ssize_t len;
776776
const char *ptr;
777777

778-
str = PyObject_CallFunction(meth, "n", buf_size);
778+
str = PyObject_CallFunction(meth, "i", buf_size);
779779
if (str == NULL)
780780
goto error;
781781

Python/sysmodule.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,14 +2775,18 @@ EM_JS(char *, _Py_emscripten_runtime, (void), {
27752775
if (typeof navigator == 'object') {
27762776
info = navigator.userAgent;
27772777
} else if (typeof process == 'object') {
2778-
info = "Node.js ".concat(process.version)
2778+
info = "Node.js ".concat(process.version);
27792779
} else {
2780-
info = "UNKNOWN"
2780+
info = "UNKNOWN";
27812781
}
27822782
var len = lengthBytesUTF8(info) + 1;
27832783
var res = _malloc(len);
2784-
stringToUTF8(info, res, len);
2784+
if (res) stringToUTF8(info, res, len);
2785+
#if __wasm64__
2786+
return BigInt(res);
2787+
#else
27852788
return res;
2789+
#endif
27862790
});
27872791

27882792
static PyObject *

0 commit comments

Comments
 (0)