-
Notifications
You must be signed in to change notification settings - Fork 741
Update Python to 3.13.3 and add support to Windows on ARM64. #1477
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
Changes from all commits
3c557fd
4094acb
fa9280e
af5efbb
de8028e
caada17
e86a482
95c1da3
9c43206
397a9cf
a2fc7cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,6 +192,44 @@ | |
"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" | ||
}, | ||
|
||
{ | ||
"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", | ||
"version": "tag-%tag%", | ||
|
@@ -350,13 +388,13 @@ | |
{ | ||
"version": "main", | ||
"bitness": 64, | ||
"uses": ["python-3.9.2-nuget-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can also delete the python-3.9.2 entries in this file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we did that, then people cannot manually choose to install the previous python 3.9.2 to e.g. compare if updating python to 3.13.3 was the root cause of a regression. i.e. with retaining that, users can still install combinations of the individual tools that they like. |
||
"uses": ["python-3.13.3-64bit", "llvm-git-main-64bit", "node-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"], | ||
"os": "win" | ||
}, | ||
{ | ||
"version": "main", | ||
"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-20.18.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"], | ||
sbc100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"os": "macos" | ||
}, | ||
{ | ||
|
@@ -381,23 +419,23 @@ | |
{ | ||
"version": "releases-%releases-tag%", | ||
"bitness": 64, | ||
"uses": ["node-20.18.0-64bit", "python-3.9.2-64bit", "releases-%releases-tag%-64bit"], | ||
"uses": ["node-20.18.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"], | ||
"os": "macos", | ||
"arch": "x86_64", | ||
"custom_install_script": "emscripten_npm_install" | ||
}, | ||
{ | ||
"version": "releases-%releases-tag%", | ||
"bitness": 64, | ||
"uses": ["node-20.18.0-64bit", "python-3.9.2-64bit", "releases-%releases-tag%-64bit"], | ||
"uses": ["node-20.18.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"], | ||
"os": "macos", | ||
"arch": "arm64", | ||
"custom_install_script": "emscripten_npm_install" | ||
}, | ||
{ | ||
"version": "releases-%releases-tag%", | ||
"bitness": 64, | ||
"uses": ["node-20.18.0-64bit", "python-3.9.2-nuget-64bit", "releases-%releases-tag%-64bit"], | ||
"uses": ["node-20.18.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"], | ||
"os": "win", | ||
"custom_install_script": "emscripten_npm_install" | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,12 +8,13 @@ | |
http://storage.google.com/webassembly. | ||
|
||
We only supply binaries for windows and macOS, but we do it very different ways for those two OSes. | ||
juj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
On Linux, we depend on the system version of python. | ||
|
||
Windows recipe: | ||
1. Download the "embeddable zip file" version of python from python.org | ||
2. Remove .pth file to work around https://bugs.python.org/issue34841 | ||
3. Download and install pywin32 in the `site-packages` directory | ||
4. Re-zip and upload to storage.google.com | ||
1. Download precompiled version of python from NuGet package manager, | ||
either the package "python" for AMD64, or "pythonarm64" for ARM64. | ||
2. Set up pip and install pywin32 and psutil via pip for emrun to work. | ||
3. Re-zip and upload to storage.google.com | ||
|
||
macOS recipe: | ||
1. Clone cpython | ||
|
@@ -32,27 +33,35 @@ | |
from subprocess import check_call | ||
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' | ||
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 | ||
# when a version of Python needs to be redownloaded. | ||
revision = '4' | ||
revision = '0' | ||
|
||
pywin32_version = '227' | ||
pywin32_base = 'https://github.com/mhammond/pywin32/releases/download/b%s/' % pywin32_version | ||
PSUTIL = 'psutil==7.0.0' | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand the second part of this comment. Do we really want to report There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is important because if one is running an Intel x64 version of Python (e.g. under Rosetta on Mac), then So in terms of packaging, we should only report ARM64, if truly running on ARM64 version of the interpreter, to avoid any chance of mistake. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, so effectively this script cannot cross build the arm64 python package. |
||
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(): | ||
pywin32_filename = 'pywin32-%s.win-amd64-py%s.exe' % (pywin32_version, major_minor_version) | ||
filename = 'python-%s-amd64.zip' % (version) | ||
out_filename = 'python-%s-%s-amd64+pywin32.zip' % (version, revision) | ||
if not os.path.exists(pywin32_filename): | ||
url = pywin32_base + pywin32_filename | ||
print('Downloading pywin32: ' + url) | ||
urllib.request.urlretrieve(url, pywin32_filename) | ||
python_arch = find_python_arch() | ||
package_name = 'pythonarm64' if python_arch == 'arm64' else 'python' | ||
download_url = f'https://www.nuget.org/api/v2/package/{package_name}/{version}' | ||
filename = f'python-{version}-win-{python_arch}.zip' | ||
out_filename = f'python-{version}-{revision}-win-{python_arch}.zip' | ||
|
||
if not os.path.exists(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') | ||
os.remove(filename) | ||
|
||
os.mkdir('pywin32') | ||
rtn = subprocess.call(unzip_cmd() + [os.path.abspath(pywin32_filename)], cwd='pywin32') | ||
assert rtn in [0, 1] | ||
|
||
os.mkdir(os.path.join('python-nuget', 'lib')) | ||
shutil.move(os.path.join('pywin32', 'PLATLIB'), os.path.join('python-nuget', 'toolss', 'Lib', 'site-packages')) | ||
src_dir = os.path.join('python-nuget', 'tools') | ||
python_exe = os.path.join(src_dir, 'python.exe') | ||
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]) | ||
|
||
check_call(zip_cmd() + [os.path.join('..', '..', out_filename), '.'], cwd='python-nuget/tools') | ||
check_call(zip_cmd() + [os.path.join('..', '..', out_filename), '.'], cwd=src_dir) | ||
print('Created: %s' % out_filename) | ||
|
||
# cleanup if everything went fine | ||
shutil.rmtree('python-nuget') | ||
shutil.rmtree('pywin32') | ||
|
||
if '--upload' in sys.argv: | ||
upload_url = upload_base + out_filename | ||
|
@@ -92,7 +99,7 @@ def build_python(): | |
check_call(['brew', 'install', 'openssl', 'xz', 'pkg-config']) | ||
if platform.machine() == 'x86_64': | ||
prefix = '/usr/local' | ||
min_macos_version = '10.11' | ||
min_macos_version = '11.0' | ||
elif platform.machine() == 'arm64': | ||
prefix = '/opt/homebrew' | ||
min_macos_version = '11.0' | ||
|
@@ -113,7 +120,9 @@ def build_python(): | |
osname = 'linux' | ||
|
||
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', '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 | ||
# process quits. | ||
check_call([pybin, pip, 'install', 'psutil']) | ||
check_call([pybin, pip, 'install', PSUTIL]) | ||
|
||
dirname = 'python-%s-%s' % (version, revision) | ||
if os.path.isdir(dirname): | ||
|
Uh oh!
There was an error while loading. Please reload this page.