documentation/AppManifests.md
All components of Flipper Zero firmware — services, user applications, and system settings — are developed independently. Each component has a build system manifest file named application.fam, which defines the basic properties of that component and its relations to other parts of the system.
When building firmware, fbt collects all app manifests and processes their dependencies. Then it builds only those components referenced in the current build configuration. See FBT docs for details on build configurations.
A firmware component's properties are declared in a Python code snippet, forming a call to the App() function with various parameters.
Only two parameters are mandatory: appid and apptype. Others are optional and may only be meaningful for certain app types.
appid: string, app ID within the build system. It is used to specify which app to include in the build configuration and resolve dependencies and conflicts.
apptype: member of FlipperAppType.* enumeration. Valid values are:
| Enum member | Firmware component type |
|---|---|
| SERVICE | System service, created at early startup |
| SYSTEM | App is not being shown in any menus. It can be started by other apps or from CLI |
| APP | Regular app for the main menu |
| PLUGIN | App to be built as a part of the firmware and to be placed in the Plugins menu |
| DEBUG | App only visible in Debug menu with debug mode enabled |
| ARCHIVE | One and only Archive app |
| SETTINGS | App to be placed in the system settings menu |
| STARTUP | Callback function to run at system startup. Does not define a separate app |
| EXTERNAL | App to be built as .fap plugin |
| METAPACKAGE | Does not define any code to be run, used for declaring dependencies and app bundles |
extern "C" to use them as entry points.fbt will abort the firmware build process.top and free CLI commands to profile your app's memory usage.["all"]."", meaning no resources are packaged.The following parameters are used only for FAPs:
["*.c*"] includes C and C++ source files. Apps cannot use the "lib" folder for their own source code, as it is reserved for fap_private_libs. Paths starting with "!" are excluded from the list of sources. They can also include wildcard characters and directory names. For example, a value of ["*.c*", "!plugins"] will include all C and C++ source files in the app folder except those in the plugins (and lib) folders. Paths with no wildcards (*, ?) are treated as full literal paths for both inclusion and exclusion..png file, 1-bit color depth, 10x10px, to be embedded within .fap file..fap file size and RAM consumption.ExtFile(path="file name", command="shell command") definitions. fbt will run the specified command for each file in the list.False. Applies only to PLUGIN type. If True, the plugin will be embedded into host app's .fap file as a resource and extracted to apps_assets/APPID folder on its start. This allows plugins to be distributed as a part of the host app.Note that commands are executed at the firmware root folder, and all intermediate files must be placed in an app's temporary build folder. For that, you can use pattern expansion by fbt: ${FAP_WORK_DIR} will be replaced with the path to the app's temporary build folder, and ${FAP_SRC_DIR} will be replaced with the path to the app's source folder. You can also use other variables defined internally by fbt.
Example for building an app from Rust sources:
sources=["target/thumbv7em-none-eabihf/release/libhello_rust.a"],
fap_extbuild=(
ExtFile(
path="${FAP_WORK_DIR}/target/thumbv7em-none-eabihf/release/libhello_rust.a",
command="cargo build --release --verbose --target thumbv7em-none-eabihf --target-dir ${FAP_WORK_DIR}/target --manifest-path ${FAP_SRC_DIR}/Cargo.toml",
),
),
fap_private_libs: list of additional libraries distributed as sources alongside the app. These libraries will be built as a part of the app build process.
Library sources must be placed in a subfolder of the lib folder within the app's source folder.
Each library is defined as a call to the Lib() function, accepting the following parameters:
["."], meaning the library's source root.["*.c*"].[].[].[].Example for building an app with a private library:
fap_private_libs=[
Lib(
name="mbedtls",
fap_include_paths=["include"],
sources=[
"library/des.c",
"library/sha1.c",
"library/platform_util.c",
],
cdefines=["MBEDTLS_ERROR_C"],
),
Lib(
name="loclass",
cflags=["-Wno-error"],
),
],
For that snippet, fbt will build 2 libraries: one from sources in lib/mbedtls folder and another from sources in the lib/loclass folder. For the mbedtls library, fbt will add lib/mbedtls/include to the list of include paths for the app and compile only the files specified in the sources list. Additionally, fbt will enable MBEDTLS_ERROR_C preprocessor definition for mbedtls sources.
For the loclass library, fbt will add lib/loclass to the list of the included paths for the app and build all sources in that folder. Also, fbt will disable treating compiler warnings as errors for the loclass library, which can be useful when compiling large 3rd-party codebases.
Both libraries will be linked with the app.
The .fam file contains one or more app definitions. For example, here's a part of applications/service/bt/application.fam:
App(
appid="bt_start",
apptype=FlipperAppType.STARTUP,
entry_point="bt_on_system_start",
order=70,
)
App(
appid="bt_settings",
name="Bluetooth",
apptype=FlipperAppType.SETTINGS,
entry_point="bt_settings_app",
stack_size=1 * 1024,
requires=[
"bt",
"gui",
],
order=10,
)
For more examples, see .fam files from various firmware parts.