| #!/usr/bin/env python3 | |
| # | |
| # Copyright 2020 WebAssembly Community Group participants | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| import collections | |
| import json | |
| import io | |
| import os | |
| import re | |
| import sys | |
| import tarfile | |
| import urllib.request | |
| import zipfile | |
| def fetch_json(url): | |
| with urllib.request.urlopen(url) as res: | |
| return json.loads(res.read().decode()) | |
| def download_zip(url, dir): | |
| with urllib.request.urlopen(url) as res: | |
| data = io.BytesIO(res.read()) | |
| archive = zipfile.ZipFile(data) | |
| for name in archive.namelist(): | |
| file = archive.open(name) | |
| with open(os.path.join(dir, name), 'wb') as output: | |
| output.write(file.read()) | |
| def download_tar(url, dir): | |
| tempfile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'temp.tar.gz') | |
| with urllib.request.urlopen(url) as res: | |
| with open(tempfile, 'wb') as temp: | |
| temp.write(res.read()) | |
| with tarfile.open(tempfile, 'r') as archive: | |
| for member in archive.getmembers(): | |
| match = re.match('^[^/]+/', member.name) | |
| if match: | |
| outname = os.path.join(dir, member.name[match.span(0)[1]:]) | |
| if member.isdir(): | |
| if not os.path.exists(outname): | |
| os.mkdir(outname) | |
| elif member.isfile(): | |
| with archive.extractfile(member) as infile: | |
| with open(outname, 'wb') as outfile: | |
| outfile.write(infile.read()) | |
| if sys.platform != 'win32': | |
| os.chmod(outname, member.mode) | |
| os.remove(tempfile) | |
| # mozjs | |
| # see: https://github.com/GoogleChromeLabs/jsvu/tree/main/engines/spidermonkey | |
| mozjs_bin = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mozjs') | |
| def mozjs_determine_platform(): | |
| is_64bits = sys.maxsize > 2**32 | |
| if sys.platform.startswith('linux'): | |
| return 'linux-x86_64' if is_64bits else 'linux-i686' | |
| if sys.platform == 'darwin': | |
| return 'mac' | |
| if sys.platform == 'win32': | |
| return 'win64' if is_64bits else 'win32' | |
| print('Cannot determine platform, assuming \'linux-x86_64\'') | |
| return 'linux-x86_64' | |
| def mozjs_determine_version(platform): | |
| data = fetch_json('https://product-details.mozilla.org/1.0/firefox_history_development_releases.json') | |
| latest = '' | |
| version = '' | |
| for v, t in data.items(): | |
| if t > latest: | |
| latest = t | |
| version = v | |
| return version | |
| def mozjs_download(platform, version): | |
| download_zip('https://archive.mozilla.org/pub/firefox/releases/' + version + '/jsshell/jsshell-' + platform + '.zip', mozjs_bin) | |
| if sys.platform != 'win32': | |
| os.rename(os.path.join(mozjs_bin, 'js'), os.path.join(mozjs_bin, 'mozjs')) | |
| os.chmod(os.path.join(mozjs_bin, 'mozjs'), 0o755) | |
| else: | |
| os.rename(os.path.join(mozjs_bin, 'js.exe'), os.path.join(mozjs_bin, 'mozjs.exe')) | |
| def mozjs_is_installed(): | |
| return os.path.exists(os.path.join(mozjs_bin, 'mozjs.exe' if sys.platform == 'win32' else 'mozjs')) | |
| def mozjs_main(): | |
| print('Setting up mozjs ...') | |
| platform = mozjs_determine_platform() | |
| print('* Platform: ' + platform) | |
| version = mozjs_determine_version(platform) | |
| print('* Latest version: ' + version) | |
| print('* Downloading to: ' + mozjs_bin) | |
| mozjs_download(platform, version) | |
| if mozjs_is_installed(): | |
| print('* Complete') | |
| else: | |
| print('* Something went wrong :(') | |
| # V8 | |
| # see: https://github.com/GoogleChromeLabs/jsvu/tree/main/engines/v8 | |
| v8_bin = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'v8') | |
| def v8_determine_platform(): | |
| is_64bits = sys.maxsize > 2**32 | |
| if sys.platform.startswith('linux'): | |
| return 'linux64' if is_64bits else 'linux32' | |
| if sys.platform == 'darwin': | |
| return 'mac64' | |
| if sys.platform == 'win32': | |
| return 'win64' if is_64bits else 'win32' | |
| print('Cannot determine platform, assuming \'linux64\'') | |
| return 'linux64' | |
| def v8_determine_version(platform): | |
| data = fetch_json('https://storage.googleapis.com/chromium-v8/official/canary/v8-' + platform + '-rel-latest.json') | |
| return data['version'] | |
| def v8_download(platform, version): | |
| download_zip('https://storage.googleapis.com/chromium-v8/official/canary/v8-' + platform + '-rel-' + version + '.zip', v8_bin) | |
| if sys.platform != 'win32': | |
| os.chmod(os.path.join(v8_bin, 'd8'), 0o755) | |
| def v8_is_installed(): | |
| return os.path.exists(os.path.join(v8_bin, 'd8.exe' if sys.platform == 'win32' else 'd8')) | |
| def v8_main(): | |
| print('Setting up V8 ...') | |
| platform = v8_determine_platform() | |
| print('* Platform: ' + platform) | |
| version = v8_determine_version(platform) | |
| print('* Latest version: ' + version) | |
| print('* Downloading to: ' + v8_bin) | |
| v8_download(platform, version) | |
| if v8_is_installed(): | |
| print('* Complete') | |
| else: | |
| print('* Something went wrong :(') | |
| # WABT | |
| # see: https://github.com/WebAssembly/wabt/releases | |
| wabt_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'wabt') | |
| wabt_bin = os.path.join(wabt_dir, 'bin') | |
| def wabt_determine_platform(): | |
| if sys.platform.startswith('linux'): | |
| return 'linux' | |
| if sys.platform == 'darwin': | |
| return 'macos' | |
| if sys.platform == 'win32': | |
| return 'windows' | |
| print('Cannot determine platform, assuming \'linux\'') | |
| return 'linux' | |
| def wabt_determine_release(platform): | |
| platform_regex = re.compile(r"^wabt-.*-%s.*.tar.gz$" % platform) | |
| data = fetch_json('https://api.github.com/repos/WebAssembly/wabt/releases/latest') | |
| for asset in data['assets']: | |
| if platform_regex.match(asset['name']): | |
| return asset['browser_download_url'] | |
| print('Cannot determine release') | |
| return '' | |
| def wabt_download(release): | |
| download_tar(release, wabt_dir) | |
| def wabt_is_installed(): | |
| return os.path.exists(os.path.join(wabt_bin, 'wasm2c.exe' if sys.platform == 'win32' else 'wasm2c')) | |
| def wabt_main(): | |
| print('Setting up WABT ...') | |
| platform = wabt_determine_platform() | |
| print('* Platform: ' + platform) | |
| release = wabt_determine_release(platform) | |
| print('* Latest release: ' + release) | |
| print('* Downloading to: ' + wabt_bin) | |
| wabt_download(release) | |
| if wabt_is_installed(): | |
| print('* Complete') | |
| else: | |
| print('* Something went wrong :(') | |
| TOOLS = { | |
| 'mozjs': mozjs_main, | |
| 'v8': v8_main, | |
| 'wabt': wabt_main, | |
| } | |
| if __name__ == '__main__': | |
| if len(sys.argv) < 2 or sys.argv[1] == '--help': | |
| msg = '' | |
| for key in TOOLS.keys(): | |
| if len(msg): | |
| msg += '|' | |
| msg += key | |
| print('usage: ./setup.py [' + msg + '|all]') | |
| sys.exit(0) | |
| tool = sys.argv[1] | |
| if tool == 'all': | |
| for main in TOOLS.values(): | |
| code = main() | |
| if code: | |
| sys.exit(code) | |
| sys.exit(0) | |
| elif TOOLS[tool]: | |
| main = TOOLS[tool] | |
| sys.exit(main()) | |
| else: | |
| print('No such tool: ' + tool) | |
| sys.exit(1) |