Build a self-contained Win32 Python wheel for Concordance#57
Build a self-contained Win32 Python wheel for Concordance#57Ben-Meister wants to merge 9 commits into
Conversation
|
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? |
a8ac713 to
0ed3274
Compare
|
Both changes have been made as requested. |
| run: | | ||
| pip install build | ||
| MINGW_SYSROOT_BIN="/usr/i686-w64-mingw32/sys-root/mingw/bin" concordance/win/make_wheel.py | ||
| - uses: actions/upload-artifact@v3 |
| Start-Sleep -Seconds 5 | ||
| cd "C:\Program Files (x86)\Concordance" | ||
| .\concordance.exe --version | ||
| - uses: actions/download-artifact@v3 |
|
Thank you both for reviewing this. Should I rebase the PR to the current changes? I’m glad that this project is still being kept up to date. FYI: I also have changes planned for submission as a subsequent PR, that build upon this PR to produce a version with curl supporting schannel, to fix the issue uncovered during testing on Windows wherein the required root certificates were not being downloaded. Scott @swt2c and I discussed this in my pull request to congruity congruity/congruity#12 (comment) and they are in my https://github.com/Ben-Meister/concordance/tree/buildcurl branch (from before the v4 artifact change so I’ll have to update those too). Let me know how to proceed. Unfortunately I was absent from this project for far too long; my apologies. I’ll need to untangle what I have in order to finish this up. |
| dll = line.split('=>')[1].strip() | ||
| if dll != 'not found': | ||
| shutil.copy2(dll, subdir) | ||
| shutil.copy2(os.path.dirname(os.path.abspath(__file__)) + '/../.libs/concordance.exe', subdir) |
There was a problem hiding this comment.
Why are you including concordance.exe in the wheel?
Also are the setup.py and pyproject.toml needed either?
There was a problem hiding this comment.
Scott I appreciate your feedback.
Re: the EXE. I’ll make the change to remove it, but I see pros and cons.
Reasons to not include the EXE: it’s not required, we can reduce our surface/size etc. And I did produce a wheel without it, as I was getting false positives from VirusTotal when I included it.
Reasons to include the EXE: it only adds 160KB. Then you have concordance available. A nice option if you’d like to isolate problems to congruity or concordance, or simply want an alternative. Otherwise you must download and install concordance separately.
Re: setup.py and pyproject.toml: These are not included in the produced wheel. They are used in the staging process, since the make_wheel.py script puts together a temporary tree for the build (based off what you did for make_installer.py, thank you!) and then calls python3 -m build -w from that location.
|
I'm wondering more generally if we should just start building wheels (maybe Windows-only for now) and actually publish them to PyPI? We'd have to build for all Pythons, but the contents would actually be the same for all, probably. I've got some recent experience in this area and can help, if this is too much scope creep for your original PR. :-) |
Actually, strike that. Can we simplify this approach quite a bit by doing the following: Then I think we don't need to the changes to setup.py and we don't need that custom wheel build script? |
|
Publishing a Concordance wheel has value, as it would make it much easier to install and use from Python. And Scott, I like your PyPI idea for the future. I understand certainly that you have a lot of projects that you are responsible for. Is this something you would like to maintain? Unfortunately I will have to contribute on an as-available basis at this time. My thought is that we can start with the minimum viable product that we have already been able to produce using this code right here: a Win32 wheel, published on GitHub. Then we can worry about other architectures, OS’s, and PyPI. The delvewheel tool is a cool find (thanks!) but won’t work for our use case without nasty kludges. The reason is that we load the libconcord DLL dynamically using |
…LL path search list
No, you are right, |
|
as a non-windows user, I have almost no opinion on this, but happy to merge it if we think it's worthwhile. @swt2c and @Ben-Meister ? |
|
I still think it's worthwhile. In lieu of PyPI, the wheel's the next best thing, and the work here would be considered a prereq for if we were to do PyPI. Makes usage a lot easier on Windows. And my all-in-one installer uses it too. I'll ask the obvious question. Currently Windows still has support for 32-bit applications, and Python still has 32-bit builds for Windows, so this is fine for now. At some point in the future we might wind up doing 64-bit Windows builds. Are there any known code paths we would have to specifically watch for issues? Or is it a matter of try it, thoroughly test, and see what breaks? |
|
Marking this one as draft for now since it's hardcoded Win32 |
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.ymlGitHub workflow via the addedmake_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 inci-linux.yml.The wheel and bindings are compatible with Python versions
both pre- andpost-3.8. In Python 3.8 (released in 2019), the DLL search path was narrowed, andos.add_dll_directorywas introduced (link). We usewith os.add_dll_directoryto 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 callos.add_dll_directorybefore 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 andos.add_dll_directoryis not available.The binding behavior, Python package format, and version compatibility are unchanged for Linux/Mac. On these platforms, the changes to
libconcord.pyare silently ignored.