[FL-3080] fbt: PVS support (#2286)
* fbt: added firmware_pvscheck & firmware_pvs targets for *nix * fbt: pvs support on Windows * fbt: additional fixes & docs for PVS support * fbt: fixes for updater env configuration * github: reworked pvs workflow * vscode: added PVS shortcut * pvs: added --ignore-ccache flag * fbt: pvs: opening web browser if there are warnings * fbt: pvs: added browser handler for mac * github: fixed report path for PVS * fbt: pvs: fixed report upload path * removed intentional PVS warning * fixed more PVS warnings * fixed secplus_v1 PVS warning * fbt: added PVSNOBROWSER flag * github: setting PVSNOBROWSER for pvs runs * fbt: less debug output Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
9e1a6a6d2e
commit
341610b8a1
27
.github/workflows/pvs_studio.yml
vendored
27
.github/workflows/pvs_studio.yml
vendored
@ -43,36 +43,15 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
||||||
|
|
||||||
- name: 'Make reports directory'
|
- name: 'Supply PVS credentials'
|
||||||
run: |
|
run: |
|
||||||
rm -rf reports/
|
|
||||||
mkdir reports
|
|
||||||
|
|
||||||
- name: 'Generate compile_comands.json'
|
|
||||||
run: |
|
|
||||||
./fbt COMPACT=1 version_json proto_ver icons firmware_cdb dolphin_internal dolphin_blocking _fap_icons api_syms
|
|
||||||
|
|
||||||
- name: 'Static code analysis'
|
|
||||||
run: |
|
|
||||||
source scripts/toolchain/fbtenv.sh
|
|
||||||
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
|
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
|
||||||
pvs-studio-analyzer analyze \
|
|
||||||
@.pvsoptions \
|
|
||||||
-C gccarm \
|
|
||||||
-j$(grep -c processor /proc/cpuinfo) \
|
|
||||||
-f build/f7-firmware-DC/compile_commands.json \
|
|
||||||
-o PVS-Studio.log
|
|
||||||
|
|
||||||
- name: 'Convert PVS-Studio output to html and detect warnings'
|
- name: 'Convert PVS-Studio output to html and detect warnings'
|
||||||
id: pvs-warn
|
id: pvs-warn
|
||||||
run: |
|
run: |
|
||||||
WARNINGS=0
|
WARNINGS=0
|
||||||
plog-converter \
|
./fbt COMPACT=1 PVSNOBROWSER=1 firmware_pvs || WARNINGS=1
|
||||||
-a GA:1,2,3 \
|
|
||||||
-t fullhtml \
|
|
||||||
--indicate-warnings \
|
|
||||||
PVS-Studio.log \
|
|
||||||
-o reports/${DEFAULT_TARGET}-${SUFFIX} || WARNINGS=1
|
|
||||||
echo "warnings=${WARNINGS}" >> $GITHUB_OUTPUT
|
echo "warnings=${WARNINGS}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: 'Upload artifacts to update server'
|
- name: 'Upload artifacts to update server'
|
||||||
@ -84,7 +63,7 @@ jobs:
|
|||||||
chmod 600 ./deploy_key;
|
chmod 600 ./deploy_key;
|
||||||
rsync -avrzP --mkpath \
|
rsync -avrzP --mkpath \
|
||||||
-e 'ssh -p ${{ secrets.RSYNC_DEPLOY_PORT }} -i ./deploy_key' \
|
-e 'ssh -p ${{ secrets.RSYNC_DEPLOY_PORT }} -i ./deploy_key' \
|
||||||
reports/ ${{ secrets.RSYNC_DEPLOY_USER }}@${{ secrets.RSYNC_DEPLOY_HOST }}:/home/data/firmware-pvs-studio-report/"${BRANCH_NAME}/";
|
build/f7-firmware-DC/pvsreport/ ${{ secrets.RSYNC_DEPLOY_USER }}@${{ secrets.RSYNC_DEPLOY_HOST }}:/home/data/firmware-pvs-studio-report/"${BRANCH_NAME}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/";
|
||||||
rm ./deploy_key;
|
rm ./deploy_key;
|
||||||
|
|
||||||
- name: 'Find Previous Comment'
|
- name: 'Find Previous Comment'
|
||||||
|
@ -1 +1 @@
|
|||||||
--rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap
|
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap
|
||||||
|
6
.vscode/example/tasks.json
vendored
6
.vscode/example/tasks.json
vendored
@ -105,6 +105,12 @@
|
|||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
|
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "[Debug] Create PVS-Studio report",
|
||||||
|
"group": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./fbt firmware_pvs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "[Debug] Build FAPs",
|
"label": "[Debug] Build FAPs",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
|
@ -54,13 +54,14 @@ assetsenv.Alias("proto_ver", proto_ver)
|
|||||||
|
|
||||||
# Gather everything into a static lib
|
# Gather everything into a static lib
|
||||||
assets_parts = (icons, proto, dolphin_blocking, dolphin_internal, proto_ver)
|
assets_parts = (icons, proto, dolphin_blocking, dolphin_internal, proto_ver)
|
||||||
|
env.Replace(FW_ASSETS_HEADERS=assets_parts)
|
||||||
|
|
||||||
assetslib = assetsenv.Library("${FW_LIB_NAME}", assets_parts)
|
assetslib = assetsenv.Library("${FW_LIB_NAME}", assets_parts)
|
||||||
assetsenv.Install("${LIB_DIST_DIR}", assetslib)
|
assetsenv.Install("${LIB_DIST_DIR}", assetslib)
|
||||||
|
|
||||||
|
|
||||||
# Resources for SD card
|
# Resources for SD card
|
||||||
|
env.SetDefault(FW_RESOURCES=None)
|
||||||
if assetsenv["IS_BASE_FIRMWARE"]:
|
if assetsenv["IS_BASE_FIRMWARE"]:
|
||||||
# External dolphin animations
|
# External dolphin animations
|
||||||
dolphin_external = assetsenv.DolphinExtBuilder(
|
dolphin_external = assetsenv.DolphinExtBuilder(
|
||||||
@ -92,8 +93,7 @@ if assetsenv["IS_BASE_FIRMWARE"]:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Exporting resources node to external environment
|
# Exporting resources node to external environment
|
||||||
env["FW_ASSETS_HEADERS"] = assets_parts
|
env.Replace(FW_RESOURCES=resources)
|
||||||
env["FW_RESOURCES"] = resources
|
|
||||||
assetsenv.Alias("resources", resources)
|
assetsenv.Alias("resources", resources)
|
||||||
|
|
||||||
Return("assetslib")
|
Return("assetslib")
|
||||||
|
@ -56,6 +56,7 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
|
|||||||
- `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `OPENOCD_ADAPTER_SERIAL=...`.
|
- `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `OPENOCD_ADAPTER_SERIAL=...`.
|
||||||
- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs.
|
- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs.
|
||||||
- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests.
|
- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests.
|
||||||
|
- `firmware_pvs` - generate a PVS Studio report for the firmware. Requires PVS Studio to be availabe on your system's `PATH`.
|
||||||
- `cli` - start a Flipper CLI session over USB.
|
- `cli` - start a Flipper CLI session over USB.
|
||||||
|
|
||||||
### Firmware targets
|
### Firmware targets
|
||||||
|
@ -15,6 +15,7 @@ env = ENV.Clone(
|
|||||||
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
|
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
|
||||||
"fwbin",
|
"fwbin",
|
||||||
"fbt_apps",
|
"fbt_apps",
|
||||||
|
"pvsstudio",
|
||||||
],
|
],
|
||||||
COMPILATIONDB_USE_ABSPATH=False,
|
COMPILATIONDB_USE_ABSPATH=False,
|
||||||
BUILD_DIR=fw_build_meta["build_dir"],
|
BUILD_DIR=fw_build_meta["build_dir"],
|
||||||
@ -69,6 +70,8 @@ env = ENV.Clone(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SDK_APISYMS=None,
|
||||||
|
_APP_ICONS=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -273,6 +276,24 @@ Precious(fwcdb)
|
|||||||
NoClean(fwcdb)
|
NoClean(fwcdb)
|
||||||
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb)
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb)
|
||||||
|
|
||||||
|
pvscheck = fwenv.PVSCheck("pvsreport.log", fwcdb)
|
||||||
|
Depends(
|
||||||
|
pvscheck,
|
||||||
|
[
|
||||||
|
fwenv["FW_VERSION_JSON"],
|
||||||
|
fwenv["FW_ASSETS_HEADERS"],
|
||||||
|
fwenv["SDK_APISYMS"],
|
||||||
|
fwenv["_APP_ICONS"],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_pvscheck", pvscheck)
|
||||||
|
AlwaysBuild(pvscheck)
|
||||||
|
Precious(pvscheck)
|
||||||
|
|
||||||
|
pvsreport = fwenv.PVSReport(None, pvscheck, REPORT_DIR=Dir("pvsreport"))
|
||||||
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_pvs", pvsreport)
|
||||||
|
AlwaysBuild(pvsreport)
|
||||||
|
|
||||||
# If current configuration was explicitly requested, generate compilation database
|
# If current configuration was explicitly requested, generate compilation database
|
||||||
# and link its directory as build/latest
|
# and link its directory as build/latest
|
||||||
if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):
|
if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):
|
||||||
|
@ -93,7 +93,11 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FURI_BIT_CLEAR
|
#ifndef FURI_BIT_CLEAR
|
||||||
#define FURI_BIT_CLEAR(x, n) ((x) &= ~(1UL << (n)))
|
#define FURI_BIT_CLEAR(x, n) \
|
||||||
|
({ \
|
||||||
|
__typeof__(x) _x = (1); \
|
||||||
|
(x) &= ~(_x << (n)); \
|
||||||
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FURI_SW_MEMBARRIER() asm volatile("" : : : "memory")
|
#define FURI_SW_MEMBARRIER() asm volatile("" : : : "memory")
|
||||||
|
@ -244,7 +244,7 @@ LevelDuration protocol_fdx_b_encoder_yield(ProtocolFDXB* protocol) {
|
|||||||
static uint64_t protocol_fdx_b_get_national_code(const uint8_t* data) {
|
static uint64_t protocol_fdx_b_get_national_code(const uint8_t* data) {
|
||||||
uint64_t national_code = bit_lib_get_bits_32(data, 0, 32);
|
uint64_t national_code = bit_lib_get_bits_32(data, 0, 32);
|
||||||
national_code = national_code << 32;
|
national_code = national_code << 32;
|
||||||
national_code |= bit_lib_get_bits_32(data, 32, 6) << (32 - 6);
|
national_code |= (uint64_t)bit_lib_get_bits_32(data, 32, 6) << (32 - 6);
|
||||||
bit_lib_reverse_bits((uint8_t*)&national_code, 0, 64);
|
bit_lib_reverse_bits((uint8_t*)&national_code, 0, 64);
|
||||||
return national_code;
|
return national_code;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,16 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
|
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
|
||||||
#define bit_set(value, bit) ((value) |= (1UL << (bit)))
|
#define bit_set(value, bit) \
|
||||||
#define bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
|
({ \
|
||||||
|
__typeof__(value) _one = (1); \
|
||||||
|
(value) |= (_one << (bit)); \
|
||||||
|
})
|
||||||
|
#define bit_clear(value, bit) \
|
||||||
|
({ \
|
||||||
|
__typeof__(value) _one = (1); \
|
||||||
|
(value) &= ~(_one << (bit)); \
|
||||||
|
})
|
||||||
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
|
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
|
||||||
#define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
|
#define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
|
||||||
|
|
||||||
|
@ -280,9 +280,9 @@ static bool subghz_protocol_chamb_code_to_bit(uint64_t* data, uint8_t size) {
|
|||||||
uint64_t data_tmp = data[0];
|
uint64_t data_tmp = data[0];
|
||||||
uint64_t data_res = 0;
|
uint64_t data_res = 0;
|
||||||
for(uint8_t i = 0; i < size; i++) {
|
for(uint8_t i = 0; i < size; i++) {
|
||||||
if((data_tmp & 0xF) == CHAMBERLAIN_CODE_BIT_0) {
|
if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_0) {
|
||||||
bit_write(data_res, i, 0);
|
bit_write(data_res, i, 0);
|
||||||
} else if((data_tmp & 0xF) == CHAMBERLAIN_CODE_BIT_1) {
|
} else if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_1) {
|
||||||
bit_write(data_res, i, 1);
|
bit_write(data_res, i, 1);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -224,7 +224,7 @@ static bool subghz_protocol_secplus_v1_encode(SubGhzProtocolEncoderSecPlus_v1* i
|
|||||||
instance->generic.data &= 0xFFFFFFFF00000000;
|
instance->generic.data &= 0xFFFFFFFF00000000;
|
||||||
instance->generic.data |= rolling;
|
instance->generic.data |= rolling;
|
||||||
|
|
||||||
if(rolling > 0xFFFFFFFF) {
|
if(rolling == 0xFFFFFFFF) {
|
||||||
rolling = 0xE6000000;
|
rolling = 0xE6000000;
|
||||||
}
|
}
|
||||||
if(fixed > 0xCFD41B90) {
|
if(fixed > 0xCFD41B90) {
|
||||||
|
@ -32,6 +32,7 @@ def BuildAppElf(env, app):
|
|||||||
ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR")
|
ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR")
|
||||||
app_work_dir = os.path.join(ext_apps_work_dir, app.appid)
|
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)
|
env.VariantDir(app_work_dir, app._appdir, duplicate=False)
|
||||||
|
|
||||||
app_env = env.Clone(FAP_SRC_DIR=app._appdir, FAP_WORK_DIR=app_work_dir)
|
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",
|
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)
|
app_env.Alias("_fap_icons", fap_icons)
|
||||||
|
env.Append(_APP_ICONS=[fap_icons])
|
||||||
|
|
||||||
private_libs = []
|
private_libs = []
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ Other:
|
|||||||
run linters
|
run linters
|
||||||
format, format_py:
|
format, format_py:
|
||||||
run code formatters
|
run code formatters
|
||||||
|
firmware_pvs:
|
||||||
|
generate a PVS-Studio report
|
||||||
|
|
||||||
For more targets & info, see documentation/fbt.md
|
For more targets & info, see documentation/fbt.md
|
||||||
"""
|
"""
|
||||||
|
106
scripts/fbt_tools/pvsstudio.py
Normal file
106
scripts/fbt_tools/pvsstudio.py
Normal 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
|
@ -235,6 +235,11 @@ vars.AddVariables(
|
|||||||
("applications_user", False),
|
("applications_user", False),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
BoolVariable(
|
||||||
|
"PVSNOBROWSER",
|
||||||
|
help="Don't open browser after generating error repots",
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
Return("vars")
|
Return("vars")
|
||||||
|
@ -143,6 +143,11 @@ sdk_apisyms = appenv.SDKSymGenerator(
|
|||||||
"${BUILD_DIR}/assets/compiled/symbols.h", appenv["SDK_DEFINITION"]
|
"${BUILD_DIR}/assets/compiled/symbols.h", appenv["SDK_DEFINITION"]
|
||||||
)
|
)
|
||||||
Alias("api_syms", sdk_apisyms)
|
Alias("api_syms", sdk_apisyms)
|
||||||
|
ENV.Replace(
|
||||||
|
SDK_APISYMS=sdk_apisyms,
|
||||||
|
_APP_ICONS=appenv["_APP_ICONS"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if appenv["FORCE"]:
|
if appenv["FORCE"]:
|
||||||
appenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms)
|
appenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms)
|
||||||
|
Loading…
Reference in New Issue
Block a user