Skip to content

Commit eea63b9

Browse files
committed
Update Python to 3.13.0 and add support to Windows on AMD64. Rewrite packaging of pywin32 because it is no longer shipped via separate binary installers, but has migrated to use pip.
1 parent 5e398ab commit eea63b9

File tree

7 files changed

+84
-34
lines changed

7 files changed

+84
-34
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ https://emscripten.org/docs/building_from_source/toolchain_what_is_needed.html.
6565

6666
### Linux
6767

68-
- `python`: Version 3.9.2 or above.
68+
- `python`: Version 3.13.0 or above.
6969
- `java`: For running closure compiler (optional)
7070

7171
The emsdk pre-compiled binaries are built against Ubuntu/Focal 20.04 LTS and

emsdk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88

99
# First look for python bundled in Emsdk
1010
if [ -z "$EMSDK_PYTHON" ]; then
11-
PYTHON3="$(dirname "$0")/python/3.9.2-1_64bit/bin/python3"
11+
PYTHON3="$(dirname "$0")/python/3.13.0-0_64bit/bin/python3"
12+
if [ ! -f "$PYTHON3" ]; then
13+
PYTHON3="$(dirname "$0")/python/3.9.2-1_64bit/bin/python3"
14+
fi
1215
if [ -f "$PYTHON3" ]; then
1316
EMSDK_PYTHON="$PYTHON3"
1417

emsdk.bat

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ setlocal
77
:: When using our bundled python we never want the users
88
:: PYTHONHOME or PYTHONPATH
99
:: https://github.com/emscripten-core/emsdk/issues/598
10+
11+
if exist "%~dp0python\3.13.0-0_64bit\python.exe" (
12+
set EMSDK_PY="%~dp0python\3.13.0-0_64bit\python.exe"
13+
set PYTHONHOME=
14+
set PYTHONPATH=
15+
goto end
16+
)
17+
1018
if exist "%~dp0python\3.9.2-1_64bit\python.exe" (
1119
set EMSDK_PY="%~dp0python\3.9.2-1_64bit\python.exe"
1220
set PYTHONHOME=

emsdk.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
$ScriptDirectory = Split-Path -parent $PSCommandPath
22

33
$PythonLocations = $(
4+
"python\3.13.0-0_64bit\python.exe",
45
"python\3.9.2-1_64bit\python.exe",
56
"python\3.9.2-nuget_64bit\python.exe"
67
)

emsdk.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,7 @@ def exit_with_error(msg):
143143
elif machine.endswith('86'):
144144
ARCH = 'x86'
145145
elif machine.startswith('aarch64') or machine.lower().startswith('arm64'):
146-
if WINDOWS:
147-
errlog('No support for Windows on Arm, fallback to x64')
148-
ARCH = 'x86_64'
149-
else:
150-
ARCH = 'arm64'
146+
ARCH = 'arm64'
151147
elif machine.startswith('arm'):
152148
ARCH = 'arm'
153149
else:

emsdk_manifest.json

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,44 @@
192192
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
193193
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.9/site-packages/certifi/cacert.pem"
194194
},
195+
196+
{
197+
"id": "python",
198+
"version": "3.13.0",
199+
"bitness": 64,
200+
"arch": "x86_64",
201+
"windows_url": "python-3.13.0-0-win-amd64.zip",
202+
"activated_cfg": "PYTHON='%installation_dir%/python.exe'",
203+
"activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
204+
},
205+
{
206+
"id": "python",
207+
"version": "3.13.0",
208+
"bitness": 64,
209+
"arch": "arm64",
210+
"windows_url": "python-3.13.0-0-win-arm64.zip",
211+
"activated_cfg": "PYTHON='%installation_dir%/python.exe'",
212+
"activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
213+
},
214+
{
215+
"id": "python",
216+
"version": "3.13.0",
217+
"bitness": 64,
218+
"arch": "x86_64",
219+
"macos_url": "python-3.13.0-0-macos-x86_64.tar.gz",
220+
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
221+
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.13/site-packages/certifi/cacert.pem"
222+
},
223+
{
224+
"id": "python",
225+
"version": "3.13.0",
226+
"bitness": 64,
227+
"arch": "arm64",
228+
"macos_url": "python-3.13.0-0-macos-arm64.tar.gz",
229+
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
230+
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.13/site-packages/certifi/cacert.pem"
231+
},
232+
195233
{
196234
"id": "java",
197235
"version": "8.152",
@@ -368,13 +406,13 @@
368406
{
369407
"version": "main",
370408
"bitness": 64,
371-
"uses": ["python-3.9.2-nuget-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
409+
"uses": ["python-3.13.0-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
372410
"os": "win"
373411
},
374412
{
375413
"version": "main",
376414
"bitness": 64,
377-
"uses": ["python-3.9.2-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
415+
"uses": ["python-3.13.0-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
378416
"os": "macos"
379417
},
380418
{

scripts/update_python.py

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
We only supply binaries for windows and macOS, but we do it very different ways for those two OSes.
1111
1212
Windows recipe:
13-
1. Download the "embeddable zip file" version of python from python.org
14-
2. Remove .pth file to work around https://bugs.python.org/issue34841
15-
3. Download and install pywin32 in the `site-packages` directory
16-
4. Re-zip and upload to storage.google.com
13+
1. Download precompiled version of python from NuGet package manager,
14+
either the package "python" for AMD64, or "pythonarm64" for ARM64.
15+
2. Set up pip and install pywin32 and psutil via pip for emrun to work.
16+
3. Re-zip and upload to storage.google.com
1717
1818
macOS recipe:
1919
1. Clone cpython
@@ -32,29 +32,35 @@
3232
from subprocess import check_call
3333
from zip import unzip_cmd, zip_cmd
3434

35-
version = '3.9.2'
35+
version = '3.13.0'
3636
major_minor_version = '.'.join(version.split('.')[:2]) # e.g. '3.9.2' -> '3.9'
37-
download_url = 'https://www.nuget.org/api/v2/package/python/%s' % version
3837
# This is not part of official Python version, but a repackaging number appended by emsdk
3938
# when a version of Python needs to be redownloaded.
40-
revision = '4'
39+
revision = '0'
4140

42-
pywin32_version = '227'
43-
pywin32_base = 'https://github.com/mhammond/pywin32/releases/download/b%s/' % pywin32_version
41+
PSUTIL = 'psutil==6.0.0'
4442

4543
upload_base = 'gs://webassembly/emscripten-releases-builds/deps/'
4644

4745

46+
# Detects whether current python interpreter architecture is ARM64 or AMD64
47+
# If running AMD64 python on an ARM64 Windows, this still intentionally returns AMD64
48+
def find_python_arch():
49+
import sysconfig
50+
arch = sysconfig.get_platform().lower()
51+
if 'amd64' in arch:
52+
return 'amd64'
53+
if 'arm64' in arch:
54+
return 'arm64'
55+
raise f'Unknown Python sysconfig platform "{arch}" (neither AMD64 or ARM64)'
4856

4957

5058
def make_python_patch():
51-
pywin32_filename = 'pywin32-%s.win-amd64-py%s.exe' % (pywin32_version, major_minor_version)
52-
filename = 'python-%s-amd64.zip' % (version)
53-
out_filename = 'python-%s-%s-amd64+pywin32.zip' % (version, revision)
54-
if not os.path.exists(pywin32_filename):
55-
url = pywin32_base + pywin32_filename
56-
print('Downloading pywin32: ' + url)
57-
urllib.request.urlretrieve(url, pywin32_filename)
59+
python_arch = find_python_arch()
60+
package_name = 'pythonarm64' if python_arch == 'arm64' else 'python'
61+
download_url = f'https://www.nuget.org/api/v2/package/{package_name}/{version}'
62+
filename = f'python-{version}-win-{python_arch}.zip'
63+
out_filename = f'python-{version}-{revision}-win-{python_arch}.zip'
5864

5965
if not os.path.exists(filename):
6066
print(f'Downloading python: {download_url} to {filename}')
@@ -64,19 +70,17 @@ def make_python_patch():
6470
check_call(unzip_cmd() + [os.path.abspath(filename)], cwd='python-nuget')
6571
os.remove(filename)
6672

67-
os.mkdir('pywin32')
68-
rtn = subprocess.call(unzip_cmd() + [os.path.abspath(pywin32_filename)], cwd='pywin32')
69-
assert rtn in [0, 1]
73+
src_dir = os.path.join('python-nuget', 'tools')
74+
python_exe = os.path.join(src_dir, 'python.exe')
75+
check_call([python_exe, '-m', 'ensurepip', '--upgrade'])
76+
check_call([python_exe, '-m', 'pip', 'install', 'pywin32==308'])
77+
check_call([python_exe, '-m', 'pip', 'install', PSUTIL])
7078

71-
os.mkdir(os.path.join('python-nuget', 'lib'))
72-
shutil.move(os.path.join('pywin32', 'PLATLIB'), os.path.join('python-nuget', 'toolss', 'Lib', 'site-packages'))
73-
74-
check_call(zip_cmd() + [os.path.join('..', '..', out_filename), '.'], cwd='python-nuget/tools')
79+
check_call(zip_cmd() + [os.path.join('..', '..', out_filename), '.'], cwd=src_dir)
7580
print('Created: %s' % out_filename)
7681

7782
# cleanup if everything went fine
7883
shutil.rmtree('python-nuget')
79-
shutil.rmtree('pywin32')
8084

8185
if '--upload' in sys.argv:
8286
upload_url = upload_base + out_filename
@@ -149,7 +153,7 @@ def build_python():
149153

150154
# Install psutil module. This is needed by emrun to track when browser
151155
# process quits.
152-
check_call([pybin, pip, 'install', 'psutil'])
156+
check_call([pybin, pip, 'install', PSUTIL])
153157

154158
dirname = 'python-%s-%s' % (version, revision)
155159
if os.path.isdir(dirname):

0 commit comments

Comments
 (0)