fbt_apps.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from SCons.Builder import Builder
  2. from SCons.Action import Action
  3. from SCons.Warnings import warn, WarningOnByDefault
  4. import SCons
  5. import os.path
  6. from fbt.appmanifest import (
  7. FlipperAppType,
  8. AppManager,
  9. ApplicationsCGenerator,
  10. FlipperManifestException,
  11. )
  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 LoadApplicationManifests(env):
  16. appmgr = env["APPMGR"] = AppManager()
  17. for app_dir, _ in env["APPDIRS"]:
  18. app_dir_node = env.Dir("#").Dir(app_dir)
  19. for entry in app_dir_node.glob("*", ondisk=True, source=True):
  20. if isinstance(entry, SCons.Node.FS.Dir) and not str(entry).startswith("."):
  21. try:
  22. app_manifest_file_path = os.path.join(
  23. entry.abspath, "application.fam"
  24. )
  25. appmgr.load_manifest(app_manifest_file_path, entry)
  26. env.Append(PY_LINT_SOURCES=[app_manifest_file_path])
  27. except FlipperManifestException as e:
  28. warn(WarningOnByDefault, str(e))
  29. def PrepareApplicationsBuild(env):
  30. appbuild = env["APPBUILD"] = env["APPMGR"].filter_apps(env["APPS"])
  31. env.Append(
  32. SDK_HEADERS=appbuild.get_sdk_headers(),
  33. )
  34. env["APPBUILD_DUMP"] = env.Action(
  35. DumpApplicationConfig,
  36. "\tINFO\t",
  37. )
  38. def DumpApplicationConfig(target, source, env):
  39. print(f"Loaded {len(env['APPMGR'].known_apps)} app definitions.")
  40. print("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. 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(LoadApplicationManifests)
  55. env.AddMethod(PrepareApplicationsBuild)
  56. env.Append(
  57. BUILDERS={
  58. "ApplicationsC": Builder(
  59. action=Action(
  60. build_apps_c,
  61. "${APPSCOMSTR}",
  62. ),
  63. suffix=".c",
  64. ),
  65. }
  66. )
  67. def exists(env):
  68. return True