jaymzh / concordance

Program Harmony remote controls from Linux, Windows, or Mac!
GNU General Public License v3.0
146 stars 19 forks source link

Build a self-contained Win32 Python wheel for Concordance #57

Open Ben-Meister opened 5 months ago

Ben-Meister commented 5 months ago

This pull request builds a 32-bit Win32 Python wheel for libconcord, the bindings and all of its dependencies. This wheel simplifies the installation (and removal) process on Windows. It also fixes the DLL load path issue, including the changes to DLL load path made in Python 3.8+.

The wheel may be used individually, or as part of an installation process. In the companion pull request to Congruity, we consume this wheel to make an all-in-one installer for Congruity. It installs a self-contained 32-bit version of Python, Congruity, this wheel, and all other package and binary dependencies required.

Because the compiled DLLs are 32-bit, a 32-bit Python version is required to use them. However, the 32-bit Python (and our installer) will happily run on a 64-bit Windows system. The wheel is compatible with and tested on Windows 11, 10, and 8.1, both the 32- and 64-bit versions.

The wheel is built as part of the ci-windows.yml GitHub workflow via the added make_wheel.py, which dynamically assembles the package using the same files that are built for the NSIS installer. A test has been added for the wheel to this workflow as well, based on the similar test present in ci-linux.yml.

The wheel and bindings are compatible with Python versions both pre- and post-3.8. In Python 3.8 (released in 2019), the DLL search path was narrowed, and os.add_dll_directory was introduced (link). We use with os.add_dll_directory to add the package directory to Python’s DLL search path when loading the libconcord DLLs (after which it’s immediately removed). If an app wants the DLLs in a different directory, the app can call os.add_dll_directory before importing the libconcord bindings. Fallback logic has been added to perform a similar method using PATH (temporary for the calling process only) when the bindings are used on Python 3.7 or earlier and os.add_dll_directory is not available.

The binding behavior, Python package format, and version compatibility are unchanged for Linux/Mac. On these platforms, the changes to libconcord.py are silently ignored.

swt2c commented 5 months ago

Thank you for your contribution. My initial quick thoughts: First of all, my opinion is that we don't need to support Python 3.7 as it has been EOL for a year or so, so you could probably drop that commit.

Second - why do we need separate pyproject.toml and setup.py files for Windows?

Ben-Meister commented 4 months ago

Both changes have been made as requested.