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): |
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 ldflags.extend(manifest_flags) | 537 ldflags.extend(manifest_flags) |
538 return ldflags, manifest_files | 538 return ldflags, intermediate_manifest, manifest_files |
539 | 539 |
540 def _GetLdManifestFlags(self, config, name, gyp_to_build_path, | 540 def _GetLdManifestFlags(self, config, name, gyp_to_build_path, |
541 allow_isolation): | 541 allow_isolation, build_dir): |
542 """Returns the set of flags that need to be added to the link to generate | 542 """Returns a 3-tuple: |
543 a default manifest, as well as the list of all the manifest files to be | 543 - the set of flags that need to be added to the link to generate |
544 merged by the manifest tool.""" | 544 a default manifest |
| 545 - the intermediate manifest that the linker will generate that should be |
| 546 used to assert it doesn't add anything to the merged one. |
| 547 - the list of all the manifest files to be merged by the manifest tool and |
| 548 included into the link.""" |
545 generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'), | 549 generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'), |
546 config, | 550 config, |
547 default='true') | 551 default='true') |
548 if generate_manifest != 'true': | 552 if generate_manifest != 'true': |
549 # This means not only that the linker should not generate the intermediate | 553 # 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 | 554 # manifest but also that the manifest tool should do nothing even when |
551 # additional manifests are specified. | 555 # additional manifests are specified. |
552 return ['/MANIFEST:NO'], [] | 556 return ['/MANIFEST:NO'], [], [] |
553 | 557 |
554 output_name = name + '.intermediate.manifest' | 558 output_name = name + '.intermediate.manifest' |
555 flags = [ | 559 flags = [ |
556 '/MANIFEST', | 560 '/MANIFEST', |
557 '/ManifestFile:' + output_name, | 561 '/ManifestFile:' + output_name, |
558 ] | 562 ] |
559 | 563 |
| 564 # Instead of using the MANIFESTUAC flags, we generate a .manifest to |
| 565 # include into the list of manifests. This allows us to avoid the need to |
| 566 # do two passes during linking. The /MANIFEST flag and /ManifestFile are |
| 567 # still used, and the intermediate manifest is used to assert that the |
| 568 # final manifest we get from merging all the additional manifest files |
| 569 # (plus the one we generate here) isn't modified by merging the |
| 570 # intermediate into it. |
| 571 |
| 572 # Always NO, because we generate a manifest file that has what we want. |
| 573 flags.append('/MANIFESTUAC:NO') |
| 574 |
560 config = self._TargetConfig(config) | 575 config = self._TargetConfig(config) |
561 enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config, | 576 enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config, |
562 default='true') | 577 default='true') |
| 578 manifest_files = [] |
| 579 generated_manifest_outer = \ |
| 580 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" \ |
| 581 "<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>%s" \ |
| 582 "</assembly>" |
563 if enable_uac == 'true': | 583 if enable_uac == 'true': |
564 execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'), | 584 execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'), |
565 config, default='0') | 585 config, default='0') |
566 execution_level_map = { | 586 execution_level_map = { |
567 '0': 'asInvoker', | 587 '0': 'asInvoker', |
568 '1': 'highestAvailable', | 588 '1': 'highestAvailable', |
569 '2': 'requireAdministrator' | 589 '2': 'requireAdministrator' |
570 } | 590 } |
571 | 591 |
572 ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config, | 592 ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config, |
573 default='false') | 593 default='false') |
574 flags.append('''/MANIFESTUAC:"level='%s' uiAccess='%s'"''' % | 594 |
575 (execution_level_map[execution_level], ui_access)) | 595 inner = ''' |
| 596 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> |
| 597 <security> |
| 598 <requestedPrivileges> |
| 599 <requestedExecutionLevel level='%s' uiAccess='%s' /> |
| 600 </requestedPrivileges> |
| 601 </security> |
| 602 </trustInfo>''' % (execution_level_map[execution_level], ui_access) |
576 else: | 603 else: |
577 flags.append('/MANIFESTUAC:NO') | 604 inner = '' |
| 605 |
| 606 generated_manifest_contents = generated_manifest_outer % inner |
| 607 generated_name = name + '.generated.manifest' |
| 608 # Need to join with the build_dir here as we're writing it during |
| 609 # generation time, but we return the un-joined version because the build |
| 610 # will occur in that directory. We only write the file if the contents |
| 611 # have changed so that simply regenerating the project files doesn't |
| 612 # cause a relink. |
| 613 build_dir_generated_name = os.path.join(build_dir, generated_name) |
| 614 gyp.common.EnsureDirExists(build_dir_generated_name) |
| 615 f = gyp.common.WriteOnDiff(build_dir_generated_name) |
| 616 f.write(generated_manifest_contents) |
| 617 f.close() |
| 618 manifest_files = [generated_name] |
578 | 619 |
579 if allow_isolation: | 620 if allow_isolation: |
580 flags.append('/ALLOWISOLATION') | 621 flags.append('/ALLOWISOLATION') |
581 | 622 |
582 manifest_files = [output_name] | |
583 manifest_files += self._GetAdditionalManifestFiles(config, | 623 manifest_files += self._GetAdditionalManifestFiles(config, |
584 gyp_to_build_path) | 624 gyp_to_build_path) |
585 return flags, manifest_files | 625 return flags, output_name, manifest_files |
586 | 626 |
587 def _GetAdditionalManifestFiles(self, config, gyp_to_build_path): | 627 def _GetAdditionalManifestFiles(self, config, gyp_to_build_path): |
588 """Gets additional manifest files that are added to the default one | 628 """Gets additional manifest files that are added to the default one |
589 generated by the linker.""" | 629 generated by the linker.""" |
590 files = self._Setting(('VCManifestTool', 'AdditionalManifestFiles'), config, | 630 files = self._Setting(('VCManifestTool', 'AdditionalManifestFiles'), config, |
591 default=[]) | 631 default=[]) |
592 if isinstance(files, str): | 632 if isinstance(files, str): |
593 files = files.split(';') | 633 files = files.split(';') |
594 return [os.path.normpath( | 634 return [os.path.normpath( |
595 gyp_to_build_path(self.ConvertVSMacros(f, config=config))) | 635 gyp_to_build_path(self.ConvertVSMacros(f, config=config))) |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 | 943 |
904 # To determine processor word size on Windows, in addition to checking | 944 # To determine processor word size on Windows, in addition to checking |
905 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current | 945 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current |
906 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which | 946 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which |
907 # contains the actual word size of the system when running thru WOW64). | 947 # contains the actual word size of the system when running thru WOW64). |
908 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or | 948 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or |
909 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): | 949 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): |
910 default_variables['MSVS_OS_BITS'] = 64 | 950 default_variables['MSVS_OS_BITS'] = 64 |
911 else: | 951 else: |
912 default_variables['MSVS_OS_BITS'] = 32 | 952 default_variables['MSVS_OS_BITS'] = 32 |
OLD | NEW |