CMAKE_COMPILE_FLAGS CMAKE_COMPILE_FLAGS_DEBUG CMAKE_COMPILE_FLAGS_RELEASE
CMAKE_COMPILE_FLAGS
是一个变量,在CMake构建系统中用于设置编译器生成的目标文件的通用编译标志。它是一个字符串列表,可以包含对所有目标的编译选项,如优化级别、调试信息等。
当你需要区分不同的构建配置时,比如debug模式和release模式,CMake会提供特定于配置的变量:
CMAKE_COMPILE_FLAGS_DEBUG
:这是一个仅适用于debug配置(通常开发阶段)的编译标志列表。在这个模式下,可能会添加更多的调试信息、检查和其他帮助诊断的选项,以便更容易找到和修复错误。CMAKE_COMPILE_FLAGS_RELEASE
:对应的是release或optimized配置(通常发布阶段),这个列表会包含一些性能优化的标志,如消除未使用的代码、减少调试信息等,以提高程序运行效率。
开发者可以在CMakeLists.txt文件中设置这些变量,以定制各个配置下的编译行为。例如:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# 设置Debug配置的编译标志
set(CMAKE_compile_FLAGS_DEBUG "-g -O0")
# 设置Release配置的编译标志
set(CMAKE_compile_FLAGS_RELEASE "-O3 -DNDEBUG")
#THIS FILE IS AUTO GENERATED FROM THE TEMPLATE! DO NOT CHANGE! set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_VERSION 1) cmake_minimum_required(VERSION 3.28) # specify cross-compilers and tools set(CMAKE_C_COMPILER arm-none-eabi-gcc) set(CMAKE_CXX_COMPILER arm-none-eabi-g++) set(CMAKE_ASM_COMPILER arm-none-eabi-gcc) set(CMAKE_AR arm-none-eabi-ar) set(CMAKE_OBJCOPY arm-none-eabi-objcopy) set(CMAKE_OBJDUMP arm-none-eabi-objdump) set(SIZE arm-none-eabi-size) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # project settings project(untitled C CXX ASM) set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_STANDARD 11) #Uncomment for hardware floating point #add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING) #add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16) #add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16) #Uncomment for software floating point #add_compile_options(-mfloat-abi=soft) add_compile_options(-mcpu=cortex-m7 -mthumb -mthumb-interwork) add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0) # uncomment to mitigate c++17 absolute addresses warnings #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register") # Enable assembler files preprocessing add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-x$<SEMICOLON>assembler-with-cpp>) if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") message(STATUS "Maximum optimization for speed") add_compile_options(-Ofast) elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") message(STATUS "Maximum optimization for speed, debug info included") add_compile_options(-Ofast -g) elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel") message(STATUS "Maximum optimization for size") add_compile_options(-Os) else () message(STATUS "Minimal optimization, debug info included") add_compile_options(-Og -g) endif () include_directories(Core/Inc Drivers/STM32H7xx_HAL_Driver/Inc Drivers/STM32H7xx_HAL_Driver/Inc/Legacy Drivers/CMSIS/Device/ST/STM32H7xx/Include Drivers/CMSIS/Include) add_definitions(-DDEBUG -DUSE_HAL_DRIVER -DSTM32H743xx) file(GLOB_RECURSE SOURCES "Core/*.*" "Drivers/*.*") set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32H743XIHX_FLASH.ld) add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map) add_link_options(-mcpu=cortex-m7 -mthumb -mthumb-interwork) add_link_options(-T ${LINKER_SCRIPT}) add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT}) set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex) set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin) add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE} COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE} COMMENT "Building ${HEX_FILE} Building ${BIN_FILE}")
首先,用户可能是在进行ARM Cortex-M7的交叉编译,所以这个CMake文件配置了交叉编译工具链,比如arm-none-eabi-gcc和g++。我需要解释这些编译器设置的作用,以及为什么需要设置CMAKE_SYSTEM_NAME为Generic,因为嵌入式系统通常没有操作系统,所以用Generic来告诉CMake不要使用宿主机的系统配置。
接下来,用户可能关心如何为不同的构建类型(如Release、Debug)设置不同的编译选项。比如,在Release模式下使用-Ofast优化,而在Debug模式下使用-Og和-g选项。这部分需要详细说明每个编译选项的作用,比如-mcpu=cortex-m7指定目标处理器,-mthumb指示使用Thumb指令集,-ffunction-sections和-fdata-sections是为了后续的链接优化,减少生成的固件大小。
然后,用户可能对链接脚本的部分感兴趣,特别是add_link_options中的-T参数指定了链接脚本的位置。链接脚本在嵌入式开发中非常重要,它决定了内存布局,所以需要解释其作用。另外,生成HEX和BIN文件的自定义命令也很关键,因为这些是烧录到微控制器中的文件格式,用户可能需要知道如何调整这些生成步骤。
还有,用户可能不太明白条件编译的部分,比如根据CMAKE_BUILD_TYPE的不同添加不同的编译选项。这时候需要说明CMake如何根据构建类型切换优化选项,以及这些优化对代码大小和调试的影响。
另外,用户可能对包含路径和预定义宏(如USE_HAL_DRIVER,STM32H743xx)有疑问,需要说明这些是STM32硬件抽象层和具体芯片型号的配置,确保正确编译HAL库。
最后,用户可能希望了解如何扩展这个项目,比如添加新的源文件或调整编译选项,特别是关于浮点运算的硬件与软件选择部分被注释掉了,用户可能需要指导如何启用这些功能,或者为什么需要根据硬件支持来选择不同的浮点选项。
总结来说,用户可能需要一个结构清晰的解释,逐步介绍CMake文件的各个部分,包括工具链配置、编译选项、链接过程、构建类型处理以及如何生成最终的可执行文件和二进制文件。同时,要指出关键配置点,帮助用户理解如何根据需求进行修改和优化。好的,我将为您逐段解析这个针对STM32H7系列微控制器的CMakeLists.txt文件:
一、工具链配置 $$ set(CMAKE_SYSTEM_NAME Generic) $$
- 交叉编译设置:
- 指定
Generic
表示无操作系统环境 - 使用ARM工具链:
arm-none-eabi-gcc/g++
- 定义汇编器/二进制工具:
objcopy
用于生成HEX/BIN文件,size
用于查看内存占用
二、项目基础设置
project(untitled C CXX ASM) # 支持C/C++/汇编混合编程
set(CMAKE_CXX_STANDARD 17) # C++17标准
set(CMAKE_C_STANDARD 11) # C11标准
三、关键编译选项解析
架构相关:
-mcpu=cortex-m7
:指定Cortex-M7内核-mthumb
:使用Thumb-2指令集-mfloat-abi=hard/soft
:浮点运算实现方式选择(示例中已注释)
优化选项:
-Ofast
:最高速度优化(Release模式)-Os
:最小体积优化(MinSizeRel模式)-Og
:调试友好优化(Debug模式)
四、内存管理配置 $$ -fdata-sections -ffunction-sections $$
- 配合链接器的
-Wl,-gc-sections
使用,通过消除未使用代码来减少固件体积
五、链接脚本关键作用
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32H743XIHX_FLASH.ld)
- 定义存储器布局:FLASH/RAM分配
- 控制代码/数据的分区存放
- 指定中断向量表位置
六、构建后处理流程
add_custom_command(...) # 生成HEX/BIN文件
- HEX文件:用于调试烧录
- BIN文件:直接烧写到Flash
- 通过
objcopy
工具转换ELF格式
七、HAL库集成要点
include_directories(...) # 包含STM32H7 HAL库路径
add_definitions(-DUSE_HAL_DRIVER) # 启用HAL库
八、典型定制点说明
硬件浮点单元启用: 取消注释相关
add_compile_options
和add_link_options
扩展外设支持: 在
include_directories
中添加新驱动的头文件路径调试配置: 保留
-g
选项时需注意Flash空间占用
九、内存使用分析
add_link_options(--print-memory-usage)
- 生成.map文件可分析各段内存分配
- 使用
arm-none-eabi-size
工具查看详细内存占用
十、推荐开发流程
- 创建build目录:
mkdir build && cd build
- 配置工程:
cmake -DCMAKE_BUILD_TYPE=Debug ..
- 编译:
make -j4
- 烧录:使用ST-Link或J-Link工具烧写生成的BIN/HEX文件
该配置模板已实现从源码编译到生成可烧录文件的完整工具链集成,开发者只需根据具体硬件修改链接脚本和外设配置即可快速移植到实际项目中。
execute_process(COMMAND sh -c "git symbolic-ref --short -q HEAD" OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND sh -c "git rev-list HEAD --abbrev=8 --abbrev-commit --max-count=1" OUTPUT_VARIABLE GIT_LAST_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND sh -c "git rev-list HEAD --count" OUTPUT_VARIABLE GIT_COMMITS_NUM OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND sh -c "git status --short --untracked-files=no | wc -l" OUTPUT_VARIABLE GIT_DIFF_STATUS OUTPUT_STRIP_TRAILING_WHITESPACE) if ( ${GIT_DIFF_STATUS} EQUAL "0" ) set(BUILD_VERSION "R${GIT_LAST_COMMIT}_${GIT_BRANCH}") else() set(BUILD_VERSION "R${GIT_LAST_COMMIT}M_${GIT_BRANCH}") endif() #build date string(TIMESTAMP DATETIME "%Y%m%d%H%M%S") #enable gdb debug symbol if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") message (STATUS "No CMAKE_BUILD_TYPE selected, defaulting to ${CMAKE_BUILD_TYPE}") endif() message (STATUS "The CMAKE_BUILD_TYPE is selected to ${CMAKE_BUILD_TYPE}") set(CMAKE_CXX_FLAGS_BASE "$ENV{CXXFLAGS} -pipe -Wall -Wno-unknown-pragmas -Wno-format-zero-length -lrt -Wno-ignored-attributes") #set(CMAKE_CXX_FLAGS_BASE "${CMAKE_CXX_FLAGS_BASE} -save-temps") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_BASE} -O2 -g") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_BASE} -O3") #set(CMAKE_DEBUG_POSTFIX _D) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CMAKE_COMMAND} -E time")
这段代码执行了一系列的命令,获取了与Git相关的信息,并设置了构建的版本号和日期。
首先,使用execute_process
命令执行了一系列的git
命令来获取Git的分支、最后一次提交、提交数量和文件差异状态的信息,并将结果保存到相应的变量中。
接下来,使用条件语句判断${GIT_DIFF_STATUS}
的值是否为0。如果是0,说明没有文件差异,那么将构建版本号设置为"R${GIT_LAST_COMMIT}${GIT_BRANCH}";否则,将构建版本号设置为"R${GIT_LAST_COMMIT}M${GIT_BRANCH}"。
然后,使用string(TIMESTAMP ...)
命令获取当前的日期和时间,并将结果保存到DATETIME
变量中。
接着,检查是否定义了CMAKE_BUILD_TYPE
变量。如果没有定义,将其设置为"Release",并输出一条消息表示默认使用了该选项。
然后,设置了编译器的基本选项CMAKE_CXX_FLAGS_BASE
,包括一些通用的编译选项和库链接选项。
接着,根据构建类型设置了不同的编译选项。对于Debug类型,使用-O2 -g
,表示开启优化级别2和调试符号。对于Release类型,使用-O3
,表示开启优化级别3。
最后,通过set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ...)
和set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ...)
命令设置了编译和链接命令的时间控制,用于输出编译和链接的时间信息。
总之,这段代码通过执行Git相关的命令获取了版本和日期信息,并设置了相应的变量和编译选项。
相关推荐
















