Index: native_client_sdk/src/tools/create_nmf.py |
=================================================================== |
--- native_client_sdk/src/tools/create_nmf.py (revision 118876) |
+++ native_client_sdk/src/tools/create_nmf.py (working copy) |
@@ -29,10 +29,13 @@ |
# Names returned by x86_64-nacl-objdump: |
'elf64-nacl': 'x86-64', |
'elf32-nacl': 'x86-32', |
- # TODO(mball): Add support for 'arm-32' and 'portable' architectures |
- # 'elf32-little': 'arm-32', |
} |
+ARCH_LOCATION = { |
+ 'x86-32': 'lib32', |
+ 'x86-64': 'lib64', |
+} |
+ |
# These constants are used within nmf files. |
RUNNABLE_LD = 'runnable-ld.so' # Name of the dynamic loader |
MAIN_NEXE = 'main.nexe' # Name of entry point for execution |
@@ -110,14 +113,16 @@ |
self.needed = None |
self.lib_prefix = lib_prefix or [] |
+ |
def GleanFromObjdump(self, files): |
'''Get architecture and dependency information for given files |
Args: |
files: A dict with key=filename and value=list or set of archs. E.g.: |
- { '/path/to/my.nexe': ['x86-32', 'x86-64'], |
- '/path/to/libmy.so': ['x86-32'], |
- '/path/to/my2.nexe': None } # Indicates all architectures |
+ { '/path/to/my.nexe': ['x86-32'] |
+ '/path/to/lib64/libmy.so': ['x86-64'], |
+ '/path/to/mydata.so': ['x86-32', 'x86-64'], |
+ '/path/to/my.data': None } # Indicates all architectures |
Returns: A tuple with the following members: |
input_info: A dict with key=filename and value=ArchFile of input files. |
@@ -147,7 +152,7 @@ |
arch=arch, |
name=name, |
path=filename, |
- url='/'.join(self.lib_prefix + [arch, name])) |
+ url='/'.join(self.lib_prefix + [ARCH_LOCATION[arch], name])) |
matched = NeededMatcher.match(line) |
if matched is not None: |
if files[filename] is None or arch in files[filename]: |
@@ -189,7 +194,7 @@ |
all_files, unexamined = self.GleanFromObjdump( |
dict([(file, None) for file in self.main_files])) |
for name, arch_file in all_files.items(): |
- arch_file.url = os.path.basename(name) |
+ arch_file.url = name |
if unexamined: |
unexamined.add('/'.join([arch_file.arch, RUNNABLE_LD])) |
while unexamined: |
@@ -232,41 +237,43 @@ |
os.path.normcase(os.path.abspath(destination))): |
shutil.copy2(source, destination) |
- def _GenerateManifest(self): |
- programs = {} |
- files = {} |
- |
- def add_files(needed): |
- for filename, arch_file in needed.items(): |
- files.setdefault(arch_file.arch, set()).add(arch_file.name) |
- |
+ def _GenerateManifest(self, runnable=True): |
+ '''Create a JSON formatted dict containing the files |
+ |
+ NaCl will map url requests based on architecture. The startup NEXE |
+ can always be found under the top key PROGRAM. Additional files are under |
+ the FILES key further mapped by file name. In the case of 'runnable' the |
+ PROGRAM key is populated with urls pointing the runnable-ld.so which acts |
+ as the startup nexe. The application itself, is then placed under the |
+ FILES key mapped as 'main.exe' instead of it's original name so that the |
+ loader can find it.''' |
+ manifest = { FILES_KEY: {}, PROGRAM_KEY: {} } |
needed = self.GetNeeded() |
- add_files(needed) |
- for filename in self.main_files: |
- arch_file = needed[filename] |
- programs[arch_file.arch] = arch_file.name |
+ for need in needed: |
+ archinfo = needed[need] |
+ urlinfo = { URL_KEY: archinfo.url } |
+ name = archinfo.name |
- filemap = {} |
- for arch in files: |
- for file in files[arch]: |
- if file not in programs.values() and file != RUNNABLE_LD: |
- filemap.setdefault(file, set()).add(arch) |
+ # If starting with runnable-ld.so, make that the main executable. |
+ if runnable: |
+ if need.endswith(RUNNABLE_LD): |
+ manifest[PROGRAM_KEY][archinfo.arch] = urlinfo |
+ continue |
- def arch_name(arch, file): |
- # nmf files expect unix-style path separators |
- return {URL_KEY: '/'.join(self.lib_prefix + [arch, file])} |
+ # For the main nexes: |
+ if need.endswith('.nexe') and need in self.main_files: |
+ # Place it under program if we aren't using the runnable-ld.so. |
+ if not runnable: |
+ manifest[PROGRAM_KEY][archinfo.arch] = urlinfo |
+ continue |
+ # Otherwise, treat it like another another file named main.nexe. |
+ name = MAIN_NEXE |
- # TODO(mcgrathr): perhaps notice a program with no deps |
- # (i.e. statically linked) and generate program=nexe instead? |
- manifest = {PROGRAM_KEY: {}, FILES_KEY: {MAIN_NEXE: {}}} |
- for arch in programs: |
- manifest[PROGRAM_KEY][arch] = arch_name(arch, RUNNABLE_LD) |
- manifest[FILES_KEY][MAIN_NEXE][arch] = {URL_KEY: programs[arch]} |
+ fileinfo = manifest[FILES_KEY].get(name, {}) |
+ fileinfo[archinfo.arch] = urlinfo |
+ manifest[FILES_KEY][name] = fileinfo |
- for file in filemap: |
- manifest[FILES_KEY][file] = dict([(arch, arch_name(arch, file)) |
- for arch in filemap[file]]) |
self.manifest = manifest |
def GetManifest(self): |
@@ -301,6 +308,9 @@ |
parser.add_option('-s', '--stage-dependencies', dest='stage_dependencies', |
help='Destination directory for staging libraries', |
metavar='DIRECTORY') |
+ parser.add_option('-r', '--remove', dest='remove', |
+ help='Remove the prefix from the files.', |
+ metavar='PATH') |
(options, args) = parser.parse_args(argv) |
if len(args) < 1: |