Skip to content

libmicroros.a is built with a hand-maintained toolchain file that may drift from IDF's compile flags (ABI mismatch risk) #373

Description

@Narukara

From #334 (comment)

The following content was generated by AI

Cause

micro-ROS is not built as regular IDF component sources. Instead, the component's CMake configure step invokes libmicroros.mk, which runs a separate colcon build to produce libmicroros.a, and the result is linked back into the ELF via add_prebuilt_library. This separate build uses its own toolchain file (esp32_toolchain.cmake.in) that only passes through a hand-picked subset of compile options (compiler binary, C standard, sdkconfig.cmake, IDF includes, a few hardcoded flags), rather than inheriting the full set of flags IDF applies to its own components.

Impact

Some ABI-affecting flags used by the main IDF build are not propagated to the micro-ROS sub-build, so libmicroros.a can be compiled with settings inconsistent with the rest of the firmware. Known gaps:

  • RISC-V -march/-mabi are not set (relies on compiler defaults) — a mismatch here breaks the calling convention/ABI.
  • PSRAM cache workaround flags (e.g. -mfix-esp32-psram-cache-issue) are not forwarded.
  • The hardcoded flag list in esp32_toolchain.cmake.in must be kept in sync manually and can silently drift as IDF changes.

(Note: many flags like optimization level or stack protector are not ABI-breaking, so their absence is harmless — the concern is specifically the ABI/codegen-relevant ones.)

Because the same compiler is used and sdkconfig.cmake is included, most struct-layout / config-dependent mismatches are already avoided, so this is a latent risk rather than a guaranteed failure — but it can produce hard-to-debug link/runtime issues in specific configurations (e.g. SPIRAM enabled, certain RISC-V targets).

Possible fix

Keeping micro-ROS as a separately built static library is unavoidable (it depends on the ROS 2 / colcon / rosidl build system), so the goal is not to remove this mechanism but to make the sub-build inherit IDF's ABI-relevant flags instead of hardcoding a subset:

  • Query the flags IDF actually uses for its components (e.g. CMAKE_C_FLAGS / COMPILE_OPTIONS, especially RISC-V -march/-mabi and PSRAM-related flags) in the outer CMakeLists.txt and pass them through libmicroros.mk into the toolchain file.
  • As a minimum/interim step, document the list of flags that are known not to be synced and must be verified manually.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions