【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 项目的构建和编译过程。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/912970.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电信网关配置管理系统 upload_channels.php 文件上传致RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

澳鹏通过高质量数据支持 Onfido 优化AI反欺诈功能

“Appen 在 Onfido 的发展中发挥了至关重要的作用&#xff0c;并已成为我们运营的重要组成部分。我们很高兴在 Appen 找到了可靠的合作伙伴。” – Onfido 数据和分析总监 Francois Jehl 简介&#xff1a;利用人工智能和机器学习增强欺诈检测 在当今日益数字化的世界&#xff…

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块&#xff0c;适用于执行简单的命令&#xff0c;不支持特殊符号 案列01&#xff0c;批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…

应对AI与机器学习的安全与授权管理新挑战,CodeMeter不断创新引领保护方案

人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术正在快速发展&#xff0c;逐渐应用到全球各类主流系统、设备及关键应用场景中&#xff0c;尤其是在政府、商业和工业组织不断加深互联的情况下&#xff0c;AI和ML技术的影响日益广泛。虽然AI技术的…

实现uniapp-微信小程序 搜索框+上拉加载+下拉刷新

pages.json 中的配置 { "path": "pages/message", "style": { "navigationBarTitleText": "消息", "enablePullDownRefresh": true, "onReachBottomDistance": 50 } }, <template><view class…

布谷直播源码部署服务器关于数据库配置的详细说明

布谷直播源码搭建部署配置接口数据库 /public/db.php&#xff08;2019年8月后的系统在该路径下配置数据库&#xff0c;老版本继续走下面的操作&#xff09; 在项目代码中执行命令安装依赖库&#xff08;⚠️注意&#xff1a;如果已经有了vendor内的依赖文件的就不用执行了&am…

【C++】STL— stack的常见用法和模拟实现

目录 1、stack的介绍 2、stack的使用 构造一个空栈 stack的简单接口应用 3、stack的模拟实现 4、栈的相关题目 4.1 最小栈 4.1.2思路 4.1.3 实现代码 4.2 栈的压入、弹出序列 4.2.2 思路 4.2.3程序实现 1、stack的介绍 在C中&#xff0c;stack是一种标准模板库&am…

vue大疆建图航拍功能实现

介绍 无人机在规划一块区域的时候&#xff0c;我们需要手动的给予一些参数来影响无人机飞行&#xff0c;对于一块地表&#xff0c;无人机每隔N秒在空中间隔的拍照地表的一块区域&#xff0c;在整个任务执行结束后&#xff0c;拍到的所有区域照片能够完整的表达出一块地表&…

[ DOS 命令基础 2 ] DOS 命令详解-网络相关命令

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

es自动补全(仅供自己参考)

elasticssearch提供了CompletionSuggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询效率&#xff0c;对于文档中字段的类型有一些约束&#xff1a; 查询类型必须是&#xff1a;completion 字段内容是多个补全词条形成的数组 P…

react jsx基本语法,脚手架,父子传参,refs等详解

1&#xff0c;简介 1.1 概念 react是一个渲染html界面的一个js库&#xff0c;类似于vue&#xff0c;但是更加灵活&#xff0c;写法也比较像原生js&#xff0c;之前我们写出一个完成的是分为html&#xff0c;js&#xff0c;css&#xff0c;现在我们使用react库我们把html和js结…

Chrome浏览器如何导出所有书签并导入书签

前言 我平常在开发中&#xff0c;基本是用的谷歌的浏览器&#xff0c;也就是Chrome&#xff0c;因为这个对于开发来说&#xff0c;比较友好。在开发中&#xff0c;包括调试接口&#xff0c;打断点&#xff0c;查看打印日志等&#xff0c;都是非常不错的。另一方面&#xff0c;…

[WSL][桌面][X11]WSL2 Ubuntu22.04 安装Ubuntu桌面并且实现GUI转发(Gnome)

1. WSL安装 这里不再赘述&#xff0c;WSL2支持systemd&#xff0c;如果你发现其没有systemd相关指令&#xff0c;那么你应该看看下面这个 https://blog.csdn.net/noneNull0/article/details/135950369 但是&#xff0c;Ubuntu2204用不了这个脚本&#xff0c;比较蛋疼。 – …

C语言中的 printf( ) 与 scanf( )

时隔多日&#xff0c;小编我又回来咯小编相信之前的博客能够给大家带来不少的收获。在我们之前的文章中&#xff0c;许多代码块的例子都用到了printf( ) 与 scanf( )这两个函数&#xff0c;大家都知道他们需要声明头文件之后才能使用&#xff0c;那这两个函数是什么呢&#xff…

【Homework】【1--4】Learning resources for DQ Robotics in MATLAB

Learning resources for DQ Robotics in MATLAB Lesson 1 代码 % Step 2: Define the real numbers a1 and a2 a1 123; a2 321;% Step 3: Calculate and display a3 a1 a2 a3 a1 a2; disp([a3 (a1 a2) , num2str(a3)])% Step 4: Calculate and display a3 a1 * a2 a3…

前端刺客系列----Vue 3 入门介绍

目录 一.什么是 Vue 3&#xff1f; 二.Vue 3 的主要特性 三,Vue3项目实战 四.总结 在前端开发的世界里&#xff0c;Vue.js 作为一款渐进式的 JavaScript 框架&#xff0c;已成为许多开发者的首选工具。自从 Vue 3 发布以来&#xff0c;它带来了许多重要的改进和新特性&…

Linux入门:环境变量与进程地址空间

一. 环境变量 1. 概念 1️⃣基本概念&#xff1a; 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#x…

2024版最新最全的Kali Linux操作系统安装使用教程(非常详细)超十万字解说Kali零基础入门到精通教程,收藏这一篇就够了

前言 这是向阳给粉丝盆友们整理的网络安全渗透测试入门阶段渗透测试工具Kali全套教程&#xff0c;本文超十万字超长分析&#xff0c;建议大家收藏慢慢学习&#xff01; 喜欢的朋友们&#xff0c;记得给向阳点赞支持和收藏一下&#xff0c;关注我&#xff0c;学习黑客技术 Ka…

【计网】基于TCP协议的Echo Server程序实现与多版本测试

目录 前言&#xff1a; 1、InitServer类的实现 1.1. 创建流式套接字 1.2. bind 绑定一个固定的网络地址和端口号 1.3.listen监听机制 1.4.完整代码 2. 循环接收接口与服务接口 2.1.accept函数讲解 讲个商场拉客的故事方便我们理解&#xff1a; 2.2.服务接口实现 3.服…

Latex公式转换编辑网站

https://editor.codecogs.com/ https://www.latexlive.com/home## https://simpletex.cn/ai/latex_ocr https://webdemo.myscript.com/views/math/index.html# 参考 https://latex.91maths.com/ https://web.baimiaoapp.com/image-to-latex https://blog.csdn.net/qq_45100…