自学内容网 自学内容网

【1.cmake工程管理-STM32 cmake工程分析】

1.stm32 cubemx的cmaek工程分析

stm32 CubeMX可以生成cmake工程,没有这个选项升级stm32 cubemx至最新版本

我的工程下载链接:

https://hedejiang.tpddns.cn:5001/sharing/Sv1syijlJ

以下是STM32的工程目录,只关心工程管理的部分

hdj@hdj-virtual-machine:~/st-cmake-project$ tree -L 2
.
├── cmake
│   ├── gcc-arm-none-eabi.cmake
│   └── stm32cubemx
├── CMakeLists.txt
├── CMakePresets.json
├── Core
│   ├── Inc
│   └── Src
├── Drivers
│   ├── CMSIS
│   └── STM32H7xx_HAL_Driver
├── startup_stm32h750xx.s
├── STM32H750XBHx_FLASH.ld
└── stm32h7-cmake.ioc

cmake目录下

hdj@hdj-virtual-machine:~/st-cmake-project/cmake$ tree -L 2
.
├── gcc-arm-none-eabi.cmake
└── stm32cubemx
    └── CMakeLists.txt

这是生成的cmake工程结构,可以看到在文件中有关cmaek管理工程的几个文件有如下几个,分析这几个文件的作用是什么,如下

工程目录下st-cmake-project的文件有           CMakeLists.txt    CMakePresets.json
                  cmake文件夹下有           gcc-arm-none-eabi.cmake  
                  cmaek->stm32cubemx      CMakeLists.txt

上述需要了解的有四个文件,来看看这些文件分别是什么,我将在原来的文件下将英文更改为中文注释,最后做小结

文件1:st-cmake-project -> CMakeLists.txt

cmake_minimum_required(VERSION 3.22)

#
# This file is generated only once,
# and is not re-generated if converter is called multiple times.
#
# User is free to modify the file as much as necessary
#

# Setup compiler settings
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)


# Define the build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif()

# Set the project name
set(CMAKE_PROJECT_NAME stm32h7-cmake)

# Include toolchain file
include("cmake/gcc-arm-none-eabi.cmake")

# Enable compile command to ease indexing with e.g. clangd
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

# Enable CMake support for ASM and C languages
enable_language(C ASM)

# Core project settings
project(${CMAKE_PROJECT_NAME})
message("Build type: " ${CMAKE_BUILD_TYPE})

# Create an executable object type
add_executable(${CMAKE_PROJECT_NAME})

# Add STM32CubeMX generated sources
add_subdirectory(cmake/stm32cubemx)

# Link directories setup
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user defined library search paths
)

# Add sources to executable
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user sources here
)

# Add include paths
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user defined include paths
)

# Add project symbols (macros)
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user defined symbols
)

# Add linked libraries
target_link_libraries(${CMAKE_PROJECT_NAME}
    stm32cubemx

    # Add user defined libraries
)

文件1解释

cmake_minimum_required(VERSION 3.22)   

#
# 此文件仅生成一次,
# 即使多次调用转换器也不会重新生成。
#
# 用户可以根据需要自由修改此文件
#

# 设置编译器配置
set(CMAKE_C_STANDARD 11)             # 设置C标准为C11
set(CMAKE_C_STANDARD_REQUIRED ON)    # 强制要求C11标准
set(CMAKE_C_EXTENSIONS ON)           # 允许使用C的扩展

# 定义构建类型
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")    # 如果未指定,默认设置为“Debug”构建类型
endif()

# 设置项目名称
set(CMAKE_PROJECT_NAME stm32h7-cmake) # 定义项目名称

# 包含工具链文件
include("cmake/gcc-arm-none-eabi.cmake") # 引入交叉编译工具链文件,配置用于编译ARM代码的编译器和编译选项

# 启用编译命令生成,方便如clangd等工具的索引
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) # 生成编译命令数据库文件compile_commands.json,便于代码索引

# 启用CMake对ASM和C语言的支持
enable_language(C ASM) # 启用汇编(ASM)和C语言支持

# 核心项目设置
project(${CMAKE_PROJECT_NAME})
message("构建类型: " ${CMAKE_BUILD_TYPE}) # 输出构建类型的信息,便于用户确认当前构建模式

# 创建一个可执行对象
add_executable(${CMAKE_PROJECT_NAME}) # 定义生成的可执行文件对象,以项目名称命名

# 添加STM32CubeMX生成的源文件目录
add_subdirectory(cmake/stm32cubemx) # 添加子目录 cmake/stm32cubemx ,用于包含STM32CubeMX生成的源文件和库

# 设置链接目录
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
    # 添加用户定义的库搜索路径
)

# 添加源文件到可执行文件
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
    # 添加用户自定义的源文件路径
)

# 添加包含路径
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
    # 添加用户定义的包含(头文件)路径
)

# 添加项目符号(宏定义)
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
    # 添加用户自定义的符号(宏定义)
)

# 添加链接库
target_link_libraries(${CMAKE_PROJECT_NAME}
    stm32cubemx # 链接由STM32CubeMX生成的库stm32cubemx

    # 添加用户定义的库
)

文件1总结

. CMakeLists.txt (项目根目录)
该文件是项目的主要CMake配置文件,负责定义项目的总体设置和构建逻辑。

项目设置:定义项目名称和编译标准(C11),指定默认的构建类型为Debug。
工具链:通过include("cmake/gcc-arm-none-eabi.cmake")引入ARM的交叉编译工具链文件。
支持语言:启用了C和汇编(ASM)支持。
添加目标和库:定义了一个可执行文件${CMAKE_PROJECT_NAME},并通过add_subdirectory将cmake/stm32cubemx子目录(包含STM32CubeMX生成的文件)添加为构建的一部分。
链接配置:设置链接目录、源文件、头文件路径等,还提供了一个接口库stm32cubemx。

文件2:st-cmake-project -> CMakePresets.json

{
    "version": 3,
    "configurePresets": [
        {
            "name": "default",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build/${presetName}",
    "toolchainFile": "${sourceDir}/cmake/gcc-arm-none-eabi.cmake",
            "cacheVariables": {
            }
        },
        {
            "name": "Debug",
            "inherits": "default",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            }
        },
        {
            "name": "RelWithDebInfo",
            "inherits": "default",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "RelWithDebInfo"
            }
        },
        {
            "name": "Release",
            "inherits": "default",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release"
            }
        },
        {
            "name": "MinSizeRel",
            "inherits": "default",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "MinSizeRel"
            }
        }
    ],
    "buildPresets": [
        {
            "name": "Debug",
            "configurePreset": "Debug"
        },
        {
            "name": "RelWithDebInfo",
            "configurePreset": "RelWithDebInfo"
        },
        {
            "name": "Release",
            "configurePreset": "Release"
        },
        {
            "name": "MinSizeRel",
            "configurePreset": "MinSizeRel"
        }
    ]
}

文件2解释

{
    "version": 3,  // CMake预设文件的版本号

    "configurePresets": [
        {
            "name": "default",  // 默认配置预设
            "hidden": true,     // 隐藏此配置,用户不可见
            "generator": "Ninja",  // 指定使用Ninja作为生成器
            "binaryDir": "${sourceDir}/build/${presetName}",  // 构建输出目录,基于源代码目录和预设名称
            "toolchainFile": "${sourceDir}/cmake/gcc-arm-none-eabi.cmake",  // 工具链文件路径,用于交叉编译配置
            "cacheVariables": {
                // 可在此添加缓存变量
            }
        },
        {
            "name": "Debug",  // 调试配置
            "inherits": "default",  // 继承默认配置
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"  // 设置构建类型为Debug,启用调试信息
            }
        },
        {
            "name": "RelWithDebInfo",  // 发布带调试信息的配置
            "inherits": "default",  // 继承默认配置
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "RelWithDebInfo"  // 设置构建类型为RelWithDebInfo,启用优化并保留调试信息
            }
        },
        {
            "name": "Release",  // 发布配置
            "inherits": "default",  // 继承默认配置
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release"  // 设置构建类型为Release,优化构建并移除调试信息
            }
        },
        {
            "name": "MinSizeRel",  // 最小化尺寸发布配置
            "inherits": "default",  // 继承默认配置
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "MinSizeRel"  // 设置构建类型为MinSizeRel,优化代码大小
            }
        }
    ],

    "buildPresets": [
        {
            "name": "Debug",  // 调试构建预设
            "configurePreset": "Debug"  // 使用Debug配置预设
        },
        {
            "name": "RelWithDebInfo",  // 发布带调试信息的构建预设
            "configurePreset": "RelWithDebInfo"  // 使用RelWithDebInfo配置预设
        },
        {
            "name": "Release",  // 发布构建预设
            "configurePreset": "Release"  // 使用Release配置预设
        },
        {
            "name": "MinSizeRel",  // 最小化尺寸发布构建预设
            "configurePreset": "MinSizeRel"  // 使用MinSizeRel配置预设
        }
    ]
}

在 CMake 中,CMakePresets.json 文件的主要作用是定义和管理配置构建的预设。它为不同的开发环境、构建类型、工具链等设置了固定的参数,这使得在不同机器或项目之间更容易统一配置,而不需要每次手动设置。

让我们以你当前的 STM32 项目为例来解释这个文件的实际作用。

  1. 配置预设(configurePresets

配置预设定义了如何配置 CMake 的生成过程。它告诉 CMake 使用哪个工具链文件、构建目录等。这个部分是让你能够跨不同环境、不同平台之间复用工具链配置。

实际应用:

假设正在开发一个 STM32 嵌入式项目,使用 gcc-arm-none-eabi 工具链进行交叉编译。可以通过在 CMakePresets.json 中设置一个配置预设来指定工具链文件、构建生成器等,避免每次编译时手动设置。

{
  "name": "default",
  "generator": "Ninja",
  "binaryDir": "${sourceDir}/build/${presetName}",
  "toolchainFile": "${sourceDir}/cmake/gcc-arm-none-eabi.cmake",
  "cacheVariables": {}
}
  • toolchainFile 指定了交叉编译所需的工具链文件,确保编译时使用正确的编译器和工具。
  • generator 设置为 Ninja,指定构建工具为 Ninja(可以改成其他工具如 Make)。

这样做的好处:每次运行 CMake 配置时,它会自动读取这个文件并按照预设的设置来进行配置,确保一致性。

  1. 构建预设(buildPresets

构建预设指定了要使用的配置预设以及其他构建相关的选项,比如构建类型(Debug/Release)等。它使得不同的构建类型(调试、发布等)使用不同的选项。

实际应用:

可能在开发过程中需要根据不同的需求切换不同的构建配置,比如 DebugRelease。可以在 CMakePresets.json 中定义这些构建预设,然后在实际构建时通过简单的命令来选择。

例如:

{
  "name": "Debug",
  "configurePreset": "Debug"
}
  • configurePreset 设置为 Debug,意味着每次选择 Debug 构建预设时,CMake 会使用预设中的配置选项(例如:启用调试信息,禁用优化等)。

这样做的好处:不需要每次手动指定编译选项,只需要通过选择合适的预设来自动应用一组配置。

  1. 在实际开发中如何使用

假设已经设置了 CMakePresets.json 文件并定义了以下预设:

  • Debug(调试模式)
  • Release(发布模式)
  • RelWithDebInfo(带有调试信息的优化版本)

当需要切换到不同的构建模式时,可以通过命令行轻松选择:

配置并构建 Debug 模式:
cmake --preset Debug
cmake --build --preset Debug
配置并构建 Release 模式:
cmake --preset Release
cmake --build --preset Release

CMake 会自动根据你选择的预设来应用相应的工具链、编译选项等,简化了手动设置的步骤。

4. 好处总结
  • 一致性:通过定义预设,保证了团队成员或不同环境中使用相同的构建配置。
  • 简化流程:减少了手动设置的复杂性。例如,不需要每次编译时手动指定工具链文件、编译类型等。
  • 可维护性:只需要修改 CMakePresets.json 文件中的配置,当环境或需求变化时,修改一次预设即可生效。

小结:

在当前的 STM32 项目中,CMakePresets.json 能够集中管理并简化编译过程。它避免了每次修改构建参数时的繁琐操作,通过预设的方式,确保了编译的一致性、灵活性和可维护性。

文件3:cmaek -> gcc-arm-none-eabi.cmake

set(CMAKE_SYSTEM_NAME               Generic)
set(CMAKE_SYSTEM_PROCESSOR          arm)

set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
set(CMAKE_C_COMPILER_ID GNU)
set(CMAKE_CXX_COMPILER_ID GNU)

# Some default GCC settings
# arm-none-eabi- must be part of path environment
set(TOOLCHAIN_PREFIX                arm-none-eabi-)

set(CMAKE_C_COMPILER                ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_ASM_COMPILER              ${CMAKE_C_COMPILER})
set(CMAKE_CXX_COMPILER              ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_LINKER                    ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_OBJCOPY                   ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_SIZE                      ${TOOLCHAIN_PREFIX}size)

set(CMAKE_EXECUTABLE_SUFFIX_ASM     ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_C       ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_CXX     ".elf")

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# MCU specific flags
set(TARGET_FLAGS "-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard ")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -fdata-sections -ffunction-sections")
if(CMAKE_BUILD_TYPE MATCHES Debug)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g3")
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -g0")
endif()

set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")

set(CMAKE_C_LINK_FLAGS "${TARGET_FLAGS}")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -T \"${CMAKE_SOURCE_DIR}/STM32H750XBHx_FLASH.ld\"")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} --specs=nano.specs")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lc -lm -Wl,--end-group")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--print-memory-usage")

set(CMAKE_CXX_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group")

文件3解释

# 设置系统名称为通用类型(Generic)
set(CMAKE_SYSTEM_NAME               Generic)
# 设置处理器架构为ARM
set(CMAKE_SYSTEM_PROCESSOR          arm)

# 强制指定C和C++编译器
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
# 设置编译器ID为GNU
set(CMAKE_C_COMPILER_ID GNU)
set(CMAKE_CXX_COMPILER_ID GNU)

# 一些默认的GCC设置
# arm-none-eabi- 必须在环境路径中
set(TOOLCHAIN_PREFIX                arm-none-eabi-)

# 指定工具链中的各个工具
set(CMAKE_C_COMPILER                ${TOOLCHAIN_PREFIX}gcc)     # C编译器
set(CMAKE_ASM_COMPILER              ${CMAKE_C_COMPILER})        # 汇编编译器
set(CMAKE_CXX_COMPILER              ${TOOLCHAIN_PREFIX}g++)     # C++编译器
set(CMAKE_LINKER                    ${TOOLCHAIN_PREFIX}g++)     # 链接器
set(CMAKE_OBJCOPY                   ${TOOLCHAIN_PREFIX}objcopy) # 二进制文件转换工具
set(CMAKE_SIZE                      ${TOOLCHAIN_PREFIX}size)    # 二进制文件大小检查工具

# 为生成的可执行文件设置后缀
set(CMAKE_EXECUTABLE_SUFFIX_ASM     ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_C       ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_CXX     ".elf")

# 尝试编译的目标类型设为静态库
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# MCU 特定的编译标志
set(TARGET_FLAGS "-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard ")  # 指定处理器、浮点单元和浮点ABI

# C编译器的通用标志
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -fdata-sections -ffunction-sections")
# 针对不同构建类型的C编译器优化
if(CMAKE_BUILD_TYPE MATCHES Debug)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g3")  # 调试构建,禁用优化并启用最高调试信息
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -g0")  # 发布构建,优化代码大小并移除调试信息
endif()

# 汇编编译器的标志
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP")  # 设置汇编语言预处理支持和依赖文件生成

# C++编译器的标志
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")  # 禁用运行时类型信息、异常和线程安全的静态变量

# 链接器标志
set(CMAKE_C_LINK_FLAGS "${TARGET_FLAGS}")
# 使用链接脚本指定存储器布局
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -T \"${CMAKE_SOURCE_DIR}/STM32H750XBHx_FLASH.ld\"")
# 使用nano.specs库,减少二进制文件大小
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} --specs=nano.specs")
# 生成内存映射文件并删除未使用的段
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections")
# 设置库组链接,确保标准C库和数学库的链接
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lc -lm -Wl,--end-group")
# 打印内存使用情况
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--print-memory-usage")

# C++链接器标志,添加标准C++库
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group")

文件4:cmaek -> stm32cubemx -> CMakeLists.txt

cmake_minimum_required(VERSION 3.22)

project(stm32cubemx)
add_library(stm32cubemx INTERFACE)

# Enable CMake support for ASM and C languages
enable_language(C ASM)

target_compile_definitions(stm32cubemx INTERFACE 
USE_HAL_DRIVER 
STM32H750xx
    $<$<CONFIG:Debug>:DEBUG>
)

target_include_directories(stm32cubemx INTERFACE
    ../../Core/Inc
    ../../Drivers/STM32H7xx_HAL_Driver/Inc
    ../../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy
    ../../Drivers/CMSIS/Device/ST/STM32H7xx/Include
    ../../Drivers/CMSIS/Include
)

target_sources(stm32cubemx INTERFACE
    ../../Core/Src/main.c
    ../../Core/Src/gpio.c
    ../../Core/Src/memorymap.c
    ../../Core/Src/stm32h7xx_it.c
    ../../Core/Src/stm32h7xx_hal_msp.c
    ../../Core/Src/stm32h7xx_hal_timebase_tim.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
    ../../Core/Src/system_stm32h7xx.c
    ../../Core/Src/sysmem.c
    ../../Core/Src/syscalls.c
    ../../startup_stm32h750xx.s
)

target_link_directories(stm32cubemx INTERFACE
)

target_link_libraries(stm32cubemx INTERFACE
)

# Validate that STM32CubeMX code is compatible with C standard
if(CMAKE_C_STANDARD LESS 11)
    message(ERROR "Generated code requires C11 or higher")
endif()

文件4解释

# 设置CMake的最低版本要求为3.22
cmake_minimum_required(VERSION 3.22)

# 设置项目名称为 stm32cubemx
project(stm32cubemx)

# 创建一个INTERFACE类型的库
# INTERFACE库只是提供头文件和其他设置,而不生成二进制文件
add_library(stm32cubemx INTERFACE)

# 启用C和汇编语言的CMake支持
enable_language(C ASM)

# 为库定义编译时的宏定义
target_compile_definitions(stm32cubemx INTERFACE 
USE_HAL_DRIVER  # 启用HAL驱动支持
STM32H750xx      # 指定目标芯片型号 STM32H750xx
    $<$<CONFIG:Debug>:DEBUG>  # 在Debug模式下定义DEBUG宏
)

# 为库添加头文件路径
# INTERFACE库的头文件路径会影响所有链接此库的目标
target_include_directories(stm32cubemx INTERFACE
    ../../Core/Inc  # STM32核心文件夹中的头文件
    ../../Drivers/STM32H7xx_HAL_Driver/Inc  # STM32 H7 HAL驱动头文件
    ../../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy  # 旧版HAL驱动头文件
    ../../Drivers/CMSIS/Device/ST/STM32H7xx/Include  # STM32H7系列CMSIS设备头文件
    ../../Drivers/CMSIS/Include  # CMSIS库公共头文件
)

# 为库添加源文件
# INTERFACE库的源文件将包含在所有链接此库的目标中
target_sources(stm32cubemx INTERFACE
    ../../Core/Src/main.c  # 主程序文件
    ../../Core/Src/gpio.c  # GPIO驱动文件
    ../../Core/Src/memorymap.c  # 内存映射文件
    ../../Core/Src/stm32h7xx_it.c  # STM32中断处理文件
    ../../Core/Src/stm32h7xx_hal_msp.c  # STM32硬件抽象层的初始化文件
    ../../Core/Src/stm32h7xx_hal_timebase_tim.c  # STM32时间基准定时器设置
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c  # Cortex相关初始化
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c  # 系统时钟配置文件
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c  # RCC扩展功能
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c  # 闪存驱动文件
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c  # 闪存扩展功能
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c  # GPIO驱动
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c  # 半主机模式控制
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c  # DMA驱动文件
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c  # DMA扩展
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c  # MDMA驱动
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c  # 电源管理驱动
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c  # 电源管理扩展功能
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c  # HAL驱动库
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c  # I2C驱动文件
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c  # I2C扩展功能
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c  # 外部中断驱动文件
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c  # 定时器驱动文件
    ../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c  # 定时器扩展
    ../../Core/Src/system_stm32h7xx.c  # 系统初始化文件
    ../../Core/Src/sysmem.c  # 系统内存管理文件
    ../../Core/Src/syscalls.c  # 系统调用文件
    ../../startup_stm32h750xx.s  # 启动汇编文件
)

# 设置库的链接目录
target_link_directories(stm32cubemx INTERFACE
    # 如果有需要的链接库路径可以添加在此
)

# 为库指定链接的外部库
target_link_libraries(stm32cubemx INTERFACE
    # 如果有需要的外部链接库可以添加在此
)

# 验证STM32CubeMX生成的代码是否符合C标准要求
if(CMAKE_C_STANDARD LESS 11)
    message(ERROR "Generated code requires C11 or higher")  # 如果C标准低于C11,输出错误信息
endif()

四个文件关联(重要)

CMakeLists.txt 文件的结构和关联

  1. 包含工具链文件(gcc-arm-none-eabi.cmake 在主 CMakeLists.txt 文件的顶部,使用 include() 语句包含了工具链文件 gcc-arm-none-eabi.cmake。这个文件定义了交叉编译的设置,包括 GCC 编译器、链接器等。工具链文件的目的是指定 ARM 编译工具链以及相关的编译和链接选项。

    include("cmake/gcc-arm-none-eabi.cmake")
    
  2. 设置 CMake 项目的核心设置 主 CMake 文件中还设置了一些基本的 CMake 配置,例如 C 标准为 C11,并且指定了编译器的类型。

    set(CMAKE_C_STANDARD 11)
    set(CMAKE_C_STANDARD_REQUIRED ON)
    set(CMAKE_C_EXTENSIONS ON)
    

    这些设置确保了编译过程中使用的 C 标准为 C11。

  3. 创建可执行目标(add_executableCMakeLists.txt 使用 add_executable() 创建了一个可执行目标。这个目标的名字是 stm32h7-cmake,并且会链接所有相关的源文件和库。

    add_executable(${CMAKE_PROJECT_NAME})
    
  4. 引入 STM32CubeMX 生成的文件(add_subdirectory(cmake/stm32cubemx) 通过 add_subdirectory() 引入了 cmake/stm32cubemx 子目录,这个子目录包含了从 STM32CubeMX 工具生成的代码。这些代码包括初始化代码、驱动程序等,这些文件是 STM32 特定的启动和硬件抽象代码。

    add_subdirectory(cmake/stm32cubemx)
    

    这意味着在主 CMake 项目中,stm32cubemx 子目录中的 CMakeLists.txt 文件会被引入并执行。cmake/stm32cubemx 目录中的文件会作为 stm32cubemx 库的源文件链接到主项目中。

  5. 设置链接目录和库(target_link_directoriestarget_link_libraries 主 CMake 文件还设置了可执行目标的链接目录和库。这里通过 target_link_libraries()stm32cubemx 库链接到可执行文件中。

    target_link_libraries(${CMAKE_PROJECT_NAME} stm32cubemx)
    

    这会把 stm32cubemx 作为一个 INTERFACE 库链接到项目中,意味着 stm32cubemx 库只提供头文件和链接信息,而不包含实际的目标文件或代码。

  6. 添加源文件和头文件(target_sourcestarget_include_directoriesstm32cubemx 子目录的 CMakeLists.txt 文件中,使用 target_sources()target_include_directories() 来添加 STM32CubeMX 生成的源文件和头文件路径:

    target_sources(stm32cubemx INTERFACE
        ../../Core/Src/main.c
        ../../Core/Src/gpio.c
        ../../Core/Src/memorymap.c
        ...
    )
    
    target_include_directories(stm32cubemx INTERFACE
        ../../Core/Inc
        ../../Drivers/STM32H7xx_HAL_Driver/Inc
        ...
    )
    

    这些源文件和头文件会被添加到 stm32cubemx INTERFACE 库中,并且通过 target_link_libraries() 被链接到主项目。

  7. 设置编译选项和符号(target_compile_definitions target_compile_definitions() 允许你为编译过程添加一些宏定义,通常用于条件编译。比如:

    target_compile_definitions(stm32cubemx INTERFACE 
        USE_HAL_DRIVER 
        STM32H750xx
        $<$<CONFIG:Debug>:DEBUG>
    )
    

    这会在 STM32CubeMX 生成的代码中定义 USE_HAL_DRIVERSTM32H750xx 等宏,确保适当的驱动和硬件配置被启用。

文件间的关联总结

  • CMakeLists.txt(主项目)
    • 引入了工具链文件 gcc-arm-none-eabi.cmake 来设置交叉编译环境。
    • 创建了可执行目标并链接了 STM32CubeMX 生成的源代码。
    • 使用 add_subdirectory() 包含了 stm32cubemx 目录,在其中查找 STM32CubeMX 生成的代码。
    • 通过 target_sources()target_include_directories() 将 STM32CubeMX 的源文件和头文件引入到主项目中。
  • CMakePresets.json
    • 定义了不同的构建配置(Debug、Release 等),并且指定了使用的工具链文件。
    • 构建时,CMakePresets.json 文件提供了针对不同构建类型(例如 Debug 或 Release)配置的 CMake 构建选项。
  • gcc-arm-none-eabi.cmake(工具链文件)
    • 定义了交叉编译工具链,指定了 GCC 编译器、链接器以及相关的选项。
    • 定义了目标 CPU(如 -mcpu=cortex-m7)、优化选项、以及调试和发布模式下的编译标志。
  • stm32cubemx/CMakeLists.txt
    • 通过 target_sources()target_include_directories()stm32cubemx INTERFACE 库添加 STM32CubeMX 生成的源文件和头文件。
    • 定义了与 STM32H7 系列 MCU 相关的编译宏,确保适当的硬件和驱动配置。

总结起来,主 CMakeLists.txt 文件通过包含工具链文件、添加 STM32CubeMX 子目录、以及配置目标和链接库,成功地将各个模块和文件整合起来,确保了整个 STM32 项目的构建和编译过程。

实际上可以用一个文件解决,这里将 编译工具链 与 **包含源文件以及头文件路径 **拆分开了,目的是保持主文件非必要无需更改,让层次更清晰


原文地址:https://blog.csdn.net/m0_51095029/article/details/143661160

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!