SConstruct 5.7 KB

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