fbt_apps.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from ansi.color import fg
  2. from fbt.appmanifest import (
  3. ApplicationsCGenerator,
  4. AppManager,
  5. FlipperAppType,
  6. FlipperManifestException,
  7. )
  8. from SCons.Action import Action
  9. from SCons.Builder import Builder
  10. from SCons.Errors import StopError
  11. from SCons.Warnings import WarningOnByDefault, warn
  12. # Adding objects for application management to env
  13. # AppManager env["APPMGR"] - loads all manifests; manages list of known apps
  14. # AppBuildset env["APPBUILD"] - contains subset of apps, filtered for current config
  15. def LoadAppManifest(env, entry):
  16. try:
  17. APP_MANIFEST_NAME = "application.fam"
  18. manifest_glob = entry.glob(APP_MANIFEST_NAME)
  19. if len(manifest_glob) == 0:
  20. raise FlipperManifestException(
  21. f"Folder {entry}: manifest {APP_MANIFEST_NAME} is missing"
  22. )
  23. app_manifest_file_path = manifest_glob[0].rfile().abspath
  24. env["APPMGR"].load_manifest(app_manifest_file_path, entry)
  25. env.Append(PY_LINT_SOURCES=[app_manifest_file_path])
  26. except FlipperManifestException as e:
  27. warn(WarningOnByDefault, str(e))
  28. def PrepareApplicationsBuild(env):
  29. try:
  30. appbuild = env["APPBUILD"] = env["APPMGR"].filter_apps(
  31. env["APPS"], env.subst("f${TARGET_HW}")
  32. )
  33. except Exception as e:
  34. raise StopError(e)
  35. env.Append(
  36. SDK_HEADERS=appbuild.get_sdk_headers(),
  37. )
  38. def DumpApplicationConfig(target, source, env):
  39. print(f"Loaded {len(env['APPMGR'].known_apps)} app definitions.")
  40. print(fg.boldgreen("Firmware modules configuration:"))
  41. for apptype in FlipperAppType:
  42. app_sublist = env["APPBUILD"].get_apps_of_type(apptype)
  43. if app_sublist:
  44. print(
  45. fg.green(f"{apptype.value}:\n\t"),
  46. ", ".join(app.appid for app in app_sublist),
  47. )
  48. def build_apps_c(target, source, env):
  49. target_file_name = target[0].path
  50. gen = ApplicationsCGenerator(env["APPBUILD"], env.subst("$LOADER_AUTOSTART"))
  51. with open(target_file_name, "w") as file:
  52. file.write(gen.generate())
  53. def generate(env):
  54. env.AddMethod(LoadAppManifest)
  55. env.AddMethod(PrepareApplicationsBuild)
  56. env.SetDefault(
  57. APPMGR=AppManager(),
  58. APPBUILD_DUMP=env.Action(
  59. DumpApplicationConfig,
  60. "\tINFO\t",
  61. ),
  62. )
  63. env.Append(
  64. BUILDERS={
  65. "ApplicationsC": Builder(
  66. action=Action(
  67. build_apps_c,
  68. "${APPSCOMSTR}",
  69. ),
  70. suffix=".c",
  71. ),
  72. }
  73. )
  74. def exists(env):
  75. return True