bootstrap.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import os
  2. import sys
  3. _SOURCE_ROOT = None
  4. def truncate_path(path):
  5. path = os.path.normpath(path)
  6. if _SOURCE_ROOT and path.startswith(_SOURCE_ROOT):
  7. return os.path.relpath(path, _SOURCE_ROOT)
  8. return os.path.basename(path)
  9. def module_load(name, path = None):
  10. import imp
  11. module_name = name
  12. module_dot = name.find(".")
  13. if module_dot >= 0:
  14. module_name = module_name[:module_dot]
  15. fileobject, pathname, description = imp.find_module(module_name, path and [path])
  16. if os.path.isdir(pathname):
  17. pathname = os.path.join(pathname, "")
  18. if module_dot >= 0:
  19. return module_load(name[module_dot + 1:], pathname)
  20. return module_load("__init__", pathname)
  21. return pathname, fileobject, name == "__init__"
  22. def list_modules():
  23. import pydoc
  24. modules = []
  25. def module_callback(path, name, description):
  26. modules.append(name)
  27. module_scanner = pydoc.ModuleScanner()
  28. module_scanner.run(module_callback)
  29. return modules
  30. def make_path_directories(path):
  31. path_directory = os.path.dirname(path)
  32. if not os.path.exists(path_directory):
  33. os.makedirs(path_directory)
  34. return path
  35. def module_blob_compile(module_file, module_path):
  36. import marshal
  37. module_code = compile(module_file.read(), truncate_path(module_path), "exec")
  38. return marshal.dumps(module_code)
  39. def module_blob_write(module_blob, module_blob_name, module_blob_file):
  40. if EXTERN:
  41. if _SOURCE_ROOT and _SOURCE_ROOT in module_blob:
  42. raise Exception('Unable to add module %s because the blob contains the source root %s' % (module_blob_name, _SOURCE_ROOT))
  43. if os.getcwd() in module_blob:
  44. raise Exception('Unable to add module %s because the blob contains the build root %s' % (module_blob_name, os.getcwd()))
  45. module_blob_file.write(module_blob)
  46. return
  47. module_blob_file.write(STATIC + "unsigned char %s[] = {" % module_blob_name)
  48. for module_blob_byte in module_blob:
  49. module_blob_file.write("%d," % ord(module_blob_byte))
  50. module_blob_file.write("};\n\n")
  51. def module_table_write(module_blobs, module_table_file):
  52. if EXTERN:
  53. off = 0
  54. module_table_file.write('extern unsigned char %s[];\n\n' % EXTERN)
  55. for module_name, module_blob_name, module_blob_size in module_blobs:
  56. if module_blob_size < 0:
  57. module_blob_size = -module_blob_size
  58. module_table_file.write("#define %s (%s + %d)\n" % (module_blob_name, EXTERN, off))
  59. off += module_blob_size
  60. module_table_file.write("""\n#include "Python.h"\n""")
  61. module_table_file.write("\nstatic struct _frozen _PyImport_FrozenModules[] = {\n")
  62. for module_name, module_blob_name, module_blob_size in module_blobs:
  63. module_table_file.write("""\t{"%s", %s, %d},\n""" % (module_name, module_blob_name, module_blob_size))
  64. module_table_file.write("\t{0, 0, 0}\n};\n")
  65. module_table_file.write("\nstruct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;\n")
  66. def load_module_list(module_list_path):
  67. return [line.strip() for line in open(module_list_path)]
  68. if len(sys.argv) == 4:
  69. module_blob_path = make_path_directories(sys.argv[1])
  70. module_table_path = make_path_directories(sys.argv[2])
  71. modules_enabled = load_module_list(sys.argv[3])
  72. mode2 = 'w'
  73. STATIC = ''
  74. EXTERN = os.path.basename(module_blob_path)[:-7]
  75. else:
  76. module_blob_path = make_path_directories(sys.argv[1])
  77. module_table_path = make_path_directories(sys.argv[1])
  78. modules_enabled = load_module_list(sys.argv[2])
  79. mode2 = 'a'
  80. STATIC = 'static '
  81. EXTERN = False
  82. #modules = list_modules()
  83. if 'ARCADIA_ROOT_DISTBUILD' in os.environ:
  84. _SOURCE_ROOT = os.path.normpath(os.environ['ARCADIA_ROOT_DISTBUILD'])
  85. module_blobs = []
  86. with open(module_blob_path, "wb") as module_blob_file:
  87. for module_name in modules_enabled:
  88. #if module_name not in modules: continue
  89. try:
  90. module_path, module_file, module_is_package = module_load(module_name)
  91. except ImportError as e:
  92. print e
  93. continue
  94. if module_file and module_path != __file__:
  95. module_blob_name = "M_" + "__".join(module_name.split("."))
  96. module_blob = module_blob_compile(module_file, module_path)
  97. module_blob_write(module_blob, module_blob_name, module_blob_file)
  98. module_blob_size = len(module_blob)
  99. if module_is_package:
  100. module_blob_size = -module_blob_size
  101. module_blobs.append((module_name, module_blob_name, module_blob_size))
  102. with open(module_table_path, mode2) as module_table_file:
  103. module_table_write(module_blobs, module_table_file)