cpython/Tools/freeze/win32.html

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>win32</TITLE>
<META NAME="Version" CONTENT="8.0.3410">
<META NAME="Date" CONTENT="10/11/96">
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\HTML.DOT">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#ffffff">

<H1>Freeze for Win32</H1>
<P>This document describes how to use Freeze for the Win32 platform.  </P>
<P>Freeze itself is a Python tool for creating stand-alone executables from Python source code.  This document does not attempt to document freeze itself - only the win32 specific changes.</P>
<H2>Frozen programs under Win32</H2>
<P>Frozen programs under Win32 can (theoretically) freeze any type of program supported by Python on Win32 - At the moment, Console .EXE and NT Service .EXE programs are supported.  GUI Python programs and COM .EXE programs are very nearly all ready to go.</P>
<H3>Program Dependencies</H3>
<P>The person freezing the program has control over what external DLLs are required by a frozen program.  The following dependencies are supported:</P>
<H4>Minimal frozen programs</H4>
<P>These programs freeze only .py files in your program.  All external DLLs are required at run-time.  This includes all .pyd/.dll modules used by your program, Python20.dll, and msvcrt.dll.  </P>
<P>A small Python program would typically create a .EXE around 300kb.</P>
<H4>Frozen Extension programs</H4>
<B><I><P>Note:</B></I> For Python1.5.1, you must get a patch from Guido to import.c for this to work.</P>
<P>These programs also freeze in the sources from all .pyd and .dll files used at runtime.  This means the resulting .EXE is only dependent on Python20.dll and msvcrt.dll.</P>
<P>A small Python program using win32api, win32con and one or 2 other win32 extensions would typically create a .EXE around 400kb.</P>
<H4>Completely frozen programs</H4>
<P>Completely stand-alone programs, as is the default on Unix systems.  These are currently not supported, mainly as the size of a decent Python program gets very large.  However, by tweaking the existing Unix support, this would not be difficult to do.</P>
<H2>Freezing Extension Modules</H2>
<P>By default, a file in the main "freeze" directory called "extensions_win32.ini" is used to obtain information about frozen extensions.  A typical entry is:</P>
<CODE><P>[win32api]</P>
<P>dsp=%PYTHONEX%\win32\win32api.dsp</P>
<P>cl=/I %PYTHONEX%\win32\src</P>
<P>libs=kernel32.lib user32.lib shell32.lib advapi32.lib</P>
</CODE><P>&nbsp;</P>
<P>This entry indicates that the win32api extension module is defined in the MSVC project file "<CODE>%PYTHONEX%\win32\win32api.dsp</CODE>".  Note the use of<CODE> </CODE>"<CODE>%PYTHONEX%" </CODE>- most strings are substituted with environment variables. In this case, it is assumed variable PYTHONEX points to the main "Python Extensions" source directory (which is assumed to be in the same structure as the release of the extension sources).</P>
<P>An entry in a .INI file can also control specific compiler options, and also the .lib files necessary to be linked with the application.</P>
<H3>Freezing Extension Module Considerations</H3>
<P>To prevent freezing extension modules, simply exclude that module using the freeze "-x" switch.</P>
<P>Occasionally, it will be necessary to explicitly include dependent modules.  For example, many win32 modules are dependent on the "pywintypes" module - for example, the win32api module.  In this case, the module may be explicitly included using the freeze "-m" option.</P>
<H3>Freezing win32com and PythonCOM</H3>
<P>PythonCOM.dll can be frozen as long as you are not implementing COM Servers.  Ie, you can freeze programs which control other applications, but can not implement programs that are themselves controlled by other applications.</P>
<P>If you use any of the win32com .pyd extensions (ex, axscript, mapi, internet, axcontrol), then you will need to specify an additional "-a" option to point to the win32comext directory.  There is an example below.</P>
<P>The use of the "win32com.client.gencache" module is not supported (although could be quite easily??)</P>
<H2>Examples</H2>
<P>Before we start, we must:</P>
<CODE><P>D:\temp\delme&gt;set PYTHONEX=d:\src\pythonex</P>
</CODE><H3>Helloworld.py</H3>
<H4>Source Code</H4><DIR>
<DIR>

<CODE><P>import sys</P>
<P>&nbsp;</P>
<P>print " ".join( ["Hello", "world"] + sys.argv[1:] )</P></DIR>
</DIR>

</CODE><H4>Command Line used</H4><DIR>
<DIR>

<FONT FACE="Courier New" SIZE=2><P>\src\python-1.5.1\tools\freeze\freeze.py helloworld.py</P>
<P>nmake</P></DIR>
</DIR>

</FONT><P>Resulting helloworld.exe: 114,688 bytes.</P>
<H3>Helloworld2.py</H3>
<P>Uses win32api.  Demonstrates requirement for pywintypes, and difference between freezing extensions and not.</P>
<H4>Source Code</H4><DIR>
<DIR>

<P>import win32api</P>
<P>print "Hello from", win32api.GetComputerName()</P></DIR>
</DIR>

<H4>Command Line used</H4>
<P>By default, win32api will be frozen in with the .EXE.  If you do not provide the "pywintypes" inclusion, then the link step will fail looking for all the pywintypes modules.</P><DIR>
<DIR>

<FONT FACE="Courier New" SIZE=2><P>\src\python-1.5.1\tools\freeze\freeze.py helloworld2.py -m pywintypes</P>
<P>nmake</P></DIR>
</DIR>

</FONT><P>Resulting helloworld2.exe: 167,936 bytes</P>
<P>Simply adding win32con to the mix gives an EXE of size: 352,768 bytes.</P>
<H4>Command Line used</H4>
<P>Using this build, we are dependent at runtime on the win32api.pyd and pywintypes15.dll files.</P><DIR>
<DIR>

<P>\src\python-1.5.1\tools\freeze\freeze.py -x win32api helloworld.py</P></DIR>
</DIR>

<P>Resulting helloworld2.exe: 114,688</P>
<P>Adding win32con to this build results in a size of: 252,928</P>
<H3>Testmapi.py</H3>
<P>Uses MAPI, a PythonCOM extension, and win32api.</P>
<H4>Source Code</H4>
<P>from win32com.mapi import mapi</P>
<P>import win32api</P>
<P>mapi.MAPIInitialize( (mapi.MAPI_INIT_VERSION, 0) )</P>
<P>print "Hello from", win32api.GetComputerName()</P>
<P>mapi.MAPIUninitialize()</P>
<H4>Command Line used</H4>
<P>As it does not import pythoncom or pywintypes itself, they must be specified.  As it uses the win32comext directory, -a must be used.  If you have built the win32com extensions from sources, then the second -a is required.</P><DIR>
<DIR>

<CODE><P>\src\python-1.5.1\tools\freeze\freeze.py -a win32com=%PYTHONEX%\com\win32comext -a win32com.mapi=%PYTHONEX%\com\build\release testmapi.py -m pywintypes -m pythoncom</P></DIR>
</DIR>

</CODE><P>Resulting testmapi.exe: 352,768 bytes</P>
<H3>PipeTestService.py</H3>
<P>This is a standard Python demo in the Win32 extensions.  It can be found in the "win32\demos\service" directory.</P>
<H4>Command Line used</H4>
<P>This will create a native NT Service EXE, dependent only on the main Python20.dll.  All other modules are built-in to the final .EXE</P><DIR>
<DIR>

<CODE><P>\src\python-1.5.1\tools\freeze\freeze.py -s service %PYTHONEX%\win32\demos\service\pipeTestService.py</P></DIR>
</DIR>

<P>Resulting pipeTestService.exe: </CODE><FONT FACE="Courier New" SIZE=2>533,504 bytes.</P></FONT></BODY>
</HTML>