Skip to content

Commit 6d7c1d0

Browse files
committed
Improve usermod validation warnings
1 parent a94a3f7 commit 6d7c1d0

2 files changed

Lines changed: 20 additions & 7 deletions

File tree

pio-scripts/dynarray.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# This is implemented as a pio post-script to ensure that we can
33
# place our linker script at the correct point in the command arguments.
44
Import("env")
5+
import shutil
56
from pathlib import Path
67

78
# Linker script fragment injected into the rodata output section of whichever
@@ -18,7 +19,13 @@
1819
def inject_before_marker(path, marker):
1920
"""Patch a linker script file in-place, inserting DYNARRAY_INJECTION before marker."""
2021
original = path.read_text()
21-
path.write_text(original.replace(marker, DYNARRAY_INJECTION + marker, 1))
22+
marker_pos = original.find(marker)
23+
if marker_pos < 0:
24+
raise RuntimeError(
25+
f"DYNARRAY injection marker not found in linker script: path={path}, marker={marker!r}"
26+
)
27+
patched = original[:marker_pos] + DYNARRAY_INJECTION + original[marker_pos:]
28+
path.write_text(patched)
2229

2330

2431
if env.get("PIOPLATFORM") == "espressif32":
@@ -38,7 +45,6 @@ def inject_before_marker(path, marker):
3845
# leaves the ASSERTs satisfied.
3946
build_dir = Path(env.subst("$BUILD_DIR"))
4047
patched_path = build_dir / "dynarray_sections.ld"
41-
import shutil
4248
shutil.copy(sections_ld_path, patched_path)
4349
inject_before_marker(patched_path, "_rodata_end = ABSOLUTE(.);")
4450

pio-scripts/validate_modules.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ def check_elf_modules(elf_path: Path, env, module_lib_builders) -> set[str]:
3737
Returns the set of build_dir basenames for confirmed modules.
3838
"""
3939
readelf_path = _get_readelf_path(env)
40-
secho(f"INFO: Checking for usermod compilation units...")
41-
4240
try:
4341
result = subprocess.run(
4442
[readelf_path, "--debug-dump=info", "--dwarf-depth=1", str(elf_path)],
4543
capture_output=True, text=True, errors="ignore", timeout=120,
4644
)
4745
output = result.stdout
46+
if result.returncode != 0 or result.stderr.strip():
47+
secho(f"WARNING: readelf exited {result.returncode}: {result.stderr.strip()}", fg="yellow", err=True)
4848
except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
4949
secho(f"WARNING: readelf failed ({e}); skipping per-module validation", fg="yellow", err=True)
5050
return {Path(b.build_dir).name for b in module_lib_builders} # conservative pass
@@ -143,20 +143,27 @@ def validate_map_file(source, target, env):
143143
Exit(1)
144144

145145
# Identify the WLED module builders, set by load_usermods.py
146-
module_lib_builders = env['WLED_MODULES']
146+
module_lib_builders = env.get('WLED_MODULES')
147+
if module_lib_builders is None:
148+
secho("ERROR: WLED_MODULES not set — ensure load_usermods.py is run as a pre: script", fg="red", err=True)
149+
Exit(1)
147150

148151
# Extract the values we care about
149152
modules = {Path(builder.build_dir).name: builder.name for builder in module_lib_builders}
150-
secho(f"INFO: {len(modules)} libraries linked as WLED optional/user modules")
153+
secho(f"INFO: {len(modules)} libraries included as WLED optional/user modules")
151154

152155
# Now parse the map file
153156
map_file_contents = read_lines(map_file_path)
154157
usermod_object_count = count_usermod_objects(map_file_contents)
155-
secho(f"INFO: {usermod_object_count} usermod object entries")
158+
secho(f"INFO: {usermod_object_count} usermod object entries found")
156159

157160
elf_path = build_dir / env.subst("${PROGNAME}.elf")
158161

159162
confirmed_modules = check_elf_modules(elf_path, env, module_lib_builders)
163+
if confirmed_modules:
164+
secho(f"INFO: Code from usermod libraries found in binary: {', '.join(confirmed_modules)}")
165+
# else - if there's no usermods found, don't generate a message. If we're legitimately missing all entries, the error report on the
166+
# next line will trip; and if the usermod set is expected to be empty, then there's no need for yet another null message.
160167

161168
missing_modules = [modname for mdir, modname in modules.items() if mdir not in confirmed_modules]
162169
if missing_modules:

0 commit comments

Comments
 (0)