Skip to content

Commit

Permalink
[FL-3330] fbt: added hooks for build & dist environments; added FW_OR…
Browse files Browse the repository at this point in the history
…IGIN_* macro for apps & SDK (flipperdevices#2705)

* fbt: added hooks for build & dist environments
* Moved env hooks to an optional file
* Fixed var name
* Added fw origin to device info
* Bumped device info version
* fbt: added FIRMWARE_ORIGIN option. Different implementation for FW_ORIGIN_* C macro.
* api: bumped versions
* fbt: added fbt_options_local.py
* gitignore: cleanup

Co-authored-by: あく <[email protected]>
  • Loading branch information
hedger and skotopes authored May 29, 2023
1 parent 3de856f commit 8d2ea14
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 17 deletions.
22 changes: 11 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,25 @@ bindings/
.mxproject
Brewfile.lock.json

# Visual Studio Code
/.vscode/

# Kate
.kateproject
.kateconfig

# legendary cmake's
build
CMakeLists.txt

# bundle output
dist

# kde
.directory

# SCons
.sconsign.dblite


# Visual Studio Code
/.vscode

# bundle output
/dist

# SCons build dir
build/
/build

# Toolchain
/toolchain
Expand All @@ -64,3 +62,5 @@ PVS-Studio.log
*.PVS-Studio.*

.gdbinit

/fbt_options_local.py
2 changes: 2 additions & 0 deletions documentation/fbt.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
Default configuration variables are set in the configuration file: `fbt_options.py`.
Values set in the command line have higher precedence over the configuration file.

You can also create a file called `fbt_options_local.py` that will be evaluated when loading default options file, enabling persisent overriding of default options without modifying default configuration.

You can find out available options with `./fbt -h`.

### Firmware application set
Expand Down
7 changes: 7 additions & 0 deletions fbt_options.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from pathlib import Path
import posixpath

# For more details on these options, run 'fbt -h'

FIRMWARE_ORIGIN = "Official"

# Default hardware target
TARGET_HW = 7
Expand Down Expand Up @@ -75,3 +77,8 @@
}

FIRMWARE_APP_SET = "default"

custom_options_fn = "fbt_options_local.py"

if Path(custom_options_fn).exists():
exec(compile(Path(custom_options_fn).read_text(), custom_options_fn, "exec"))
11 changes: 11 additions & 0 deletions firmware.scons
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ env = ENV.Clone(
"fbt_apps",
"pvsstudio",
"fbt_hwtarget",
"fbt_envhooks",
],
COMPILATIONDB_USE_ABSPATH=False,
BUILD_DIR=fw_build_meta["build_dir"],
Expand Down Expand Up @@ -72,6 +73,8 @@ env = ENV.Clone(
_APP_ICONS=None,
)

env.PreConfigureFwEnvionment()

if env["IS_BASE_FIRMWARE"]:
env.Append(
FIRMWARE_BUILD_CFG="firmware",
Expand Down Expand Up @@ -100,6 +103,13 @@ lib_targets = env.BuildModules(
],
)

# Configure firmware origin definitions
env.Append(
CPPDEFINES=[
env.subst("FW_ORIGIN_${FIRMWARE_ORIGIN}"),
]
)


# Now, env is fully set up with everything to build apps
fwenv = env.Clone(FW_ARTIFACTS=[])
Expand Down Expand Up @@ -271,5 +281,6 @@ if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):

Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_all", fw_artifacts)

env.PostConfigureFwEnvionment()

Return("fwenv")
4 changes: 3 additions & 1 deletion firmware/targets/f18/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,28.0,,
Version,+,28.1,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -2003,6 +2003,8 @@ Function,-,vdprintf,int,"int, const char*, __gnuc_va_list"
Function,+,version_get,const Version*,
Function,+,version_get_builddate,const char*,const Version*
Function,+,version_get_dirty_flag,_Bool,const Version*
Function,+,version_get_firmware_origin,const char*,const Version*
Function,+,version_get_git_origin,const char*,const Version*
Function,+,version_get_gitbranch,const char*,const Version*
Function,+,version_get_gitbranchnum,const char*,const Version*
Function,+,version_get_githash,const char*,const Version*
Expand Down
4 changes: 3 additions & 1 deletion firmware/targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,28.0,,
Version,+,28.1,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -2945,6 +2945,8 @@ Function,-,vdprintf,int,"int, const char*, __gnuc_va_list"
Function,+,version_get,const Version*,
Function,+,version_get_builddate,const char*,const Version*
Function,+,version_get_dirty_flag,_Bool,const Version*
Function,+,version_get_firmware_origin,const char*,const Version*
Function,+,version_get_git_origin,const char*,const Version*
Function,+,version_get_gitbranch,const char*,const Version*
Function,+,version_get_gitbranchnum,const char*,const Version*
Function,+,version_get_githash,const char*,const Version*
Expand Down
20 changes: 19 additions & 1 deletion firmware/targets/f7/furi_hal/furi_hal_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
property_value_out(&property_context, NULL, 2, "format", "minor", "1");
} else {
property_value_out(&property_context, NULL, 3, "device", "info", "major", "2");
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "1");
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "2");
}

// Model name
Expand Down Expand Up @@ -173,6 +173,24 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
&property_context, "%d", 3, "firmware", "api", "major", api_version_major);
property_value_out(
&property_context, "%d", 3, "firmware", "api", "minor", api_version_minor);

property_value_out(
&property_context,
NULL,
3,
"firmware",
"origin",
"fork",
version_get_firmware_origin(firmware_version));

property_value_out(
&property_context,
NULL,
3,
"firmware",
"origin",
"git",
version_get_git_origin(firmware_version));
}

if(furi_hal_bt_is_alive()) {
Expand Down
5 changes: 5 additions & 0 deletions furi/core/core_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ extern "C" {
#define TOSTRING(x) STRINGIFY(x)
#endif

#ifndef CONCATENATE
#define CONCATENATE(a, b) CONCATENATE_(a, b)
#define CONCATENATE_(a, b) a##b
#endif

#ifndef REVERSE_BYTES_U32
#define REVERSE_BYTES_U32(x) \
((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \
Expand Down
15 changes: 14 additions & 1 deletion lib/toolbox/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#define VERSION_MAGIC (0xBE40u)
#define VERSION_MAJOR (0x1u)
#define VERSION_MINOR (0x0u)
#define VERSION_MINOR (0x1u)

struct Version {
// Header
Expand All @@ -20,6 +20,9 @@ struct Version {
// Payload bits and pieces
const uint8_t target;
const bool build_is_dirty;
// v 1.1
const char* firmware_origin;
const char* git_origin;
};

/* version of current running firmware (bootloader/flipper) */
Expand All @@ -37,6 +40,8 @@ static const Version version = {
,
.target = TARGET,
.build_is_dirty = BUILD_DIRTY,
.firmware_origin = FIRMWARE_ORIGIN,
.git_origin = GIT_ORIGIN,
};

const Version* version_get(void) {
Expand Down Expand Up @@ -71,3 +76,11 @@ uint8_t version_get_target(const Version* v) {
bool version_get_dirty_flag(const Version* v) {
return v ? v->build_is_dirty : version.build_is_dirty;
}

const char* version_get_firmware_origin(const Version* v) {
return v ? v->firmware_origin : version.firmware_origin;
}

const char* version_get_git_origin(const Version* v) {
return v ? v->git_origin : version.git_origin;
}
11 changes: 11 additions & 0 deletions lib/toolbox/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ uint8_t version_get_target(const Version* v);
*/
bool version_get_dirty_flag(const Version* v);

/**
* Get firmware origin. "Official" for mainline firmware, fork name for forks.
* Set by FIRMWARE_ORIGIN fbt argument.
*/
const char* version_get_firmware_origin(const Version* v);

/**
* Get git repo origin
*/
const char* version_get_git_origin(const Version* v);

#ifdef __cplusplus
}
#endif
16 changes: 15 additions & 1 deletion scripts/debug/flipperversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class VersionData:
version: str
target: int
build_is_dirty: bool
# Since version 1.1
firmware_origin: str = ""
git_origin: str = ""
# More fields may be added in the future
extra: Optional[Dict[str, str]] = field(default_factory=dict)


Expand Down Expand Up @@ -52,14 +56,20 @@ def load_versioned(self, major, minor):

# Struct version 1.0
extra_data = int(self.version_ptr[5].cast(self._uint_type))
return VersionData(
version_data = VersionData(
git_hash=self.version_ptr[1].cast(self._cstr_type).string(),
git_branch=self.version_ptr[2].cast(self._cstr_type).string(),
build_date=self.version_ptr[3].cast(self._cstr_type).string(),
version=self.version_ptr[4].cast(self._cstr_type).string(),
target=extra_data & 0xF,
build_is_dirty=bool((extra_data >> 8) & 0xF),
)
if minor >= 1:
version_data.firmware_origin = (
self.version_ptr[6].cast(self._cstr_type).string()
)
version_data.git_origin = self.version_ptr[7].cast(self._cstr_type).string()
return version_data

def load_unversioned(self):
"""Parse an early version of the version struct."""
Expand Down Expand Up @@ -104,6 +114,10 @@ def invoke(self, arg, from_tty):
print(f"\tGit commit: {v.version.git_hash}")
print(f"\tDirty: {v.version.build_is_dirty}")
print(f"\tHW Target: {v.version.target}")
if v.version.firmware_origin:
print(f"\tOrigin: {v.version.firmware_origin}")
if v.version.git_origin:
print(f"\tGit origin: {v.version.git_origin}")


FlipperFwVersion()
67 changes: 67 additions & 0 deletions scripts/fbt_tools/fbt_envhooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
To introduce changes to firmware build environment that are specific to your fork:
create a file "scripts/fbt/fbt_hooks.py"
With it, you can define functions that will be called at specific points of
firmware build configuration, with environment as an argument.
For example, you can define a function `PreConfigureFwEnvionment(env)` that
defines that will be a part of SDK build, so applications can
use them for conditional compilation.
Here is a list of all available hooks:
PreConfigureFwEnvionment(env):
This function is called on firmware environment (incl. updater)
before any major configuration is done.
PostConfigureFwEnvionment(env):
This function is called on firmware environment (incl. updater)
after all configuration is done.
PreConfigureUfbtEnvionment(env):
This function is called on ufbt environment at the beginning of
its configuration, before dist environment is created.
PostConfigureUfbtEnvionment(env):
This function is called on ufbt dist_env environment after all
configuration and target creation is done.
"""


class DefaultFbtHooks:
pass


try:
from fbt import fbt_hooks
except ImportError:
fbt_hooks = DefaultFbtHooks()


def generate(env):
stub_hook = lambda env: None
control_hooks = [
"PreConfigureFwEnvionment",
"PostConfigureFwEnvionment",
"PreConfigureUfbtEnvionment",
"PostConfigureUfbtEnvionment",
]

if (
isinstance(fbt_hooks, DefaultFbtHooks)
and env.subst("${FIRMWARE_ORIGIN}") != "Official"
):
# If fbt_hooks.py is not present, but we are not building official firmware,
# create "scripts/fbt/fbt_hooks.py" to implement changes to firmware build environment.
pass

for hook_name in control_hooks:
hook_fn = getattr(fbt_hooks, hook_name, stub_hook)
env.AddMethod(hook_fn, hook_name)


def exists():
return True
4 changes: 3 additions & 1 deletion scripts/fbt_tools/fbt_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def generate(env):
BUILDERS={
"VersionBuilder": Builder(
action=Action(
'${PYTHON3} "${VERSION_SCRIPT}" generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir "${ROOT_DIR}"',
'${PYTHON3} "${VERSION_SCRIPT}" generate '
"-t ${TARGET_HW} -fw-origin ${FIRMWARE_ORIGIN} "
'-o ${TARGET.dir.posix} --dir "${ROOT_DIR}"',
"${VERSIONCOMSTR}",
),
emitter=version_emitter,
Expand Down
5 changes: 5 additions & 0 deletions scripts/ufbt/SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ env = core_env.Clone(
"fbt_apps",
"fbt_extapps",
"fbt_assets",
"fbt_envhooks",
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
],
FBT_FAP_DEBUG_ELF_ROOT=ufbt_build_dir,
Expand All @@ -117,6 +118,8 @@ env = core_env.Clone(
wrap_tempfile(env, "LINKCOM")
wrap_tempfile(env, "ARCOM")

env.PreConfigureUfbtEnvionment()

# print(env.Dump())

# Dist env
Expand Down Expand Up @@ -474,3 +477,5 @@ dist_env.PhonyTarget(
"env",
"@echo $( ${FBT_SCRIPT_DIR}/toolchain/fbtenv.sh $)",
)

dist_env.PostConfigureUfbtEnvionment()
Loading

0 comments on commit 8d2ea14

Please sign in to comment.