fbt fixes pt4 (#1899)

* fbt: fixed py scripts for gdb
* fbt: removed compiled dolphin assets from tracked files; resolved cached dependency issues by globally disabling deps cache; changed dependency tracking for dolphin assets
* fbt: fix for "resources" node lookup
* toolchain: bump to v.16 with scons + x64 win binaries
* fbt: using scons from toolchain
* vscode: fixed paths for 64-bit Windows toolchain
* fbt: added colors!
* fbt: moved import validator to ansi lib coloring
* fbt: moved COMSTR vars to tools
* fbt: custom action for fap dist
* fbt: added OPENOCD_ADAPTER_SERIAL configuration var for openocd operations
* fbt: added get_stlink target
* docs: details on libs for faps
* vscode: added DAP config for using Flipper as a debugger for a 2nd Flipper
* fbt: blind deps fix for sdk_origin
* fbt: sdk: moved deployment actions to pure python
* Github: disable disableLicenseExpirationCheck option for pvs

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
hedger
2022-10-26 02:15:02 +04:00
committed by GitHub
parent 984d89c6d0
commit 0adad32418
243 changed files with 302 additions and 740 deletions

View File

@@ -30,22 +30,25 @@ def dolphin_emitter(target, source, env):
res_root_dir = source[0].Dir(env["DOLPHIN_RES_TYPE"])
source = [res_root_dir]
source.extend(
env.GlobRecursive("*.*", res_root_dir),
env.GlobRecursive("*.*", res_root_dir.srcnode()),
)
target_base_dir = target[0]
env.Replace(_DOLPHIN_OUT_DIR=target[0])
if env["DOLPHIN_RES_TYPE"] == "external":
target = []
target.extend(
map(
lambda node: target_base_dir.File(
res_root_dir.rel_path(node).replace(".png", ".bm")
),
filter(lambda node: isinstance(node, SCons.Node.FS.File), source),
)
)
target = [target_base_dir.File("manifest.txt")]
## A detailed list of files to be generated
## works better if we just leave target the folder
# target = []
# target.extend(
# map(
# lambda node: target_base_dir.File(
# res_root_dir.rel_path(node).replace(".png", ".bm")
# ),
# filter(lambda node: isinstance(node, SCons.Node.FS.File), source),
# )
# )
else:
asset_basename = f"assets_dolphin_{env['DOLPHIN_RES_TYPE']}"
target = [
@@ -53,6 +56,13 @@ def dolphin_emitter(target, source, env):
target_base_dir.File(asset_basename + ".h"),
]
# Debug output
# print(
# f"Dolphin res type: {env['DOLPHIN_RES_TYPE']},\ntarget files:",
# list(f.path for f in target),
# f"\nsource files:",
# list(f.path for f in source),
# )
return target, source

View File

@@ -1,4 +1,39 @@
from re import search
from SCons.Errors import UserError
from fbt_options import OPENOCD_OPTS
def _get_device_serials(search_str="STLink"):
import serial.tools.list_ports as list_ports
return set([device.serial_number for device in list_ports.grep(search_str)])
def GetDevices(env):
serials = _get_device_serials()
if len(serials) == 0:
raise UserError("No devices found")
print("\n".join(serials))
def generate(env, **kw):
env.AddMethod(GetDevices)
if (adapter_serial := env.subst("$OPENOCD_ADAPTER_SERIAL")) != "auto":
env.Append(
OPENOCD_OPTS=[
"-c",
f"adapter serial {adapter_serial}",
]
)
# Final command is "init", always explicitly added
env.Append(
OPENOCD_OPTS=["-c", "init"],
)
env.SetDefault(
OPENOCD_GDB_PIPE=[
"|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"

View File

@@ -1,3 +1,4 @@
import shutil
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Errors import UserError
@@ -9,6 +10,7 @@ from fbt.elfmanifest import assemble_manifest_data
from fbt.appmanifest import FlipperApplication, FlipperManifestException
from fbt.sdk import SdkCache
import itertools
from ansi.color import fg
def BuildAppElf(env, app):
@@ -175,7 +177,8 @@ def validate_app_imports(target, source, env):
if unresolved_syms:
SCons.Warnings.warn(
SCons.Warnings.LinkWarning,
f"\033[93m{source[0].path}: app won't run. Unresolved symbols: \033[95m{unresolved_syms}\033[0m",
fg.brightyellow(f"{source[0].path}: app won't run. Unresolved symbols: ")
+ fg.brightmagenta(f"{unresolved_syms}"),
)
@@ -209,14 +212,51 @@ def GetExtAppFromPath(env, app_dir):
return (app, app_elf[0], app_validator[0])
def fap_dist_emitter(target, source, env):
target_dir = target[0]
target = []
for dist_entry in env["_extapps"]["dist"].values():
target.append(target_dir.Dir(dist_entry[0]).File(dist_entry[1][0].name))
for compact_entry in env["_extapps"]["compact"].values():
source.extend(compact_entry)
return (target, source)
def fap_dist_action(target, source, env):
# FIXME
target_dir = env.Dir("#/assets/resources/apps")
shutil.rmtree(target_dir.path, ignore_errors=True)
for src, target in zip(source, target):
os.makedirs(os.path.dirname(target.path), exist_ok=True)
shutil.copy(src.path, target.path)
def generate(env, **kw):
env.SetDefault(EXT_APPS_WORK_DIR=kw.get("EXT_APPS_WORK_DIR"))
# env.VariantDir(env.subst("$EXT_APPS_WORK_DIR"), env.Dir("#"), duplicate=False)
if not env["VERBOSE"]:
env.SetDefault(
FAPDISTCOMSTR="\tFAPDIST\t${TARGET}",
APPMETA_COMSTR="\tAPPMETA\t${TARGET}",
APPMETAEMBED_COMSTR="\tFAP\t${TARGET}",
APPCHECK_COMSTR="\tAPPCHK\t${SOURCE}",
)
env.AddMethod(BuildAppElf)
env.AddMethod(GetExtAppFromPath)
env.Append(
BUILDERS={
"FapDist": Builder(
action=Action(
fap_dist_action,
"$FAPDISTCOMSTR",
),
emitter=fap_dist_emitter,
),
"EmbedAppMetadata": Builder(
action=[
Action(prepare_app_metadata, "$APPMETA_COMSTR"),

View File

@@ -1,3 +1,4 @@
import shutil
from SCons.Builder import Builder
from SCons.Action import Action
from SCons.Errors import UserError
@@ -117,42 +118,30 @@ class SdkTreeBuilder:
target = [target_folder.File("sdk.opts")]
return target, source
def _create_deploy_commands(self):
def _run_deploy_commands(self):
dirs_to_create = set(
self.sdk_deploy_dir.Dir(dirpath) for dirpath in self.header_dirs
self.sdk_deploy_dir.Dir(dirpath).path for dirpath in self.header_dirs
)
actions = [
Delete(self.sdk_deploy_dir),
Mkdir(self.sdk_deploy_dir),
Copy(
self.sdk_root_dir,
self.env["SDK_DEFINITION"],
),
]
actions += [Mkdir(d) for d in dirs_to_create]
actions += [
Action(
Copy(self.sdk_deploy_dir.File(h).path, h),
# f"Copy {h} to {self.sdk_deploy_dir}",
)
for h in self.header_depends
]
return actions
shutil.rmtree(self.sdk_root_dir.path, ignore_errors=False)
def generate_actions(self):
for sdkdir in dirs_to_create:
os.makedirs(sdkdir, exist_ok=True)
shutil.copy2(self.env["SDK_DEFINITION"].path, self.sdk_root_dir.path)
for header in self.header_depends:
shutil.copy2(header, self.sdk_deploy_dir.File(header).path)
def deploy_action(self):
self._parse_sdk_depends()
self._run_deploy_commands()
self._generate_sdk_meta()
return self._create_deploy_commands()
def deploy_sdk_tree(target, source, env, for_signature):
if for_signature:
return []
def deploy_sdk_tree_action(target, source, env):
sdk_tree = SdkTreeBuilder(env, target, source)
return sdk_tree.generate_actions()
return sdk_tree.deploy_action()
def deploy_sdk_tree_emitter(target, source, env):
@@ -217,6 +206,30 @@ def generate_sdk_symbols(source, target, env):
def generate(env, **kw):
if not env["VERBOSE"]:
env.SetDefault(
SDK_PREGEN_COMSTR="\tPREGEN\t${TARGET}",
SDK_COMSTR="\tSDKSRC\t${TARGET}",
SDKSYM_UPDATER_COMSTR="\tSDKCHK\t${TARGET}",
SDKSYM_GENERATOR_COMSTR="\tSDKSYM\t${TARGET}",
SDKDEPLOY_COMSTR="\tSDKTREE\t${TARGET}",
)
# Filtering out things cxxheaderparser cannot handle
env.SetDefault(
SDK_PP_FLAGS=[
'-D"_Static_assert(x,y)="',
'-D"__asm__(x)="',
'-D"__attribute__(x)="',
"-Drestrict=",
"-D_Noreturn=",
"-D__restrict=",
"-D__extension__=",
"-D__inline=inline",
"-D__inline__=inline",
]
)
env.AddMethod(ProcessSdkDepends)
env.Append(
BUILDERS={
@@ -235,7 +248,10 @@ def generate(env, **kw):
suffix=".i",
),
"SDKTree": Builder(
generator=deploy_sdk_tree,
action=Action(
deploy_sdk_tree_action,
"$SDKDEPLOY_COMSTR",
),
emitter=deploy_sdk_tree_emitter,
src_suffix=".d",
),

View File

@@ -0,0 +1,43 @@
import SCons.Warnings as Warnings
# 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()
# find the deepest traceback frame that is not part
# of SCons:
for frame in tb:
filename = frame[0]
if filename.find("fbt_tweaks") != -1:
continue
if filename.find(os.sep + "SCons" + os.sep) == -1:
return frame
return tb[0]
def fbt_warning(e):
filename, lineno, routine, dummy = find_deepest_user_frame(
traceback.extract_stack()
)
fbt_line = "\nfbt: warning: %s\n" % e.args[0]
sys.stderr.write(fg.boldmagenta(fbt_line))
fbt_line = (
fg.yellow("%s, line %d, " % (routine, lineno)) + 'in file "%s"\n' % filename
)
sys.stderr.write(fg.yellow(fbt_line))
def generate(env):
Warnings._warningOut = fbt_warning
def exists():
return True

View File

@@ -12,6 +12,14 @@ def generate(env):
OBJCOPY=__OBJCOPY_ARM_BIN, # FIXME
NM=__NM_ARM_BIN, # FIXME
)
if not env["VERBOSE"]:
env.SetDefault(
HEXCOMSTR="\tHEX\t${TARGET}",
BINCOMSTR="\tBIN\t${TARGET}",
DFUCOMSTR="\tDFU\t${TARGET}",
)
env.Append(
BUILDERS={
"HEXBuilder": Builder(

View File

@@ -6,8 +6,6 @@ def generate(env):
env.SetDefault(
GDB="gdb",
GDBPY="gdb-py",
GDBOPTS="",
GDBPYOPTS="",
GDBCOM="$GDB $GDBOPTS $SOURCES", # no $TARGET
GDBPYCOM="$GDBPY $GDBOPTS $GDBPYOPTS $SOURCES", # no $TARGET
)