在Windows上使用GCC和CMake构建STM32F407固件的配置指南
CMake支持跨平台构建STM32微控制器固件。通过一套脚本,您可以在Windows和Linux上构建项目。这解决了GNU Make中操作系统特定路径和工具的问题。对于单平台开发,切换并非必需,但在支持多操作系统时,CMake成为元构建系统中的标准选择。
该系统生成原生构建文件:适用于Linux/Windows的GNU Make、Ninja或IDE项目。重点在于使用ARM GCC针对STM32F407VE,结合ST的HAL和CMSIS。
基于脚本构建的优势
从命令行构建可扩展到数百个固件项目。随着项目增长,GUI IDE会限制自动化。脚本允许您:
- 自动化CI/CD流水线
- 夜间构建所有变体
- 通过单一命令集成到代码仓库中
对于150多个固件项目,一个批处理文件就足够了:运行它,几分钟内即可生成.hex文件。
任务定义: 针对STM32F407VE的C项目。使用ARM GCC交叉编译器。CMake生成GNU Make。结合STM32 HAL和CMSIS。目标平台:Windows 10。
向编译器传递严格标志:
-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
向链接器传递:
-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不直接生成CMake文件——仅生成GNU Make。解决方案:手动迁移。
理论:从Make到CMake
环境变量存储路径、编译器标志和设置。对所有工具可见。
构建系统自动化编译、链接和依赖关系。示例:GNU Make、Ninja、IAR。
构建系统生成器(如CMake、Meson)为原生构建系统创建文件。
CMake + GNU Make方案:
- CMake读取CMakeLists.txt
- 生成Makefile
- GNU Make构建产物
在Windows中检查CMake:where cmake。
迁移Make → CMake
机械式语法替换。CMake更冗长但更强大。
| GNU Make | CMake | 解释 |
|----------|--------|-----------|
| VAR += value | string(APPEND VAR " value") | 向变量追加 |
| CRC=Y | set(CRC Y) | 定义 |
| $(VAR) | ${VAR} | 插入 |
| ifeq($(IAR),Y) | if(IAR STREQUAL Y) | 条件判断 |
| SOURCES_C += src/main.c | target_sources(app PRIVATE src/main.c) | 源文件 |
| OPT += -Ipath | target_include_directories(app PUBLIC path) | 路径 |
转换示例:
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(根目录):
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)
组件配置
在config.cmake中,激活模块:
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)
在code_base.cmake中,有条件地添加组件:
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()
关键要点
- CMake提供跨平台兼容性,无需重写脚本
- Make→CMake迁移是基于模板的替换,可通过AI自动化
- 严格的-Werror标志在编译时捕获错误
- config.cmake管理HAL模块选择
- 基于脚本的构建可扩展到100多个固件项目
— Editorial Team
暂无评论。