17db96d56Sopenharmony_ciTHE FREEZE SCRIPT
27db96d56Sopenharmony_ci=================
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci(Directions for Windows are at the end of this file.)
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ciWhat is Freeze?
87db96d56Sopenharmony_ci---------------
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciFreeze make it possible to ship arbitrary Python programs to people
117db96d56Sopenharmony_ciwho don't have Python.  The shipped file (called a "frozen" version of
127db96d56Sopenharmony_ciyour Python program) is an executable, so this only works if your
137db96d56Sopenharmony_ciplatform is compatible with that on the receiving end (this is usually
147db96d56Sopenharmony_cia matter of having the same major operating system revision and CPU
157db96d56Sopenharmony_citype).
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ciThe shipped file contains a Python interpreter and large portions of
187db96d56Sopenharmony_cithe Python run-time.  Some measures have been taken to avoid linking
197db96d56Sopenharmony_ciunneeded modules, but the resulting binary is usually not small.
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ciThe Python source code of your program (and of the library modules
227db96d56Sopenharmony_ciwritten in Python that it uses) is not included in the binary --
237db96d56Sopenharmony_ciinstead, the compiled byte-code (the instruction stream used
247db96d56Sopenharmony_ciinternally by the interpreter) is incorporated.  This gives some
257db96d56Sopenharmony_ciprotection of your Python source code, though not much -- a
267db96d56Sopenharmony_cidisassembler for Python byte-code is available in the standard Python
277db96d56Sopenharmony_cilibrary.  At least someone running "strings" on your binary won't see
287db96d56Sopenharmony_cithe source.
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ciHow does Freeze know which modules to include?
327db96d56Sopenharmony_ci----------------------------------------------
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ciPrevious versions of Freeze used a pretty simple-minded algorithm to
357db96d56Sopenharmony_cifind the modules that your program uses, essentially searching for
367db96d56Sopenharmony_cilines starting with the word "import".  It was pretty easy to trick it
377db96d56Sopenharmony_ciinto making mistakes, either missing valid import statements, or
387db96d56Sopenharmony_cimistaking string literals (e.g. doc strings) for import statements.
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ciThis has been remedied: Freeze now uses the regular Python parser to
417db96d56Sopenharmony_ciparse the program (and all its modules) and scans the generated byte
427db96d56Sopenharmony_cicode for IMPORT instructions.  It may still be confused -- it will not
437db96d56Sopenharmony_ciknow about calls to the __import__ built-in function, or about import
447db96d56Sopenharmony_cistatements constructed on the fly and executed using the 'exec'
457db96d56Sopenharmony_cistatement, and it will consider import statements even when they are
467db96d56Sopenharmony_ciunreachable (e.g. "if 0: import foobar").
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ciThis new version of Freeze also knows about Python's new package
497db96d56Sopenharmony_ciimport mechanism, and uses exactly the same rules to find imported
507db96d56Sopenharmony_cimodules and packages.  One exception: if you write 'from package
517db96d56Sopenharmony_ciimport *', Python will look into the __all__ variable of the package
527db96d56Sopenharmony_cito determine which modules are to be imported, while Freeze will do a
537db96d56Sopenharmony_cidirectory listing.
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ciOne tricky issue: Freeze assumes that the Python interpreter and
567db96d56Sopenharmony_cienvironment you're using to run Freeze is the same one that would be
577db96d56Sopenharmony_ciused to run your program, which should also be the same whose sources
587db96d56Sopenharmony_ciand installed files you will learn about in the next section.  In
597db96d56Sopenharmony_ciparticular, your PYTHONPATH setting should be the same as for running
607db96d56Sopenharmony_ciyour program locally.  (Tip: if the program doesn't run when you type
617db96d56Sopenharmony_ci"python hello.py" there's little chance of getting the frozen version
627db96d56Sopenharmony_cito run.)
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ciHow do I use Freeze?
667db96d56Sopenharmony_ci--------------------
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ciNormally, you should be able to use it as follows:
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci	python freeze.py hello.py
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ciwhere hello.py is your program and freeze.py is the main file of
737db96d56Sopenharmony_ciFreeze (in actuality, you'll probably specify an absolute pathname
747db96d56Sopenharmony_cisuch as /usr/joe/python/Tools/freeze/freeze.py).
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ciWhat do I do next?
787db96d56Sopenharmony_ci------------------
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ciFreeze creates a number of files: frozen.c, config.c and Makefile,
817db96d56Sopenharmony_ciplus one file for each Python module that gets included named
827db96d56Sopenharmony_ciM_<module>.c.  To produce the frozen version of your program, you can
837db96d56Sopenharmony_cisimply type "make".  This should produce a binary file.  If the
847db96d56Sopenharmony_cifilename argument to Freeze was "hello.py", the binary will be called
857db96d56Sopenharmony_ci"hello".
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ciNote: you can use the -o option to freeze to specify an alternative
887db96d56Sopenharmony_cidirectory where these files are created. This makes it easier to
897db96d56Sopenharmony_ciclean up after you've shipped the frozen binary.  You should invoke
907db96d56Sopenharmony_ci"make" in the given directory.
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ciFreezing Tkinter programs
947db96d56Sopenharmony_ci-------------------------
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ciUnfortunately, it is currently not possible to freeze programs that
977db96d56Sopenharmony_ciuse Tkinter without a Tcl/Tk installation. The best way to ship a
987db96d56Sopenharmony_cifrozen Tkinter program is to decide in advance where you are going
997db96d56Sopenharmony_cito place the Tcl and Tk library files in the distributed setup, and
1007db96d56Sopenharmony_cithen declare these directories in your frozen Python program using
1017db96d56Sopenharmony_cithe TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables.
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ciFor example, assume you will ship your frozen program in the directory
1047db96d56Sopenharmony_ci<root>/bin/windows-x86 and will place your Tcl library files
1057db96d56Sopenharmony_ciin <root>/lib/tcl8.2 and your Tk library files in <root>/lib/tk8.2. Then
1067db96d56Sopenharmony_ciplacing the following lines in your frozen Python script before importing
1077db96d56Sopenharmony_ciTkinter or Tix would set the environment correctly for Tcl/Tk/Tix:
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ciimport os
1107db96d56Sopenharmony_ciimport os.path
1117db96d56Sopenharmony_ciRootDir = os.path.dirname(os.path.dirname(os.getcwd()))
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ciimport sys
1147db96d56Sopenharmony_ciif sys.platform == "win32":
1157db96d56Sopenharmony_ci   sys.path = ['', '..\\..\\lib\\python-2.0']
1167db96d56Sopenharmony_ci   os.environ['TCL_LIBRARY'] = RootDir + '\\lib\\tcl8.2'
1177db96d56Sopenharmony_ci   os.environ['TK_LIBRARY'] = RootDir + '\\lib\\tk8.2'
1187db96d56Sopenharmony_ci   os.environ['TIX_LIBRARY'] = RootDir + '\\lib\\tix8.1'
1197db96d56Sopenharmony_cielif sys.platform == "linux2":
1207db96d56Sopenharmony_ci   sys.path = ['', '../../lib/python-2.0']
1217db96d56Sopenharmony_ci   os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2'
1227db96d56Sopenharmony_ci   os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2'
1237db96d56Sopenharmony_ci   os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1'
1247db96d56Sopenharmony_cielif sys.platform == "solaris":
1257db96d56Sopenharmony_ci   sys.path = ['', '../../lib/python-2.0']
1267db96d56Sopenharmony_ci   os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2'
1277db96d56Sopenharmony_ci   os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2'
1287db96d56Sopenharmony_ci   os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1'
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ciThis also adds <root>/lib/python-2.0 to your Python path
1317db96d56Sopenharmony_cifor any Python files such as _tkinter.pyd you may need.
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ciNote that the dynamic libraries (such as tcl82.dll tk82.dll python20.dll
1347db96d56Sopenharmony_ciunder Windows, or libtcl8.2.so and libtcl8.2.so under Unix) are required
1357db96d56Sopenharmony_ciat program load time, and are searched by the operating system loader
1367db96d56Sopenharmony_cibefore Python can be started. Under Windows, the environment
1377db96d56Sopenharmony_civariable PATH is consulted, and under Unix, it may be the
1387db96d56Sopenharmony_cienvironment variable LD_LIBRARY_PATH and/or the system
1397db96d56Sopenharmony_cishared library cache (ld.so). An additional preferred directory for
1407db96d56Sopenharmony_cifinding the dynamic libraries is built into the .dll or .so files at
1417db96d56Sopenharmony_cicompile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile.
1427db96d56Sopenharmony_ciThe OS must find the dynamic libraries or your frozen program won't start.
1437db96d56Sopenharmony_ciUsually I make sure that the .so or .dll files are in the same directory
1447db96d56Sopenharmony_cias the executable, but this may not be foolproof.
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ciA workaround to installing your Tcl library files with your frozen
1477db96d56Sopenharmony_ciexecutable would be possible, in which the Tcl/Tk library files are
1487db96d56Sopenharmony_ciincorporated in a frozen Python module as string literals and written
1497db96d56Sopenharmony_cito a temporary location when the program runs; this is currently left
1507db96d56Sopenharmony_cias an exercise for the reader.  An easier approach is to freeze the
1517db96d56Sopenharmony_ciTcl/Tk/Tix code into the dynamic libraries using the Tcl ET code,
1527db96d56Sopenharmony_cior the Tix Stand-Alone-Module code. Of course, you can also simply
1537db96d56Sopenharmony_cirequire that Tcl/Tk is required on the target installation, but be
1547db96d56Sopenharmony_cicareful that the version corresponds.
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ciThere are some caveats using frozen Tkinter applications:
1577db96d56Sopenharmony_ci	Under Windows if you use the -s windows option, writing
1587db96d56Sopenharmony_cito stdout or stderr is an error.
1597db96d56Sopenharmony_ci	The Tcl [info nameofexecutable] will be set to where the
1607db96d56Sopenharmony_ciprogram was frozen, not where it is run from.
1617db96d56Sopenharmony_ci	The global variables argc and argv do not exist.
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ciA warning about shared library modules
1657db96d56Sopenharmony_ci--------------------------------------
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ciWhen your Python installation uses shared library modules such as
1687db96d56Sopenharmony_ci_tkinter.pyd, these will not be incorporated in the frozen program.
1697db96d56Sopenharmony_ci Again, the frozen program will work when you test it, but it won't
1707db96d56Sopenharmony_ci work when you ship it to a site without a Python installation.
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ciFreeze prints a warning when this is the case at the end of the
1737db96d56Sopenharmony_cifreezing process:
1747db96d56Sopenharmony_ci
1757db96d56Sopenharmony_ci	Warning: unknown modules remain: ...
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ciWhen this occurs, the best thing to do is usually to rebuild Python
1787db96d56Sopenharmony_ciusing static linking only. Or use the approach described in the previous
1797db96d56Sopenharmony_cisection to declare a library path using sys.path, and place the modules
1807db96d56Sopenharmony_cisuch as _tkinter.pyd there.
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ciTroubleshooting
1847db96d56Sopenharmony_ci---------------
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ciIf you have trouble using Freeze for a large program, it's probably
1877db96d56Sopenharmony_cibest to start playing with a really simple program first (like the file
1887db96d56Sopenharmony_cihello.py).  If you can't get that to work there's something
1897db96d56Sopenharmony_cifundamentally wrong -- perhaps you haven't installed Python.  To do a
1907db96d56Sopenharmony_ciproper install, you should do "make install" in the Python root
1917db96d56Sopenharmony_cidirectory.
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci
1947db96d56Sopenharmony_ciUsage under Windows 95 or NT
1957db96d56Sopenharmony_ci----------------------------
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ciUnder Windows 95 or NT, you *must* use the -p option and point it to
1987db96d56Sopenharmony_cithe top of the Python source tree.
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ciWARNING: the resulting executable is not self-contained; it requires
2017db96d56Sopenharmony_cithe Python DLL, currently PYTHON20.DLL (it does not require the
2027db96d56Sopenharmony_cistandard library of .py files though).  It may also require one or
2037db96d56Sopenharmony_cimore extension modules loaded from .DLL or .PYD files; the module
2047db96d56Sopenharmony_cinames are printed in the warning message about remaining unknown
2057db96d56Sopenharmony_cimodules.
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ciThe driver script generates a Makefile that works with the Microsoft
2087db96d56Sopenharmony_cicommand line C compiler (CL).  To compile, run "nmake"; this will
2097db96d56Sopenharmony_cibuild a target "hello.exe" if the source was "hello.py".  Only the
2107db96d56Sopenharmony_cifiles frozenmain.c and frozen.c are used; no config.c is generated or
2117db96d56Sopenharmony_ciused, since the standard DLL is used.
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ciIn order for this to work, you must have built Python using the VC++
2147db96d56Sopenharmony_ci(Developer Studio) 5.0 compiler.  The provided project builds
2157db96d56Sopenharmony_cipython20.lib in the subdirectory pcbuild\Release of thje Python source
2167db96d56Sopenharmony_citree, and this is where the generated Makefile expects it to be.  If
2177db96d56Sopenharmony_cithis is not the case, you can edit the Makefile or (probably better)
2187db96d56Sopenharmony_ciwinmakemakefile.py (e.g., if you are using the 4.2 compiler, the
2197db96d56Sopenharmony_cipython20.lib file is generated in the subdirectory vc40 of the Python
2207db96d56Sopenharmony_cisource tree).
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ciIt is possible to create frozen programs that don't have a console
2237db96d56Sopenharmony_ciwindow, by specifying the option '-s windows'. See the Usage below.
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ciUsage
2267db96d56Sopenharmony_ci-----
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ciHere is a list of all of the options (taken from freeze.__doc__):
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ciusage: freeze [options...] script [module]...
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ciOptions:
2337db96d56Sopenharmony_ci-p prefix:    This is the prefix used when you ran ``make install''
2347db96d56Sopenharmony_ci              in the Python build directory.
2357db96d56Sopenharmony_ci              (If you never ran this, freeze won't work.)
2367db96d56Sopenharmony_ci              The default is whatever sys.prefix evaluates to.
2377db96d56Sopenharmony_ci              It can also be the top directory of the Python source
2387db96d56Sopenharmony_ci              tree; then -P must point to the build tree.
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci-P exec_prefix: Like -p but this is the 'exec_prefix', used to
2417db96d56Sopenharmony_ci                install objects etc.  The default is whatever sys.exec_prefix
2427db96d56Sopenharmony_ci                evaluates to, or the -p argument if given.
2437db96d56Sopenharmony_ci                If -p points to the Python source tree, -P must point
2447db96d56Sopenharmony_ci                to the build tree, if different.
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci-e extension: A directory containing additional .o files that
2477db96d56Sopenharmony_ci              may be used to resolve modules.  This directory
2487db96d56Sopenharmony_ci              should also have a Setup file describing the .o files.
2497db96d56Sopenharmony_ci              On Windows, the name of a .INI file describing one
2507db96d56Sopenharmony_ci              or more extensions is passed.
2517db96d56Sopenharmony_ci              More than one -e option may be given.
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_ci-o dir:       Directory where the output files are created; default '.'.
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ci-m:           Additional arguments are module names instead of filenames.
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci-a package=dir: Additional directories to be added to the package's
2587db96d56Sopenharmony_ci                __path__.  Used to simulate directories added by the
2597db96d56Sopenharmony_ci                package at runtime (eg, by OpenGL and win32com).
2607db96d56Sopenharmony_ci                More than one -a option may be given for each package.
2617db96d56Sopenharmony_ci
2627db96d56Sopenharmony_ci-l file:      Pass the file to the linker (windows only)
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci-d:           Debugging mode for the module finder.
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci-q:           Make the module finder totally quiet.
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci-h:           Print this help message.
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci-x module     Exclude the specified module.
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_ci-i filename:  Include a file with additional command line options.  Used
2737db96d56Sopenharmony_ci              to prevent command lines growing beyond the capabilities of
2747db96d56Sopenharmony_ci              the shell/OS.  All arguments specified in filename
2757db96d56Sopenharmony_ci              are read and the -i option replaced with the parsed
2767db96d56Sopenharmony_ci              params (note - quoting args in this file is NOT supported)
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ci-s subsystem: Specify the subsystem (For Windows only.);
2797db96d56Sopenharmony_ci              'console' (default), 'windows', 'service' or 'com_dll'
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci-w:           Toggle Windows (NT or 95) behavior.
2827db96d56Sopenharmony_ci              (For debugging only -- on a win32 platform, win32 behavior
2837db96d56Sopenharmony_ci              is automatic.)
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ciArguments:
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ciscript:       The Python script to be executed by the resulting binary.
2887db96d56Sopenharmony_ci
2897db96d56Sopenharmony_cimodule ...:   Additional Python modules (referenced by pathname)
2907db96d56Sopenharmony_ci              that will be included in the resulting binary.  These
2917db96d56Sopenharmony_ci              may be .py or .pyc files.  If -m is specified, these are
2927db96d56Sopenharmony_ci              module names that are search in the path instead.
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci
2957db96d56Sopenharmony_ci
2967db96d56Sopenharmony_ci--Guido van Rossum (home page: https://www.python.org/~guido/)
297