pi_pico/cmake/CMakeLists.txt
Mohamed Salem 3687e48684 Add complete firmware stack with USB-CDC proof of life
Dockerized build system (Dockerfile, docker-compose, build.sh) with
Pico SDK cross-compilation. Modular CMake split into project_config,
mcu_config, and sources_config under cmake/. Component architecture
following inc/prg/cfg convention: STD_TYPES, MCU_USB, HAL_COM,
APP_CLSW, SYS_ECU. Full call chain SYS_ECU -> APP_CLSW -> HAL_COM
-> MCU_USB verified end-to-end on RP2040-Zero hardware over USB-CDC.
Includes flash.sh for automated .uf2 flashing on macOS and
devcontainer config for VS Code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:23:24 +02:00

66 lines
3.3 KiB
CMake

# ============================================================================
# Top-level CMakeLists.txt for the color_switcher Pico firmware project
# ============================================================================
# This file is intentionally kept thin: it orchestrates the build phases in
# the strict order CMake requires. All real configuration lives in the
# cmake_config/*.cmake fragments so each concern is isolated and easy to find.
#
# Build phase order (forced by the Pico SDK + CMake semantics):
# 1. project_config - variables only, no side effects
# 2. mcu_config - defines mcu_init / mcu_sdk_config / mcu_link_target
# 3. mcu_init() - SDK bootstrap (MUST run before project())
# 4. project() - declares the CMake project using project_config vars
# 5. mcu_sdk_config() - pico_sdk_init() (MUST run after project())
# 6. sources_config - collects PROJECT_SOURCES and PROJECT_INCLUDE_DIRS
# 7. add_executable() - the actual firmware build target
# 8. mcu_link_target() - target_link_libraries + stdio + UF2 output
# ============================================================================
# Require CMake 3.13 or newer. The Pico SDK uses features (like
# target_link_libraries on object libraries) that were added in 3.13,
# so older versions will fail to configure with cryptic errors.
cmake_minimum_required(VERSION 3.13)
# The real project root is one level above this file (this CMakeLists.txt
# lives in <project>/cmake/). Everything outside the build system - the
# src/ tree, the Dockerfile, etc. - is referenced via PROJECT_ROOT_DIR so
# we never have to sprinkle "../" paths throughout the cmake fragments.
get_filename_component(PROJECT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
# Make cmake_config/ searchable so include(foo) resolves to
# cmake_config/foo.cmake without needing the full path each time.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_config)
# Phase 1 - project-wide variables (PROJECT_NAME, PROJECT_VERSION, etc.)
include(project_config)
# Phase 2 - MCU helper macros/functions (no side effects, just definitions)
include(mcu_config)
# Phase 3 - Pico SDK bootstrap. MUST run before project() so the ARM
# cross-compile toolchain is configured before CMake enables languages.
mcu_init()
# Phase 4 - declare the CMake project using variables from project_config.
# This triggers CMake to detect the (already-configured) cross compiler.
project(${PROJECT_NAME}
VERSION ${PROJECT_VERSION}
LANGUAGES ${PROJECT_LANGUAGES})
# Phase 5 - register every Pico SDK library as a CMake target so we can
# pick which ones to link later. This does NOT pull libraries into the
# final binary - mcu_link_target() does that.
mcu_sdk_config()
# Phase 6 - collect the list of .c files and include directories into
# PROJECT_SOURCES and PROJECT_INCLUDE_DIRS variables.
include(sources_config)
# Phase 7 - declare the firmware executable and its include paths.
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE_DIRS})
# Phase 8 - link only the SDK libraries we actually use (pico_stdlib,
# hardware_uart), route stdio over USB-CDC, and emit the .uf2 firmware file.
mcu_link_target(${PROJECT_NAME})