TL;DR: how to use Cython as a distribution method instead of Py2exe, cx_freeze, pyinstaller, etc.
Following Making an executable in Cython, I'd like to see how it could be possible to distribute a Python program to any Windows user (who doesn't have Python already installed on his machine) by compiling it first with Cython --embed
.
Let's use a test.py
:
import json
print(json.dumps({'key': 'hello world'}))
and compile it:
cython test.py --embed
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
cl test.c /I C:\Python37\include /link C:\Python37\libs\python37.lib
It works and produces a 140KB test.exe
executable.
Running test.exe
on another machine doesn't work out-of-the-box, it requires:
Even with this, it still does not work (screenshot below instead of copy/paste because I didn't manage the copy/paste in the VM - off topic here):
ModuleNotFoundError: No module named 'encodings'
Question: what is the minimal set of files required to distribute an --embed
-Cython-compiled code and make it work on any machine (without Python previously installed on it)?
After further research (I tried in an empty Win 7 x64 bit VM, without any VCredist previously installed), it seems that these files are enough:
the program itself, test.exe
(produced by cython --embed
and compilation with cl.exe
)
python37.dll
python37.zip
coming from packages named "Windows x86-64 embeddable zip file" in https://www.python.org/downloads/windows/
vcruntime140.dll
, as mentioned in Can I bundle the Visual Studio 2015 C++ Redistributable DLL's with my application? or ask the user to install vc_redist.x64.exe before
ucrtbase.dll
more than 30 files api-ms-win-*.dll
were required too; if not you will have the following error:
... api-ms-win-crt-runtime-l1-1-0.dll is missing ...
Notes:
if you require another library, like pygame
, just copy/paste the folder from C:\Python37\Lib\site-packages\pygame
seems to work
for me, concrt140.dll, msvcp140.dll, vccorlib140.dll did not seem necessary
Useful to test all this: Prevent a Python-embedded to look in my default path C:\Python38 for modules.