Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: tools/win/split_link/split_link.py

Issue 14850021: Generate, merge, and embed manifest when doing split_link (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/win/split_link/install_split_link.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 ref = ctypes.c_wchar_p * size.value 42 ref = ctypes.c_wchar_p * size.value
43 raw = ref.from_address(ptr) 43 raw = ref.from_address(ptr)
44 args = [arg for arg in raw] 44 args = [arg for arg in raw]
45 finally: 45 finally:
46 ctypes.windll.kernel32.LocalFree(ptr) 46 ctypes.windll.kernel32.LocalFree(ptr)
47 47
48 inputs = [] 48 inputs = []
49 flags = [] 49 flags = []
50 for arg in args: 50 for arg in args:
51 lower_arg = arg.lower() 51 lower_arg = arg.lower()
52 # We'll be replacing this ourselves. 52 # We'll be replacing these ourselves.
53 if lower_arg.startswith('/out:'): 53 if lower_arg.startswith('/out:'):
54 continue 54 continue
55 if lower_arg.startswith('/manifestfile:'):
56 continue
55 if (not lower_arg.startswith('/') and 57 if (not lower_arg.startswith('/') and
56 lower_arg.endswith(('.obj', '.lib', '.res'))): 58 lower_arg.endswith(('.obj', '.lib', '.res'))):
57 inputs.append(arg) 59 inputs.append(arg)
58 else: 60 else:
59 flags.append(arg) 61 flags.append(arg)
60 62
61 return flags, inputs 63 return flags, inputs
62 64
63 65
64 def GetOriginalLinkerPath(): 66 def GetRegistryValue(subkey):
65 try: 67 try:
66 val = _winreg.QueryValue(_winreg.HKEY_CURRENT_USER, 68 val = _winreg.QueryValue(_winreg.HKEY_CURRENT_USER,
67 'Software\\Chromium\\split_link_installed') 69 'Software\\Chromium\\' + subkey)
68 if os.path.exists(val): 70 if os.path.exists(val):
69 return val 71 return val
70 except WindowsError: 72 except WindowsError:
71 pass 73 pass
72 74
73 raise SystemExit("Couldn't read linker location from registry") 75 raise SystemExit("Couldn't read from registry")
76
77
78 def GetOriginalLinkerPath():
79 return GetRegistryValue('split_link_installed')
80
81
82 def GetMtPath():
83 return GetRegistryValue('split_link_mt_path')
74 84
75 85
76 def PartFor(input_file, description_parts, description_all): 86 def PartFor(input_file, description_parts, description_all):
77 """Determines which part a given link input should be put into (or all).""" 87 """Determines which part a given link input should be put into (or all)."""
78 # Check if it should go in all parts. 88 # Check if it should go in all parts.
79 input_file = input_file.lower() 89 input_file = input_file.lower()
80 if any(re.search(spec, input_file) for spec in description_all): 90 if any(re.search(spec, input_file) for spec in description_all):
81 return -1 91 return -1
82 # Or pick which particular one it belongs in. 92 # Or pick which particular one it belongs in.
83 for i, spec_list in enumerate(description_parts): 93 for i, spec_list in enumerate(description_parts):
(...skipping 27 matching lines...) Expand all
111 mo = regex.search(line) 121 mo = regex.search(line)
112 if mo: 122 if mo:
113 if strip_leading_underscore: 123 if strip_leading_underscore:
114 result.add(mo.group(1)[1:]) 124 result.add(mo.group(1)[1:])
115 else: 125 else:
116 result.add(mo.group(1)) 126 result.add(mo.group(1))
117 break 127 break
118 128
119 mo = re.search(r'fatal error LNK1120: (\d+) unresolved externals', output) 129 mo = re.search(r'fatal error LNK1120: (\d+) unresolved externals', output)
120 # Make sure we have the same number that the linker thinks we have. 130 # Make sure we have the same number that the linker thinks we have.
121 assert mo or not result 131 if mo is None and result:
132 raise SystemExit(output)
122 if len(result) != int(mo.group(1)): 133 if len(result) != int(mo.group(1)):
123 print output 134 print output
124 print 'Expecting %d, got %d' % (int(mo.group(1)), len(result)) 135 print 'Expecting %d, got %d' % (int(mo.group(1)), len(result))
125 assert len(result) == int(mo.group(1)) 136 assert len(result) == int(mo.group(1))
126 return sorted(result) 137 return sorted(result)
127 138
128 139
129 def AsCommandLineArgs(items): 140 def AsCommandLineArgs(items):
130 """Intended for output to a response file. Quotes all arguments.""" 141 """Intended for output to a response file. Quotes all arguments."""
131 return '\n'.join('"' + x + '"' for x in items) 142 return '\n'.join('"' + x + '"' for x in items)
132 143
133 144
134 def OutputNameForIndex(index): 145 def OutputNameForIndex(index):
135 """Gets the final output DLL name, given a zero-based index.""" 146 """Gets the final output DLL name, given a zero-based index."""
136 if index == 0: 147 if index == 0:
137 return "chrome.dll" 148 return "chrome.dll"
138 else: 149 else:
139 return 'chrome%d.dll' % index 150 return 'chrome%d.dll' % index
140 151
141 152
153 def ManifestNameForIndex(index):
154 return OutputNameForIndex(index) + '.intermediate.manifest'
155
156
142 def RunLinker(flags, index, inputs, phase): 157 def RunLinker(flags, index, inputs, phase):
143 """Invokes the linker and returns the stdout, returncode and target name.""" 158 """Invokes the linker and returns the stdout, returncode and target name."""
144 rspfile = 'part%d_%s.rsp' % (index, phase) 159 rspfile = 'part%d_%s.rsp' % (index, phase)
145 with open(rspfile, 'w') as f: 160 with open(rspfile, 'w') as f:
146 print >> f, AsCommandLineArgs(inputs) 161 print >> f, AsCommandLineArgs(inputs)
147 print >> f, AsCommandLineArgs(flags) 162 print >> f, AsCommandLineArgs(flags)
148 output_name = OutputNameForIndex(index) 163 output_name = OutputNameForIndex(index)
164 manifest_name = ManifestNameForIndex(index)
149 print >> f, '/ENTRY:ChromeEmptyEntry@12' 165 print >> f, '/ENTRY:ChromeEmptyEntry@12'
150 print >> f, '/OUT:' + output_name 166 print >> f, '/OUT:' + output_name
167 print >> f, '/MANIFESTFILE:' + manifest_name
151 # Log('[[[\n' + open(rspfile).read() + '\n]]]') 168 # Log('[[[\n' + open(rspfile).read() + '\n]]]')
152 link_exe = GetOriginalLinkerPath() 169 link_exe = GetOriginalLinkerPath()
153 popen = subprocess.Popen([link_exe, '@' + rspfile], stdout=subprocess.PIPE) 170 popen = subprocess.Popen([link_exe, '@' + rspfile], stdout=subprocess.PIPE)
154 stdout, _ = popen.communicate() 171 stdout, _ = popen.communicate()
155 return stdout, popen.returncode, output_name 172 return stdout, popen.returncode, output_name
156 173
157 174
158 def GenerateDefFiles(unresolved_by_part): 175 def GenerateDefFiles(unresolved_by_part):
159 """Given a list of unresolved externals, generates a .def file that will 176 """Given a list of unresolved externals, generates a .def file that will
160 cause all those symbols to be exported.""" 177 cause all those symbols to be exported."""
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 for i in range(5): 263 for i in range(5):
247 Log('--- starting pass %d' % i) 264 Log('--- starting pass %d' % i)
248 ok, dlls, unresolved_by_part = AttemptLink( 265 ok, dlls, unresolved_by_part = AttemptLink(
249 flags, inputs_by_part, unresolved_by_part, deffiles, import_libs) 266 flags, inputs_by_part, unresolved_by_part, deffiles, import_libs)
250 if ok: 267 if ok:
251 break 268 break
252 deffiles = GenerateDefFiles(unresolved_by_part) 269 deffiles = GenerateDefFiles(unresolved_by_part)
253 import_libs = BuildImportLibs(flags, inputs_by_part, deffiles) 270 import_libs = BuildImportLibs(flags, inputs_by_part, deffiles)
254 else: 271 else:
255 return 1 272 return 1
273
274 mt_exe = GetMtPath()
275 for i, dll in enumerate(dlls):
276 Log('embedding manifest in %s' % dll)
277 args = [mt_exe, '-nologo', '-manifest']
278 args.append(ManifestNameForIndex(i))
279 args.append(description['manifest'])
280 args.append('-outputresource:%s;2' % dll)
281 subprocess.check_call(args)
282
256 Log('built %r' % dlls) 283 Log('built %r' % dlls)
257 284
258 return 0 285 return 0
259 286
260 287
261 if __name__ == '__main__': 288 if __name__ == '__main__':
262 sys.exit(main()) 289 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/win/split_link/install_split_link.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698