17db96d56Sopenharmony_ciimport marshal 27db96d56Sopenharmony_ciimport bkfile 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci# Write a file containing frozen code for the modules in the dictionary. 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ciheader = """ 87db96d56Sopenharmony_ci#include "Python.h" 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_cistatic struct _frozen _PyImport_FrozenModules[] = { 117db96d56Sopenharmony_ci""" 127db96d56Sopenharmony_citrailer = """\ 137db96d56Sopenharmony_ci {0, 0, 0} /* sentinel */ 147db96d56Sopenharmony_ci}; 157db96d56Sopenharmony_ci""" 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci# if __debug__ == 0 (i.e. -O option given), set Py_OptimizeFlag in frozen app. 187db96d56Sopenharmony_cidefault_entry_point = """ 197db96d56Sopenharmony_ciint 207db96d56Sopenharmony_cimain(int argc, char **argv) 217db96d56Sopenharmony_ci{ 227db96d56Sopenharmony_ci extern int Py_FrozenMain(int, char **); 237db96d56Sopenharmony_ci""" + ((not __debug__ and """ 247db96d56Sopenharmony_ci Py_OptimizeFlag++; 257db96d56Sopenharmony_ci""") or "") + """ 267db96d56Sopenharmony_ci PyImport_FrozenModules = _PyImport_FrozenModules; 277db96d56Sopenharmony_ci return Py_FrozenMain(argc, argv); 287db96d56Sopenharmony_ci} 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci""" 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_cidef makefreeze(base, dict, debug=0, entry_point=None, fail_import=()): 337db96d56Sopenharmony_ci if entry_point is None: entry_point = default_entry_point 347db96d56Sopenharmony_ci done = [] 357db96d56Sopenharmony_ci files = [] 367db96d56Sopenharmony_ci mods = sorted(dict.keys()) 377db96d56Sopenharmony_ci for mod in mods: 387db96d56Sopenharmony_ci m = dict[mod] 397db96d56Sopenharmony_ci mangled = "__".join(mod.split(".")) 407db96d56Sopenharmony_ci if m.__code__: 417db96d56Sopenharmony_ci file = 'M_' + mangled + '.c' 427db96d56Sopenharmony_ci with bkfile.open(base + file, 'w') as outfp: 437db96d56Sopenharmony_ci files.append(file) 447db96d56Sopenharmony_ci if debug: 457db96d56Sopenharmony_ci print("freezing", mod, "...") 467db96d56Sopenharmony_ci str = marshal.dumps(m.__code__) 477db96d56Sopenharmony_ci size = len(str) 487db96d56Sopenharmony_ci is_package = '0' 497db96d56Sopenharmony_ci if m.__path__: 507db96d56Sopenharmony_ci is_package = '1' 517db96d56Sopenharmony_ci done.append((mod, mangled, size, is_package)) 527db96d56Sopenharmony_ci writecode(outfp, mangled, str) 537db96d56Sopenharmony_ci if debug: 547db96d56Sopenharmony_ci print("generating table of frozen modules") 557db96d56Sopenharmony_ci with bkfile.open(base + 'frozen.c', 'w') as outfp: 567db96d56Sopenharmony_ci for mod, mangled, size, _ in done: 577db96d56Sopenharmony_ci outfp.write('extern unsigned char M_%s[];\n' % mangled) 587db96d56Sopenharmony_ci outfp.write(header) 597db96d56Sopenharmony_ci for mod, mangled, size, is_package in done: 607db96d56Sopenharmony_ci outfp.write('\t{"%s", M_%s, %d, %s},\n' % (mod, mangled, size, is_package)) 617db96d56Sopenharmony_ci outfp.write('\n') 627db96d56Sopenharmony_ci # The following modules have a NULL code pointer, indicating 637db96d56Sopenharmony_ci # that the frozen program should not search for them on the host 647db96d56Sopenharmony_ci # system. Importing them will *always* raise an ImportError. 657db96d56Sopenharmony_ci # The zero value size is never used. 667db96d56Sopenharmony_ci for mod in fail_import: 677db96d56Sopenharmony_ci outfp.write('\t{"%s", NULL, 0},\n' % (mod,)) 687db96d56Sopenharmony_ci outfp.write(trailer) 697db96d56Sopenharmony_ci outfp.write(entry_point) 707db96d56Sopenharmony_ci return files 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci# Write a C initializer for a module containing the frozen python code. 757db96d56Sopenharmony_ci# The array is called M_<mod>. 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_cidef writecode(fp, mod, data): 787db96d56Sopenharmony_ci print('unsigned char M_%s[] = {' % mod, file=fp) 797db96d56Sopenharmony_ci indent = ' ' * 4 807db96d56Sopenharmony_ci for i in range(0, len(data), 16): 817db96d56Sopenharmony_ci print(indent, file=fp, end='') 827db96d56Sopenharmony_ci for c in bytes(data[i:i+16]): 837db96d56Sopenharmony_ci print('%d,' % c, file=fp, end='') 847db96d56Sopenharmony_ci print('', file=fp) 857db96d56Sopenharmony_ci print('};', file=fp) 86