SConstruct 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #
  2. # Main Fipper Build System entry point
  3. #
  4. # This file is evaluated by scons (the build system) every time fbt is invoked.
  5. # Scons constructs all referenced environments & their targets' dependency
  6. # trees on startup. So, to keep startup time as low as possible, we're hiding
  7. # construction of certain targets behind command-line options.
  8. import os
  9. DefaultEnvironment(tools=[])
  10. # Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
  11. # This environment is created only for loading options & validating file/dir existance
  12. fbt_variables = SConscript("site_scons/commandline.scons")
  13. cmd_environment = Environment(tools=[], variables=fbt_variables)
  14. Help(fbt_variables.GenerateHelpText(cmd_environment))
  15. # Building basic environment - tools, utility methods, cross-compilation
  16. # settings, gcc flags for Cortex-M4, basic builders and more
  17. coreenv = SConscript(
  18. "site_scons/environ.scons",
  19. exports={"VAR_ENV": cmd_environment},
  20. )
  21. SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
  22. # Store root dir in environment for certain tools
  23. coreenv["ROOT_DIR"] = Dir(".")
  24. # Create a separate "dist" environment and add construction envs to it
  25. distenv = coreenv.Clone(
  26. tools=["fbt_dist", "openocd", "blackmagic"],
  27. OPENOCD_GDB_PIPE=["|openocd -c 'gdb_port pipe' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"],
  28. GDBOPTS_BASE=[
  29. "-ex",
  30. "target extended-remote ${GDBREMOTE}",
  31. "-ex",
  32. "set confirm off",
  33. ],
  34. GDBOPTS_BLACKMAGIC=[
  35. "-ex",
  36. "monitor swdp_scan",
  37. "-ex",
  38. "monitor debug_bmp enable",
  39. "-ex",
  40. "attach 1",
  41. "-ex",
  42. "set mem inaccessible-by-default off",
  43. ],
  44. GDBPYOPTS=[
  45. "-ex",
  46. "source debug/FreeRTOS/FreeRTOS.py",
  47. "-ex",
  48. "source debug/PyCortexMDebug/PyCortexMDebug.py",
  49. "-ex",
  50. "svd_load ${SVD_FILE}",
  51. "-ex",
  52. "compare-sections",
  53. ],
  54. ENV=os.environ,
  55. )
  56. firmware_env = distenv.AddFwProject(
  57. base_env=coreenv,
  58. fw_type="firmware",
  59. fw_env_key="FW_ENV",
  60. )
  61. # If enabled, initialize updater-related targets
  62. if GetOption("fullenv"):
  63. updater_env = distenv.AddFwProject(
  64. base_env=coreenv,
  65. fw_type="updater",
  66. fw_env_key="UPD_ENV",
  67. )
  68. # Target for self-update package
  69. dist_arguments = [
  70. "-r",
  71. '"${ROOT_DIR.abspath}/assets/resources"',
  72. "--bundlever",
  73. '"${UPDATE_VERSION_STRING}"',
  74. "--radio",
  75. '"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"',
  76. "--radiotype",
  77. "${COPRO_STACK_TYPE}",
  78. "${COPRO_DISCLAIMER}",
  79. "--obdata",
  80. '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"',
  81. ]
  82. if distenv["UPDATE_SPLASH"]:
  83. dist_arguments += [
  84. "--splash",
  85. distenv.subst("assets/slideshow/$UPDATE_SPLASH"),
  86. ]
  87. selfupdate_dist = distenv.DistCommand(
  88. "updater_package",
  89. (distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
  90. DIST_EXTRA=dist_arguments,
  91. )
  92. # Updater debug
  93. distenv.PhonyTarget(
  94. "updater_debug",
  95. "${GDBPYCOM}",
  96. source=updater_env["FW_ELF"],
  97. GDBREMOTE="${OPENOCD_GDB_PIPE}",
  98. )
  99. distenv.PhonyTarget(
  100. "updater_blackmagic",
  101. "${GDBPYCOM}",
  102. source=updater_env["FW_ELF"],
  103. GDBOPTS=distenv.subst("$GDBOPTS_BLACKMAGIC"),
  104. GDBREMOTE="${BLACKMAGIC_ADDR}",
  105. )
  106. # Installation over USB & CLI
  107. usb_update_package = distenv.UsbInstall(
  108. "#build/usbinstall.flag",
  109. (
  110. distenv["DIST_DEPENDS"],
  111. firmware_env["FW_RESOURCES"],
  112. selfupdate_dist,
  113. ),
  114. )
  115. if distenv["FORCE"]:
  116. distenv.AlwaysBuild(usb_update_package)
  117. distenv.Depends(usb_update_package, selfupdate_dist)
  118. distenv.Alias("flash_usb", usb_update_package)
  119. # Target for copying & renaming binaries to dist folder
  120. basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
  121. distenv.Default(basic_dist)
  122. # Target for bundling core2 package for qFlipper
  123. copro_dist = distenv.CoproBuilder(
  124. distenv.Dir("assets/core2_firmware"),
  125. [],
  126. )
  127. distenv.Alias("copro_dist", copro_dist)
  128. firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
  129. distenv.Alias("flash", firmware_flash)
  130. firmware_bm_flash = distenv.PhonyTarget(
  131. "flash_blackmagic",
  132. "$GDB $GDBOPTS $SOURCES $GDBFLASH",
  133. source=firmware_env["FW_ELF"],
  134. GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
  135. GDBREMOTE="${BLACKMAGIC_ADDR}",
  136. GDBFLASH=[
  137. "-ex",
  138. "load",
  139. "-ex",
  140. "quit",
  141. ],
  142. )
  143. # Debugging firmware
  144. firmware_debug = distenv.PhonyTarget(
  145. "debug",
  146. "${GDBPYCOM}",
  147. source=firmware_env["FW_ELF"],
  148. GDBOPTS="${GDBOPTS_BASE}",
  149. GDBREMOTE="${OPENOCD_GDB_PIPE}",
  150. )
  151. distenv.Depends(firmware_debug, firmware_flash)
  152. distenv.PhonyTarget(
  153. "blackmagic",
  154. "${GDBPYCOM}",
  155. source=firmware_env["FW_ELF"],
  156. GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
  157. GDBREMOTE="${BLACKMAGIC_ADDR}",
  158. )
  159. # Debug alien elf
  160. distenv.PhonyTarget(
  161. "debug_other",
  162. "${GDBPYCOM}",
  163. GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
  164. GDBREMOTE="${OPENOCD_GDB_PIPE}",
  165. )
  166. # Just start OpenOCD
  167. distenv.PhonyTarget(
  168. "openocd",
  169. "${OPENOCDCOM}",
  170. )
  171. # Linter
  172. distenv.PhonyTarget(
  173. "lint",
  174. "${PYTHON3} scripts/lint.py check ${LINT_SOURCES}",
  175. LINT_SOURCES=firmware_env["LINT_SOURCES"],
  176. )
  177. distenv.PhonyTarget(
  178. "format",
  179. "${PYTHON3} scripts/lint.py format ${LINT_SOURCES}",
  180. LINT_SOURCES=firmware_env["LINT_SOURCES"],
  181. )
  182. # Find blackmagic probe
  183. distenv.PhonyTarget(
  184. "get_blackmagic",
  185. "@echo $( ${BLACKMAGIC_ADDR} $)",
  186. )