fbt_assets.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import SCons
  2. from SCons.Builder import Builder
  3. from SCons.Action import Action
  4. from SCons.Node.FS import File
  5. import os
  6. import subprocess
  7. def icons_emitter(target, source, env):
  8. target = [
  9. "compiled/assets_icons.c",
  10. "compiled/assets_icons.h",
  11. ]
  12. return target, source
  13. def proto_emitter(target, source, env):
  14. out_path = target[0].path
  15. target = []
  16. for src in source:
  17. basename = os.path.splitext(src.name)[0]
  18. target.append(env.File(f"compiled/{basename}.pb.c"))
  19. target.append(env.File(f"compiled/{basename}.pb.h"))
  20. return target, source
  21. def dolphin_emitter(target, source, env):
  22. res_root_dir = source[0].Dir(env["DOLPHIN_RES_TYPE"])
  23. source = [res_root_dir]
  24. source.extend(
  25. env.GlobRecursive("*.*", res_root_dir),
  26. )
  27. target_base_dir = target[0]
  28. env.Replace(_DOLPHIN_OUT_DIR=target[0])
  29. if env["DOLPHIN_RES_TYPE"] == "external":
  30. target = []
  31. target.extend(
  32. map(
  33. lambda node: target_base_dir.File(
  34. res_root_dir.rel_path(node).replace(".png", ".bm")
  35. ),
  36. filter(lambda node: isinstance(node, SCons.Node.FS.File), source),
  37. )
  38. )
  39. else:
  40. asset_basename = f"assets_dolphin_{env['DOLPHIN_RES_TYPE']}"
  41. target = [
  42. target_base_dir.File(asset_basename + ".c"),
  43. target_base_dir.File(asset_basename + ".h"),
  44. ]
  45. return target, source
  46. def _invoke_git(args, source_dir):
  47. cmd = ["git"]
  48. cmd.extend(args)
  49. return (
  50. subprocess.check_output(cmd, cwd=source_dir, stderr=subprocess.STDOUT)
  51. .strip()
  52. .decode()
  53. )
  54. def proto_ver_generator(target, source, env):
  55. target_file = target[0]
  56. src_dir = source[0].dir.abspath
  57. try:
  58. git_fetch = _invoke_git(
  59. ["fetch", "--tags"],
  60. source_dir=src_dir,
  61. )
  62. except (subprocess.CalledProcessError, EnvironmentError) as e:
  63. # Not great, not terrible
  64. print("Git: fetch failed")
  65. try:
  66. git_describe = _invoke_git(
  67. ["describe", "--tags", "--abbrev=0"],
  68. source_dir=src_dir,
  69. )
  70. except (subprocess.CalledProcessError, EnvironmentError) as e:
  71. print("Git: describe failed")
  72. Exit("git error")
  73. # print("describe=", git_describe)
  74. git_major, git_minor = git_describe.split(".")
  75. version_file_data = (
  76. "#pragma once",
  77. f"#define PROTOBUF_MAJOR_VERSION {git_major}",
  78. f"#define PROTOBUF_MINOR_VERSION {git_minor}",
  79. "",
  80. )
  81. with open(str(target_file), "wt") as file:
  82. file.write("\n".join(version_file_data))
  83. def generate(env):
  84. env.SetDefault(
  85. ASSETS_COMPILER="${ROOT_DIR.abspath}/scripts/assets.py",
  86. NANOPB_COMPILER="${ROOT_DIR.abspath}/lib/nanopb/generator/nanopb_generator.py",
  87. )
  88. env.Append(
  89. BUILDERS={
  90. "IconBuilder": Builder(
  91. action=Action(
  92. '${PYTHON3} "${ASSETS_COMPILER}" icons ${SOURCE.posix} ${TARGET.dir.posix}',
  93. "${ICONSCOMSTR}",
  94. ),
  95. emitter=icons_emitter,
  96. ),
  97. "ProtoBuilder": Builder(
  98. action=Action(
  99. '${PYTHON3} "${NANOPB_COMPILER}" -q -I${SOURCE.dir.posix} -D${TARGET.dir.posix} ${SOURCES.posix}',
  100. "${PROTOCOMSTR}",
  101. ),
  102. emitter=proto_emitter,
  103. suffix=".pb.c",
  104. src_suffix=".proto",
  105. ),
  106. "DolphinSymBuilder": Builder(
  107. action=Action(
  108. '${PYTHON3} "${ASSETS_COMPILER}" dolphin -s dolphin_${DOLPHIN_RES_TYPE} "${SOURCE}" "${_DOLPHIN_OUT_DIR}"',
  109. "${DOLPHINCOMSTR}",
  110. ),
  111. emitter=dolphin_emitter,
  112. ),
  113. "DolphinExtBuilder": Builder(
  114. action=Action(
  115. '${PYTHON3} "${ASSETS_COMPILER}" dolphin "${SOURCE}" "${_DOLPHIN_OUT_DIR}"',
  116. "${DOLPHINCOMSTR}",
  117. ),
  118. emitter=dolphin_emitter,
  119. ),
  120. "ProtoVerBuilder": Builder(
  121. action=Action(
  122. proto_ver_generator,
  123. "${PBVERCOMSTR}",
  124. ),
  125. ),
  126. }
  127. )
  128. def exists(env):
  129. return True