* utils/version: use git description token as version, add memoization * pio: move extra scripts to a separate directory * pio: add -DAPP_REVISION=... as local build flagmaster
@ -1,171 +0,0 @@ | |||||
#!/usr/bin/env python | |||||
from __future__ import print_function | |||||
import os | |||||
import sys | |||||
from subprocess import call | |||||
import click | |||||
Import("env", "projenv") | |||||
PIO_PLATFORM = env.PioPlatform() | |||||
FRAMEWORK_DIR = PIO_PLATFORM.get_package_dir("framework-arduinoespressif8266") | |||||
# ------------------------------------------------------------------------------ | |||||
# Utils | |||||
# ------------------------------------------------------------------------------ | |||||
class Color(object): | |||||
BLACK = '\x1b[1;30m' | |||||
RED = '\x1b[1;31m' | |||||
GREEN = '\x1b[1;32m' | |||||
YELLOW = '\x1b[1;33m' | |||||
BLUE = '\x1b[1;34m' | |||||
MAGENTA = '\x1b[1;35m' | |||||
CYAN = '\x1b[1;36m' | |||||
WHITE = '\x1b[1;37m' | |||||
LIGHT_GREY = '\x1b[0;30m' | |||||
LIGHT_RED = '\x1b[0;31m' | |||||
LIGHT_GREEN = '\x1b[0;32m' | |||||
LIGHT_YELLOW = '\x1b[0;33m' | |||||
LIGHT_BLUE = '\x1b[0;34m' | |||||
LIGHT_MAGENTA = '\x1b[0;35m' | |||||
LIGHT_CYAN = '\x1b[0;36m' | |||||
LIGHT_WHITE = '\x1b[0;37m' | |||||
def clr(color, text): | |||||
return color + str(text) + '\x1b[0m' | |||||
def print_warning(message, color=Color.LIGHT_YELLOW): | |||||
print(clr(color, message), file=sys.stderr) | |||||
def print_filler(fill, color=Color.WHITE, err=False): | |||||
width, _ = click.get_terminal_size() | |||||
if len(fill) > 1: | |||||
fill = fill[0] | |||||
out = sys.stderr if err else sys.stdout | |||||
print(clr(color, fill * width), file=out) | |||||
def ldscript_inject_libpath(): | |||||
# espressif8266@1.5.0 did not append this directory into the LIBPATH | |||||
libpath_sdk = os.path.join(FRAMEWORK_DIR, "tools", "sdk", "ld") | |||||
env.Append(LIBPATH=[libpath_sdk]) | |||||
libpath_base = os.path.join("$PROJECT_DIR", "..", "dist", "ld") | |||||
env.Append(LIBPATH=[ | |||||
os.path.join(libpath_base, "pre_2.5.0") | |||||
]) | |||||
# local.eagle.app.v6.common.ld exists only with Core >2.5.0 | |||||
def check_local_ld(target ,source, env): | |||||
local_ld = env.subst(os.path.join("$BUILD_DIR", "ld", "local.eagle.app.v6.common.ld")) | |||||
if os.path.exists(local_ld): | |||||
env.Prepend(LIBPATH=[ | |||||
os.path.join(libpath_base, "latest") | |||||
]) | |||||
env.AddPreAction( | |||||
os.path.join("$BUILD_DIR", "firmware.elf"), | |||||
check_local_ld | |||||
) | |||||
# ------------------------------------------------------------------------------ | |||||
# Callbacks | |||||
# ------------------------------------------------------------------------------ | |||||
def remove_float_support(): | |||||
flags = " ".join(env['LINKFLAGS']) | |||||
flags = flags.replace("-u _printf_float", "") | |||||
flags = flags.replace("-u _scanf_float", "") | |||||
newflags = flags.split() | |||||
env.Replace( | |||||
LINKFLAGS = newflags | |||||
) | |||||
def cpp_check(target, source, env): | |||||
print("Started cppcheck...\n") | |||||
call(["cppcheck", os.getcwd()+"/espurna", "--force", "--enable=all"]) | |||||
print("Finished cppcheck...\n") | |||||
def check_size(target, source, env): | |||||
(binary,) = target | |||||
path = binary.get_abspath() | |||||
size = os.stat(path).st_size | |||||
print(clr(Color.LIGHT_BLUE, "Binary size: {} bytes".format(size))) | |||||
# Warn 1MB variants about exceeding OTA size limit | |||||
flash_size = int(env.BoardConfig().get("upload.maximum_size", 0)) | |||||
if (flash_size == 1048576) and (size >= 512000): | |||||
print_filler("*", color=Color.LIGHT_YELLOW, err=True) | |||||
print_warning("File is too large for OTA! Here you can find instructions on how to flash it:") | |||||
print_warning("https://github.com/xoseperez/espurna/wiki/TwoStepUpdates", color=Color.LIGHT_CYAN) | |||||
print_filler("*", color=Color.LIGHT_YELLOW, err=True) | |||||
def dummy_ets_printf(target, source, env): | |||||
(postmortem_src_file, ) = source | |||||
(postmortem_obj_file, ) = target | |||||
cmd = ["xtensa-lx106-elf-objcopy"] | |||||
# recent Core switched to cpp+newlib & ets_printf_P | |||||
cmd.extend(["--redefine-sym", "ets_printf=dummy_ets_printf"]) | |||||
cmd.extend(["--redefine-sym", "ets_printf_P=dummy_ets_printf"]) | |||||
cmd.append(postmortem_obj_file.get_abspath()) | |||||
env.Execute(env.VerboseAction(" ".join(cmd), "Removing ets_printf / ets_printf_P")) | |||||
env.Depends(postmortem_obj_file,"$BUILD_DIR/src/dummy_ets_printf.c.o") | |||||
def patch_lwip(): | |||||
# ignore when building with lwip2 | |||||
if "lwip_gcc" not in env["LIBS"]: | |||||
return | |||||
toolchain_prefix = os.path.join(PIO_PLATFORM.get_package_dir("toolchain-xtensa"), "bin", "xtensa-lx106-elf-") | |||||
patch_action = env.VerboseAction(" ".join([ | |||||
"-patch", "-u", "-N", "-d", | |||||
os.path.join(FRAMEWORK_DIR, "tools", "sdk", "lwip"), | |||||
os.path.join("src", "core", "tcp_out.c"), | |||||
env.subst(os.path.join("$PROJECT_DIR", "..", "dist", "patches", "lwip_mtu_issue_1610.patch")) | |||||
]), "Patching lwip source") | |||||
build_action = env.VerboseAction(" ".join([ | |||||
"make", "-C", os.path.join(FRAMEWORK_DIR, "tools", "sdk", "lwip", "src"), | |||||
"install", | |||||
"TOOLS_PATH={}".format(toolchain_prefix), | |||||
"LWIP_LIB=liblwip_gcc.a" | |||||
]), "Rebuilding lwip") | |||||
patcher = env.Alias("patch-lwip", None, patch_action) | |||||
builder = env.Alias("build-lwip", patcher, build_action) | |||||
if os.environ.get("ESPURNA_PIO_PATCH_ISSUE_1610"): | |||||
env.Depends("$BUILD_DIR/${PROGNAME}.elf", builder) | |||||
env.AlwaysBuild(patcher) | |||||
env.AlwaysBuild(builder) | |||||
# ------------------------------------------------------------------------------ | |||||
# Hooks | |||||
# ------------------------------------------------------------------------------ | |||||
# Always show warnings for project code | |||||
projenv.ProcessUnFlags("-w") | |||||
# 2.4.0 and up | |||||
remove_float_support() | |||||
ldscript_inject_libpath() | |||||
# two-step update hint when using 1MB boards | |||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", check_size) | |||||
# disable postmortem printing to the uart. another one is in eboot, but this is what causes the most harm | |||||
if "DISABLE_POSTMORTEM_STACKDUMP" in env["CPPFLAGS"]: | |||||
env.AddPostAction("$BUILD_DIR/FrameworkArduino/core_esp8266_postmortem.c.o", dummy_ets_printf) | |||||
env.AddPostAction("$BUILD_DIR/FrameworkArduino/core_esp8266_postmortem.cpp.o", dummy_ets_printf) | |||||
# patch lwip1 sources conditionally: | |||||
# https://github.com/xoseperez/espurna/issues/1610 | |||||
patch_lwip() |
@ -0,0 +1,6 @@ | |||||
from .checks import check_cppcheck, check_printsize | |||||
from .float_support import remove_float_support | |||||
from .ldscripts import ldscripts_inject_libpath | |||||
from .lwip import lwip_inject_patcher | |||||
from .postmortem import dummy_ets_printf | |||||
from .git import app_inject_revision |
@ -0,0 +1,29 @@ | |||||
import os | |||||
from .display import Color, clr, print_filler, print_warning | |||||
def check_printsize(target, source, env): | |||||
(binary,) = target | |||||
path = binary.get_abspath() | |||||
size = os.stat(path).st_size | |||||
print(clr(Color.LIGHT_BLUE, "Binary size: {} bytes".format(size))) | |||||
# Warn 1MB variants about exceeding OTA size limit | |||||
flash_size = int(env.BoardConfig().get("upload.maximum_size", 0)) | |||||
if (flash_size == 1048576) and (size >= 512000): | |||||
print_filler("*", color=Color.LIGHT_YELLOW, err=True) | |||||
print_warning( | |||||
"File is too large for OTA! Here you can find instructions on how to flash it:" | |||||
) | |||||
print_warning( | |||||
"https://github.com/xoseperez/espurna/wiki/TwoStepUpdates", | |||||
color=Color.LIGHT_CYAN, | |||||
) | |||||
print_filler("*", color=Color.LIGHT_YELLOW, err=True) | |||||
def check_cppcheck(target, source, env): | |||||
print_warning("Started cppcheck...\n") | |||||
call(["cppcheck", os.getcwd() + "/espurna", "--force", "--enable=all"]) | |||||
print_warning("Finished cppcheck...\n") |
@ -0,0 +1,40 @@ | |||||
from __future__ import print_function | |||||
import sys | |||||
import click | |||||
class Color(object): | |||||
BLACK = "\x1b[1;30m" | |||||
RED = "\x1b[1;31m" | |||||
GREEN = "\x1b[1;32m" | |||||
YELLOW = "\x1b[1;33m" | |||||
BLUE = "\x1b[1;34m" | |||||
MAGENTA = "\x1b[1;35m" | |||||
CYAN = "\x1b[1;36m" | |||||
WHITE = "\x1b[1;37m" | |||||
LIGHT_GREY = "\x1b[0;30m" | |||||
LIGHT_RED = "\x1b[0;31m" | |||||
LIGHT_GREEN = "\x1b[0;32m" | |||||
LIGHT_YELLOW = "\x1b[0;33m" | |||||
LIGHT_BLUE = "\x1b[0;34m" | |||||
LIGHT_MAGENTA = "\x1b[0;35m" | |||||
LIGHT_CYAN = "\x1b[0;36m" | |||||
LIGHT_WHITE = "\x1b[0;37m" | |||||
def clr(color, text): | |||||
return color + str(text) + "\x1b[0m" | |||||
def print_warning(message, color=Color.LIGHT_YELLOW): | |||||
print(clr(color, message), file=sys.stderr) | |||||
def print_filler(fill, color=Color.WHITE, err=False): | |||||
width, _ = click.get_terminal_size() | |||||
if len(fill) > 1: | |||||
fill = fill[0] | |||||
out = sys.stderr if err else sys.stdout | |||||
print(clr(color, fill * width), file=out) |
@ -0,0 +1,8 @@ | |||||
def remove_float_support(env): | |||||
flags = " ".join(env["LINKFLAGS"]) | |||||
flags = flags.replace("-u _printf_float", "") | |||||
flags = flags.replace("-u _scanf_float", "") | |||||
newflags = flags.split() | |||||
env.Replace(LINKFLAGS=newflags) |
@ -0,0 +1,23 @@ | |||||
import os | |||||
import subprocess | |||||
def git(*args): | |||||
cmd = ["git"] | |||||
cmd.extend(args) | |||||
proc = subprocess.Popen( | |||||
cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True | |||||
) | |||||
return proc.stdout.readlines()[0].strip() | |||||
def app_inject_revision(env): | |||||
revision = "" | |||||
try: | |||||
revision = "\\\"{}\\\"".format(git("rev-parse", "--short=8", "HEAD")) | |||||
except: # pylint: disable=broad-except | |||||
pass | |||||
# Note: code expects this as undefined when empty | |||||
if revision: | |||||
env.Append(CPPDEFINES=[ | |||||
("APP_REVISION", revision) | |||||
]) |
@ -0,0 +1,24 @@ | |||||
import os | |||||
def ldscripts_inject_libpath(env): | |||||
platform = env.PioPlatform() | |||||
framework_dir = platform.get_package_dir("framework-arduinoespressif8266") | |||||
# espressif8266@1.5.0 did not append this directory into the LIBPATH | |||||
libpath_sdk = os.path.join(framework_dir, "tools", "sdk", "ld") | |||||
env.Append(LIBPATH=[libpath_sdk]) | |||||
libpath_base = os.path.join("$PROJECT_DIR", "..", "dist", "ld") | |||||
env.Append(LIBPATH=[os.path.join(libpath_base, "pre_2.5.0")]) | |||||
# local.eagle.app.v6.common.ld exists only with Core >2.5.0 | |||||
def check_local_ld(target, source, env): | |||||
local_ld = env.subst( | |||||
os.path.join("$BUILD_DIR", "ld", "local.eagle.app.v6.common.ld") | |||||
) | |||||
if os.path.exists(local_ld): | |||||
env.Prepend(LIBPATH=[os.path.join(libpath_base, "latest")]) | |||||
env.AddPreAction(os.path.join("$BUILD_DIR", "firmware.elf"), check_local_ld) |
@ -0,0 +1,56 @@ | |||||
import os | |||||
def lwip_inject_patcher(env): | |||||
# ignore when building with lwip2 | |||||
if "lwip_gcc" not in env["LIBS"]: | |||||
return | |||||
platform = env.PioPlatform() | |||||
framework_dir = platform.get_package_dir("framework-arduinoespressif8266") | |||||
toolchain_prefix = os.path.join( | |||||
platform.get_package_dir("toolchain-xtensa"), "bin", "xtensa-lx106-elf-" | |||||
) | |||||
patch_action = env.VerboseAction( | |||||
" ".join( | |||||
[ | |||||
"-patch", | |||||
"-u", | |||||
"-N", | |||||
"-d", | |||||
os.path.join(framework_dir, "tools", "sdk", "lwip"), | |||||
os.path.join("src", "core", "tcp_out.c"), | |||||
env.subst( | |||||
os.path.join( | |||||
"$PROJECT_DIR", | |||||
"..", | |||||
"dist", | |||||
"patches", | |||||
"lwip_mtu_issue_1610.patch", | |||||
) | |||||
), | |||||
] | |||||
), | |||||
"Patching lwip source", | |||||
) | |||||
build_action = env.VerboseAction( | |||||
" ".join( | |||||
[ | |||||
"make", | |||||
"-C", | |||||
os.path.join(framework_dir, "tools", "sdk", "lwip", "src"), | |||||
"install", | |||||
"TOOLS_PATH={}".format(toolchain_prefix), | |||||
"LWIP_LIB=liblwip_gcc.a", | |||||
] | |||||
), | |||||
"Rebuilding lwip", | |||||
) | |||||
patcher = env.Alias("patch-lwip", None, patch_action) | |||||
builder = env.Alias("build-lwip", patcher, build_action) | |||||
if os.environ.get("ESPURNA_PIO_PATCH_ISSUE_1610"): | |||||
env.Depends("$BUILD_DIR/${PROGNAME}.elf", builder) | |||||
env.AlwaysBuild(patcher) | |||||
env.AlwaysBuild(builder) |
@ -0,0 +1,13 @@ | |||||
def dummy_ets_printf(target, source, env): | |||||
(postmortem_src_file,) = source | |||||
(postmortem_obj_file,) = target | |||||
cmd = ["xtensa-lx106-elf-objcopy"] | |||||
# recent Core switched to cpp+newlib & ets_printf_P | |||||
cmd.extend(["--redefine-sym", "ets_printf=dummy_ets_printf"]) | |||||
cmd.extend(["--redefine-sym", "ets_printf_P=dummy_ets_printf"]) | |||||
cmd.append(postmortem_obj_file.get_abspath()) | |||||
env.Execute(env.VerboseAction(" ".join(cmd), "Removing ets_printf / ets_printf_P")) | |||||
env.Depends(postmortem_obj_file, "$BUILD_DIR/src/dummy_ets_printf.c.o") |
@ -0,0 +1,38 @@ | |||||
# Run this script every time building an env: | |||||
from espurna_utils import ( | |||||
check_printsize, | |||||
remove_float_support, | |||||
ldscripts_inject_libpath, | |||||
lwip_inject_patcher, | |||||
app_inject_revision, | |||||
dummy_ets_printf | |||||
) | |||||
Import("env", "projenv") | |||||
# Always show warnings for project code | |||||
projenv.ProcessUnFlags("-w") | |||||
# 2.4.0 and up | |||||
remove_float_support(env) | |||||
ldscripts_inject_libpath(env) | |||||
# two-step update hint when using 1MB boards | |||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", check_printsize) | |||||
# disable postmortem printing to the uart. another one is in eboot, but this is what causes the most harm | |||||
if "DISABLE_POSTMORTEM_STACKDUMP" in env["CPPFLAGS"]: | |||||
env.AddPostAction( | |||||
"$BUILD_DIR/FrameworkArduino/core_esp8266_postmortem.c.o", dummy_ets_printf | |||||
) | |||||
env.AddPostAction( | |||||
"$BUILD_DIR/FrameworkArduino/core_esp8266_postmortem.cpp.o", dummy_ets_printf | |||||
) | |||||
# patch lwip1 sources conditionally: | |||||
# https://github.com/xoseperez/espurna/issues/1610 | |||||
lwip_inject_patcher(env) | |||||
# when using git, add -DAPP_REVISION=(git-commit-hash) | |||||
app_inject_revision(projenv) |