build.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 "base/strings/string_util.h"
  28. #include <string>
  29. #endif
  30. namespace electron::fuses {
  31. const volatile char kFuseWire[] = { /* sentinel */ {sentinel}, /* fuse_version */ {fuse_version}, /* fuse_wire_length */ {fuse_wire_length}, /* fuse_wire */ {initial_config}};
  32. {getters}
  33. } // namespace electron:fuses
  34. """
  35. with open(os.path.join(dir_path, "fuses.json5"), 'r') as f:
  36. fuse_defaults = json.loads(''.join(line for line in f.readlines() if not line.strip()[0] == "/"), object_pairs_hook=OrderedDict)
  37. fuse_version = fuse_defaults['_version']
  38. del fuse_defaults['_version']
  39. del fuse_defaults['_schema']
  40. del fuse_defaults['_comment']
  41. if fuse_version >= pow(2, 8):
  42. raise Exception("Fuse version can not exceed one byte in size")
  43. fuses = fuse_defaults.keys()
  44. initial_config = ""
  45. getters_h = ""
  46. getters_cc = ""
  47. index = len(SENTINEL) + 1
  48. for fuse in fuses:
  49. index += 1
  50. initial_config += fuse_defaults[fuse]
  51. name = ''.join(word.title() for word in fuse.split('_'))
  52. getters_h += "FUSE_EXPORT bool Is{name}Enabled();\n".replace("{name}", name)
  53. getters_cc += """
  54. bool Is{name}Enabled() {
  55. #if DCHECK_IS_ON()
  56. // RunAsNode is checked so early that base::CommandLine isn't yet
  57. // initialized, so guard here to avoid a CHECK.
  58. if (base::CommandLine::InitializedForCurrentProcess()) {
  59. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  60. if (command_line->HasSwitch("{switch_name}")) {
  61. std::string switch_value = command_line->GetSwitchValueASCII("{switch_name}");
  62. return switch_value == "1";
  63. }
  64. }
  65. #endif
  66. return kFuseWire[{index}] == '1';
  67. }
  68. """.replace("{name}", name).replace("{switch_name}", f"set-fuse-{fuse.lower()}").replace("{index}", str(index))
  69. def c_hex(n):
  70. s = hex(n)[2:]
  71. return "0x" + s.rjust(2, '0')
  72. def hex_arr(s):
  73. arr = []
  74. for char in s:
  75. arr.append(c_hex(ord(char)))
  76. return ",".join(arr)
  77. header = TEMPLATE_H.replace("{getters}", getters_h.strip())
  78. impl = TEMPLATE_CC.replace("{sentinel}", hex_arr(SENTINEL))
  79. impl = impl.replace("{fuse_version}", c_hex(fuse_version))
  80. impl = impl.replace("{fuse_wire_length}", c_hex(len(fuses)))
  81. impl = impl.replace("{initial_config}", hex_arr(initial_config))
  82. impl = impl.replace("{getters}", getters_cc.strip())
  83. with open(sys.argv[1], 'w') as f:
  84. f.write(header)
  85. with open(sys.argv[2], 'w') as f:
  86. f.write(impl)