aboutsummaryrefslogtreecommitdiff
path: root/emcc
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-18 07:59:06 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-18 07:59:06 -0800
commit56b65a54cb92d2d4a34535f71dbae08d758d3fc3 (patch)
tree0220d27388eab38587a8fd12140552e0ce513435 /emcc
parente77d99dac0b1ba58c773b4b8c7d8a223ad008624 (diff)
parent47bc8ba2c47c67d8824c2b7bf35195a079cbed7c (diff)
Merge branch 'incoming'
Diffstat (limited to 'emcc')
-rwxr-xr-xemcc81
1 files changed, 54 insertions, 27 deletions
diff --git a/emcc b/emcc
index 88730539..a0f59f0b 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]
@@ -80,10 +80,6 @@ from tools import shared
DEBUG = os.environ.get('EMCC_DEBUG')
TEMP_DIR = os.environ.get('EMCC_TEMP_DIR')
-################### XXX
-print >> sys.stderr, '\n***This is a WORK IN PROGRESS***'
-################### XXX
-
if DEBUG: print >> sys.stderr, 'emcc: ', ' '.join(sys.argv)
# Handle some global flags
@@ -148,16 +144,23 @@ 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)
-# If this is a configure-type thing, just do that
+# If this is a configure-type thing, do not compile to JavaScript, instead use clang
+# to compile to a native binary (using our headers, so things make sense later)
CONFIGURE_CONFIG = os.environ.get('EMMAKEN_JUST_CONFIGURE')
CMAKE_CONFIG = 'CMakeFiles/cmTryCompileExec.dir' in ' '.join(sys.argv)# or 'CMakeCCompilerId' in ' '.join(sys.argv)
if CONFIGURE_CONFIG or CMAKE_CONFIG:
- compiler = 'g++' if 'CXXCompiler' in ' '.join(sys.argv) or os.environ.get('EMMAKEN_CXX') else 'gcc'
+ compiler = shared.CLANG
+ if not ('CXXCompiler' in ' '.join(sys.argv) or os.environ.get('EMMAKEN_CXX')):
+ compiler = shared.to_cc(compiler)
cmd = [compiler] + shared.EMSDK_OPTS + sys.argv[1:]
- if DEBUG: print >> sys.stderr, 'emcc, just configuring: ', cmd
+ if DEBUG: print >> sys.stderr, 'emcc, just configuring: ', compiler, cmd
exit(os.execvp(compiler, cmd))
if os.environ.get('EMMAKEN_COMPILER'):
@@ -179,6 +182,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])
@@ -266,6 +270,12 @@ try:
closure = int(newargs[i+1])
newargs[i] = ''
newargs[i+1] = ''
+ elif newargs[i] == '-MF': # clang cannot handle this, so we fake it
+ f = open(newargs[i+1], 'w')
+ f.write('\n')
+ f.close()
+ newargs[i] = ''
+ newargs[i+1] = ''
newargs = [ arg for arg in newargs if arg is not '' ]
if llvm_opt_level is None: llvm_opt_level = 1 if opt_level >= 1 else 0
@@ -289,14 +299,23 @@ 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
- input_files.append(arg)
+ if arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES): # we already removed -o <target>, so all these should be inputs
newargs[i] = ''
- if arg.endswith(SOURCE_SUFFIXES):
- has_source_inputs = True
+ if os.path.exists(arg):
+ if arg.endswith(SOURCE_SUFFIXES):
+ input_files.append(arg)
+ has_source_inputs = True
+ else:
+ # this should be bitcode, make sure it is valid
+ if arg.endswith('.ll') or shared.Building.is_bitcode(arg):
+ input_files.append(arg)
+ else:
+ print >> sys.stderr, 'emcc: %s: Not valid LLVM bitcode' % arg
+ else:
+ print >> sys.stderr, 'emcc: %s: No such file or directory' % arg
newargs = [ arg for arg in newargs if arg is not '' ]
- assert len(input_files) > 0, 'emcc: no input files specified'
+ assert len(input_files) > 0, 'emcc: no input files'
newargs += CC_ADDITIONAL_ARGS
@@ -334,24 +353,29 @@ try:
## Compile source code to bitcode
- if DEBUG: print >> sys.stderr, 'emcc: compiling to bitcode'
+ if DEBUG: print >> sys.stderr, 'emcc: compiling to bitcode (%s)' % str(sys.argv)
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
- newargs = newargs + ['-emit-llvm', '-c']
-
for input_file in input_files:
if input_file.endswith(SOURCE_SUFFIXES):
- args = newargs + [input_file, '-o', in_temp(unsuffixed_basename(input_file) + '.o')]
+ args = newargs + ['-emit-llvm', '-c', 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:
if DEBUG: print >> sys.stderr, 'emcc: LLVM opts'
for input_file in input_files:
- shared.Building.llvm_opt(in_temp(unsuffixed_basename(input_file) + '.o'), LLVM_INTERNAL_OPT_LEVEL, safe=llvm_opt_level < 2)
+ try:
+ shared.Building.llvm_opt(in_temp(unsuffixed_basename(input_file) + '.o'), LLVM_INTERNAL_OPT_LEVEL, safe=llvm_opt_level < 2)
+ except:
+ # This might be an invalid input, which will get ignored during linking later anyhow
+ print >> sys.stderr, 'emcc: warning: LLVM opt failed to run on %s, continuing without optimization' % input_file
# If we were just asked to generate bitcode, stop there
if final_suffix not in ['js', 'html']:
@@ -364,9 +388,12 @@ try:
else:
assert not has_dash_c, 'fatal error: cannot specify -o with -c with multiple files' + str(sys.argv)
# We have a specified target (-o <target>), which is not JavaScript or HTML, and
- # we have multiple files: Link them. TODO: Pass complex linker args along
- shared.Building.link(map(lambda input_file: in_temp(unsuffixed_basename(input_file) + '.o'), input_files), specified_target)
-
+ # we have multiple files: Link them TODO: llvm link-time opts?
+ ld_args = map(lambda input_file: in_temp(unsuffixed_basename(input_file) + '.o'), input_files) + \
+ ['-o', specified_target]
+ #[arg.split('-Wl,')[1] for arg in filter(lambda arg: arg.startswith('-Wl,'), sys.argv)]
+ if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(ld_args)
+ Popen([shared.LLVM_LINK] + ld_args).communicate()
exit(0)
## Continue on to create JavaScript
@@ -389,7 +416,7 @@ try:
if need_dlmalloc and not has_dlmalloc:
# We need to build and link dlmalloc in
if DEBUG: print >> sys.stderr, 'emcc: including dlmalloc'
- Popen([shared.EMCC, shared.path_from_root('src', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')]).communicate()
+ Popen([shared.EMCC, shared.path_from_root('src', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=PIPE, stderr=PIPE).communicate()
if llvm_opt_level > 0:
shared.Building.llvm_opt(in_temp('dlmalloc.o'), LLVM_INTERNAL_OPT_LEVEL, safe=llvm_opt_level < 2)
extra_files_to_link.append(in_temp('dlmalloc.o'))
@@ -408,7 +435,7 @@ try:
if len(input_files) + len(extra_files_to_link) > 1:
shared.Building.link(map(lambda input_file: in_temp(unsuffixed_basename(input_file) + '.o'), input_files) + extra_files_to_link,
in_temp(target_basename + '.bc'))
- # TODO: LLVM link-time opts?
+ # TODO: LLVM link-time opts? here and/or elsewhere?
else:
shutil.move(in_temp(unsuffixed_basename(input_files[0]) + '.o'), in_temp(target_basename + '.bc'))