其他分享
首页 > 其他分享> > [001] [ESP32开发笔记] IDF工程创建与CMake配置

[001] [ESP32开发笔记] IDF工程创建与CMake配置

作者:互联网

ESP32
开发笔记
工程创建 工程分析 项目CMakeLists文件 组件CMakeLists文件 组件依赖

芯片型号:ESP32-S2-MINI-1
开发环境:VS Code + ESP-IDF插件

1 工程创建

2 工程分析

以官方示例项目分析:

- myProject/
             - CMakeLists.txt
             - sdkconfig
             - components/ - component1/ - CMakeLists.txt
                                         - Kconfig
                                         - src1.c
                           - component2/ - CMakeLists.txt
                                         - Kconfig
                                         - src1.c
                                         - include/ - component2.h
             - main/       - CMakeLists.txt
                           - src1.c
                           - src2.c

             - build/

注意

3 项目CMakeLists文件

每个项目都有一个顶层 CMakeLists.txt 文件,包含整个项目的构建设置。默认情况下,项目 CMakeLists 文件会非常小。

3.1 必要部分

在这里插入图片描述
最小项目CMakeLists文件必须包含下面三行代码:

cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(myProject)

3.2 可选的项目变量

注意:

cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/led_strip)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

3.3 覆盖默认的构建规范

构建系统设置了一些全局的构建规范(编译标志、定义等),这些规范可用于编译来自所有组件的所有源文件。

例如,其中一个默认的构建规范是编译选项 Wextra。假设一个用户想用 Wno-extra 来覆盖这个选项, 应在 project() 之后进行:

cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(myProject)

idf_build_set_property(COMPILE_OPTIONS "-Wno-error" APPEND)

4 组件CMakeLists文件

组件 ComponentsCOMPONENT_DIRS 列表中包含 CMakeLists.txt 文件的任何目录。是模块化且独立的代码,会被编译成静态库(.a 文件)并链接到应用程序。每个项目都包含一个或多个组件,这些组件可以是 ESP-IDF 的一部分,可以是项目自身组件目录的一部分,也可以从自定义组件目录添加

最小组件CMakeLists文件

最小组件 CMakeLists.txt 文件通过使用 idf_component_register 将组件添加到构建系统中。

idf_component_register( SRCS "app_main.c"
                    	INCLUDE_DIRS "include"
                        REQUIRES mbedtls)

也可以用CMake的set语法:

set(srcs 
"app_main.c" "src/oled.c")
idf_component_register(SRCS ${srcs}
                    INCLUDE_DIRS "inc")

4.1 同名组件

ESP-IDF 在搜索所有待构建的组件时,会按照COMPONENT_DIRS指定的顺序依次进行,即 ESP-IDF 内部组件(IDF_PATH/components)–> EXTRA_COMPONENT_DIRS 中的组件 --> 项目组件(PROJECT_DIR/components)。如果这些目录中的两个或者多个包含具有相同名字的组件,则使用搜索到的最后一个位置的组件。这就允许将组件复制到项目目录中再修改以覆盖 ESP-IDF 组件,如果使用这种方式,ESP-IDF 目录本身可以保持不变。

如果在现有项目中通过将组件移动到一个新位置来覆盖它,项目不会自动看到新组件的路径。请运行 idf.py reconfigure 命令后(或删除项目构建文件夹)再重新构建。

4.2 重命名 main 组件

构建系统会对 main 组件进行特殊处理。假如 main 组件位于预期的位置(即${PROJECT_PATH}/main),那么它会被自动添加到构建系统中。其他组件也会作为其依赖项被添加到构建系统中,这使用户免于处理依赖关系,并提供即时可用的构建功能。重命名 main 组件会减轻上述这些幕后工作量,但要求用户指定重命名后的组件位置,并手动为其添加依赖项。重命名 main 组件的步骤如下:

  1. 重命名 main 目录。
  2. 项目CMakeLists.txt文件中设置 EXTRA_COMPONENT_DIRS,并添加重命名后的 main 目录。
  3. 组件CMakeLists.txt文件中设置 COMPONENT_REQUIRESCOMPONENT_PRIV_REQUIRES 以指定依赖项。

4.3 预设的组件变量

以下专用于组件的变量可以在组件 CMakeLists 中使用,但不建议修改:

以下变量在项目级别中被设置,但可在组件 CMakeLists 中使用:

4.4 构建/项目变量

以下是可作为构建属性的构建/项目变量,可通过组件 CMakeLists.txt 中的 idf_build_get_property 查询其变量值。

4.5 组件配置

每个组件都可以包含一个 Kconfig 文件,和 CMakeLists.txt 放在同一目录下。Kconfig 文件中包含要添加到该组件配置菜单中的一些配置设置信息。

5 组件依赖

每个组件都需要声明它所依赖的组件,即requires

idf_component_register(...
                       REQUIRES mbedtls
                       PRIV_REQUIRES console spiffs)

如果组件仅支持某些硬件目标(IDF_TARGET 的值),则可以在 idf_component_register 中指定 REQUIRED_IDF_TARGETS 来声明这个需求。在这种情况下,如果构建系统导入了不支持当前硬件目标的组件时就会报错。

在 CMake 中,REQUIRESPRIV_REQUIRES 是 CMake 函数 target_link_libraries(... PUBLIC ...)target_link_libraries(... PRIVATE ...) 的近似包装。

5.1 组件依赖示例

假设现在有一个 car 组件,它需要使用 engine 组件,而 engine 组件需要使用 spark_plug 组件:

- autoProject/
             - CMakeLists.txt
             - components/ - car/ - CMakeLists.txt
                                     - car.c
                                     - car.h
                           - engine/ - CMakeLists.txt
                                     - engine.c
                                     - include/ - engine.h
                           - spark_plug/  - CMakeLists.txt
                                          - plug.c
                                          - plug.h

5.1.1 Car 组件

car.h 头文件

car.h 头文件是 car 组件的公共接口。该头文件直接包含了 engine.h,这是因为它需要使用 engine.h 中的一些声明:

/* car.h */
#include "engine.h"

#ifdef ENGINE_IS_HYBRID
#define CAR_MODEL "Hybrid"
#endif

同时 car.c 也包含了 car.h:

/* car.c */
#include "car.h"

这代表文件 car/CMakeLists.txt 需要声明 car 需要 engine

idf_component_register(SRCS "car.c"
                  INCLUDE_DIRS "."
                  REQUIRES engine)

5.1.2 Engine 组件

engine 组件也有一个公共头文件 include/engine.h,但这个头文件更为简单:

/* engine.h */
#define ENGINE_IS_HYBRID

void engine_start(void);

engine.c 中执行:

/* engine.c */
#include "engine.h"
#include "spark_plug.h"
...

在该组件中,engine 依赖于 spark_plug,但这是私有依赖关系。编译 engine.c 需要 spark_plug.h 但不需要包含 engine.h

这代表文件 engine/CMakeLists.txt 可以使用 PRIV_REQUIRES

idf_component_register(SRCS "engine.c"
                  INCLUDE_DIRS "include"
                  PRIV_REQUIRES spark_plug)

因此,car 组件中的源文件不需要在编译器搜索路径中添加 spark_plug include 目录。这可以加快编译速度,避免编译器命令行过于的冗长。

5.1.3 Spark Plug 组件

spark_plug 组件没有依赖项,它有一个公共头文件 spark_plug.h,但不包含其他组件的头文件。

这代表 spark_plug/CMakeLists.txt 文件不需要任何 REQUIRESPRIV_REQUIRES

idf_component_register(SRCS "spark_plug.c"
                  INCLUDE_DIRS ".")

5.2 源文件 Include 目录

每个组件的源文件都是用这些 Include 路径目录编译的,这些路径在传递给 idf_component_register 的参数中指定:

idf_component_register(..
                       INCLUDE_DIRS "include"		# include文件夹下的所有.h文件
                       PRIV_INCLUDE_DIRS "other")	

5.3 main组件依赖项

main 组件比较特别,因为它在构建过程中自动依赖所有其他组件。所以不需要向这个组件传递 REQUIRESPRIV_REQUIRES

5.4 通用组件依赖项

为避免重复性工作,各组件都用自动依赖一些“通用” IDF 组件,即使它们没有被明确提及。这些组件的头文件会一直包含在构建系统中。

通用组件包括:cxx、newlib、freertos、esp_hw_support、heap、log、lwip、soc、hal、esp_rom、esp_common、esp_system。

注意:要避免循环依赖,关于其定义和解决方法参考:循环依赖


参考:

  1. ESP-IDF编程指南-构建系统
  2. ESP32开发 2.添加.c.h并修改CMakeLists,来定制自己的工程
  3. ESPIDF添加自定义组件(创建C和H文件)
  4. ESP32学习笔记(21)——构建自己的工程和组件库

END

标签:DIRS,CMakeLists,CMake,ESP32,IDF,001,组件,txt,REQUIRES
来源: https://blog.csdn.net/kouxi1/article/details/123072022