aboutsummaryrefslogtreecommitdiff
path: root/tools/shared.py
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-02-09 10:41:19 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-02-09 10:41:19 -0800
commit18d7818121e8501ccd01962acd36aa9f45843b52 (patch)
tree80e2ab18281bb20235f3e8ccc02b27fb5b8f4ec7 /tools/shared.py
parent721212235f16f5c5ff0857b5f71743b054ed5a46 (diff)
parent88d76d4ad9a8a4f6ec4fa7a2d3ef765706b01950 (diff)
Merge pull request #228 from ehsan/use_ar_upstream
Use emar for creating static libraries and ld for linking
Diffstat (limited to 'tools/shared.py')
-rw-r--r--tools/shared.py47
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)