1050

I'm building a Python application and don't want to force my clients to install Python and modules.

So, is there a way to compile a Python script to be a standalone executable?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeff
  • 14,365
  • 8
  • 30
  • 30
  • 494
    The part of the question that says "I don't want to force my clients to install Python and modules." It doesn't say the clients can't do it, it says the developer doesn't want to require them to do it. There's no point in debating the point here, because the clients are not reading SO to speak for themselves. I wouldn't want to install a Flash development environment just to watch youtube, or a C development environment just to play Sudoku, or a Python development environment to run a version of Angry Birds written in Python. That's what redistributable runtimes are for. – Dave Nov 11 '11 at 20:03
  • 1
    Would an answer including many files, but only one for running the application be acceptable? I'm thinking some sort of automation of packaging of the app + requirements with portable python distribution, and making an installation script to automate it. – Niko Föhr Nov 16 '20 at 19:22

19 Answers19

552

You can use PyInstaller to package Python programs as standalone executables. It works on Windows, Linux, and Mac.

PyInstaller Quickstart

Install PyInstaller from PyPI:

pip install pyinstaller

Go to your program’s directory and run:

pyinstaller yourprogram.py

This will generate the bundle in a subdirectory called dist.

pyinstaller -F yourprogram.py

Adding -F (or --onefile) parameter will pack everything into single "exe".

pyinstaller -F --paths=<your_path>\Lib\site-packages  yourprogram.py

running into "ImportError" you might consider side-packages.

 pip install pynput==1.6.8

still runing in Import-Erorr - try to downgrade pyinstaller - see Getting error when using pynput with pyinstaller

For a more detailed walkthrough, see the manual.

Ma Ha
  • 17
  • 4
Rumple Stiltskin
  • 9,597
  • 1
  • 20
  • 25
  • 21
    It's worth noting that pyinstaller can compile to a single .exe file. Also on which OS it is run, makes *that* executable, i.e. .exe when run on Windows – Richard de Wit Jun 06 '14 at 14:17
  • 2
    @ItayMoav-Malimovka They are working in the support of Python 3. See https://github.com/pyinstaller/pyinstaller/tree/python3. – PhoneixS Jan 13 '15 at 08:21
  • 18
    As @GeenHenk said, if you "compile" on Windows it make a exe, get in mind that you can't compile for Windows (make an exe) on Linux, or make a Linux executable on Windows. You can only make the executable of the platform you are running. (In Linux you can use wine to trick this) – PhoneixS Jan 13 '15 at 08:24
  • 40
    using 'pyinstaller' is way easier than 'py2exe'. It takes care of every dependencies including numpy, pandas, anything and gives you a single executable on the working platform! – aks Mar 09 '16 at 05:00
  • 20
    Seems like exactly what I was looking for. And now supports Python 3! Thanks :) – Daniel Gruszczyk Aug 30 '16 at 08:23
  • 7
    I tried them all, the PyInstaller and others (py2exe, freeze, cython, embedded version of python and etc) still can't handle dependency of the python dynamic library itself at least in the Windows (python*.dll). The dll has dependency on the runtime which HAS TO BE installed separately. After the process you gain the executable which will be linked to the dll and so has the same importability. So your 'standalone' executable is not much standalone, but more like embeddable. To workaround the runtime dependency you HAVE TO rebuild the python from the source using `cpython` project. – Andry Jul 13 '17 at 08:33
  • @ aks. I have a python script. It uses modules like pandas ,matplotlib ,time and tkFileDialog. It works fine within python platform . When I try to create exe using pyinstaller and run the application It shows error using pandas. I do not understand why this error. I am using python 2.7. – Poka Dec 05 '17 at 09:34
  • 1
    It does make an .exe file but when I try to run it I have the following errors: LoadLibrary: The specified module could not be found. – user3841581 Dec 22 '17 at 19:29
  • What is the code is made of many files ? Does this work ? – daveturner Jul 17 '20 at 01:22
  • Does one need to ship the entire 'dist' folder OR just shipping the .exe file be sufficient for the program to run successfully ? – StanGeo Dec 08 '20 at 00:21
  • 4
    This answer is incorrect: This is NOT a standalone exe, it still needs python and other things installed. – Markus Bawidamann Dec 22 '20 at 19:47
  • @Rumple Does it also work if we have lot of data in the folder which it to be read and process by .py file? – dan Jan 02 '21 at 09:47
  • PyInstaller executables are not portable across different Windows versions: "The output of PyInstaller is specific to the active operating system and the active version of Python." – Vic Apr 22 '21 at 11:22
  • throwing some OS error to me, like not readable output or what. (MacOS) – luky Aug 28 '21 at 13:29
  • unfortunately Everytime i use pyinstaller an error with missing python.dll appears – babak Dec 17 '21 at 15:37
298

You can use py2exe as already answered and use Cython to convert your key .py files in .pyc, C compiled files, like .dll in Windows and .so on Linux.

It is much harder to revert than common .pyo and .pyc files (and also gain in performance!).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
neurino
  • 11,500
  • 2
  • 40
  • 63
  • 1
    Thanks for answer. I've considered Cython, but it seems it still need Python to run compiled executable. Do you mean compiling script to .pyc using Cython? (I didn't know if Cython has such feature) – Jeff Mar 28 '11 at 12:18
  • 10
    I mean you have *two problems*: closed source and no-deps. For closed source compile your _important_ code in C libs using Cython. For no-deps use py2exe and make an executable with .pyd (cython compiled) files within. – neurino Mar 28 '11 at 12:24
  • 8
    What would you do about the libraries (numpy, scipy, matplotlib) ? For instance, how would clients be able to use the ginput() function in matplotlib from the executable, without having it installed on their computer. – chimpsarehungry Apr 10 '13 at 18:04
  • @chimpsarehungry what about static linking? – Braden Best Jan 28 '15 at 07:15
  • py2exe is Windows only, but people report success in running the resulting binaries on Linux under WINE, after tweaking the binaries to fix a small py2exe output bug. – Jonathan Hartley Mar 15 '15 at 01:32
  • 15
    Last release seem to be in 2008, is this still maintained ? – Zitrax Sep 17 '15 at 08:45
  • It only supports python ver upto 2.7 :-( – Philipp Munin Jun 01 '17 at 18:59
  • There's also a py2app for mac, but I've had issues getting it to work for the project I wanted it for. There's a port to python3.3 on pypi: https://pypi.python.org/pypi/py2exe/ And this fork that supports unicode paths: https://github.com/goatpig/py2exe This really is an area the python community is lacking in. – TheAtomicOption Nov 22 '17 at 17:25
  • I tracked down the line of code that cython created in C to increment a variable using c+=1: __pyx_t_5 = __Pyx_PyInt_AddObjC(__pyx_t_1, __pyx_int_1, 1, 1); So, no, Python doesn't intellegently see +=1 as ++. How inefficient. – PalaDolphin Feb 23 '18 at 06:01
  • On the py2exe page, yes, the last release info is from 2008! However, on py2exe Github page it is visible, that right now, Python 3.6 is supported. https://github.com/py2exe/py2exe/releases/ – Kozaka Sep 18 '22 at 18:11
116

You might wish to investigate Nuitka. It takes Python source code and converts it in to C++ API calls. Then it compiles into an executable binary (ELF on Linux). It has been around for a few years now and supports a wide range of Python versions.

You will probably also get a performance improvement if you use it. It is recommended.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
cdarke
  • 42,728
  • 8
  • 80
  • 84
  • 10
    Nuitka is an awesome tool. No need not to use it. I'd only point out one thing - it's not limited to Linux only - it's _cross-platform_ - another reason why to use it. – sjaustirni Nov 20 '14 at 16:09
  • 6
    Nuitka works on Python 2.6, 2.7, 3.2, 3.3, and 3.4, and is cross-platform:(Linux, FreeBSD, NetBSD, MacOS X, and Windows (32/64 bits). Others may work as well. Architectures: x86, x86_64 (amd64), and arm. Other architectures may also work, out of the box.) – Jonathan Hartley Mar 15 '15 at 01:33
  • It is not supported for most recent 3.6.. and is a nightmare to set up on windows – Tetora Oct 30 '17 at 07:04
  • Works like a charm on macOS High Sierra + Python 3.5.2. Thank you! – Anthony L. Dec 26 '17 at 05:59
  • 2
    Does this create a standalone executable? – voices Jan 29 '19 at 10:44
  • @tjt263: it can. See http://nuitka.net/doc/user-manual.html#use-case-1-program-compilation-with-all-modules-embedded – cdarke Jan 29 '19 at 14:34
  • @cdarke It seems to contradict itself: *"The resulting binary still depends on CPython and used C extension modules being installed. If you want to be able to copy it to another machine, use `--standalone` and copy the created `program.dist` directory and execute the `program.exe` (Windows) or `program` (other platforms) put inside."* – voices Jan 29 '19 at 14:50
  • 1
    Worked pretty much out-of-the-box for me on Windows and I did get a pretty good performance improvement. Making a standalone executable failed, however :( – jkrei0 Aug 04 '20 at 17:14
  • @cdarke thank u thank u thank u thank u, Nuitka made the trick for me after over a day of grieve getting my program built. Love & light from Iceland – somethingSomething Mar 13 '22 at 13:24
  • 1
    always gives an error and is broken beyond belief, would not recommend – Vaidøtas I. Jun 30 '22 at 11:18
45

Yes, it is possible to compile Python scripts into standalone executables.

PyInstaller can be used to convert Python programs into stand-alone executables, under Windows, Linux, Mac OS X, FreeBSD, Solaris, and AIX. It is one of the recommended converters.

py2exe converts Python scripts into only executable on the Windows platform.

Cython is a static compiler for both the Python programming language and the extended Cython programming language.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fury.slay
  • 1,202
  • 1
  • 15
  • 26
  • 2
    Thanks for this. I was using py2exe, and couldnt get the icons working with it at all. PyInstaller worked first time, and looks great! – Chud37 May 11 '17 at 07:24
  • Can I create standalone executable from Windows for Linux and macOS? Or I should install Linux and macOS on VirtualBox? I do not have enough free space on my laptop. – 8Observer8 Apr 07 '19 at 11:19
  • 1
    I found answer on my question in the documentation here: https://pyinstaller.readthedocs.io/en/stable/usage.html#supporting-multiple-platforms – 8Observer8 Apr 07 '19 at 11:26
34

I would like to compile some useful information about creating standalone files on Windows using Python 2.7.

I have used py2exe and it works, but I had some problems.

This last reason made me try PyInstaller http://www.pyinstaller.org/.

In my opinion, it is much better because:

  • It is easier to use.

I suggest creating a .bat file with the following lines for example (pyinstaller.exe must be in in the Windows path):

pyinstaller.exe --onefile MyCode.py

So, I think that, at least for python 2.7, a better and simpler option is PyInstaller.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Diego
  • 1,232
  • 17
  • 20
  • 5
    The `--onefile` flag won't help you to make it portable on the Windows, because the executable still wants to link with the `api-ms-win-crt-runtime-l1-1-0.dll` library (or/and others) which must be installed through the `vcredist` package. So a dependency is still there and must be installed before the run. – Andry Jul 13 '17 at 11:13
34

And a third option is cx_Freeze, which is cross-platform.

Paolo
  • 20,112
  • 21
  • 72
  • 113
Katriel
  • 120,462
  • 19
  • 136
  • 170
  • 2
    Here we are in Feb of 2019 and there are no listed `cx_Freeze` releases on pypi since end of 2017. Was this project abandoned? – user9074332 Feb 21 '19 at 05:39
  • 1
    Sorry I know I'm a bit late (2020) but no, cx_Freeze is not abandoned! The maintainer is still pushing updates, although at a much slower rate. – Armster Jun 19 '20 at 20:59
30
pyinstaller yourfile.py -F --onefile

This creates a standalone EXE file on Windows.

Important note 1: The EXE file will be generated in a folder named 'dist'.

Important note 2: Do not forget --onefile flag

You can install PyInstaller using pip install PyInstaller

Enter image description here

Enter image description here

NOTE: In rare cases there are hidden dependencies...so if you run the EXE file and get missing library error (win32timezone in the example below) then use something like this:

pyinstaller --hiddenimport win32timezone -F "Backup Program.py"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chadee Fouad
  • 2,630
  • 2
  • 23
  • 29
23

I like PyInstaller - especially the "windowed" variant:

pyinstaller --onefile --windowed myscript.py

It will create one single *.exe file in a distination/folder.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
cslotty
  • 1,696
  • 20
  • 28
  • did you already try this on target machine without python? how is this get upvoted? – greendino Jun 12 '20 at 20:31
  • What do you mean, @AbdullahSaid? Why would someone use pyinstaller on a machine without Python on it? – cslotty Jun 14 '20 at 08:27
  • I didn't say that. what I meant is, if the executable gonna run on a machine without python installed in it. or should I say "customer PC", I already try it on my VM's without python and it just won't work, why would you create an installer for yourself is for? you meant to write it so other PC could install it without any dependency right?. read the title above – greendino Jun 14 '20 at 18:22
  • 1
    @AbdullahSaid The target system doesn't need Python installed separately, it's packed in the resulting exe-file. Otherwise this wouldn't make much sense. On execution, the exe file will unpack itself into its own temp-folder and take everything from there! – cslotty Jun 15 '20 at 11:12
19

You may like py2exe. You'll also find information in there for doing it on Linux.

Niko Föhr
  • 28,336
  • 10
  • 93
  • 96
user237419
  • 8,829
  • 4
  • 31
  • 38
15

Use py2exe.... use the below set up files:

from distutils.core import setup
import py2exe

from distutils.filelist import findall
import matplotlib

setup(
    console = ['PlotMemInfo.py'],

    options = {
        'py2exe': {
            'packages': ['matplotlib'],
            'dll_excludes': ['libgdk-win32-2.0-0.dll',
                             'libgobject-2.0-0.dll',
            'libgdk_pixbuf-2.0-0.dll']
        }
    },
    data_files = matplotlib.get_py2exe_datafiles()
)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anand
  • 823
  • 1
  • 10
  • 19
  • I did this and it created a python27.dll file and it is still required. I moved the .exe file out of the folder holding the python27.dll file and the .exe file no longer runs. – mjwrazor Aug 16 '16 at 14:58
  • Could you show such script for Linux and macOS? I want to create standalone executable files from Windows for Linux and macOS. – 8Observer8 Apr 07 '19 at 11:22
14

I also recommend PyInstaller for better backward compatibility such as Python 2.3 - 2.7.

For py2exe, you have to have Python 2.6.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yantaq
  • 3,968
  • 2
  • 33
  • 34
  • pyinstaller has import problems. For example: in my case, I'm in this DIR ~/Documents/python101/ and ex50_pycomp.py & ex50.py are in this dir. ex50_pycomp.py importing ex50.py. I run pyinstaller ex50_pycomp.py and i see all complied, produced dist. All good right? I cd into dist/ex50_pycomp/ and run ex50_pycomp it works. Once I put this ex50_pycom into a virtualmachine, then this says import error and in another other linux box it says " -bash: ./ex_50_pycom: cannot execute binary file: Exec format error" – driven_spider Sep 18 '18 at 04:31
  • prob1:I was using python2.7 but pyinstaller was talking with python3 python3 setup.py build python3 setup.py install your python3 will get all pkg_resources prob 3:if using sys_path becomes a problem so give your path like this pyinstaller --hidden-import=pkg_resources --onefile file.py --path=my_path rw-rw-r-- my_path:python3's dist folder pyinstaller --hidden-import=pkg_resources --onefile file.py --path=/usr/local/lib/python3.5/dist-packages/my_code_lib-0+untagged.8.gd264bd5.dirty-py3.5.egg/my_folder -rw-rw-r-- – driven_spider Sep 29 '18 at 19:53
10

For Python 3.2 scripts, the only choice is cx_Freeze. Build it from sources; otherwise it won't work.

For Python 2.x I suggest PyInstaller as it can package a Python program in a single executable, unlike cx_Freeze which outputs also libraries.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ravi.chunduru
  • 196
  • 2
  • 6
8

Since it seems to be missing from the current list of answers, I think it is worth mentioning that the standard library includes a zipapp module that can be used for this purpose. Its basic usage is just compressing a bunch of Python files into a zip file with extension .pyz than can be directly executed as python myapp.pyz, but you can also make a self-contained package from a requirements.txt file:

$ python -m pip install -r requirements.txt --target myapp
$ python -m zipapp -p "interpreter" myapp

Where interpreter can be something like /usr/bin/env python (see Specifying the Interpreter).

Usually, the generated .pyz / .pyzw file should be executable, in Unix because it gets marked as such and in Windows because Python installation usually registers those extensions. However, it is relatively easy to make a Windows executable that should work as long as the user has python3.dll in the path.

If you don't want to require the end user to install Python, you can distribute the application along with the embeddable Python package.

jdehesa
  • 58,456
  • 7
  • 77
  • 121
  • This is a promissing option, but is there a starter repo or project to see it in action, also I couldn't overcome this point `The embedded distribution does not include the Microsoft C Runtime` – Abd-Elaziz Sharaf Jun 28 '22 at 22:21
7

py2exe will make the EXE file you want, but you need to have the same version of MSVCR90.dll on the machine you're going to use your new EXE file.

See Tutorial for more information.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Belial
  • 821
  • 1
  • 9
  • 12
7

You can find the list of distribution utilities listed at Distribution Utilities.

I use bbfreeze and it has been working very well (yet to have Python 3 support though).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Joe
  • 1,312
  • 20
  • 24
  • http://stackoverflow.com/questions/33683133/python-gui2exe-application-standalone-build-using-py2exe I use bbfreeze very nice package. – user914425 Dec 02 '15 at 19:59
  • Does it take care of dependencies and install relevant py modules? – Volatil3 May 09 '16 at 17:20
  • @Volatil3 Yes, all the dependencies are taken care of. WRT to installation of modules on the host system - there are different kinds of compilations. The bbfreeze will compile everything into multiple `.so` files, or copy the .egg files directly and they shall all be present in a single directory (or as a single file). There is no installation required. – Joe Jul 26 '16 at 08:16
6

Use Cython to convert to C, compile, and link with GCC.

Another could be, make the core functions in C (the ones you want to make hard to reverse), compile them and use Boost.Python to import the compiled code (plus you get a much faster code execution). Then use any tool mentioned to distribute.

F.Moure
  • 61
  • 1
  • 4
5

Not exactly a packaging of the Python code, but there is now also Grumpy from Google, which transpiles the code to Go.

It doesn't support the Python C API, so it may not work for all projects.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
freeformz
  • 847
  • 8
  • 12
5

Using PyInstaller, I found a better method using shortcut to the .exe rather than making --onefile. Anyway, there are probably some data files around and if you're running a site-based app then your program depends on HTML, JavaScript, and CSS files too. There isn't any point in moving all these files somewhere... Instead what if we move the working path up?

Make a shortcut to the EXE file, move it at top and set the target and start-in paths as specified, to have relative paths going to dist\folder:

Target: %windir%\system32\cmd.exe /c start dist\web_wrapper\web_wrapper.exe
Start in: "%windir%\system32\cmd.exe /c start dist\web_wrapper\"

We can rename the shortcut to anything, so renaming to "GTFS-Manager". Now when I double-click the shortcut, it's as if I python-ran the file! I found this approach better than the --onefile one as:

  1. In onefile's case, there's a problem with a .dll missing for the Windows 7 OS which needs some prior installation, etc. Yawn. With the usual build with multiple files, no such issues.
  2. All the files that my Python script uses (it's deploying a tornado web server and needs a whole freakin' website worth of files to be there!) don't need to be moved anywhere: I simply create the shortcut at top.
  3. I can actually use this exact same folder on Ubuntu (run python3 myfile.py) and Windows (double-click the shortcut).
  4. I don't need to bother with the overly complicated hacking of .spec file to include data files, etc.

Oh, remember to delete off the build folder after building. It will save on size.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nikhil VJ
  • 5,630
  • 7
  • 34
  • 55
  • Hi, just updating.. I decided to forgo UPX compression and go the --onefile way finally. Had to pick one, because UPX currently has a bug in compressing a particular DLL. – Nikhil VJ Jan 04 '19 at 23:05
1

I'm told that PyRun is also an option. It currently supports Linux, FreeBSD and Mac OS X.

Niko Föhr
  • 28,336
  • 10
  • 93
  • 96
  • 14
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](//stackoverflow.com/help/deleted-answers) – Petter Friberg Mar 28 '17 at 18:50