blob: 4ea1905b10260d316c9d01bdb21825a158fe678e [file] [log] [blame]
Guido van Rossum00ff4331994-10-03 16:33:08 +00001import marshal
Guido van Rossum75dc4961998-03-05 03:42:00 +00002import string
Guido van Rossumbaf06031998-08-25 14:06:55 +00003import bkfile
Guido van Rossum00ff4331994-10-03 16:33:08 +00004
5
6# Write a file containing frozen code for the modules in the dictionary.
7
8header = """
Guido van Rossumf75f80e1996-06-17 17:48:30 +00009#include "Python.h"
10
11static struct _frozen _PyImport_FrozenModules[] = {
Guido van Rossum00ff4331994-10-03 16:33:08 +000012"""
13trailer = """\
Guido van Rossum912a14c1998-03-05 04:56:37 +000014 {0, 0, 0} /* sentinel */
Guido van Rossum00ff4331994-10-03 16:33:08 +000015};
Guido van Rossum78fc3631998-03-20 17:37:24 +000016"""
Guido van Rossumf75f80e1996-06-17 17:48:30 +000017
Guido van Rossum1abfb9c1998-04-23 14:39:05 +000018# if __debug__ == 0 (i.e. -O option given), set Py_OptimizeFlag in frozen app.
Guido van Rossum78fc3631998-03-20 17:37:24 +000019default_entry_point = """
Guido van Rossumb3afce51997-07-19 21:58:30 +000020int
21main(argc, argv)
Guido van Rossum912a14c1998-03-05 04:56:37 +000022 int argc;
23 char **argv;
Guido van Rossumb3afce51997-07-19 21:58:30 +000024{
Guido van Rossum1abfb9c1998-04-23 14:39:05 +000025""" + ((not __debug__ and """
26 Py_OptimizeFlag++;
27""") or "") + """
Guido van Rossum912a14c1998-03-05 04:56:37 +000028 PyImport_FrozenModules = _PyImport_FrozenModules;
29 return Py_FrozenMain(argc, argv);
Guido van Rossumb3afce51997-07-19 21:58:30 +000030}
31
Guido van Rossum00ff4331994-10-03 16:33:08 +000032"""
33
Guido van Rossumbaf06031998-08-25 14:06:55 +000034def makefreeze(base, dict, debug=0, entry_point = None):
Guido van Rossum78fc3631998-03-20 17:37:24 +000035 if entry_point is None: entry_point = default_entry_point
Guido van Rossum912a14c1998-03-05 04:56:37 +000036 done = []
Guido van Rossumbaf06031998-08-25 14:06:55 +000037 files = []
Guido van Rossum912a14c1998-03-05 04:56:37 +000038 mods = dict.keys()
39 mods.sort()
40 for mod in mods:
41 m = dict[mod]
42 mangled = string.join(string.split(mod, "."), "__")
43 if m.__code__:
Guido van Rossumbaf06031998-08-25 14:06:55 +000044 file = 'M_' + mangled + '.c'
45 outfp = bkfile.open(base + file, 'w')
46 files.append(file)
Guido van Rossum912a14c1998-03-05 04:56:37 +000047 if debug:
48 print "freezing", mod, "..."
49 str = marshal.dumps(m.__code__)
50 size = len(str)
51 if m.__path__:
52 # Indicate package by negative size
53 size = -size
54 done.append((mod, mangled, size))
55 writecode(outfp, mangled, str)
Guido van Rossumbaf06031998-08-25 14:06:55 +000056 outfp.close()
Guido van Rossum912a14c1998-03-05 04:56:37 +000057 if debug:
58 print "generating table of frozen modules"
Guido van Rossumbaf06031998-08-25 14:06:55 +000059 outfp = bkfile.open(base + 'frozen.c', 'w')
60 for mod, mangled, size in done:
61 outfp.write('extern unsigned char M_%s[];\n' % mangled)
Guido van Rossum912a14c1998-03-05 04:56:37 +000062 outfp.write(header)
63 for mod, mangled, size in done:
64 outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size))
65 outfp.write(trailer)
Guido van Rossum78fc3631998-03-20 17:37:24 +000066 outfp.write(entry_point)
Guido van Rossumbaf06031998-08-25 14:06:55 +000067 outfp.close()
68 return files
Guido van Rossum78fc3631998-03-20 17:37:24 +000069
Guido van Rossum00ff4331994-10-03 16:33:08 +000070
71
Guido van Rossum00ff4331994-10-03 16:33:08 +000072# Write a C initializer for a module containing the frozen python code.
73# The array is called M_<mod>.
74
75def writecode(outfp, mod, str):
Guido van Rossumbaf06031998-08-25 14:06:55 +000076 outfp.write('unsigned char M_%s[] = {' % mod)
Guido van Rossum912a14c1998-03-05 04:56:37 +000077 for i in range(0, len(str), 16):
78 outfp.write('\n\t')
79 for c in str[i:i+16]:
80 outfp.write('%d,' % ord(c))
81 outfp.write('\n};\n')
Guido van Rossumbaf06031998-08-25 14:06:55 +000082
83## def writecode(outfp, mod, str):
84## outfp.write('unsigned char M_%s[%d] = "%s";\n' % (mod, len(str),
85## string.join(map(lambda s: `s`[1:-1], string.split(str, '"')), '\\"')))