exclude the variant from LTO (#10829)

* exclude the variant from LTO

* address CI build failure
clod helped
This commit is contained in:
Tom
2026-07-02 08:14:57 -05:00
committed by GitHub
co-authored by GitHub
parent 4e36f4271e
commit d4db80ebb7
+58 -1
View File
@@ -33,7 +33,7 @@ Import("env")
env.Append(LINKFLAGS=["-flto", "-flto-partition=1to1"]) env.Append(LINKFLAGS=["-flto", "-flto-partition=1to1"])
# The -fno-lto re-compiles below run with the global env, which lacks the framework's # The ISR -fno-lto re-compiles below run with the global env, which lacks the framework's
# bundled-library include dirs -- and those libs cross-include each other (Wire pulls in # bundled-library include dirs -- and those libs cross-include each other (Wire pulls in
# Adafruit_TinyUSB.h, which pulls in SPI.h, ...). Add every bundled-lib dir (+ its src/) so # Adafruit_TinyUSB.h, which pulls in SPI.h, ...). Add every bundled-lib dir (+ its src/) so
# the re-compiles resolve without chasing headers one at a time. # the re-compiles resolve without chasing headers one at a time.
@@ -51,6 +51,52 @@ USB_ISR = "Adafruit_TinyUSB_nrf" # USBD_IRQHandler
LIB_ISR = ("/bluefruit.cpp", "/Wire_nRF52.cpp", "/PDM.cpp", "/RotaryEncoder.cpp") LIB_ISR = ("/bluefruit.cpp", "/Wire_nRF52.cpp", "/PDM.cpp", "/RotaryEncoder.cpp")
# The active board variant file owns strong overrides of the core's weak initVariant()/
# earlyInitVariant()/lateInitVariant() stubs (cores/nRF5/main.cpp). Same failure mode as the ISRs
# above: whole-image LTO mis-resolves the call (made from the -fno-lto framework core) to the empty
# WEAK stub, so the board's early hardware setup -- e.g. driving PIN_3V3_EN to power the LoRa/sensor
# rail -- silently never runs and the radio probe finds no chip. Compiling the variant without LTO
# lets ordinary linking pick the strong override. HW-proven on nrf52_promicro_diy_tcxo (boot-trace
# 2026-06-30). NOTE: only the real board variant (built from /variants/...) -- NOT the guarded
# src/platform/extra_variants/*/variant.cpp no-op stubs, which don't tolerate the -fno-lto recompile.
#
# Anchor to THIS repo's variants/ tree: a board variant's abspath is
# <PROJECT_DIR>/variants/<arch>/<board>/variant.cpp. Anchoring deliberately excludes
# - PlatformIO's framework-owned .../framework-arduinoadafruitnrf52/variants/*/variant.cpp
# - the src/platform/extra_variants/*/variant.cpp stubs (they live under src/, not variants/)
# both of which also end in "/variant.cpp" but must NOT be recompiled here.
_PROJECT_VARIANTS = (
env.subst("$PROJECT_DIR").replace("\\", "/").rstrip("/") + "/variants/"
)
def _is_board_variant(path):
return (
path.endswith("/variant.cpp")
and path.startswith(_PROJECT_VARIANTS)
and "extra_variants" not in path
)
# projenv is the construction env PlatformIO uses to compile project sources (src/ + the board
# variant). Unlike the bare framework env captured above, it carries the -DAPP_VERSION... flags
# and the generated-protobuf include path (pb.h) that bin/platformio-custom.py appends *after*
# this pre-script's eval. It isn't exported yet at eval time, but it is by the time the build
# middleware fires -- so fetch it lazily from SCons' export registry, falling back to env.
_projenv_cache = []
def _get_projenv():
if not _projenv_cache:
try:
from SCons.Script.SConscript import global_exports
_projenv_cache.append(global_exports.get("projenv", env))
except Exception:
_projenv_cache.append(env)
return _projenv_cache[0]
def _no_lto(node): def _no_lto(node):
try: try:
path = node.get_abspath() path = node.get_abspath()
@@ -69,6 +115,17 @@ def _no_lto(node):
CCFLAGS=env["CCFLAGS"] + ["-fno-lto"], CCFLAGS=env["CCFLAGS"] + ["-fno-lto"],
CPPPATH=env["CPPPATH"] + _extra_inc, CPPPATH=env["CPPPATH"] + _extra_inc,
) )
if _is_board_variant(path):
# The board variant is a project source, not a framework object: it can #include
# configuration.h/sleep.h, which need the -DAPP_VERSION... define and the generated-
# protobuf include path (pb.h). Recompile it with projenv (which has both) -- using the
# bare framework env here fails with "APP_VERSION must be set" / "pb.h: No such file".
build_env = _get_projenv()
return build_env.Object(
node,
CCFLAGS=build_env["CCFLAGS"] + ["-fno-lto"],
CPPPATH=build_env["CPPPATH"] + _extra_inc,
)
return node return node