diff options
Diffstat (limited to 'tools/shared.py')
-rw-r--r-- | tools/shared.py | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/tools/shared.py b/tools/shared.py index 7f633318..ba953e19 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -90,6 +90,7 @@ CLANG_CPP=os.path.expanduser(os.path.join(LLVM_ROOT, 'clang++')) CLANG=CLANG_CPP LLVM_LINK=os.path.join(LLVM_ROOT, 'llvm-link') LLVM_LD=os.path.join(LLVM_ROOT, 'llvm-ld') +LLVM_AR=os.path.join(LLVM_ROOT, 'llvm-ar') LLVM_OPT=os.path.expanduser(os.path.join(LLVM_ROOT, 'opt')) LLVM_AS=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-as')) LLVM_DIS=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-dis')) @@ -450,18 +451,18 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' \ stderr=open(os.path.join(project_dir, 'configure_err'), 'w'), env=env) Building.make(make + make_args, stdout=open(os.path.join(project_dir, 'make_'), 'w'), stderr=open(os.path.join(project_dir, 'make_err'), 'w'), env=env) - bc_file = os.path.join(project_dir, 'bc.bc') - Building.link(generated_libs, bc_file) if cache is not None: - cache[cache_name] = open(bc_file, 'rb').read() + cache[cache_name] = {} + for f in generated_libs: + cache[cache_name][f] = open(f, 'rb').read() if old_dir: os.chdir(old_dir) - return bc_file + return generated_libs @staticmethod def link(files, target): try_delete(target) - output = Popen([LLVM_LINK] + files + ['-o', target], stdout=PIPE).communicate()[0] + output = Popen([LLVM_LD, '-disable-opt'] + files + ['-b', target], stdout=PIPE).communicate()[0] assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output # Emscripten optimizations that we run on the .ll file @@ -553,6 +554,13 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' \ assert os.path.exists(output_filename), 'emcc could not create output file' @staticmethod + def emar(action, output_filename, filenames, stdout=None, stderr=None, env=None): + try_delete(output_filename) + Popen([EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate() + if 'c' in action: + assert os.path.exists(output_filename), 'emar could not create output file' + + @staticmethod def emscripten(filename, append_ext=True, extra_args=[]): # Allow usage of emscripten.py without warning os.environ['EMSCRIPTEN_SUPPRESS_USAGE_WARNING'] = '1' @@ -732,6 +740,22 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' \ return filename + '.cc.js' + _is_ar_cache = {} + @staticmethod + def is_ar(filename): + try: + if Building._is_ar_cache.get(filename): + return Building._is_ar_cache[filename] + b = open(filename, 'r').read(8) + sigcheck = b[0] == '!' and b[1] == '<' and \ + b[2] == 'a' and b[3] == 'r' and \ + b[4] == 'c' and b[5] == 'h' and \ + b[6] == '>' and ord(b[7]) == 10 + Building._is_ar_cache[filename] = sigcheck + return sigcheck + except: + return False + @staticmethod def is_bitcode(filename): # checks if a file contains LLVM bitcode @@ -740,9 +764,13 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' \ defs = Building.llvm_nm(filename, stderr=PIPE) # If no symbols found, it might just be an empty bitcode file, try to dis it if len(defs.defs) + len(defs.undefs) + len(defs.commons) == 0: - test_ll = os.path.join(EMSCRIPTEN_TEMP_DIR, 'test.ll') - Building.llvm_dis(filename, test_ll) - assert os.path.exists(test_ll) + # llvm-nm 3.0 has a bug when reading symbols from ar files + # so try to see if we're dealing with an ar file, in which + # case we should try to dis it. + if not Building.is_ar(filename): + test_ll = os.path.join(EMSCRIPTEN_TEMP_DIR, 'test.ll') + Building.llvm_dis(filename, test_ll) + assert os.path.exists(test_ll) except: return False @@ -750,6 +778,9 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' \ b = open(filename, 'r').read(4) if b[0] == 'B' and b[1] == 'C': return True + # look for ar signature + elif Building.is_ar(filename): + return True # on OS X, there is a 20-byte prefix elif ord(b[0]) == 222 and ord(b[1]) == 192 and ord(b[2]) == 23 and ord(b[3]) == 11: b = open(filename, 'r').read(24) |