contrib/packaging/wix/mercurial.wxs
author Gregory Szorc <gregory.szorc@gmail.com>
Thu, 06 May 2021 16:03:43 -0700
changeset 47205 603efb3845ba
parent 46819 d4ba4d51f85f
child 49169 06107198f95b
permissions -rw-r--r--
pyoxidizer: support producing MSI installers Newer versions of PyOxidizer have support for building WiX MSI installers "natively." Essentially, you can script the definition of your WiX installer via Starlark and PyOxidizer can invoke WiX tools to produce the installer. This commit teaches our PyOxidizer config file to produce MSI installers similarly to how `contrib/packaging/packging.py wix` would do it. We had to make a very minor change to `mercurial.wxs` to reflect different paths depending on who builds. This is because when PyOxidizer builds WiX installers, it does so from an isolated directory, not Mercurial's source directory. We simply copy the files into the build environment so they are accessible. After this change, running `pyoxidizer build msi` produces a nearly identical install layout to what the previous method produces. When I applied this series on top of the 5.8 tag, here is the list of differences and explanations: * docs/*.html files are missing from the new installer because the Python build environment doesn't have docutils. * .pyd and .exe files differ, likely because I'm using a different Visual Studio toolchain on my local computer than the official build environment. * Various .dist-info/ directories have different names. This is because older versions of PyOxidizer had buggy behavior and weren't properly normalizing package names in .dist-info/ directories. e.g. we went from `cached-property-1.5.2.dist-info` to `cached_property-1.5.2.dist-info`. * Translations (.mo files) may be missing if gettext isn't in %Path%. This is because the packaging.py code installs gettext and ensures it can be found. * Some *.dist-info/RECORD files vary due to SHA-256 content digest divergence due to build environment differences. (This should be harmless.) * The new install layout ships a python3.dll because newer versions of PyOxidizer ship this file. * The new install layout has a different vcruntime140.dll and also a vcruntime140_1.dll because newer versions of PyOxidizer ship a newer version of the Visual C++ Redistributable Runtime. The new PyOxidizer functionality is not yet integrated with packaging.py. This will come in a subsequent commit. So for now, the new functionality introduced here is unused. Differential Revision: https://phab.mercurial-scm.org/D10683

<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>

  <!-- Copyright 2010 Steve Borho <steve@borho.org>

  This software may be used and distributed according to the terms of the
  GNU General Public License version 2 or any later version. -->

  <?include guids.wxi ?>
  <?include defines.wxi ?>

  <?if $(var.Platform) = "x64" ?>
    <?define PFolder = ProgramFiles64Folder ?>
  <?else?>
    <?define PFolder = ProgramFilesFolder ?>
  <?endif?>

  <Product Id='*'
    Name='Mercurial $(var.Version) ($(var.Platform))'
    UpgradeCode='$(var.ProductUpgradeCode)'
    Language='1033' Codepage='1252' Version='$(var.Version)'
    Manufacturer='Olivia Mackall and others'>

    <Package Id='*'
      Keywords='Installer'
      Description="Mercurial distributed SCM (version $(var.Version))"
      Comments='$(var.Comments)'
      Platform='$(var.Platform)'
      Manufacturer='Olivia Mackall and others'
      InstallerVersion='300' Languages='1033' Compressed='yes' SummaryCodepage='1252' />

    <Media Id='1' Cabinet='mercurial.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'
           CompressionLevel='high' />
    <Property Id='DiskPrompt' Value="Mercurial $(var.Version) Installation [1]" />

    <Condition Message='Mercurial MSI installers require Windows XP or higher'>
        VersionNT >= 501
    </Condition>

    <Property Id="INSTALLDIR">
      <ComponentSearch Id='SearchForMainExecutableComponent'
                       Guid='$(var.ComponentMainExecutableGUID)'
                       Type='directory' />
    </Property>

    <!--Property Id='ARPCOMMENTS'>any comments</Property-->
    <Property Id='ARPCONTACT'>mercurial@mercurial-scm.org</Property>
    <Property Id='ARPHELPLINK'>https://mercurial-scm.org/wiki/</Property>
    <Property Id='ARPURLINFOABOUT'>https://mercurial-scm.org/about/</Property>
    <Property Id='ARPURLUPDATEINFO'>https://mercurial-scm.org/downloads/</Property>
    <Property Id='ARPHELPTELEPHONE'>https://mercurial-scm.org/wiki/Support</Property>
    <Property Id='ARPPRODUCTICON'>hgIcon.ico</Property>

    <Property Id='INSTALLEDMERCURIALPRODUCTS' Secure='yes'></Property>
    <Property Id='REINSTALLMODE'>amus</Property>

    <!--Auto-accept the license page-->
    <Property Id='LicenseAccepted'>1</Property>

    <Directory Id='TARGETDIR' Name='SourceDir'>
      <Directory Id='$(var.PFolder)' Name='PFiles'>
        <Directory Id='INSTALLDIR' Name='Mercurial'>
          <Component Id='MainExecutable' Guid='$(var.ComponentMainExecutableGUID)' Win64='$(var.IsX64)'>
            <CreateFolder />
            <Environment Id="Environment" Name="PATH" Part="last" System="yes"
                         Permanent="no" Value="[INSTALLDIR]" Action="set" />
          </Component>
        </Directory>
      </Directory>

      <Directory Id="ProgramMenuFolder" Name="Programs">
        <Directory Id="ProgramMenuDir" Name="Mercurial $(var.Version)">
          <Component Id="ProgramMenuDir" Guid="$(var.ProgramMenuDir.guid)" Win64='$(var.IsX64)'>
            <RemoveFolder Id='ProgramMenuDir' On='uninstall' />
            <RegistryValue Root='HKCU' Key='Software\Mercurial\InstallDir' Type='string'
                           Value='[INSTALLDIR]' KeyPath='yes' />
            <Shortcut Id='UrlShortcut' Directory='ProgramMenuDir' Name='Mercurial Web Site'
                      Target='[ARPHELPLINK]' Icon="hgIcon.ico" IconIndex='0' />
          </Component>
        </Directory>
      </Directory>

      <!-- Install VCRedist merge modules on Python 2. On Python 3,
           vcruntimeXXX.dll is part of the install layout and gets picked up
           as a regular file. -->
      <?if $(var.PythonVersion) = "2" ?>
        <?if $(var.Platform) = "x86" ?>
          <Merge Id='VCRuntime' DiskId='1' Language='1033'
                SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x86_msm.msm' />
          <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
                SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
        <?else?>
          <Merge Id='VCRuntime' DiskId='1' Language='1033'
                SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x64_msm.msm' />
          <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
                SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x64_msm.msm' />
        <?endif?>
      <?endif?>
    </Directory>

    <Feature Id='Complete' Title='Mercurial' Description='The complete package'
        Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR' >
      <Feature Id='MainProgram' Title='Program' Description='Mercurial command line app'
             Level='1' Absent='disallow' >
        <ComponentRef Id='MainExecutable' />
        <ComponentRef Id='ProgramMenuDir' />
        <ComponentGroupRef Id="hg.group.ROOT" />
        <ComponentGroupRef Id="hg.group.defaultrc" />
        <ComponentGroupRef Id="hg.group.helptext" />
        <?ifdef MercurialHasLib?>
          <ComponentGroupRef Id="hg.group.lib" />
        <?endif?>
        <ComponentGroupRef Id="hg.group.templates" />
        <?if $(var.PythonVersion) = "2" ?>
          <MergeRef Id='VCRuntime' />
          <MergeRef Id='VCRuntimePolicy' />
        <?endif?>
      </Feature>
      <?ifdef MercurialExtraFeatures?>
        <?foreach EXTRAFEAT in $(var.MercurialExtraFeatures)?>
          <FeatureRef Id="$(var.EXTRAFEAT)" />
        <?endforeach?>
      <?endif?>
      <Feature Id='Locales' Title='Translations' Description='Translations' Level='1'>
        <ComponentGroupRef Id="hg.group.locale" />
      </Feature>
      <Feature Id='Documentation' Title='Documentation' Description='HTML man pages' Level='1'>
        <ComponentGroupRef Id="hg.group.doc" />
      </Feature>
      <Feature Id='Misc' Title='Miscellaneous' Description='Contributed scripts' Level='1'>
        <ComponentGroupRef Id="hg.group.contrib" />
      </Feature>
    </Feature>

    <UIRef Id="WixUI_FeatureTree" />
    <UIRef Id="WixUI_ErrorProgressText" />

    <?ifdef PyOxidizer?>
    <WixVariable Id="WixUILicenseRtf" Value="COPYING.rtf" />
    <Icon Id="hgIcon.ico" SourceFile="mercurial.ico" />
    <?else?>
    <WixVariable Id="WixUILicenseRtf" Value="contrib\packaging\wix\COPYING.rtf" />
    <Icon Id="hgIcon.ico" SourceFile="contrib/win32/mercurial.ico" />
    <?endif?>

    <Upgrade Id='$(var.ProductUpgradeCode)'>
      <UpgradeVersion
        IncludeMinimum='yes' Minimum='0.0.0' IncludeMaximum='no' OnlyDetect='no'
        Property='INSTALLEDMERCURIALPRODUCTS' />
    </Upgrade>

    <InstallExecuteSequence>
      <RemoveExistingProducts After='InstallInitialize'/>
    </InstallExecuteSequence>

  </Product>
</Wix>