# HG changeset patch # User Gregory Szorc # Date 2020-01-27 00:23:57 # Node ID 281b6690e6465bf61837c52af8d079f876c2dcd4 # Parent b1069b369d6e9d75d924901b8500d3014cd20f8b packaging: add support for PyOxidizer I've successfully built Mercurial on the development tip of PyOxidizer on Linux and Windows. It mostly "just works" on Linux. Windows is a bit more finicky. In-memory resource files are probably not all working correctly due to bugs in PyOxidizer's naming of modules. PyOxidizer now now supports installing files next to the produced binary. (We do this for templates in the added file.) So a workaround should be available. Also, since the last time I submitted support for PyOxidizer, PyOxidizer gained the ability to auto-generate Rust projects to build executables. So we don't need to worry about vendoring any Rust code to initially support PyOxidizer. However, at some point we will likely want to write our own command line driver that embeds a Python interpreter via PyOxidizer so we can run Rust code outside the confines of a Python interpreter. But that will be a follow-up. I would also like to add packaging.py CLI commands to build PyOxidizer distributions. This can come later, if ever. PyOxidizer's new "targets" feature makes it really easy to define packaging tasks in its Starlark configuration file. While not much is implemented yet, eventually we should be able to produce MSIs, etc using a `pyoxidizer build` one-liner. We'll get there... Differential Revision: https://phab.mercurial-scm.org/D7450 diff --git a/contrib/packaging/pyoxidizer.bzl b/contrib/packaging/pyoxidizer.bzl new file mode 100644 --- /dev/null +++ b/contrib/packaging/pyoxidizer.bzl @@ -0,0 +1,57 @@ +# Instructions: +# +# 1. cargo install --version 0.5.0 pyoxidizer +# 2. cd /path/to/hg +# 3. pyoxidizer build --path contrib/packaging [--release] +# 4. Run build/pyoxidizer///app/hg +# +# If you need to build again, you need to remove the build/lib.* and +# build/temp.* directories, otherwise PyOxidizer fails to pick up C +# extensions. This is a bug in PyOxidizer. + +ROOT = CWD + "/../.." + +set_build_path(ROOT + "/build/pyoxidizer") + +def make_exe(): + dist = default_python_distribution() + + code = "import hgdemandimport; hgdemandimport.enable(); from mercurial import dispatch; dispatch.run()" + + config = PythonInterpreterConfig( + raw_allocator = "system", + run_eval = code, + # We need this to make resourceutil happy, since it looks for sys.frozen. + sys_frozen = True, + ) + + exe = dist.to_python_executable( + name = "hg", + config = config, + ) + + # Use setup.py install to build Mercurial and collect Python resources to + # embed in the executable. + resources = dist.setup_py_install(ROOT) + exe.add_python_resources(resources) + + return exe + +def make_install(exe): + m = FileManifest() + + # `hg` goes in root directory. + m.add_python_resource(".", exe) + + templates = glob( + include=[ROOT + "/mercurial/templates/**/*"], + strip_prefix = ROOT + "/mercurial/", + ) + m.add_manifest(templates) + + return m + +register_target("exe", make_exe) +register_target("app", make_install, depends = ["exe"], default = True) + +resolve_targets()