packaging: add support for PyOxidizer
authorGregory Szorc <gregory.szorc@gmail.com>
Sun, 26 Jan 2020 16:23:57 -0800
changeset 44216 281b6690e646
parent 44215 b1069b369d6e
child 44217 064eb65d040f
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
contrib/packaging/pyoxidizer.bzl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/packaging/pyoxidizer.bzl	Sun Jan 26 16:23:57 2020 -0800
@@ -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/<arch>/<debug|release>/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()