( )⚙ D10683 pyoxidizer: support producing MSI installers

This is an archive of the discontinued Mercurial Phabricator instance.

pyoxidizer: support producing MSI installers
ClosedPublic

Authored by indygreg on May 6 2021, 8:00 PM.

Details

Summary

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.

Diff Detail

Repository
rHG Mercurial
Branch
default
Lint
No Linters Available
Unit
No Unit Test Coverage

Event Timeline

indygreg created this revision.May 6 2021, 8:00 PM

@mharbison72 You may be interested in this series starting at approximately this patch. Version 0.15 of PyOxidizer supports building MSIs "natively." I implemented enough features to port Mercurial's MSI generation to it. I need to have a go at porting TortoiseHg to use PyOxidizer. But I'm optimistic it is doable. Note that you don't need to use the "build a Python binary" pieces of PyOxidizer with MSI generation: they are completely separate.

I know very little about how to do WiX properly, but we had some issues with the redistributable runtime in TortoiseHg, and the file overwrite mode. The existing Mercurial installer shouldn't have the redistributable runtime issue (since it uses VS 2008), but does have the same overwrite mode. I'll leave them here in case they're worth considering.

https://foss.heptapod.net/mercurial/tortoisehg/thg/-/issues/5662
https://foss.heptapod.net/mercurial/tortoisehg/thg/-/issues/5630

baymax updated this revision to Diff 27754.May 7 2021, 11:30 AM

✅ refresh by Heptapod after a successful CI run (🐙 💚)

baymax updated this revision to Diff 27791.May 10 2021, 11:37 AM

✅ refresh by Heptapod after a successful CI run (🐙 💚)

mharbison72 accepted this revision.May 10 2021, 11:43 PM
This revision is now accepted and ready to land.May 10 2021, 11:43 PM
This revision was automatically updated to reflect the committed changes.