generate_node_headers.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/usr/bin/env python3
  2. import json
  3. import os
  4. import sys
  5. import shutil
  6. from pathlib import Path
  7. SRC_DIR = Path(__file__).resolve().parents[3]
  8. sys.path.append(os.path.join(SRC_DIR, 'third_party/electron_node/tools'))
  9. import install
  10. class LoadPythonDictionaryError(Exception):
  11. """Custom exception for errors in LoadPythonDictionary."""
  12. def LoadPythonDictionary(path):
  13. with open(path, 'r', encoding='utf-8') as f:
  14. file_string = f.read()
  15. try:
  16. file_data = eval(file_string, {'__builtins__': None}, None)
  17. except SyntaxError as e:
  18. e.filename = path
  19. raise
  20. except Exception as e:
  21. err_msg = f"Unexpected error while reading {path}: {str(e)}"
  22. raise LoadPythonDictionaryError(err_msg) from e
  23. if not isinstance(file_data, dict):
  24. raise LoadPythonDictionaryError(
  25. f"{path} does not eval to a dictionary"
  26. )
  27. return file_data
  28. def get_out_dir():
  29. out_dir = 'Testing'
  30. override = os.environ.get('ELECTRON_OUT_DIR')
  31. if override is not None:
  32. out_dir = override
  33. return os.path.join(SRC_DIR, 'out', out_dir)
  34. if __name__ == '__main__':
  35. node_root_dir = os.path.join(SRC_DIR, 'third_party/electron_node')
  36. out = {}
  37. out['headers'] = []
  38. def add_headers(_, files, dest_dir):
  39. if 'src/node.h' in files:
  40. files = [
  41. f for f in files
  42. if f.endswith('.h') and f != 'src/node_version.h'
  43. ]
  44. if files:
  45. dir_index = next(
  46. (i for i, d in enumerate(out['headers'])
  47. if d['dest_dir'] == dest_dir),
  48. -1
  49. )
  50. if dir_index != -1:
  51. out['headers'][dir_index]['files'] += sorted(files)
  52. else:
  53. hs = {'files': sorted(files), 'dest_dir': dest_dir}
  54. out['headers'].append(hs)
  55. root_gen_dir = os.path.join(get_out_dir(), 'gen')
  56. config_gypi_path = os.path.join(root_gen_dir, 'config.gypi')
  57. node_headers_dir = os.path.join(root_gen_dir, 'node_headers')
  58. options = install.parse_options([
  59. 'install',
  60. '--root-dir', node_root_dir,
  61. '--v8-dir', os.path.join(SRC_DIR, 'v8'),
  62. '--config-gypi-path', config_gypi_path,
  63. '--headers-only'
  64. ])
  65. options.variables['node_use_openssl'] = 'false'
  66. options.variables['node_shared_libuv'] = 'false'
  67. # We generate zlib headers in Electron's BUILD.gn.
  68. options.variables['node_shared_zlib'] = ''
  69. install.headers(options, add_headers)
  70. header_groups = []
  71. for header_group in out['headers']:
  72. sources = [
  73. os.path.join(node_root_dir, file)
  74. for file in header_group['files']
  75. ]
  76. outputs = [
  77. os.path.join(
  78. node_headers_dir, header_group['dest_dir'],
  79. os.path.basename(file)
  80. )
  81. for file in sources
  82. ]
  83. for src, dest in zip(sources, outputs):
  84. os.makedirs(os.path.dirname(dest), exist_ok=True)
  85. if os.path.exists(dest):
  86. if os.path.samefile(src, dest):
  87. continue
  88. os.remove(dest)
  89. shutil.copyfile(src, dest)
  90. node_header_file = os.path.join(root_gen_dir, 'node_headers.json')
  91. with open(node_header_file, 'w', encoding='utf-8') as nhf:
  92. json_data = json.dumps(
  93. out, sort_keys=True, indent=2, separators=(',', ': ')
  94. )
  95. nhf.write(json_data)