#!/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()