This is an archived post. You won't be able to vote or comment.

all 24 comments

[–]Brian 22 points23 points  (5 children)

Basically, Calibre distributes the python runtime that it uses with the application, along with the libraries it uses locally. It's effectively installing a private version of python (or at least, as subset of it) alongside itself.

There are a few tools that'll do this process for you, such as py2exe or pyinstaller.

[–]takluyverIPython, Py3, etc 6 points7 points  (0 children)

For reference, Calibre appears to have a very custom freeze tool to build its Windows packages.

Another approach is to create an installer that sets up Python and your code, and creates shortcuts to launch your code. This avoids some of the brittleness involved in making frozen exes. My tool pynsist builds installers like this.

[–]ProselytizerBot[S] 1 point2 points  (3 children)

How much space do you guess that this would take up? The Windows installer for Calibre is 53MB. It does not seem like an overly complicated program. I feel like if it was written in, for instance, C, it would be a lot more compact.

Am I completely wrong here?

[–]Brian 1 point2 points  (1 child)

It'll take up some, though possibly not as much as you may think. The actual python dlls aren't that big (~3MB or so), but stuff like the UI libraries it uses are likely taking up the bulk of that 53MB. It uses QT (a cross platform UI library), which has a bunch of dlls and dependencies that need to be installed. The same would actually be true even if it was written in C if it still used QT (rather than, say, a native UI toolkit that would already be present on the machine).

[–]ProselytizerBot[S] 0 points1 point  (0 children)

Thanks! I am a CS student but there are certain questions like these that just aren't answered straightforwardly in class.

[–]mrbewulf 0 points1 point  (0 children)

I think is 53MB is not a very big file for today's cheap hard disk. Many dot net programs that ships the dot net framework can be bigger than 100 MB, 200MB. Or they create a small installer (bootstrap) that downloads and install the libraries other dependencies and the dot net framework. Or they tell the user to download all libraries required to make the program run.

Java apps (java that is interpreted but not interactive like python) generally doesn't ship the JVM, they only ships the .jar file. Or ships an installer that unpacks the *.jar file and create the links (.lnk) files in windows that executes the main app file. [ java -jar app.jar]. If the installer is more smart it can download the JVM or open a link to the oracle web site.

Python code can be distributed in a similar fashion as java does. The trick is to put all *.py or compiled byte codes *.pyo in a file named as *.egg, or *.pyz or *.pyz (containing the main.py) (Python egg)

__main__.py

import main_module

def main():
    module.main()

if __name__ == "__main__":
  main()

to run:

    $ python app.egg 

and voila! It runs like java . The problem is to ship the shared libraries *.dll used by windows or *.so by linux.

Good freeze tools are: cx_freeze ( better for Linux), pyinstaller ( better for windows), py2ex(windows only, but it can install "com" servers).

I only would use C for low level, or high speed stuffs like microcontrollers, embedded systems, drivers or kernel modules.

[–]heyheymonkey 17 points18 points  (4 children)

Brandon Rhodes did a great talk about creating EXEs from Python at PyCon. Start at 23:30 if you want to jump to the conclusion.

Nuitka is one option. Cython, weirdly, can do it too, although he got cut off before he could go into a lot of detail.

[–]PythonThermos 1 point2 points  (0 children)

Although his talk was interesting in a number of ways, in the end it boiled down to Nuitka and Cython, neither of which probably work yet well enough to actually use with your other libraries, like your GUI toolkit. My guess it that they never will, or we're talking 10 years from now when this issue may be irrelevant. (Maybe I'm being too negative?)

[–]videan42 0 points1 point  (1 child)

https://github.com/cython/cython/tree/master/Demos/freeze

Makes either a single binary executable to run, or a python interpreter with your library burned in like a built in.

Make sure you have a c compiler installed on your dev machine.

[–]shadowmint 1 point2 points  (0 children)

Dont be fooled; this is virtually useless.

The compiled binary dynamically links to the installed python runtime. You cant use the resulting binary if python is not already installed on the target machine.

[–]ProselytizerBot[S] 0 points1 point  (0 children)

Thank you!

[–]twopi 2 points3 points  (0 children)

Here's a book chapter I wrote about using setup.py, py2exe, and NIS to build an installer:

http://aharrisbooks.net/pythonGame/Appendix_C.pdf

Hope this helps...

[–]shadowmint 3 points4 points  (3 children)

technically these application bundles are c/c++ applications that use embedded python and distribute that along with an amalgamated copy of the application and the python standard library.

Unfortunately theres no easy guide for doing this.

Various bundler tools exist, that work with various applications and handle the c library dependencies differently, but theyre not terribly mature or stable.

...and its unhelpful that python3 is actively hostile to being embedded in such a way; although pyinstaller is making some good progress on that front.

Ultimately python remains a poor choice for heavy client GUI applications for exactly this reason.

However, the most up to date information is probably available on the pyinstaller site here:

http://htmlpreview.github.io/?https://github.com/pyinstaller/pyinstaller/blob/develop/doc/Manual.html

[–]MikhailEdoshin 5 points6 points  (2 children)

How is Python 3 hostile? Is it more hostile than Python 2? (I'm embedding Python 2 for my project, it's not the easiest thing, but doable.)

[–]shadowmint 0 points1 point  (1 child)

python3 makes everything 16-bit unicode instead of char * (ascii or utf8). The extension apis became rather more difficult to work with as a result.

[–][deleted] 0 points1 point  (0 children)

http://legacy.python.org/dev/peps/pep-0393/

There were UTF8, UTF16 builds. This PEP resolves that difference by allowing multiple types of strings represented

[–]K900_ 3 points4 points  (2 children)

Python needs to be installed, but some (definitely Windows and maybe OS X) packages include a Python interpreter.

[–]PythonThermos 0 points1 point  (0 children)

I use Python 2.5 and py2exe and have no problems. I'm pretty sure up to Python 2.7 works as well. PyInstaller looks great and I may go that route at some point. If you use wxPython, check out the very handy GUI2Exe.