diff options
author | Guido van Rossum <guido@python.org> | 2001-10-18 19:15:32 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-10-18 19:15:32 (GMT) |
commit | 03f7f088743bbab2dd5aa426670a41fd643112cd (patch) | |
tree | b1427132d21ba0eb5f14120e1d91b6425e9b0826 | |
parent | db7287c0f5b197bbfaf624d181333a92135ec261 (diff) | |
download | cpython-03f7f088743bbab2dd5aa426670a41fd643112cd.zip cpython-03f7f088743bbab2dd5aa426670a41fd643112cd.tar.gz cpython-03f7f088743bbab2dd5aa426670a41fd643112cd.tar.bz2 |
Part 2/2 of SF patch #416704: More robust freeze, by Toby Dickenson.
(With slight cosmetic improvements to shorten lines and a grammar fix
to a docstring.)
This addes -X and -E options to freeze. From the docstring:
-X module Like -x, except the module can never be imported by
the frozen binary.
-E: Freeze will fail if any modules can't be found (that
were not excluded using -x or -X).
-rwxr-xr-x | Tools/freeze/freeze.py | 44 | ||||
-rw-r--r-- | Tools/freeze/makefreeze.py | 9 | ||||
-rw-r--r-- | Tools/freeze/modulefinder.py | 17 |
3 files changed, 59 insertions, 11 deletions
diff --git a/Tools/freeze/freeze.py b/Tools/freeze/freeze.py index b534098..c347d53 100755 --- a/Tools/freeze/freeze.py +++ b/Tools/freeze/freeze.py @@ -42,7 +42,14 @@ Options: -h: Print this help message. --x module Exclude the specified module. +-x module Exclude the specified module. It will still be imported + by the frozen binary if it exists on the host system. + +-X module Like -x, except the module can never be imported by + the frozen binary. + +-E: Freeze will fail if any modules can't be found (that + were not excluded using -x or -X). -i filename: Include a file with additional command line options. Used to prevent command lines growing beyond the capabilities of @@ -114,10 +121,15 @@ def main(): odir = '' win = sys.platform[:3] == 'win' replace_paths = [] # settable with -r option + error_if_any_missing = 0 # default the exclude list for each platform if win: exclude = exclude + [ - 'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', 'os2', 'ce'] + 'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', + 'os2', 'ce', 'riscos', 'riscosenviron', 'riscospath', + ] + + fail_import = exclude[:] # modules that are imported by the Python runtime implicits = ["site", "exceptions"] @@ -129,14 +141,17 @@ def main(): makefile = 'Makefile' subsystem = 'console' - # parse command line by first replacing any "-i" options with the file contents. + # parse command line by first replacing any "-i" options with the + # file contents. pos = 1 - while pos < len(sys.argv)-1: # last option can not be "-i", so this ensures "pos+1" is in range! + while pos < len(sys.argv)-1: + # last option can not be "-i", so this ensures "pos+1" is in range! if sys.argv[pos] == '-i': try: options = string.split(open(sys.argv[pos+1]).read()) except IOError, why: - usage("File name '%s' specified with the -i option can not be read - %s" % (sys.argv[pos+1], why) ) + usage("File name '%s' specified with the -i option " + "can not be read - %s" % (sys.argv[pos+1], why) ) # Replace the '-i' and the filename with the read params. sys.argv[pos:pos+2] = options pos = pos + len(options) - 1 # Skip the name and the included args. @@ -144,7 +159,7 @@ def main(): # Now parse the command line with the extras inserted. try: - opts, args = getopt.getopt(sys.argv[1:], 'r:a:de:hmo:p:P:qs:wx:l:') + opts, args = getopt.getopt(sys.argv[1:], 'r:a:dEe:hmo:p:P:qs:wX:x:l:') except getopt.error, msg: usage('getopt error: ' + str(msg)) @@ -175,6 +190,11 @@ def main(): subsystem = a if o == '-x': exclude.append(a) + if o == '-X': + exclude.append(a) + fail_import.append(a) + if o == '-E': + error_if_any_missing = 1 if o == '-l': addn_link.append(a) if o == '-a': @@ -225,7 +245,9 @@ def main(): # sanity check of directories and files check_dirs = [prefix, exec_prefix, binlib, incldir] - if not win: check_dirs = check_dirs + extensions # These are not directories on Windows. + if not win: + # These are not directories on Windows. + check_dirs = check_dirs + extensions for dir in check_dirs: if not os.path.exists(dir): usage('needed directory %s not found' % dir) @@ -350,8 +372,14 @@ def main(): print dict = mf.modules + if error_if_any_missing: + missing = mf.any_missing() + if missing: + sys.exit("There are some missing modules: %r" % missing) + # generate output for frozen modules - files = makefreeze.makefreeze(base, dict, debug, custom_entry_point) + files = makefreeze.makefreeze(base, dict, debug, custom_entry_point, + fail_import) # look for unfrozen modules (builtin and of unknown origin) builtins = [] diff --git a/Tools/freeze/makefreeze.py b/Tools/freeze/makefreeze.py index b7bf9fd..ac59a9c 100644 --- a/Tools/freeze/makefreeze.py +++ b/Tools/freeze/makefreeze.py @@ -32,7 +32,7 @@ main(argc, argv) """ -def makefreeze(base, dict, debug=0, entry_point = None): +def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()): if entry_point is None: entry_point = default_entry_point done = [] files = [] @@ -63,6 +63,13 @@ def makefreeze(base, dict, debug=0, entry_point = None): 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 prozen 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() diff --git a/Tools/freeze/modulefinder.py b/Tools/freeze/modulefinder.py index 015708b..924c3a4 100644 --- a/Tools/freeze/modulefinder.py +++ b/Tools/freeze/modulefinder.py @@ -356,8 +356,12 @@ class ModuleFinder: return m def find_module(self, name, path): - if name in self.excludes: - self.msgout(3, "find_module -> Excluded") + if path: + fullname = '.'.join(path)+'.'+name + else: + fullname = name + if fullname in self.excludes: + self.msgout(3, "find_module -> Excluded", fullname) raise ImportError, name if path is None: @@ -397,6 +401,15 @@ class ModuleFinder: mods.sort() print "?", key, "from", string.join(mods, ', ') + def any_missing(self): + keys = self.badmodules.keys() + missing = [] + for key in keys: + if key not in self.excludes: + # Missing, and its not supposed to be + missing.append(key) + return missing + def replace_paths_in_code(self, co): new_filename = original_filename = os.path.normpath(co.co_filename) for f,r in self.replace_paths: |