Chromium Code Reviews| 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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 if it's not overridden.""" | 447 if it's not overridden.""" |
| 448 config = self._TargetConfig(config) | 448 config = self._TargetConfig(config) |
| 449 output_file = self._Setting( | 449 output_file = self._Setting( |
| 450 ('VCLinkerTool', 'ProfileGuidedDatabase'), config) | 450 ('VCLinkerTool', 'ProfileGuidedDatabase'), config) |
| 451 if output_file: | 451 if output_file: |
| 452 output_file = expand_special(self.ConvertVSMacros( | 452 output_file = expand_special(self.ConvertVSMacros( |
| 453 output_file, config=config)) | 453 output_file, config=config)) |
| 454 return output_file | 454 return output_file |
| 455 | 455 |
| 456 def GetLdflags(self, config, gyp_to_build_path, expand_special, | 456 def GetLdflags(self, config, gyp_to_build_path, expand_special, |
| 457 manifest_base_name, is_executable): | 457 manifest_base_name, is_executable, build_dir, open_output): |
| 458 """Returns the flags that need to be added to link commands, and the | 458 """Returns the flags that need to be added to link commands, and the |
| 459 manifest files.""" | 459 manifest files.""" |
| 460 config = self._TargetConfig(config) | 460 config = self._TargetConfig(config) |
| 461 ldflags = [] | 461 ldflags = [] |
| 462 ld = self._GetWrapper(self, self.msvs_settings[config], | 462 ld = self._GetWrapper(self, self.msvs_settings[config], |
| 463 'VCLinkerTool', append=ldflags) | 463 'VCLinkerTool', append=ldflags) |
| 464 self._GetDefFileAsLdflags(ldflags, gyp_to_build_path) | 464 self._GetDefFileAsLdflags(ldflags, gyp_to_build_path) |
| 465 ld('GenerateDebugInformation', map={'true': '/DEBUG'}) | 465 ld('GenerateDebugInformation', map={'true': '/DEBUG'}) |
| 466 ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:') | 466 ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:') |
| 467 ldflags.extend(self._GetAdditionalLibraryDirectories( | 467 ldflags.extend(self._GetAdditionalLibraryDirectories( |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 ldflags.append('/DYNAMICBASE') | 524 ldflags.append('/DYNAMICBASE') |
| 525 | 525 |
| 526 # If the NXCOMPAT flag has not been specified, default to on. Despite the | 526 # If the NXCOMPAT flag has not been specified, default to on. Despite the |
| 527 # documentation that says this only defaults to on when the subsystem is | 527 # documentation that says this only defaults to on when the subsystem is |
| 528 # Vista or greater (which applies to the linker), the IDE defaults it on | 528 # Vista or greater (which applies to the linker), the IDE defaults it on |
| 529 # unless it's explicitly off. | 529 # unless it's explicitly off. |
| 530 if not filter(lambda x: 'NXCOMPAT' in x, ldflags): | 530 if not filter(lambda x: 'NXCOMPAT' in x, ldflags): |
| 531 ldflags.append('/NXCOMPAT') | 531 ldflags.append('/NXCOMPAT') |
| 532 | 532 |
| 533 have_def_file = filter(lambda x: x.startswith('/DEF:'), ldflags) | 533 have_def_file = filter(lambda x: x.startswith('/DEF:'), ldflags) |
| 534 manifest_flags, manifest_files = self._GetLdManifestFlags( | 534 manifest_flags, intermediate_manifest, manifest_files = \ |
| 535 config, manifest_base_name, gyp_to_build_path, | 535 self._GetLdManifestFlags(config, manifest_base_name, gyp_to_build_path, |
| 536 is_executable and not have_def_file) | 536 is_executable and not have_def_file, build_dir, |
| 537 open_output) | |
| 537 ldflags.extend(manifest_flags) | 538 ldflags.extend(manifest_flags) |
| 538 return ldflags, manifest_files | 539 return ldflags, intermediate_manifest, manifest_files |
| 539 | 540 |
| 540 def _GetLdManifestFlags(self, config, name, gyp_to_build_path, | 541 def _GetLdManifestFlags(self, config, name, gyp_to_build_path, |
| 541 allow_isolation): | 542 allow_isolation, build_dir, open_output): |
| 542 """Returns the set of flags that need to be added to the link to generate | 543 """Returns a 3-tuple: |
| 543 a default manifest, as well as the list of all the manifest files to be | 544 - the set of flags that need to be added to the link to generate |
| 544 merged by the manifest tool.""" | 545 a default manifest |
| 546 - the intermediate manifest that the linker will generate that should be | |
| 547 used to assert it doesn't add anything to the merged one. | |
| 548 - the list of all the manifest files to be merged by the manifest tool and | |
| 549 included into the link.""" | |
| 545 generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'), | 550 generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'), |
| 546 config, | 551 config, |
| 547 default='true') | 552 default='true') |
| 548 if generate_manifest != 'true': | 553 if generate_manifest != 'true': |
| 549 # This means not only that the linker should not generate the intermediate | 554 # This means not only that the linker should not generate the intermediate |
| 550 # manifest but also that the manifest tool should do nothing even when | 555 # manifest but also that the manifest tool should do nothing even when |
| 551 # additional manifests are specified. | 556 # additional manifests are specified. |
| 552 return ['/MANIFEST:NO'], [] | 557 return ['/MANIFEST:NO'], [], [] |
| 553 | 558 |
| 554 output_name = name + '.intermediate.manifest' | 559 output_name = name + '.intermediate.manifest' |
| 555 flags = [ | 560 flags = [ |
| 556 '/MANIFEST', | 561 '/MANIFEST', |
| 557 '/ManifestFile:' + output_name, | 562 '/ManifestFile:' + output_name, |
| 558 ] | 563 ] |
| 559 | 564 |
| 565 # Instead of using the MANIFESTUAC flags, we generate a .manifest to | |
| 566 # include into the list of manifests. This allows us to avoid the need to | |
| 567 # do two passing during linking. The /MANIFEST flag and /ManifestFile are | |
| 568 # still used, and the intermediate manifest is used to assert that the | |
| 569 # final manifest we get from merging all the additional manifest files | |
| 570 # (plus the one we generate here) isn't modified by merging the | |
| 571 # intermediate into it. | |
| 572 | |
| 573 # Always NO, because we generate a manifest file that has what we want. | |
| 574 flags.append('/MANIFESTUAC:NO') | |
| 575 | |
| 560 config = self._TargetConfig(config) | 576 config = self._TargetConfig(config) |
| 561 enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config, | 577 enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config, |
| 562 default='true') | 578 default='true') |
| 579 manifest_files = [] | |
| 563 if enable_uac == 'true': | 580 if enable_uac == 'true': |
| 564 execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'), | 581 execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'), |
| 565 config, default='0') | 582 config, default='0') |
| 566 execution_level_map = { | 583 execution_level_map = { |
| 567 '0': 'asInvoker', | 584 '0': 'asInvoker', |
| 568 '1': 'highestAvailable', | 585 '1': 'highestAvailable', |
| 569 '2': 'requireAdministrator' | 586 '2': 'requireAdministrator' |
| 570 } | 587 } |
| 571 | 588 |
| 572 ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config, | 589 ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config, |
| 573 default='false') | 590 default='false') |
| 574 flags.append('''/MANIFESTUAC:"level='%s' uiAccess='%s'"''' % | 591 |
| 575 (execution_level_map[execution_level], ui_access)) | 592 generated_manifest_contents = ''' |
| 576 else: | 593 <?xml version='1.0' encoding='UTF-8' standalone='yes'?> |
| 577 flags.append('/MANIFESTUAC:NO') | 594 <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> |
| 595 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> | |
| 596 <security> | |
| 597 <requestedPrivileges> | |
| 598 <requestedExecutionLevel level='%s' uiAccess='%s' /> | |
| 599 </requestedPrivileges> | |
| 600 </security> | |
| 601 </trustInfo> | |
| 602 </assembly>''' % (execution_level_map[execution_level], ui_access) | |
| 603 generated_name = name + '.generated.manifest' | |
| 604 # Need to join with the build_dir here as we're writing it during | |
| 605 # generation time, but we return the un-joined version because the build | |
| 606 # will occur in that directory. | |
| 607 with open_output(os.path.join(build_dir, generated_name), 'w') as f: | |
|
yukawa
2013/12/10 11:18:30
If the time stamp of |os.path.join(build_dir, gene
scottmg
2013/12/10 19:27:21
Good question! I believe it will not cause unneces
| |
| 608 f.write(generated_manifest_contents) | |
| 609 manifest_files = [generated_name] | |
| 578 | 610 |
| 579 if allow_isolation: | 611 if allow_isolation: |
| 580 flags.append('/ALLOWISOLATION') | 612 flags.append('/ALLOWISOLATION') |
| 581 | 613 |
| 582 manifest_files = [output_name] | |
| 583 manifest_files += self._GetAdditionalManifestFiles(config, | 614 manifest_files += self._GetAdditionalManifestFiles(config, |
| 584 gyp_to_build_path) | 615 gyp_to_build_path) |
| 585 return flags, manifest_files | 616 return flags, output_name, manifest_files |
| 586 | 617 |
| 587 def _GetAdditionalManifestFiles(self, config, gyp_to_build_path): | 618 def _GetAdditionalManifestFiles(self, config, gyp_to_build_path): |
| 588 """Gets additional manifest files that are added to the default one | 619 """Gets additional manifest files that are added to the default one |
| 589 generated by the linker.""" | 620 generated by the linker.""" |
| 590 files = self._Setting(('VCManifestTool', 'AdditionalManifestFiles'), config, | 621 files = self._Setting(('VCManifestTool', 'AdditionalManifestFiles'), config, |
| 591 default=[]) | 622 default=[]) |
| 592 if isinstance(files, str): | 623 if isinstance(files, str): |
| 593 files = files.split(';') | 624 files = files.split(';') |
| 594 return [os.path.normpath( | 625 return [os.path.normpath( |
| 595 gyp_to_build_path(self.ConvertVSMacros(f, config=config))) | 626 gyp_to_build_path(self.ConvertVSMacros(f, config=config))) |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 903 | 934 |
| 904 # To determine processor word size on Windows, in addition to checking | 935 # To determine processor word size on Windows, in addition to checking |
| 905 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current | 936 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current |
| 906 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which | 937 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which |
| 907 # contains the actual word size of the system when running thru WOW64). | 938 # contains the actual word size of the system when running thru WOW64). |
| 908 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or | 939 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or |
| 909 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): | 940 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): |
| 910 default_variables['MSVS_OS_BITS'] = 64 | 941 default_variables['MSVS_OS_BITS'] = 64 |
| 911 else: | 942 else: |
| 912 default_variables['MSVS_OS_BITS'] = 32 | 943 default_variables['MSVS_OS_BITS'] = 32 |
| OLD | NEW |