| Index: pnacl/driver/pnacl-nmf.py
|
| diff --git a/pnacl/driver/pnacl-nmf.py b/pnacl/driver/pnacl-nmf.py
|
| deleted file mode 100755
|
| index f693bdfc895d5eb2f5c42ebfff8ef6e883132614..0000000000000000000000000000000000000000
|
| --- a/pnacl/driver/pnacl-nmf.py
|
| +++ /dev/null
|
| @@ -1,220 +0,0 @@
|
| -#!/usr/bin/python
|
| -# Copyright (c) 2012 The Native Client Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -#
|
| -# IMPORTANT NOTE: If you make local mods to this file, you must run:
|
| -# % pnacl/build.sh driver
|
| -# in order for them to take effect in the scons build. This command
|
| -# updates the copy in the toolchain/ tree.
|
| -#
|
| -
|
| -# Generate a draft manifest file given bitcode pexe.
|
| -# URLs and unknown runtime dependencies may be manually changed afterwards.
|
| -
|
| -from driver_tools import *
|
| -from driver_env import env
|
| -from driver_log import Log, DriverOpen, TempFiles
|
| -from collections import deque
|
| -import filetype
|
| -
|
| -import hashlib
|
| -import json
|
| -
|
| -EXTRA_ENV = {
|
| - 'INPUTS' : '',
|
| - 'OUTPUT' : '',
|
| -
|
| - 'BASELINE_NMF' : '',
|
| -
|
| - # FLAT_URL_SCHEME is '1' if we are just trying to test via scons and
|
| - # do not want to put libraries under any kind of directory structure
|
| - # to simplify file staging. This means that really only one of the files
|
| - # is valid, since all arches will have the same URL. This is only for tests.
|
| - 'FLAT_URL_SCHEME' : '0',
|
| -
|
| - # Search path for finding pso's to grab transitive dependencies.
|
| - 'SEARCH_DIRS' : '${SEARCH_DIRS_USER} ${SEARCH_DIRS_BUILTIN}',
|
| - 'SEARCH_DIRS_USER' : '',
|
| - # This doesn't include native lib directories, so we aren't
|
| - # tracing transitive dependencies for those.
|
| - 'SEARCH_DIRS_BUILTIN': ' ${BASE_USR}/lib/ ' +
|
| - ' ${BASE_SDK}/lib/ ' +
|
| - ' ${BASE_LIB}/ ',
|
| -}
|
| -
|
| -NMF_PATTERNS = [
|
| - ( ('-L', '(.+)'),
|
| - "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
|
| - ( '-L(.+)',
|
| - "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
|
| - ( '--library-path=(.+)',
|
| - "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
|
| - ( ('--base-nmf', '(.+)'),
|
| - "env.set('BASELINE_NMF', pathtools.normalize($0))\n"),
|
| -
|
| - ( ('-o', '(.+)'), "env.set('OUTPUT', pathtools.normalize($0))\n"),
|
| - ( '--flat-url-scheme', "env.set('FLAT_URL_SCHEME', '1')"),
|
| -
|
| - ( '(.*)', "env.append('INPUTS', pathtools.normalize($0))"),
|
| -]
|
| -
|
| -def get_help(argv):
|
| - return """
|
| -NaCl Manifest Generator for PNaCl.
|
| -
|
| -Usage: %s [options] <pexe_file>
|
| -
|
| -BASIC OPTIONS:
|
| - -o <file> Output to <file>
|
| - --base-nmf <file> Use a baseline NMF file as a starting point.
|
| - -L <dir> Add library search path
|
| - --library-path=<dir> Ditto.
|
| - --flat-url-scheme For testing: Do not nest architecture-specific
|
| - files in an architecture-specific directory
|
| - when generating URLs.
|
| -""" % env.getone('SCRIPT_NAME')
|
| -
|
| -def AddUrlForAllArches(json_dict, shortname):
|
| - KNOWN_NMF_ARCHES = ['x86-32', 'x86-64', 'arm']
|
| - for arch in KNOWN_NMF_ARCHES:
|
| - json_dict[arch] = {}
|
| - if env.getbool('FLAT_URL_SCHEME'):
|
| - json_dict[arch]['url'] = '%s' % shortname
|
| - else:
|
| - json_dict[arch]['url'] = 'lib-%s/%s' % (arch, shortname)
|
| -
|
| -def SetPortableUrl(json_dict, shortname, filepath):
|
| - json_dict['portable'] = {}
|
| - json_dict['portable']['pnacl-translate'] = {}
|
| - json_dict['portable']['pnacl-translate']['url'] = shortname
|
| - fd = DriverOpen(filepath, 'r')
|
| - sha = hashlib.sha256()
|
| - sha.update(fd.read())
|
| - fd.close()
|
| - json_dict['portable']['pnacl-translate']['sha256'] = sha.hexdigest()
|
| -
|
| -def GetActualFilePathAndType(shortname):
|
| - actual_lib_path = ldtools.FindFile([shortname],
|
| - env.get('SEARCH_DIRS'),
|
| - ldtools.LibraryTypes.ANY)
|
| - if actual_lib_path == None:
|
| - Log.Warning('Could not find path of lib: %s, assuming it is native',
|
| - shortname)
|
| - file_type = 'so'
|
| - else:
|
| - file_type = filetype.FileType(actual_lib_path)
|
| - return actual_lib_path, file_type
|
| -
|
| -def GetTransitiveClosureOfNeeded(base_needed):
|
| - visited_portable = set()
|
| - visited_native = set()
|
| - all_needed = set(base_needed)
|
| - worklist = deque(base_needed)
|
| - while len(worklist) != 0:
|
| - lib = worklist.popleft()
|
| - if lib in visited_portable or lib in visited_native:
|
| - continue
|
| - actual_lib_path, file_type = GetActualFilePathAndType(lib)
|
| - if file_type == 'so':
|
| - # We could trace if we used objdump / readelf...
|
| - Log.Warning('Not tracing dependencies of native lib %s', lib)
|
| - visited_native.add(lib)
|
| - continue
|
| - elif file_type == 'pso':
|
| - visited_portable.add(lib)
|
| - more_needed = filetype.GetBitcodeMetadata(
|
| - actual_lib_path).get('NeedsLibrary', [])
|
| - all_needed |= set(more_needed)
|
| - worklist.extend(more_needed)
|
| - else:
|
| - Log.Fatal('Lib: %s is neither bitcode nor native', lib)
|
| - return all_needed
|
| -
|
| -def ReadBaselineNMF(baseline_file):
|
| - f = DriverOpen(baseline_file, 'r')
|
| - json_dict = json.load(f)
|
| - f.close()
|
| - return json_dict
|
| -
|
| -def EchoBaselineNMF(baseline_nmf, output_file):
|
| - json.dump(baseline_nmf, output_file, sort_keys=True, indent=2)
|
| -
|
| -def GenerateStaticNMF(pexe_file, baseline_nmf, output_file):
|
| - nmf_json = baseline_nmf
|
| - nmf_json['program'] = {}
|
| - SetPortableUrl(nmf_json['program'],
|
| - pathtools.basename(pexe_file),
|
| - pexe_file)
|
| - json.dump(nmf_json, output_file, sort_keys=True, indent=2)
|
| -
|
| -
|
| -def GenerateDynamicNMF(pexe_file, baseline_nmf, needed, output_file):
|
| - nmf_json = baseline_nmf
|
| - # Set runnable-ld.so as the program interpreter.
|
| - nmf_json['program'] = {}
|
| - AddUrlForAllArches(nmf_json['program'], 'runnable-ld.so')
|
| - # Set the pexe as the main program.
|
| - nmf_json['files'] = baseline_nmf.get('files', {})
|
| - nmf_json['files']['main.nexe'] = {}
|
| - SetPortableUrl(nmf_json['files']['main.nexe'],
|
| - pathtools.basename(pexe_file),
|
| - pexe_file)
|
| -
|
| - # Get transitive closure of needed libraries.
|
| - transitive_needed = GetTransitiveClosureOfNeeded(needed)
|
| -
|
| - # Make urls for libraries.
|
| - for lib in transitive_needed:
|
| - nmf_json['files'][lib] = {}
|
| - actual_lib_path, file_type = GetActualFilePathAndType(lib)
|
| - if file_type == 'so':
|
| - # Assume a native version exists for every known arch.
|
| - AddUrlForAllArches(nmf_json['files'][lib], lib)
|
| - elif file_type == 'pso':
|
| - SetPortableUrl(nmf_json['files'][lib],
|
| - lib,
|
| - actual_lib_path)
|
| - else:
|
| - Log.Fatal('Needed library is not a .so nor a .pso')
|
| - json.dump(nmf_json, output_file, sort_keys=True, indent=2)
|
| -
|
| -
|
| -def main(argv):
|
| - env.update(EXTRA_ENV)
|
| - ParseArgs(argv, NMF_PATTERNS)
|
| - exe_file = env.getone('INPUTS')
|
| -
|
| - if not exe_file:
|
| - Log.Fatal('Expecting input exe_file')
|
| - DriverExit(1)
|
| -
|
| - baseline_file = env.getone('BASELINE_NMF')
|
| - if not baseline_file:
|
| - baseline_nmf = {}
|
| - else:
|
| - baseline_nmf = ReadBaselineNMF(baseline_file)
|
| -
|
| - output = env.getone('OUTPUT')
|
| - if output == '':
|
| - output_file = sys.stdout
|
| - else:
|
| - output_file = DriverOpen(output, 'w')
|
| -
|
| - if not FileType(exe_file) == 'pexe':
|
| - EchoBaselineNMF(baseline_nmf, output_file)
|
| - return 0
|
| - needed = GetBitcodeMetadata(exe_file).get('NeedsLibrary', [])
|
| - if len(needed) == 0:
|
| - GenerateStaticNMF(exe_file, baseline_nmf, output_file)
|
| - else:
|
| - # runnable_ld.so is going to ask for libgcc_s.so.1 even though it does
|
| - # not show up in the pexe's NEEDED metadata, so it won't show up
|
| - # in the NMF and on the App's webserver.
|
| - #
|
| - # For now, hack in libgcc_s.so.1.
|
| - # http://code.google.com/p/nativeclient/issues/detail?id=2582
|
| - needed.append('libgcc_s.so.1')
|
| - GenerateDynamicNMF(exe_file, baseline_nmf, needed, output_file)
|
| - DriverClose(output_file)
|
| - return 0
|
|
|