一、在main中调用Hello_world
1、生成静态库
生成静态库参考上一节构建系统与组件 在项目文件夹下找到build文件夹的esp-idf文件夹,再找到要生成的静态库文件夹的名称,上一节在components/printf_hello_world新建组件,所以找到printf_hello_world文件夹下生成的.a静态库。 这里的libprintf_hello_world.a就是该组件生成的静态库。 每个组件 CMakeLists 文件会构建生成与组件同名的库,并最终被链接到应用程序中。
2、使用静态库
参考示例use_hello_world_lib 将build文件夹下生成的libprintf_hello_world.a复制到printf_hello_world文件夹下,删除printf_hello_world.c文件 在printf_hello_world组件中的cmakelists.txt文件下删除"hello_world.c"源文件,将.a静态库链接到系统中
set(LIBS printf_hello_world)
add_library(${LIBS} STATIC IMPORTED)
set_property(TARGET ${LIBS} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib${LIBS}.a)
target_link_libraries(${COMPONENT_LIB} INTERFACE ${LIBS})
set_property(TARGET ${LIBS} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${COMPONENT_LIB})
set(LIBS 后面改为自己的组件名 在编译之前用idf.py fullclean 一下删除build文件夹下的配置,重新编译一遍,不然编译不通过。
也可以直接使用target_link_libraries来代替上面的链接
target_link_libraries(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/libprintf_hello_world.a")
接下来烧录进esp32开发板看到输出Hello world!即调用成功。
二、多个组件关系
1、多个组件生成.a静态库
参考multi_components 新建第二个组件second_component,在hello_world.c中调用second_component组件 调用时不仅要在hello_world.c声明second_component.h头文件,还要在printf_hello_world组件下的cmakelists.txt中包含头文件,不然编译不通过 以同样的方式新建第三个组件,同时在第二个组件的cmakelists.txt中包含第三个组件的头文件。 结果依次输出Hello world! second_component! third_component!
2、使用多个组件.a静态库
同样在multi_components项目下的build文件夹下esp_idf文件夹中找到对应的libprintf_hello_world.a libsecond_component.a libthird_component.a三个静态库以同样的方式链接,参考示例use_multi_components_lib 同样打印出三个组件的信息,即链接成功。
注意:如果编译不通过或链接未成功可以在顶层cmakelists.txt下设置EXTRA_COMPONENT_DIRS(用于搜索组件的其它可选目录列表。路径可以是相对于项目目录的相对路径,也可以是绝对路径)变量查找components位置处的组件。要使用 cmake 中的 set 命令 来设置这些变量,set() 命令需放在 include(…) 之前,cmake_minimum(…) 之后,如:
set(EXTRA_COMPONENT_DIRS ${COMPONENTS_PATH}/printf_hello_world)
在一个大的工程下封装某个函数为.a静态库时,如果调用的其他文件的函数较多的情况下可能会出现构建失败并出现关于 “Undefined reference to …” 的链接器错误。(在.c源文件状态下能编译通过但是链接.a静态库时编译不通过出现“Undefined reference to …” ) 出现原因可能是封装的这个函数在调用某个库或组件中的函数时链接不到,这时在封库的组件的cmakelists.txt下依赖REQUIRES 一下调用的组件应该就编译通过了;也有可能是循环依赖导致。
|