diff options
53 files changed, 2329 insertions, 1780 deletions
@@ -113,3 +113,4 @@ a license to everyone to use it as detailed in LICENSE.) * Heidi Pan <heidi.pan@intel.com> (copyright owned by Intel) * Vasilis Kalintiris <ehostunreach@gmail.com> * Adam C. Clifton <adam@hulkamaniac.com> +* Volo Zyko <volo.zyko@gmail.com> diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake index c30632ca..4f434d14 100644 --- a/cmake/Platform/Emscripten.cmake +++ b/cmake/Platform/Emscripten.cmake @@ -109,6 +109,8 @@ set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@") # Specify the program to use when building static libraries. Force Emscripten-related command line options to clang. set(CMAKE_CXX_ARCHIVE_CREATE "${CMAKE_AR} rc <TARGET> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <OBJECTS>${CMAKE_END_TEMP_FILE}") set(CMAKE_C_ARCHIVE_CREATE "${CMAKE_AR} rc <TARGET> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <OBJECTS>${CMAKE_END_TEMP_FILE}") +set(CMAKE_CXX_ARCHIVE_APPEND "${CMAKE_AR} r <TARGET> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <OBJECTS>${CMAKE_END_TEMP_FILE}") +set(CMAKE_C_ARCHIVE_APPEND "${CMAKE_AR} r <TARGET> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <OBJECTS>${CMAKE_END_TEMP_FILE}") # Set a global EMSCRIPTEN variable that can be used in client CMakeLists.txt to detect when building using Emscripten. # There seems to be some kind of bug with CMake, so you might need to define this manually on the command line with "-DEMSCRIPTEN=1". @@ -122,22 +124,22 @@ SET(APPLE) set(CMAKE_C_SIZEOF_DATA_PTR 4) set(CMAKE_CXX_SIZEOF_DATA_PTR 4) -set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELEASE") -set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_MINSIZEREL") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELWITHDEBINFO") -set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELEASE") -set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_MINSIZEREL") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELWITHDEBINFO") +set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELEASE") +set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_MINSIZEREL") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELWITHDEBINFO") +set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELEASE") +set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_MINSIZEREL") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELWITHDEBINFO") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELEASE") set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_MINSIZEREL") -set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO") set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELEASE") set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL") -set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO") +set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO") set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELEASE") set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL") -set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO") +set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO") function(em_validate_asmjs_after_build target) add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo Validating build output for asm.js... COMMAND "python" ARGS "${EMSCRIPTEN_ROOT_PATH}/tools/validate_asmjs.py" "$<TARGET_FILE:${target}>") @@ -203,3 +205,24 @@ endfunction() function(em_link_post_js target) em_add_tracked_link_flag(${target} "--post-js" ${ARGN}) endfunction() + +# Experimental support for targeting generation of Visual Studio project files (vs-tool) of Emscripten projects for Windows. +# To use this, pass the combination -G "Visual Studio 10" -DCMAKE_TOOLCHAIN_FILE=Emscripten.cmake +if ("${CMAKE_GENERATOR}" MATCHES "^Visual Studio.*") + # By default, CMake generates VS project files with a <GenerateManifest>true</GenerateManifest> directive. + # This causes VS to attempt to invoke rc.exe during the build, which will fail since app manifests are meaningless for Emscripten. + # To disable this, add the following linker flag. This flag will not go to emcc, since the Visual Studio CMake generator will swallow it. + set(EMSCRIPTEN_VS_LINKER_FLAGS "/MANIFEST:NO") + # CMake is hardcoded to write a ClCompile directive <ObjectFileName>$(IntDir)</ObjectFileName> in all VS project files it generates. + # This makes VS pass emcc a -o param that points to a directory instead of a file, which causes emcc autogenerate the output filename. + # CMake is hardcoded to assume all object files have the suffix .obj, so adjust the emcc-autogenerated default suffix name to match. + set(EMSCRIPTEN_VS_LINKER_FLAGS "${EMSCRIPTEN_VS_LINKER_FLAGS} --default-obj-ext .obj") + # Also hint CMake that it should not hardcode <ObjectFileName> generation. Requires a custom CMake build for this to work (ignored on others) + # See http://www.cmake.org/Bug/view.php?id=14673 and https://github.com/juj/CMake + set(CMAKE_VS_NO_DEFAULT_OBJECTFILENAME 1) + + # Apply and cache Emscripten Visual Studio IDE-specific linker flags. + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EMSCRIPTEN_VS_LINKER_FLAGS}" CACHE STRING "") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${EMSCRIPTEN_VS_LINKER_FLAGS}" CACHE STRING "") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${EMSCRIPTEN_VS_LINKER_FLAGS}" CACHE STRING "") +endif() @@ -53,14 +53,17 @@ from tools import shared, jsrun from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename, WINDOWS from tools.response_file import read_response_file -C_SUFFIXES = ('.c', '.C') -CXX_SUFFIXES = ('.cpp', '.cxx', '.cc', '.CPP', '.CXX', '.CC') -SOURCE_SUFFIXES = C_SUFFIXES + CXX_SUFFIXES + ('.m', '.mm') -BITCODE_SUFFIXES = ('.bc', '.o', '.obj') -DYNAMICLIB_SUFFIXES = ('.dylib', '.so', '.dll') -STATICLIB_SUFFIXES = ('.a',) -ASSEMBLY_SUFFIXES = ('.ll',) +# endings = dot + a suffix, safe to test by filename.endswith(endings) +C_ENDINGS = ('.c', '.C') +CXX_ENDINGS = ('.cpp', '.cxx', '.cc', '.CPP', '.CXX', '.CC') +SOURCE_ENDINGS = C_ENDINGS + CXX_ENDINGS + ('.m', '.mm') +BITCODE_ENDINGS = ('.bc', '.o', '.obj') +DYNAMICLIB_ENDINGS = ('.dylib', '.so', '.dll') +STATICLIB_ENDINGS = ('.a',) +ASSEMBLY_ENDINGS = ('.ll',) + LIB_PREFIXES = ('', 'lib') + JS_CONTAINING_SUFFIXES = ('js', 'html') # Mapping of emcc opt levels to llvm opt levels. We use llvm opt level 3 in emcc opt @@ -345,7 +348,9 @@ Options that are modified or new in %s include: --embed-file and --preload-file wildcard is supported - --compression <codec> Compress both the compiled code and embedded/ + --compression <codec> **THIS OPTION IS DEPRECATED** + + Compress both the compiled code and embedded/ preloaded files. <codec> should be a triple, <native_encoder>,<js_decoder>,<js_name> @@ -514,6 +519,13 @@ Options that are modified or new in %s include: file, and if that is not set, the default location ~/.emscripten is assumed. + --default-obj-ext .ext Specifies the file suffix to generate if the location + of a directory name is passed to -o directive, e.g. + emcc -c a.c -o dir/ + will by default generate an output name 'dir/a.o', + but this cmdline param can be passed to generate a + file with a custom suffix 'dir/a.ext'. + The target file, if specified (-o <target>), defines what will be generated: @@ -762,9 +774,13 @@ def in_temp(name): def filename_type_suffix(filename): for i in reversed(filename.split('.')[1:]): if not i.isdigit(): - return '.' + i + return i return '' +def filename_type_ending(filename): + suffix = filename_type_suffix(filename) + return '' if not suffix else ('.' + suffix) + try: call = CXX if use_cxx else CC @@ -797,6 +813,7 @@ try: use_preload_cache = False no_heap_copy = False proxy_to_worker = False + default_object_extension = '.o' if use_cxx: default_cxx_std = '-std=c++03' # Enforce a consistent C++ standard when compiling .cpp files, if user does not specify one on the cmdline. @@ -907,6 +924,7 @@ try: newargs[i] = '' newargs[i+1] = '' elif newargs[i].startswith('--compression'): + logging.warning('--compression is deprecated. Instead, it is recommended you use native gzip compression in your webserver') check_bad_eq(newargs[i]) parts = newargs[i+1].split(',') assert len(parts) == 3, '--compression requires specifying native_encoder,js_decoder,js_name - see emcc --help. got: %s' % newargs[i+1] @@ -992,6 +1010,12 @@ try: # This option is parsed in tools/shared.py, here only clean it up from being passed to clang. newargs[i] = '' newargs[i+1] = '' + elif newargs[i] == '--default-obj-ext': + newargs[i] = '' + default_object_extension = newargs[i+1] + if not default_object_extension.startswith('.'): + default_object_extension = '.' + default_object_extension + newargs[i+1] = '' newargs = [ arg for arg in newargs if arg is not '' ] @@ -1053,23 +1077,23 @@ try: 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', '-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)): + if (os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS)): arg = os.path.realpath(arg) if not arg.startswith('-'): if not os.path.exists(arg): - logging.error(arg + ': No such file or directory') + logging.error('%s: No such file or directory ("%s" was expected to be an input file, based on the commandline arguments provided)' % (arg, arg)) 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 + arg_ending = filename_type_ending(arg) + if arg_ending.endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS) 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): + if arg_ending.endswith(SOURCE_ENDINGS): 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 + elif arg_ending.endswith(ASSEMBLY_ENDINGS) 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): + elif arg_ending.endswith(STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS): # 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: @@ -1081,10 +1105,10 @@ try: newargs[i] = '' else: logging.warning(arg + ' is not valid LLVM bitcode') - elif arg_suffix.endswith(STATICLIB_SUFFIXES): + elif arg_ending.endswith(STATICLIB_ENDINGS): 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)) + logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_ENDINGS) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_ENDINGS)) else: logging.error(arg + ': Unknown format, not a static library!') exit(1) @@ -1109,17 +1133,12 @@ try: target = target_basename + '.o' final_suffix = 'o' - # do not link in libs when just generating object code (not an 'executable', i.e. JS, or a library) - if ('.' + final_suffix) in BITCODE_SUFFIXES and len(libs) > 0: - logging.warning('not linking against libraries since only compiling to bitcode') - libs = [] - # Find library files for lib in libs: logging.debug('looking for library "%s"' % lib) found = False for prefix in LIB_PREFIXES: - for suff in STATICLIB_SUFFIXES + DYNAMICLIB_SUFFIXES: + for suff in STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS: name = prefix + lib + suff for lib_dir in lib_dirs: path = os.path.join(lib_dir, name) @@ -1130,12 +1149,21 @@ try: break if found: break if found: break - - if ignore_dynamic_linking: - input_files = filter(lambda input_file: not input_file.endswith(DYNAMICLIB_SUFFIXES), input_files) + if not found: logging.warning('emcc: cannot find library "%s"' % lib) + + # If not compiling to JS, then we are compiling to an intermediate bitcode objects or library, so + # ignore dynamic linking, since multiple dynamic linkings can interfere with each other + if not filename_type_suffix(target) in JS_CONTAINING_SUFFIXES or ignore_dynamic_linking: + def check(input_file): + if filename_type_ending(input_file) in DYNAMICLIB_ENDINGS: + if not ignore_dynamic_linking: logging.warning('ignoring dynamic library %s because not compiling to JS or HTML, remember to link it when compiling to JS or HTML at the end' % os.path.basename(input_file)) + return False + else: + return True + input_files = filter(lambda input_file: check(input_file), input_files) if len(input_files) == 0: - logging.error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_SUFFIXES + BITCODE_SUFFIXES + DYNAMICLIB_SUFFIXES + STATICLIB_SUFFIXES + ASSEMBLY_SUFFIXES)) + logging.error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + STATICLIB_ENDINGS + ASSEMBLY_ENDINGS)) exit(0) newargs = CC_ADDITIONAL_ARGS + newargs @@ -1162,7 +1190,9 @@ try: logging.warning('disabling asm.js since embind is not ready for it yet') shared.Settings.ASM_JS = 0 - if os.environ.get('EMCC_FAST_COMPILER'): + fastcomp = os.environ.get('EMCC_FAST_COMPILER') == '1' + + if fastcomp: shared.Settings.ASM_JS = 1 if shared.Settings.DISABLE_EXCEPTION_CATCHING == 0: logging.warning('disabling exception catching since not supported in fastcomp yet') @@ -1181,9 +1211,12 @@ try: assert shared.Settings.PGO == 0, 'pgo not supported in fastcomp' assert shared.Settings.TARGET_LE32 == 1, 'fastcomp requires le32' assert not bind, 'embind not supported in fastcomp yet' + if jcache: + logging.warning('jcache is not supported in fastcomp (you should not need it anyhow), disabling') + jcache = False if shared.Settings.ASM_JS: - assert opt_level >= 1 or os.environ.get('EMCC_FAST_COMPILER'), 'asm.js requires -O1 or above' + assert opt_level >= 1 or fastcomp, 'asm.js requires -O1 or above' if bind: shared.Settings.RESERVED_FUNCTION_POINTERS = max(shared.Settings.RESERVED_FUNCTION_POINTERS, 10) @@ -1195,16 +1228,6 @@ try: shared.Settings.CORRECT_OVERFLOWS = 1 assert not shared.Settings.PGO, 'cannot run PGO in ASM_JS mode' - heap = 4096 - while heap < shared.Settings.TOTAL_MEMORY: - if heap < 16*1024*1024: - heap *= 2 - else: - heap += 16*1024*1024 - if heap != shared.Settings.TOTAL_MEMORY: - logging.warning('increasing TOTAL_MEMORY to %d to be more reasonable for asm.js' % heap) - shared.Settings.TOTAL_MEMORY = heap - if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2: debug_level = 4 # must keep debug info to do line-by-line operations @@ -1272,14 +1295,14 @@ try: # First, generate LLVM bitcode. For each input file, we get base.o with bitcode for input_file in input_files: - file_suffix = filename_type_suffix(input_file) - if file_suffix.endswith(SOURCE_SUFFIXES): + 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') temp_files.append(output_file) args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file] - if file_suffix.endswith(CXX_SUFFIXES): + if file_ending.endswith(CXX_ENDINGS): 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) @@ -1287,17 +1310,17 @@ try: logging.error('compiler frontend failed to generate LLVM bitcode, halting') sys.exit(1) else: # bitcode - if file_suffix.endswith(BITCODE_SUFFIXES): + if file_ending.endswith(BITCODE_ENDINGS): 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 file_suffix.endswith(DYNAMICLIB_SUFFIXES) or shared.Building.is_ar(input_file): + elif file_ending.endswith(DYNAMICLIB_ENDINGS) 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) - elif file_suffix.endswith(ASSEMBLY_SUFFIXES): + elif file_ending.endswith(ASSEMBLY_ENDINGS): 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 @@ -1315,8 +1338,8 @@ try: # Optimize source files if llvm_opts > 0: for i, input_file in enumerate(input_files): - file_suffix = filename_type_suffix(input_file) - if file_suffix.endswith(SOURCE_SUFFIXES): + file_ending = filename_type_ending(input_file) + if file_ending.endswith(SOURCE_ENDINGS): temp_file = temp_files[i] logging.debug('optimizing %s with -O%s' % (input_file, llvm_opts)) shared.Building.llvm_opt(temp_file, llvm_opts) @@ -1329,7 +1352,16 @@ try: else: if len(input_files) == 1: temp_output_base = in_temp(unsuffixed(uniquename(input_files[0]))) - shutil.move(temp_output_base + '.o', specified_target) + 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) + 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) 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. @@ -1661,11 +1693,11 @@ try: # First, combine the bitcode files if there are several. We must also link if we have a singleton .a if len(input_files) + len(extra_files_to_link) > 1 or \ - (not LEAVE_INPUTS_RAW and not (suffix(temp_files[0]) in BITCODE_SUFFIXES or suffix(temp_files[0]) in DYNAMICLIB_SUFFIXES) and shared.Building.is_ar(temp_files[0])): + (not LEAVE_INPUTS_RAW and not (suffix(temp_files[0]) in BITCODE_ENDINGS or suffix(temp_files[0]) in DYNAMICLIB_ENDINGS) and shared.Building.is_ar(temp_files[0])): linker_inputs = temp_files + extra_files_to_link logging.debug('linking: ' + str(linker_inputs)) t0 = time.time() - shared.Building.link(linker_inputs, in_temp(target_basename + '.bc'), force_archive_contents = len(filter(lambda temp: not temp.endswith(STATICLIB_SUFFIXES), temp_files)) == 0) + shared.Building.link(linker_inputs, in_temp(target_basename + '.bc'), force_archive_contents = len(filter(lambda temp: not temp.endswith(STATICLIB_ENDINGS), temp_files)) == 0) t1 = time.time() logging.debug(' linking took %.2f seconds' % (t1 - t0)) final = in_temp(target_basename + '.bc') @@ -1711,22 +1743,25 @@ try: # At minimum remove dead functions etc., this potentially saves a lot in the size of the generated code (and the time to compile it) link_opts += shared.Building.get_safe_internalize() + ['-globaldce'] - # Simplify LLVM bitcode for fastcomp - if os.environ.get('EMCC_FAST_COMPILER') and not AUTODEBUG: - link_opts += ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'] - if (not save_bc and not os.environ.get('EMCC_FAST_COMPILER')) or AUTODEBUG: + if (not save_bc and not fastcomp) or AUTODEBUG: # let llvm opt directly emit ll, to skip writing and reading all the bitcode link_opts += ['-S'] shared.Building.llvm_opt(final, link_opts, final + '.link.ll') final = final + '.link.ll' if DEBUG: save_intermediate('linktime', 'll') else: + if fastcomp and not save_bc: + # Simplify LLVM bitcode for fastcomp + link_opts += ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'] shared.Building.llvm_opt(final, link_opts) if DEBUG: save_intermediate('linktime', 'bc') - - if save_bc: - shutil.copyfile(final, save_bc) + if save_bc: + shutil.copyfile(final, save_bc) + if fastcomp: + shared.Building.llvm_opt(final, ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'], final + '.adsimp.bc') + final += '.adsimp.bc' + if DEBUG: save_intermediate('adsimp', 'bc') # Prepare .ll for Emscripten if not LEAVE_INPUTS_RAW: @@ -1743,7 +1778,7 @@ try: if DEBUG: save_intermediate('autodebug', 'll') # Simplify bitcode after autodebug - if os.environ.get('EMCC_FAST_COMPILER') and AUTODEBUG: + if fastcomp and (AUTODEBUG or LEAVE_INPUTS_RAW): shared.Building.llvm_opt(final, ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt'], final + '.adsimp.bc') final += '.adsimp.bc' if DEBUG: save_intermediate('adsimp', 'bc') |