OLD | NEW |
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 string |
17 import sys | 17 import sys |
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 # A regex matching an argument corresponding to a PDB filename passed as an | 21 # A regex matching an argument corresponding to the output filename passed to |
22 # argument to link.exe. | 22 # link.exe. |
23 _LINK_EXE_PDB_ARG = re.compile('/PDB:(?P<pdb>.+\.exe\.pdb)$', re.IGNORECASE) | 23 _LINK_EXE_OUT_ARG = re.compile('/OUT:(?P<out>.+)$', re.IGNORECASE) |
24 | 24 |
25 def main(args): | 25 def main(args): |
26 executor = WinTool() | 26 executor = WinTool() |
27 exit_code = executor.Dispatch(args) | 27 exit_code = executor.Dispatch(args) |
28 if exit_code is not None: | 28 if exit_code is not None: |
29 sys.exit(exit_code) | 29 sys.exit(exit_code) |
30 | 30 |
31 | 31 |
32 class WinTool(object): | 32 class WinTool(object): |
33 """This class performs all the Windows tooling steps. The methods can either | 33 """This class performs all the Windows tooling steps. The methods can either |
34 be executed directly, or dispatched from an argument list.""" | 34 be executed directly, or dispatched from an argument list.""" |
35 | 35 |
36 def _MaybeUseSeparateMspdbsrv(self, env, args): | 36 def _UseSeparateMspdbsrv(self, env, args): |
37 """Allows to use a unique instance of mspdbsrv.exe for the linkers linking | 37 """Allows to use a unique instance of mspdbsrv.exe per linker instead of a |
38 an .exe target if GYP_USE_SEPARATE_MSPDBSRV has been set.""" | 38 shared one.""" |
39 if not os.environ.get('GYP_USE_SEPARATE_MSPDBSRV'): | |
40 return | |
41 | |
42 if len(args) < 1: | 39 if len(args) < 1: |
43 raise Exception("Not enough arguments") | 40 raise Exception("Not enough arguments") |
44 | 41 |
45 if args[0] != 'link.exe': | 42 if args[0] != 'link.exe': |
46 return | 43 return |
47 | 44 |
48 # Checks if this linker produces a PDB for an .exe target. If so use the | 45 # Use the output filename passed to the linker to generate an endpoint name |
49 # name of this PDB to generate an endpoint name for mspdbsrv.exe. | 46 # for mspdbsrv.exe. |
50 endpoint_name = None | 47 endpoint_name = None |
51 for arg in args: | 48 for arg in args: |
52 m = _LINK_EXE_PDB_ARG.match(arg) | 49 m = _LINK_EXE_OUT_ARG.match(arg) |
53 if m: | 50 if m: |
54 endpoint_name = '%s_%d' % (m.group('pdb'), os.getpid()) | 51 endpoint_name = '%s_%d' % (m.group('out'), os.getpid()) |
55 break | 52 break |
56 | 53 |
57 if endpoint_name is None: | 54 if endpoint_name is None: |
58 return | 55 return |
59 | 56 |
60 # Adds the appropriate environment variable. This will be read by link.exe | 57 # Adds the appropriate environment variable. This will be read by link.exe |
61 # to know which instance of mspdbsrv.exe it should connect to (if it's | 58 # to know which instance of mspdbsrv.exe it should connect to (if it's |
62 # not set then the default endpoint is used). | 59 # not set then the default endpoint is used). |
63 env['_MSPDBSRV_ENDPOINT_'] = endpoint_name | 60 env['_MSPDBSRV_ENDPOINT_'] = endpoint_name |
64 | 61 |
(...skipping 27 matching lines...) Expand all Loading... |
92 if os.path.exists(dest): | 89 if os.path.exists(dest): |
93 if os.path.isdir(dest): | 90 if os.path.isdir(dest): |
94 shutil.rmtree(dest) | 91 shutil.rmtree(dest) |
95 else: | 92 else: |
96 os.unlink(dest) | 93 os.unlink(dest) |
97 if os.path.isdir(source): | 94 if os.path.isdir(source): |
98 shutil.copytree(source, dest) | 95 shutil.copytree(source, dest) |
99 else: | 96 else: |
100 shutil.copy2(source, dest) | 97 shutil.copy2(source, dest) |
101 | 98 |
102 def ExecLinkWrapper(self, arch, *args): | 99 def ExecLinkWrapper(self, arch, use_separate_mspdbsrv, *args): |
103 """Filter diagnostic output from link that looks like: | 100 """Filter diagnostic output from link that looks like: |
104 ' Creating library ui.dll.lib and object ui.dll.exp' | 101 ' Creating library ui.dll.lib and object ui.dll.exp' |
105 This happens when there are exports from the dll or exe. | 102 This happens when there are exports from the dll or exe. |
106 """ | 103 """ |
107 env = self._GetEnv(arch) | 104 env = self._GetEnv(arch) |
108 self._MaybeUseSeparateMspdbsrv(env, args) | 105 if use_separate_mspdbsrv == 'True': |
| 106 self._UseSeparateMspdbsrv(env, args) |
109 link = subprocess.Popen(args, | 107 link = subprocess.Popen(args, |
110 shell=True, | 108 shell=True, |
111 env=env, | 109 env=env, |
112 stdout=subprocess.PIPE, | 110 stdout=subprocess.PIPE, |
113 stderr=subprocess.STDOUT) | 111 stderr=subprocess.STDOUT) |
114 out, _ = link.communicate() | 112 out, _ = link.communicate() |
115 for line in out.splitlines(): | 113 for line in out.splitlines(): |
116 if not line.startswith(' Creating library '): | 114 if not line.startswith(' Creating library '): |
117 print line | 115 print line |
118 return link.returncode | 116 return link.returncode |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 def ExecActionWrapper(self, arch, rspfile, *dir): | 277 def ExecActionWrapper(self, arch, rspfile, *dir): |
280 """Runs an action command line from a response file using the environment | 278 """Runs an action command line from a response file using the environment |
281 for |arch|. If |dir| is supplied, use that as the working directory.""" | 279 for |arch|. If |dir| is supplied, use that as the working directory.""" |
282 env = self._GetEnv(arch) | 280 env = self._GetEnv(arch) |
283 args = open(rspfile).read() | 281 args = open(rspfile).read() |
284 dir = dir[0] if dir else None | 282 dir = dir[0] if dir else None |
285 return subprocess.call(args, shell=True, env=env, cwd=dir) | 283 return subprocess.call(args, shell=True, env=env, cwd=dir) |
286 | 284 |
287 if __name__ == '__main__': | 285 if __name__ == '__main__': |
288 sys.exit(main(sys.argv[1:])) | 286 sys.exit(main(sys.argv[1:])) |
OLD | NEW |