一、项目结构
先来看看如下项目结构:
ESP32
├─ .gitignore
├─ .vscode
│ ├─ configurationCache.log
│ ├─ c_cpp_properties.json
│ ├─ dryrun.log
│ ├─ settings.json
│ └─ targets.log
├─ CMakeLists.txt
├─ components
│ └─ captive_portal
│ ├─ captive_portal.c
│ ├─ captive_portal.h
│ ├─ CMakeLists.txt
│ ├─ component.mk
│ ├─ dns_server
│ │ ├─ dns_server.c
│ │ └─ dns_server.h
│ ├─ http_server
│ │ ├─ cJSON
│ │ │ ├─ cJSON.c
│ │ │ └─ cJSON.h
│ │ ├─ index.html
│ │ ├─ my_http_server.c
│ │ ├─ my_http_server.h
│ │ └─ url_code
│ │ ├─ my_url_code.c
│ │ └─ my_url_code.h
│ ├─ soft_ap
│ │ ├─ console_app
│ │ │ ├─ cmd_system
│ │ │ │ ├─ cmd_system.c
│ │ │ │ └─ cmd_system.h
│ │ │ ├─ console_app.c
│ │ │ └─ console_app.h
│ │ ├─ my_soft_ap.c
│ │ └─ my_soft_ap.h
│ └─ wifi_station
│ ├─ wifi_station.c
│ └─ wifi_station.h
├─ main
│ ├─ app_main.c
│ ├─ CMakeLists.txt
│ └─ component.mk
├─ Makefile
├─ README.md
└─ sdkconfig
二、生成目录结构
先说下怎么生成这样的目录结构,步骤如下:
1. vscode安装插件,project-tree
2. 安装之后按ctrl+shift+p 或 直接F1打开命令输入框,并输入Project Tree回车
3. 点击要生成目录的项目,回车
4. 将项目目录生成并存储到README.md中
三、CMakeLists.txt写法说明
由上面目录结构可以看到 项目中组件目录components下只有一个组件captive_portal,其它子目录都是在captive_portal目录下作为组件captive_portal所用到的模块,只有components根目录下的目录才算一个组件,所以当前项目的组件只有一个captive_portal (当然main严格上讲也属于一个组件,这里我们只讨论components下的组件)。
由上面的结构可以发现组件下的子目录并没有CMakeLists.txt和component.mk,实际上也不需要,只有每个组件根目录下才需要有CMakeLists.txt和component.mk(component.mk很多时候并不是必需的)。
那么组件子目录下的依赖组件或头文件目录及源文件引用信息该写在哪里呢?答案是写在当前组件根目录下的CMakeLists.txt和component.mk,只需要加上源文件或头文件目录的相对应前置目录即可。我们看一下组件captive-portal根目录下CMakeLists.txt的内容如下:
# compoments/captive-portal下的CMakeList文件
#加入源文件
#加入头文件
#加入组件依赖关系
#要加入当前目录下所有源文件,多个文件用空格分隔
#INCLUDE_DIRS .表示加入当前目录下所有头文件
#REQUIRES console nvs_flash 表明该组件依赖console和nvs_flash两个系统组件
# 调用idf_compoment_register函数向系统注册源文件和头文件
idf_component_register( SRCS "captive_portal.c" #当前组件直接或间接用到的源文件列表
"./dns_server/dns_server.c"
"./http_server/my_http_server.c"
"./http_server/url_code/my_url_code.c"
"./wifi_station/wifi_station.c"
"./soft_ap/my_soft_ap.c"
INCLUDE_DIRS "." #当前组件直接或间接用到的头文件目录列表
"./wifi_station"
"./http_server"
"./http_server/url_code"
"./dns_server"
"./soft_ap"
"$ENV{IDF_PATH}/components/esp_wifi/include"
"$ENV{IDF_PATH}/components/nvs_flash/include"
"$ENV{IDF_PATH}/components/esp_http_server/include"
EMBED_FILES http_server/index.html #将wifi.html文件内容以二进制形式(文本形式用EMBED_TXTFILES)添加到 Flash 的 .rodata 段
REQUIRES nvs_flash esp_http_server #添加依赖的组件,否则会提示找不到头文件
REQUIRES nvs_flash nghttp
)
其中有一些.c源文件或头文件或依赖组件并不是由captive_portal.c直接使用的,可能是由其下的子目录使用,但当前组件captive_portal.c会间接使用到它,所以要把它们全部写在组件captive-portal根目录下CMakeLists.txt中,否则会报错找不到文件或变量未定义等。也即相当于把原子目录下的CMakeLists.txt全部合并到captive-portal组件根目录下的CMakeLists.txt。
同理,把原子目录下的component.mk内容全部合并到captive_portal根目录下的component.mk中,注意添加上对应目录即可。
四、component.mk写法说明
captive_portal根目录下的component.mk内容如下:
COMPONENT_EMBED_FILES := http_server/index.html #将index.html文件内容以二进制形式(文本形式用EMBED_TXTFILES)添加到 Flash 的 .rodata 段(该内容原本位于http_server下的component.mk)
其中COMPONENT_EMBED_FILES := index.html 原本是在http_server目录下的component.mk内容,移到captive-portal组件根目录后要加上目录http_server/,否则无法查找到该文件。