Use bundled/embedded python3 binary on OSX (#561)

See https://github.com/emscripten-core/emscripten/issues/7198
This commit is contained in:
Sam Clegg
2020-07-21 10:21:02 -07:00
committed by GitHub
parent d8984b2a9d
commit 4aa028017c
5 changed files with 78 additions and 29 deletions

View File

@@ -54,9 +54,6 @@ jobs:
- run: - run:
name: Install cmake name: Install cmake
command: brew install cmake command: brew install cmake
- run:
name: Install python 3
command: brew install python3
- run: scripts/test.sh - run: scripts/test.sh
- run: - run:
name: test.py name: test.py

16
emsdk
View File

@@ -6,13 +6,13 @@
# Wrapper script that runs emsdk.py # Wrapper script that runs emsdk.py
base_dir=$(dirname "$0") if [ -z "$EMSDK_PYTHON" ]; then
# Look for python3 first. This is especially important on macOS (See:
# Look for python3 first. This is especially important on macOS (See: # https://github.com/emscripten-core/emsdk/pull/273)
# https://github.com/emscripten-core/emsdk/pull/273) EMSDK_PYTHON=$(which python3 2> /dev/null)
python=$(which python3 2> /dev/null) if [ $? != 0 ]; then
if [ $? != 0 ]; then EMSDK_PYTHON=python
python=python fi
fi fi
exec "$python" "$0.py" "$@" exec "$EMSDK_PYTHON" "$0.py" "$@"

View File

@@ -288,6 +288,16 @@
"activated_cfg": "PYTHON='%installation_dir%/python.exe'", "activated_cfg": "PYTHON='%installation_dir%/python.exe'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe" "activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
}, },
{
"id": "python",
"version": "3.7.4",
"bitness": 64,
"arch": "x86_64",
"osx_url": "python-3.7.4-macos.tar.gz",
"activated_path": "%installation_dir%/bin",
"activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
"activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3"
},
{ {
"id": "java", "id": "java",
"version": "8.152", "version": "8.152",
@@ -475,7 +485,7 @@
{ {
"version": "upstream-master", "version": "upstream-master",
"bitness": 64, "bitness": 64,
"uses": ["llvm-git-master-64bit", "node-12.18.1-64bit", "emscripten-master-64bit", "binaryen-master-64bit"], "uses": ["llvm-git-master-64bit", "node-12.18.1-64bit", "python-3.7.4-64bit", "emscripten-master-64bit", "binaryen-master-64bit"],
"os": "osx" "os": "osx"
}, },
{ {
@@ -505,7 +515,7 @@
{ {
"version": "fastcomp-master", "version": "fastcomp-master",
"bitness": 64, "bitness": 64,
"uses": ["fastcomp-clang-master-64bit", "node-12.18.1-64bit", "emscripten-master-64bit", "binaryen-master-64bit"], "uses": ["fastcomp-clang-master-64bit", "node-12.18.1-64bit", "python-3.7.4-64bit", "emscripten-master-64bit", "binaryen-master-64bit"],
"os": "osx" "os": "osx"
}, },
{ {
@@ -566,7 +576,7 @@
{ {
"version": "releases-upstream-%releases-tag%", "version": "releases-upstream-%releases-tag%",
"bitness": 64, "bitness": 64,
"uses": ["node-12.18.1-64bit", "releases-upstream-%releases-tag%-64bit"], "uses": ["node-12.18.1-64bit", "python-3.7.4-64bit", "releases-upstream-%releases-tag%-64bit"],
"os": "osx", "os": "osx",
"custom_install_script": "emscripten_npm_install" "custom_install_script": "emscripten_npm_install"
}, },
@@ -587,7 +597,7 @@
{ {
"version": "releases-fastcomp-%releases-tag%", "version": "releases-fastcomp-%releases-tag%",
"bitness": 64, "bitness": 64,
"uses": ["node-12.18.1-64bit", "releases-fastcomp-%releases-tag%-64bit"], "uses": ["node-12.18.1-64bit", "python-3.7.4-64bit", "releases-fastcomp-%releases-tag%-64bit"],
"os": "osx", "os": "osx",
"custom_install_script": "emscripten_npm_install" "custom_install_script": "emscripten_npm_install"
}, },
@@ -637,7 +647,7 @@
{ {
"version": "fastcomp-%precompiled_tag32%", "version": "fastcomp-%precompiled_tag32%",
"bitness": 32, "bitness": 32,
"uses": ["fastcomp-clang-e%precompiled_tag32%-32bit", "node-8.9.1-32bit", "emscripten-%precompiled_tag32%"], "uses": ["fastcomp-clang-e%precompiled_tag32%-32bit", "node-8.9.1-32bit", "python-3.7.4-64bit", "emscripten-%precompiled_tag32%"],
"os": "osx", "os": "osx",
"version_filter": [ "version_filter": [
["%precompiled_tag32%", ">", "1.37.22"] ["%precompiled_tag32%", ">", "1.37.22"]
@@ -646,7 +656,7 @@
{ {
"version": "fastcomp-%precompiled_tag64%", "version": "fastcomp-%precompiled_tag64%",
"bitness": 64, "bitness": 64,
"uses": ["fastcomp-clang-e%precompiled_tag64%-64bit", "node-8.9.1-64bit", "emscripten-%precompiled_tag64%"], "uses": ["fastcomp-clang-e%precompiled_tag64%-64bit", "node-8.9.1-64bit", "python-3.7.4-64bit", "emscripten-%precompiled_tag64%"],
"os": "osx", "os": "osx",
"version_filter": [ "version_filter": [
["%precompiled_tag64%", ">", "1.37.22"] ["%precompiled_tag64%", ">", "1.37.22"]

View File

@@ -8,4 +8,7 @@ set -e
./emsdk install latest ./emsdk install latest
./emsdk activate latest ./emsdk activate latest
source ./emsdk_env.sh --build=Release source ./emsdk_env.sh --build=Release
# On mac and windows python3 should be in the path and point to the
# bundled version.
which python3
emcc -v emcc -v

View File

@@ -7,22 +7,28 @@
"""Updates the python binaries that we cache store at """Updates the python binaries that we cache store at
http://storage.google.com/webassembly. http://storage.google.com/webassembly.
Currently this is windows only and we rely on the system python on other We only supply binaries for windows and macOS, but we do it very different ways for those two OSes.
platforms.
We currently bundle a version of python for windows use the following Windows recipe:
recipe:
1. Download the "embeddable zip file" version of python from python.org 1. Download the "embeddable zip file" version of python from python.org
2. Remove .pth file to work around https://bugs.python.org/issue34841 2. Remove .pth file to work around https://bugs.python.org/issue34841
3. Download and install pywin32 in the `site-packages` directory 3. Download and install pywin32 in the `site-packages` directory
4. Re-zip and upload to storage.google.com 4. Re-zip and upload to storage.google.com
macOS recipe:
1. Clone cpython
2. Use homebrew to install and configure openssl (for static linking!)
3. Build cpython from source and use `make install` to create archive.
""" """
import urllib.request import glob
import subprocess import multiprocessing
import os import os
import urllib.request
import shutil import shutil
import subprocess
import sys import sys
from subprocess import check_call
version = '3.7.4' version = '3.7.4'
base = 'https://www.python.org/ftp/python/%s/' % version base = 'https://www.python.org/ftp/python/%s/' % version
@@ -51,7 +57,7 @@ def make_python_patch(arch):
urllib.request.urlretrieve(download_url, filename) urllib.request.urlretrieve(download_url, filename)
os.mkdir('python-embed') os.mkdir('python-embed')
subprocess.check_call(['unzip', '-q', os.path.abspath(filename)], cwd='python-embed') check_call(['unzip', '-q', os.path.abspath(filename)], cwd='python-embed')
os.remove(os.path.join('python-embed', 'python37._pth')) os.remove(os.path.join('python-embed', 'python37._pth'))
os.mkdir('pywin32') os.mkdir('pywin32')
@@ -61,23 +67,56 @@ def make_python_patch(arch):
os.mkdir(os.path.join('python-embed', 'lib')) os.mkdir(os.path.join('python-embed', 'lib'))
shutil.move(os.path.join('pywin32', 'PLATLIB'), os.path.join('python-embed', 'lib', 'site-packages')) shutil.move(os.path.join('pywin32', 'PLATLIB'), os.path.join('python-embed', 'lib', 'site-packages'))
subprocess.check_call(['zip', '-rq', os.path.join('..', out_filename), '.'], cwd='python-embed') check_call(['zip', '-rq', os.path.join('..', out_filename), '.'], cwd='python-embed')
upload_url = upload_base + out_filename upload_url = upload_base + out_filename
print('Uploading: ' + upload_url) print('Uploading: ' + upload_url)
cmd = ['gsutil', 'cp', '-n', out_filename, upload_url] cmd = ['gsutil', 'cp', '-n', out_filename, upload_url]
print(' '.join(cmd)) print(' '.join(cmd))
subprocess.check_call(cmd) check_call(cmd)
# cleanup if everything went fine # cleanup if everything went fine
shutil.rmtree('python-embed') shutil.rmtree('python-embed')
shutil.rmtree('pywin32') shutil.rmtree('pywin32')
def main(): def build_python():
for arch in ('amd64', 'win32'): if sys.platform.startswith('darwin'):
make_python_patch(arch) osname = 'macos'
# Take some rather drastic steps to link openssl statically
check_call(['brew', 'install', 'openssl', 'pkg-config'])
os.remove('/usr/local/opt/openssl/lib/libssl.dylib')
os.remove('/usr/local/opt/openssl/lib/libcrypto.dylib')
os.environ['PKG_CONFIG_PATH'] = '/usr/local/opt/openssl/lib/pkgconfig/'
else:
osname = 'linux'
src_dir = 'cpython'
if not os.path.exists(src_dir):
check_call(['git', 'clone', 'https://github.com/python/cpython'])
check_call(['git', 'checkout', 'v' + version], cwd=src_dir)
check_call(['./configure'], cwd=src_dir)
check_call(['make', '-j', str(multiprocessing.cpu_count())], cwd=src_dir)
check_call(['make', 'install', 'DESTDIR=install'], cwd=src_dir)
install_dir = os.path.join(src_dir, 'install')
os.rename(os.path.join(install_dir, 'usr', 'local'), 'python-%s' % version)
tarball = 'python-%s-%s.tar.gz' % (version, osname)
shutil.rmtree(os.path.join('python-%s' % version, 'lib', 'python3.7', 'test'))
shutil.rmtree(os.path.join('python-%s' % version, 'include'))
for lib in glob.glob(os.path.join('python-%s' % version, 'lib', 'lib*.a')):
os.remove(lib)
check_call(['tar', 'zcvf', tarball, 'python-%s' % version])
print('Uploading: ' + upload_base + tarball)
check_call(['gsutil', 'cp', '-n', tarball, upload_base + tarball])
def main():
if sys.platform.startswith('win'):
for arch in ('amd64', 'win32'):
make_python_patch(arch)
else:
build_python()
return 0 return 0