💾 Archived View for makeworld.space › gemlog › 2021-10-04-linux-wine-pyinstaller.gmi captured on 2022-07-16 at 13:43:33. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
Packaging a Python project into a standalone executable is often a struggle. Thankfully we have tools like PyInstaller[1] to make this easier. Recently I ran into another struggle of my own, which was that it seemed impossible to "cross-compile" with PyInstaller. That is to say, run PyInstaller on one OS, and have it generate an executable for another. It was hinted at that Linux → Windows was possible using Wine, but I couldn't find any guides on it.
Eventually, I got it working, so here is that guide. Hope this helps! This guide *might* also work on macOS, but I have not tested it.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
First off, I was only able to use Python 3.8. I tried with 3.9, but I was not able to install it under WINE. If you are able to, feel free to use that, and change references to `38` in this post to `39`. I was also using PyInstaller 4.5.1, but other versions should work fine.
The first step is to install WINE for your Linux system. WINE is a compatibility layer that allows the running of Windows software on non-Windows systems. You can install WINE easily enough from your distro's package manager. I am using `wine-6.16`, but most likely your distro's version will work fine.
Next, download the Python 3.8 Windows installer. You can download that directly from the official Python Software Foundation here[3]. With it downloaded, you can run `wine python-3.8.9.exe` to begin the installation. WINE may prompt you to install something like .NET or Mono, you should click Yes and let it install.
You should not use the default installation, follow these steps:
1. Check "Add Python 3.8 to PATH"
2. Click "Customize installation
3. Click "Next"
4. Click "Install for all users"
5. Set the install location as `C:\\Python38`
6. Click "Install"
7. Close the window.
Using the `C:\\Python38` path helps keep things standard for this blog post.
Now Python 3.8 should be successfully installed in WINE. You can check this by running `wine C:/Python38/python.exe --version`, which will run Windows Python through WINE. Amazing!
Next we'll need to upgrade pip, to make sure things will install fine. Run `wine C:/Python38/python.exe -m pip install --upgrade pip`. WINE might spit out a lot of warnings about `libgnutls` or something or other, but as long as Pip doesn't report any errors it's fine.
Now if your project has any dependencies, you should export them into the standard Python `requirements.txt` file. You can then install them into your WINE Python with this command:
wine C:/Python38/python.exe -m pip install -r requirements.txt
If you're using a superior dependency manager like Poetry[4], you should be able to install and use that in WINE, although I haven't tested that.
In any case, you'll need PyInstaller to be installed, so run this command if PyInstaller wasn't in `requirements.txt` already:
wine C:/Python38/python.exe -m pip install pyinstaller
Now you can run PyInstaller and an EXE will be built! Just run
wine C:/Python38/Scripts/pyinstaller.exe ...
and replace `...` with whatever arguments you used to build a Linux executable.
Enjoy!
1: https://www.pyinstaller.org/
2: https://github.com/noahbroyles/pyinstaller-wine/blob/master/main.py