Skip to main content

Set up POSIX

The SDK also builds as a plain CMake library for Linux and macOS. The result is a normal host process that speaks the same MQTT contract as a real device: same node data model, same shadow updates, same OTA job handling.

The POSIX build is currently intended for testing and development without hardware — products ship on ESP-IDF. Within that role it is the fastest way to work on app-side, backend, or protocol behaviour, and it is what the SDK's own integration tests run against. Everything platform-specific sits behind the osal abstraction layer, so your app_main.c is identical to the ESP-IDF version.

For hardware builds, see Set up ESP-IDF.

What POSIX gives you (and what it doesn't)

POSIX host
RainMaker Neo core, data model, MQTT, shadowsReal
Schedules, automations, timezone, system serviceReal
Local control HTTP server, challenge-responseReal
OTA over MQTTReal, against a mock bootloader with ota_0 / ota_1 files instead of flash partitions
Factory NVSReal, as files under nvs_persistent/
Wi-Fi provisioningNo-op. The host is already on a network; app_network_provision() returns success without doing anything.
LED, button, GPIOStubbed. app_led / app_button log !!!HARDWARE!!! instead of driving pins.

1. Toolchain

Install a native toolchain:

  • CMake 3.16 or newer
  • A C compiler (GCC or Clang)
  • Ninja or Make

2. Python environment

Some POSIX dependencies — notably the mbedTLS configuration scripts and the Kconfig tooling — need Python packages available on PATH when CMake runs. CMake installs them for you, but only if a virtual environment is active.

From the SDK repository root:

python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -U pip
pip install -r posix_requirements.txt

Keep the environment activated for every configure and build. If CMake reports missing Python modules, this is almost always why.

Fetched at build time

Upstream sources for mbedTLS, Unity, and protobuf-c are fetched by CMake FetchContent on first configure (see third_party/install_scripts/), so the first build needs network access. They are never committed to the SDK.

3. Build an example

cd examples/light
cmake -B build
cmake --build build

The build tree comes out like this:

build/
├── light # mock bootloader, named after the project
├── partitions/
│ ├── ota_0 # the app image — this is what you upload for OTA
│ └── ota_1 # the second OTA slot
│ └── ota_config.bin
└── nvs_persistent/ # factory NVS lives here (see below)

Run it from the build directory so the relative paths for NVS and the OTA partitions resolve:

cd build
./light

./light is the mock bootloader; it launches the app image from partitions/. Send SIGINT (Ctrl-C) for a clean teardown.

Before the node can connect it needs credentials: generate a factory NVS image and copy the generated nvs_persistent/ directory next to the executable — see Factory NVS.

4. Add the SDK to your own project

A POSIX project consumes the SDK with add_subdirectory() and links against the esp_rmaker_neo target. Order matters, because esp_rmaker_neo transitively defines the osal platform targets that the example helpers depend on:

cmake_minimum_required(VERSION 3.16)

# Firmware version — must be set before project()
set(PROJECT_VER "1.0.0" CACHE STRING "Firmware version")

project(my_app C ASM)

add_executable(${PROJECT_NAME} main/app_main.c main/app_driver.c)

set(RMNG_ROOT /path/to/esp-rainmaker-neo-firmware)

add_subdirectory(${RMNG_ROOT}/components/esp_rmaker_neo components/esp_rmaker_neo)
add_subdirectory(${RMNG_ROOT}/components/esp_rmaker_neo_ota components/esp_rmaker_neo_ota) # optional

target_link_libraries(${PROJECT_NAME} PRIVATE esp_rmaker_neo esp_rmaker_neo_ota)

To seed Kconfig defaults for the SDK subtree, prepend to SDKCONFIG_DEFAULTS before the add_subdirectory() call:

list(PREPEND SDKCONFIG_DEFAULTS ${CMAKE_CURRENT_LIST_DIR}/sdkconfig.defaults)

If you link esp_rmaker_neo_ota, it exports the mock-bootloader variables the examples use to lay out their build tree:

VariableMeaning
RMNG_OTA_POSIX_BOOTLOADER_NAMETarget name of the mock bootloader — rename it to your project name
RMNG_OTA_POSIX_PARTITION_FOLDERDirectory the app image must be built into (partitions/)
RMNG_OTA_POSIX_DEFAULT_FIRST_PARTITIONOutput name for the initial app image (ota_0)

See examples/light/CMakeLists.txt for the full pattern, and Start your own project.

Next steps