Volver al inicio

CMake para STM32F407: compilación con GCC en Windows

El artículo describe la configuración de CMake para compilación de firmware multiplataforma de STM32F407VE con ARM GCC en Windows. Migración detallada desde GNU Make, configuración de módulos HAL y flags estrictos del compilador. Adecuado para desarrolladores embebidos intermedios/senior.

Compilación de firmware STM32: CMake + GCC en Win10
Advertisement 728x90

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:

Google AdInline article slot
  • 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:

Google AdInline article slot
-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.

Google AdInline article slot

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_floattarget_link_options(app PRIVATE -u _printf_float)
  • include archivo.mkinclude(${archivo}.cmake)
  • SOURCES += archivo.cstring(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

Advertisement 728x90

Leer después