Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to compile a python application into static binary?

Tags:

python

build

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.

like image 287
roboslone Avatar asked Oct 07 '16 09:10

roboslone


People also ask

Can you compile Python to a binary?

To cross-compile, you must download the Python source code and cross-compile Python itself for the platform you are targeting - it is not possible from a binary installation of Python (as the . lib etc file for other platforms are not included.)

Can you compile a Python program?

Python, as a dynamic language, cannot be "compiled" into machine code statically, like C or COBOL can. You'll always need an interpreter to execute the code, which, by definition in the language, is a dynamic operation.


1 Answers

There are two ways you could go about to solve your problem

  1. Use a static builder, like freeze, or pyinstaller, or py2exe
  2. Compile using cython

I will explain how you can go about doing it using the second, 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, where as using cython will result in a file that's KBs in size

First, install cython. Then, rename your python file (say test.py) into a .pyx file

sudo pip install cython mv test.py test.pyx 

Then, you can use cython along with GCC to compile it (cython generates a C file out of a Python .pyx file, and then GCC compiles the C file)

(in reference to https://stackoverflow.com/a/22040484/5714445)

cython test.pyx --embed gcc -Os -I /usr/include/python3.5m -o test test.c -lpython3.5m -lpthread -lm -lutil -ldl 

NOTE: Depending on your version of python, you might have to change the last command. To know which version of python you are using, simply use

$ python -V 

You will now have a binary file 'test', which is what you are looking for

Other things to note:

  1. Cython is used to use C-Type Variable definitions for static memory allocation to speed up Python programs. In your case however, you will still be using traditional Python definitions.
  2. If you are using additional libraries (like 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
like image 72
R. S. Nikhil Krishna Avatar answered Sep 29 '22 09:09

R. S. Nikhil Krishna