aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-21 20:43:10 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-21 20:43:10 -0800
commit8aa6919b7acf0b4034735ac7ee597e946fefaf4d (patch)
tree3ba77ead655e88db79243d4e00abcc73df5d3402 /tools
parent06bfe6541d88fda62a6b531e16250c63d85dcfe6 (diff)
parent160cc728e0839e441897d951fa61020bc2176717 (diff)
merge incoming
Diffstat (limited to 'tools')
-rwxr-xr-xtools/bindings_generator.py2
-rwxr-xr-xtools/emconfiguren.py2
-rwxr-xr-xtools/emmaken.py2
-rwxr-xr-xtools/emmakenxx.py4
-rwxr-xr-xtools/exec_llvm.py2
-rwxr-xr-xtools/fix_closure.py2
-rwxr-xr-xtools/ll-strip.py2
-rw-r--r--tools/make_minigzip.py2
-rw-r--r--tools/namespacer.py2
-rwxr-xr-xtools/nativize_llvm.py2
-rwxr-xr-xtools/reproduceriter.py2
-rw-r--r--tools/scons/site_scons/site_tools/emscripten/__init__.py2
-rw-r--r--tools/scons/site_scons/site_tools/emscripten/emscripten.py2
-rw-r--r--tools/settings_template_readonly.py1
-rw-r--r--tools/shared.py71
15 files changed, 59 insertions, 41 deletions
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py
index 0c7c814f..d2c165a2 100755
--- a/tools/bindings_generator.py
+++ b/tools/bindings_generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
'''
Use CppHeaderParser to parse some C++ headers, and generate binding code for them.
diff --git a/tools/emconfiguren.py b/tools/emconfiguren.py
index fd7b7549..35d83b87 100755
--- a/tools/emconfiguren.py
+++ b/tools/emconfiguren.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
import sys
print >> sys.stderr, '\n\nemconfiguren.py is deprecated! use "emconfigure"\n\n'
diff --git a/tools/emmaken.py b/tools/emmaken.py
index ae4794f0..77405761 100755
--- a/tools/emmaken.py
+++ b/tools/emmaken.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
import sys
print >> sys.stderr, '\n\nemmaken.py is deprecated! use "emcc"\n\n'
diff --git a/tools/emmakenxx.py b/tools/emmakenxx.py
index 1c31f3c2..0af3f99e 100755
--- a/tools/emmakenxx.py
+++ b/tools/emmakenxx.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
'''
see emmaken.py
@@ -14,5 +14,5 @@ from tools.shared import *
emmaken = path_from_root('tools', 'emmaken.py')
os.environ['EMMAKEN_CXX'] = '1'
-exit(subprocess.call(['python', emmaken] + sys.argv[1:]))
+exit(subprocess.call([PYTHON, emmaken] + sys.argv[1:]))
diff --git a/tools/exec_llvm.py b/tools/exec_llvm.py
index 71c0f18d..2685f9e4 100755
--- a/tools/exec_llvm.py
+++ b/tools/exec_llvm.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2
'''
Small utility to execute some llvm bitcode.
diff --git a/tools/fix_closure.py b/tools/fix_closure.py
index ab2dacbc..91d2a866 100755
--- a/tools/fix_closure.py
+++ b/tools/fix_closure.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
'''
With very very large projects, closure compiler can translate FUNCTION_TABLE into something like
diff --git a/tools/ll-strip.py b/tools/ll-strip.py
index b03e4f3a..a08da478 100755
--- a/tools/ll-strip.py
+++ b/tools/ll-strip.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2
import sys, re
diff --git a/tools/make_minigzip.py b/tools/make_minigzip.py
index 60177318..0c96457b 100644
--- a/tools/make_minigzip.py
+++ b/tools/make_minigzip.py
@@ -9,5 +9,5 @@ zlib = shared.Building.build_library('zlib', shared.EMSCRIPTEN_TEMP_DIR, shared.
print 'Building minigzip'
-Popen(['python', shared.EMCC, '-O2', shared.path_from_root('tests', 'zlib', 'minigzip.c'), zlib, '-o', shared.path_from_root('tools', 'minigzip.js')]).communicate()
+Popen(['python2', shared.EMCC, '-O2', shared.path_from_root('tests', 'zlib', 'minigzip.c'), zlib, '-o', shared.path_from_root('tools', 'minigzip.js')]).communicate()
diff --git a/tools/namespacer.py b/tools/namespacer.py
index 810689eb..81b8d2d1 100644
--- a/tools/namespacer.py
+++ b/tools/namespacer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2
'''
Tool that generates namespace boilerplate. Given
diff --git a/tools/nativize_llvm.py b/tools/nativize_llvm.py
index de78dce2..e76b9a4e 100755
--- a/tools/nativize_llvm.py
+++ b/tools/nativize_llvm.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python2
'''
Small utility to build some llvm bitcode into native code. Useful when lli (called
diff --git a/tools/reproduceriter.py b/tools/reproduceriter.py
index 058eeecf..c820978b 100755
--- a/tools/reproduceriter.py
+++ b/tools/reproduceriter.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
'''
Reproducer Rewriter
diff --git a/tools/scons/site_scons/site_tools/emscripten/__init__.py b/tools/scons/site_scons/site_tools/emscripten/__init__.py
index 8ae2288e..ebd2c21b 100644
--- a/tools/scons/site_scons/site_tools/emscripten/__init__.py
+++ b/tools/scons/site_scons/site_tools/emscripten/__init__.py
@@ -1,3 +1,3 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
from emscripten import exists, generate
diff --git a/tools/scons/site_scons/site_tools/emscripten/emscripten.py b/tools/scons/site_scons/site_tools/emscripten/emscripten.py
index ce704bf8..5abd4fee 100644
--- a/tools/scons/site_scons/site_tools/emscripten/emscripten.py
+++ b/tools/scons/site_scons/site_tools/emscripten/emscripten.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
import os
diff --git a/tools/settings_template_readonly.py b/tools/settings_template_readonly.py
index 93ea2036..970a8f8c 100644
--- a/tools/settings_template_readonly.py
+++ b/tools/settings_template_readonly.py
@@ -7,6 +7,7 @@ import os
# this helps projects using emscripten find it
EMSCRIPTEN_ROOT = os.path.expanduser(os.getenv('EMSCRIPTEN') or '{{{ EMSCRIPTEN_ROOT }}}')
LLVM_ROOT = os.path.expanduser(os.getenv('LLVM') or '{{{ LLVM_ROOT }}}')
+PYTHON = os.path.expanduser(os.getenv('PYTHON') or '{{{ PYTHON }}}')
# See below for notes on which JS engine(s) you need
NODE_JS = os.path.expanduser(os.getenv('NODE') or '{{{ NODE }}}')
diff --git a/tools/shared.py b/tools/shared.py
index 6fea9a92..d850b770 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -96,6 +96,12 @@ else:
except:
pass
config_file = config_file.replace('{{{ NODE }}}', node)
+ python = 'python'
+ try:
+ python = Popen(['which', 'python'], stdout=PIPE).communicate()[0].replace('\n', '')
+ except:
+ pass
+ config_file = config_file.replace('{{{ PYTHON }}}', python)
# write
open(CONFIG_FILE, 'w').write(config_file)
@@ -110,6 +116,7 @@ A settings file has been copied to %s, at absolute path: %s
It contains our best guesses for the important paths, which are:
LLVM_ROOT = %s
+ PYTHON = %s
NODE_JS = %s
EMSCRIPTEN_ROOT = %s
@@ -117,7 +124,7 @@ Please edit the file if any of those are incorrect.
This command will now exit. When you are done editing those paths, re-run it.
==============================================================================
-''' % (EM_CONFIG, CONFIG_FILE, llvm_root, node, __rootpath__)
+''' % (EM_CONFIG, CONFIG_FILE, llvm_root, python, node, __rootpath__)
sys.exit(0)
try:
config_text = open(CONFIG_FILE, 'r').read() if CONFIG_FILE else EM_CONFIG
@@ -128,7 +135,7 @@ except Exception, e:
# Expectations
-EXPECTED_LLVM_VERSION = (3,1)
+EXPECTED_LLVM_VERSION = (3,2)
def check_clang_version():
expected = 'clang version ' + '.'.join(map(str, EXPECTED_LLVM_VERSION))
@@ -165,7 +172,7 @@ def check_node_version():
# we re-check sanity when the settings are changed)
# We also re-check sanity and clear the cache when the version changes
-EMSCRIPTEN_VERSION = '1.0.1a'
+EMSCRIPTEN_VERSION = '1.1.0'
def check_sanity(force=False):
try:
@@ -319,6 +326,12 @@ except:
CLOSURE_COMPILER = path_from_root('third_party', 'closure-compiler', 'compiler.jar')
try:
+ PYTHON
+except:
+ print >> sys.stderr, 'PYTHON not defined in ~/.emscripten, using "python"'
+ PYTHON = 'python'
+
+try:
JAVA
except:
print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"'
@@ -333,7 +346,7 @@ except:
# Force a simple, standard target as much as possible: target 32-bit linux, and disable various flags that hint at other platforms
COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-U__i386__', '-U__x86_64__', '-U__i386', '-U__x86_64', '-U__SSE__', '-U__SSE2__', '-U__MMX__',
'-UX87_DOUBLE_ROUNDING', '-UHAVE_GCC_ASM_FOR_X87', '-DEMSCRIPTEN', '-U__STRICT_ANSI__', '-U__CYGWIN__',
- '-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu', '-D__IEEE_LITTLE_ENDIAN']
+ '-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu', '-D__IEEE_LITTLE_ENDIAN', '-fno-math-errno']
USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK')
@@ -499,6 +512,14 @@ def read_pgo_data(filename):
'overflows_lines': overflows_lines
}
+def unique_ordered(values): # return a list of unique values in an input list, without changing order (list(set(.)) would change order randomly)
+ seen = set()
+ def check(value):
+ if value in seen: return False
+ seen.add(value)
+ return True
+ return filter(check, values)
+
# Settings. A global singleton. Not pretty, but nicer than passing |, settings| everywhere
class Settings:
@@ -713,7 +734,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
Popen([LLVM_EXTRACT, filename, '-delete', '-func=' + symbol, '-o', filename], stderr=PIPE).communicate()
@staticmethod
- def link(files, target, remove_duplicates=False):
+ def link(files, target):
actual_files = []
unresolved_symbols = set(['main']) # tracking unresolveds is necessary for .a linking, see below. (and main is always a necessary symbol)
resolved_symbols = set()
@@ -774,26 +795,11 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
os.chdir(cwd)
try_delete(target)
- if remove_duplicates:
- # Remove duplicate symbols. This is a workaround for how we compile .a files, we try to
- # emulate ld behavior which is permissive TODO: cache llvm-nm results
- seen_symbols = set()
- print >> sys.stderr, actual_files
- for actual in actual_files:
- symbols = Building.llvm_nm(actual)
- dupes = seen_symbols.intersection(symbols.defs)
- if len(dupes) > 0:
- print >> sys.stderr, 'emcc: warning: removing duplicates in', actual
- for dupe in dupes:
- print >> sys.stderr, 'emcc: warning: removing duplicate', dupe
- Building.remove_symbol(actual, dupe)
- Popen([LLVM_EXTRACT, actual, '-delete', '-glob=.str', '-o', actual], stderr=PIPE).communicate() # garbage that appears here
- seen_symbols = seen_symbols.union(symbols.defs)
-
# Finish link
+ actual_files = unique_ordered(actual_files) # tolerate people trying to link a.so a.so etc.
if DEBUG: print >>sys.stderr, 'emcc: llvm-linking:', actual_files
output = Popen([LLVM_LINK] + actual_files + ['-o', target], stdout=PIPE).communicate()[0]
- assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output + '\nemcc: If you get duplicate symbol errors, try --remove-duplicates'
+ assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output
for temp_dir in temp_dirs:
try_delete(temp_dir)
@@ -878,13 +884,13 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
if output_filename is None:
output_filename = filename + '.o'
try_delete(output_filename)
- Popen(ENV_PREFIX + ['python', EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate()
+ Popen([PYTHON, EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate()
assert os.path.exists(output_filename), 'emcc could not create output file'
@staticmethod
def emar(action, output_filename, filenames, stdout=None, stderr=None, env=None):
try_delete(output_filename)
- Popen(ENV_PREFIX + ['python', EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate()
+ Popen([PYTHON, EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate()
if 'c' in action:
assert os.path.exists(output_filename), 'emar could not create output file'
@@ -895,7 +901,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Run Emscripten
settings = Settings.serialize()
- compiler_output = timeout_run(Popen(ENV_PREFIX + ['python', EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling')
+ compiler_output = timeout_run(Popen([PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling')
#print compiler_output
# Detect compilation crashes and errors
@@ -917,6 +923,12 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
return Settings.INLINING_LIMIT == 0
@staticmethod
+ def get_safe_internalize():
+ exports = ','.join(map(lambda exp: exp[1:], Settings.EXPORTED_FUNCTIONS))
+ # internalize carefully, llvm 3.2 will remove even main if not told not to
+ return ['-internalize', '-internalize-public-api-list=' + exports]
+
+ @staticmethod
def pick_llvm_opts(optimization_level):
'''
It may be safe to use nonportable optimizations (like -OX) if we remove the platform info from the .ll
@@ -951,7 +963,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
opts.append('-basicaa') # makes fannkuch slow but primes fast
if Building.can_build_standalone():
- opts.append('-internalize')
+ opts += Building.get_safe_internalize()
opts.append('-globalopt')
opts.append('-ipsccp')
@@ -1111,7 +1123,12 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
def make(opt_level):
raw = RELOOPER + '.raw.js'
- Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js', os.path.join('relooper', 'emscripten', 'glue.js'), '-s', 'TOTAL_MEMORY=52428800', '-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=["memcpy", "memset", "malloc", "free", "puts"]', '-O' + str(opt_level), '--closure', '0'], raw)
+ Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js',
+ os.path.join('relooper', 'emscripten', 'glue.js'),
+ '-s', 'TOTAL_MEMORY=52428800',
+ '-s', 'EXPORTED_FUNCTIONS=["_rl_set_output_buffer","_rl_make_output_buffer","_rl_new_block","_rl_delete_block","_rl_block_add_branch_to","_rl_new_relooper","_rl_delete_relooper","_rl_relooper_add_block","_rl_relooper_calculate","_rl_relooper_render"]',
+ '-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=["memcpy", "memset", "malloc", "free", "puts"]',
+ '-O' + str(opt_level), '--closure', '0'], raw)
f = open(RELOOPER, 'w')
f.write("// Relooper, (C) 2012 Alon Zakai, MIT license, https://github.com/kripken/Relooper\n")
f.write("var Relooper = (function() {\n");