Show More
@@ -516,6 +516,26 class buildhgextindex(Command): | |||
|
516 | 516 | |
|
517 | 517 | class buildhgexe(build_ext): |
|
518 | 518 | description = 'compile hg.exe from mercurial/exewrapper.c' |
|
519 | user_options = build_ext.user_options + [ | |
|
520 | ('long-paths-support', None, 'enable support for long paths on ' | |
|
521 | 'Windows (off by default and ' | |
|
522 | 'experimental)'), | |
|
523 | ] | |
|
524 | ||
|
525 | LONG_PATHS_MANIFEST = """ | |
|
526 | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
|
527 | <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |
|
528 | <application> | |
|
529 | <windowsSettings | |
|
530 | xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> | |
|
531 | <ws2:longPathAware>true</ws2:longPathAware> | |
|
532 | </windowsSettings> | |
|
533 | </application> | |
|
534 | </assembly>""" | |
|
535 | ||
|
536 | def initialize_options(self): | |
|
537 | build_ext.initialize_options(self) | |
|
538 | self.long_paths_support = False | |
|
519 | 539 | |
|
520 | 540 | def build_extensions(self): |
|
521 | 541 | if os.name != 'nt': |
@@ -557,10 +577,45 class buildhgexe(build_ext): | |||
|
557 | 577 | objects = self.compiler.compile(['mercurial/exewrapper.c'], |
|
558 | 578 | output_dir=self.build_temp) |
|
559 | 579 | dir = os.path.dirname(self.get_ext_fullpath('dummy')) |
|
560 | target = os.path.join(dir, 'hg') | |
|
561 | self.compiler.link_executable(objects, target, | |
|
580 | self.hgtarget = os.path.join(dir, 'hg') | |
|
581 | self.compiler.link_executable(objects, self.hgtarget, | |
|
562 | 582 | libraries=[], |
|
563 | 583 | output_dir=self.build_temp) |
|
584 | if self.long_paths_support: | |
|
585 | self.addlongpathsmanifest() | |
|
586 | ||
|
587 | def addlongpathsmanifest(self): | |
|
588 | """Add manifest pieces so that hg.exe understands long paths | |
|
589 | ||
|
590 | This is an EXPERIMENTAL feature, use with care. | |
|
591 | To enable long paths support, one needs to do two things: | |
|
592 | - build Mercurial with --long-paths-support option | |
|
593 | - change HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\ | |
|
594 | LongPathsEnabled to have value 1. | |
|
595 | ||
|
596 | Please ignore 'warning 81010002: Unrecognized Element "longPathAware"'; | |
|
597 | it happens because Mercurial uses mt.exe circa 2008, which is not | |
|
598 | yet aware of long paths support in the manifest (I think so at least). | |
|
599 | This does not stop mt.exe from embedding/merging the XML properly. | |
|
600 | ||
|
601 | Why resource #1 should be used for .exe manifests? I don't know and | |
|
602 | wasn't able to find an explanation for mortals. But it seems to work. | |
|
603 | """ | |
|
604 | exefname = self.compiler.executable_filename(self.hgtarget) | |
|
605 | fdauto, manfname = tempfile.mkstemp(suffix='.hg.exe.manifest') | |
|
606 | os.close(fdauto) | |
|
607 | with open(manfname, 'w') as f: | |
|
608 | f.write(self.LONG_PATHS_MANIFEST) | |
|
609 | log.info("long paths manifest is written to '%s'" % manfname) | |
|
610 | inputresource = '-inputresource:%s;#1' % exefname | |
|
611 | outputresource = '-outputresource:%s;#1' % exefname | |
|
612 | log.info("running mt.exe to update hg.exe's manifest in-place") | |
|
613 | # supplying both -manifest and -inputresource to mt.exe makes | |
|
614 | # it merge the embedded and supplied manifests in the -outputresource | |
|
615 | self.spawn(['mt.exe', '-nologo', '-manifest', manfname, | |
|
616 | inputresource, outputresource]) | |
|
617 | log.info("done updating hg.exe's manifest") | |
|
618 | os.remove(manfname) | |
|
564 | 619 | |
|
565 | 620 | @property |
|
566 | 621 | def hgexepath(self): |
General Comments 0
You need to be logged in to leave comments.
Login now