micro-ROS / micro-ROS/micro_ros_espidf_component
Menuconfig transport selection does not propagate to vendored libmicroros build
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 419
- Forks
- 124
- Avg merge
- 21h 35m
- Merged PRs (30d)
- 3
Description
### Summary
Selecting `Micro XRCE-DDS over UART` under `micro-ROS Settings > micro-ROS network interface select` in `idf.py menuconfig` sets the ESP-IDF-side transport wrapper but has no effect on the vendored colcon build that produces `libmicroros.a`. The rmw layer is still compiled with `-DRMW_UXRCE_TRANSPORT=udp` from the vendored `colcon.meta`, so `RMW_UXRCE_TRANSPORT_CUSTOM` is never defined, `rmw_microros/rmw_microros.h` skips the guarded include of `custom_transport.h`, and any call to `rmw_uros_set_custom_transport()` fails at compile time with `-Werror=implicit-function-declaration`.
A workaround exists via `app-colcon.meta` at the app root, the pickup is already implemented in `CMakeLists.txt` and threaded through `libmicroros.mk` as `APP_COLCON_META`.
### Environment
- Branch: `jazzy`
- Commit: `16cf0d534e618c2752e5546710cd2c81c0a586cc`
- Target: ESP32-S3 DevKitC-1
- ESP-IDF: v5.3.5
- Host: Ubuntu 24.04 on WSL2
### Reproducer
```bash
# From an ESP-IDF project with this component vendored under components/
idf.py set-target esp32s3
idf.py menuconfig
# Component config -> micro-ROS Settings -> micro-ROS network interface select -> "Micro XRCE-DDS over UART"
idf.py clean-microros
idf.py build
```
Application code calling `rmw_uros_set_custom_transport()` fails:
```
error: implicit declaration of function 'rmw_uros_set_custom_transport'
[-Werror=implicit-function-declaration]
```
The generated `rmw_microxrcedds_c/config.h` confirms the root cause:
```
#define RMW_UXRCE_TRANSPORT_UDP
/* #undef RMW_UXRCE_TRANSPORT_CUSTOM */
```
The menuconfig transport symbol `CONFIG_MICRO_ROS_ESP_UART_TRANSPORT=y` never enters the colcon build; the vendored `colcon.meta` hard-codes `-DRMW_UXRCE_TRANSPORT=udp` and this wins by default.
### Verified workaround
Create `app-colcon.meta` at the app root (sibling to `main/`), using the required `"names"` wrapper:
```json
{
"names": {
"rmw_microxrcedds": {
"cmake-args": [
"-DRMW_UXRCE_TRANSPORT=custom"
]
}
}
}
```
Then `idf.py clean-microros && idf.py build`. Verified end to end on the environment above: `RMW_UXRCE_TRANSPORT_CUSTOM` is defined in the built `config.h` and the application compiles and links cleanly.
Note: the "names" wrapper is required. A JSON body without it is parsed successfully, added to --metas, and its contents silently ignored, reproducing the original compile error with no signal that the override was rejected.
### Proposed fix
Have the component's `CMakeLists.txt` map the Kconfig transport selection to the correct `RMW_UXRCE_TRANSPORT` value and generate a small meta file in the build tree, passed to colcon via the existing `APP_COLCON_META` seam. Any user-supplied `app-colcon.meta` continues to override the generated one, so nothing that already works breaks.
On the jazzy branch, `Kconfig.projbuild` exposes exactly three network-interface options, so the mapping is minimal:
- `CONFIG_MICRO_ROS_ESP_NETIF_WLAN` -> `udp`
- `CONFIG_MICRO_ROS_ESP_NETIF_ENET` -> `udp`
- `CONFIG_MICRO_ROS_ESP_UART_TRANSPORT` -> `custom`
Sketch (approve-or-steer level, not the final diff):
```cmake
if(CONFIG_MICRO_ROS_ESP_UART_TRANSPORT)
set(UROS_RMW_TRANSPORT "custom")
elseif(CONFIG_MICRO_ROS_ESP_NETIF_WLAN OR CONFIG_MICRO_ROS_ESP_NETIF_ENET)
set(UROS_RMW_TRANSPORT "udp")
else()
set(UROS_RMW_TRANSPORT "udp")
endif()
set(UROS_KCONFIG_META "${CMAKE_BINARY_DIR}/uros_kconfig_transport.meta")
file(WRITE ${UROS_KCONFIG_META}
"{\"names\": {\"rmw_microxrcedds\": {\"cmake-args\": [\"-DRMW_UXRCE_TRANSPORT=${UROS_RMW_TRANSPORT}\"]}}}\n"
)
# Compose APP_COLCON_META so user-supplied app-colcon.meta still wins
set(UROS_APP_COLCON_META "${UROS_KCONFIG_META}")
if(EXISTS "${PROJECT_DIR}/app-colcon.meta")
set(UROS_APP_COLCON_META
"${UROS_KCONFIG_META} ${PROJECT_DIR}/app-colcon.meta")
endif()
```
Users on WLAN or Ethernet: unchanged (both resolve to `udp`, matching the current vendored `colcon.meta`). Users with an existing `app-colcon.meta`: unchanged (their file is passed last and still wins). Users who edited the vendored `colcon.meta` directly: still works (their edit is the first `--metas` entry; the generated meta comes after and overrides only the transport field).
### Cache invalidation
One rough edge worth flagging: changing the menuconfig transport option changes the content of the generated meta, but colcon's build cache for `libmicroros.a` is not invalidated on that change. An initial PR would preserve that behaviour and add a README note that `idf.py clean-microros` is required after any transport change. A follow-up PR could make the generated meta a proper build dependency of `libmicroros.a` for automatic invalidation; I would prefer to keep those separate.
### Ask
I would like to submit this fix. Before writing the PR I want to confirm two things:
1. Is auto-generating the transport meta from Kconfig the direction you want? If you prefer a smaller change (README-only clarification of the `app-colcon.meta` workaround, its `names` schema requirement, and its silent-failure trap) I am happy to do that instead.
2. Is `${PROJECT_DIR}/app-colcon.meta` the correct convention for the "app root" pickup on jazzy? That matches the existing `CMakeLists.txt` lines around 26-28; I want to confirm this generalises before I compose against it.
Diagnosis and workaround verified with ESP-IDF v5.3.5. Happy to attach a minimal reproducer as an example under `examples/` if useful.
Thanks for maintaining this component.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the transport options in Kconfig.projbuild and the existing APP_COLCON_META handling in CMakeLists.txt around lines 26-28, then trace how libmicroros.mk passes metadata to the vendored colcon build. Reproduce the UART configuration with the listed idf.py commands and inspect the generated rmw_microxrcedds/config.h. Done means the selected transport reaches the generated configuration and the application builds with the documented clean step.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cmake
- Domain
- build-system, embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100