mirror of https://github.com/python/cpython.git
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).
This commit is contained in:
parent
db7287c0f5
commit
03f7f08874
|
@ -42,7 +42,14 @@
|
||||||
|
|
||||||
-h: Print this help message.
|
-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
|
-i filename: Include a file with additional command line options. Used
|
||||||
to prevent command lines growing beyond the capabilities of
|
to prevent command lines growing beyond the capabilities of
|
||||||
|
@ -114,10 +121,15 @@ def main():
|
||||||
odir = ''
|
odir = ''
|
||||||
win = sys.platform[:3] == 'win'
|
win = sys.platform[:3] == 'win'
|
||||||
replace_paths = [] # settable with -r option
|
replace_paths = [] # settable with -r option
|
||||||
|
error_if_any_missing = 0
|
||||||
|
|
||||||
# default the exclude list for each platform
|
# default the exclude list for each platform
|
||||||
if win: exclude = exclude + [
|
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
|
# modules that are imported by the Python runtime
|
||||||
implicits = ["site", "exceptions"]
|
implicits = ["site", "exceptions"]
|
||||||
|
@ -129,14 +141,17 @@ def main():
|
||||||
makefile = 'Makefile'
|
makefile = 'Makefile'
|
||||||
subsystem = 'console'
|
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
|
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':
|
if sys.argv[pos] == '-i':
|
||||||
try:
|
try:
|
||||||
options = string.split(open(sys.argv[pos+1]).read())
|
options = string.split(open(sys.argv[pos+1]).read())
|
||||||
except IOError, why:
|
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.
|
# Replace the '-i' and the filename with the read params.
|
||||||
sys.argv[pos:pos+2] = options
|
sys.argv[pos:pos+2] = options
|
||||||
pos = pos + len(options) - 1 # Skip the name and the included args.
|
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.
|
# Now parse the command line with the extras inserted.
|
||||||
try:
|
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:
|
except getopt.error, msg:
|
||||||
usage('getopt error: ' + str(msg))
|
usage('getopt error: ' + str(msg))
|
||||||
|
|
||||||
|
@ -175,6 +190,11 @@ def main():
|
||||||
subsystem = a
|
subsystem = a
|
||||||
if o == '-x':
|
if o == '-x':
|
||||||
exclude.append(a)
|
exclude.append(a)
|
||||||
|
if o == '-X':
|
||||||
|
exclude.append(a)
|
||||||
|
fail_import.append(a)
|
||||||
|
if o == '-E':
|
||||||
|
error_if_any_missing = 1
|
||||||
if o == '-l':
|
if o == '-l':
|
||||||
addn_link.append(a)
|
addn_link.append(a)
|
||||||
if o == '-a':
|
if o == '-a':
|
||||||
|
@ -225,7 +245,9 @@ def main():
|
||||||
|
|
||||||
# sanity check of directories and files
|
# sanity check of directories and files
|
||||||
check_dirs = [prefix, exec_prefix, binlib, incldir]
|
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:
|
for dir in check_dirs:
|
||||||
if not os.path.exists(dir):
|
if not os.path.exists(dir):
|
||||||
usage('needed directory %s not found' % dir)
|
usage('needed directory %s not found' % dir)
|
||||||
|
@ -350,8 +372,14 @@ def main():
|
||||||
print
|
print
|
||||||
dict = mf.modules
|
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
|
# 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)
|
# look for unfrozen modules (builtin and of unknown origin)
|
||||||
builtins = []
|
builtins = []
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
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
|
if entry_point is None: entry_point = default_entry_point
|
||||||
done = []
|
done = []
|
||||||
files = []
|
files = []
|
||||||
|
@ -63,6 +63,13 @@ def makefreeze(base, dict, debug=0, entry_point = None):
|
||||||
outfp.write(header)
|
outfp.write(header)
|
||||||
for mod, mangled, size in done:
|
for mod, mangled, size in done:
|
||||||
outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size))
|
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(trailer)
|
||||||
outfp.write(entry_point)
|
outfp.write(entry_point)
|
||||||
outfp.close()
|
outfp.close()
|
||||||
|
|
|
@ -356,8 +356,12 @@ def add_module(self, fqname):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def find_module(self, name, path):
|
def find_module(self, name, path):
|
||||||
if name in self.excludes:
|
if path:
|
||||||
self.msgout(3, "find_module -> Excluded")
|
fullname = '.'.join(path)+'.'+name
|
||||||
|
else:
|
||||||
|
fullname = name
|
||||||
|
if fullname in self.excludes:
|
||||||
|
self.msgout(3, "find_module -> Excluded", fullname)
|
||||||
raise ImportError, name
|
raise ImportError, name
|
||||||
|
|
||||||
if path is None:
|
if path is None:
|
||||||
|
@ -397,6 +401,15 @@ def report(self):
|
||||||
mods.sort()
|
mods.sort()
|
||||||
print "?", key, "from", string.join(mods, ', ')
|
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):
|
def replace_paths_in_code(self, co):
|
||||||
new_filename = original_filename = os.path.normpath(co.co_filename)
|
new_filename = original_filename = os.path.normpath(co.co_filename)
|
||||||
for f,r in self.replace_paths:
|
for f,r in self.replace_paths:
|
||||||
|
|
Loading…
Reference in New Issue