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