mirror of
https://github.com/crosspoint-reader/crosspoint-reader.git
synced 2026-08-13 14:21:57 -07:00
Replace hardcoded path lookup with a multi-strategy search that tries PlatformIO's package API first, then falls back to globbing common package directories. This handles cases where the framework package name or location varies across installations.
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
"""
|
|
PlatformIO pre-build script: make the arduino-esp32 core define _btLibraryInUse
|
|
in a BLE-controller-only build.
|
|
|
|
The core header cores/esp32/esp32-hal-bt-mem.h emits a constructor
|
|
(_setBtLibraryInUse) that references `_btLibraryInUse` whenever BLE hardware is
|
|
present, but the core only DEFINES that symbol (in esp32-hal-bt.c) when an IDF
|
|
host stack -- CONFIG_BLUEDROID_ENABLED or CONFIG_NIMBLE_ENABLED -- is enabled.
|
|
|
|
CrossPoint runs the ESP-IDF BLE *controller* only, with NimBLE-Arduino supplying
|
|
the host (both IDF host stacks are disabled in custom_sdkconfig to avoid duplicate
|
|
npl_freertos_* symbols). In that configuration the core never defines the symbol,
|
|
so NimBLE's constructor link-fails with "undefined reference to `_btLibraryInUse'"
|
|
-- and it fails in links that application source cannot reach (the final firmware
|
|
link and the arduino-lib-builder core-rebuild's dummy firmware).
|
|
|
|
Fix: turn the header's `extern bool _btLibraryInUse;` DECLARATION into a weak
|
|
DEFINITION. Every translation unit that includes the header (NimBLE) then provides
|
|
the symbol itself; the linker merges the duplicate weak defs, and the core's own
|
|
strong definition still wins whenever a host stack is actually enabled. It must
|
|
live in the header, not our src, because only the header is seen by NimBLE's TU in
|
|
every link.
|
|
|
|
Idempotent text edit. Patching bumps the header mtime, so NimBLE recompiles
|
|
against it on the next build.
|
|
"""
|
|
|
|
Import("env") # noqa: F821 (SCons-injected global)
|
|
import glob
|
|
import os
|
|
|
|
EXTERN_DECL = "extern bool _btLibraryInUse;"
|
|
MARKER = "patch_bt_mem.py"
|
|
WEAK_DEF = (
|
|
"__attribute__((weak)) bool _btLibraryInUse = false; /* CrossPoint " + MARKER + " */"
|
|
)
|
|
|
|
|
|
def _find_header(env):
|
|
rel = os.path.join("cores", "esp32", "esp32-hal-bt-mem.h")
|
|
candidates = []
|
|
|
|
# 1) Ask the platform for the framework package dir (works when the name matches).
|
|
try:
|
|
fw = env.PioPlatform().get_package_dir("framework-arduinoespressif32") # noqa: F821
|
|
if fw:
|
|
candidates.append(os.path.join(fw, rel))
|
|
except Exception:
|
|
pass
|
|
|
|
# 2) Glob the packages dir(s) -- robust to the exact package name/version.
|
|
pkg_dirs = []
|
|
for key in ("PROJECT_PACKAGES_DIR", "PROJECT_CORE_DIR"):
|
|
try:
|
|
d = env.subst("$%s" % key) # noqa: F821
|
|
if d:
|
|
pkg_dirs.append(d)
|
|
except Exception:
|
|
pass
|
|
pkg_dirs.append(os.path.expanduser(os.path.join("~", ".platformio", "packages")))
|
|
for base in pkg_dirs:
|
|
pattern = os.path.join(base, "**", "framework-arduinoespressif32*", rel)
|
|
candidates.extend(glob.glob(pattern, recursive=True))
|
|
|
|
for c in candidates:
|
|
if os.path.isfile(c):
|
|
return c
|
|
return None
|
|
|
|
|
|
def patch_bt_mem(env):
|
|
header = _find_header(env)
|
|
if not header:
|
|
print("patch_bt_mem: esp32-hal-bt-mem.h not found; skipping (controller-only "
|
|
"link may fail on _btLibraryInUse)")
|
|
return
|
|
|
|
with open(header, "r") as f:
|
|
text = f.read()
|
|
|
|
if MARKER in text:
|
|
print("patch_bt_mem: already patched (%s)" % header)
|
|
return
|
|
if EXTERN_DECL not in text:
|
|
print("patch_bt_mem: '%s' not found in %s; NOT patching (upstream header "
|
|
"changed -- update this script)" % (EXTERN_DECL, header))
|
|
return
|
|
|
|
text = text.replace(EXTERN_DECL, WEAK_DEF, 1)
|
|
with open(header, "w") as f:
|
|
f.write(text)
|
|
print("patch_bt_mem: patched %s (_btLibraryInUse now weak-defined)" % header)
|
|
|
|
|
|
patch_bt_mem(env) # noqa: F821
|