]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | import marshal\r |
2 | import bkfile\r | |
3 | \r | |
4 | \r | |
5 | # Write a file containing frozen code for the modules in the dictionary.\r | |
6 | \r | |
7 | header = """\r | |
8 | #include "Python.h"\r | |
9 | \r | |
10 | static struct _frozen _PyImport_FrozenModules[] = {\r | |
11 | """\r | |
12 | trailer = """\\r | |
13 | {0, 0, 0} /* sentinel */\r | |
14 | };\r | |
15 | """\r | |
16 | \r | |
17 | # if __debug__ == 0 (i.e. -O option given), set Py_OptimizeFlag in frozen app.\r | |
18 | default_entry_point = """\r | |
19 | int\r | |
20 | main(int argc, char **argv)\r | |
21 | {\r | |
22 | extern int Py_FrozenMain(int, char **);\r | |
23 | """ + ((not __debug__ and """\r | |
24 | Py_OptimizeFlag++;\r | |
25 | """) or "") + """\r | |
26 | PyImport_FrozenModules = _PyImport_FrozenModules;\r | |
27 | return Py_FrozenMain(argc, argv);\r | |
28 | }\r | |
29 | \r | |
30 | """\r | |
31 | \r | |
32 | def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()):\r | |
33 | if entry_point is None: entry_point = default_entry_point\r | |
34 | done = []\r | |
35 | files = []\r | |
36 | mods = dict.keys()\r | |
37 | mods.sort()\r | |
38 | for mod in mods:\r | |
39 | m = dict[mod]\r | |
40 | mangled = "__".join(mod.split("."))\r | |
41 | if m.__code__:\r | |
42 | file = 'M_' + mangled + '.c'\r | |
43 | outfp = bkfile.open(base + file, 'w')\r | |
44 | files.append(file)\r | |
45 | if debug:\r | |
46 | print "freezing", mod, "..."\r | |
47 | str = marshal.dumps(m.__code__)\r | |
48 | size = len(str)\r | |
49 | if m.__path__:\r | |
50 | # Indicate package by negative size\r | |
51 | size = -size\r | |
52 | done.append((mod, mangled, size))\r | |
53 | writecode(outfp, mangled, str)\r | |
54 | outfp.close()\r | |
55 | if debug:\r | |
56 | print "generating table of frozen modules"\r | |
57 | outfp = bkfile.open(base + 'frozen.c', 'w')\r | |
58 | for mod, mangled, size in done:\r | |
59 | outfp.write('extern unsigned char M_%s[];\n' % mangled)\r | |
60 | outfp.write(header)\r | |
61 | for mod, mangled, size in done:\r | |
62 | outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size))\r | |
63 | outfp.write('\n')\r | |
64 | # The following modules have a NULL code pointer, indicating\r | |
65 | # that the prozen program should not search for them on the host\r | |
66 | # system. Importing them will *always* raise an ImportError.\r | |
67 | # The zero value size is never used.\r | |
68 | for mod in fail_import:\r | |
69 | outfp.write('\t{"%s", NULL, 0},\n' % (mod,))\r | |
70 | outfp.write(trailer)\r | |
71 | outfp.write(entry_point)\r | |
72 | outfp.close()\r | |
73 | return files\r | |
74 | \r | |
75 | \r | |
76 | \r | |
77 | # Write a C initializer for a module containing the frozen python code.\r | |
78 | # The array is called M_<mod>.\r | |
79 | \r | |
80 | def writecode(outfp, mod, str):\r | |
81 | outfp.write('unsigned char M_%s[] = {' % mod)\r | |
82 | for i in range(0, len(str), 16):\r | |
83 | outfp.write('\n\t')\r | |
84 | for c in str[i:i+16]:\r | |
85 | outfp.write('%d,' % ord(c))\r | |
86 | outfp.write('\n};\n')\r | |
87 | \r | |
88 | ## def writecode(outfp, mod, str):\r | |
89 | ## outfp.write('unsigned char M_%s[%d] = "%s";\n' % (mod, len(str),\r | |
90 | ## '\\"'.join(map(lambda s: repr(s)[1:-1], str.split('"')))))\r |