CMake für STM32F407-Firmware unter Windows mit GCC einrichten
CMake ermöglicht plattformübergreifendes Erstellen von Firmware für STM32-Mikrocontroller. Mit einem einzigen Satz von Skripten können Sie Projekte sowohl unter Windows als auch Linux bauen. Dies löst das Problem von betriebssystemspezifischen Pfaden und Utilities in GNU Make. Für die Entwicklung auf einer einzigen Plattform ist ein Wechsel nicht nötig, aber bei der Unterstützung mehrerer Betriebssysteme wird CMake zum Standard unter den Meta-Build-Systemen.
Das System generiert native Build-Dateien: GNU Make für Linux/Windows, Ninja oder IDE-Projekte. Der Fokus liegt auf ARM GCC für STM32F407VE mit STs HAL und CMSIS.
Vorteile skriptbasierter Builds
Das Bauen über die Kommandozeile skaliert auf Hunderte von Firmware-Projekten. GUI-IDEs schränken die Automatisierung ein, wenn Projekte wachsen. Skripte ermöglichen Ihnen:
- CI/CD-Pipelines automatisieren
- Alle Varianten über Nacht bauen
- Integration in Repositories mit einem einzigen Befehl
Für 150+ Firmware-Projekte reicht eine Batch-Datei: ausführen, und innerhalb weniger Minuten sind .hex-Dateien fertig.
Aufgabendefinition: Ein C-Projekt für STM32F407VE. ARM GCC Cross-Compiler. CMake generiert GNU Make. STM32 HAL + CMSIS. Ziel: Windows 10.
Strikte Flags an den Compiler übergeben:
-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
An den Linker:
-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 generiert CMake nicht direkt – nur GNU Make. Die Lösung: manuelle Migration.
Theorie: Von Make zu CMake
Umgebungsvariablen speichern Pfade, Compiler-Flags und Einstellungen. Für alle Utilities sichtbar.
Build-System automatisiert Kompilierung, Linking und Abhängigkeiten. Beispiele: GNU Make, Ninja, IAR.
Build-System-Generator (CMake, Meson) erstellt Dateien für native Build-Systeme.
CMake + GNU Make Schema:
- CMake liest CMakeLists.txt
- Generiert Makefile
- GNU Make baut Artefakte
CMake prüfen: where cmake unter Windows.
Migration Make → CMake
Mechanische Syntax-Ersetzung. CMake ist ausführlicher, aber leistungsfähiger.
| GNU Make | CMake | Erklärung |
|----------|--------|-----------|
| VAR += value | string(APPEND VAR " value") | An Variable anhängen |
| CRC=Y | set(CRC Y) | Definition |
| $(VAR) | ${VAR} | Einfügung |
| ifeq($(IAR),Y) | if(IAR STREQUAL Y) | Bedingung |
| SOURCES_C += src/main.c | target_sources(app PRIVATE src/main.c) | Quelldateien |
| OPT += -Ipath | target_include_directories(app PUBLIC path) | Pfade |
Transformationsbeispiele:
LINKER_FLAGS += -u _printf_float→target_link_options(app PRIVATE -u _printf_float)include file.mk→include(${file}.cmake)SOURCES += file.c→string(APPEND SOURCES " ${file}.c")ifneq($(FLAG),Y)→if(NOT (FLAG STREQUAL Y))
CMakeLists.txt (Root):
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)
Komponentenkonfiguration
In config.cmake Module aktivieren:
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)
In code_base.cmake Komponenten bedingt hinzufügen:
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()
Wichtige Erkenntnisse
- CMake bietet plattformübergreifende Kompatibilität ohne Skripte neu schreiben
- Make→CMake-Migration ist eine vorlagenbasierte Ersetzung, automatisierbar mit KI
- Strikte -Werror-Flags fangen Fehler zur Kompilierzeit
- config.cmake verwaltet HAL-Modulauswahl
- Skriptbasierte Builds skalieren auf 100+ Firmware-Projekte
— Editorial Team
Noch keine Kommentare.