| OLD | NEW |
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. 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 """ | 5 """ |
| 6 This module helps emulate Visual Studio 2008 behavior on top of other | 6 This module helps emulate Visual Studio 2008 behavior on top of other |
| 7 build systems, primarily ninja. | 7 build systems, primarily ninja. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import os | 10 import os |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 # Try to find an installation location for the Windows DDK by checking | 137 # Try to find an installation location for the Windows DDK by checking |
| 138 # the WDK_DIR environment variable, may be None. | 138 # the WDK_DIR environment variable, may be None. |
| 139 self.wdk_dir = os.environ.get('WDK_DIR') | 139 self.wdk_dir = os.environ.get('WDK_DIR') |
| 140 | 140 |
| 141 supported_fields = [ | 141 supported_fields = [ |
| 142 ('msvs_configuration_attributes', dict), | 142 ('msvs_configuration_attributes', dict), |
| 143 ('msvs_settings', dict), | 143 ('msvs_settings', dict), |
| 144 ('msvs_system_include_dirs', list), | 144 ('msvs_system_include_dirs', list), |
| 145 ('msvs_disabled_warnings', list), | 145 ('msvs_disabled_warnings', list), |
| 146 ('msvs_precompiled_header', str), |
| 147 ('msvs_precompiled_source', str), |
| 146 ] | 148 ] |
| 147 configs = spec['configurations'] | 149 configs = spec['configurations'] |
| 148 for field, default in supported_fields: | 150 for field, default in supported_fields: |
| 149 setattr(self, field, {}) | 151 setattr(self, field, {}) |
| 150 for configname, config in configs.iteritems(): | 152 for configname, config in configs.iteritems(): |
| 151 getattr(self, field)[configname] = config.get(field, default()) | 153 getattr(self, field)[configname] = config.get(field, default()) |
| 152 | 154 |
| 153 self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) | 155 self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) |
| 154 | 156 |
| 155 def GetVSMacroEnv(self, base_to_build=None): | 157 def GetVSMacroEnv(self, base_to_build=None): |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 cl('BufferSecurityCheck', map={'true': '/GS', 'false': '/GS-'}) | 270 cl('BufferSecurityCheck', map={'true': '/GS', 'false': '/GS-'}) |
| 269 cl('BasicRuntimeChecks', map={'1': 's', '2': 'u', '3': '1'}, prefix='/RTC') | 271 cl('BasicRuntimeChecks', map={'1': 's', '2': 'u', '3': '1'}, prefix='/RTC') |
| 270 cl('RuntimeLibrary', | 272 cl('RuntimeLibrary', |
| 271 map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M') | 273 map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M') |
| 272 cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH') | 274 cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH') |
| 273 cl('AdditionalOptions', prefix='') | 275 cl('AdditionalOptions', prefix='') |
| 274 # ninja handles parallelism by itself, don't have the compiler do it too. | 276 # ninja handles parallelism by itself, don't have the compiler do it too. |
| 275 cflags = filter(lambda x: not x.startswith('/MP'), cflags) | 277 cflags = filter(lambda x: not x.startswith('/MP'), cflags) |
| 276 return cflags | 278 return cflags |
| 277 | 279 |
| 280 def GetPrecompiledHeader(self, config, gyp_to_build_path): |
| 281 """Returns an object that handles the generation of precompiled header |
| 282 build steps.""" |
| 283 return _PchHelper(self, config, gyp_to_build_path) |
| 284 |
| 285 def _GetPchFlags(self, config, extension): |
| 286 """Get the flags to be added to the cflags for precompiled header support. |
| 287 """ |
| 288 # The PCH is only built once by a particular source file. Usage of PCH must |
| 289 # only be for the same language (i.e. C vs. C++), so only include the pch |
| 290 # flags when the language matches. |
| 291 if self.msvs_precompiled_header[config]: |
| 292 source_ext = os.path.splitext(self.msvs_precompiled_source[config])[1] |
| 293 if _LanguageMatchesForPch(source_ext, extension): |
| 294 pch = os.path.split(self.msvs_precompiled_header[config])[1] |
| 295 return ['/Yu' + pch, '/FI' + pch, '/Fp${pchprefix}.' + pch + '.pch'] |
| 296 return [] |
| 297 |
| 278 def GetCflagsC(self, config): | 298 def GetCflagsC(self, config): |
| 279 """Returns the flags that need to be added to .c compilations.""" | 299 """Returns the flags that need to be added to .c compilations.""" |
| 280 return [] | 300 return self._GetPchFlags(config, '.c') |
| 281 | 301 |
| 282 def GetCflagsCC(self, config): | 302 def GetCflagsCC(self, config): |
| 283 """Returns the flags that need to be added to .cc compilations.""" | 303 """Returns the flags that need to be added to .cc compilations.""" |
| 284 return ['/TP'] | 304 return ['/TP'] + self._GetPchFlags(config, '.cc') |
| 285 | 305 |
| 286 def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path): | 306 def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path): |
| 287 """Get and normalize the list of paths in AdditionalLibraryDirectories | 307 """Get and normalize the list of paths in AdditionalLibraryDirectories |
| 288 setting.""" | 308 setting.""" |
| 289 libpaths = self._Setting((root, 'AdditionalLibraryDirectories'), | 309 libpaths = self._Setting((root, 'AdditionalLibraryDirectories'), |
| 290 config, default=[]) | 310 config, default=[]) |
| 291 libpaths = [os.path.normpath(gyp_to_build_path(self.ConvertVSMacros(p))) | 311 libpaths = [os.path.normpath(gyp_to_build_path(self.ConvertVSMacros(p))) |
| 292 for p in libpaths] | 312 for p in libpaths] |
| 293 return ['/LIBPATH:"' + p + '"' for p in libpaths] | 313 return ['/LIBPATH:"' + p + '"' for p in libpaths] |
| 294 | 314 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 output = [header, dlldata, iid, proxy] | 451 output = [header, dlldata, iid, proxy] |
| 432 variables = [('tlb', tlb), | 452 variables = [('tlb', tlb), |
| 433 ('h', header), | 453 ('h', header), |
| 434 ('dlldata', dlldata), | 454 ('dlldata', dlldata), |
| 435 ('iid', iid), | 455 ('iid', iid), |
| 436 ('proxy', proxy)] | 456 ('proxy', proxy)] |
| 437 # TODO(scottmg): Are there configuration settings to set these flags? | 457 # TODO(scottmg): Are there configuration settings to set these flags? |
| 438 flags = ['/char', 'signed', '/env', 'win32', '/Oicf'] | 458 flags = ['/char', 'signed', '/env', 'win32', '/Oicf'] |
| 439 return outdir, output, variables, flags | 459 return outdir, output, variables, flags |
| 440 | 460 |
| 461 |
| 462 def _LanguageMatchesForPch(source_ext, pch_source_ext): |
| 463 c_exts = ('.c',) |
| 464 cc_exts = ('.cc', '.cxx', '.cpp') |
| 465 return ((source_ext in c_exts and pch_source_ext in c_exts) or |
| 466 (source_ext in cc_exts and pch_source_ext in cc_exts)) |
| 467 |
| 468 class PrecompiledHeader(object): |
| 469 """Helper to generate dependencies and build rules to handle generation of |
| 470 precompiled headers. Interface matches the GCH handler in xcode_emulation.py. |
| 471 """ |
| 472 def __init__(self, settings, config, gyp_to_build_path): |
| 473 self.settings = settings |
| 474 self.config = config |
| 475 self.gyp_to_build_path = gyp_to_build_path |
| 476 |
| 477 def _PchHeader(self): |
| 478 """Get the header that will appear in an #include line for all source |
| 479 files.""" |
| 480 return os.path.split(self.settings.msvs_precompiled_header[self.config])[1] |
| 481 |
| 482 def _PchSource(self): |
| 483 """Get the source file that is built once to compile the pch data.""" |
| 484 return self.gyp_to_build_path( |
| 485 self.settings.msvs_precompiled_source[self.config]) |
| 486 |
| 487 def _PchOutput(self): |
| 488 """Get the name of the output of the compiled pch data.""" |
| 489 return '${pchprefix}.' + self._PchHeader() + '.pch' |
| 490 |
| 491 def GetObjDependencies(self, sources, objs): |
| 492 """Given a list of sources files and the corresponding object files, |
| 493 returns a list of the pch files that should be depended upon. The |
| 494 additional wrapping in the return value is for interface compatability |
| 495 with make.py on Mac, and xcode_emulation.py.""" |
| 496 if not self._PchHeader(): |
| 497 return [] |
| 498 source = self._PchSource() |
| 499 assert source |
| 500 pch_ext = os.path.splitext(self._PchSource())[1] |
| 501 for source in sources: |
| 502 if _LanguageMatchesForPch(os.path.splitext(source)[1], pch_ext): |
| 503 return [(None, None, self._PchOutput())] |
| 504 return [] |
| 505 |
| 506 def GetPchBuildCommands(self): |
| 507 """Returns [(path_to_pch, language_flag, language, header)]. |
| 508 |path_to_gch| and |header| are relative to the build directory.""" |
| 509 header = self._PchHeader() |
| 510 source = self._PchSource() |
| 511 if not source or not header: |
| 512 return [] |
| 513 ext = os.path.splitext(source)[1] |
| 514 lang = 'c' if ext == '.c' else 'cc' |
| 515 return [(self._PchOutput(), '/Yc' + header, lang, source)] |
| 516 |
| 517 |
| 441 vs_version = None | 518 vs_version = None |
| 442 def GetVSVersion(generator_flags): | 519 def GetVSVersion(generator_flags): |
| 443 global vs_version | 520 global vs_version |
| 444 if not vs_version: | 521 if not vs_version: |
| 445 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion( | 522 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion( |
| 446 generator_flags.get('msvs_version', 'auto')) | 523 generator_flags.get('msvs_version', 'auto')) |
| 447 return vs_version | 524 return vs_version |
| 448 | 525 |
| 449 def _GetBinaryPath(generator_flags, tool): | 526 def _GetBinaryPath(generator_flags, tool): |
| 450 vs = GetVSVersion(generator_flags) | 527 vs = GetVSVersion(generator_flags) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 470 return vs.SetupScript() | 547 return vs.SetupScript() |
| 471 | 548 |
| 472 def ExpandMacros(string, expansions): | 549 def ExpandMacros(string, expansions): |
| 473 """Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv | 550 """Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv |
| 474 for the canonical way to retrieve a suitable dict.""" | 551 for the canonical way to retrieve a suitable dict.""" |
| 475 if '$' in string: | 552 if '$' in string: |
| 476 for old, new in expansions.iteritems(): | 553 for old, new in expansions.iteritems(): |
| 477 assert '$(' not in new, new | 554 assert '$(' not in new, new |
| 478 string = string.replace(old, new) | 555 string = string.replace(old, new) |
| 479 return string | 556 return string |
| OLD | NEW |