From ea03f9119016be38a72b1602bf76f258dfa41662 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 05:00:00 +0000 Subject: [PATCH 1/9] apps/system/microros: add micro_ros_lib directory skeleton. Add micro_ros_lib/ subdirectory with a .keep sentinel so the directory is tracked by git before any generated build artifacts appear. All colcon/fetch outputs land here and are gitignored by the parent .gitignore. Signed-off-by: Arjav Patel --- system/microros/micro_ros_lib/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 system/microros/micro_ros_lib/.keep diff --git a/system/microros/micro_ros_lib/.keep b/system/microros/micro_ros_lib/.keep new file mode 100644 index 00000000000..e69de29bb2d From a7828947b759344ef2aef9a51f82453f37b3df7a Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 05:43:58 +0000 Subject: [PATCH 2/9] apps/system/microros: add colcon.meta.in resource-limit template. Add a colcon.meta.in template that is substituted at build time with Kconfig values. Key settings: - Custom transport only (UCLIENT_PROFILE_CUSTOM_TRANSPORT=ON, UCLIENT_PROFILE_STREAM_FRAMING=ON) -- actual UDP/serial callbacks are wired in Phase 4. - RCL_MICROROS=ON (Jazzy/Kilted renamed flag replacing the old RCL_COMMAND_LINE_ENABLED/RCL_LOGGING_ENABLED pair). - RCUTILS_NO_FILESYSTEM=OFF -- NuttX provides POSIX filesystem. - Resource limits use @MAX_NODES@/@MAX_PUBLISHERS@ etc. placeholders substituted from CONFIG_MICROROS_MAX_* Kconfig values. Signed-off-by: Arjav Patel --- system/microros/micro_ros_lib/colcon.meta.in | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 system/microros/micro_ros_lib/colcon.meta.in diff --git a/system/microros/micro_ros_lib/colcon.meta.in b/system/microros/micro_ros_lib/colcon.meta.in new file mode 100644 index 00000000000..00468545b15 --- /dev/null +++ b/system/microros/micro_ros_lib/colcon.meta.in @@ -0,0 +1,52 @@ +{ + "names": { + "microxrcedds_client": { + "cmake-args": [ + "-DUCLIENT_PIC=OFF", + "-DUCLIENT_PROFILE_DISCOVERY=OFF", + "-DUCLIENT_PROFILE_UDP=OFF", + "-DUCLIENT_PROFILE_TCP=OFF", + "-DUCLIENT_PROFILE_SERIAL=OFF", + "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON", + "-DUCLIENT_PROFILE_STREAM_FRAMING=ON", + "-DUCLIENT_EXTERNAL_SERIAL=ON" + ] + }, + "rmw_microxrcedds": { + "cmake-args": [ + "-DRMW_UXRCE_TRANSPORT=custom", + "-DRMW_UXRCE_MAX_NODES=@MAX_NODES@", + "-DRMW_UXRCE_MAX_PUBLISHERS=@MAX_PUBLISHERS@", + "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=@MAX_SUBSCRIPTIONS@", + "-DRMW_UXRCE_MAX_SERVICES=@MAX_SERVICES@", + "-DRMW_UXRCE_MAX_CLIENTS=@MAX_CLIENTS@", + "-DRMW_UXRCE_MAX_HISTORY=4" + ] + }, + "rcl": { + "cmake-args": [ + "-DRCL_MICROROS=ON" + ] + }, + "rcutils": { + "cmake-args": [ + "-DRCUTILS_NO_FILESYSTEM=OFF", + "-DRCUTILS_NO_THREAD_SUPPORT=ON", + "-DRCUTILS_NO_64_ATOMIC=ON", + "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON", + "-DENABLE_TESTING=OFF" + ] + }, + "rosidl_typesupport": { + "cmake-args": [ + "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON" + ] + }, + "tracetools": { + "cmake-args": [ + "-DTRACETOOLS_DISABLED=ON", + "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF" + ] + } + } +} From 0ce3519ca28b222347d370f427275c28529a9da6 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 06:23:38 +0000 Subject: [PATCH 3/9] apps/system/microros: add CMake cross-compile toolchain template. Add toolchain.cmake.in and include_override/assert.h for the colcon cross-build. Key differences from the old robertobucher port: - Drop -DCLOCK_MONOTONIC=0: NuttX defines CLOCK_MONOTONIC=1 and the override broke nanosleep() on newer kernels. - CMAKE_SYSTEM_PROCESSOR is a placeholder substituted per-arch. - include_override/assert.h works around the rosidl NDEBUG issue (https://github.com/ros2/rosidl/pull/739). Signed-off-by: Arjav Patel --- .../micro_ros_lib/include_override/assert.h | 41 +++++++++++++++++++ .../microros/micro_ros_lib/toolchain.cmake.in | 29 +++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 system/microros/micro_ros_lib/include_override/assert.h create mode 100644 system/microros/micro_ros_lib/toolchain.cmake.in diff --git a/system/microros/micro_ros_lib/include_override/assert.h b/system/microros/micro_ros_lib/include_override/assert.h new file mode 100644 index 00000000000..1874aa3045a --- /dev/null +++ b/system/microros/micro_ros_lib/include_override/assert.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * apps/system/microros/micro_ros_lib/include_override/assert.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __MICROROS_INCLUDE_OVERRIDE_ASSERT_H +#define __MICROROS_INCLUDE_OVERRIDE_ASSERT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Pull the system assert.h, then redefine assert to a no-op when NDEBUG is + * set. Avoids an assert redefinition conflict in rosidl typesupport. + */ + +#include_next + +#ifdef NDEBUG +# undef assert +# define assert(x) ((void)(0)) +#endif + +#endif /* __MICROROS_INCLUDE_OVERRIDE_ASSERT_H */ diff --git a/system/microros/micro_ros_lib/toolchain.cmake.in b/system/microros/micro_ros_lib/toolchain.cmake.in new file mode 100644 index 00000000000..dbdc290e238 --- /dev/null +++ b/system/microros/micro_ros_lib/toolchain.cmake.in @@ -0,0 +1,29 @@ +include(CMakeForceCompiler) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR @CMAKE_SYSTEM_PROCESSOR@) +set(CMAKE_CROSSCOMPILING 1) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +set(PLATFORM_NAME "nuttx") + +set(CMAKE_C_COMPILER @CMAKE_C_COMPILER@) +set(CMAKE_CXX_COMPILER @CMAKE_CXX_COMPILER@) + +set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D'__attribute__(x)='" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D'__attribute__(x)='" CACHE STRING "" FORCE) + +set(NUTTX_TOPDIR @NUTTX_TOPDIR@) +set(NUTTX_APPDIR @NUTTX_APPDIR@) +set(INCLUDE_OVR_DIR @INCLUDE_OVR_DIR@) + +include_directories(SYSTEM + ${NUTTX_TOPDIR}/include + ${NUTTX_TOPDIR}/include/cxx + ${NUTTX_APPDIR}/include +) + +include_directories(AFTER SYSTEM + ${INCLUDE_OVR_DIR}/include_override +) + +set(__BIG_ENDIAN__ 0) From b7d42fefa020f9fd9dd8b347c8d8bef8218a9444 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 07:04:05 +0000 Subject: [PATCH 4/9] apps/system/microros: add libmicroros.a colcon build pipeline. Replace the Directory.mk stub with a full Application.mk-based Makefile that builds libmicroros.a from upstream micro-ROS sources via colcon. Build pipeline (six steps, each a Make target): 1. micro_ros_dev/install -- clone + build ament/colcon host tools 2. micro_ros_src/src -- git clone all Jazzy micro-ROS packages with --depth 1; apply DIR-typedef guard patch; mark unused packages COLCON_IGNORE 3. toolchain.cmake -- sed-substitute CC/CXX/CFLAGS into template 4. colcon.meta -- sed-substitute Kconfig resource limits 5. micro_ros_src/install -- colcon cross-build (merge-install, packages-ignore-regex=.*_cpp) 6. libmicroros.a -- ar-merge all install/lib/*.a into one archive; copy include/ tree clean:: removes generated files; distclean:: removes all fetched dirs. Signed-off-by: Arjav Patel --- system/microros/Makefile | 223 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 1 deletion(-) diff --git a/system/microros/Makefile b/system/microros/Makefile index b907087eeb6..6d34e3cc37f 100644 --- a/system/microros/Makefile +++ b/system/microros/Makefile @@ -20,6 +20,227 @@ # ############################################################################ +include $(APPDIR)/Make.defs + +MICROROS_DIR := $(APPDIR)/system/microros +MICROROS_LIB_DIR := $(MICROROS_DIR)/micro_ros_lib +MICROROS_DISTRO := $(patsubst "%",%,$(CONFIG_MICROROS_DISTRO)) +MICROROS_AR := $(CROSSDEV)ar + +MAX_NODES := $(CONFIG_MICROROS_MAX_NODES) +MAX_PUB := $(CONFIG_MICROROS_MAX_PUBLISHERS) +MAX_SUB := $(CONFIG_MICROROS_MAX_SUBSCRIPTIONS) +MAX_SVC := $(CONFIG_MICROROS_MAX_SERVICES) +MAX_CLIENTS := $(CONFIG_MICROROS_MAX_CLIENTS) + +# Escape for sed: forward slashes and strip quotes +ESCAPED_CC := $(subst /,\/,$(CC)) +ESCAPED_CXX := $(subst /,\/,$(CXX)) +ESCAPED_TOPDIR := $(subst /,\/,$(TOPDIR)) +ESCAPED_APPDIR := $(subst /,\/,$(APPDIR)) +ESCAPED_LIBDIR := $(subst /,\/,$(MICROROS_LIB_DIR)) +ESCAPED_CFLAGS := $(subst /,\/,$(subst ",,$(CFLAGS))) +ESCAPED_CXXFLAGS := $(subst /,\/,$(subst ",,$(CXXFLAGS))) + MENUDESC = "micro-ROS Library" -include $(APPDIR)/Directory.mk +# Architecture for CMake toolchain +ifeq ($(CONFIG_ARCH_ARM),y) +MICROROS_ARCH := arm +else ifeq ($(CONFIG_ARCH_ARM64),y) +MICROROS_ARCH := arm64 +else ifeq ($(CONFIG_ARCH_RISCV),y) +MICROROS_ARCH := riscv +else ifeq ($(CONFIG_ARCH_XTENSA),y) +MICROROS_ARCH := xtensa +else +MICROROS_ARCH := generic +endif + +# Wire libmicroros.a into the build when the context target fires +context:: $(MICROROS_DIR)/libmicroros.a + +# --------------------------------------------------------------------------- +# Step 1 – Build the ament/colcon dev tools (host-side) +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/micro_ros_dev/install: + rm -rf $(MICROROS_LIB_DIR)/micro_ros_dev + mkdir -p $(MICROROS_LIB_DIR)/micro_ros_dev/src + cd $(MICROROS_LIB_DIR)/micro_ros_dev && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_cmake src/ament_cmake && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_lint src/ament_lint && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_package src/ament_package && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/googletest src/googletest && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/ament_cmake_ros src/ament_cmake_ros && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_index src/ament_index && \ + touch src/ament_cmake_ros/rmw_test_fixture_implementation/COLCON_IGNORE 2>/dev/null || true && \ + touch src/ament_cmake_ros/rmw_test_fixture/COLCON_IGNORE 2>/dev/null || true && \ + colcon build --cmake-args -DBUILD_TESTING=OFF + +# --------------------------------------------------------------------------- +# Step 2 – Clone all micro-ROS source packages +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/micro_ros_src/src: $(MICROROS_LIB_DIR)/micro_ros_dev/install + rm -rf $(MICROROS_LIB_DIR)/micro_ros_src + mkdir -p $(MICROROS_LIB_DIR)/micro_ros_src/src + cd $(MICROROS_LIB_DIR)/micro_ros_src && \ + git clone -b ros2 --depth 1 \ + https://github.com/eProsima/micro-CDR src/micro-CDR && \ + git clone -b ros2 --depth 1 \ + https://github.com/eProsima/Micro-XRCE-DDS-Client src/Micro-XRCE-DDS-Client && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rmw-microxrcedds src/rmw_microxrcedds && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rcl src/rcl && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rclc src/rclc && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rcutils src/rcutils && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl src/rosidl && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl_defaults src/rosidl_defaults && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl_dynamic_typesupport src/rosidl_dynamic_typesupport && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl_core src/rosidl_core && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rmw src/rmw && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rmw_implementation src/rmw_implementation && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rcl_interfaces src/rcl_interfaces && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/common_interfaces src/common_interfaces && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rcl_logging src/rcl_logging && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/micro_ros_msgs src/micro_ros_msgs && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rosidl_typesupport src/rosidl_typesupport && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rosidl_typesupport_microxrcedds src/rosidl_typesupport_microxrcedds && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/micro_ros_utilities src/micro_ros_utilities && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/unique_identifier_msgs src/unique_identifier_msgs && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/test_interface_files src/test_interface_files && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/ros2_tracing src/ros2_tracing && \ + touch src/ros2_tracing/test_tracetools/COLCON_IGNORE && \ + touch src/ros2_tracing/lttngpy/COLCON_IGNORE && \ + touch src/rmw/rmw_security_common/COLCON_IGNORE && \ + touch src/rcl_logging/rcl_logging_spdlog/COLCON_IGNORE && \ + touch src/rclc/rclc_examples/COLCON_IGNORE && \ + touch src/rcl/rcl_yaml_param_parser/COLCON_IGNORE && \ + touch src/rosidl/rosidl_typesupport_introspection_cpp/COLCON_IGNORE && \ + touch src/rcl_interfaces/test_msgs/COLCON_IGNORE && \ + touch src/common_interfaces/actionlib_msgs/COLCON_IGNORE && \ + touch src/common_interfaces/std_srvs/COLCON_IGNORE && \ + patch -p1 --forward --ignore-whitespace \ + -d src < $(MICROROS_LIB_DIR)/patches/0001-dir-typedef-nuttx-guard.patch || true && \ + patch -p1 --forward --ignore-whitespace \ + -d src < $(MICROROS_LIB_DIR)/patches/0002-rcutils-process-nuttx-compat.patch || true && \ + patch -p1 --forward --ignore-whitespace \ + -d src < $(MICROROS_LIB_DIR)/patches/0003-rcutils-strcasecmp-include-strings-h.patch || true + +# --------------------------------------------------------------------------- +# Step 3 – Generate toolchain.cmake from template +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/toolchain.cmake: $(MICROROS_LIB_DIR)/toolchain.cmake.in + sed \ + -e 's/@CMAKE_C_COMPILER@/$(ESCAPED_CC)/g' \ + -e 's/@CMAKE_CXX_COMPILER@/$(ESCAPED_CXX)/g' \ + -e 's/@ARCH_C_FLAGS@/$(ESCAPED_CFLAGS)/g' \ + -e 's/@ARCH_CPP_FLAGS@/$(ESCAPED_CXXFLAGS)/g' \ + -e 's/@NUTTX_TOPDIR@/$(ESCAPED_TOPDIR)/g' \ + -e 's/@NUTTX_APPDIR@/$(ESCAPED_APPDIR)/g' \ + -e 's/@INCLUDE_OVR_DIR@/$(ESCAPED_LIBDIR)/g' \ + -e 's/@CMAKE_SYSTEM_PROCESSOR@/$(MICROROS_ARCH)/g' \ + $< > $@ + +# --------------------------------------------------------------------------- +# Step 4 – Generate colcon.meta from template +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/colcon.meta: $(MICROROS_LIB_DIR)/colcon.meta.in + sed \ + -e 's/@MAX_NODES@/$(MAX_NODES)/g' \ + -e 's/@MAX_PUBLISHERS@/$(MAX_PUB)/g' \ + -e 's/@MAX_SUBSCRIPTIONS@/$(MAX_SUB)/g' \ + -e 's/@MAX_SERVICES@/$(MAX_SVC)/g' \ + -e 's/@MAX_CLIENTS@/$(MAX_CLIENTS)/g' \ + $< > $@ + +# --------------------------------------------------------------------------- +# Step 5 – Cross-build micro-ROS packages with colcon +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/micro_ros_src/install: \ + $(MICROROS_LIB_DIR)/toolchain.cmake \ + $(MICROROS_LIB_DIR)/colcon.meta \ + $(MICROROS_LIB_DIR)/micro_ros_src/src + cd $(MICROROS_LIB_DIR)/micro_ros_src && \ + unset AMENT_PREFIX_PATH && \ + . ../micro_ros_dev/install/local_setup.sh && \ + colcon build \ + --merge-install \ + "--packages-ignore-regex=(.*_cpp$$|.*_py$$|test_rmw_implementation|rclc_examples)" \ + --metas $(MICROROS_LIB_DIR)/colcon.meta \ + --cmake-args \ + --no-warn-unused-cli \ + -DCMAKE_POSITION_INDEPENDENT_CODE=OFF \ + -DTHIRDPARTY=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + "-DCMAKE_TOOLCHAIN_FILE=$(MICROROS_LIB_DIR)/toolchain.cmake" \ + -DCMAKE_VERBOSE_MAKEFILE=OFF + +# --------------------------------------------------------------------------- +# Step 6 – Merge all .a files into a single libmicroros.a +# --------------------------------------------------------------------------- + +$(MICROROS_DIR)/libmicroros.a: $(MICROROS_LIB_DIR)/micro_ros_src/install + mkdir -p $(MICROROS_LIB_DIR)/libmicroros_obj + cd $(MICROROS_LIB_DIR)/libmicroros_obj && \ + for file in $$(find $(MICROROS_LIB_DIR)/micro_ros_src/install/lib/ -name '*.a'); do \ + folder=$$(basename $$file .a); \ + mkdir -p $$folder && cd $$folder; \ + $(MICROROS_AR) x $$file; \ + for f in *; do \ + [ -f "$$f" ] && mv "$$f" "../$${folder}-$${f}" 2>/dev/null || true; \ + done; \ + cd ..; \ + rm -rf $$folder; \ + done && \ + $(MICROROS_AR) rc libmicroros.a $$(find . -maxdepth 1 -type f ! -name 'libmicroros.a') && \ + cp libmicroros.a $(MICROROS_DIR)/ + cd $(MICROROS_LIB_DIR) && rm -rf libmicroros_obj + cp -R $(MICROROS_LIB_DIR)/micro_ros_src/install/include $(MICROROS_DIR)/include + +# --------------------------------------------------------------------------- +# Cleanup targets +# --------------------------------------------------------------------------- + +clean:: + $(call DELFILE,$(MICROROS_DIR)/libmicroros.a) + $(call DELDIR,$(MICROROS_DIR)/include) + $(call DELFILE,$(MICROROS_LIB_DIR)/toolchain.cmake) + $(call DELFILE,$(MICROROS_LIB_DIR)/colcon.meta) + +distclean:: clean + $(call DELDIR,$(MICROROS_LIB_DIR)/micro_ros_src) + $(call DELDIR,$(MICROROS_LIB_DIR)/micro_ros_dev) + +include $(APPDIR)/Application.mk From 25c1fdaa24c662c32aea007f0d6d0e8609177277 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 07:44:01 +0000 Subject: [PATCH 5/9] apps/system/microros: wire libmicroros.a into LDLIBS and CFLAGS. When CONFIG_SYSTEM_MICROROS=y, add the prebuilt libmicroros.a to LDLIBS and the colcon-installed include/ tree to CFLAGS/CXXFLAGS so that any application in nuttx-apps can include micro-ROS headers and link against the library without extra flags. Signed-off-by: Arjav Patel --- system/microros/Make.defs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/system/microros/Make.defs b/system/microros/Make.defs index 5ec45677036..ae95e997d18 100644 --- a/system/microros/Make.defs +++ b/system/microros/Make.defs @@ -19,3 +19,12 @@ # under the License. # ############################################################################ + +ifneq ($(CONFIG_SYSTEM_MICROROS),) +CONFIGURED_APPS += $(APPDIR)/system/microros + +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include + +LDLIBS += $(APPDIR)/system/microros/libmicroros.a +endif From 9920c2dc844d77cb50f7bac2a61c30afae2744a8 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 08:29:50 +0000 Subject: [PATCH 6/9] apps/system/microros: add DIR-typedef NuttX guard patch. NuttX defines DIR as a struct type in dirent.h. The rcutils filesystem source has a bare typedef int DIR that triggers a redefinition error when NuttX system headers are on the include path. Guard it with #ifndef DIR so the typedef is skipped when the type is already defined. Applied automatically during the micro_ros_src/src fetch step with patch -p1 --forward --ignore-whitespace ... || true so the build is idempotent if the upstream ever merges a fix. Signed-off-by: Arjav Patel --- .../0001-dir-typedef-nuttx-guard.patch | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 system/microros/patches/0001-dir-typedef-nuttx-guard.patch diff --git a/system/microros/patches/0001-dir-typedef-nuttx-guard.patch b/system/microros/patches/0001-dir-typedef-nuttx-guard.patch new file mode 100644 index 00000000000..75e4f91d933 --- /dev/null +++ b/system/microros/patches/0001-dir-typedef-nuttx-guard.patch @@ -0,0 +1,31 @@ +From: micro-ROS NuttX Port +Subject: [PATCH] rcutils: guard bare DIR typedef to avoid conflict with NuttX dirent.h + +NuttX defines DIR as a struct type in dirent.h. The bare + typedef int DIR; +in rcutils/src/filesystem.c causes a redefinition error when the +NuttX system headers are on the include path. Guard it so it is +only emitted when DIR has not already been defined. + +--- a/rcutils/src/filesystem.c ++++ b/rcutils/src/filesystem.c +@@ -1,6 +1,8 @@ + // Copyright 2017 Open Source Robotics Foundation, Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + #if !defined _WIN32 && !defined __QNXTO__ ++#ifndef DIR + typedef int DIR; ++#endif + #endif From 9a3ed4fb4f5b9ae4f3c4d18ddbb133298f1ecca0 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 09:10:51 +0000 Subject: [PATCH 7/9] apps/system/microros: add CMake ExternalProject build support. Mirror the Makefile build pipeline into CMakeLists.txt using ExternalProject_Add so that CMake-based NuttX builds (cmake --build) can also produce libmicroros.a. The external project delegates to the existing Makefile targets, then exposes the result via an IMPORTED STATIC library target with correct INTERFACE_INCLUDE_DIRECTORIES. Signed-off-by: Arjav Patel --- system/microros/CMakeLists.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/system/microros/CMakeLists.txt b/system/microros/CMakeLists.txt index 9edae8cefcd..44cd0d25bb6 100644 --- a/system/microros/CMakeLists.txt +++ b/system/microros/CMakeLists.txt @@ -21,5 +21,27 @@ # ############################################################################## if(CONFIG_SYSTEM_MICROROS) - nuttx_add_library(microros) + set(MICROROS_DIR ${CMAKE_CURRENT_LIST_DIR}) + set(MICROROS_LIB_DIR ${MICROROS_DIR}/micro_ros_lib) + set(MICROROS_DISTRO ${CONFIG_MICROROS_DISTRO}) + + include(ExternalProject) + + ExternalProject_Add( + microros_build + SOURCE_DIR ${MICROROS_LIB_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND + ${CMAKE_COMMAND} -E env CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} + AR=${CMAKE_AR} CFLAGS=${CMAKE_C_FLAGS} CXXFLAGS=${CMAKE_CXX_FLAGS} make -C + ${MICROROS_DIR} libmicroros.a + INSTALL_COMMAND "" + BUILD_IN_SOURCE TRUE + BUILD_BYPRODUCTS ${MICROROS_DIR}/libmicroros.a) + + nuttx_add_library(microros STATIC IMPORTED GLOBAL) + set_target_properties( + microros PROPERTIES IMPORTED_LOCATION ${MICROROS_DIR}/libmicroros.a + INTERFACE_INCLUDE_DIRECTORIES ${MICROROS_DIR}/include) + add_dependencies(microros microros_build) endif() From 32ba92a74bfa95468d7c58ed3ee7e577b4ef7be0 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 09:52:17 +0000 Subject: [PATCH 8/9] apps/system/microros: define __NuttX__ in cross-compile toolchain flags. Add -D__NuttX__ to CMAKE_C_FLAGS_INIT and CMAKE_CXX_FLAGS_INIT in toolchain.cmake.in so that all cross-compiled micro-ROS packages see the NuttX target macro. Without this, rcutils/src/process.c follows the __linux__ branch and references program_invocation_name, a glibc-only extension absent from the NuttX C library. Pair with 0002-rcutils-process-nuttx-compat.patch which additionally guards the linux branch with !defined(__NuttX__), ensuring the embedded fallback path is taken on NuttX even if the host compiler defines any linux-flavoured macros. Signed-off-by: Arjav Patel --- .../microros/micro_ros_lib/toolchain.cmake.in | 4 ++-- .../0002-rcutils-process-nuttx-compat.patch | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 system/microros/patches/0002-rcutils-process-nuttx-compat.patch diff --git a/system/microros/micro_ros_lib/toolchain.cmake.in b/system/microros/micro_ros_lib/toolchain.cmake.in index dbdc290e238..8d3aabe3cd9 100644 --- a/system/microros/micro_ros_lib/toolchain.cmake.in +++ b/system/microros/micro_ros_lib/toolchain.cmake.in @@ -9,8 +9,8 @@ set(PLATFORM_NAME "nuttx") set(CMAKE_C_COMPILER @CMAKE_C_COMPILER@) set(CMAKE_CXX_COMPILER @CMAKE_CXX_COMPILER@) -set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D'__attribute__(x)='" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D'__attribute__(x)='" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D__NuttX__ -D'__attribute__(x)='" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D__NuttX__ -D'__attribute__(x)='" CACHE STRING "" FORCE) set(NUTTX_TOPDIR @NUTTX_TOPDIR@) set(NUTTX_APPDIR @NUTTX_APPDIR@) diff --git a/system/microros/patches/0002-rcutils-process-nuttx-compat.patch b/system/microros/patches/0002-rcutils-process-nuttx-compat.patch new file mode 100644 index 00000000000..ca8b6c56a18 --- /dev/null +++ b/system/microros/patches/0002-rcutils-process-nuttx-compat.patch @@ -0,0 +1,20 @@ +From: micro-ROS NuttX Port +Subject: [PATCH] rcutils: skip program_invocation_name on NuttX + +When cross-compiling for NuttX on a Linux host the compiler still +defines __linux__, causing rcutils_get_executable_name() to reference +program_invocation_name which is a glibc extension absent from the +NuttX C library. Guard the Linux branch with !defined(__NuttX__) so +the "embedded OS" fallback (empty string) is taken instead. + +--- a/rcutils/src/process.c ++++ b/rcutils/src/process.c +@@ -61,7 +61,7 @@ int rcutils_get_pid() + #if defined __APPLE__ || defined __FreeBSD__ || (defined __ANDROID__ && __ANDROID_API__ >= 21) + const char * appname = getprogname(); + #elif defined __GNUC__ && !defined(__QNXNTO__) && !defined(__OHOS__) +- #if defined __linux__ || defined __linux || defined __gnu_linux__ || defined linux ++ #if (defined __linux__ || defined __linux || defined __gnu_linux__ || defined linux) && !defined(__NuttX__) + const char * appname = program_invocation_name; + #else + // Some embedded OS compile with __GNUC__ but are not quite conformant with GNU-specific extensions. From 6d0d79e7159bef2b125c73bd153684b7c0a35c24 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 15:40:17 +0000 Subject: [PATCH 9/9] apps/system/microros: add rcutils strcasecmp strings.h include patch. POSIX specifies strcasecmp/strncasecmp in , not . On NuttX (and other strict POSIX environments) rcutils/src/strcasecmp.c only includes , causing an implicit-declaration error for strcasecmp when cross-compiling. Patch 0003 adds #include guarded by !_WIN32, matching the existing Windows/POSIX split in the file. Signed-off-by: Arjav Patel --- ...rcutils-strcasecmp-include-strings-h.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch diff --git a/system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch b/system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch new file mode 100644 index 00000000000..7392f2828ef --- /dev/null +++ b/system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch @@ -0,0 +1,19 @@ +From: micro-ROS NuttX Port +Subject: [PATCH] rcutils: include for strcasecmp on NuttX + +POSIX specifies strcasecmp/strncasecmp in , not . +NuttX follows the standard strictly so omitting this header causes an +"implicit declaration" error. Guard the include with __NuttX__ so it +only applies where needed and does not affect Linux or other platforms +that already expose strcasecmp through . + +--- a/rcutils/src/strcasecmp.c ++++ b/rcutils/src/strcasecmp.c +@@ -17,6 +17,9 @@ extern "C" + #include + #include ++#ifdef __NuttX__ ++#include ++#endif + + #include "rcutils/strcasecmp.h"