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

Side by Side Diff: pylib/gyp/win_tool.py

Issue 111373002: win ninja: Refactor manifest generate and embed to be 1-pass (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: remove unused Created 7 years 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 | « pylib/gyp/msvs_emulation.py ('k') | test/win/gyptest-link-generate-manifest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 2
3 # Copyright (c) 2012 Google Inc. All rights reserved. 3 # Copyright (c) 2012 Google Inc. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Utility functions for Windows builds. 7 """Utility functions for Windows builds.
8 8
9 These functions are executed via gyp-win-tool when using the ninja generator. 9 These functions are executed via gyp-win-tool when using the ninja generator.
10 """ 10 """
11 11
12 import os 12 import os
13 import re 13 import re
14 import shutil 14 import shutil
15 import subprocess 15 import subprocess
16 import string
16 import sys 17 import sys
17 18
18 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 19 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
19 20
20 # A regex matching an argument corresponding to a PDB filename passed as an 21 # A regex matching an argument corresponding to a PDB filename passed as an
21 # argument to link.exe. 22 # argument to link.exe.
22 _LINK_EXE_PDB_ARG = re.compile('/PDB:(?P<pdb>.+\.exe\.pdb)$', re.IGNORECASE) 23 _LINK_EXE_PDB_ARG = re.compile('/PDB:(?P<pdb>.+\.exe\.pdb)$', re.IGNORECASE)
23 24
24 def main(args): 25 def main(args):
25 executor = WinTool() 26 executor = WinTool()
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 shell=True, 110 shell=True,
110 env=env, 111 env=env,
111 stdout=subprocess.PIPE, 112 stdout=subprocess.PIPE,
112 stderr=subprocess.STDOUT) 113 stderr=subprocess.STDOUT)
113 out, _ = link.communicate() 114 out, _ = link.communicate()
114 for line in out.splitlines(): 115 for line in out.splitlines():
115 if not line.startswith(' Creating library '): 116 if not line.startswith(' Creating library '):
116 print line 117 print line
117 return link.returncode 118 return link.returncode
118 119
120 def ExecLinkWithManifests(self, arch, embed_manifest, out, ldcmd, resname,
121 mt, rc, intermediate_manifest, *manifests):
122 """A wrapper for handling creating a manifest resource and then executing
123 a link command."""
124 # The 'normal' way to do manifests is to have link generate a manifest
125 # based on gathering dependencies from the object files, then merge that
126 # manifest with other manifests supplied as sources, convert the merged
127 # manifest to a resource, and then *relink*, including the compiled
128 # version of the manifest resource. This breaks incremental linking, and
129 # is generally overly complicated. Instead, we merge all the manifests
130 # provided (along with one that includes what would normally be in the
131 # linker-generated one, see msvs_emulation.py), and include that into the
132 # first and only link. We still tell link to generate a manifest, but we
133 # only use that to assert that our simpler process did not miss anything.
134 variables = {
135 'python': sys.executable,
136 'arch': arch,
137 'out': out,
138 'ldcmd': ldcmd,
139 'resname': resname,
140 'mt': mt,
141 'rc': rc,
142 'intermediate_manifest': intermediate_manifest,
143 'manifests': ' '.join(manifests),
144 }
145 add_to_ld = ''
146 if manifests:
147 subprocess.check_call(
148 '%(python)s gyp-win-tool manifest-wrapper %(arch)s %(mt)s -nologo '
149 '-manifest %(manifests)s -out:%(out)s.manifest' % variables)
150 if embed_manifest == 'True':
151 subprocess.check_call(
152 '%(python)s gyp-win-tool manifest-to-rc %(arch)s %(out)s.manifest'
153 ' %(out)s.manifest.rc %(resname)s' % variables)
154 subprocess.check_call(
155 '%(python)s gyp-win-tool rc-wrapper %(arch)s %(rc)s '
156 '%(out)s.manifest.rc' % variables)
157 add_to_ld = ' %(out)s.manifest.res' % variables
158 subprocess.check_call(ldcmd + add_to_ld)
159
160 # Run mt.exe on the theoretically complete manifest we generated, merging
161 # it with the one the linker generated to confirm that the linker
162 # generated one does not add anything. This is strictly unnecessary for
163 # correctness, it's only to verify that e.g. /MANIFESTDEPENDENCY was not
164 # used in a #pragma comment.
165 if manifests:
166 # Merge the intermediate one with ours to .assert.manifest, then check
167 # that .assert.manifest is identical to ours.
168 subprocess.check_call(
169 '%(python)s gyp-win-tool manifest-wrapper %(arch)s %(mt)s -nologo '
170 '-manifest %(out)s.manifest %(intermediate_manifest)s '
171 '-out:%(out)s.assert.manifest' % variables)
172 assert_manifest = '%(out)s.assert.manifest' % variables
173 our_manifest = '%(out)s.manifest' % variables
174 # Load and normalize the manifests. mt.exe sometimes removes whitespace,
175 # and sometimes doesn't unfortunately.
176 with open(our_manifest, 'rb') as our_f:
177 with open(assert_manifest, 'rb') as assert_f:
178 our_data = our_f.read().translate(None, string.whitespace)
179 assert_data = assert_f.read().translate(None, string.whitespace)
180 if our_data != assert_data:
181 os.unlink(out)
182 def dump(filename):
183 sys.stderr.write('%s\n-----\n' % filename)
184 with open(filename, 'rb') as f:
185 sys.stderr.write(f.read() + '\n-----\n')
186 dump(intermediate_manifest)
187 dump(our_manifest)
188 dump(assert_manifest)
189 sys.stderr.write(
190 'Linker generated manifest "%s" added to final manifest "%s" '
191 '(result in "%s"). '
192 'Were /MANIFEST switches used in #pragma statements? ' % (
193 intermediate_manifest, our_manifest, assert_manifest))
194 return 1
195
119 def ExecManifestWrapper(self, arch, *args): 196 def ExecManifestWrapper(self, arch, *args):
120 """Run manifest tool with environment set. Strip out undesirable warning 197 """Run manifest tool with environment set. Strip out undesirable warning
121 (some XML blocks are recognized by the OS loader, but not the manifest 198 (some XML blocks are recognized by the OS loader, but not the manifest
122 tool).""" 199 tool)."""
123 env = self._GetEnv(arch) 200 env = self._GetEnv(arch)
124 popen = subprocess.Popen(args, shell=True, env=env, 201 popen = subprocess.Popen(args, shell=True, env=env,
125 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 202 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
126 out, _ = popen.communicate() 203 out, _ = popen.communicate()
127 for line in out.splitlines(): 204 for line in out.splitlines():
128 if line and 'manifest authoring warning 81010002' not in line: 205 if line and 'manifest authoring warning 81010002' not in line:
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 def ExecActionWrapper(self, arch, rspfile, *dir): 279 def ExecActionWrapper(self, arch, rspfile, *dir):
203 """Runs an action command line from a response file using the environment 280 """Runs an action command line from a response file using the environment
204 for |arch|. If |dir| is supplied, use that as the working directory.""" 281 for |arch|. If |dir| is supplied, use that as the working directory."""
205 env = self._GetEnv(arch) 282 env = self._GetEnv(arch)
206 args = open(rspfile).read() 283 args = open(rspfile).read()
207 dir = dir[0] if dir else None 284 dir = dir[0] if dir else None
208 return subprocess.call(args, shell=True, env=env, cwd=dir) 285 return subprocess.call(args, shell=True, env=env, cwd=dir)
209 286
210 if __name__ == '__main__': 287 if __name__ == '__main__':
211 sys.exit(main(sys.argv[1:])) 288 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « pylib/gyp/msvs_emulation.py ('k') | test/win/gyptest-link-generate-manifest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698