blob: 38880501124e63611e76f5ed15e28407dd869970 [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
Marc-André Lemburg64b4f272002-04-04 16:15:41 +000021main(int argc, char **argv)
Guido van Rossumb3afce51997-07-19 21:58:30 +000022{
Tim Petersdbd9ba62000-07-09 03:09:57 +000023 extern int Py_FrozenMain(int, char **);
Guido van Rossum1abfb9c1998-04-23 14:39:05 +000024""" + ((not __debug__ and """
25 Py_OptimizeFlag++;
26""") or "") + """
Guido van Rossum912a14c1998-03-05 04:56:37 +000027 PyImport_FrozenModules = _PyImport_FrozenModules;
28 return Py_FrozenMain(argc, argv);
Guido van Rossumb3afce51997-07-19 21:58:30 +000029}
30
Guido van Rossum00ff4331994-10-03 16:33:08 +000031"""
32
Guido van Rossum03f7f082001-10-18 19:15:32 +000033def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()):
Guido van Rossum78fc3631998-03-20 17:37:24 +000034 if entry_point is None: entry_point = default_entry_point
Guido van Rossum912a14c1998-03-05 04:56:37 +000035 done = []
Guido van Rossumbaf06031998-08-25 14:06:55 +000036 files = []
Guido van Rossum912a14c1998-03-05 04:56:37 +000037 mods = dict.keys()
38 mods.sort()
39 for mod in mods:
40 m = dict[mod]
41 mangled = string.join(string.split(mod, "."), "__")
42 if m.__code__:
Guido van Rossumbaf06031998-08-25 14:06:55 +000043 file = 'M_' + mangled + '.c'
44 outfp = bkfile.open(base + file, 'w')
45 files.append(file)
Guido van Rossum912a14c1998-03-05 04:56:37 +000046 if debug:
47 print "freezing", mod, "..."
48 str = marshal.dumps(m.__code__)
49 size = len(str)
50 if m.__path__:
51 # Indicate package by negative size
52 size = -size
53 done.append((mod, mangled, size))
54 writecode(outfp, mangled, str)
Guido van Rossumbaf06031998-08-25 14:06:55 +000055 outfp.close()
Guido van Rossum912a14c1998-03-05 04:56:37 +000056 if debug:
57 print "generating table of frozen modules"
Guido van Rossumbaf06031998-08-25 14:06:55 +000058 outfp = bkfile.open(base + 'frozen.c', 'w')
59 for mod, mangled, size in done:
60 outfp.write('extern unsigned char M_%s[];\n' % mangled)
Guido van Rossum912a14c1998-03-05 04:56:37 +000061 outfp.write(header)
62 for mod, mangled, size in done:
63 outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size))
Guido van Rossum03f7f082001-10-18 19:15:32 +000064 outfp.write('\n')
65 # The following modules have a NULL code pointer, indicating
66 # that the prozen program should not search for them on the host
67 # system. Importing them will *always* raise an ImportError.
68 # The zero value size is never used.
69 for mod in fail_import:
70 outfp.write('\t{"%s", NULL, 0},\n' % (mod,))
Guido van Rossum912a14c1998-03-05 04:56:37 +000071 outfp.write(trailer)
Guido van Rossum78fc3631998-03-20 17:37:24 +000072 outfp.write(entry_point)
Guido van Rossumbaf06031998-08-25 14:06:55 +000073 outfp.close()
74 return files
Guido van Rossum78fc3631998-03-20 17:37:24 +000075
Guido van Rossum00ff4331994-10-03 16:33:08 +000076
77
Guido van Rossum00ff4331994-10-03 16:33:08 +000078# Write a C initializer for a module containing the frozen python code.
79# The array is called M_<mod>.
80
81def writecode(outfp, mod, str):
Guido van Rossumbaf06031998-08-25 14:06:55 +000082 outfp.write('unsigned char M_%s[] = {' % mod)
Guido van Rossum912a14c1998-03-05 04:56:37 +000083 for i in range(0, len(str), 16):
84 outfp.write('\n\t')
85 for c in str[i:i+16]:
86 outfp.write('%d,' % ord(c))
87 outfp.write('\n};\n')
Guido van Rossumbaf06031998-08-25 14:06:55 +000088
89## def writecode(outfp, mod, str):
90## outfp.write('unsigned char M_%s[%d] = "%s";\n' % (mod, len(str),
91## string.join(map(lambda s: `s`[1:-1], string.split(str, '"')), '\\"')))