1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 12:42:30 +04:00

Merge branch 'fz-dev' into dev

This commit is contained in:
MX
2023-01-18 18:26:49 +03:00
79 changed files with 1133 additions and 847 deletions

View File

@@ -7,7 +7,7 @@ from SCons.Node import NodeList
import SCons.Warnings
from fbt.elfmanifest import assemble_manifest_data
from fbt.appmanifest import FlipperApplication, FlipperManifestException
from fbt.appmanifest import FlipperApplication, FlipperManifestException, FlipperAppType
from fbt.sdk.cache import SdkCache
from fbt.util import extract_abs_dir_path
@@ -32,6 +32,7 @@ def BuildAppElf(env, app):
ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR")
app_work_dir = os.path.join(ext_apps_work_dir, app.appid)
env.SetDefault(_APP_ICONS=[])
env.VariantDir(app_work_dir, app._appdir, duplicate=False)
app_env = env.Clone(FAP_SRC_DIR=app._appdir, FAP_WORK_DIR=app_work_dir)
@@ -63,6 +64,7 @@ def BuildAppElf(env, app):
icon_bundle_name=f"{app.fap_icon_assets_symbol if app.fap_icon_assets_symbol else app.appid }_icons",
)
app_env.Alias("_fap_icons", fap_icons)
env.Append(_APP_ICONS=[fap_icons])
private_libs = []
@@ -232,11 +234,18 @@ def GetExtAppFromPath(env, app_dir):
return app_artifacts
def fap_dist_emitter(target, source, env):
def resources_fap_dist_emitter(target, source, env):
target_dir = target[0]
target = []
for _, app_artifacts in env["EXT_APPS"].items():
# We don't deploy example apps & debug tools with SD card resources
if (
app_artifacts.app.apptype == FlipperAppType.DEBUG
or app_artifacts.app.fap_category == "Examples"
):
continue
source.extend(app_artifacts.compact)
target.append(
target_dir.Dir(app_artifacts.app.fap_category).File(
@@ -247,7 +256,7 @@ def fap_dist_emitter(target, source, env):
return (target, source)
def fap_dist_action(target, source, env):
def resources_fap_dist_action(target, source, env):
# FIXME
target_dir = env.Dir("#/assets/resources/apps")
@@ -280,10 +289,10 @@ def generate(env, **kw):
BUILDERS={
"FapDist": Builder(
action=Action(
fap_dist_action,
resources_fap_dist_action,
"$FAPDISTCOMSTR",
),
emitter=fap_dist_emitter,
emitter=resources_fap_dist_emitter,
),
"EmbedAppMetadata": Builder(
action=[

View File

@@ -11,6 +11,8 @@ Building:
Build all FAP apps
fap_{APPID}, launch_app APPSRC={APPID}:
Build FAP app with appid={APPID}; upload & start it over USB
fap_deploy:
Build and upload all FAP apps over USB
Flashing & debugging:
flash, flash_blackmagic, jflash:
@@ -29,6 +31,8 @@ Other:
run linters
format, format_py:
run code formatters
firmware_pvs:
generate a PVS-Studio report
For more targets & info, see documentation/fbt.md
"""

View File

@@ -0,0 +1,106 @@
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Script import Delete, Mkdir, GetBuildFailures
import multiprocessing
import webbrowser
import atexit
import sys
import subprocess
__no_browser = False
def _set_browser_action(target, source, env):
if env["PVSNOBROWSER"]:
global __no_browser
__no_browser = True
def emit_pvsreport(target, source, env):
target_dir = env["REPORT_DIR"]
if env["PLATFORM"] == "win32":
# Report generator on Windows emits to a subfolder of given output folder
target_dir = target_dir.Dir("fullhtml")
return [target_dir.File("index.html")], source
def atexist_handler():
global __no_browser
if __no_browser:
return
for bf in GetBuildFailures():
if bf.node.exists and bf.node.name.endswith(".html"):
# macOS
if sys.platform == "darwin":
subprocess.run(["open", bf.node.abspath])
else:
webbrowser.open(bf.node.abspath)
break
def generate(env):
env.SetDefault(
PVSNCORES=multiprocessing.cpu_count(),
PVSOPTIONS=[
"@.pvsoptions",
"-j${PVSNCORES}",
# "--incremental", # kinda broken on PVS side
],
PVSCONVOPTIONS=[
"-a",
"GA:1,2,3",
"-t",
"fullhtml",
"--indicate-warnings",
],
)
if env["PLATFORM"] == "win32":
env.SetDefault(
PVSCHECKBIN="CompilerCommandsAnalyzer.exe",
PVSCONVBIN="PlogConverter.exe",
)
else:
env.SetDefault(
PVSCHECKBIN="pvs-studio-analyzer",
PVSCONVBIN="plog-converter",
)
if not env["VERBOSE"]:
env.SetDefault(
PVSCHECKCOMSTR="\tPVS\t${TARGET}",
PVSCONVCOMSTR="\tPVSREP\t${TARGET}",
)
env.Append(
BUILDERS={
"PVSCheck": Builder(
action=Action(
'${PVSCHECKBIN} analyze ${PVSOPTIONS} -f "${SOURCE}" -o "${TARGET}"',
"${PVSCHECKCOMSTR}",
),
suffix=".log",
src_suffix=".json",
),
"PVSReport": Builder(
action=Action(
[
Delete("${TARGET.dir}"),
# PlogConverter.exe and plog-converter have different behavior
Mkdir("${TARGET.dir}") if env["PLATFORM"] == "win32" else None,
Action(_set_browser_action, None),
'${PVSCONVBIN} ${PVSCONVOPTIONS} "${SOURCE}" -o "${REPORT_DIR}"',
],
"${PVSCONVCOMSTR}",
),
emitter=emit_pvsreport,
src_suffix=".log",
),
}
)
atexit.register(atexist_handler)
def exists(env):
return True

View File

@@ -15,6 +15,13 @@ import serial.tools.list_ports as list_ports
class Main(App):
def init(self):
self.parser.add_argument("-p", "--port", help="CDC Port", default="auto")
self.parser.add_argument(
"-n",
"--no-launch",
dest="launch_app",
action="store_false",
help="Don't launch app",
)
self.parser.add_argument("fap_src_path", help="App file to upload")
self.parser.add_argument(
@@ -84,11 +91,14 @@ class Main(App):
self.logger.error(f"Error: upload failed: {storage.last_error}")
return -3
storage.send_and_wait_eol(f'loader open "Applications" {fap_dst_path}\r')
result = storage.read.until(storage.CLI_EOL)
if len(result):
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
return -4
if self.args.launch_app:
storage.send_and_wait_eol(
f'loader open "Applications" {fap_dst_path}\r'
)
result = storage.read.until(storage.CLI_EOL)
if len(result):
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
return -4
return 0
finally:

View File

@@ -43,9 +43,11 @@ fbtenv_restore_env()
PYTHONNOUSERSITE="$SAVED_PYTHONNOUSERSITE";
PYTHONPATH="$SAVED_PYTHONPATH";
PYTHONHOME="$SAVED_PYTHONHOME";
unset SAVED_PYTHONNOUSERSITE;
unset SAVED_PYTHONPATH;
unset SAVED_PYTHONHOME;
unset SCRIPT_PATH;
unset FBT_TOOLCHAIN_VERSION;
@@ -69,7 +71,7 @@ fbtenv_check_sourced()
return 1;
}
fbtenv_chck_many_source()
fbtenv_check_if_sourced_multiple_times()
{
if ! echo "${PS1:-""}" | grep -qF "[fbt]"; then
if ! echo "${PROMPT:-""}" | grep -qF "[fbt]"; then
@@ -285,7 +287,7 @@ fbtenv_main()
fbtenv_restore_env;
return 0;
fi
fbtenv_chck_many_source; # many source it's just a warning
fbtenv_check_if_sourced_multiple_times; # many source it's just a warning
fbtenv_check_script_path || return 1;
fbtenv_check_download_toolchain || return 1;
fbtenv_set_shell_prompt;
@@ -293,12 +295,14 @@ fbtenv_main()
PATH="$TOOLCHAIN_ARCH_DIR/bin:$PATH";
PATH="$TOOLCHAIN_ARCH_DIR/protobuf/bin:$PATH";
PATH="$TOOLCHAIN_ARCH_DIR/openocd/bin:$PATH";
SAVED_PYTHONNOUSERSITE="${PYTHONNOUSERSITE:-""}";
SAVED_PYTHONPATH="${PYTHONPATH:-""}";
SAVED_PYTHONHOME="${PYTHONHOME:-""}";
PYTHONNOUSERSITE=1;
PYTHONPATH=;
PYTHONHOME=;
}
fbtenv_main "${1:-""}";