| 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 |