0

TL;博士

如何以优雅的方式将 CMakeLists.txt 与包含的项目级库一起使用?

介绍

尊敬的堆栈用户,

在我使用 Raspberry RP2040 遇到的手动创建的构建系统(以前使用预配置的 STM32CubeIDE、SW4STM32 和 MSP430 CCS)开始我的旅程后不久,我偶然发现了一项艰巨的(主观)任务,即在更意识的方式。浏览大量教程、提示和问题(以及 Pico 项目生成器),我设法构建了我的简单项目。然而我觉得它是以相当临时的方式完成的。

环境

情况如何:我有一个使用 RP2040 picoSDK 的项目 - 外围配置功能的集合,存储在项目目录之外的某种 HAL。将 picoSDK 视为外部库函数。使用这个 picoSDK,我创建了一个使用多个外围设备的简单应用程序。我将我的项目划分为以下结构: 项目结构

我的文件之间的连接如下: 我的 main.c 文件使用模块之一,模块使用两个外围设备的文件关系。所有这些文件都需要访问全局定义,并且 picoSDK 包括来自 common.h 文件。

为了清楚起见,我在 Windows 10 上使用 VS 代码,我使用 arm-gcc 10.3.1 进行编译,我的 CMake 版本是 3.20.6

问题和当前解决方案

现在,我一直在尝试在每个目录中使用具有多个 CMakeLists.txt 的方法(在此线程中建议:CMake with subdirectories)来创建基于目录的库,然后使用 add_subdirectory() 将它们全部添加到顶级 CMakeLists.txt 但没有成功。CMakeLists.txt 我以下列方式完成的工作:

cmake_minimum_required(VERSION 3.13)

# [Platfrom specific command] Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

project(ProjectName C CXX ASM)

# [Platfrom specific command] Initialize the Raspberry Pi Pico SDK
pico_sdk_init()

set(sources main.c
            Common.h
            Peripherals/PeripheralA.c
            Peripherals/PeripheralA.h
            Peripherals/PeripheralB.c
            Peripherals/PeripheralB.h
            Modules/ModuleSource.c
            Modules/ModuleSource.h
            Modules/ModuleConfig.h)
            
# Create executable with specified sources
add_executable(ProjectName ${sources})

# Add the standard library to the build (picoSDK inclusion)
target_link_libraries(ProjectName pico_stdlib)

# Add any user requested libraries (a part of picoSDK)
target_link_libraries( ProjectName
        hardware_timer
        )

免责声明:针对特定情况添加了特定于平台的行,当此问题落入精通 RP2040 的人手中时

问题

现在,我觉得嵌入式域有点不同,因为我的项目的每个部分(外围设备、模块甚至主文件)都需要访问基础:用于驱动微控制器的库(此处为 picoSDK),因此我想问一下:建议的方法是什么,CMakeLists.txt 内容的大纲是什么?我确信该项目会增长,并且根据其他回复,将所有内容都保存在一个 CMakeLists.txt 文件中是不建议的。

我正在寻找提示、好的建议和批评。我非常感谢您花时间阅读这篇文章或 - 当然 - 回复它。如果这个问题从熟练的用户角度解决了一些琐碎、已经回答或毫无意义的问题 - 请接受我的道歉。

4

1 回答 1

0

我能给你的最好建议是将你的代码组织到库中。它将解耦代码并为单元测试、模拟、代码重用等开辟机会。

您绝对应该避免依赖common.h外围设备和模块。

下面是一个示例,说明如何创建库并将它们链接到彼此以及主项目。

顶级 CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

# [Platfrom specific command] Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

project(ProjectName C CXX ASM)

# [Platfrom specific command] Initialize the Raspberry Pi Pico SDK
pico_sdk_init()

# Create executable with specified sources
add_executable(ProjectName main.c)

add_subdirectory(Modules)
add_subdirectory(Peripherals)

# Peripherals depend on pico_stdlib only.
target_link_libraries(Peripherals PUBLIC pico_stdlib)

# Modules depend on peripherals only.
target_link_libraries(Modules PUBLIC Peripherals)

# Link direct dependencies of the project.
target_link_libraries(ProjectName
    PRIVATE
        Modules
        hardware_timer
)

外设/CMakeLists.txt

project(Peripherals)

add_library(${PROJECT_NAME})

target_include_directories(${PROJECT_NAME} ${PROJECT_SOURCE_DIR})

target_sources(${PROJECT_NAME}
    PRIVATE
        Peripherals/PeripheralA.c
        Peripherals/PeripheralA.h
        Peripherals/PeripheralB.c
        Peripherals/PeripheralB.h
)

模块/CMakeLists.txt

project(Modules)

add_library(${PROJECT_NAME})

target_include_directories(${PROJECT_NAME} ${PROJECT_SOURCE_DIR})

target_sources(${PROJECT_NAME}
    PRIVATE
        Modules/ModuleSource.c
        Modules/ModuleSource.h
        Modules/ModuleConfig.h
)
于 2022-03-06T02:14:25.683 回答