Saturday, September 3, 2011

Python 3.2: Create Executable with cx_Freeze 4.2.3

I have been searching online, looking for a way to convert my Python 3.2 scripts into executable. I guess Python 3 is still fairly new, many existing tools like py2exe do not support it :(

cx_Freeze is the only tool I found (as of today) that is compatible with Python 3. It works great. I did have to fix the path in cxfreeze.bat due to my custom installation directory of Python 3.2. But other than that it was really simple. Just copy & paste the command from the documentation:
cxfreeze hello.py --target-dir dist

It created an executable, along with some .dll and .pyd files. The total size is 4.17 MB. Not bad considering the client do not need to install Python.

My next goal was to figure out how to set an icon for my executable. I created a setup.py according to the documentation, along with the help from some online examples, I was able to add the icon within 5 minutes!

However, ever since I switched to use the setup.py method, it creates a library.zip instead of append all script files to the executable. I tried various command line options, searched online, still no luck. It was driving me crazy since I know it is possible!

I started digging into the source code of cx_Freeze. Thanks to this mail archive which gave me some ideas on what to look for, I was able to trace back in freezer.py:363, by default it set create_shared_zip to True. Okay. So how do I change it? After hours of research, I still cannot figure it out. I was tempted to change my local copy of cx_Freeze and hard code it to False.

Finally, by looking up another boolean option "compressed", I was able to find an example, right in the samples directory! Orz
cx_Freeze\samples\advanced\setup.py

The final version of my setup.py look like this:
from cx_Freeze import setup, Executable

executables = [
    Executable("main.py",
               icon="logo.ico",
               appendScriptToExe=True,
               appendScriptToLibrary=False,
               )
]

buildOptions = dict(create_shared_zip=False)

setup(name="hello",
      version="0.1",
      description="the typical 'Hello, world!' script",
      options=dict(build_exe=buildOptions),
      executables=executables,
      )

Hope it helps whoever want to disable the library.zip.

5 comments:

Rodrigo J. Fonseca said...

That helped a lot, thanks!

David Callanan said...

Thanks alot!

David Callanan said...

Thanks alot!

David Callanan said...

Thanks alot!

Bart said...

This is where I though cx_Freeze is for, just building an executable. Thanks a lot!