build.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python3
  2. from collections import OrderedDict
  3. import json
  4. import os
  5. import sys
  6. dir_path = os.path.dirname(os.path.realpath(__file__))
  7. SENTINEL = "dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX"
  8. TEMPLATE_H = """
  9. #ifndef ELECTRON_FUSES_H_
  10. #define ELECTRON_FUSES_H_
  11. #if defined(WIN32)
  12. #define FUSE_EXPORT __declspec(dllexport)
  13. #else
  14. #define FUSE_EXPORT __attribute__((visibility("default")))
  15. #endif
  16. namespace electron::fuses {
  17. extern const volatile char kFuseWire[];
  18. {getters}
  19. } // namespace electron::fuses
  20. #endif // ELECTRON_FUSES_H_
  21. """
  22. TEMPLATE_CC = """
  23. #include "electron/fuses.h"
  24. #include "base/dcheck_is_on.h"
  25. #if DCHECK_IS_ON()
  26. #include "base/command_line.h"
  27. #include <string>
  28. #endif
  29. namespace electron::fuses {
  30. const volatile char kFuseWire[] = { /* sentinel */ {sentinel}, /* fuse_version */ {fuse_version}, /* fuse_wire_length */ {fuse_wire_length}, /* fuse_wire */ {initial_config}};
  31. {getters}
  32. } // namespace electron:fuses
  33. """
  34. with open(os.path.join(dir_path, "fuses.json5"), 'r') as f:
  35. fuse_defaults = json.loads(''.join(line for line in f.readlines() if not line.strip()[0] == "/"), object_pairs_hook=OrderedDict)
  36. fuse_version = fuse_defaults['_version']
  37. del fuse_defaults['_version']
  38. del fuse_defaults['_schema']
  39. del fuse_defaults['_comment']
  40. if fuse_version >= pow(2, 8):
  41. raise Exception("Fuse version can not exceed one byte in size")
  42. fuses = fuse_defaults.keys()
  43. initial_config = ""
  44. getters_h = ""
  45. getters_cc = ""
  46. index = len(SENTINEL) + 1
  47. for fuse in fuses:
  48. index += 1
  49. initial_config += fuse_defaults[fuse]
  50. name = ''.join(word.title() for word in fuse.split('_'))
  51. getters_h += "FUSE_EXPORT bool Is{name}Enabled();\n".replace("{name}", name)
  52. getters_cc += """
  53. bool Is{name}Enabled() {
  54. #if DCHECK_IS_ON()
  55. // RunAsNode is checked so early that base::CommandLine isn't yet
  56. // initialized, so guard here to avoid a CHECK.
  57. if (base::CommandLine::InitializedForCurrentProcess()) {
  58. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  59. if (command_line->HasSwitch("{switch_name}")) {
  60. std::string switch_value = command_line->GetSwitchValueASCII("{switch_name}");
  61. return switch_value == "1";
  62. }
  63. }
  64. #endif
  65. return kFuseWire[{index}] == '1';
  66. }
  67. """.replace("{name}", name).replace("{switch_name}", f"set-fuse-{fuse.lower()}").replace("{index}", str(index))
  68. def c_hex(n):
  69. s = hex(n)[2:]
  70. return "0x" + s.rjust(2, '0')
  71. def hex_arr(s):
  72. arr = []
  73. for char in s:
  74. arr.append(c_hex(ord(char)))
  75. return ",".join(arr)
  76. header = TEMPLATE_H.replace("{getters}", getters_h.strip())
  77. impl = TEMPLATE_CC.replace("{sentinel}", hex_arr(SENTINEL))
  78. impl = impl.replace("{fuse_version}", c_hex(fuse_version))
  79. impl = impl.replace("{fuse_wire_length}", c_hex(len(fuses)))
  80. impl = impl.replace("{initial_config}", hex_arr(initial_config))
  81. impl = impl.replace("{getters}", getters_cc.strip())
  82. with open(sys.argv[1], 'w') as f:
  83. f.write(header)
  84. with open(sys.argv[2], 'w') as f:
  85. f.write(impl)