Mercurial > hg
comparison setup.py @ 49396:ece490b02a9b
setup: use the full executable manifest from `python.exe`
The manifest embedded by the build process (before the string here is added)
already accounts for the `<requestedExecutionLevel level="asInvoker" ...>`
setting. (Note that the PyOxidizer build is missing this, so it will likely
trigger the UAC escalation prompt on each run.) However, using `mt.exe` to
merge the fragment with what is already in the manifest seems to strip all
whitespace, making it unreadable.
Since Mercurial can be run via `python.exe`, it makes sense that we would have
the same manifest settings (like the supported OS list), though I'm unaware of
any functionality this enables. It also has the nice effect of making the
content readable from a resource editor. The manifest comes from python 3.9.12.
Note that this seems to strip the `<?xml ... ?>` declaration when viewed with
ResourceHacker 5.1.7, but this was also the state of things with the previous
commit, and `mt.exe "-inputresource:hg.exe;#1" -out:extracted` does contain the
declaration and the BOM in both cases. No idea why this differs from other
executables.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Mon, 18 Jul 2022 19:18:00 -0400 |
parents | 747c4fc20886 |
children | 54421ef8a423 bc59c1e5dd01 |
comparison
equal
deleted
inserted
replaced
49395:747c4fc20886 | 49396:ece490b02a9b |
---|---|
665 | 665 |
666 | 666 |
667 class buildhgexe(build_ext): | 667 class buildhgexe(build_ext): |
668 description = 'compile hg.exe from mercurial/exewrapper.c' | 668 description = 'compile hg.exe from mercurial/exewrapper.c' |
669 | 669 |
670 LONG_PATHS_MANIFEST = """ | 670 LONG_PATHS_MANIFEST = """\ |
671 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | 671 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
672 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | 672 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> |
673 <application> | 673 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> |
674 <windowsSettings | 674 <security> |
675 xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> | 675 <requestedPrivileges> |
676 <ws2:longPathAware>true</ws2:longPathAware> | 676 <requestedExecutionLevel |
677 </windowsSettings> | 677 level="asInvoker" |
678 </application> | 678 uiAccess="false" |
679 </assembly>""" | 679 /> |
680 </requestedPrivileges> | |
681 </security> | |
682 </trustInfo> | |
683 <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> | |
684 <application> | |
685 <!-- Windows Vista --> | |
686 <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> | |
687 <!-- Windows 7 --> | |
688 <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> | |
689 <!-- Windows 8 --> | |
690 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> | |
691 <!-- Windows 8.1 --> | |
692 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> | |
693 <!-- Windows 10 and Windows 11 --> | |
694 <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> | |
695 </application> | |
696 </compatibility> | |
697 <application xmlns="urn:schemas-microsoft-com:asm.v3"> | |
698 <windowsSettings | |
699 xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> | |
700 <ws2:longPathAware>true</ws2:longPathAware> | |
701 </windowsSettings> | |
702 </application> | |
703 <dependency> | |
704 <dependentAssembly> | |
705 <assemblyIdentity type="win32" | |
706 name="Microsoft.Windows.Common-Controls" | |
707 version="6.0.0.0" | |
708 processorArchitecture="*" | |
709 publicKeyToken="6595b64144ccf1df" | |
710 language="*" /> | |
711 </dependentAssembly> | |
712 </dependency> | |
713 </assembly> | |
714 """ | |
680 | 715 |
681 def initialize_options(self): | 716 def initialize_options(self): |
682 build_ext.initialize_options(self) | 717 build_ext.initialize_options(self) |
683 | 718 |
684 def build_extensions(self): | 719 def build_extensions(self): |
774 wasn't able to find an explanation for mortals. But it seems to work. | 809 wasn't able to find an explanation for mortals. But it seems to work. |
775 """ | 810 """ |
776 exefname = self.compiler.executable_filename(self.hgtarget) | 811 exefname = self.compiler.executable_filename(self.hgtarget) |
777 fdauto, manfname = tempfile.mkstemp(suffix='.hg.exe.manifest') | 812 fdauto, manfname = tempfile.mkstemp(suffix='.hg.exe.manifest') |
778 os.close(fdauto) | 813 os.close(fdauto) |
779 with open(manfname, 'w') as f: | 814 with open(manfname, 'w', encoding="UTF-8") as f: |
780 f.write(self.LONG_PATHS_MANIFEST) | 815 f.write(self.LONG_PATHS_MANIFEST) |
781 log.info("long paths manifest is written to '%s'" % manfname) | 816 log.info("long paths manifest is written to '%s'" % manfname) |
782 inputresource = '-inputresource:%s;#1' % exefname | |
783 outputresource = '-outputresource:%s;#1' % exefname | 817 outputresource = '-outputresource:%s;#1' % exefname |
784 log.info("running mt.exe to update hg.exe's manifest in-place") | 818 log.info("running mt.exe to update hg.exe's manifest in-place") |
785 # supplying both -manifest and -inputresource to mt.exe makes | 819 |
786 # it merge the embedded and supplied manifests in the -outputresource | |
787 self.spawn( | 820 self.spawn( |
788 [ | 821 [ |
789 self.compiler.mt, | 822 self.compiler.mt, |
790 '-nologo', | 823 '-nologo', |
791 '-manifest', | 824 '-manifest', |
792 manfname, | 825 manfname, |
793 inputresource, | |
794 outputresource, | 826 outputresource, |
795 ] | 827 ] |
796 ) | 828 ) |
797 log.info("done updating hg.exe's manifest") | 829 log.info("done updating hg.exe's manifest") |
798 os.remove(manfname) | 830 os.remove(manfname) |