micro-ROS / micro-ROS/micro_ros_espidf_component

Menuconfig transport selection does not propagate to vendored libmicroros build

Open
#379 0 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.