diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-12-16 18:14:02 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-12-16 18:14:23 -0800 |
commit | d157b2049d07d3396cfa6d646d56705100ef412f (patch) | |
tree | 0404f0893be489c04393698d0808fe8269ce58fe | |
parent | 48a10df5a060461bc8a213e14e9f3aba2e0b7858 (diff) |
support for .ll files as inputs to emcc
-rwxr-xr-x | emcc | 20 | ||||
-rw-r--r-- | tests/runner.py | 9 | ||||
-rw-r--r-- | tools/shared.py | 15 |
3 files changed, 29 insertions, 15 deletions
@@ -11,12 +11,12 @@ use emar, emld and emranlib instead of the same command without 'em'. Example uses: - * For configure, instead of ./configure, cmake, etc., run emconfiguren.py + * For configure, instead of ./configure, cmake, etc., run emconfigure.py with that command as an argument, for example - emconfiguren.py ./configure [options] + emconfigure.py ./configure [options] - emconfiguren.py is a tiny script that just sets some environment vars + emconfigure.py is a tiny script that just sets some environment vars as a convenience. The command just shown is equivalent to EMMAKEN_JUST_CONFIGURE=1 RANLIB=PATH/emranlib AR=PATH/emar CXX=PATH/em++ CC=PATH/emcc ./configure [options] @@ -148,6 +148,10 @@ The -c option (which tells gcc not to run the linker) will cause LLVM bitcode to be generated, as %s only generates JavaScript in the final linking stage of building. +The input file(s) can be either source code files that +Clang can handle (C or C++), LLVM bitcode in binary form, +or LLVM assembly files in human-readable form. + ''' % (this, this, this) exit(0) @@ -179,6 +183,7 @@ if EMMAKEN_CFLAGS: CC_ADDITIONAL_ARGS += EMMAKEN_CFLAGS.split(' ') # ---------------- Utilities --------------- SOURCE_SUFFIXES = ('.c', '.cpp', '.cxx', '.cc') +BITCODE_SUFFIXES = ('.bc', '.o', '.ll') def unsuffixed(name): return '.'.join(name.split('.')[:-1]) @@ -289,7 +294,7 @@ try: for i in range(len(newargs)): # find input files XXX this a simple heuristic. we should really analyze based on a full understanding of gcc params, # right now we just assume that what is left contains no more |-x OPT| things arg = newargs[i] - if arg.endswith(SOURCE_SUFFIXES + ('.bc', '.o')): # we already removed -o <target>, so all these should be inputs + if arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES): # we already removed -o <target>, so all these should be inputs input_files.append(arg) newargs[i] = '' if arg.endswith(SOURCE_SUFFIXES): @@ -344,8 +349,11 @@ try: args = newargs + [input_file, '-o', in_temp(unsuffixed_basename(input_file) + '.o')] if DEBUG: print >> sys.stderr, "emcc running:", call, ' '.join(args) Popen([call] + args).communicate() - else: - shutil.copyfile(input_file, in_temp(unsuffixed_basename(input_file) + '.o')) + else: # bitcode + if input_file.endswith(('.bc', '.o')): + shutil.copyfile(input_file, in_temp(unsuffixed_basename(input_file) + '.o')) + else: #.ll + shared.Building.llvm_as(input_file, in_temp(unsuffixed_basename(input_file) + '.o')) # Optimize, if asked to if llvm_opt_level > 0: diff --git a/tests/runner.py b/tests/runner.py index 5eb88062..03a4c425 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -4939,6 +4939,13 @@ Options that are modified or new in %s include: assert os.path.exists(target), 'Expected %s to exist since args are %s : %s' % (target, str(args), '\n'.join(output)) self.assertContained('hello, world!', self.run_llvm_interpreter([target])) + # emcc src.ll ==> generates .js + clear() + output = Popen([compiler, path_from_root('tests', 'hello_world.ll')], stdout=PIPE, stderr=PIPE).communicate() + assert len(output[0]) == 0, output[0] + assert os.path.exists('a.out.js'), '\n'.join(output) + self.assertContained('hello, world!', run_js('a.out.js')) + # dlmalloc. dlmalloc is special in that it is the only part of libc that is (1) hard to write well, and # very speed-sensitive. So we do not implement it in JS in library.js, instead we compile it from source for source, has_malloc in [('hello_world' + suffix, False), ('hello_malloc.cpp', True)]: @@ -5057,13 +5064,11 @@ Options that are modified or new in %s include: assert os.path.exists('combined.bc'), '\n'.join(output) self.assertContained('side got: hello from main, over', self.run_llvm_interpreter(['combined.bc'])) - # TODO: compile .ll inputs to emcc into .bc # TODO: test normal project linking, static and dynamic: get_library should not need to be told what to link! # TODO: when ready, switch tools/shared building to use emcc over emmaken # TODO: when this is done, more test runner to test these (i.e., test all -Ox thoroughly) # TODO: emscripten tutorial with emcc # TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py. - # TODO: hide output from compiling dlmalloc internally # Finally, do some web browser tests def run_browser(html_file, message): diff --git a/tools/shared.py b/tools/shared.py index 7bd31729..97e953be 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -334,14 +334,15 @@ class Building: assert os.path.exists(filename + '.o.ll'), 'Could not create .ll file: ' + output @staticmethod - def llvm_as(filename): + def llvm_as(input_filename, output_filename=None): # LLVM assembly ==> LLVM binary - try: - os.remove(target) - except: - pass - output = Popen([LLVM_AS, filename + '.o.ll', '-o=' + filename + '.o'], stdout=PIPE).communicate()[0] - assert os.path.exists(filename + '.o'), 'Could not create bc file: ' + output + if output_filename is None: + # use test runner conventions + output_filename = input_filename + '.o' + input_filename = input_filename + '.o.ll' + try_delete(output_filename) + output = Popen([LLVM_AS, input_filename, '-o=' + output_filename], stdout=PIPE).communicate()[0] + assert os.path.exists(output_filename), 'Could not create bc file: ' + output @staticmethod def llvm_nm(filename): |