aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-03-25 17:55:34 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-03-25 17:55:34 -0700
commit78d5d9c1e1db669839cd17a0df01b69af67539f6 (patch)
treeb9bc79913b512b37904f0748fe6730783b9d1387
parent135a906d9996bd93e3aa6764943a754dd3668651 (diff)
let emcc directly access bitcode files when possible, to emit proper .d files and avoid unnecessary copies
-rwxr-xr-xemcc23
-rw-r--r--tests/test_other.py17
-rw-r--r--tools/shared.py33
3 files changed, 21 insertions, 52 deletions
diff --git a/emcc b/emcc
index c30845ed..0dd2eaab 100755
--- a/emcc
+++ b/emcc
@@ -50,7 +50,7 @@ emcc can be influenced by a few environment variables:
import os, sys, shutil, tempfile, subprocess, shlex, time, re, logging
from subprocess import PIPE
from tools import shared, jsrun, system_libs
-from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename, WINDOWS
+from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename, WINDOWS, safe_move
from tools.response_file import read_response_file
# endings = dot + a suffix, safe to test by filename.endswith(endings)
@@ -1352,13 +1352,22 @@ try:
execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
sys.exit(1)
+ def get_bitcode_file(input_file):
+ if final_suffix == 'o':
+ # no need for a temp file, just emit to the right place
+ if len(input_files) == 1:
+ # can just emit directly to the target
+ if specified_target: return specified_target
+ return unsuffixed(input_file) + '.' + final_suffix
+ return unsuffixed(input_file) + '.o'
+ return in_temp(unsuffixed(uniquename(input_file)) + '.o')
+
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
for input_file in input_files:
file_ending = filename_type_ending(input_file)
if file_ending.endswith(SOURCE_ENDINGS):
logging.debug('compiling source file: ' + input_file)
- input_file = shared.Building.preprocess(input_file, in_temp(uniquename(input_file)))
- output_file = in_temp(unsuffixed(uniquename(input_file)) + '.o')
+ output_file = get_bitcode_file(input_file)
temp_files.append(output_file)
args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file]
if file_ending.endswith(CXX_ENDINGS):
@@ -1410,20 +1419,20 @@ try:
if final_suffix not in JS_CONTAINING_SUFFIXES:
if not specified_target:
for input_file in input_files:
- shutil.move(in_temp(unsuffixed(uniquename(input_file)) + '.o'), unsuffixed_basename(input_file) + '.' + final_suffix)
+ safe_move(get_bitcode_file(input_file), unsuffixed_basename(input_file) + '.' + final_suffix)
else:
if len(input_files) == 1:
- temp_output_base = in_temp(unsuffixed(uniquename(input_files[0])))
+ temp_output_base = unsuffixed(get_bitcode_file(input_files[0]))
if specified_target.endswith('/') or specified_target.endswith('\\') or os.path.isdir(specified_target): # User passed '-o <directory' as the location to output to.
obj_output_name = os.path.join(specified_target, os.path.splitext(os.path.basename(input_file))[0] + default_object_extension)
logging.debug('User specified -o <directoryname> as the location of the output. Generating output file ' + obj_output_name)
try:
- shutil.move(temp_output_base + '.o', obj_output_name)
+ safe_move(temp_output_base + '.o', obj_output_name)
except IOError, e:
logging.error('Could not write to output file ' + obj_output_name + '. Perhaps the output directory does not exist?')
exit(1)
else: # User passed '-o <filename>' as the location to output to.
- shutil.move(temp_output_base + '.o', specified_target)
+ safe_move(temp_output_base + '.o', specified_target)
if os.path.exists(temp_output_base + '.d'):
# There was a .d file generated, from -MD or -MMD and friends, save a copy of it to where the output resides,
# adjusting the target name away from the temporary file name to the specified target.
diff --git a/tests/test_other.py b/tests/test_other.py
index 9146888c..93cd9796 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -1978,23 +1978,6 @@ seeked= file.
code = open('a.out.js').read()
assert 'SAFE_HEAP' in code, 'valid -s option had an effect'
- def test_jcache_printf(self):
- open(self.in_dir('src.cpp'), 'w').write(r'''
- #include <stdio.h>
- #include <stdint.h>
- #include <emscripten.h>
- int main() {
- emscripten_jcache_printf("hello world\n");
- emscripten_jcache_printf("hello %d world\n", 5);
- emscripten_jcache_printf("hello %.3f world\n", 123.456789123);
- emscripten_jcache_printf("hello %llx world\n", 0x1234567811223344ULL);
- return 0;
- }
- ''')
- Popen([PYTHON, EMCC, self.in_dir('src.cpp')]).communicate()
- output = run_js('a.out.js')
- self.assertIdentical('hello world\nhello 5 world\nhello 123.457 world\nhello 1234567811223300 world\n', output)
-
def test_conftest_s_flag_passing(self):
open(os.path.join(self.get_dir(), 'conftest.c'), 'w').write(r'''
int main() {
diff --git a/tools/shared.py b/tools/shared.py
index 1adbdfaa..ac4b42ea 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -1585,34 +1585,6 @@ class Building:
import gen_struct_info
gen_struct_info.main(['-qo', info_path, path_from_root('src/struct_info.json')])
- @staticmethod
- def preprocess(infile, outfile):
- '''
- Preprocess source C/C++ in some special ways that emscripten needs. Returns
- a filename (potentially the same one if nothing was changed).
-
- Currently this only does emscripten_jcache_printf(..) rewriting.
- '''
- src = open(infile).read() # stack warning on jcacheprintf! in docs # add jcache printf test separatrely, for content of printf
- if 'emscripten_jcache_printf' not in src: return infile
- def fix(m):
- text = m.groups(0)[0]
- assert text.count('(') == 1 and text.count(')') == 1, 'must have simple expressions in emscripten_jcache_printf calls, no parens'
- assert text.count('"') == 2, 'must have simple expressions in emscripten_jcache_printf calls, no strings as varargs parameters'
- if os.environ.get('EMCC_FAST_COMPILER') != '0': # fake it in fastcomp
- return text.replace('emscripten_jcache_printf', 'printf')
- start = text.index('(')
- end = text.rindex(')')
- args = text[start+1:end].split(',')
- args = map(lambda x: x.strip(), args)
- if args[0][0] == '"':
- # flatten out
- args = map(lambda x: str(ord(x)), args[0][1:len(args[0])-1]) + ['0'] + args[1:]
- return 'emscripten_jcache_printf_(' + ','.join(args) + ')'
- src = re.sub(r'(emscripten_jcache_printf\([^)]+\))', lambda m: fix(m), src)
- open(outfile, 'w').write(src)
- return outfile
-
# compatibility with existing emcc, etc. scripts
Cache = cache.Cache(debug=DEBUG_CACHE)
JCache = cache.JCache(Cache)
@@ -1821,5 +1793,10 @@ def unsuffixed(name):
def unsuffixed_basename(name):
return os.path.basename(unsuffixed(name))
+def safe_move(src, dst):
+ if os.path.abspath(src) == os.path.abspath(dst):
+ return
+ shutil.move(src, dst)
+
import js_optimizer