OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 from __future__ import with_statement | 6 from __future__ import with_statement |
7 | 7 |
8 import errno | 8 import errno |
9 import optparse | 9 import optparse |
10 import os | 10 import os |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 class NmfUtils(object): | 111 class NmfUtils(object): |
112 '''Helper class for creating and managing nmf files | 112 '''Helper class for creating and managing nmf files |
113 | 113 |
114 Attributes: | 114 Attributes: |
115 manifest: A JSON-structured dict containing the nmf structure | 115 manifest: A JSON-structured dict containing the nmf structure |
116 needed: A dict with key=filename and value=ArchFile (see GetNeeded) | 116 needed: A dict with key=filename and value=ArchFile (see GetNeeded) |
117 ''' | 117 ''' |
118 | 118 |
119 def __init__(self, main_files=None, objdump='x86_64-nacl-objdump', | 119 def __init__(self, main_files=None, objdump='x86_64-nacl-objdump', |
120 lib_path=None, extra_files=None, lib_prefix=None, | 120 lib_path=None, extra_files=None, lib_prefix=None, |
121 toolchain=None, remap={}): | 121 toolchain=None, remap=None): |
122 '''Constructor | 122 '''Constructor |
123 | 123 |
124 Args: | 124 Args: |
125 main_files: List of main entry program files. These will be named | 125 main_files: List of main entry program files. These will be named |
126 files->main.nexe for dynamic nexes, and program for static nexes | 126 files->main.nexe for dynamic nexes, and program for static nexes |
127 objdump: path to x86_64-nacl-objdump tool (or Linux equivalent) | 127 objdump: path to x86_64-nacl-objdump tool (or Linux equivalent) |
128 lib_path: List of paths to library directories | 128 lib_path: List of paths to library directories |
129 extra_files: List of extra files to include in the nmf | 129 extra_files: List of extra files to include in the nmf |
130 lib_prefix: A list of path components to prepend to the library paths, | 130 lib_prefix: A list of path components to prepend to the library paths, |
131 both for staging the libraries and for inclusion into the nmf file. | 131 both for staging the libraries and for inclusion into the nmf file. |
132 Examples: ['..'], ['lib_dir'] | 132 Examples: ['..'], ['lib_dir'] |
133 toolchain: Specify which toolchain newlib|glibc|pnacl which can require | 133 toolchain: Specify which toolchain newlib|glibc|pnacl which can require |
134 different forms of the NMF. | 134 different forms of the NMF. |
135 remap: Remaps the library name in the manifest. | 135 remap: Remaps the library name in the manifest. |
136 ''' | 136 ''' |
137 self.objdump = objdump | 137 self.objdump = objdump |
138 self.main_files = main_files or [] | 138 self.main_files = main_files or [] |
139 self.extra_files = extra_files or [] | 139 self.extra_files = extra_files or [] |
140 self.lib_path = lib_path or [] | 140 self.lib_path = lib_path or [] |
141 self.manifest = None | 141 self.manifest = None |
142 self.needed = None | 142 self.needed = None |
143 self.lib_prefix = lib_prefix or [] | 143 self.lib_prefix = lib_prefix or [] |
144 self.toolchain = toolchain | 144 self.toolchain = toolchain |
145 self.remap = remap | 145 self.remap = remap or {} |
146 | 146 |
147 | 147 |
148 def GleanFromObjdump(self, files): | 148 def GleanFromObjdump(self, files): |
149 '''Get architecture and dependency information for given files | 149 '''Get architecture and dependency information for given files |
150 | 150 |
151 Args: | 151 Args: |
152 files: A dict with key=filename and value=list or set of archs. E.g.: | 152 files: A dict with key=filename and value=list or set of archs. E.g.: |
153 { '/path/to/my.nexe': ['x86-32'] | 153 { '/path/to/my.nexe': ['x86-32'] |
154 '/path/to/lib64/libmy.so': ['x86-64'], | 154 '/path/to/lib64/libmy.so': ['x86-64'], |
155 '/path/to/mydata.so': ['x86-32', 'x86-64'], | 155 '/path/to/mydata.so': ['x86-32', 'x86-64'], |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 | 196 |
197 def FindLibsInPath(self, name): | 197 def FindLibsInPath(self, name): |
198 '''Finds the set of libraries matching |name| within lib_path | 198 '''Finds the set of libraries matching |name| within lib_path |
199 | 199 |
200 Args: | 200 Args: |
201 name: name of library to find | 201 name: name of library to find |
202 | 202 |
203 Returns: | 203 Returns: |
204 A list of system paths that match the given name within the lib_path''' | 204 A list of system paths that match the given name within the lib_path''' |
205 files = [] | 205 files = [] |
206 for dir in self.lib_path: | 206 for dirname in self.lib_path: |
207 file = os.path.join(dir, name) | 207 filename = os.path.join(dirname, name) |
208 if os.path.exists(file): | 208 if os.path.exists(filename): |
209 files.append(file) | 209 files.append(filename) |
210 if not files: | 210 if not files: |
211 raise Error('cannot find library %s' % name) | 211 raise Error('cannot find library %s' % name) |
212 return files | 212 return files |
213 | 213 |
214 def GetNeeded(self): | 214 def GetNeeded(self): |
215 '''Collect the list of dependencies for the main_files | 215 '''Collect the list of dependencies for the main_files |
216 | 216 |
217 Returns: | 217 Returns: |
218 A dict with key=filename and value=ArchFile of input files. | 218 A dict with key=filename and value=ArchFile of input files. |
219 Includes the input files as well, with arch filled in if absent. | 219 Includes the input files as well, with arch filled in if absent. |
220 Example: { '/path/to/my.nexe': ArchFile(my.nexe), | 220 Example: { '/path/to/my.nexe': ArchFile(my.nexe), |
221 '/path/to/libfoo.so': ArchFile(libfoo.so) }''' | 221 '/path/to/libfoo.so': ArchFile(libfoo.so) }''' |
222 if self.needed: | 222 if self.needed: |
223 return self.needed | 223 return self.needed |
224 | 224 |
225 runnable = (self.toolchain != 'newlib' and self.toolchain != 'pnacl') | 225 runnable = (self.toolchain != 'newlib' and self.toolchain != 'pnacl') |
226 DebugPrint('GetNeeded(%s)' % self.main_files) | 226 DebugPrint('GetNeeded(%s)' % self.main_files) |
227 if runnable: | 227 if runnable: |
228 examined = set() | 228 examined = set() |
229 all_files, unexamined = self.GleanFromObjdump( | 229 all_files, unexamined = self.GleanFromObjdump( |
230 dict([(file, None) for file in self.main_files])) | 230 dict([(f, None) for f in self.main_files])) |
231 for name, arch_file in all_files.items(): | 231 for name, arch_file in all_files.items(): |
232 arch_file.url = name | 232 arch_file.url = name |
233 if unexamined: | 233 if unexamined: |
234 unexamined.add('/'.join([arch_file.arch, RUNNABLE_LD])) | 234 unexamined.add('/'.join([arch_file.arch, RUNNABLE_LD])) |
235 while unexamined: | 235 while unexamined: |
236 files_to_examine = {} | 236 files_to_examine = {} |
237 for arch_name in unexamined: | 237 for arch_name in unexamined: |
238 arch, name = arch_name.split('/') | 238 arch, name = arch_name.split('/') |
239 for path in self.FindLibsInPath(name): | 239 for path in self.FindLibsInPath(name): |
240 files_to_examine.setdefault(path, set()).add(arch) | 240 files_to_examine.setdefault(path, set()).add(arch) |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 else: | 423 else: |
424 path_prefix = [] | 424 path_prefix = [] |
425 | 425 |
426 nmf = NmfUtils(objdump=options.objdump, | 426 nmf = NmfUtils(objdump=options.objdump, |
427 main_files=args, | 427 main_files=args, |
428 lib_path=options.lib_path, | 428 lib_path=options.lib_path, |
429 lib_prefix=path_prefix, | 429 lib_prefix=path_prefix, |
430 toolchain=options.toolchain, | 430 toolchain=options.toolchain, |
431 remap=remap) | 431 remap=remap) |
432 | 432 |
433 manifest = nmf.GetManifest() | 433 nmf.GetManifest() |
434 if options.output is None: | 434 if options.output is None: |
435 sys.stdout.write(nmf.GetJson()) | 435 sys.stdout.write(nmf.GetJson()) |
436 else: | 436 else: |
437 with open(options.output, 'w') as output: | 437 with open(options.output, 'w') as output: |
438 output.write(nmf.GetJson()) | 438 output.write(nmf.GetJson()) |
439 | 439 |
440 if options.stage_dependencies: | 440 if options.stage_dependencies: |
441 Trace("Staging dependencies...") | 441 Trace("Staging dependencies...") |
442 nmf.StageDependencies(options.stage_dependencies) | 442 nmf.StageDependencies(options.stage_dependencies) |
443 | 443 |
444 return 0 | 444 return 0 |
445 | 445 |
446 | 446 |
447 # Invoke this file directly for simple testing. | 447 # Invoke this file directly for simple testing. |
448 if __name__ == '__main__': | 448 if __name__ == '__main__': |
449 try: | 449 try: |
450 rtn = Main(sys.argv[1:]) | 450 rtn = Main(sys.argv[1:]) |
451 except Error, e: | 451 except Error, e: |
452 print "%s: %s" % (os.path.basename(__file__), e) | 452 print "%s: %s" % (os.path.basename(__file__), e) |
453 rtn = 1 | 453 rtn = 1 |
454 sys.exit(rtn) | 454 sys.exit(rtn) |
OLD | NEW |