New version, with contributions from Sjoerd Mullender and Mark Hammond.
Sjoerd writes: This version of freeze creates one file per Python module, instead of one humongous file for all Python modules. bkfile: new module to used to write files with backups. No new file is produced if the new contents is identical to the old. New option "-x excluded-module" for modulefinder test program. New option "-i filename" for freeze main program to include a list of options in place of the -i option.
This commit is contained in:
parent
6c74fea07d
commit
baf0603493
|
@ -77,10 +77,12 @@ such as /usr/joe/python/Tools/freeze/freeze.py).
|
||||||
What do I do next?
|
What do I do next?
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Freeze creates three files: frozen.c, config.c and Makefile. To
|
Freeze creates a number of files: frozen.c, config.c and Makefile,
|
||||||
produce the frozen version of your program, you can simply type
|
plus one file for each Python module that gets included named
|
||||||
"make". This should produce a binary file. If the filename argument
|
M_<module>.c. To produce the frozen version of your program, you can
|
||||||
to Freeze was "hello.py", the binary will be called "hello".
|
simply type "make". This should produce a binary file. If the
|
||||||
|
filename argument to Freeze was "hello.py", the binary will be called
|
||||||
|
"hello".
|
||||||
|
|
||||||
Note: you can use the -o option to freeze to specify an alternative
|
Note: you can use the -o option to freeze to specify an alternative
|
||||||
directory where these files are created. This makes it easier to
|
directory where these files are created. This makes it easier to
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
_orig_open = open
|
||||||
|
|
||||||
|
class _BkFile:
|
||||||
|
def __init__(self, file, mode, bufsize):
|
||||||
|
import os
|
||||||
|
self.__filename = file
|
||||||
|
self.__backup = file + '~'
|
||||||
|
try:
|
||||||
|
os.unlink(self.__backup)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.rename(file, self.__backup)
|
||||||
|
except os.error:
|
||||||
|
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
|
||||||
|
self.readinto = self.__file.readinto
|
||||||
|
self.readline = self.__file.readline
|
||||||
|
self.readlines = self.__file.readlines
|
||||||
|
self.seek = self.__file.seek
|
||||||
|
self.softspace = self.__file.softspace
|
||||||
|
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 cmp
|
||||||
|
# don't use cmp.cmp because of NFS bugs :-( and
|
||||||
|
# anyway, the stat mtime values differ so do_cmp will
|
||||||
|
# most likely be called anyway
|
||||||
|
if cmp.do_cmp(self.__backup, self.__filename):
|
||||||
|
import os
|
||||||
|
os.unlink(self.__filename)
|
||||||
|
os.rename(self.__backup, self.__filename)
|
||||||
|
|
||||||
|
def open(file, mode = 'r', bufsize = -1):
|
||||||
|
if 'w' not in mode:
|
||||||
|
return _orig_open(file, mode, bufsize)
|
||||||
|
return _BkFile(file, mode, bufsize)
|
|
@ -9,11 +9,13 @@ options anyway (eg, to enable or disable specific functionality)
|
||||||
|
|
||||||
So my basic stragtegy is:
|
So my basic stragtegy is:
|
||||||
|
|
||||||
* Have a Windows INI file which "describes" an extension module.
|
* Have some Windows INI files which "describe" one or more extension modules.
|
||||||
|
(Freeze comes with a default one for all known modules - but you can specify
|
||||||
|
your own).
|
||||||
* This description can include:
|
* This description can include:
|
||||||
- The MSVC .dsp file for the extension. The .c source file names
|
- The MSVC .dsp file for the extension. The .c source file names
|
||||||
are extraced from there.
|
are extraced from there.
|
||||||
- Specific compiler options
|
- Specific compiler/linker options
|
||||||
- Flag to indicate if Unicode compilation is expected.
|
- Flag to indicate if Unicode compilation is expected.
|
||||||
|
|
||||||
At the moment the name and location of this INI file is hardcoded,
|
At the moment the name and location of this INI file is hardcoded,
|
||||||
|
@ -52,31 +54,52 @@ class CExtension:
|
||||||
def GetLinkerLibs(self):
|
def GetLinkerLibs(self):
|
||||||
return self.linkerLibs
|
return self.linkerLibs
|
||||||
|
|
||||||
def checkextensions(unknown, ignored):
|
def checkextensions(unknown, extra_inis):
|
||||||
# Create a table of frozen extensions
|
# Create a table of frozen extensions
|
||||||
|
|
||||||
mapFileName = os.path.join( os.path.split(sys.argv[0])[0], "extensions_win32.ini")
|
defaultMapName = os.path.join( os.path.split(sys.argv[0])[0], "extensions_win32.ini")
|
||||||
|
if not os.path.isfile(defaultMapName):
|
||||||
|
sys.stderr.write("WARNING: %s can not be found - standard extensions may not be found" % mapFileName)
|
||||||
|
else:
|
||||||
|
# must go on end, so other inis can override.
|
||||||
|
extra_inis.append(defaultMapName)
|
||||||
|
|
||||||
ret = []
|
ret = []
|
||||||
for mod in unknown:
|
for mod in unknown:
|
||||||
defn = get_extension_defn( mod, mapFileName )
|
for ini in extra_inis:
|
||||||
if defn is not None:
|
# print "Looking for", mod, "in", win32api.GetFullPathName(ini),"...",
|
||||||
ret.append( defn )
|
defn = get_extension_defn( mod, ini )
|
||||||
|
if defn is not None:
|
||||||
|
# print "Yay - found it!"
|
||||||
|
ret.append( defn )
|
||||||
|
break
|
||||||
|
# print "Nope!"
|
||||||
|
else: # For not broken!
|
||||||
|
sys.stderr.write("No definition of module %s in any specified map file.\n" % (mod))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_extension_defn(moduleName, mapFileName):
|
def get_extension_defn(moduleName, mapFileName):
|
||||||
if win32api is None: return None
|
if win32api is None: return None
|
||||||
dsp = win32api.GetProfileVal(moduleName, "dsp", "", mapFileName)
|
dsp = win32api.GetProfileVal(moduleName, "dsp", "", mapFileName)
|
||||||
if dsp=="":
|
if dsp=="":
|
||||||
sys.stderr.write("No definition of module %s in map file '%s'\n" % (moduleName, mapFileName))
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# We allow environment variables in the file name
|
# We allow environment variables in the file name
|
||||||
dsp = win32api.ExpandEnvironmentStrings(dsp)
|
dsp = win32api.ExpandEnvironmentStrings(dsp)
|
||||||
|
# If the path to the .DSP file is not absolute, assume it is relative
|
||||||
|
# to the description file.
|
||||||
|
if not os.path.isabs(dsp):
|
||||||
|
dsp = os.path.join( os.path.split(mapFileName)[0], dsp)
|
||||||
|
# Parse it to extract the source files.
|
||||||
sourceFiles = parse_dsp(dsp)
|
sourceFiles = parse_dsp(dsp)
|
||||||
if sourceFiles is None:
|
if sourceFiles is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
module = CExtension(moduleName, sourceFiles)
|
module = CExtension(moduleName, sourceFiles)
|
||||||
|
# Put the path to the DSP into the environment so entries can reference it.
|
||||||
|
os.environ['dsp_path'] = os.path.split(dsp)[0]
|
||||||
|
os.environ['ini_path'] = os.path.split(mapFileName)[0]
|
||||||
|
|
||||||
cl_options = win32api.GetProfileVal(moduleName, "cl", "", mapFileName)
|
cl_options = win32api.GetProfileVal(moduleName, "cl", "", mapFileName)
|
||||||
if cl_options:
|
if cl_options:
|
||||||
|
@ -90,7 +113,7 @@ def get_extension_defn(moduleName, mapFileName):
|
||||||
|
|
||||||
libs = string.split(win32api.GetProfileVal(moduleName, "libs", "", mapFileName))
|
libs = string.split(win32api.GetProfileVal(moduleName, "libs", "", mapFileName))
|
||||||
for lib in libs:
|
for lib in libs:
|
||||||
module.AddLinkerLib(lib)
|
module.AddLinkerLib(win32api.ExpandEnvironmentStrings(lib))
|
||||||
|
|
||||||
for exc in exclude:
|
for exc in exclude:
|
||||||
if exc in module.sourceFiles:
|
if exc in module.sourceFiles:
|
||||||
|
|
|
@ -112,6 +112,6 @@ Unicode = 1
|
||||||
; Pythonwin
|
; Pythonwin
|
||||||
[win32ui]
|
[win32ui]
|
||||||
dsp=%PYTHONEX%\Pythonwin\win32ui.dsp
|
dsp=%PYTHONEX%\Pythonwin\win32ui.dsp
|
||||||
cl=/I %PYTHONEX%\win32\src
|
cl=/D _AFXDLL /D FREEZE_WIN32UI /GX /I %PYTHONEX%\win32\src
|
||||||
libs=mfc42.lib
|
libs=mfc42.lib
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
usage: freeze [options...] script [module]...
|
usage: freeze [options...] script [module]...
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
-p prefix: This is the prefix used when you ran ``make install''
|
-p prefix: This is the prefix used when you ran ``make install''
|
||||||
in the Python build directory.
|
in the Python build directory.
|
||||||
(If you never ran this, freeze won't work.)
|
(If you never ran this, freeze won't work.)
|
||||||
|
@ -22,6 +21,8 @@ Options:
|
||||||
-e extension: A directory containing additional .o files that
|
-e extension: A directory containing additional .o files that
|
||||||
may be used to resolve modules. This directory
|
may be used to resolve modules. This directory
|
||||||
should also have a Setup file describing the .o files.
|
should also have a Setup file describing the .o files.
|
||||||
|
On Windows, the name of a .INI file describing one
|
||||||
|
or more extensions is passed.
|
||||||
More than one -e option may be given.
|
More than one -e option may be given.
|
||||||
|
|
||||||
-o dir: Directory where the output files are created; default '.'.
|
-o dir: Directory where the output files are created; default '.'.
|
||||||
|
@ -41,15 +42,20 @@ Options:
|
||||||
|
|
||||||
-h: Print this help message.
|
-h: Print this help message.
|
||||||
|
|
||||||
-w: Toggle Windows (NT or 95) behavior.
|
|
||||||
(For debugging only -- on a win32 platform, win32 behaviour
|
|
||||||
is automatic.)
|
|
||||||
|
|
||||||
-x module Exclude the specified module.
|
-x module Exclude the specified module.
|
||||||
|
|
||||||
|
-i filename: Include a file with additional command line options. Used
|
||||||
|
to prevent command lines growing beyond the capabilities of
|
||||||
|
the shell/OS. All arguments specified in filename
|
||||||
|
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'
|
'console' (default), 'windows', 'service' or 'com_dll'
|
||||||
|
|
||||||
|
-w: Toggle Windows (NT or 95) behavior.
|
||||||
|
(For debugging only -- on a win32 platform, win32 behaviour
|
||||||
|
is automatic.)
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
|
@ -87,6 +93,7 @@ import makeconfig
|
||||||
import makefreeze
|
import makefreeze
|
||||||
import makemakefile
|
import makemakefile
|
||||||
import parsesetup
|
import parsesetup
|
||||||
|
import bkfile
|
||||||
|
|
||||||
|
|
||||||
# Main program
|
# Main program
|
||||||
|
@ -105,8 +112,8 @@ def main():
|
||||||
win = sys.platform[:3] == 'win'
|
win = sys.platform[:3] == 'win'
|
||||||
|
|
||||||
# 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', 'posix', 'os2']
|
'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', 'os2']
|
||||||
|
|
||||||
# modules that are imported by the Python runtime
|
# modules that are imported by the Python runtime
|
||||||
implicits = ["site", "exceptions"]
|
implicits = ["site", "exceptions"]
|
||||||
|
@ -118,7 +125,20 @@ def main():
|
||||||
makefile = 'Makefile'
|
makefile = 'Makefile'
|
||||||
subsystem = 'console'
|
subsystem = 'console'
|
||||||
|
|
||||||
# parse command line
|
# 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!
|
||||||
|
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) )
|
||||||
|
# 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.
|
||||||
|
pos = pos + 1
|
||||||
|
|
||||||
|
# Now parse the command line with the extras inserted.
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'a:de:hmo:p:P:qs:wx:l:')
|
opts, args = getopt.getopt(sys.argv[1:], 'a:de:hmo:p:P:qs:wx:l:')
|
||||||
except getopt.error, msg:
|
except getopt.error, msg:
|
||||||
|
@ -197,13 +217,15 @@ def main():
|
||||||
includes = ['-I' + incldir, '-I' + config_h_dir]
|
includes = ['-I' + incldir, '-I' + config_h_dir]
|
||||||
|
|
||||||
# sanity check of directories and files
|
# sanity check of directories and files
|
||||||
for dir in [prefix, exec_prefix, binlib, incldir] + extensions:
|
check_dirs = [prefix, exec_prefix, binlib, incldir]
|
||||||
|
if not win: check_dirs = check_dirs + extensions # These are not directories on Windows.
|
||||||
|
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)
|
||||||
if not os.path.isdir(dir):
|
if not os.path.isdir(dir):
|
||||||
usage('%s: not a directory' % dir)
|
usage('%s: not a directory' % dir)
|
||||||
if win:
|
if win:
|
||||||
files = supp_sources
|
files = supp_sources + extensions # extensions are files on Windows.
|
||||||
else:
|
else:
|
||||||
files = [config_c_in, makefile_in] + supp_sources
|
files = [config_c_in, makefile_in] + supp_sources
|
||||||
for file in supp_sources:
|
for file in supp_sources:
|
||||||
|
@ -260,7 +282,9 @@ def main():
|
||||||
print "Created output directory", odir
|
print "Created output directory", odir
|
||||||
except os.error, msg:
|
except os.error, msg:
|
||||||
usage('%s: mkdir failed (%s)' % (odir, str(msg)))
|
usage('%s: mkdir failed (%s)' % (odir, str(msg)))
|
||||||
|
base = ''
|
||||||
if odir:
|
if odir:
|
||||||
|
base = os.path.join(odir, '')
|
||||||
frozen_c = os.path.join(odir, frozen_c)
|
frozen_c = os.path.join(odir, frozen_c)
|
||||||
config_c = os.path.join(odir, config_c)
|
config_c = os.path.join(odir, config_c)
|
||||||
target = os.path.join(odir, target)
|
target = os.path.join(odir, target)
|
||||||
|
@ -323,21 +347,7 @@ def main():
|
||||||
dict = mf.modules
|
dict = mf.modules
|
||||||
|
|
||||||
# generate output for frozen modules
|
# generate output for frozen modules
|
||||||
backup = frozen_c + '~'
|
files = makefreeze.makefreeze(base, dict, debug, custom_entry_point)
|
||||||
try:
|
|
||||||
os.rename(frozen_c, backup)
|
|
||||||
except os.error:
|
|
||||||
backup = None
|
|
||||||
outfp = open(frozen_c, 'w')
|
|
||||||
try:
|
|
||||||
makefreeze.makefreeze(outfp, dict, debug, custom_entry_point)
|
|
||||||
finally:
|
|
||||||
outfp.close()
|
|
||||||
if backup:
|
|
||||||
if cmp.cmp(backup, frozen_c):
|
|
||||||
sys.stderr.write('%s not changed, not written\n' % frozen_c)
|
|
||||||
os.unlink(frozen_c)
|
|
||||||
os.rename(backup, frozen_c)
|
|
||||||
|
|
||||||
# look for unfrozen modules (builtin and of unknown origin)
|
# look for unfrozen modules (builtin and of unknown origin)
|
||||||
builtins = []
|
builtins = []
|
||||||
|
@ -387,7 +397,7 @@ def main():
|
||||||
frozen_extensions)
|
frozen_extensions)
|
||||||
# Create a module definition for the bootstrap C code.
|
# Create a module definition for the bootstrap C code.
|
||||||
xtras = [frozenmain_c, os.path.basename(frozen_c),
|
xtras = [frozenmain_c, os.path.basename(frozen_c),
|
||||||
frozendllmain_c, extensions_c]
|
frozendllmain_c, extensions_c] + files
|
||||||
maindefn = checkextensions_win32.CExtension( '__main__', xtras )
|
maindefn = checkextensions_win32.CExtension( '__main__', xtras )
|
||||||
frozen_extensions.append( maindefn )
|
frozen_extensions.append( maindefn )
|
||||||
outfp = open(makefile, 'w')
|
outfp = open(makefile, 'w')
|
||||||
|
@ -403,22 +413,12 @@ def main():
|
||||||
# generate config.c and Makefile
|
# generate config.c and Makefile
|
||||||
builtins.sort()
|
builtins.sort()
|
||||||
infp = open(config_c_in)
|
infp = open(config_c_in)
|
||||||
backup = config_c + '~'
|
outfp = bkfile.open(config_c, 'w')
|
||||||
try:
|
|
||||||
os.rename(config_c, backup)
|
|
||||||
except os.error:
|
|
||||||
backup = None
|
|
||||||
outfp = open(config_c, 'w')
|
|
||||||
try:
|
try:
|
||||||
makeconfig.makeconfig(infp, outfp, builtins)
|
makeconfig.makeconfig(infp, outfp, builtins)
|
||||||
finally:
|
finally:
|
||||||
outfp.close()
|
outfp.close()
|
||||||
infp.close()
|
infp.close()
|
||||||
if backup:
|
|
||||||
if cmp.cmp(backup, config_c):
|
|
||||||
sys.stderr.write('%s not changed, not written\n' % config_c)
|
|
||||||
os.unlink(config_c)
|
|
||||||
os.rename(backup, config_c)
|
|
||||||
|
|
||||||
cflags = defines + includes + ['$(OPT)']
|
cflags = defines + includes + ['$(OPT)']
|
||||||
libs = [os.path.join(binlib, 'libpython$(VERSION).a')]
|
libs = [os.path.join(binlib, 'libpython$(VERSION).a')]
|
||||||
|
@ -431,31 +431,14 @@ def main():
|
||||||
|
|
||||||
somevars['CFLAGS'] = string.join(cflags) # override
|
somevars['CFLAGS'] = string.join(cflags) # override
|
||||||
files = ['$(OPT)', '$(LDFLAGS)', base_config_c, base_frozen_c] + \
|
files = ['$(OPT)', '$(LDFLAGS)', base_config_c, base_frozen_c] + \
|
||||||
supp_sources + addfiles + libs + \
|
files + supp_sources + addfiles + libs + \
|
||||||
['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)']
|
['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)']
|
||||||
|
|
||||||
backup = makefile + '~'
|
outfp = bkfile.open(makefile, 'w')
|
||||||
if os.path.exists(makefile):
|
|
||||||
try:
|
|
||||||
os.unlink(backup)
|
|
||||||
except os.error:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
os.rename(makefile, backup)
|
|
||||||
except os.error:
|
|
||||||
backup = None
|
|
||||||
outfp = open(makefile, 'w')
|
|
||||||
try:
|
try:
|
||||||
makemakefile.makemakefile(outfp, somevars, files, base_target)
|
makemakefile.makemakefile(outfp, somevars, files, base_target)
|
||||||
finally:
|
finally:
|
||||||
outfp.close()
|
outfp.close()
|
||||||
if backup:
|
|
||||||
if not cmp.cmp(backup, makefile):
|
|
||||||
print 'previous Makefile saved as', backup
|
|
||||||
else:
|
|
||||||
sys.stderr.write('%s not changed, not written\n' % makefile)
|
|
||||||
os.unlink(makefile)
|
|
||||||
os.rename(backup, makefile)
|
|
||||||
|
|
||||||
# Done!
|
# Done!
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import marshal
|
import marshal
|
||||||
import string
|
import string
|
||||||
|
import bkfile
|
||||||
|
|
||||||
|
|
||||||
# Write a file containing frozen code for the modules in the dictionary.
|
# Write a file containing frozen code for the modules in the dictionary.
|
||||||
|
@ -30,15 +31,19 @@ main(argc, argv)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def makefreeze(outfp, dict, debug=0, entry_point = None):
|
def makefreeze(base, dict, debug=0, entry_point = None):
|
||||||
if entry_point is None: entry_point = default_entry_point
|
if entry_point is None: entry_point = default_entry_point
|
||||||
done = []
|
done = []
|
||||||
|
files = []
|
||||||
mods = dict.keys()
|
mods = dict.keys()
|
||||||
mods.sort()
|
mods.sort()
|
||||||
for mod in mods:
|
for mod in mods:
|
||||||
m = dict[mod]
|
m = dict[mod]
|
||||||
mangled = string.join(string.split(mod, "."), "__")
|
mangled = string.join(string.split(mod, "."), "__")
|
||||||
if m.__code__:
|
if m.__code__:
|
||||||
|
file = 'M_' + mangled + '.c'
|
||||||
|
outfp = bkfile.open(base + file, 'w')
|
||||||
|
files.append(file)
|
||||||
if debug:
|
if debug:
|
||||||
print "freezing", mod, "..."
|
print "freezing", mod, "..."
|
||||||
str = marshal.dumps(m.__code__)
|
str = marshal.dumps(m.__code__)
|
||||||
|
@ -48,13 +53,19 @@ def makefreeze(outfp, dict, debug=0, entry_point = None):
|
||||||
size = -size
|
size = -size
|
||||||
done.append((mod, mangled, size))
|
done.append((mod, mangled, size))
|
||||||
writecode(outfp, mangled, str)
|
writecode(outfp, mangled, str)
|
||||||
|
outfp.close()
|
||||||
if debug:
|
if debug:
|
||||||
print "generating table of frozen modules"
|
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)
|
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(trailer)
|
outfp.write(trailer)
|
||||||
outfp.write(entry_point)
|
outfp.write(entry_point)
|
||||||
|
outfp.close()
|
||||||
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,9 +73,13 @@ def makefreeze(outfp, dict, debug=0, entry_point = None):
|
||||||
# The array is called M_<mod>.
|
# The array is called M_<mod>.
|
||||||
|
|
||||||
def writecode(outfp, mod, str):
|
def writecode(outfp, mod, str):
|
||||||
outfp.write('static unsigned char M_%s[] = {' % mod)
|
outfp.write('unsigned char M_%s[] = {' % mod)
|
||||||
for i in range(0, len(str), 16):
|
for i in range(0, len(str), 16):
|
||||||
outfp.write('\n\t')
|
outfp.write('\n\t')
|
||||||
for c in str[i:i+16]:
|
for c in str[i:i+16]:
|
||||||
outfp.write('%d,' % ord(c))
|
outfp.write('%d,' % ord(c))
|
||||||
outfp.write('\n};\n')
|
outfp.write('\n};\n')
|
||||||
|
|
||||||
|
## def writecode(outfp, mod, str):
|
||||||
|
## outfp.write('unsigned char M_%s[%d] = "%s";\n' % (mod, len(str),
|
||||||
|
## string.join(map(lambda s: `s`[1:-1], string.split(str, '"')), '\\"')))
|
||||||
|
|
|
@ -359,14 +359,16 @@ class ModuleFinder:
|
||||||
keys = self.badmodules.keys()
|
keys = self.badmodules.keys()
|
||||||
keys.sort()
|
keys.sort()
|
||||||
for key in keys:
|
for key in keys:
|
||||||
print "?", key
|
# ... but not if they were explicitely excluded.
|
||||||
|
if key not in self.excludes:
|
||||||
|
print "?", key
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
# Parse command line
|
# Parse command line
|
||||||
import getopt
|
import getopt
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "dmp:q")
|
opts, args = getopt.getopt(sys.argv[1:], "dmp:qx:")
|
||||||
except getopt.error, msg:
|
except getopt.error, msg:
|
||||||
print msg
|
print msg
|
||||||
return
|
return
|
||||||
|
@ -375,6 +377,7 @@ def test():
|
||||||
debug = 1
|
debug = 1
|
||||||
domods = 0
|
domods = 0
|
||||||
addpath = []
|
addpath = []
|
||||||
|
exclude = []
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o == '-d':
|
if o == '-d':
|
||||||
debug = debug + 1
|
debug = debug + 1
|
||||||
|
@ -384,6 +387,8 @@ def test():
|
||||||
addpath = addpath + string.split(a, os.pathsep)
|
addpath = addpath + string.split(a, os.pathsep)
|
||||||
if o == '-q':
|
if o == '-q':
|
||||||
debug = 0
|
debug = 0
|
||||||
|
if o == '-x':
|
||||||
|
exclude.append(a)
|
||||||
|
|
||||||
# Provide default arguments
|
# Provide default arguments
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -401,7 +406,7 @@ def test():
|
||||||
print " ", `item`
|
print " ", `item`
|
||||||
|
|
||||||
# Create the module finder and turn its crank
|
# Create the module finder and turn its crank
|
||||||
mf = ModuleFinder(path, debug)
|
mf = ModuleFinder(path, debug, exclude)
|
||||||
for arg in args[1:]:
|
for arg in args[1:]:
|
||||||
if arg == '-m':
|
if arg == '-m':
|
||||||
domods = 1
|
domods = 1
|
||||||
|
|
|
@ -50,13 +50,29 @@ def makemakefile(outfp, vars, files, target):
|
||||||
sys.stdout = save
|
sys.stdout = save
|
||||||
|
|
||||||
def realwork(vars, moddefns, target):
|
def realwork(vars, moddefns, target):
|
||||||
print "# Makefile for Windows (NT or 95) generated by freeze.py script"
|
print "# Makefile for Microsoft Visual C++ generated by freeze.py script"
|
||||||
print
|
print
|
||||||
print 'target = %s' % target
|
print 'target = %s' % target
|
||||||
print 'pythonhome = "%s"' % vars['prefix']
|
print 'pythonhome = "%s"' % vars['prefix']
|
||||||
# XXX The following line is fishy and may need manual fixing
|
print
|
||||||
print 'pythonlib = "%s"' % (vars['exec_prefix'] +
|
print 'DEBUG=0 # Set to 1 to use the _d versions of Python.'
|
||||||
"/pcbuild/release/python15.lib")
|
print '!IF $(DEBUG)'
|
||||||
|
print 'debug_suffix=_d'
|
||||||
|
print 'c_debug=/Zi /Od /DDEBUG /D_DEBUG'
|
||||||
|
print 'l_debug=/DEBUG'
|
||||||
|
print 'temp_dir=Build\\Debug'
|
||||||
|
print '!ELSE'
|
||||||
|
print 'debug_suffix='
|
||||||
|
print 'c_debug=/Ox'
|
||||||
|
print 'l_debug='
|
||||||
|
print 'temp_dir=Build\\Release'
|
||||||
|
print '!ENDIF'
|
||||||
|
print
|
||||||
|
|
||||||
|
print '# The following line assumes you have built Python using the standard instructions'
|
||||||
|
print '# Otherwise fix the following line to point to the library.'
|
||||||
|
print 'pythonlib = "$(pythonhome)/pcbuild/python15$(debug_suffix).lib"'
|
||||||
|
print
|
||||||
|
|
||||||
# We only ever write one "entry point" symbol - either
|
# We only ever write one "entry point" symbol - either
|
||||||
# "main" or "WinMain". Therefore, there is no need to
|
# "main" or "WinMain". Therefore, there is no need to
|
||||||
|
@ -69,21 +85,27 @@ def realwork(vars, moddefns, target):
|
||||||
target_link_flags = "-dll"
|
target_link_flags = "-dll"
|
||||||
target_ext = ".dll"
|
target_ext = ".dll"
|
||||||
|
|
||||||
print "cdl = /MD" # XXX - Should this come from vars? User may have specific requirements...
|
|
||||||
|
print "# As the target uses Python15.dll, we must use this compiler option!"
|
||||||
|
print "cdl = /MD"
|
||||||
print
|
print
|
||||||
print "all: $(target)%s" % (target_ext)
|
print "all: $(target)$(debug_suffix)%s" % (target_ext)
|
||||||
|
print
|
||||||
|
|
||||||
|
print '$(temp_dir):'
|
||||||
|
print ' if not exist $(temp_dir)\. mkdir $(temp_dir)'
|
||||||
print
|
print
|
||||||
|
|
||||||
objects = []
|
objects = []
|
||||||
libs = ["shell32.lib", "comdlg32.lib", "wsock32.lib", "user32.lib"]
|
libs = ["shell32.lib", "comdlg32.lib", "wsock32.lib", "user32.lib", "oleaut32.lib"]
|
||||||
for moddefn in moddefns:
|
for moddefn in moddefns:
|
||||||
print "# Module", moddefn.name
|
print "# Module", moddefn.name
|
||||||
for file in moddefn.sourceFiles:
|
for file in moddefn.sourceFiles:
|
||||||
base = os.path.basename(file)
|
base = os.path.basename(file)
|
||||||
base, ext = os.path.splitext(base)
|
base, ext = os.path.splitext(base)
|
||||||
objects.append(base + ".obj")
|
objects.append(base + ".obj")
|
||||||
print '%s.obj: "%s"' % (base, file)
|
print '$(temp_dir)\%s.obj: "%s"' % (base, file)
|
||||||
print "\t@$(CC) -c -nologo $(cdl) /D BUILD_FREEZE",
|
print "\t@$(CC) -c -nologo /Fo$* $(cdl) $(c_debug) /D BUILD_FREEZE",
|
||||||
print "-I$(pythonhome)/Include -I$(pythonhome)/PC \\"
|
print "-I$(pythonhome)/Include -I$(pythonhome)/PC \\"
|
||||||
print "\t\t$(cflags) $(cdebug) $(cinclude) \\"
|
print "\t\t$(cflags) $(cdebug) $(cinclude) \\"
|
||||||
extra = moddefn.GetCompilerOptions()
|
extra = moddefn.GetCompilerOptions()
|
||||||
|
@ -102,20 +124,20 @@ def realwork(vars, moddefns, target):
|
||||||
print ; print
|
print ; print
|
||||||
|
|
||||||
print "OBJS=",
|
print "OBJS=",
|
||||||
for obj in objects: print '"%s"' % (obj),
|
for obj in objects: print '"$(temp_dir)\%s"' % (obj),
|
||||||
print ; print
|
print ; print
|
||||||
|
|
||||||
print "LIBS=",
|
print "LIBS=",
|
||||||
for lib in libs: print '"%s"' % (lib),
|
for lib in libs: print '"%s"' % (lib),
|
||||||
print ; print
|
print ; print
|
||||||
|
|
||||||
print "$(target)%s: $(OBJS)" % (target_ext)
|
print "$(target)$(debug_suffix)%s: $(temp_dir) $(OBJS)" % (target_ext)
|
||||||
print "\tlink -out:$(target)%s %s" % (target_ext, target_link_flags),
|
print "\tlink -out:$(target)$(debug_suffix)%s %s" % (target_ext, target_link_flags),
|
||||||
print "\t$(OBJS) \\"
|
print "\t$(OBJS) \\"
|
||||||
print "\t$(LIBS) \\"
|
print "\t$(LIBS) \\"
|
||||||
print "\t$(ADDN_LINK_FILES) \\"
|
print "\t$(ADDN_LINK_FILES) \\"
|
||||||
print "\t\t$(pythonlib) $(lcustom)\\"
|
print "\t$(pythonlib) $(lcustom) $(l_debug)\\"
|
||||||
print "\t\t$(resources)"
|
print "\t$(resources)"
|
||||||
print
|
print
|
||||||
print "clean:"
|
print "clean:"
|
||||||
print "\t-rm -f *.obj"
|
print "\t-rm -f *.obj"
|
||||||
|
|
Loading…
Reference in New Issue