aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-16 18:14:02 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-16 18:14:23 -0800
commitd157b2049d07d3396cfa6d646d56705100ef412f (patch)
tree0404f0893be489c04393698d0808fe8269ce58fe
parent48a10df5a060461bc8a213e14e9f3aba2e0b7858 (diff)
support for .ll files as inputs to emcc
-rwxr-xr-xemcc20
-rw-r--r--tests/runner.py9
-rw-r--r--tools/shared.py15
3 files changed, 29 insertions, 15 deletions
diff --git a/emcc b/emcc
index 1d2217ed..ebcdb1d3 100755
--- a/emcc
+++ b/emcc
@@ -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):