blob: b7bf9fda4e73e97e5649eb69eeff8996f450917e [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{
Tim Petersdbd9ba62000-07-09 03:09:57 +000025 extern int Py_FrozenMain(int, char **);
Guido van Rossum1abfb9c1998-04-23 14:39:05 +000026""" + ((not __debug__ and """
27 Py_OptimizeFlag++;
28""") or "") + """
Guido van Rossum912a14c1998-03-05 04:56:37 +000029 PyImport_FrozenModules = _PyImport_FrozenModules;
30 return Py_FrozenMain(argc, argv);
Guido van Rossumb3afce51997-07-19 21:58:30 +000031}
32
Guido van Rossum00ff4331994-10-03 16:33:08 +000033"""
34
Guido van Rossumbaf06031998-08-25 14:06:55 +000035def makefreeze(base, dict, debug=0, entry_point = None):
Guido van Rossum78fc3631998-03-20 17:37:24 +000036 if entry_point is None: entry_point = default_entry_point
Guido van Rossum912a14c1998-03-05 04:56:37 +000037 done = []
Guido van Rossumbaf06031998-08-25 14:06:55 +000038 files = []
Guido van Rossum912a14c1998-03-05 04:56:37 +000039 mods = dict.keys()
40 mods.sort()
41 for mod in mods:
42 m = dict[mod]
43 mangled = string.join(string.split(mod, "."), "__")
44 if m.__code__:
Guido van Rossumbaf06031998-08-25 14:06:55 +000045 file = 'M_' + mangled + '.c'
46 outfp = bkfile.open(base + file, 'w')
47 files.append(file)
Guido van Rossum912a14c1998-03-05 04:56:37 +000048 if debug:
49 print "freezing", mod, "..."
50 str = marshal.dumps(m.__code__)
51 size = len(str)
52 if m.__path__:
53 # Indicate package by negative size
54 size = -size
55 done.append((mod, mangled, size))
56 writecode(outfp, mangled, str)
Guido van Rossumbaf06031998-08-25 14:06:55 +000057 outfp.close()
Guido van Rossum912a14c1998-03-05 04:56:37 +000058 if debug:
59 print "generating table of frozen modules"
Guido van Rossumbaf06031998-08-25 14:06:55 +000060 outfp = bkfile.open(base + 'frozen.c', 'w')
61 for mod, mangled, size in done:
62 outfp.write('extern unsigned char M_%s[];\n' % mangled)
Guido van Rossum912a14c1998-03-05 04:56:37 +000063 outfp.write(header)
64 for mod, mangled, size in done:
65 outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size))
66 outfp.write(trailer)
Guido van Rossum78fc3631998-03-20 17:37:24 +000067 outfp.write(entry_point)
Guido van Rossumbaf06031998-08-25 14:06:55 +000068 outfp.close()
69 return files
Guido van Rossum78fc3631998-03-20 17:37:24 +000070
Guido van Rossum00ff4331994-10-03 16:33:08 +000071
72
Guido van Rossum00ff4331994-10-03 16:33:08 +000073# Write a C initializer for a module containing the frozen python code.
74# The array is called M_<mod>.
75
76def writecode(outfp, mod, str):
Guido van Rossumbaf06031998-08-25 14:06:55 +000077 outfp.write('unsigned char M_%s[] = {' % mod)
Guido van Rossum912a14c1998-03-05 04:56:37 +000078 for i in range(0, len(str), 16):
79 outfp.write('\n\t')
80 for c in str[i:i+16]:
81 outfp.write('%d,' % ord(c))
82 outfp.write('\n};\n')
Guido van Rossumbaf06031998-08-25 14:06:55 +000083
84## def writecode(outfp, mod, str):
85## outfp.write('unsigned char M_%s[%d] = "%s";\n' % (mod, len(str),
86## string.join(map(lambda s: `s`[1:-1], string.split(str, '"')), '\\"')))