[FL-3174] Dolphin builder in ufbt; minor ufbt/fbt improvements (#2601)

* ufbt: added "dolphin_ext" target (expects "external" subfolder in cwd with dolphin assets); cleaned up unused code
* ufbt: codestyle fixes
* scripts: fixed style according to ruff linter
* scripts: additional cleanup & codestyle fixes
* github: pass target hw code when installing local SDK with ufbt
* ufbt: added error message for missing folder in dolphin builder
* scripts: more linter fixes
* sdk: added flipper_format_stream; ufbt: support for --extra-define
* fbt: reduced amount of global defines
* scripts, fbt: rearranged imports

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
hedger 2023-05-03 08:48:49 +03:00 committed by GitHub
parent 015ab4a024
commit c3ececcf96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 311 additions and 382 deletions

View file

@ -193,12 +193,14 @@ jobs:
TARGET="$(echo '${{ matrix.target }}' | sed 's/f//')"; \
./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package
echo "sdk-file=$(ls dist/${{ matrix.target }}-*/flipper-z-${{ matrix.target }}-sdk-*.zip)" >> $GITHUB_OUTPUT
echo "hw-target-code=$TARGET" >> $GITHUB_OUTPUT
- name: Deploy uFBT with SDK
uses: flipperdevices/flipperzero-ufbt-action@v0.1.0
with:
task: setup
sdk-file: ${{ steps.build-fw.outputs.sdk-file }}
sdk-hw-target: ${{ steps.build-fw.outputs.hw-target-code }}
- name: Build test app with SDK
run: |

View file

@ -1,7 +1,7 @@
Import("env")
from fbt.version import get_git_commit_unix_timestamp
Import("env")
assetsenv = env.Clone(
tools=["fbt_assets"],
FW_LIB_NAME="assets",

View file

@ -1,5 +1,3 @@
Import("ENV", "fw_build_meta")
from SCons.Errors import UserError
from SCons.Node import FS
@ -10,6 +8,8 @@ from fbt_extra.util import (
link_elf_dir_as_latest,
)
Import("ENV", "fw_build_meta")
# Building initial C environment for libs
env = ENV.Clone(
tools=[

View file

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,23.1,,
Version,+,23.3,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@ -112,6 +112,7 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,,
Header,+,lib/flipper_application/plugins/plugin_manager.h,,
Header,+,lib/flipper_format/flipper_format.h,,
Header,+,lib/flipper_format/flipper_format_i.h,,
Header,+,lib/flipper_format/flipper_format_stream.h,,
Header,+,lib/libusb_stm32/inc/hid_usage_button.h,,
Header,+,lib/libusb_stm32/inc/hid_usage_consumer.h,,
Header,+,lib/libusb_stm32/inc/hid_usage_desktop.h,,
@ -755,6 +756,11 @@ Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32
Function,+,flipper_format_rewind,_Bool,FlipperFormat*
Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat*
Function,+,flipper_format_set_strict_mode,void,"FlipperFormat*, _Bool"
Function,+,flipper_format_stream_delete_key_and_write,_Bool,"Stream*, FlipperStreamWriteData*, _Bool"
Function,+,flipper_format_stream_get_value_count,_Bool,"Stream*, const char*, uint32_t*, _Bool"
Function,+,flipper_format_stream_read_value_line,_Bool,"Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool"
Function,+,flipper_format_stream_write_comment_cstr,_Bool,"Stream*, const char*"
Function,+,flipper_format_stream_write_value_line,_Bool,"Stream*, FlipperStreamWriteData*"
Function,+,flipper_format_string_alloc,FlipperFormat*,
Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t"
Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t"

1 entry status name type params
2 Version + 23.1 23.3
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
112 Header + lib/flipper_application/plugins/plugin_manager.h
113 Header + lib/flipper_format/flipper_format.h
114 Header + lib/flipper_format/flipper_format_i.h
115 Header + lib/flipper_format/flipper_format_stream.h
116 Header + lib/libusb_stm32/inc/hid_usage_button.h
117 Header + lib/libusb_stm32/inc/hid_usage_consumer.h
118 Header + lib/libusb_stm32/inc/hid_usage_desktop.h
756 Function + flipper_format_rewind _Bool FlipperFormat*
757 Function + flipper_format_seek_to_end _Bool FlipperFormat*
758 Function + flipper_format_set_strict_mode void FlipperFormat*, _Bool
759 Function + flipper_format_stream_delete_key_and_write _Bool Stream*, FlipperStreamWriteData*, _Bool
760 Function + flipper_format_stream_get_value_count _Bool Stream*, const char*, uint32_t*, _Bool
761 Function + flipper_format_stream_read_value_line _Bool Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool
762 Function + flipper_format_stream_write_comment_cstr _Bool Stream*, const char*
763 Function + flipper_format_stream_write_value_line _Bool Stream*, FlipperStreamWriteData*
764 Function + flipper_format_string_alloc FlipperFormat*
765 Function + flipper_format_update_bool _Bool FlipperFormat*, const char*, const _Bool*, const uint16_t
766 Function + flipper_format_update_float _Bool FlipperFormat*, const char*, const float*, const uint16_t

View file

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,23.1,,
Version,+,23.3,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@ -118,6 +118,7 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,,
Header,+,lib/flipper_application/plugins/plugin_manager.h,,
Header,+,lib/flipper_format/flipper_format.h,,
Header,+,lib/flipper_format/flipper_format_i.h,,
Header,+,lib/flipper_format/flipper_format_stream.h,,
Header,+,lib/ibutton/ibutton_key.h,,
Header,+,lib/ibutton/ibutton_protocols.h,,
Header,+,lib/ibutton/ibutton_worker.h,,
@ -918,6 +919,11 @@ Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32
Function,+,flipper_format_rewind,_Bool,FlipperFormat*
Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat*
Function,+,flipper_format_set_strict_mode,void,"FlipperFormat*, _Bool"
Function,+,flipper_format_stream_delete_key_and_write,_Bool,"Stream*, FlipperStreamWriteData*, _Bool"
Function,+,flipper_format_stream_get_value_count,_Bool,"Stream*, const char*, uint32_t*, _Bool"
Function,+,flipper_format_stream_read_value_line,_Bool,"Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool"
Function,+,flipper_format_stream_write_comment_cstr,_Bool,"Stream*, const char*"
Function,+,flipper_format_stream_write_value_line,_Bool,"Stream*, FlipperStreamWriteData*"
Function,+,flipper_format_string_alloc,FlipperFormat*,
Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t"
Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t"

1 entry status name type params
2 Version + 23.1 23.3
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
118 Header + lib/flipper_application/plugins/plugin_manager.h
119 Header + lib/flipper_format/flipper_format.h
120 Header + lib/flipper_format/flipper_format_i.h
121 Header + lib/flipper_format/flipper_format_stream.h
122 Header + lib/ibutton/ibutton_key.h
123 Header + lib/ibutton/ibutton_protocols.h
124 Header + lib/ibutton/ibutton_worker.h
919 Function + flipper_format_rewind _Bool FlipperFormat*
920 Function + flipper_format_seek_to_end _Bool FlipperFormat*
921 Function + flipper_format_set_strict_mode void FlipperFormat*, _Bool
922 Function + flipper_format_stream_delete_key_and_write _Bool Stream*, FlipperStreamWriteData*, _Bool
923 Function + flipper_format_stream_get_value_count _Bool Stream*, const char*, uint32_t*, _Bool
924 Function + flipper_format_stream_read_value_line _Bool Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool
925 Function + flipper_format_stream_write_comment_cstr _Bool Stream*, const char*
926 Function + flipper_format_stream_write_value_line _Bool Stream*, FlipperStreamWriteData*
927 Function + flipper_format_string_alloc FlipperFormat*
928 Function + flipper_format_update_bool _Bool FlipperFormat*, const char*, const _Bool*, const uint16_t
929 Function + flipper_format_update_float _Bool FlipperFormat*, const char*, const float*, const uint16_t

View file

@ -7,6 +7,7 @@ env.Append(
SDK_HEADERS=[
File("flipper_format.h"),
File("flipper_format_i.h"),
File("flipper_format_stream.h"),
],
)

View file

@ -7,9 +7,6 @@ env.Append(
"#/lib/FreeRTOS-Kernel/portable/GCC/ARM_CM4F",
"#/lib/FreeRTOS-glue",
],
CPPDEFINES=[
"HAVE_FREERTOS",
],
)

View file

@ -4,9 +4,6 @@ env.Append(
CPPPATH=[
"#/lib/libusb_stm32/inc",
],
CPPDEFINES=[
("USB_PMASIZE", "0x400"),
],
SDK_HEADERS=env.GlobRecursive(
"*.h",
Dir("libusb_stm32/inc"),
@ -16,6 +13,11 @@ env.Append(
libenv = env.Clone(FW_LIB_NAME="usb_stm32")
libenv.ApplyLibFlags()
libenv.Append(
CPPDEFINES=[
("USB_PMASIZE", "0x400"),
],
)
sources = [

View file

@ -4,14 +4,16 @@ env.Append(
CPPPATH=[
"#/lib/littlefs",
],
CPPDEFINES=[
("LFS_CONFIG", "lfs_config.h"),
],
)
libenv = env.Clone(FW_LIB_NAME="littlefs")
libenv.ApplyLibFlags()
libenv.Append(
CPPDEFINES=[
("LFS_CONFIG", "lfs_config.h"),
],
)
sources = Glob("littlefs/*.c", source=True)

View file

@ -1,7 +1,7 @@
Import("env")
from fbt.util import GLOB_FILE_EXCLUSION
Import("env")
env.Append(
CPPPATH=[
"#/lib/digital_signal",

View file

@ -1,8 +1,8 @@
Import("env")
from fbt.version import get_fast_git_version_id
Import("env")
env.Append(
CPPPATH=[
"#/lib/toolbox",

View file

@ -1,10 +1,10 @@
#!/usr/bin/env python3
import os
from flipper.app import App
from flipper.assets.icon import file2image
import os
ICONS_SUPPORTED_FORMATS = ["png"]
ICONS_TEMPLATE_H_HEADER = """#pragma once
@ -127,7 +127,7 @@ class Main(App):
if not filenames:
continue
if "frame_rate" in filenames:
self.logger.debug(f"Folder contains animation")
self.logger.debug("Folder contains animation")
icon_name = "A_" + os.path.split(dirpath)[1].replace("-", "_")
width = height = None
frame_count = 0
@ -186,7 +186,7 @@ class Main(App):
icons_c.write("\n")
icons.append((icon_name, width, height, 0, 1))
# Create array of images:
self.logger.debug(f"Finalizing source file")
self.logger.debug("Finalizing source file")
for name, width, height, frame_rate, frame_count in icons:
icons_c.write(
ICONS_TEMPLATE_C_ICONS.format(
@ -201,7 +201,7 @@ class Main(App):
icons_c.close()
# Create Public Header
self.logger.debug(f"Creating header")
self.logger.debug("Creating header")
icons_h = open(
os.path.join(self.args.output_directory, f"{self.args.filename}.h"),
"w",
@ -211,7 +211,7 @@ class Main(App):
for name, width, height, frame_rate, frame_count in icons:
icons_h.write(ICONS_TEMPLATE_H_ICON_NAME.format(name=name))
icons_h.close()
self.logger.debug(f"Done")
self.logger.debug("Done")
return 0
def manifest(self):
@ -232,7 +232,7 @@ class Main(App):
new_manifest = Manifest(self.args.timestamp)
new_manifest.create(directory_path)
self.logger.info(f"Comparing new manifest with existing")
self.logger.info("Comparing new manifest with existing")
only_in_old, changed, only_in_new = Manifest.compare(old_manifest, new_manifest)
for record in only_in_old:
self.logger.info(f"Only in old: {record}")
@ -246,38 +246,38 @@ class Main(App):
else:
self.logger.info("Manifest is up-to-date!")
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0
def copro(self):
from flipper.assets.copro import Copro
self.logger.info(f"Bundling coprocessor binaries")
self.logger.info("Bundling coprocessor binaries")
copro = Copro(self.args.mcu)
self.logger.info(f"Loading CUBE info")
self.logger.info("Loading CUBE info")
copro.loadCubeInfo(self.args.cube_dir, self.args.cube_ver)
self.logger.info(f"Bundling")
self.logger.info("Bundling")
copro.bundle(
self.args.output_dir,
self.args.stack_file,
self.args.stack_type,
self.args.stack_addr,
)
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0
def dolphin(self):
from flipper.assets.dolphin import Dolphin
self.logger.info(f"Processing Dolphin sources")
self.logger.info("Processing Dolphin sources")
dolphin = Dolphin()
self.logger.info(f"Loading data")
self.logger.info("Loading data")
dolphin.load(self.args.input_directory)
self.logger.info(f"Packing")
self.logger.info("Packing")
dolphin.pack(self.args.output_directory, self.args.symbol_name)
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0

View file

@ -1,12 +1,12 @@
#!/usr/bin/env python3
import os
import posixpath
from flipper.app import App
from flipper.storage import FlipperStorage, FlipperStorageOperations
from flipper.utils.cdc import resolve_port
import os
import posixpath
class Main(App):
def init(self):

View file

@ -1,7 +1,7 @@
from dataclasses import dataclass, field
from typing import List, Optional, Tuple, Callable
from enum import Enum
import os
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable, List, Optional, Tuple
class FlipperManifestException(Exception):
@ -93,7 +93,7 @@ class AppManager:
def get(self, appname: str):
try:
return self.known_apps[appname]
except KeyError as _:
except KeyError:
raise FlipperManifestException(
f"Missing application manifest for '{appname}'"
)
@ -223,6 +223,7 @@ class AppBuildset:
return self.appmgr.get(app_name).supports_hardware_target(self.hw_target)
def _get_app_depends(self, app_name: str) -> List[str]:
app_def = self.appmgr.get(app_name)
# Skip app if its target is not supported by the target we are building for
if not self._check_if_app_target_supported(app_name):
self._writer(
@ -230,7 +231,6 @@ class AppBuildset:
)
return []
app_def = self.appmgr.get(app_name)
return list(
filter(
self._check_if_app_target_supported,
@ -296,7 +296,7 @@ class AppBuildset:
try:
parent_app = self.appmgr.get(parent_app_id)
parent_app._plugins.append(extension_app)
except FlipperManifestException as e:
except FlipperManifestException:
self._writer(
f"Module {extension_app.appid} has unknown parent {parent_app_id}"
)

View file

@ -1,12 +1,10 @@
from dataclasses import dataclass
import os
import struct
from dataclasses import dataclass, field
from .appmanifest import FlipperApplication
from flipper.assets.icon import file2image
from .appmanifest import FlipperApplication
_MANIFEST_MAGIC = 0x52474448

View file

@ -1,5 +1,5 @@
import os
import hashlib
import os
import struct
from typing import TypedDict

View file

@ -1,20 +1,13 @@
import operator
import os
import csv
import operator
from enum import Enum, auto
from typing import Set, ClassVar, Any
import os
from dataclasses import dataclass
from enum import Enum, auto
from typing import Any, ClassVar, Set
from ansi.color import fg
from . import (
ApiEntries,
ApiEntryFunction,
ApiEntryVariable,
ApiHeader,
)
from . import ApiEntries, ApiEntryFunction, ApiEntryVariable, ApiHeader
@dataclass(frozen=True)
@ -137,7 +130,7 @@ class SdkCache:
f"API version is still WIP: {self.version}. Review the changes and re-run command."
)
)
print(f"CSV file entries to mark up:")
print("CSV file entries to mark up:")
print(
fg.yellow(
"\n".join(

View file

@ -1,10 +1,9 @@
import SCons
from SCons.Subst import quote_spaces
from SCons.Errors import StopError
import re
import os
import re
import SCons
from SCons.Errors import StopError
from SCons.Subst import quote_spaces
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")

View file

@ -1,5 +1,5 @@
import subprocess
import datetime
import subprocess
from functools import cache

View file

@ -3,7 +3,7 @@ def exists():
def generate(env):
if ccache := env.WhereIs("ccache"):
if env.WhereIs("ccache"):
env["CCACHE"] = "ccache"
env["CC_NOCACHE"] = env["CC"]
env["CC"] = "$CCACHE $CC_NOCACHE"

View file

@ -1,15 +1,11 @@
from SCons.Errors import StopError
from SCons.Tool import asm
from SCons.Tool import gcc
from SCons.Tool import gxx
from SCons.Tool import ar
from SCons.Tool import gnulink
import strip
import subprocess
import gdb
import objdump
import strip
from SCons.Action import _subproc
import subprocess
from SCons.Errors import StopError
from SCons.Tool import ar, asm, gcc, gnulink, gxx
def prefix_commands(env, command_prefix, cmd_list):

View file

@ -1,15 +1,14 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Errors import StopError
from SCons.Warnings import warn, WarningOnByDefault
from ansi.color import fg
from fbt.appmanifest import (
FlipperAppType,
AppManager,
ApplicationsCGenerator,
AppManager,
FlipperAppType,
FlipperManifestException,
)
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Errors import StopError
from SCons.Warnings import WarningOnByDefault, warn
# Adding objects for application management to env
# AppManager env["APPMGR"] - loads all manifests; manages list of known apps

View file

@ -1,10 +1,10 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Errors import StopError
import os
import subprocess
from ansi.color import fg
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Errors import StopError
def icons_emitter(target, source, env):
@ -76,11 +76,11 @@ def proto_ver_generator(target, source, env):
target_file = target[0]
src_dir = source[0].dir.abspath
try:
git_fetch = _invoke_git(
_invoke_git(
["fetch", "--tags"],
source_dir=src_dir,
)
except (subprocess.CalledProcessError, EnvironmentError) as e:
except (subprocess.CalledProcessError, EnvironmentError):
# Not great, not terrible
print(fg.boldred("Git: fetch failed"))
@ -89,7 +89,7 @@ def proto_ver_generator(target, source, env):
["describe", "--tags", "--abbrev=0"],
source_dir=src_dir,
)
except (subprocess.CalledProcessError, EnvironmentError) as e:
except (subprocess.CalledProcessError, EnvironmentError):
raise StopError("Git: describe failed")
git_major, git_minor = git_describe.split(".")

View file

@ -1,5 +1,3 @@
from re import search
from SCons.Errors import UserError

View file

@ -1,6 +1,5 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Script import Mkdir
from SCons.Builder import Builder
from SCons.Defaults import Touch

View file

@ -3,23 +3,19 @@ import os
import pathlib
import shutil
from dataclasses import dataclass, field
from typing import Optional, TypedDict
from ansi.color import fg
from typing import Optional
import SCons.Warnings
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Errors import UserError
from SCons.Node import NodeList
from SCons.Node.FS import File, Entry
from ansi.color import fg
from fbt.appmanifest import FlipperApplication, FlipperAppType, FlipperManifestException
from fbt.elfmanifest import assemble_manifest_data
from fbt.fapassets import FileBundler
from fbt.sdk.cache import SdkCache
from fbt.util import extract_abs_dir_path
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Errors import UserError
from SCons.Node.FS import Entry, File
_FAP_META_SECTION = ".fapmeta"
_FAP_FILEASSETS_SECTION = ".fapassets"
@ -289,7 +285,7 @@ def GetExtAppByIdOrPath(env, app_dir):
try:
# Maybe user passed an appid?
app = appmgr.get(app_dir)
except FlipperManifestException as _:
except FlipperManifestException:
# Look up path components in known app dirs
for dir_part in reversed(pathlib.Path(app_dir).parts):
if app := appmgr.find_by_appdir(dir_part):

View file

@ -1,5 +1,3 @@
from SCons.Builder import Builder
from SCons.Action import Action
import json

View file

@ -1,21 +1,20 @@
import json
import os.path
import pathlib
import posixpath
import shutil
from SCons.Builder import Builder
from fbt.sdk.cache import SdkCache
from fbt.sdk.collector import SdkCollector
from fbt.util import path_as_posix
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Errors import UserError
# from SCons.Scanner import C
from SCons.Script import Entry
from SCons.Util import LogicalLines
import os.path
import posixpath
import pathlib
import json
from fbt.sdk.collector import SdkCollector
from fbt.sdk.cache import SdkCache
from fbt.util import path_as_posix
def ProcessSdkDepends(env, filename):
try:

View file

@ -1,15 +1,13 @@
import os
import sys
import traceback
import SCons.Warnings as Warnings
from ansi.color import fg
from SCons.Errors import UserError
# from SCons.Script.Main import find_deepest_user_frame
from ansi.color import fg, bg, fx
import traceback
import sys
import os
def find_deepest_user_frame(tb):
tb.reverse()

View file

@ -1,5 +1,5 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Builder import Builder
def version_emitter(target, source, env):

View file

@ -1,6 +1,6 @@
from SCons.Builder import Builder
from SCons.Action import Action
import SCons
from SCons.Action import Action
from SCons.Builder import Builder
__OBJCOPY_ARM_BIN = "arm-none-eabi-objcopy"
__NM_ARM_BIN = "arm-none-eabi-nm"

View file

@ -1,7 +1,3 @@
from SCons.Builder import Builder
from SCons.Action import Action
def generate(env):
env.SetDefault(
GDB="gdb",

View file

@ -1,5 +1,5 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Builder import Builder
def generate(env):

View file

@ -1,7 +1,7 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Defaults import Touch
import SCons
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Defaults import Touch
__OPENOCD_BIN = "openocd"

View file

@ -1,11 +1,12 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Script import Delete, Mkdir, GetBuildFailures, Flatten
import multiprocessing
import webbrowser
import atexit
import sys
import multiprocessing
import subprocess
import sys
import webbrowser
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Script import Delete, Flatten, GetBuildFailures, Mkdir
__no_browser = False

View file

@ -1,5 +1,6 @@
import posixpath
import os
import posixpath
from SCons.Errors import UserError

View file

@ -1,6 +1,6 @@
import SCons
from SCons.Script import Flatten
from fbt.util import GLOB_FILE_EXCLUSION
from SCons.Script import Flatten
def GlobRecursive(env, pattern, node=".", exclude=[]):

View file

@ -1,5 +1,5 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Builder import Builder
def generate(env):

View file

@ -1,13 +1,9 @@
#!/usr/bin/env python3
import logging
import argparse
import sys
import os
from flipper.app import App
from flipper.cube import CubeProgrammer
from flipper.assets.coprobin import CoproBinary
from flipper.cube import CubeProgrammer
STATEMENT = "AGREE_TO_LOSE_FLIPPER_FEATURES_THAT_USE_CRYPTO_ENCLAVE"
@ -94,59 +90,59 @@ class Main(App):
}
def wipe(self):
self.logger.info(f"Wiping flash")
self.logger.info("Wiping flash")
cp = CubeProgrammer(self._getCubeParams())
self.logger.info(f"Setting RDP to 0xBB")
self.logger.info("Setting RDP to 0xBB")
cp.setOptionBytes({"RDP": ("0xBB", "rw")})
self.logger.info(f"Verifying RDP")
self.logger.info("Verifying RDP")
r = cp.checkOptionBytes({"RDP": ("0xBB", "rw")})
assert r == True
assert r is True
self.logger.info(f"Result: {r}")
self.logger.info(f"Setting RDP to 0xAA")
self.logger.info("Setting RDP to 0xAA")
cp.setOptionBytes({"RDP": ("0xAA", "rw")})
self.logger.info(f"Verifying RDP")
self.logger.info("Verifying RDP")
r = cp.checkOptionBytes({"RDP": ("0xAA", "rw")})
assert r == True
assert r is True
self.logger.info(f"Result: {r}")
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0
def core1bootloader(self):
self.logger.info(f"Flashing bootloader")
self.logger.info("Flashing bootloader")
cp = CubeProgrammer(self._getCubeParams())
cp.flashBin("0x08000000", self.args.bootloader)
self.logger.info(f"Complete")
self.logger.info("Complete")
cp.resetTarget()
return 0
def core1firmware(self):
self.logger.info(f"Flashing firmware")
self.logger.info("Flashing firmware")
cp = CubeProgrammer(self._getCubeParams())
cp.flashBin("0x08008000", self.args.firmware)
self.logger.info(f"Complete")
self.logger.info("Complete")
cp.resetTarget()
return 0
def core1(self):
self.logger.info(f"Flashing bootloader")
self.logger.info("Flashing bootloader")
cp = CubeProgrammer(self._getCubeParams())
cp.flashBin("0x08000000", self.args.bootloader)
self.logger.info(f"Flashing firmware")
self.logger.info("Flashing firmware")
cp.flashBin("0x08008000", self.args.firmware)
cp.resetTarget()
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0
def core2fus(self):
if self.args.statement != STATEMENT:
self.logger.error(
f"PLEASE DON'T. THIS FEATURE INTENDED ONLY FOR FACTORY FLASHING"
"PLEASE DON'T. THIS FEATURE INTENDED ONLY FOR FACTORY FLASHING"
)
return 1
self.logger.info(f"Flashing Firmware Update Service")
self.logger.info("Flashing Firmware Update Service")
cp = CubeProgrammer(self._getCubeParams())
cp.flashCore2(self.args.fus_address, self.args.fus)
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0
def core2radio(self):
@ -163,15 +159,15 @@ class Main(App):
f"Radio address not provided, guessed as 0x{radio_address:X}"
)
if radio_address > 0x080E0000:
self.logger.error(f"I KNOW WHAT YOU DID LAST SUMMER")
self.logger.error("I KNOW WHAT YOU DID LAST SUMMER")
return 1
cp = CubeProgrammer(self._getCubeParams())
self.logger.info(f"Removing Current Radio Stack")
self.logger.info("Removing Current Radio Stack")
cp.deleteCore2RadioStack()
self.logger.info(f"Flashing Radio Stack")
self.logger.info("Flashing Radio Stack")
cp.flashCore2(radio_address, self.args.radio)
self.logger.info(f"Complete")
self.logger.info("Complete")
return 0

View file

@ -44,7 +44,7 @@ class App:
if isinstance(return_code, int):
return self._exit(return_code)
else:
self.logger.error(f"Missing return code")
self.logger.error("Missing return code")
return self._exit(255)
def _exit(self, code):

View file

@ -6,7 +6,7 @@ import xml.etree.ElementTree as ET
import posixpath
import os
from flipper.utils import *
from flipper.utils import file_sha256, timestamp
from flipper.assets.coprobin import CoproBinary, get_stack_type
@ -45,13 +45,13 @@ class Copro:
cube_manifest = ET.parse(cube_manifest_file)
cube_package = cube_manifest.find("PackDescription")
if not cube_package:
raise Exception(f"Unknown Cube manifest format")
raise Exception("Unknown Cube manifest format")
cube_version = cube_package.get("Patch") or cube_package.get("Release")
if not cube_version or not cube_version.startswith("FW.WB"):
raise Exception(f"Incorrect Cube package or version info")
raise Exception("Incorrect Cube package or version info")
cube_version = cube_version.replace("FW.WB.", "", 1)
if cube_version != reference_cube_version:
raise Exception(f"Unsupported cube version")
raise Exception("Unsupported cube version")
self.version = cube_version
def _getFileName(self, name):

View file

@ -1,6 +1,7 @@
import struct
import math
import os, os.path
import os
import os.path
import sys

View file

@ -1,13 +1,11 @@
import multiprocessing
import logging
import os
import sys
import shutil
from collections import Counter
from flipper.utils.fff import *
from flipper.utils.templite import *
from .icon import *
from flipper.utils.fff import FlipperFormatFile
from flipper.utils.templite import Templite
from .icon import ImageTools, file2image
def _convert_image_to_bm(pair: set):
@ -121,7 +119,7 @@ class DolphinBubbleAnimation:
self.meta["Passive frames"] + self.meta["Active frames"]
== ordered_frames_count
)
except EOFError as e:
except EOFError:
raise Exception("Invalid meta file: too short")
except AssertionError as e:
self.logger.exception(e)
@ -158,7 +156,7 @@ class DolphinBubbleAnimation:
except AssertionError as e:
self.logger.exception(e)
self.logger.error(
f"Animation {self.name} bubble slot {bubble_slot} got incorrect data: {bubble}"
f"Animation {self.name} bubble slot {bubble['Slot']} got incorrect data: {bubble}"
)
raise Exception("Meta file is invalid: incorrect bubble data")
except EOFError:

View file

@ -1,9 +1,6 @@
import logging
import argparse
import subprocess
import io
import os
import sys
ICONS_SUPPORTED_FORMATS = ["png"]
@ -36,11 +33,8 @@ class ImageTools:
@staticmethod
def is_processing_slow():
try:
from PIL import Image, ImageOps
import heatshrink2
return False
except ImportError as e:
except ImportError:
return True
def __init__(self):
@ -52,7 +46,7 @@ class ImageTools:
try:
from PIL import Image, ImageOps
except ImportError as e:
except ImportError:
self.__pil_unavailable = True
self.logger.info("pillow module is missing, using convert cli util")
return self.png2xbm(file)
@ -72,7 +66,7 @@ class ImageTools:
try:
import heatshrink2
except ImportError as e:
except ImportError:
self.__hs2_unavailable = True
self.logger.info("heatshrink2 module is missing, using heatshrink cli util")
return self.xbm2hs(data)

View file

@ -1,11 +1,10 @@
import datetime
import logging
import os
import posixpath
from pathlib import Path
from flipper.utils import *
from flipper.utils.fstree import *
from flipper.utils import timestamp, file_md5
from flipper.utils.fstree import FsNode, compare_fs_trees
MANIFEST_VERSION = 0

View file

@ -1,7 +1,5 @@
#!/usr/bin/env python3
import logging
import struct
from enum import Enum
from dataclasses import dataclass
@ -181,7 +179,7 @@ class OptionBytesData:
def gen_values(self):
obref = ObReferenceValuesGenerator()
converted_refs = list(obref.apply(ob) for ob in self.obs)
list(obref.apply(ob) for ob in self.obs)
return obref

View file

@ -14,7 +14,7 @@ class CubeProgrammer:
if "port" in config and config["port"]:
connect.append(f"port={config['port']}")
else:
connect.append(f"port=swd")
connect.append("port=swd")
if "serial" in config and config["serial"]:
connect.append(f"sn={config['serial']}")
self.params.append("-c " + " ".join(connect))
@ -43,20 +43,20 @@ class CubeProgrammer:
return output.decode()
def getVersion(self):
output = self._execute(["--version"])
self._execute(["--version"])
def checkOptionBytes(self, option_bytes):
output = self._execute(["-ob displ"])
ob_correct = True
for line in output.split("\n"):
line = line.strip()
if not ":" in line:
if ":" not in line:
self.logger.debug(f"Skipping line: {line}")
continue
key, data = line.split(":", 1)
key = key.strip()
data = data.strip()
if not key in option_bytes.keys():
if key not in option_bytes.keys():
self.logger.debug(f"Skipping key: {key}")
continue
self.logger.debug(f"Processing key: {key} {data}")

View file

@ -151,7 +151,7 @@ class FlipperStorage:
try:
# TODO: better decoding, considering non-ascii characters
line = line.decode("ascii")
except:
except Exception:
continue
line = line.strip()
@ -194,7 +194,7 @@ class FlipperStorage:
try:
# TODO: better decoding, considering non-ascii characters
line = line.decode("ascii")
except:
except Exception:
continue
line = line.strip()

View file

@ -1,6 +1,5 @@
import datetime
import hashlib
import os
def timestamp():

View file

@ -31,13 +31,13 @@ class OpenOCDProgrammer(Programmer):
config["interface"] = interface
config["target"] = "target/stm32wbx.cfg"
if not serial is None:
if serial is not None:
if interface == "interface/cmsis-dap.cfg":
config["serial"] = f"cmsis_dap_serial {serial}"
elif "stlink" in interface:
config["serial"] = f"stlink_serial {serial}"
if not port_base is None:
if port_base is not None:
config["port_base"] = port_base
self.openocd = OpenOCD(config)
@ -59,7 +59,7 @@ class OpenOCDProgrammer(Programmer):
raise Exception(f"File {file_path} not found")
self.openocd.start()
self.openocd.send_tcl(f"init")
self.openocd.send_tcl("init")
self.openocd.send_tcl(
f"program {file_path} 0x{address:08x}{' verify' if verify else ''} reset exit"
)
@ -196,7 +196,7 @@ class OpenOCDProgrammer(Programmer):
if ob_need_to_apply:
stm32.option_bytes_apply(self.openocd)
else:
self.logger.info(f"Option Bytes are already correct")
self.logger.info("Option Bytes are already correct")
# Load Option Bytes
# That will reset and also lock the Option Bytes and the Flash
@ -256,7 +256,7 @@ class OpenOCDProgrammer(Programmer):
already_written = False
if already_written:
self.logger.info(f"OTP memory is already written with the given data")
self.logger.info("OTP memory is already written with the given data")
return OpenOCDProgrammerResult.Success
self.reset(self.RunMode.Stop)

View file

@ -123,7 +123,7 @@ class STM32WB55:
def clear_flash_errors(self, oocd: OpenOCD):
# Errata 2.2.9: Flash OPTVERR flag is always set after system reset
# And also clear all other flash error flags
self.logger.debug(f"Resetting flash errors")
self.logger.debug("Resetting flash errors")
self.FLASH_SR.load(oocd)
self.FLASH_SR.OP_ERR = 1
self.FLASH_SR.PROG_ERR = 1
@ -218,7 +218,7 @@ class STM32WB55:
raise Exception("Flash lock failed")
def option_bytes_apply(self, oocd: OpenOCD):
self.logger.debug(f"Applying Option Bytes")
self.logger.debug("Applying Option Bytes")
self.FLASH_CR.load(oocd)
self.FLASH_CR.OPT_STRT = 1
@ -228,7 +228,7 @@ class STM32WB55:
self.flash_wait_for_operation(oocd)
def option_bytes_load(self, oocd: OpenOCD):
self.logger.debug(f"Loading Option Bytes")
self.logger.debug("Loading Option Bytes")
self.FLASH_CR.load(oocd)
self.FLASH_CR.OBL_LAUNCH = 1
self.FLASH_CR.store(oocd)

View file

@ -77,8 +77,8 @@ class TempliteCompiler:
return
lines = self.block.splitlines()
margin = min(len(l) - len(l.lstrip()) for l in lines if l.strip())
self.block = "\n".join("\t" * self.offset + l[margin:] for l in lines)
margin = min(len(line) - len(line.lstrip()) for line in lines if line.strip())
self.block = "\n".join("\t" * self.offset + line[margin:] for line in lines)
self.blocks.append(self.block)
if self.block.endswith(":"):
self.offset += 1

View file

@ -1,10 +1,11 @@
#!/usr/bin/env python3
from flipper.app import App
import subprocess
import os
import math
import os
import subprocess
from ansi.color import fg
from flipper.app import App
class Main(App):

View file

@ -1,14 +1,14 @@
#!/usr/bin/env python3
import ssl
import json
import os
import shlex
import re
import string
import random
import argparse
import datetime
import json
import os
import random
import re
import shlex
import ssl
import string
import urllib.request

View file

@ -1,14 +1,13 @@
#!/usr/bin/env python3
import multiprocessing
import os
import re
import shutil
import subprocess
import multiprocessing
from flipper.app import App
SOURCE_CODE_FILE_EXTENSIONS = [".h", ".c", ".cpp", ".cxx", ".hpp"]
SOURCE_CODE_FILE_PATTERN = r"^[0-9A-Za-z_]+\.[a-z]+$"
SOURCE_CODE_DIR_PATTERN = r"^[0-9A-Za-z_]+$"
@ -59,7 +58,7 @@ class Main(App):
show_message = True
if show_message:
self.logger.warning(
f"Folders are not renamed automatically, please fix it by yourself"
"Folders are not renamed automatically, please fix it by yourself"
)
def _find_sources(self, folders: list):
@ -70,7 +69,7 @@ class Main(App):
for filename in filenames:
ext = os.path.splitext(filename.lower())[1]
if not ext in SOURCE_CODE_FILE_EXTENSIONS:
if ext not in SOURCE_CODE_FILE_EXTENSIONS:
continue
output.append(os.path.join(dirpath, filename))
return output
@ -80,7 +79,7 @@ class Main(App):
try:
subprocess.check_call(task)
return True
except subprocess.CalledProcessError as e:
except subprocess.CalledProcessError:
return False
def _format_sources(self, sources: list, dry_run: bool = False):
@ -144,7 +143,7 @@ class Main(App):
def _apply_file_permissions(self, sources: list, dry_run: bool = False):
execute_permissions = 0o111
pattern = re.compile(SOURCE_CODE_FILE_PATTERN)
re.compile(SOURCE_CODE_FILE_PATTERN)
good = []
bad = []
# Check sources for unexpected execute permissions

View file

@ -1,9 +1,10 @@
#!/usr/bin/env python3
import argparse
import os
import re
import sys
import argparse
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

View file

@ -1,8 +1,9 @@
#!/usr/bin/env python3
from flipper.app import App
import json
from flipper.app import App
class Main(App):
def init(self):

View file

@ -44,7 +44,7 @@ class Main(App):
)
def check(self):
self.logger.info(f"Checking Option Bytes")
self.logger.info("Checking Option Bytes")
# OpenOCD
openocd = OpenOCDProgrammer(
@ -60,7 +60,7 @@ class Main(App):
return return_code
def set(self):
self.logger.info(f"Setting Option Bytes")
self.logger.info("Setting Option Bytes")
# OpenOCD
openocd = OpenOCDProgrammer(

View file

@ -1,13 +1,13 @@
#!/usr/bin/env python3
import datetime
import logging
import argparse
import subprocess
import os
import sys
import re
import struct
import datetime
from flipper.app import App
from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult
OTP_MAGIC = 0xBABE
OTP_VERSION = 0x02
@ -33,9 +33,6 @@ OTP_DISPLAYS = {
"mgg": 0x02,
}
from flipper.app import App
from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult
class OTPException(Exception):
def __init__(self, message: str, result: OpenOCDProgrammerResult):
@ -158,7 +155,7 @@ class Main(App):
)
def generate_all(self):
self.logger.info(f"Generating OTP")
self.logger.info("Generating OTP")
self._processFirstArgs()
self._processSecondArgs()
with open(f"{self.args.file}_first.bin", "wb") as file:
@ -172,18 +169,18 @@ class Main(App):
return 0
def flash_first(self):
self.logger.info(f"Flashing first block of OTP")
self.logger.info("Flashing first block of OTP")
self._processFirstArgs()
filename = f"otp_unknown_first_{self.timestamp}.bin"
try:
self.logger.info(f"Packing binary data")
self.logger.info("Packing binary data")
with open(filename, "wb") as file:
file.write(self._packFirst())
self.logger.info(f"Flashing OTP")
self.logger.info("Flashing OTP")
openocd = OpenOCDProgrammer(
self.args.interface,
@ -195,7 +192,7 @@ class Main(App):
if programmer_result != OpenOCDProgrammerResult.Success:
raise OTPException("Failed to flash OTP", programmer_result)
self.logger.info(f"Flashed Successfully")
self.logger.info("Flashed Successfully")
except OTPException as e:
self.logger.exception(e)
return e.get_exit_code()
@ -205,18 +202,18 @@ class Main(App):
return 0
def flash_second(self):
self.logger.info(f"Flashing second block of OTP")
self.logger.info("Flashing second block of OTP")
self._processSecondArgs()
filename = f"otp_{self.args.name}_second_{self.timestamp}.bin"
try:
self.logger.info(f"Packing binary data")
self.logger.info("Packing binary data")
with open(filename, "wb") as file:
file.write(self._packSecond())
self.logger.info(f"Flashing OTP")
self.logger.info("Flashing OTP")
openocd = OpenOCDProgrammer(
self.args.interface,
@ -228,7 +225,7 @@ class Main(App):
if programmer_result != OpenOCDProgrammerResult.Success:
raise OTPException("Failed to flash OTP", programmer_result)
self.logger.info(f"Flashed Successfully")
self.logger.info("Flashed Successfully")
except OTPException as e:
self.logger.exception(e)
return e.get_exit_code()
@ -238,7 +235,7 @@ class Main(App):
return 0
def flash_all(self):
self.logger.info(f"Flashing OTP")
self.logger.info("Flashing OTP")
self._processFirstArgs()
self._processSecondArgs()
@ -246,12 +243,12 @@ class Main(App):
filename = f"otp_{self.args.name}_whole_{self.timestamp}.bin"
try:
self.logger.info(f"Packing binary data")
self.logger.info("Packing binary data")
with open(filename, "wb") as file:
file.write(self._packFirst())
file.write(self._packSecond())
self.logger.info(f"Flashing OTP")
self.logger.info("Flashing OTP")
openocd = OpenOCDProgrammer(
self.args.interface,
@ -263,7 +260,7 @@ class Main(App):
if programmer_result != OpenOCDProgrammerResult.Success:
raise OTPException("Failed to flash OTP", programmer_result)
self.logger.info(f"Flashed Successfully")
self.logger.info("Flashed Successfully")
except OTPException as e:
self.logger.exception(e)
return e.get_exit_code()

View file

@ -1,13 +1,13 @@
#!/usr/bin/env python3
import typing
import subprocess
import logging
import time
import os
import socket
import subprocess
import time
import typing
from abc import ABC, abstractmethod
from dataclasses import dataclass
from flipper.app import App
@ -223,7 +223,7 @@ class BlackmagicProgrammer(Programmer):
try:
socket.inet_aton(address)
return True
except:
except Exception:
return False
def set_serial(self, serial: str):
@ -415,12 +415,12 @@ class Main(App):
if len(interfaces) == 0:
interfaces = [p for p in network_programmers if p.get_name() == i_name]
else:
self.logger.info(f"Probing for interfaces...")
self.logger.info("Probing for interfaces...")
interfaces = self._search_interface(self.args.serial)
if len(interfaces) == 0:
# Probe network blackmagic
self.logger.info(f"Probing for network interfaces...")
self.logger.info("Probing for network interfaces...")
interfaces = self._search_network_interface(self.args.serial)
if len(interfaces) == 0:

View file

@ -1,14 +1,12 @@
#!/usr/bin/env python3
import operator
from functools import reduce
from flipper.app import App
from flipper.storage import FlipperStorage, FlipperStorageOperations
from flipper.utils.cdc import resolve_port
import os
import posixpath
from functools import reduce
import operator
class Main(App):
def init(self):
@ -38,8 +36,8 @@ class Main(App):
self.parser.set_defaults(func=self.install)
@staticmethod
def flatten(l):
return reduce(operator.concat, l, [])
def flatten(item_list):
return reduce(operator.concat, item_list, [])
def install(self):
self.args.sources = self.flatten(self.args.sources)

View file

@ -5,7 +5,7 @@ import shutil
import tarfile
import zipfile
from os import makedirs, walk
from os.path import exists, join, relpath, basename, split
from os.path import basename, exists, join, relpath
from ansi.color import fg
from flipper.app import App

View file

@ -1,14 +1,12 @@
#!/usr/bin/env python3
from typing import final
from flipper.app import App
from flipper.storage import FlipperStorage, FlipperStorageOperations
from flipper.utils.cdc import resolve_port
import logging
import os
import pathlib
import serial.tools.list_ports as list_ports
from flipper.app import App
from flipper.storage import FlipperStorage, FlipperStorageOperations
from flipper.utils.cdc import resolve_port
class Main(App):
@ -54,7 +52,7 @@ class Main(App):
f"update install {flipper_update_path}/{manifest_name}\r"
)
result = storage.read.until(storage.CLI_EOL)
if not b"Verifying" in result:
if b"Verifying" not in result:
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
return 3
result = storage.read.until(storage.CLI_EOL)

View file

@ -1,9 +1,10 @@
import logging
import subprocess
from flipper.utils.cdc import resolve_port
import os
import subprocess
import sys
from flipper.utils.cdc import resolve_port
def main():
logger = logging.getLogger()

View file

@ -1,14 +1,14 @@
#!/usr/bin/env python3
import binascii
import filecmp
import os
import tempfile
from flipper.app import App
from flipper.storage import FlipperStorage, FlipperStorageOperations
from flipper.utils.cdc import resolve_port
import os
import binascii
import filecmp
import tempfile
def WrapStorageOp(func):
def wrapper(*args, **kwargs):
@ -122,7 +122,7 @@ class Main(App):
try:
print("Text data:")
print(data.decode())
except:
except Exception:
print("Binary hexadecimal data:")
print(binascii.hexlify(data).decode())

View file

@ -1,7 +1,6 @@
from SCons.Platform import TempFileMunge
from SCons.Node import FS
from SCons.Errors import UserError
from SCons.Warnings import warn, WarningOnByDefault
import os
@ -14,6 +13,7 @@ SetOption("max_drift", 1)
ufbt_state_dir = Dir(os.environ.get("UFBT_STATE_DIR", "#.ufbt"))
ufbt_script_dir = Dir(os.environ.get("UFBT_SCRIPT_DIR"))
ufbt_build_dir = ufbt_state_dir.Dir("build")
ufbt_current_sdk_dir = ufbt_state_dir.Dir("current")
@ -63,16 +63,7 @@ core_env = Environment(
],
)
if "update" in BUILD_TARGETS:
SConscript(
"update.scons",
exports={"core_env": core_env},
)
if "purge" in BUILD_TARGETS:
core_env.Execute(Delete(ufbt_state_dir))
print("uFBT state purged")
Exit(0)
core_env.Append(CPPDEFINES=GetOption("extra_defines"))
# Now we can import stuff bundled with SDK - it was added to sys.path by ufbt_state
@ -109,7 +100,7 @@ env = core_env.Clone(
"fbt_assets",
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
],
FBT_FAP_DEBUG_ELF_ROOT=ufbt_state_dir.Dir("build"),
FBT_FAP_DEBUG_ELF_ROOT=ufbt_build_dir,
TEMPFILE=TempFileMunge,
MAXLINELENGTH=2048,
PROGSUFFIX=".elf",
@ -427,3 +418,25 @@ dist_env.PhonyTarget(
"get_apiversion",
"@echo $( ${UFBT_API_VERSION} $)",
)
# Dolphin animation builder. Expects "external" directory in current dir
# with animation sources & manifests. Builds & uploads them to connected Flipper
dolphin_src_dir = original_app_dir.Dir("external")
if dolphin_src_dir.exists():
dolphin_dir = ufbt_build_dir.Dir("dolphin")
dolphin_external = dist_env.DolphinExtBuilder(
ufbt_build_dir.Dir("dolphin"),
original_app_dir,
DOLPHIN_RES_TYPE="external",
)
dist_env.PhonyTarget(
"dolphin_ext",
'${PYTHON3} ${FBT_SCRIPT_DIR}/storage.py send "${SOURCE}" /ext/dolphin',
source=ufbt_build_dir.Dir("dolphin"),
)
else:
def missing_dolphin_folder(**kw):
raise UserError(f"Dolphin folder not found: {dolphin_src_dir}")
dist_env.PhonyTarget("dolphin_ext", Action(missing_dolphin_folder, None))

View file

@ -1,32 +1,18 @@
AddOption(
"--extra-define",
action="append",
dest="extra_defines",
default=[],
help="Extra global define that will be passed to C/C++ compiler, can be specified multiple times",
)
AddOption(
"--proxy-env",
action="store",
dest="proxy_env",
default="",
help="Comma-separated list of additional environment variables to pass to child SCons processes",
)
AddOption(
"--channel",
action="store",
dest="sdk_channel",
choices=["dev", "rc", "release"],
default="",
help="Release channel to use for SDK",
)
AddOption(
"--branch",
action="store",
dest="sdk_branch",
help="Custom main repo branch to use for SDK",
)
AddOption(
"--hw-target",
action="store",
dest="sdk_target",
help="SDK Hardware target",
help="Comma-separated list of additional environment variables to pass to "
"child SCons processes",
)
vars = Variables("ufbt_options.py", ARGUMENTS)

View file

@ -1,8 +1,8 @@
from SCons.Script import GetBuildFailures
import SCons.Errors
import atexit
import SCons.Errors
from ansi.color import fg, fx
from SCons.Script import GetBuildFailures
def bf_to_str(bf):

View file

@ -1,12 +1,11 @@
from SCons.Errors import StopError
from SCons.Warnings import warn, WarningOnByDefault
import json
import os
import sys
import pathlib
import sys
from functools import reduce
from SCons.Errors import StopError
def _load_sdk_data(sdk_root):
split_vars = {

View file

@ -1,37 +0,0 @@
from SCons.Errors import StopError
Import("core_env")
update_env = core_env.Clone(
toolpath=[core_env["FBT_SCRIPT_DIR"].Dir("fbt_tools")],
tools=["python3"],
)
print("Updating SDK...")
ufbt_state = update_env["UFBT_STATE"]
update_args = [
"--ufbt-dir",
f'"{update_env["UFBT_STATE_DIR"]}"',
]
if branch_name := GetOption("sdk_branch"):
update_args.extend(["--branch", branch_name])
elif channel_name := GetOption("sdk_channel"):
update_args.extend(["--channel", channel_name])
elif branch_name := ufbt_state.get("branch", None):
update_args.extend(["--branch", branch_name])
elif channel_name := ufbt_state.get("channel", None):
update_args.extend(["--channel", channel_name])
else:
raise StopError("No branch or channel specified for SDK update")
if hw_target := GetOption("sdk_target"):
update_args.extend(["--hw-target", hw_target])
else:
update_args.extend(["--hw-target", ufbt_state["hw_target"]])
update_env.Replace(UPDATE_ARGS=update_args)
result = update_env.Execute(
update_env.subst('$PYTHON3 "$UFBT_BOOTSTRAP_SCRIPT" $UPDATE_ARGS'),
)
Exit(result)

View file

@ -1,16 +1,16 @@
#!/usr/bin/env python3
from flipper.app import App
from flipper.utils.fff import FlipperFormatFile
from flipper.assets.coprobin import CoproBinary, get_stack_type
from flipper.assets.obdata import OptionBytesData, ObReferenceValues
from os.path import basename, join, exists
import math
import os
import shutil
import zlib
import tarfile
import math
import zlib
from os.path import exists, join
from flipper.app import App
from flipper.assets.coprobin import CoproBinary, get_stack_type
from flipper.assets.obdata import ObReferenceValues, OptionBytesData
from flipper.utils.fff import FlipperFormatFile
from slideshow import Main as SlideshowMain
@ -267,9 +267,9 @@ class Main(App):
@staticmethod
def batch(iterable, n=1):
l = len(iterable)
for ndx in range(0, l, n):
yield iterable[ndx : min(ndx + n, l)]
iterable_len = len(iterable)
for ndx in range(0, iterable_len, n):
yield iterable[ndx : min(ndx + n, iterable_len)]
if __name__ == "__main__":

View file

@ -1,12 +1,12 @@
#!/usb/bin/env python3
from flipper.app import App
import subprocess
import os
import json
import os
import subprocess
from datetime import date, datetime
from flipper.app import App
class GitVersion:
REVISION_SUFFIX_LENGTH = 8

View file

@ -1,12 +1,12 @@
from dataclasses import dataclass, field
from fbt.appmanifest import FlipperAppType
from SCons.Node import NodeList
from SCons.Warnings import warn, WarningOnByDefault
from SCons.Errors import UserError
Import("ENV")
from fbt.appmanifest import FlipperAppType
appenv = ENV["APPENV"] = ENV.Clone(
tools=[