Configuración de CMake para compilar firmware STM32F407 en Windows con GCC
CMake permite la compilación multiplataforma de firmware para microcontroladores STM32. Con un solo conjunto de scripts, puedes compilar proyectos tanto en Windows como en Linux. Esto resuelve el problema de rutas y utilidades específicas del sistema operativo en GNU Make. Para desarrollo en una sola plataforma, no es necesario cambiar, pero al dar soporte a múltiples sistemas operativos, CMake se convierte en el estándar entre los sistemas de compilación meta.
El sistema genera archivos de compilación nativos: GNU Make para Linux/Windows, Ninja o proyectos de IDE. El enfoque está en ARM GCC para STM32F407VE con HAL de ST y CMSIS.
Ventajas de la compilación basada en scripts
Compilar desde la línea de comandos escala a cientos de proyectos de firmware. Los IDE con interfaz gráfica limitan la automatización a medida que los proyectos crecen. Los scripts permiten:
- Automatizar pipelines de CI/CD
- Compilar todas las variantes durante la noche
- Integrar en repositorios con un solo comando
Para más de 150 proyectos de firmware, un archivo por lotes es suficiente: ejecútalo y, en minutos, los archivos .hex están listos.
Definición de la tarea: Un proyecto C para STM32F407VE. Compilador cruzado ARM GCC. CMake genera GNU Make. STM32 HAL + CMSIS. Objetivo: Windows 10.
Pasa banderas estrictas al compilador:
-MMD -MP -O0 -std=c11 -Wall -Werror -mcpu=cortex-m4 -march=armv7e-m -Werror=address -Werror=address-of-packed-member -Werror=array-bounds=1 -Werror=bool-compare -Werror=bool-operation -Werror=char-subscripts -Werror=clobbered -Werror=div-by-zero -Werror=duplicate-decl-specifier -Werror=empty-body -Werror=enum-compare -Werror=float-equal -Werror=ignored-qualifiers -Werror=implicit -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=init-self -Werror=int-in-bool-context -Werror=int-to-pointer-cast -Werror=logical-not-parentheses -Werror=logical-op -Werror=maybe-uninitialized -Werror=memset-elt-size -Werror=misleading-indentation -Werror=missing-braces -Werror=multistatement-macros -Werror=old-style-declaration -Werror=overflow -Werror=pointer-arith -Werror=pointer-sign -Werror=return-local-addr -Werror=return-type -Werror=shadow -Werror=shift-count-overflow -Werror=sign-compare -Werror=sizeof-pointer-div -Werror=strict-aliasing -Werror=switch -Werror=tautological-compare -Werror=type-limits -Werror=uninitialized -Werror=unused-variable -g3 -Wextra -Wno-conversion -Wno-cpp -Wno-discarded-qualifiers -Wno-implicit -Wno-int-conversion -Wno-nonnull-compare -Wno-redundant-decls -Wno-restrict -Wno-sign-compare -Wno-stringop-truncation -Wno-switch-bool -Wno-unused-parameter -fallthrough -fdata-sections -ffreestanding -ffunction-sections -finline-small -fmax-errors=70 -fno-common -fno-move-loop-invariants -fno-printf-return-value -fomit-frame-pointer -fshort-enums -fsigned-char -fstack-usage -fzero-initialized-in-bss -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb
Al enlazador:
-specs=nosys.specs -Xlinker --gc-sections -Xlinker --nmagic -Wl,--gc-sections -Xlinker --print-memory-usage -t -Wl,--cref -Wl,--gc-sections --verbose -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -lm
STM32CubeMX no genera CMake directamente—solo GNU Make. La solución: migración manual.
Teoría: De Make a CMake
Variables de entorno almacenan rutas, banderas del compilador y configuraciones. Visibles para todas las utilidades.
Sistema de compilación automatiza la compilación, enlace y dependencias. Ejemplos: GNU Make, Ninja, IAR.
Generador de sistemas de compilación (CMake, Meson) crea archivos para sistemas de compilación nativos.
Esquema CMake + GNU Make:
- CMake lee CMakeLists.txt
- Genera Makefile
- GNU Make construye artefactos
Verifica CMake: where cmake en Windows.
Migrando Make → CMake
Reemplazo mecánico de sintaxis. CMake es más verboso pero más potente.
| GNU Make | CMake | Explicación |
|----------|--------|-----------|
| VAR += valor | string(APPEND VAR " valor") | Añadir a una variable |
| CRC=Y | set(CRC Y) | Definición |
| $(VAR) | ${VAR} | Inserción |
| ifeq($(IAR),Y) | if(IAR STREQUAL Y) | Condición |
| SOURCES_C += src/main.c | target_sources(app PRIVATE src/main.c) | Archivos fuente |
| OPT += -Iruta | target_include_directories(app PUBLIC ruta) | Rutas |
Ejemplos de transformación:
LINKER_FLAGS += -u _printf_float→target_link_options(app PRIVATE -u _printf_float)include archivo.mk→include(${archivo}.cmake)SOURCES += archivo.c→string(APPEND SOURCES " ${archivo}.c")ifneq($(FLAG),Y)→if(NOT (FLAG STREQUAL Y))
CMakeLists.txt (raíz):
cmake_minimum_required(VERSION 3.16)
project(jz_f407vet6_mbr_gcc_cmake)
set(PROJECT_NAME jz_f407vet6_mbr_gcc_cmake)
enable_language(C ASM)
set(CURRENT_CMAKELISTS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(PROJECT_LOC ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${PROJECT_LOC})
set(BUILD_DIR ${PROJECT_LOC}/build)
set(TARGET ${PROJECT_NAME})
set(EXECUTABLE ${TARGET})
get_filename_component(WORKSPACE_LOC "${PROJECT_LOC}/../.." ABSOLUTE)
include_directories(${WORKSPACE_LOC})
include(${PROJECT_LOC}/config.cmake)
include(${WORKSPACE_LOC}/cmake_scripts/code_base.cmake)
include(${WORKSPACE_LOC}/cmake_scripts/rules.cmake)
Configuración de componentes
En config.cmake, activa módulos:
set(CONTROL Y)
set(DWT Y)
set(ARM_GCC Y)
set(CORTEX_M4 Y)
set(FLASH Y)
set(FPU Y)
set(GPIO Y)
set(INTERRUPT Y)
set(JZ_F407VET6 Y)
set(LED_MONO Y)
set(MBR Y)
set(MCAL_STM32 Y)
set(MICROCONTROLLER Y)
set(NVIC Y)
set(RCC Y)
set(SCHEDULER Y)
set(STM32F407VE Y)
set(STM32F4X_HAL_DRIVER Y)
set(SUPER_CYCLE Y)
set(SYSTEM Y)
set(SYSTICK Y)
set(SYS_INIT Y)
set(TIME Y)
En code_base.cmake, añade componentes condicionalmente:
if(GPIO STREQUAL Y)
target_sources(app PRIVATE gpio/src/gpio.c)
target_include_directories(app PUBLIC gpio/inc)
add_compile_definitions(GPIO_ENABLED)
endif()
Conclusiones clave
- CMake proporciona compatibilidad multiplataforma sin reescribir scripts
- La migración Make→CMake es un reemplazo basado en plantillas, automatizable con IA
- Las banderas estrictas -Werror detectan errores en tiempo de compilación
- config.cmake gestiona la selección de módulos HAL
- La compilación basada en scripts escala a más de 100 proyectos de firmware
— Editorial Team
Aún no hay comentarios.