Skip to content

Commit

Permalink
Allow the PNaCl toolchain to be used in place of a standard version o…
Browse files Browse the repository at this point in the history
…f Clang.

The main differences between PNaCl and standard Clang are that the tools are
prefixed with "pnacl-" instead of "llvm-" and PNaCl does not accept "-o=file"
style arguments, and requires them to be specified as "-o file".
  • Loading branch information
ncbray authored and kripken committed Aug 8, 2013
1 parent 30a929e commit 34229a7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
6 changes: 3 additions & 3 deletions scons-tools/llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def generate(env):
LLVM_LINK='llvm-link')

env['BUILDERS']['LLVMDis'] = Builder(
action=os.path.join('${LLVM_ROOT}', '$LLVM_DIS') + ' -o=$TARGET $SOURCE')
action=os.path.join('${LLVM_ROOT}', '$LLVM_DIS') + ' -o $TARGET $SOURCE')

env['BUILDERS']['LLVMOpt'] = Builder(
action=os.path.join('${LLVM_ROOT}', '$LLVM_OPT') + ' $LLVM_OPT_FLAGS $LLVM_OPT_PASSES -o=$TARGET $SOURCE')
action=os.path.join('${LLVM_ROOT}', '$LLVM_OPT') + ' $LLVM_OPT_FLAGS $LLVM_OPT_PASSES -o $TARGET $SOURCE')

env['BUILDERS']['LLVMLink'] = Builder(
action=os.path.join('${LLVM_ROOT}', '$LLVM_LINK') + ' -o=$TARGET $SOURCES',
action=os.path.join('${LLVM_ROOT}', '$LLVM_LINK') + ' -o $TARGET $SOURCES',
emitter=add_libraries)
4 changes: 2 additions & 2 deletions tools/exec_llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ def path_from_root(*pathelems):
sys.path += [path_from_root('')]
from tools.shared import *

Popen([LLVM_OPT, sys.argv[1], '-strip-debug', '-o=' + sys.argv[1]+'.clean.bc']).communicate()[0]
Popen([LLVM_OPT, sys.argv[1], '-strip-debug', '-o', sys.argv[1]+'.clean.bc']).communicate()[0]

# Execute with empty environment - just like the JS script will have
Popen([LLVM_INTERPRETER, sys.argv[1]+'.clean.bc'] + sys.argv[2:], env={'HOME': '.'}).communicate()[0]

#Popen([LLVM_COMPILER, '-march=c', sys.argv[1], '-o=' + sys.argv[1]+'.cbe.c']).communicate()[0]
#Popen([LLVM_COMPILER, '-march=c', sys.argv[1], '-o', sys.argv[1]+'.cbe.c']).communicate()[0]
#Popen(['gcc', sys.argv[1]+'.cbe.c', '-lstdc++']).communicate()[0]
#Popen(['./a.out'] + sys.argv[2:]).communicate()[0]

4 changes: 2 additions & 2 deletions tools/nativize_llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ def path_from_root(*pathelems):
libs = sys.argv[2:] # e.g.: dl for dlopen/dlclose, util for openpty/forkpty

print 'bc => clean bc'
Popen([LLVM_OPT, filename, '-strip-debug', '-o=' + filename + '.clean.bc']).communicate()[0]
Popen([LLVM_OPT, filename, '-strip-debug', '-o', filename + '.clean.bc']).communicate()[0]
print 'bc => s'
for params in [[], ['-march=x86-64']]: # try x86, then x86-64 FIXME
print 'params', params
Popen([LLVM_COMPILER] + params + [filename + '.clean.bc', '-o=' + filename + '.s']).communicate()[0]
Popen([LLVM_COMPILER] + params + [filename + '.clean.bc', '-o', filename + '.s']).communicate()[0]
print 's => o'
Popen(['as', filename + '.s', '-o', filename + '.o']).communicate()[0]
if os.path.exists(filename + '.o'): break
Expand Down
36 changes: 28 additions & 8 deletions tools/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def check_sanity(force=False):
logging.critical('Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG))
sys.exit(1)

for cmd in [CLANG, LLVM_LINK, LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM]:
for cmd in [CLANG, LINK_CMD[0], LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM]:
if not os.path.exists(cmd) and not os.path.exists(cmd + '.exe'): # .exe extension required for Windows
logging.critical('Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG))
sys.exit(1)
Expand Down Expand Up @@ -370,9 +370,21 @@ def check_sanity(force=False):
except NameError:
CLANG_ADD_VERSION = os.getenv('CLANG_ADD_VERSION')

USING_PNACL_TOOLCHAIN = os.path.exists(os.path.join(LLVM_ROOT, 'pnacl-clang'))

def modify_prefix(tool):
if USING_PNACL_TOOLCHAIN:
if tool.startswith('llvm-'):
tool = tool[5:]
tool = 'pnacl-' + tool
if WINDOWS:
tool += '.bat'
return tool

# Some distributions ship with multiple llvm versions so they add
# the version to the binaries, cope with that
def build_llvm_tool_path(tool):
tool = modify_prefix(tool)
if LLVM_ADD_VERSION:
return os.path.join(LLVM_ROOT, tool + "-" + LLVM_ADD_VERSION)
else:
Expand All @@ -381,6 +393,7 @@ def build_llvm_tool_path(tool):
# Some distributions ship with multiple clang versions so they add
# the version to the binaries, cope with that
def build_clang_tool_path(tool):
tool = modify_prefix(tool)
if CLANG_ADD_VERSION:
return os.path.join(LLVM_ROOT, tool + "-" + CLANG_ADD_VERSION)
else:
Expand All @@ -389,7 +402,11 @@ def build_clang_tool_path(tool):
CLANG_CC=os.path.expanduser(build_clang_tool_path('clang'))
CLANG_CPP=os.path.expanduser(build_clang_tool_path('clang++'))
CLANG=CLANG_CPP
LLVM_LINK=build_llvm_tool_path('llvm-link')
if USING_PNACL_TOOLCHAIN:
# The PNaCl toolchain doesn't have llvm-link, but we can fake it
LINK_CMD = [build_llvm_tool_path('llvm-ld'), '-nostdlib', '-r']
else:
LINK_CMD = [build_llvm_tool_path('llvm-link')]
LLVM_AR=build_llvm_tool_path('llvm-ar')
LLVM_OPT=os.path.expanduser(build_llvm_tool_path('opt'))
LLVM_AS=os.path.expanduser(build_llvm_tool_path('llvm-as'))
Expand Down Expand Up @@ -954,15 +971,15 @@ def link(files, target, force_archive_contents=False):
logging.debug('emcc: llvm-linking: %s to %s', actual_files, target)

# check for too-long command line
link_cmd = [LLVM_LINK] + actual_files + ['-o', target]
link_cmd = LINK_CMD + actual_files + ['-o', target]
# 8k is a bit of an arbitrary limit, but a reasonable one
# for max command line size before we use a respose file
response_file = None
if WINDOWS and len(' '.join(link_cmd)) > 8192:
logging.debug('using response file for llvm-link')
[response_fd, response_file] = mkstemp(suffix='.response', dir=TEMP_DIR)

link_cmd = [LLVM_LINK, "@" + response_file]
link_cmd = LINK_CMD + ["@" + response_file]

response_fh = os.fdopen(response_fd, 'w')
for arg in actual_files:
Expand Down Expand Up @@ -1006,15 +1023,15 @@ def llvm_opt(filename, opts):
opts = Building.pick_llvm_opts(opts)
#opts += ['-debug-pass=Arguments']
logging.debug('emcc: LLVM opts: ' + str(opts))
output = Popen([LLVM_OPT, filename] + opts + ['-o=' + filename + '.opt.bc'], stdout=PIPE).communicate()[0]
output = Popen([LLVM_OPT, filename] + opts + ['-o', filename + '.opt.bc'], stdout=PIPE).communicate()[0]
assert os.path.exists(filename + '.opt.bc'), 'Failed to run llvm optimizations: ' + output
shutil.move(filename + '.opt.bc', filename)

@staticmethod
def llvm_opts(filename): # deprecated version, only for test runner. TODO: remove
if Building.LLVM_OPTS:
shutil.move(filename + '.o', filename + '.o.pre')
output = Popen([LLVM_OPT, filename + '.o.pre'] + Building.LLVM_OPT_OPTS + ['-o=' + filename + '.o'], stdout=PIPE).communicate()[0]
output = Popen([LLVM_OPT, filename + '.o.pre'] + Building.LLVM_OPT_OPTS + ['-o', filename + '.o'], stdout=PIPE).communicate()[0]
assert os.path.exists(filename + '.o'), 'Failed to run llvm optimizations: ' + output

@staticmethod
Expand All @@ -1025,7 +1042,7 @@ def llvm_dis(input_filename, output_filename=None):
output_filename = input_filename + '.o.ll'
input_filename = input_filename + '.o'
try_delete(output_filename)
output = Popen([LLVM_DIS, input_filename, '-o=' + output_filename], stdout=PIPE).communicate()[0]
output = Popen([LLVM_DIS, input_filename, '-o', output_filename], stdout=PIPE).communicate()[0]
assert os.path.exists(output_filename), 'Could not create .ll file: ' + output
return output_filename

Expand All @@ -1037,7 +1054,7 @@ def llvm_as(input_filename, output_filename=None):
output_filename = input_filename + '.o'
input_filename = input_filename + '.o.ll'
try_delete(output_filename)
output = Popen([LLVM_AS, input_filename, '-o=' + output_filename], stdout=PIPE).communicate()[0]
output = Popen([LLVM_AS, input_filename, '-o', output_filename], stdout=PIPE).communicate()[0]
assert os.path.exists(output_filename), 'Could not create bc file: ' + output
return output_filename

Expand All @@ -1058,6 +1075,9 @@ class ret:
for line in output.split('\n'):
if len(line) == 0: continue
parts = filter(lambda seg: len(seg) > 0, line.split(' '))
# pnacl-nm will print zero offsets for bitcode
if len(parts) == 3 and parts[0] == "00000000":
parts.pop(0)
if len(parts) == 2: # ignore lines with absolute offsets, these are not bitcode anyhow (e.g. |00000630 t d_source_name|)
status, symbol = parts
if status == 'U':
Expand Down

0 comments on commit 34229a7

Please sign in to comment.