What I'm trying to do is ship my code to a remote server, that may have different python version installed and/or may not have packages my app requires.
Right now to achieve such portability I have to build relocatable virtualenv with interpreter and code. That approach has some issues (for example, you have to manually copy a bunch of libraries into your virtualenv, since --always-copy
doesn't work as expected) and generally slow.
There's (in theory) a way to build python itself statically.
I wonder if I could pack interpreter with my code into one binary and run my application as module. Something like that: ./mypython -m myapp run
or ./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application
.
There are two ways you could go about to solve your problem
pyinstaller
, or py2exe
cython
and link against a statically-compiled version of CPythonThis answer explains how you can go about doing it using the second approach, since the first method is not cross platform and version, and has been explained in other answers. Also, using programs like pyinstaller typically results in huge file sizes, while using cython will result in a file that's much smaller
First, install cython
.
sudo -H pip3 install cython
Then, you can use cython
to generate a C file out of the Python .py
file
(in reference to https://stackoverflow.com/a/22040484/5714445)
cython example_file.py --embed
Use GCC to compile it after getting your statically-compiled python version (Note: The below assumes you are trying to compile it to Python3)
gcc -Os $(python3-config --includes) example_file.c -o output_bin_file $(python3-config --ldflags --embed)
You will now have a binary file output_bin_file
, which is what you are looking for
Other things to note:
example_file.py
to whatever file you are actually trying to compile.opencv
, for example), you might have to provide the directory to them using -L
and then specify the name of the library using -l
in the GCC Flags. For more information on this, please refer to GCC flags