diff options
Diffstat (limited to 'Tools/freeze/freeze.py')
-rwxr-xr-x | Tools/freeze/freeze.py | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/Tools/freeze/freeze.py b/Tools/freeze/freeze.py index 3de6bdb..ce0a454 100755 --- a/Tools/freeze/freeze.py +++ b/Tools/freeze/freeze.py @@ -28,6 +28,8 @@ Options: -m: Additional arguments are module names instead of filenames. +-l file: Pass the file to the linker (windows only) + -d: Debugging mode for the module finder. -q: Make the module finder totally quiet. @@ -38,8 +40,11 @@ Options: (For debugging only -- on a win32 platform, win32 behaviour is automatic.) --s subsystem: Specify the subsystem; 'windows' or 'console' (default). - (For Windows only.) +-x module Exclude the specified module. + +-s subsystem: Specify the subsystem (For Windows only.); + 'console' (default), 'windows', 'service' or 'com_dll' + Arguments: @@ -87,12 +92,17 @@ def main(): prefix = None # settable with -p option exec_prefix = None # settable with -P option extensions = [] + exclude = [] # settable with -x option + addn_link = [] # settable with -l, but only honored under Windows. path = sys.path[:] modargs = 0 debug = 1 odir = '' win = sys.platform[:3] == 'win' + # default the exclude list for each platform +# if win: exclude = exclude + ['dos', 'dospath', 'mac', 'macpath', 'MACFS', 'posix', 'os2'] + # modules that are imported by the Python runtime implicits = ["site", "exceptions"] @@ -105,7 +115,7 @@ def main(): # parse command line try: - opts, args = getopt.getopt(sys.argv[1:], 'de:hmo:p:P:qs:w') + opts, args = getopt.getopt(sys.argv[1:], 'de:hmo:p:P:qs:wx:l:') except getopt.error, msg: usage('getopt error: ' + str(msg)) @@ -134,6 +144,10 @@ def main(): if not win: usage("-s subsystem option only on Windows") subsystem = a + if o == '-x': + exclude.append(a) + if o == '-l': + addn_link.append(a) # default prefix and exec_prefix if not exec_prefix: @@ -156,6 +170,7 @@ def main(): config_c_in = os.path.join(prefix, 'Modules', 'config.c.in') frozenmain_c = os.path.join(prefix, 'Python', 'frozenmain.c') makefile_in = os.path.join(exec_prefix, 'Modules', 'Makefile') + if win: frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c') else: binlib = os.path.join(exec_prefix, 'lib', 'python%s' % version, 'config') @@ -198,12 +213,15 @@ def main(): for arg in args: if arg == '-m': break + # if user specified -m on the command line before _any_ + # file names, then nothing should be checked (as the + # very first file should be a module name) + if modargs: + break if not os.path.exists(arg): usage('argument %s not found' % arg) if not os.path.isfile(arg): usage('%s: not a plain file' % arg) - if modargs: - break # process non-option arguments scriptfile = args[0] @@ -234,12 +252,32 @@ def main(): target = os.path.join(odir, target) makefile = os.path.join(odir, makefile) + # Handle special entry point requirements + # (on Windows, some frozen programs do not use __main__, but + # import the module directly. Eg, DLLs, Services, etc + custom_entry_point = None # Currently only used on Windows + python_entry_is_main = 1 # Is the entry point called __main__? + # handle -s option on Windows + if win: + import winmakemakefile + try: + custom_entry_point, python_entry_is_main = winmakemakefile. get_custom_entry_point(subsystem) + except ValueError, why: + usage(why) + + # Actual work starts here... # collect all modules of the program dir = os.path.dirname(scriptfile) path[0] = dir - mf = modulefinder.ModuleFinder(path, debug) + mf = modulefinder.ModuleFinder(path, debug, exclude) + + if win and subsystem=='service': + # If a Windows service, then add the "built-in" module. + mod = mf.add_module("servicemanager") + mod.__file__="dummy.pyd" # really built-in to the resulting EXE + for mod in implicits: mf.import_hook(mod) for mod in modules: @@ -253,7 +291,16 @@ def main(): mf.import_hook(mod) else: mf.load_file(mod) - mf.run_script(scriptfile) + + # Add the main script as either __main__, or the actual module name. + if python_entry_is_main: + mf.run_script(scriptfile) + else: + if modargs: + mf.import_hook(scriptfile) + else: + mf.load_file(scriptfile) + if debug > 0: mf.report() print @@ -267,10 +314,7 @@ def main(): backup = None outfp = open(frozen_c, 'w') try: - makefreeze.makefreeze(outfp, dict, debug) - if win and subsystem == 'windows': - import winmakemakefile - outfp.write(winmakemakefile.WINMAINTEMPLATE) + makefreeze.makefreeze(outfp, dict, debug, custom_entry_point) finally: outfp.close() if backup: @@ -294,12 +338,29 @@ def main(): # search for unknown modules in extensions directories (not on Windows) addfiles = [] - if unknown and not win: - addfiles, addmods = \ - checkextensions.checkextensions(unknown, extensions) - for mod in addmods: - unknown.remove(mod) - builtins = builtins + addmods + addmoddefns = [] # Windows list of modules. + if unknown: + if not win: + addfiles, addmods = \ + checkextensions.checkextensions(unknown, extensions) + for mod in addmods: + unknown.remove(mod) + builtins = builtins + addmods + else: + # Do the windows thang... + import checkextensions_win32 + # Get a list of CExtension instances, each describing a module + # (including its source files) + addmoddefns = checkextensions_win32.checkextensions(unknown, extensions) + maindefn = checkextensions_win32.CExtension( '__main__', + [frozenmain_c, os.path.basename(frozen_c),frozendllmain_c]) + + for mod in addmoddefns: + unknown.remove(mod.name) + builtins.append(mod.name) + + addmoddefns.append( maindefn ) + # report unknown modules if unknown: @@ -314,8 +375,7 @@ def main(): try: winmakemakefile.makemakefile(outfp, locals(), - [frozenmain_c, - os.path.basename(frozen_c)], + addmoddefns, os.path.basename(target)) finally: outfp.close() |