Skip to content

Build System and Feature Flags

Relevant source files

This document describes the CMake-based build system and compile-time feature flags used in the PiBot CNC Pendant firmware. It covers the multi-tier configuration strategy (board, memory, radio, and target firmware), the component dependency model, and how preprocessor flags are used to optimize the binary for specific hardware capabilities and memory constraints.


The firmware uses a sophisticated CMake structure built on top of the ESP-IDF build system. It automates the selection of board configurations, memory sizes, and target CNC firmwares.

The build process follows a specific resolution order defined in the root CMakeLists.txt:

  1. Hardware Selection: Defines the physical board (e.g., ESP32_PIBOT_CNC_PENDANT_V1). CMakeLists.txt#6
  2. Flash and PSRAM Size: Configures partition tables and application-level buffer sizing. CMakeLists.txt#30-44
  3. Target Firmware: Sets the G-code dialect and UI layout (FluidNC, grblHAL, Marlin, etc.). CMakeLists.txt#49-55
  4. Communication Services: Enables/disables Serial, USB, WiFi, or Bluetooth. CMakeLists.txt#62-68

Each board has a dedicated directory (e.g., boards/pibot_pendant_v1_0/) containing a board_config.cmake file. This file forces hardware-specific defaults:

Sources:CMakeLists.txt#1-135boards/pibot_pendant_v1_0/board_config.cmake#1-112


Feature flags are mapped from CMake OPTION variables to C++ preprocessor macros in cmake/features.cmake. These flags allow the compiler to strip unused code, reducing flash and RAM footprints.

CMake OptionPreprocessor MacroImpacted Functionality
TFT_UI_SERVICEESP3D_DISPLAY_FEATUREEnables LVGL, UIManager, and Screen stack. cmake/features.cmake#189
TFT_TOUCH_SERVICEESP3D_TOUCH_FEATUREEnables touch controller drivers. cmake/features.cmake#191
HARDWARE_ENCODERESP3D_HARDWARE_ENCODER_FEATUREEnables PCNT-based rotary encoder support. cmake/features.cmake#208
WIFI_SERVICEESP3D_WIFI_FEATUREEnables Network stack and WiFi-based clients. cmake/features.cmake#141
BT_SERVICEESP3D_BT_FEATUREEnables Bluetooth Classic (SPP) and BLE. cmake/features.cmake#132
SOCKET_CLIENT_SERVICEESP3D_SOCKET_CLIENT_FEATUREEnables TCP client for CNC-over-IP. cmake/features.cmake#177
PROD_BUILDESP3D_LOG=0Silences all dev logging and snapshots. cmake/dev_tools.cmake#17-27

The cmake/features.cmake file handles include path injection based on the TARGET_FW_* flags. This ensures that only the relevant G-code parsers and UI components for the chosen CNC controller (e.g., FluidNC) are visible to the compiler. cmake/features.cmake#6-64

Sources:cmake/features.cmake#1-213cmake/dev_tools.cmake#1-90


Component Dependency and Source Management

Section titled “Component Dependency and Source Management”

The main/CMakeLists.txt file acts as a dynamic manifest, appending source directories to the SOURCES list only if their corresponding feature flags are enabled.

Conditional Modules

main/CMakeLists.txt

Core Sources (core, core/commands, modules/gcode_host, modules/values)

modules/serial

modules/wifi

modules/bt_serial / modules/bt_ble

display/cnc/fluidnc

modules/log/sd or telnet

Sources:main/CMakeLists.txt#1-200


To prevent invalid hardware/software combinations, cmake/sanity_check.cmake performs validation during the generation phase.

  • WiFi vs. Bluetooth: Mutually exclusive on boards without PSRAM (like the PiBot Pendant) because the ESP32 cannot hold both stacks in RAM simultaneously. cmake/sanity_check.cmake#71-77
  • Socket Server vs. Client: A single device cannot act as both the TCP server (incoming) and TCP client (outgoing to CNC) on the same port range. cmake/sanity_check.cmake#87-93
  • CNC over IP Resource Lock: If SOCKET_CLIENT_SERVICE is enabled, features like SSDP_SERVICE and WEBUI_SERVER are forbidden to ensure the WiFi station is dedicated to the CNC link. cmake/sanity_check.cmake#98-125
  • Logging Backends: Backend 1 (SD) requires SD_CARD_SERVICE=ON, and Backend 3 (Telnet) requires SOCKET_SERVER_SERVICE=ON. cmake/sanity_check.cmake#144-156

Sources:cmake/sanity_check.cmake#1-160


The build system includes a post-build step in cmake/postbuild.cmake that packages the resulting binaries into a standardized directory structure.

  1. Detection: Detects the configuration name based on memory, radio, and firmware (e.g., ESP32_PIBOT_CNC_PENDANT_V1_8MB_wifi_fluidnc). cmake/postbuild.cmake#11-68
  2. Packaging: Creates an installer/ directory. cmake/postbuild.cmake#73-86
  3. Binary Naming: Copies and renames the firmware binary to include configuration details. cmake/postbuild.cmake#89-96
  4. OTA and Partitions: Generates ota_data_initial.bin and copies partition-table.bin for flashing. cmake/postbuild.cmake#98-115
  5. Flash Manager: Generates a flash map JSON for the variant and includes flash_mgr.py for easy distribution. cmake/postbuild.cmake#122-132

Sources:cmake/postbuild.cmake#1-148


The firmware supports automated building of multiple variants using Python scripts that pass specific CMake arguments. Variants are discovered from each board’s build_scripts/variants.py. tools/build_scripts/build_mgr.py#125-164

variants.py

CMake Arguments

cmake .. && idf.py build

-DMEMORY_4_MB=ON -DWIFI_SERVICE=ON

-DMEMORY_8_MB=ON -DBT_SERVICE=ON

4mb_wifi_fluidnc

8mb_bt_serial_fluidnc

The common.py script for each board handles the generation of the ui_resources partition binary. This ensures that the boot logo, icons, and fonts match the specific variant’s resolution and target firmware. boards/pibot_pendant_v1_0/build_scripts/common.py#142-168

Sources:tools/build_scripts/build_mgr.py#1-164boards/pibot_pendant_v1_0/build_scripts/common.py#1-168