extapps.scons 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. from SCons.Errors import UserError
  2. Import("ENV")
  3. from fbt.appmanifest import FlipperAppType
  4. appenv = ENV["APPENV"] = ENV.Clone(
  5. tools=[
  6. (
  7. "fbt_extapps",
  8. {
  9. "EXT_APPS_WORK_DIR": ENV.subst(
  10. "${BUILD_DIR}/.extapps",
  11. )
  12. },
  13. ),
  14. "fbt_assets",
  15. "fbt_sdk",
  16. ]
  17. )
  18. appenv.Replace(
  19. LINKER_SCRIPT=appenv.subst("$APP_LINKER_SCRIPT"),
  20. )
  21. appenv.AppendUnique(
  22. CCFLAGS=[
  23. "-ggdb3",
  24. "-mword-relocations",
  25. "-mlong-calls",
  26. "-fno-common",
  27. "-nostdlib",
  28. "-fvisibility=hidden",
  29. ],
  30. LINKFLAGS=[
  31. "-Ur",
  32. "-Wl,-Ur",
  33. # "-Wl,--orphan-handling=error",
  34. "-Bsymbolic",
  35. "-nostartfiles",
  36. "-mlong-calls",
  37. "-fno-common",
  38. "-nostdlib",
  39. "-Wl,--gc-sections",
  40. "-Wl,--no-export-dynamic",
  41. "-fvisibility=hidden",
  42. "-Wl,-e${APP_ENTRY}",
  43. "-Xlinker",
  44. "-Map=${TARGET}.map",
  45. "-specs=nano.specs",
  46. "-specs=nosys.specs",
  47. ],
  48. LIBS=[
  49. "m",
  50. "gcc",
  51. "stdc++",
  52. "supc++",
  53. ],
  54. )
  55. extapps = appenv["_extapps"] = {
  56. "compact": {},
  57. "debug": {},
  58. "validators": {},
  59. "dist": {},
  60. "resources_dist": None,
  61. "sdk_tree": None,
  62. }
  63. def build_app_as_external(env, appdef):
  64. compact_elf, debug_elf, validator = env.BuildAppElf(appdef)
  65. extapps["compact"][appdef.appid] = compact_elf
  66. extapps["debug"][appdef.appid] = debug_elf
  67. extapps["validators"][appdef.appid] = validator
  68. extapps["dist"][appdef.appid] = (appdef.fap_category, compact_elf)
  69. apps_to_build_as_faps = [
  70. FlipperAppType.PLUGIN,
  71. FlipperAppType.EXTERNAL,
  72. ]
  73. if appenv["DEBUG_TOOLS"]:
  74. apps_to_build_as_faps.append(FlipperAppType.DEBUG)
  75. for apptype in apps_to_build_as_faps:
  76. for app in appenv["APPBUILD"].get_apps_of_type(apptype, True):
  77. build_app_as_external(appenv, app)
  78. # Ugly access to global option
  79. if extra_app_list := GetOption("extra_ext_apps"):
  80. for extra_app in extra_app_list.split(","):
  81. build_app_as_external(appenv, appenv["APPMGR"].get(extra_app))
  82. if appenv["FORCE"]:
  83. appenv.AlwaysBuild(extapps["compact"].values())
  84. # Deprecation stub
  85. def legacy_app_build_stub(**kw):
  86. raise UserError(f"Target name 'firmware_extapps' is deprecated, use 'faps' instead")
  87. appenv.PhonyTarget("firmware_extapps", appenv.Action(legacy_app_build_stub, None))
  88. Alias("faps", extapps["compact"].values())
  89. Alias("faps", extapps["validators"].values())
  90. extapps["resources_dist"] = appenv.FapDist(appenv.Dir("#/assets/resources/apps"), [])
  91. if appsrc := appenv.subst("$APPSRC"):
  92. app_manifest, fap_file, app_validator = appenv.GetExtAppFromPath(appsrc)
  93. appenv.PhonyTarget(
  94. "launch_app",
  95. '${PYTHON3} "${APP_RUN_SCRIPT}" ${SOURCE} --fap_dst_dir "/ext/apps/${FAP_CATEGORY}"',
  96. source=fap_file,
  97. FAP_CATEGORY=app_manifest.fap_category,
  98. )
  99. appenv.Alias("launch_app", app_validator)
  100. # SDK management
  101. sdk_origin_path = "${BUILD_DIR}/sdk_origin"
  102. sdk_source = appenv.SDKPrebuilder(
  103. sdk_origin_path,
  104. # Deps on root SDK headers and generated files
  105. (appenv["SDK_HEADERS"], appenv["FW_ASSETS_HEADERS"]),
  106. )
  107. # Extra deps on headers included in deeper levels
  108. Depends(sdk_source, appenv.ProcessSdkDepends(f"{sdk_origin_path}.d"))
  109. appenv["SDK_DIR"] = appenv.Dir("${BUILD_DIR}/sdk")
  110. sdk_tree = extapps["sdk_tree"] = appenv.SDKTree(appenv["SDK_DIR"], sdk_origin_path)
  111. # AlwaysBuild(sdk_tree)
  112. Alias("sdk_tree", sdk_tree)
  113. sdk_apicheck = appenv.SDKSymUpdater(appenv["SDK_DEFINITION"], sdk_origin_path)
  114. Precious(sdk_apicheck)
  115. NoClean(sdk_apicheck)
  116. AlwaysBuild(sdk_apicheck)
  117. Alias("sdk_check", sdk_apicheck)
  118. sdk_apisyms = appenv.SDKSymGenerator(
  119. "${BUILD_DIR}/assets/compiled/symbols.h", appenv["SDK_DEFINITION"]
  120. )
  121. Alias("api_syms", sdk_apisyms)
  122. if appenv["FORCE"]:
  123. appenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms)
  124. Return("extapps")