Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Adding a Platform (CMake Layer)

Scope. This page covers the CMake-side glue: how the build system picks the right platform shim, links the right archives, and dispatches per-app fixups (linker scripts, startup files, ISR vectors). For the runtime traits a new platform must implement in Rust / platform-cffi, see Custom Platform.

Since, porting a new platform to nano-ros is one new file:

nano-ros/cmake/platform/nano-ros-<plat>.cmake

Adding a platform no longer touches the root CMakeLists.txt, never edits per-example trees, and never duplicates platform helpers across 20+ examples.

Module contract (§A)

Every cmake/platform/nano-ros-<plat>.cmake must expose:

SymbolKindPurpose
NanoRos::PlatformALIAS libraryAliased to the platform-specific INTERFACE target; linked into NanoRos::NanoRos umbrella by the root CMakeLists.
nros_platform_<plat>_ifaceINTERFACE libraryCarries the platform staticlib + host-system libs + transitive deps.
nros_platform_link_app(target)functionPer-app fixups: linker script, startup objects, ISR vectors, RTOS-specific final-link tweaks. Empty for POSIX.
NROS_PLATFORM_LINK_FEATUREScache variableDefault link-feature set for this platform (e.g. tcp udp_unicast).

The root CMakeLists.txt dispatches via:

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/platform/nano-ros-${NANO_ROS_PLATFORM}.cmake")

When the user’s project sets NANO_ROS_PLATFORM=foo before add_subdirectory(nano-ros), your module at cmake/platform/nano-ros-foo.cmake runs and supplies the four contract elements above.

Minimal skeleton

# cmake/platform/nano-ros-foo.cmake

if(DEFINED _NROS_PLATFORM_FOO_INCLUDED)
    return()
endif()
set(_NROS_PLATFORM_FOO_INCLUDED TRUE)

set(NROS_PLATFORM_LINK_FEATURES tcp udp_unicast
    CACHE STRING "Default link features for the Foo platform")

# Build / pull in the platform staticlib. May be add_subdirectory(...)
# into packages/core/nros-platform-foo/ for a Cargo + cmake hybrid, or
# may declare an IMPORTED target pointing at a prebuilt RTOS archive.
add_subdirectory(
    "${CMAKE_CURRENT_LIST_DIR}/../../packages/core/nros-platform-foo"
    nros_platform_foo_build)

add_library(nros_platform_foo_iface INTERFACE)
if(TARGET nros_platform_foo)
    target_link_libraries(nros_platform_foo_iface INTERFACE nros_platform_foo)
endif()

if(NOT TARGET NanoRos::Platform)
    add_library(NanoRos::Platform ALIAS nros_platform_foo_iface)
endif()

function(nros_platform_link_app target)
    # Per-app fixups go here. Linker scripts, startup objects, ISR
    # vectors. Delegate to cmake/board/nano-ros-board-${NANO_ROS_BOARD}.cmake
    # when the platform supports multiple boards.
    if(DEFINED NANO_ROS_BOARD)
        include("${CMAKE_CURRENT_LIST_DIR}/../board/nano-ros-board-${NANO_ROS_BOARD}.cmake")
        if(COMMAND nros_board_link_app)
            nros_board_link_app(${target})
        endif()
    endif()
endfunction()

That’s it. The root CMakeLists picks up the new platform automatically — the validation block resolves cmake/platform/nano-ros-foo.cmake and fatals out only when no such file exists.

Board overlays

When your platform spans multiple boards (different MCUs, link scripts, peripheral inits), carve a board overlay:

nano-ros/cmake/board/nano-ros-board-<board>.cmake

Board overlays provide nros_board_link_app(target) and run inside nros_platform_link_app when the user sets NANO_ROS_BOARD. The board layer owns:

  • Linker script selection (target_link_options(${target} PRIVATE -T<script>))
  • Startup object emission (crt0.o, vector table, etc.)
  • MCU-specific final-link flags

See cmake/board/nano-ros-board-mps2-an385.cmake for a working example.

Where the existing layer-2 helpers live

For RTOS ports that compose the kernel + netstack + glue inside CMake (FreeRTOS, ThreadX, NuttX), the per-RTOS helper functions (nros_freertos_build_kernel, nros_threadx_compose_platform, …) stay at packages/core/nros-c/cmake/nros-<rtos>.cmake. The modules include(...) those helpers — the per-platform file is the dispatch entry, not the implementation.

See also