aboutsummaryrefslogtreecommitdiff
path: root/emcc
diff options
context:
space:
mode:
Diffstat (limited to 'emcc')
-rwxr-xr-xemcc132
1 files changed, 100 insertions, 32 deletions
diff --git a/emcc b/emcc
index cd42d49a..ff81e424 100755
--- a/emcc
+++ b/emcc
@@ -720,6 +720,13 @@ else:
def in_temp(name):
return os.path.join(temp_dir, os.path.basename(name))
+# Parses the essential suffix of a filename, discarding Unix-style version numbers in the name. For example for 'libz.so.1.2.8' returns '.so'
+def filename_type_suffix(filename):
+ for i in reversed(filename.split('.')[1:]):
+ if not i.isdigit():
+ return '.' + i
+ return ''
+
try:
call = CXX if use_cxx else CC
@@ -926,7 +933,7 @@ try:
if default_cxx_std:
newargs = newargs + [default_cxx_std]
- if js_opts is None: js_opts = True
+ if js_opts is None: js_opts = opt_level >= 1
if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level]
if llvm_lto is None and opt_level >= 3: llvm_lto = 3
if opt_level == 0: debug_level = 4
@@ -974,35 +981,45 @@ try:
if i > 0:
prev = newargs[i-1]
- if prev in ['-MT', '-MF', '-MQ', '-D', '-U', '-o', '-x', '-Xpreprocessor', '-include', '-imacros', '-idirafter', '-iprefix', '-iwithprefix', '-iwithprefixbefore', '-isysroot', '-imultilib', '-A', '-isystem', '-iquote', '-install_name', '-I', '-L']: continue # ignore this gcc-style argument
+ if prev in ['-MT', '-MF', '-MQ', '-D', '-U', '-o', '-x', '-Xpreprocessor', '-include', '-imacros', '-idirafter', '-iprefix', '-iwithprefix', '-iwithprefixbefore', '-isysroot', '-imultilib', '-A', '-isystem', '-iquote', '-install_name', '-compatibility_version', '-current_version', '-I', '-L']: continue # ignore this gcc-style argument
if (os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES)):
arg = os.path.realpath(arg)
- if not arg.startswith('-') and (arg.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES) or shared.Building.is_ar(arg)): # we already removed -o <target>, so all these should be inputs
- newargs[i] = ''
- if os.path.exists(arg):
- if arg.endswith(SOURCE_SUFFIXES):
+ if not arg.startswith('-'):
+ if not os.path.exists(arg):
+ logging.error(arg + ': No such file or directory')
+ exit(1)
+
+ arg_suffix = filename_type_suffix(arg)
+ if arg_suffix.endswith(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + ASSEMBLY_SUFFIXES) or shared.Building.is_ar(arg): # we already removed -o <target>, so all these should be inputs
+ newargs[i] = ''
+ if arg_suffix.endswith(SOURCE_SUFFIXES):
input_files.append(arg)
has_source_inputs = True
+ elif arg_suffix.endswith(ASSEMBLY_SUFFIXES) or shared.Building.is_bitcode(arg): # this should be bitcode, make sure it is valid
+ input_files.append(arg)
+ elif arg_suffix.endswith(STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES):
+ # if it's not, and it's a library, just add it to libs to find later
+ l = unsuffixed_basename(arg)
+ for prefix in LIB_PREFIXES:
+ if not prefix: continue
+ if l.startswith(prefix):
+ l = l[len(prefix):]
+ break
+ libs.append(l)
+ newargs[i] = ''
else:
- # this should be bitcode, make sure it is valid
- if arg.endswith(ASSEMBLY_SUFFIXES) or shared.Building.is_bitcode(arg):
- input_files.append(arg)
- elif arg.endswith(STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES):
- # if it's not, and it's a library, just add it to libs to find later
- l = unsuffixed_basename(arg)
- for prefix in LIB_PREFIXES:
- if not prefix: continue
- if l.startswith(prefix):
- l = l[len(prefix):]
- break
- libs.append(l)
- newargs[i] = ''
+ logging.warning(arg + ' is not valid LLVM bitcode')
+ elif arg_suffix.endswith(STATICLIB_SUFFIXES):
+ if not shared.Building.is_ar(arg):
+ if shared.Building.is_bitcode(arg):
+ logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_SUFFIXES) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_SUFFIXES))
else:
- logging.warning(arg + ' is not valid LLVM bitcode')
+ logging.error(arg + ': Unknown format, not a static library!')
+ exit(1)
else:
- logging.error(arg + ': No such file or directory')
+ logging.error(arg + ": Input file has an unknown suffix, don't know what to do with it!")
exit(1)
elif arg.startswith('-L'):
lib_dirs.append(arg[2:])
@@ -1119,6 +1136,7 @@ try:
if shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE:
assert not memory_init_file, 'memory init file is not supported with module linking'
+ assert shared.Settings.ASM_JS, 'module linking requires asm.js output (-s ASM_JS=1)'
shared.Settings.LINKABLE = 1 # TODO: add FORCE_DCE option for the brave people that do want to dce here and in side modules
debug_level = max(debug_level, 2)
@@ -1143,6 +1161,9 @@ try:
if proxy_to_worker:
shared.Settings.PROXY_TO_WORKER = 1
+ if js_opts:
+ shared.Settings.RUNNING_JS_OPTS = 1
+
## Compile source code to bitcode
logging.debug('compiling to bitcode')
@@ -1151,13 +1172,14 @@ try:
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
for input_file in input_files:
- if input_file.endswith(SOURCE_SUFFIXES):
+ file_suffix = filename_type_suffix(input_file)
+ if file_suffix.endswith(SOURCE_SUFFIXES):
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')
temp_files.append(output_file)
args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file]
- if input_file.endswith(CXX_SUFFIXES):
+ if file_suffix.endswith(CXX_SUFFIXES):
args += shared.EMSDK_CXX_OPTS
logging.debug("running: " + call + ' ' + ' '.join(args))
execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
@@ -1165,17 +1187,17 @@ try:
logging.error('compiler frontend failed to generate LLVM bitcode, halting')
sys.exit(1)
else: # bitcode
- if input_file.endswith(BITCODE_SUFFIXES):
+ if file_suffix.endswith(BITCODE_SUFFIXES):
logging.debug('copying bitcode file: ' + input_file)
temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o')
shutil.copyfile(input_file, temp_file)
temp_files.append(temp_file)
- elif input_file.endswith(DYNAMICLIB_SUFFIXES) or shared.Building.is_ar(input_file):
+ elif file_suffix.endswith(DYNAMICLIB_SUFFIXES) or shared.Building.is_ar(input_file):
logging.debug('copying library file: ' + input_file)
temp_file = in_temp(uniquename(input_file))
shutil.copyfile(input_file, temp_file)
temp_files.append(temp_file)
- else: #.ll
+ elif file_suffix.endswith(ASSEMBLY_SUFFIXES):
if not LEAVE_INPUTS_RAW:
# Note that by assembling the .ll file, then disassembling it later, we will
# remove annotations which is a good thing for compilation time
@@ -1183,6 +1205,9 @@ try:
temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o')
shared.Building.llvm_as(input_file, temp_file)
temp_files.append(temp_file)
+ else:
+ logging.error(input_file + ': Unknown file suffix when compiling to LLVM bitcode!')
+ sys.exit(1)
if not LEAVE_INPUTS_RAW:
assert len(temp_files) == len(input_files)
@@ -1190,7 +1215,8 @@ try:
# Optimize source files
if llvm_opts > 0:
for i, input_file in enumerate(input_files):
- if input_file.endswith(SOURCE_SUFFIXES):
+ file_suffix = filename_type_suffix(input_file)
+ if file_suffix.endswith(SOURCE_SUFFIXES):
temp_file = temp_files[i]
logging.debug('optimizing %s with -O%d' % (input_file, llvm_opts))
shared.Building.llvm_opt(temp_file, llvm_opts)
@@ -1217,7 +1243,7 @@ try:
extra_files_to_link = []
- if not LEAVE_INPUTS_RAW and not AUTODEBUG and \
+ if not LEAVE_INPUTS_RAW and \
not shared.Settings.BUILD_AS_SHARED_LIB == 2 and \
not shared.Settings.SIDE_MODULE: # shared libraries/side modules link no C libraries, need them in parent
@@ -1282,6 +1308,10 @@ try:
os.path.join('libc', 'gen', 'vwarnx.c'),
os.path.join('libc', 'stdlib', 'strtod.c'),
]
+ musl_files = [
+ ]
+ for directory, sources in musl_files:
+ libc_files += [os.path.join('libc', 'musl', 'src', directory, source) for source in sources]
return build_libc('libc.bc', libc_files)
def apply_libc(need):
@@ -1319,6 +1349,33 @@ try:
'wctrans.c',
'wcwidth.c',
]],
+ ['locale', [
+ 'iconv.c',
+ 'iswalnum_l.c',
+ 'iswalpha_l.c',
+ 'iswblank_l.c',
+ 'iswcntrl_l.c',
+ 'iswctype_l.c',
+ 'iswdigit_l.c',
+ 'iswgraph_l.c',
+ 'iswlower_l.c',
+ 'iswprint_l.c',
+ 'iswpunct_l.c',
+ 'iswspace_l.c',
+ 'iswupper_l.c',
+ 'iswxdigit_l.c',
+ 'strfmon.c',
+ 'strxfrm.c',
+ 'towctrans_l.c',
+ 'towlower_l.c',
+ 'towupper_l.c',
+ 'wcscoll.c',
+ 'wcscoll_l.c',
+ 'wcsxfrm.c',
+ 'wcsxfrm_l.c',
+ 'wctrans_l.c',
+ 'wctype_l.c',
+ ]],
['multibyte', [
'btowc.c',
'mblen.c',
@@ -1336,6 +1393,14 @@ try:
'wctob.c',
'wctomb.c',
]],
+ ['stdio', [
+ 'fwprintf.c',
+ 'swprintf.c',
+ 'vfwprintf.c',
+ 'vswprintf.c',
+ 'vwprintf.c',
+ 'wprintf.c',
+ ]],
['stdlib', [
'ecvt.c',
'fcvt.c',
@@ -1345,7 +1410,7 @@ try:
'wcpcpy.c',
'wcpncpy.c',
'wcscasecmp.c',
- # 'wcscasecmp_l.c', # XXX: alltypes.h issue
+ 'wcscasecmp_l.c',
'wcscat.c',
'wcschr.c',
'wcscmp.c',
@@ -1354,7 +1419,7 @@ try:
'wcsdup.c',
'wcslen.c',
'wcsncasecmp.c',
- # 'wcsncasecmp_l.c', # XXX: alltypes.h issue
+ 'wcsncasecmp_l.c',
'wcsncat.c',
'wcsncmp.c',
'wcsncpy.c',
@@ -1642,7 +1707,7 @@ try:
global final, js_optimizer_queue, js_optimizer_extra_info
if len(js_optimizer_extra_info) == 0:
js_optimizer_extra_info = None
- if len(js_optimizer_queue) > 0 and not(len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'):
+ if len(js_optimizer_queue) > 0 and not(not shared.Settings.ASM_JS and len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'):
if DEBUG != '2':
if shared.Settings.ASM_JS:
js_optimizer_queue = ['asm'] + js_optimizer_queue
@@ -1677,7 +1742,10 @@ try:
else:
return 'eliminate'
- js_optimizer_queue += [get_eliminate(), 'simplifyExpressions']
+ js_optimizer_queue += [get_eliminate()]
+
+ if opt_level >= 2:
+ js_optimizer_queue += ['simplifyExpressions']
if closure and not shared.Settings.ASM_JS:
flush_js_optimizer_queue()