openUBMC采用Conan
包管理器与CMake
构建系统集成的方式,实现组件的独立构建和发布。Conan
是一个C
/C++
构建框架,由命令、属性和方法构成,主要负责封装并对外提供一致的接口,并基于Conan
仓库完成组件交付。CMake
定义了如何从源代码生成可执行文件或库,主要任务是负责项目的构建过程。关于CMake
的详细介绍请参考Cmake官方文档;Conan
的详细介绍请参考Conan官方文档。
openUBMC组件构建由CMake
脚本cmakelists.txt
和Conan
脚本conaninfo.py
、conanfile.py
以及conanbase.py
组成:
cmakelists.txt
:CMake
构建配置文件,用于定义项目的构建规则、依赖关系、编译选项等,简化项目的编译和构建过程。conaninfo.py
:定义了Conan
基本信息,包括包名,版本号和git仓。conanbase.py
:定义了统一的Conan
构建脚本。conanfile.py
:Conan
脚本,继承自conanbase.py
,可以重写conanbase
的方法。
CMake基本使用
CMake
是一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个函数库。
CMake
的所有语句都写在一个CMakeLists.txt
的文件中。CMakeLists.txt
文件确定后,直接使用Cmake命令运行CMakeLists.txt
所在的目录,Cmake之后就会自动生成makefile文件,然后再直接make就可以编译出构建结果。
更简单的解释就是CMake
是为了生成Makefile
而存在,开发者不需要自己去写Makefile
,只需要写简单的CMakeLists.txt
即可。开发者可以在CMakeLists.txt
中添加引用所需的C
/C++
库。
这里,以组件new_app
的CMakeLists.txt
为例,简单介绍openUBMC中用到的CMake
指令:
-- cmake最低版本需求
cmake_minimum_required(VERSION 3.14)
-- 设置项目名称,后面可添加支持的语言,默认是C和C++
project(new_app)
-- 查找PkgConfig模块,通过PkgConfig模块找到你想要找到的第三方库
find_package(PkgConfig REQUIRED)
-- 用于查找PkgConfig格式的库信息
pkg_search_module(GLIB REQUIRED glib-2.0)
...
-- 设置变量的值
set(TARGET_LIB ${PROJECT_NAME})
...
-- 告诉CMake使用Conan生成的文件,这将包含Conan生成的conanbuildinfo.cmake文件,并进行基本的设置。
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
-- 指定安装时运行规则
install(DIRECTORY src/lualib DESTINATION ${APP_INSTALL_DIR} OPTIONAL)
...
Conan基本介绍
Conan
是一个开源的C/C++
包管理器,用于下载、管理和构建项目所需的依赖库。简单来说,Conan
可以作为包的使用者和包的创建者,它使用conanfile.py
文件自动化实现构建出包。在openUBMC中,Conan
与CMake
构建工具集成实现项目的编译和构建。
conanfile.py
文件需定义一个继承自ConanFile
的类。这个类包括两个部分:属性和方法。属性用于设置一些只读信息而方法用于自动化打包的逻辑。在编写完conanfile.py
文件之后,执行Conan
工具的conan create
命令会默认按照以下顺序自动执行conanfile类的方法:
1. export()
2. export_sources()
3. config_options()
4. configure()
5. layout()
6. requirements()
7. package_id()
8. validate()
9. validate_build()
10. build_requirements()
11. build_id()
12. system_requirements()
13. source()
14. generate()
15. imports()
16. build()
17. package()
18. package_info()
这里简单介绍conanbase
中定义的export
、generate
、build
和package
等方法。各方法的函数体功能简要介绍如下
import os
import stat
import urllib3
from conans import ConanFile, CMake
from bingo.component.gen import GenComp
urllib3.disable_warnings()
class ConanBase(ConanFile):
name = "new_app" #定义包名
version = "0.0.1"
url = "https://www.huawei.com"
settings = "os", "compiler", "build_type", "arch" # 定义不同二进制包的配置。对操作系统、编译器、构建类型或架构定义的任何修改都将生成不同的二进制包。
generators = "cmake"
language = "lua"
_cmake = None
_codegen_version = 14
scm = {
"type": "git",
"url": "",
"revision": "auto"
}
options = { # 包特定的配置,可以在default_options中定义默认值
"asan": [True, False],
"gcov": [True, False],
"manufacture": [True, False],
}
default_options = {
"asan": False,
"gcov": False,
"manufacture": False,
}
def generate(self):
# 执行将创建一个映射Conan和CMake语法的conan_toolchain.cmake文件
...
# 构建时,此方法会自动生成export目录
def export(self):
# 此方法定义拷贝文件到export目录
...
def requirements(self):
# 引用组件的依赖包
...
# 构建时,此方法会自动生成build目录
def build(self):
# 主要调用了cmake下的build方法,相当于执行了cmake build命令,完成从预处理到链接的全部过程
...
cmake = self._configure_cmake()
cmake.build()
# 构建时,此方法会自动生成package目录
def package(self):
# 执行了cmake install命令,根据cmakelists.txt文件当中的install命令将编译生成后的文件移动到指定位置
cmake = self._configure_cmake()
cmake.install()
...
openUBMC的工程工具bingo
在构建命令bingo build
中集成了自动生成conanbase.py
的功能。此文件定义了继承自ConanFile
的类conanbase
,并在此类中已实现基本的构建方法。因此,在各组件的conanfile.py文件中,只需定义继承自conanbase的类即可。若开发者需要自定义构建出包文件,可在conanfile.py
文件定义的类中重写相关方法。
conanfile.py
文件的settings
字段定义了不同二进制包的配置。在此示例中,对操作系统、编译器、构建类型或架构定义的任何修改都将生成不同的二进制包。这些配置信息的值都统一存放于profile
文件中。在执行构建时,Conan
工具会根据设置的–profile
参数获取配置文件中的所有信息,并应用于要构建或安装的软件包。如果没有指定该参数,相当于使用–profile=default
进行调用。
在组件目录下执行命令构建包时,会生成以<包名>/<版本>@<用户>/<渠道>
格式命名的Conan
包,并存放在~/.conan/data
路径下。开发者可以通过所需依赖的组件包名定义依赖等。
Conan
生成的包将会存放在~/.conan/data
目录下,构建生成的每一个Conan
包都会包含五个重要文件夹,每个文件夹都在confile
类中有对应同名的方法。
export
: 用于存储包的文件夹。export_source
: 在conanfile.py
文件定义的类中,使用exports_sources
方法copy
的文件默认存放于此文件夹中。source
: 存储源码文件。build
: 完成实际源代码编译的文件夹。package
: 最终构建生成的包所在的文件夹。每个不同的二进制配置将有一个子文件夹。
构建、发布
openUBMC的工程工具实现了CMake
和Conan
工具的相关文件自动生成。同时,支持CLI命令一键完成组件的构建,运行bingo build
命令所执行的整个构建流程可以描述为:
- 主动生成
conanbase.py
文件。组件的conanfile.py
文件继承自conanbase.py
定义的类conanbase
。 - 根据命令参数获取交叉编译所需的配置信息。
- 清除组件锁文件,对于组件在
service.json
文件中未指明特定版本的依赖,使用最新版本的依赖包。 - 执行
conan create
命令,依据conanfile.py
文件实现构组件定制化构建出包。
bingo build
命令的相关参数如下:
Build conan
optional arguments:
-h, --help show this help message and exit
-bt BUILD_TYPE, --build_type BUILD_TYPE
构建类型,可选:dt,debug,release
默认:debug
--stage STAGE 组件包发布阶段, 可选: dev(developer), pre, rc, stable
默认:dev
-r REMOTE, --remote REMOTE
conan仓别名,请检查conan remote list查看已配置的conan仓
默认: openUBMC_dev
-nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存)
-o OPTIONS, --options OPTIONS
Define options values (host machine), e.g.: -o Pkg:with_qt=true
--user USER 指定conan包的user字段,尝试从/etc/bingo.conf文件读取conan.user字段,否则由程序管理
-as, --asan Enable address sanitizer
bingo build
命令集成了Conan
和CMake
工具的使用,实现组件自动化编译出包。 开发者进行个人开发时,使用此命令生成的组件Conan
包,将会发布并存放于本地的root/.conan/data
目录下。