Skip to main content

Module section

Module section 

Source
Expand description

RMW backend self-registration (Phase 249 P4b.1 — .init_array ctor).

Every nros-rmw-<name> crate (or C/C++ static lib) self-registers its vtable with the cffi registry. The trigger differs by tier:

  • Hosted (Rust + C/C++): the backend emits a #[used] ctor function pointer into the platform loader’s pre-main init section (.init_array on ELF). The loader fires every ctor before main, so each backend’s crate::nros_rmw_cffi_register_named call has already run by the time the runtime opens a session. No runtime walk, no linkme distributed slice.

  • Embedded (target_os = "none"): the ctor expands to nothing. Bare-metal firmware has no loader that walks .init_array in the shape the registry needs, so the board / typed carrier calls nros_rmw_<x>::register() EXPLICITLY (phase-249 P1). The RTOS targets (NuttX / Zephyr / ESP-IDF / VxWorks) keep that explicit call too; the ctor there is harmless (register is idempotent).

The native app keeps its #[used] __FORCE_LINK_* anchor (phase-244 D7 Shape B): the anchor defeats dead-code elimination so the backend closure AND its ctor survive into the final binary — it is NOT a registration call.

This replaces the phase-128 linkme distributed-slice walker (RMW_INIT_ENTRIES + nros_rmw_cffi_walk_init_section), removed in phase-249 P4b.1 (RFC-0042 §D3.3).

§C / C++ backends

Static-lib backends emit their entry via the NROS_RMW_REGISTER_BACKEND macro in <nros/rmw_vtable.h>; the cmake nano_ros_link_rmw strong stub handles the C/C++-via-cmake path (phase-249 P2b/P4a).