前言
因?yàn)槭煜ち薙TM32的開發(fā)方式,同時(shí)隨著項(xiàng)目文件越來(lái)越多,可以將自己寫的代碼分模塊添加到工程中,下面分析如何將自己寫的組件添加到工程中使其能夠正常編譯運(yùn)行。
簡(jiǎn)介
在ESP-IDF中,構(gòu)建,編譯,以及下載都是通過(guò)idf.py腳本來(lái)實(shí)現(xiàn)的,該腳本使用
-
CMake,配置待構(gòu)建的項(xiàng)目
-
Ninja,用于構(gòu)建項(xiàng)目
-
esptool.py,燒錄目標(biāo)硬件設(shè)備
從上面可以看出管理項(xiàng)目架構(gòu)使用的是CMake,一個(gè) ESP-IDF 項(xiàng)目可以看作是多個(gè)不同組件的集合,示例代碼的結(jié)構(gòu)一般如下所示:
- 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/
-
頂層項(xiàng)目 CMakeLists.txt 文件,這是 CMake 用于學(xué)習(xí)如何構(gòu)建項(xiàng)目的主要文件,可以在這個(gè)文件中設(shè)置項(xiàng)目全局的 CMake 變量。頂層項(xiàng)目 CMakeLists.txt 文件會(huì)導(dǎo)入 /tools/cmake/project.cmake 文件,由它負(fù)責(zé)實(shí)現(xiàn)構(gòu)建系統(tǒng)的其余部分。該文件最后會(huì)設(shè)置項(xiàng)目的名稱,并定義該項(xiàng)目。
-
“sdkconfig” 項(xiàng)目配置文件,執(zhí)行 idf.py menuconfig 時(shí)會(huì)創(chuàng)建或更新此文件,文件中保存了項(xiàng)目中所有組件(包括 ESP-IDF 本身)的配置信息。 sdkconfig 文件可能會(huì)也可能不會(huì)被添加到項(xiàng)目的源碼管理系統(tǒng)中。
-
可選的 “components” 目錄中包含了項(xiàng)目的部分自定義組件,并不是每個(gè)項(xiàng)目都需要這種自定義組件,但它有助于構(gòu)建可復(fù)用的代碼或者導(dǎo)入第三方(不屬于 ESP-IDF)的組件?;蛘?,您也可以在頂層 CMakeLists.txt 中設(shè)置 EXTRA_COMPONENT_DIRS 變量以查找其他指定位置處的組件。
-
“main” 目錄是一個(gè)特殊的組件,它包含項(xiàng)目本身的源代碼。”main” 是默認(rèn)名稱,CMake 變量COMPONENT_DIRS 默認(rèn)包含此組件,但您可以修改此變量。有關(guān)詳細(xì)信息,請(qǐng)參閱 重命名 main 組件。如果項(xiàng)目中源文件較多,建議將其歸于組件中,而不是全部放在 “main” 中。
-
“build” 目錄是存放構(gòu)建輸出的地方,如果沒(méi)有此目錄,idf.py 會(huì)自動(dòng)創(chuàng)建。CMake 會(huì)配置項(xiàng)目,并在此目錄下生成臨時(shí)的構(gòu)建文件。隨后,在主構(gòu)建進(jìn)程的運(yùn)行期間,該目錄還會(huì)保存臨時(shí)目標(biāo)文件、庫(kù)文件以及最終輸出的二進(jìn)制文件。此目錄通常不會(huì)添加到項(xiàng)目的源碼管理系統(tǒng)中,也不會(huì)隨項(xiàng)目源碼一同發(fā)布。
頂層CMakeLists.txt
可以看出,CMake文件分為頂層CMake和組件CMake,頂層CMake通過(guò)包含的方式包含組件CMake
頂層CMake為文件如下所示
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "./conponets/conponent1" | "./conponets/conponent2")
project(myProject)
一個(gè)CMake文件應(yīng)該首先指定所需的CMake的最小版本,然后包含了$IDF_PATH/tools/cmake/project.cmake
這個(gè)配置文件,最后project(project name)
指定了構(gòu)建項(xiàng)目的名稱。
在這個(gè)文件中就出現(xiàn)了EXTRA_COMPONENTS_DIRS,其實(shí)從其名字里不難看出EXTRA(外部)、COMPONENTS(組件)、DIRS(文件夾)它是用來(lái)保存外部組件文件夾的一個(gè)CMake變量
因此可以通過(guò)set(EXTRA_CONPONENTS)的方式導(dǎo)入外部組件,但是這條命令只能使用一次,多次使用時(shí)后面的會(huì)覆蓋前面的,可以通過(guò)set(EXTRA_COMPONENT_DIRS “./user_components_1” | “./user_components_2”)的方式或者使用CMake的函數(shù)list(APPEND EXTRA_COMPONENT_DIRS “子目錄”)這兩種方法實(shí)現(xiàn)包含多個(gè)組件。
組件CMakeLists.txt
每個(gè)組件都包含一個(gè)CMakeLists.txt用于包含組件所包含的文件,便于頂層CMake索引。
最小組件 CMakeLists.txt 文件通過(guò)使用 idf_component_register
將組件添加到構(gòu)建系統(tǒng)中。
idf_component_register(SRCS “src1.c”
INCLUDE_DIRS “include”
REQUIRES demo1
PRI_REQUIRES demo2)
-
SRCS 是組件包含的源文件列表(.c、.cpp、.cc、.S),里面所有的源文件都將會(huì)編譯進(jìn)組件庫(kù)中。
-
INCLUDE_DIRS 是組件的頭文件列表,里面的路徑會(huì)被添加到所有需要該組件的組件(包括 main 組件)全局 include 搜索路徑中。
-
REQUIRES 實(shí)際上并不是必需的,但通常需要它來(lái)聲明該組件需要使用哪些其它組件,舉個(gè)例子,當(dāng)自己寫的組件的頭文件需要依賴其他組件的時(shí)候需要在REQUIRES后跟所需的組件名稱
-
PRI_REQUIRES與REQUIRES的作用類似,都是包含所需的組件,但是PRI_REQUIRES的意思是私有依賴,即源文件中需要包含組件的頭文件時(shí)可以使用PRI_REQUIRES來(lái)包含組件,而REQUIRES是頭文件包含其他組件的頭文件時(shí)用的。
在 CMake 中,REQUIRES 和 PRIV_REQUIRES 是 CMake 函數(shù) target_link_libraries(… PUBLIC …) 和 target_link_libraries(… PRIVATE …) 的近似包裝。
下面是一個(gè)官方的示例:
組件依賴示例
假設(shè)現(xiàn)在有一個(gè) 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
- spark_plug.c
- spark_plug.h
Car 組件
car.h 頭文件是 car 組件的公共接口。該頭文件直接包含了 engine.h,這是因?yàn)樗枰褂?engine.h 中的一些聲明:
/* car.h */
#include "engine.h"
#ifdef ENGINE_IS_HYBRID
#define CAR_MODEL "Hybrid"
#endif
同時(shí) car.c 也包含了 car.h:
/* car.c */
#include "car.h"
這代表文件 car/CMakeLists.txt 需要聲明 car 需要 engine:
idf_component_register(SRCS "car.c"
INCLUDE_DIRS "."
REQUIRES engine)
-
SRCS 提供 car 組件中源文件列表。
-
INCLUDE_DIRS 提供該組件公共頭文件目錄列表,由于 car.h 是公共接口,所以這里列出了所有包含了 car.h 的目錄。
-
REQUIRES 給出該組件的公共接口所需的組件列表。由于 car.h 是一個(gè)公共頭文件并且包含了來(lái)自 engine 的頭文件,所以我們這里包含 engine。這樣可以確保任何包含 car.h 的其他組件也能遞歸地包含所需的 engine.h。
Engine 組件
engine 組件也有一個(gè)公共頭文件 include/engine.h,但這個(gè)頭文件更為簡(jiǎn)單:
/* engine.h */
#define ENGINE_IS_HYBRID
void engine_start(void);
engine.c :
/* engine.c */
#include "engine.h"
#include "spark_plug.h"
...
在該組件中,engine 依賴于 spark_plug,但這是私有依賴關(guān)系。編譯 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 目錄。這可以加快編譯速度,避免編譯器命令行過(guò)于的冗長(zhǎng)。
Spark Plug 組件
spark_plug 組件沒(méi)有依賴項(xiàng),它有一個(gè)公共頭文件 spark_plug.h,但不包含其他組件的頭文件。
這代表 spark_plug/CMakeLists.txt 文件不需要任何 REQUIRES 或 PRIV_REQUIRES:
idf_component_register(SRCS "spark_plug.c"
INCLUDE_DIRS ".")
源文件 Include 目錄
每個(gè)組件的源文件都是用這些 Include 路徑目錄編譯的,這些路徑在傳遞給 idf_component_register 的參數(shù)中指定:
idf_component_register(..
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "other")
當(dāng)前組件的 INCLUDE_DIRS 和 PRIV_INCLUDE_DIRS。
REQUIRES 和 PRIV_REQUIRES 參數(shù)指定的所有其他組件(即當(dāng)前組件的所有公共和私有依賴項(xiàng))所設(shè)置的 INCLUDE_DIRS。
遞歸列出所有組件 REQUIRES 列表中 INCLUDE_DIRS 目錄(如遞歸展開這個(gè)組件的所有公共依賴項(xiàng))。
頂層CMakeLists.txt
參考上面列出來(lái)的頂層CMake,需要使用set(EXTRA_COMPONENT_DIRS "./user_components_1" | "./user_components_2")
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "./car")
project(smartconfig)
總結(jié):
如果要添加一個(gè)組件,我們需要修改頂層CMakeLists.txt以及新添加的組件的CMakeLists.txt,具體內(nèi)容參考上面示例
參考:
-
樂(lè)鑫官方構(gòu)建系統(tǒng)
-
https://blog.csdn.net/lum250/article/details/123382392
-
https://blog.csdn.net/RuiyaoNi/article/details/124804251文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-432879.html
-
https://blog.csdn.net/DINGDING_GO/article/details/112724707文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-432879.html
到了這里,關(guān)于ESP-IDF開發(fā)框架添加自定義組件 ESP32-C3的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!