Mirror of espurna firmware for wireless switches and more
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.8 KiB

5 years ago
  1. #!/usr/bin/env python
  2. from __future__ import print_function
  3. import os
  4. import sys
  5. from subprocess import call
  6. import click
  7. Import("env", "projenv")
  8. PIO_PLATFORM = env.PioPlatform()
  9. FRAMEWORK_DIR = PIO_PLATFORM.get_package_dir("framework-arduinoespressif8266")
  10. # ------------------------------------------------------------------------------
  11. # Utils
  12. # ------------------------------------------------------------------------------
  13. class Color(object):
  14. BLACK = '\x1b[1;30m'
  15. RED = '\x1b[1;31m'
  16. GREEN = '\x1b[1;32m'
  17. YELLOW = '\x1b[1;33m'
  18. BLUE = '\x1b[1;34m'
  19. MAGENTA = '\x1b[1;35m'
  20. CYAN = '\x1b[1;36m'
  21. WHITE = '\x1b[1;37m'
  22. LIGHT_GREY = '\x1b[0;30m'
  23. LIGHT_RED = '\x1b[0;31m'
  24. LIGHT_GREEN = '\x1b[0;32m'
  25. LIGHT_YELLOW = '\x1b[0;33m'
  26. LIGHT_BLUE = '\x1b[0;34m'
  27. LIGHT_MAGENTA = '\x1b[0;35m'
  28. LIGHT_CYAN = '\x1b[0;36m'
  29. LIGHT_WHITE = '\x1b[0;37m'
  30. def clr(color, text):
  31. return color + str(text) + '\x1b[0m'
  32. def print_warning(message, color=Color.LIGHT_YELLOW):
  33. print(clr(color, message), file=sys.stderr)
  34. def print_filler(fill, color=Color.WHITE, err=False):
  35. width, _ = click.get_terminal_size()
  36. if len(fill) > 1:
  37. fill = fill[0]
  38. out = sys.stderr if err else sys.stdout
  39. print(clr(color, fill * width), file=out)
  40. def ldscript_inject_libpath():
  41. # espressif8266@1.5.0 did not append this directory into the LIBPATH
  42. libpath_sdk = os.path.join(FRAMEWORK_DIR, "tools", "sdk", "ld")
  43. env.Append(LIBPATH=[libpath_sdk])
  44. libpath_base = os.path.join("$PROJECT_DIR", "..", "dist", "ld")
  45. env.Append(LIBPATH=[
  46. os.path.join(libpath_base, "pre_2.5.0")
  47. ])
  48. # local.eagle.app.v6.common.ld exists only with Core >2.5.0
  49. def check_local_ld(target ,source, env):
  50. local_ld = env.subst(os.path.join("$BUILD_DIR", "ld", "local.eagle.app.v6.common.ld"))
  51. if os.path.exists(local_ld):
  52. env.Prepend(LIBPATH=[
  53. os.path.join(libpath_base, "latest")
  54. ])
  55. env.AddPreAction(
  56. os.path.join("$BUILD_DIR", "firmware.elf"),
  57. check_local_ld
  58. )
  59. # ------------------------------------------------------------------------------
  60. # Callbacks
  61. # ------------------------------------------------------------------------------
  62. def remove_float_support():
  63. flags = " ".join(env['LINKFLAGS'])
  64. flags = flags.replace("-u _printf_float", "")
  65. flags = flags.replace("-u _scanf_float", "")
  66. newflags = flags.split()
  67. env.Replace(
  68. LINKFLAGS = newflags
  69. )
  70. def cpp_check(target, source, env):
  71. print("Started cppcheck...\n")
  72. call(["cppcheck", os.getcwd()+"/espurna", "--force", "--enable=all"])
  73. print("Finished cppcheck...\n")
  74. def check_size(target, source, env):
  75. (binary,) = target
  76. path = binary.get_abspath()
  77. size = os.stat(path).st_size
  78. print(clr(Color.LIGHT_BLUE, "Binary size: {} bytes".format(size)))
  79. # Warn 1MB variants about exceeding OTA size limit
  80. flash_size = int(env.BoardConfig().get("upload.maximum_size", 0))
  81. if (flash_size == 1048576) and (size >= 512000):
  82. print_filler("*", color=Color.LIGHT_YELLOW, err=True)
  83. print_warning("File is too large for OTA! Here you can find instructions on how to flash it:")
  84. print_warning("https://github.com/xoseperez/espurna/wiki/TwoStepUpdates", color=Color.LIGHT_CYAN)
  85. print_filler("*", color=Color.LIGHT_YELLOW, err=True)
  86. def dummy_ets_printf(target, source, env):
  87. (postmortem_src_file, ) = source
  88. (postmortem_obj_file, ) = target
  89. cmd = ["xtensa-lx106-elf-objcopy"]
  90. # recent Core switched to cpp+newlib & ets_printf_P
  91. cmd.extend(["--redefine-sym", "ets_printf=dummy_ets_printf"])
  92. cmd.extend(["--redefine-sym", "ets_printf_P=dummy_ets_printf"])
  93. cmd.append(postmortem_obj_file.get_abspath())
  94. env.Execute(env.VerboseAction(" ".join(cmd), "Removing ets_printf / ets_printf_P"))
  95. env.Depends(postmortem_obj_file,"$BUILD_DIR/src/dummy_ets_printf.c.o")
  96. def patch_lwip():
  97. # ignore when building with lwip2
  98. if "lwip_gcc" not in env["LIBS"]:
  99. return
  100. toolchain_prefix = os.path.join(PIO_PLATFORM.get_package_dir("toolchain-xtensa"), "bin", "xtensa-lx106-elf-")
  101. patch_action = env.VerboseAction(" ".join([
  102. "-patch", "-u", "-N", "-d",
  103. os.path.join(FRAMEWORK_DIR, "tools", "sdk", "lwip"),
  104. os.path.join("src", "core", "tcp_out.c"),
  105. env.subst(os.path.join("$PROJECT_DIR", "..", "dist", "patches", "lwip_mtu_issue_1610.patch"))
  106. ]), "Patching lwip source")
  107. build_action = env.VerboseAction(" ".join([
  108. "make", "-C", os.path.join(FRAMEWORK_DIR, "tools", "sdk", "lwip", "src"),
  109. "install",
  110. "TOOLS_PATH={}".format(toolchain_prefix),
  111. "LWIP_LIB=liblwip_gcc.a"
  112. ]), "Rebuilding lwip")
  113. patcher = env.Alias("patch-lwip", None, patch_action)
  114. builder = env.Alias("build-lwip", patcher, build_action)
  115. if os.environ.get("ESPURNA_PIO_PATCH_ISSUE_1610"):
  116. env.Depends("$BUILD_DIR/${PROGNAME}.elf", builder)
  117. env.AlwaysBuild(patcher)
  118. env.AlwaysBuild(builder)
  119. # ------------------------------------------------------------------------------
  120. # Hooks
  121. # ------------------------------------------------------------------------------
  122. # Always show warnings for project code
  123. projenv.ProcessUnFlags("-w")
  124. # 2.4.0 and up
  125. remove_float_support()
  126. ldscript_inject_libpath()
  127. # two-step update hint when using 1MB boards
  128. env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", check_size)
  129. # disable postmortem printing to the uart. another one is in eboot, but this is what causes the most harm
  130. if "DISABLE_POSTMORTEM_STACKDUMP" in env["CPPFLAGS"]:
  131. env.AddPostAction("$BUILD_DIR/FrameworkArduino/core_esp8266_postmortem.c.o", dummy_ets_printf)
  132. env.AddPostAction("$BUILD_DIR/FrameworkArduino/core_esp8266_postmortem.cpp.o", dummy_ets_printf)
  133. # patch lwip1 sources conditionally:
  134. # https://github.com/xoseperez/espurna/issues/1610
  135. patch_lwip()