A TU whose only symbols are static (e.g. SHELL_CMD_REGISTER + LOG_MODULE_REGISTER) is silently dropped by the linker when pulled from an archive — the used attribute protects against intra-TU elimination but does not force archive inclusion. Today every CLI file needs a non-static anchor function called from a central init.
Fix (validated in a 2026-04-22 spike): ESP-IDF 5.0+'s idf_component_register(... WHOLE_ARCHIVE) — the same mechanism Zephyr uses, per-component. Applied to the consumer's CLI component (not zshell itself) it eliminates the anchor boilerplate and also fixes LOG_MODULE_REGISTER-only TUs. No macro changes needed.
Work:
- Document in
docs/linker-section-registration.md + zshell README.
- Optional:
zshell_register_cli_component(name) CMake convenience helper.
Ruled out: .lf KEEP() (only guards gc-sections, not archive pull-in); visibility attributes (archive pull is driven by unresolved refs, not visibility).
A TU whose only symbols are
static(e.g.SHELL_CMD_REGISTER+LOG_MODULE_REGISTER) is silently dropped by the linker when pulled from an archive — theusedattribute protects against intra-TU elimination but does not force archive inclusion. Today every CLI file needs a non-static anchor function called from a central init.Fix (validated in a 2026-04-22 spike): ESP-IDF 5.0+'s
idf_component_register(... WHOLE_ARCHIVE)— the same mechanism Zephyr uses, per-component. Applied to the consumer's CLI component (not zshell itself) it eliminates the anchor boilerplate and also fixesLOG_MODULE_REGISTER-only TUs. No macro changes needed.Work:
docs/linker-section-registration.md+ zshell README.zshell_register_cli_component(name)CMake convenience helper.Ruled out:
.lfKEEP()(only guards gc-sections, not archive pull-in); visibility attributes (archive pull is driven by unresolved refs, not visibility).