| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Takes the same arguments as Windows link.exe, and a definition of libraries | 5 """Takes the same arguments as Windows link.exe, and a definition of libraries |
| 6 to split into subcomponents. Does multiple passes of link.exe invocation to | 6 to split into subcomponents. Does multiple passes of link.exe invocation to |
| 7 determine exports between parts and generates .def and import libraries to | 7 determine exports between parts and generates .def and import libraries to |
| 8 cause symbols to be available to other parts.""" | 8 cause symbols to be available to other parts.""" |
| 9 | 9 |
| 10 import _winreg | 10 import _winreg |
| 11 import ctypes | 11 import ctypes |
| 12 import os | 12 import os |
| 13 import re | 13 import re |
| 14 import subprocess | 14 import subprocess |
| 15 import sys | 15 import sys |
| 16 import tempfile | 16 import tempfile |
| 17 | 17 |
| 18 | 18 |
| 19 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | 19 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 20 | 20 |
| 21 | 21 |
| 22 # This can be set to ignore data exports. The resulting DLLs will probably not |
| 23 # run, but at least they can be generated. The log of data exports will still |
| 24 # be output. |
| 25 IGNORE_DATA = 0 |
| 26 |
| 27 |
| 22 def Log(message): | 28 def Log(message): |
| 23 print 'split_link:', message | 29 print 'split_link:', message |
| 24 | 30 |
| 25 | 31 |
| 26 def GetFlagsAndInputs(argv): | 32 def GetFlagsAndInputs(argv): |
| 27 """Parses the command line intended for link.exe and return the flags and | 33 """Parses the command line intended for link.exe and return the flags and |
| 28 input files.""" | 34 input files.""" |
| 29 rsp_expanded = [] | 35 rsp_expanded = [] |
| 30 for arg in argv: | 36 for arg in argv: |
| 31 if arg[0] == '@': | 37 if arg[0] == '@': |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 deffiles = [] | 236 deffiles = [] |
| 231 Log('generating .def files') | 237 Log('generating .def files') |
| 232 for i, part in enumerate(unresolved_by_part): | 238 for i, part in enumerate(unresolved_by_part): |
| 233 deffile = 'part%d.def' % i | 239 deffile = 'part%d.def' % i |
| 234 with open(deffile, 'w') as f: | 240 with open(deffile, 'w') as f: |
| 235 print >> f, 'LIBRARY %s' % OutputNameForIndex(i) | 241 print >> f, 'LIBRARY %s' % OutputNameForIndex(i) |
| 236 print >> f, 'EXPORTS' | 242 print >> f, 'EXPORTS' |
| 237 for j, part in enumerate(unresolved_by_part): | 243 for j, part in enumerate(unresolved_by_part): |
| 238 if i == j: | 244 if i == j: |
| 239 continue | 245 continue |
| 240 is_data = [' DATA' if IsDataDefinition(export) else '' | 246 is_data = \ |
| 241 for export in part] | 247 [' DATA' if IsDataDefinition(export) and not IGNORE_DATA else '' |
| 248 for export in part] |
| 242 print >> f, '\n'.join(' ' + export + data | 249 print >> f, '\n'.join(' ' + export + data |
| 243 for export, data in zip(part, is_data)) | 250 for export, data in zip(part, is_data)) |
| 244 deffiles.append(deffile) | 251 deffiles.append(deffile) |
| 245 return deffiles | 252 return deffiles |
| 246 | 253 |
| 247 | 254 |
| 248 def BuildImportLibs(flags, inputs_by_part, deffiles): | 255 def BuildImportLibs(flags, inputs_by_part, deffiles): |
| 249 """Runs the linker to generate an import library.""" | 256 """Runs the linker to generate an import library.""" |
| 250 import_libs = [] | 257 import_libs = [] |
| 251 Log('building import libs') | 258 Log('building import libs') |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 data_exports = 0 | 378 data_exports = 0 |
| 372 for i, part in enumerate(unresolved_by_part): | 379 for i, part in enumerate(unresolved_by_part): |
| 373 for export in part: | 380 for export in part: |
| 374 if IsDataDefinition(export): | 381 if IsDataDefinition(export): |
| 375 print 'part %d contains data export: %s (aka %s)' % ( | 382 print 'part %d contains data export: %s (aka %s)' % ( |
| 376 i, Unmangle(export), export) | 383 i, Unmangle(export), export) |
| 377 data_exports += 1 | 384 data_exports += 1 |
| 378 deffiles = GenerateDefFiles(unresolved_by_part) | 385 deffiles = GenerateDefFiles(unresolved_by_part) |
| 379 import_libs = BuildImportLibs(flags, inputs_by_part, deffiles) | 386 import_libs = BuildImportLibs(flags, inputs_by_part, deffiles) |
| 380 else: | 387 else: |
| 381 if data_exports: | 388 if data_exports and not IGNORE_DATA: |
| 382 print '%d data exports found, see report above.' % data_exports | 389 print '%d data exports found, see report above.' % data_exports |
| 383 print('These cannot be exported, and must be either duplicated to the ' | 390 print('These cannot be exported, and must be either duplicated to the ' |
| 384 'target DLL (if constant), or wrapped in a function.') | 391 'target DLL (if constant), or wrapped in a function.') |
| 385 return 1 | 392 return 1 |
| 386 | 393 |
| 387 mt_exe = GetMtPath() | 394 mt_exe = GetMtPath() |
| 388 for i, dll in enumerate(dlls): | 395 for i, dll in enumerate(dlls): |
| 389 Log('embedding manifest in %s' % dll) | 396 Log('embedding manifest in %s' % dll) |
| 390 args = [mt_exe, '-nologo', '-manifest'] | 397 args = [mt_exe, '-nologo', '-manifest'] |
| 391 args.append(ManifestNameForIndex(i)) | 398 args.append(ManifestNameForIndex(i)) |
| 392 args.append(description['manifest']) | 399 args.append(description['manifest']) |
| 393 args.append('-outputresource:%s;2' % dll) | 400 args.append('-outputresource:%s;2' % dll) |
| 394 subprocess.check_call(args) | 401 subprocess.check_call(args) |
| 395 | 402 |
| 396 Log('built %r' % dlls) | 403 Log('built %r' % dlls) |
| 397 | 404 |
| 398 return 0 | 405 return 0 |
| 399 | 406 |
| 400 | 407 |
| 401 if __name__ == '__main__': | 408 if __name__ == '__main__': |
| 402 sys.exit(main()) | 409 sys.exit(main()) |
| OLD | NEW |