diff options
Diffstat (limited to 'Tools/freeze')
-rw-r--r-- | Tools/freeze/README | 18 | ||||
-rw-r--r-- | Tools/freeze/bkfile.py | 67 | ||||
-rw-r--r-- | Tools/freeze/extensions_win32.ini | 8 | ||||
-rwxr-xr-x | Tools/freeze/freeze.py | 21 | ||||
-rw-r--r-- | Tools/freeze/makefreeze.py | 54 |
5 files changed, 67 insertions, 101 deletions
diff --git a/Tools/freeze/README b/Tools/freeze/README index 81be2c8432..5bc5b049d5 100644 --- a/Tools/freeze/README +++ b/Tools/freeze/README @@ -100,8 +100,8 @@ to place the Tcl and Tk library files in the distributed setup, and then declare these directories in your frozen Python program using the TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. -For example, assume you will ship your frozen program in the directory -<root>/bin/windows-x86 and will place your Tcl library files +For example, assume you will ship your frozen program in the directory +<root>/bin/windows-x86 and will place your Tcl library files in <root>/lib/tcl8.2 and your Tk library files in <root>/lib/tk8.2. Then placing the following lines in your frozen Python script before importing Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix: @@ -138,8 +138,8 @@ variable PATH is consulted, and under Unix, it may be the environment variable LD_LIBRARY_PATH and/or the system shared library cache (ld.so). An additional preferred directory for finding the dynamic libraries is built into the .dll or .so files at -compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. -The OS must find the dynamic libraries or your frozen program won't start. +compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. +The OS must find the dynamic libraries or your frozen program won't start. Usually I make sure that the .so or .dll files are in the same directory as the executable, but this may not be foolproof. @@ -149,8 +149,8 @@ incorporated in a frozen Python module as string literals and written to a temporary location when the program runs; this is currently left as an exercise for the reader. An easier approach is to freeze the Tcl/Tk/Tix code into the dynamic libraries using the Tcl ET code, -or the Tix Stand-Alone-Module code. Of course, you can also simply -require that Tcl/Tk is required on the target installation, but be +or the Tix Stand-Alone-Module code. Of course, you can also simply +require that Tcl/Tk is required on the target installation, but be careful that the version corresponds. There are some caveats using frozen Tkinter applications: @@ -164,7 +164,7 @@ program was frozen, not where it is run from. A warning about shared library modules -------------------------------------- -When your Python installation uses shared library modules such as +When your Python installation uses shared library modules such as _tkinter.pyd, these will not be incorporated in the frozen program. Again, the frozen program will work when you test it, but it won't work when you ship it to a site without a Python installation. @@ -275,9 +275,9 @@ Options: are read and the -i option replaced with the parsed params (note - quoting args in this file is NOT supported) --s subsystem: Specify the subsystem (For Windows only.); +-s subsystem: Specify the subsystem (For Windows only.); 'console' (default), 'windows', 'service' or 'com_dll' - + -w: Toggle Windows (NT or 95) behavior. (For debugging only -- on a win32 platform, win32 behavior is automatic.) diff --git a/Tools/freeze/bkfile.py b/Tools/freeze/bkfile.py index 6abacc9e0e..20a70b0639 100644 --- a/Tools/freeze/bkfile.py +++ b/Tools/freeze/bkfile.py @@ -1,49 +1,26 @@ from builtins import open as _orig_open -class _BkFile: - def __init__(self, file, mode, bufsize): - import os - self.__filename = file - self.__backup = file + '~' - try: - os.unlink(self.__backup) - except OSError: - pass - try: - os.rename(file, self.__backup) - except OSError: - self.__backup = None - self.__file = _orig_open(file, mode, bufsize) - self.closed = self.__file.closed - self.fileno = self.__file.fileno - self.flush = self.__file.flush - self.isatty = self.__file.isatty - self.mode = self.__file.mode - self.name = self.__file.name - self.read = self.__file.read - try: - self.readinto = self.__file.readinto - except AttributeError: - pass - self.readline = self.__file.readline - self.readlines = self.__file.readlines - self.seek = self.__file.seek - self.tell = self.__file.tell - self.truncate = self.__file.truncate - self.write = self.__file.write - self.writelines = self.__file.writelines - - def close(self): - self.__file.close() - if self.__backup is None: - return - import filecmp - if filecmp.cmp(self.__backup, self.__filename, shallow = 0): - import os - os.unlink(self.__filename) - os.rename(self.__backup, self.__filename) - -def open(file, mode = 'r', bufsize = -1): +def open(file, mode='r', bufsize=-1): if 'w' not in mode: return _orig_open(file, mode, bufsize) - return _BkFile(file, mode, bufsize) + import os + backup = file + '~' + try: + os.unlink(backup) + except OSError: + pass + try: + os.rename(file, backup) + except OSError: + return _orig_open(file, mode, bufsize) + f = _orig_open(file, mode, bufsize) + _orig_close = f.close + def close(): + _orig_close() + import filecmp + if filecmp.cmp(backup, file, shallow=False): + import os + os.unlink(file) + os.rename(backup, file) + f.close = close + return f diff --git a/Tools/freeze/extensions_win32.ini b/Tools/freeze/extensions_win32.ini index 1e36abad57..d01fd6b9f5 100644 --- a/Tools/freeze/extensions_win32.ini +++ b/Tools/freeze/extensions_win32.ini @@ -6,7 +6,7 @@ ; This is all setup for all the win32 extension modules ; released by Mark Hammond. -; You must ensure that the environment variable PYTHONEX is set +; You must ensure that the environment variable PYTHONEX is set ; to point to the root win32 extensions directory ; PYTHONPREFIX must point to the Python build root directory @@ -49,7 +49,7 @@ dsp=%PYTHONPREFIX%\PCBuild\select.dsp [zlib] dsp=%PYTHONPREFIX%\PCBuild\zlib.dsp -cl=/I %PYTHONPREFIX%\..\zlib-1.1.4 /D _WINDOWS /D WIN32 +cl=/I %PYTHONPREFIX%\..\zlib-1.1.4 /D _WINDOWS /D WIN32 libs=%PYTHONPREFIX%\..\zlib-1.1.4\zlib.lib /nodefaultlib:libc [winreg] @@ -95,7 +95,7 @@ dsp=%PYTHONEX%\win32\win32event.dsp cl=/I %PYTHONEX%\win32\src [win32file] -dsp=%PYTHONEX%\win32\win32file.dsp +dsp=%PYTHONEX%\win32\win32file.dsp cl=/I %PYTHONEX%\win32\src [win32net] @@ -108,7 +108,7 @@ dsp=%PYTHONEX%\win32\win32pdh.dsp cl=/I %PYTHONEX%\win32\src [win32pipe] -dsp=%PYTHONEX%\win32\win32pipe.dsp +dsp=%PYTHONEX%\win32\win32pipe.dsp cl=/I %PYTHONEX%\win32\src [win32security] diff --git a/Tools/freeze/freeze.py b/Tools/freeze/freeze.py index e0c6c2c580..c0758078f8 100755 --- a/Tools/freeze/freeze.py +++ b/Tools/freeze/freeze.py @@ -366,8 +366,10 @@ def main(): mf.load_file(mod) # Alias "importlib._bootstrap" to "_frozen_importlib" so that the - # import machinery can bootstrap. + # import machinery can bootstrap. Do the same for + # importlib._bootstrap_external. mf.modules["_frozen_importlib"] = mf.modules["importlib._bootstrap"] + mf.modules["_frozen_importlib_external"] = mf.modules["importlib._bootstrap_external"] # Add the main script as either __main__, or the actual module name. if python_entry_is_main: @@ -439,25 +441,17 @@ def main(): frozendllmain_c, os.path.basename(extensions_c)] + files maindefn = checkextensions_win32.CExtension( '__main__', xtras ) frozen_extensions.append( maindefn ) - outfp = open(makefile, 'w') - try: + with open(makefile, 'w') as outfp: winmakemakefile.makemakefile(outfp, locals(), frozen_extensions, os.path.basename(target)) - finally: - outfp.close() return # generate config.c and Makefile builtins.sort() - infp = open(config_c_in) - outfp = bkfile.open(config_c, 'w') - try: + with open(config_c_in) as infp, bkfile.open(config_c, 'w') as outfp: makeconfig.makeconfig(infp, outfp, builtins) - finally: - outfp.close() - infp.close() cflags = ['$(OPT)'] cppflags = defines + includes @@ -475,11 +469,8 @@ def main(): files + supp_sources + addfiles + libs + \ ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)'] - outfp = bkfile.open(makefile, 'w') - try: + with bkfile.open(makefile, 'w') as outfp: makemakefile.makemakefile(outfp, somevars, files, base_target) - finally: - outfp.close() # Done! diff --git a/Tools/freeze/makefreeze.py b/Tools/freeze/makefreeze.py index ef18ec7b28..64e3e6bf71 100644 --- a/Tools/freeze/makefreeze.py +++ b/Tools/freeze/makefreeze.py @@ -39,36 +39,34 @@ def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()): mangled = "__".join(mod.split(".")) if m.__code__: file = 'M_' + mangled + '.c' - outfp = bkfile.open(base + file, 'w') - files.append(file) - if debug: - print("freezing", mod, "...") - str = marshal.dumps(m.__code__) - size = len(str) - if m.__path__: - # Indicate package by negative size - size = -size - done.append((mod, mangled, size)) - writecode(outfp, mangled, str) - outfp.close() + with bkfile.open(base + file, 'w') as outfp: + files.append(file) + if debug: + print("freezing", mod, "...") + str = marshal.dumps(m.__code__) + size = len(str) + if m.__path__: + # Indicate package by negative size + size = -size + done.append((mod, mangled, size)) + writecode(outfp, mangled, str) if debug: print("generating table of frozen modules") - outfp = bkfile.open(base + 'frozen.c', 'w') - for mod, mangled, size in done: - outfp.write('extern unsigned char M_%s[];\n' % mangled) - outfp.write(header) - for mod, mangled, size in done: - outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size)) - outfp.write('\n') - # The following modules have a NULL code pointer, indicating - # that the frozen program should not search for them on the host - # system. Importing them will *always* raise an ImportError. - # The zero value size is never used. - for mod in fail_import: - outfp.write('\t{"%s", NULL, 0},\n' % (mod,)) - outfp.write(trailer) - outfp.write(entry_point) - outfp.close() + with bkfile.open(base + 'frozen.c', 'w') as outfp: + for mod, mangled, size in done: + outfp.write('extern unsigned char M_%s[];\n' % mangled) + outfp.write(header) + for mod, mangled, size in done: + outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size)) + outfp.write('\n') + # The following modules have a NULL code pointer, indicating + # that the frozen program should not search for them on the host + # system. Importing them will *always* raise an ImportError. + # The zero value size is never used. + for mod in fail_import: + outfp.write('\t{"%s", NULL, 0},\n' % (mod,)) + outfp.write(trailer) + outfp.write(entry_point) return files |