Created
November 26, 2014 06:11
-
-
Save evanw/e5aa506a31a5dfbd807e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a simple wrapper for the "emcc" command from the emscripten compiler. | |
# Unlike the emscripten SDK script, it lets you specify the compiler version | |
# number. Just pass the version number using the "--version" flag and put the | |
# flags for "emcc" after the "--": | |
# | |
# python emcc_wrapper.py --version 1.27.0 -- -O3 -s NO_EXIT_RUNTIME=1 ... | |
# | |
import os | |
import sys | |
import pipes | |
import urllib2 | |
import hashlib | |
import subprocess | |
import argparse | |
cache_folder = os.path.expanduser('~/.emcc_wrapper') | |
def run(command, **kwargs): | |
print ' '.join(map(pipes.quote, command)) | |
subprocess.check_call(command, **kwargs) | |
def mkdir(path): | |
try: | |
os.makedirs(path) | |
except: | |
pass | |
def fetch(url): | |
print 'fetching', url | |
request = urllib2.urlopen(url) | |
content = '' | |
while True: | |
chunk = request.read(128 * 1024) | |
if not chunk: | |
sys.stdout.write('\n') | |
return content | |
content += chunk | |
sys.stdout.write('\r%.1f mb' % (float(len(content)) / (1024 * 1024))) | |
sys.stdout.flush() | |
def extract(file, folder): | |
print 'extracting to', folder | |
mkdir(folder) | |
run(['unzip', file, '-d', folder]) | |
def download(url): | |
path = os.path.join(cache_folder, 'downloads', hashlib.md5(url).hexdigest()) | |
if not os.path.exists(path): | |
content = fetch(url) | |
mkdir(os.path.dirname(path)) | |
open(path, 'w').write(content) | |
return path | |
def download_github_release(repo, version, path): | |
url = 'https://github.com/kripken/%s/archive/%s.zip' % (repo, version) | |
path = os.path.join(cache_folder, version, path) | |
if not os.path.exists(path): | |
temp = path + '-temp' | |
extract(download(url), temp) | |
nested = os.path.join(temp, '%s-%s' % (repo, version)) | |
if os.path.exists(nested): | |
os.rename(nested, path) | |
os.rmdir(temp) | |
else: | |
os.rename(temp, path) | |
return path | |
def build_llvm(source, version): | |
target = os.path.join(os.path.dirname(source), 'llvm-build') | |
if not os.path.exists(target): | |
mkdir(target) | |
flags = [ | |
# These are from http://kripken.github.io/emscripten-site/docs/building_from_source/building_fastcomp_manually_from_source.html | |
'-DCMAKE_BUILD_TYPE=Release', | |
'-DLLVM_TARGETS_TO_BUILD=X86;JSBackend', | |
'-DLLVM_INCLUDE_EXAMPLES=OFF', | |
'-DLLVM_INCLUDE_TESTS=OFF', | |
'-DCLANG_INCLUDE_EXAMPLES=OFF', | |
'-DCLANG_INCLUDE_TESTS=OFF', | |
] | |
run(['cmake', source] + flags, cwd=target) | |
run(['make', '-j4'], cwd=target) | |
return os.path.join(target, 'bin') | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('arguments', metavar='ARGUMENT', nargs='*', help='arguments for the real emcc') | |
parser.add_argument('--version', required=True, help='the emscripten SDK version') | |
parser.add_argument('--python', default='python', help='the python binary to use') | |
options = parser.parse_args() | |
emscripten_path = download_github_release('emscripten', options.version, 'emscripten') | |
llvm_path = download_github_release('emscripten-fastcomp', options.version, 'emscripten-fastcomp') | |
clang_path = download_github_release('emscripten-fastcomp-clang', options.version, os.path.join('emscripten-fastcomp', 'tools', 'clang')) | |
bin_path = build_llvm(llvm_path, options.version) | |
config = [ | |
('EMSCRIPTEN_ROOT', emscripten_path), | |
('LLVM_ROOT', bin_path), | |
('NODE_JS', 'node'), | |
('COMPILER_ENGINE', 'node'), | |
('JS_ENGINES', ['node']), | |
] | |
command = [options.python, os.path.join(emscripten_path, 'emcc')] | |
command += ['--em-config', ';'.join('%s=%s' % (name, repr(value)) for name, value in config)] | |
command += options.arguments | |
run(command) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment