导入第三方库概述
可以在应用程序的目录之外生成库代码,但重要的是应用程序和库代码都面向相同的应用程序二进制接口 (ABI)。在大多数体系结构上,都有控制ABI目标的编译器标志,因此库和应用程序具有某些共同的编译器标志非常重要。
为了更轻松地集成第三方组件,Zephyr构建系统定义了CMake函数,使应用程序构建脚本能够访问zephyr编译器选项。这些函数在cmake/extensions.cmake中记录和定义,并遵循zephyr_get_<type>_<format>命名约定。
以下变量通常需要导出到第三方生成系统:
- 编译标志
CMAKE_C_COMPILER - 链接标志
CMAKE_AR - 体系架构
ARCH - 板子信息
BOARD - 标识
Zephyr内核版本
示例
目录结构
|--++ external_lib|--++ mylib|--++ include|-- mylib.h|--++ src|-- mylib.c|-- Makefile|--++ src|-- main.c|-- CMakeLists.txt|-- README.rst|-- prj.conf|-- sample.yaml
CmakeLists.txt的编写
# SPDX-License-Identifier: Apache-2.0# 指定cmake的最低运行版本cmake_minimum_required(VERSION 3.20.0)# 查找zephyrfind_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})# 定义项目名称project(external_lib)# 添加应用程序的源文件target_sources(app PRIVATE src/main.c)# 获取zephyr编译C代码的系统的头文件路径zephyr_get_include_directories_for_lang_as_string(C includes)# 获取zephyr编译C代码系统的头文件系统路径zephyr_get_system_include_directories_for_lang_as_string(C system_includes)# 获取zephyr编译C代码的外部定义zephyr_get_compile_definitions_for_lang_as_string(C definitions)# 获取zephyr编译C代码的编译标志zephyr_get_compile_options_for_lang_as_string(C options)# 设置编译第三方库时的标志set(external_project_cflags"${includes} ${definitions} ${options} ${system_includes}")# 包含外部项目模块include(ExternalProject)# 设置需要编译外部库的源码目录set(mylib_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/mylib)# 设置需要编译外部库的头文件目录set(mylib_build_dir ${CMAKE_CURRENT_BINARY_DIR}/mylib)# 设置生成的库的存放目录set(MYLIB_LIB_DIR ${mylib_build_dir}/lib)# 设置库的头文件路径set(MYLIB_INCLUDE_DIR ${mylib_src_dir}/include)# 判定camke使用的的生成器,然后设置生成库时采用的生成器一致if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")# https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.htmlset(submake "$(MAKE)")else() # Obviously no MAKEFLAGS. Let's hope a "make" can be found somewhere.set(submake "make")endif()# 设置生成库时需要的信息ExternalProject_Add(mylib_project # 一个自定义的目标PREFIX ${mylib_build_dir} # 库的根目录SOURCE_DIR ${mylib_src_dir} # 库的源码目录BINARY_DIR ${mylib_src_dir} # 库的二进制根目录CONFIGURE_COMMAND "" # 库的配置命令BUILD_COMMAND # 库的编译命令${submake} # 库使用的生成器PREFIX=${mylib_build_dir} # 库编译时的根目录CC=${CMAKE_C_COMPILER} # 库编译时采用的C标志AR=${CMAKE_AR} # 库连接时采用的C连接标志CFLAGS=${external_project_cflags} # 库编译时采用的外部标志INSTALL_COMMAND "" # 库的安装指令BUILD_BYPRODUCTS ${MYLIB_LIB_DIR}/libmylib.a # 编译之后存放的文件)# 创建一个我们的应用程序可以链接的包装器CMake库add_library(mylib_lib STATIC IMPORTED GLOBAL)# mylib_lib目标依赖于mylib_project的目标执行add_dependencies(mylib_libmylib_project)# 设置mylib_lib的IMPORTED_LOCATION属性为生成的静态库set_target_properties(mylib_lib PROPERTIES IMPORTED_LOCATION ${MYLIB_LIB_DIR}/libmylib.a)# 设置mylib_lib的INTERFACE_INCLUDE_DIRECTORIES属性为头文件路径set_target_properties(mylib_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${MYLIB_INCLUDE_DIR})# 连接生成的库到应用程序target_link_libraries(app PUBLIC mylib_lib)
