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 |