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})
...
-- 指定安装时运行规则
install(DIRECTORY src/lualib DESTINATION ${APP_INSTALL_DIR} OPTIONAL)
...若为定制组件,则在通用组件配置的基础上,新增定制组件构建项
## customized resource deployment options
set(CUSTOMER new_app)
set(CUSTOM_INSTALL_DIR opt/bmc/extend/${CUSTOMER})
-- 定制仓所需的sr等文件/目录
install(DIRECTORY sr DESTINATION ${CUSTOM_INSTALL_DIR} OPTIONAL)
...
message(STATUS "new_app customized resource deployment is completed.")二、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 包结构
可通过conan cache path <组件名>获取Conan生成的包所存在的具体目录,构建生成的每一个Conan包都会包含五个重要文件夹,每个文件夹都在confile类中有对应同名的方法。
e: 用于存储包的文件夹,export方法的默认目标文件夹。es: 在conanfile.py文件定义的类中,使用exports_sources方法copy的文件默认存放于此文件夹中。s: 存储源码文件,source方法的默认目标文件夹。b: 完成实际源代码编译的文件夹,build方法的默认目标文件夹。p: 最终构建生成的包所在的文件夹,每个不同的二进制配置将有一个子文件夹。package方法的默认目标文件夹。
三、组件构建操作(bingo gen/build)
在构建组件时,我们需要切换到组件目录,执行bingo命令,否则bingo命令不生效,这里以iam组件作为示例,演示组件的构建流程。一般默认通过git仓库获取组件源码仓,即从gitcode openUBMC社区获得仓库克隆链接,具体克隆方式不在此详述。
请注意通过非git渠道获取的组件源码仓,需要在仓库目录下执行git init完成git初始化,否则无法执行部分bingo命令。
获取帮助
进入到iam的源码目录,执行bingo --help命令来查看支持的构建参数
root@dev:/home/workspace/forks/iam# bingo --help
[2026-11-05 17:21:36,612 INFO] cli.py:643 Component commands
[2026-11-05 17:21:36,612 INFO] cli.py:687 build 构建出包
[2026-11-05 17:21:36,612 INFO] cli.py:687 deploy 将组件及其依赖部署至temp/rootfs目录
[2026-11-05 17:21:36,612 INFO] cli.py:687 test 构建DT.
[2026-11-05 17:21:36,612 INFO] cli.py:687 gen 代码自动生成,支持Lua和C语言,C组件需要在service.json中添加`"language": "c",`配置.
[2026-11-05 17:21:36,612 INFO] cli.py:687 git_history 获取指定开始时间与结束时间之间提交信息,并生成release note
[2026-11-05 17:21:36,612 INFO] cli.py:643 Misc commands
[2026-11-05 17:21:36,612 INFO] cli.py:687 help 获取命令帮助
[2026-11-05 17:21:36,612 INFO] cli.py:687 config bingo参数配置
[2026-11-05 17:21:36,613 INFO] cli.py:687 skill 技能管理
[2026-11-05 17:21:36,613 INFO] cli.py:687 deps 安装系统依赖
[2026-11-05 17:21:36,613 INFO] cli.py:687 schema_validate 对指定目录下所有yaml/json文件或指定yaml/json文件进行 schema 规范检查
[2026-11-05 17:21:36,613 INFO] cli.py:687 hpm_signer HPM 文件重签名
[2026-11-05 17:21:36,613 INFO] cli.py:687 simple_sign 使用简易https签名服务器进行文件签名
[2026-11-05 17:21:36,613 INFO] cli.py:687 new 创建组件
[2026-11-05 17:21:36,613 INFO] cli.py:687 build_full 获取组件源码并构建出组件的全量二进制
[2026-11-05 17:21:36,613 INFO] cli.py:687 asan_log_scan ASAN 内存问题扫描(识别代码仓内的内存泄漏/越界)
[2026-11-05 17:21:36,613 INFO] cli.py:687 analysis 依赖和接口分析
[2026-11-05 17:21:36,613 INFO] cli.py:687 json_check json 文件检查
[2026-11-05 17:21:36,613 INFO] cli.py:687 qemu 拉起qemu仿真环境, 自动准备qemu工具与openUBMC镜像并前台启动
[2026-11-05 17:21:36,613 INFO] cli.py:687 upgrade 升级 bingo 版本
[2026-11-05 17:21:36,613 INFO] cli.py:643 Studio commands
[2026-11-05 17:21:36,613 INFO] cli.py:687 check CSR 语法正确性与模型一致性检查
[2026-11-05 17:21:36,613 INFO] cli.py:687 studio 执行bmc studio启动停止操作
[2026-11-05 17:21:36,613 INFO] cli.py:647
[2026-11-05 17:21:36,613 INFO] cli.py:651 输入 "bingo <command> -h" 获取子命令帮助在上面返回的结果中,我们只使用到部分,build,gen为主要使用的命令,下面主要介绍这两条命令
代码自动生成(bingo gen)
gen命令基于模型配置来自动生成代码/更新生成的代码/校验接口一致性,现在组件的代码都是使用此工具来自动生成,由gen自动生成之后才能完成构建,所以这里先讲gen命令,查看gen命令的help菜单:
root@dev:/home/workspace/forks/iam# bingo gen --help
usage: bingo gen/支持C、C++和Lua语言代码生成 [-h] [-v VERSION] [-r REMOTE] [-s SERVICE_FILE] [-w]
代码自动生成.
options:
-h, --help show this help message and exit
-v VERSION, --version VERSION
use specified version
-r REMOTE, --remote REMOTE
conan remote, 如不设置则默认读取本地conan配置
-s SERVICE_FILE, --service_file SERVICE_FILE
Service file
-w, --with_template generate with template可以看到这个命令的参数结构相对比较简单,建立好模板文件,使用如下命令即可生成代码,即bingo gen -bt debug --stage rc:
root@dev:/home/workspace/forks/iam# bingo gen -bt debug --stage rc
# -bt debug: 构建类型
# --stage rc: 预发布包
# 如果在mds目录下配置了model.json,则带上-w参数来进行模板生成
# 截取最后部分日志如下,没有发生报错,则表示自动生成成功
[2026-11-05 19:11:00,485 INFO] template.py:163 >> python3 /home/workspace/forks/iam/temp/lua_codegen/script/lua_format.py /home/workspace/forks/iam/gen/iam/orm_classes.lua
mkdir -p /home/workspace/forks/iam/temp/lua_codegen/temp/iam/features/
rm -rf /home/workspace/forks/iam/temp/lua_codegen/../../temp/plugin
python3 /home/workspace/forks/iam/temp/lua_codegen/script/gen_feature_json.py -i /home/workspace/forks/iam/temp/lua_codegen/temp/iam/_model.json -o /home/workspace/forks/iam/temp/lua_codegen/temp/iam/features/ -n iam -f
make[3]: Leaving directory '/home/workspace/forks/iam/temp/lua_codegen/templates/apps'
make[2]: Leaving directory '/home/workspace/forks/iam/temp/lua_codegen/templates'
make[1]: Leaving directory '/home/workspace/forks/iam/temp/lua_codegen'构建命令(bingo build)
openUBMC的工程工具实现了CMake和Conan工具的相关文件自动生成。同时,支持CLI命令一键完成组件的构建,运行bingo build命令所执行的整个构建流程可以描述为:
- 主动生成
conanbase.py文件。组件的conanfile.py文件继承自conanbase.py定义的类conanbase。 - 根据命令参数获取交叉编译所需的配置信息。
- 清除组件锁文件,对于组件在
service.json文件中未指明特定版本的依赖,使用最新版本的依赖包。 - 执行
conan create命令,依据conanfile.py文件实现构组件定制化构建出包。
bingo build命令的相关参数如下:
Build conan
options:
-h, --help show this help message and exit
-bt BUILD_TYPE, --build_type BUILD_TYPE
构建类型,可选:debug, release
默认:debug
--stage STAGE 组件包发布阶段, 可选: ['dev', 'pre', 'rc', 'stable']
默认:dev
-u, --upload 上传组件包到conan仓
-r REMOTE, --remote REMOTE
conan仓别名,请检查conan remote list查看已配置的conan仓
--conan2 强制使用conan2构建组件,此参数仅用于临时兼容组件conan1和conan2构建场景
-nc, --no_cache 强制更新conan缓存依赖
-o OPTIONS, --options OPTIONS
Define options values (host machine), e.g.: -o Pkg/*:with_qt=True; 组件二进制调试保留开关: -o 'Pkg/*:no_strip=True',默认 False,可由组件覆写
--user USER 指定conan包的user字段,未指定时依次尝试读取mds/service.json的user字段,都未指定时使用'openubmc'
-wb, --without_build 不强制源码构建组件自身
--ccache 使用 ccache 加速 C/C++ 编译bingo build相关的参数有很多,常需要使用的参数只有其中几个,以具体实例来讲解:
# -b Openubmc: 指定单板名,某些组件和单板名挂钩,需要指定单板名来打入某些文件,如果组件和单板无关,不带此参数
# -bt debug: 构建类型,调试包
# --stage rc: 预发布包
bingo build -b Openubmc -bt debug --stage rc
# 截取部分日志放如下
iam/1.140.4@openubmc/rc: Created package revision 7160200fcfbda08eea20470a460a63dc
iam/1.140.4@openubmc/rc: Package '946abd1454eb585d02b9f4d8766f3e74f3d4b750' created
iam/1.140.4@openubmc/rc: Full package reference: iam/1.140.4@openubmc/rc#f2704a56483dd41f9eb9a84ce01d9f4f:946abd1454eb585d02b9f4d8766f3e74f3d4b750#7160200fcfbda08eea20470a460a63dc
iam/1.140.4@openubmc/rc: Package folder /root/.conan2/p/b/iama9b8a57790aa5/p
...
[2026-11-05 19:45:02,508 INFO] cli.py:190 构建成功在日志最后的“构建成功”上方数行,能看到编译完成的版本号,这个版本号就是生成的组件版本,详细文件可见下文查找构建生成文件
简单而言,bingo build命令集成了Conan和CMake工具的使用,实现组件自动化编译出包。 开发者进行个人开发时,使用bingo build命令生成的组件Conan包,将会存放于本地的root/.conan2/p目录下。
四、查找构建生成文件
Conan2
组件下执行bingo build默认发布阶段为dev,此时通过cd ~/.conan2/p可进入到生成组件文件夹。需要找到之前构建完成的iam组件conan包,可以通过conan cache path iam/1.140.4@openubmc/rc命令查询其本地conan包配方文件夹,示例如下:
root@dev:/home/workspace/forks/iam# conan cache path iam/1.140.4@openubmc/rc
/root/.conan2/p/iamf2056c30d9ee0/e通过conan cache path iam/1.140.4@openubmc/rc命令查询其本地conan制品文件夹,示例如下:
root@dev:/home/workspace/forks/iam# conan cache path iam/1.140.4@openubmc/rc#f2704a56483dd41f9eb9a84ce01d9f4f:946abd1454eb585d02b9f4d8766f3e74f3d4b750#7160200fcfbda08eea20470a460a63dc
/root/.conan2/p/b/iama9b8a57790aa5/pbingo会根据组件的conanfile.py或者conanbase.py文件,会构建生成对应的conan文件,其中:
e: 用于存储包的文件夹,export方法的默认目标文件夹。es: 在conanfile.py文件定义的类中,使用exports_sources方法copy的文件默认存放于此文件夹中。s: 存储源码文件,source方法的默认目标文件夹。b: 完成实际源代码编译的文件夹,build方法的默认目标文件夹。p: 最终构建生成的包所在的文件夹,每个不同的二进制配置将有一个子文件夹。package方法的默认目标文件夹。
Conan1(已不再维护)
组件下执行bingo build默认发布阶段为dev,此时通过cd ~/.conan/data/<组件名>/<版本号>/hw.ibmc.dev/dev可进入到生成组件文件夹。
bingo会根据组件的conanfile.py或者conanbase.py文件,会构建生成对应的conan文件,其中:
source文件夹中是构建的源代码文件,在文件的source()方法中定义,如果没有定义,会默认复制文件同层文件和文件夹。export_source文件夹是导出的source中的文件,在文件的exports_sources中配置相关信息。build文件夹是构建源代码生成的文件,是根据文件中build方法配置构建信息package文件夹中是打包构建后的代码,在文件的package方法中配置打包信息。- 在metadata.json文件中,可以查看生成文件的recipe哈希值、包的唯一标志符以及包的修订哈希值,它用于跟踪包的变化。可通过此编号在conan仓中找到上传组件信息。
五、组件测试
对于openUBMC的各个组件来说,它们在开发阶段就具备了独立测试的能力。开发者进行的测试可以显著减少版本集成后的缺陷,并减少后期定位缺陷的成本。开发者编写的测试代码与业务代码具有同等的重要性。当前openUBMC DT测试框架主要涵盖的场景包括单元测试和集成测试。
openUBMC的工程工具实现了CLI工具以执行组件测试,在组件目录下执行bingo test -h,查看其涉及的参数:
root@dev:/home/workspace/forks/iam# bingo test -h
Test component
options:
-h, --help show this help message and exit
-bt BUILD_TYPE, --build_type BUILD_TYPE
构建类型,可选:debug, release 默认:debug
--stage STAGE 组件包发布阶段, 可选: ['dev', 'pre', 'rc', 'stable'] 默认:dev
-r REMOTE, --remote REMOTE
conan仓别名,请检查conan remote list查看已配置的conan仓
--conan2 强制使用conan2构建组件,此参数仅用于临时兼容组件conan1和conan2构建场景
-s, --from_source Build from source, include dependency component
-nc, --no_cache 强制更新conan缓存依赖
-o OPTIONS, --options OPTIONS
Define options values (host machine), e.g.: -o Pkg/*:with_qt=True; 组件二进制调试保留开关: -o 'Pkg/*:no_strip=True',默认 False,可由组件覆写
--user USER 指定conan包的user字段,未指定时依次尝试读取mds/service.json的user字段,都未指定时使用'openubmc'
-as, --asan Enable address sanitizer
-ct, --clang_tidy 启用clang-tidy代码静态检查
-wb, --without_build 不强制源码构建组件自身
-pr PROFILE, --profile PROFILE
显式指定conan构建使用的profile文件 (~/.conan/profiles目录下)别名, 默认为: 空 可选值: profile_oee.ini, profile.ini, profile.luajit.ini, profile.dt.ini, default
-jit, --enable_luajit
Enable luajit
--ccache 使用 ccache 加速 C/C++ 编译
-ut, --unit_test Enable unit test
-it, --integration_test
Enable integration test
-ft, --fuzz_test Enable fuzz test
-fg, --fuzz_gen Generate fuzz case
-mt, --mock_test Enable mock test
-mg, --mock_gen Generate mock case
-lf LOG_FILE, --log_file LOG_FILE
Monitor log file directory path
-cnt FUZZ_COUNT, --fuzz_count FUZZ_COUNT
Fuzz count
-f TEST_FILTER, --test_filter TEST_FILTER
Run unit test with a filter
-a APP, --app APP App in hica
--coverage_exclude COVERAGE_EXCLUDE
Specify coverage exclude file path of whitelist
--minimum, -m 获取dt构建的最小版本
--package_info PACKAGE_INFO, -pi PACKAGE_INFO
package_info 文件路径, 使用manifest配套版本dt构建, 此文件在manifest构建时会在inner目录生成其中,bingo test -ut和bingo test -it分别单元测试和集成测试的运行命令,也是开发人员最常用的测试命令。此外可参考组件的独立测试查看详细的测试设计。
六、组件发布
组件制品发布到Conan仓
要将组件的修改合入最新的整包制品中,首先需要将组件制品发布到Conan仓中。openUBMC社区当前提供下述两种方法进行组件的发布。
- PR 合入之前评论
/publish:PR 合入后自动触发组件构建 ,即由流水线执行conan upload将制品发布到社区中心仓,成功后openUBMC-robot在 PR 下评论 "This component has been successfully published."即为发布成功。 - openlibing 平台手动触发流水线(仅 maintainer/committer):在openlibing中的构建-流水线下找到
PublishComponent,选择仓库和分支后可以手动触发发布流水线,效果与方案一一致。
值得注意的是,组件支持同版本重复发布,同一版本号下重复发布由产生的 recipe revision 区分不同的制品。recipe revision由组件的源码与构建时由bingo生成的配方共同决定。完成发布后可以通过如下方式查看社区中心仓中新发布的组件制品:
conan search "<组件名>/" -r openubmc_opensource查询所有该组件的制品conan list "<组件名>/<版本>@openubmc/stable#*" -r openubmc_opensource查询所有该组件特定版本号下的revision
以bios组件为例:
root@dev:/home/workspace# conan search "bios/" -r openubmc_opensource
Found 89 pkg/version recipes matching bios/ in openubmc_opensource
openubmc_opensource
bios
bios/1.80.54@openubmc/stable
bios/1.80.55@openubmc/stable
bios/1.80.56@openubmc/stable
#...只截取部分
root@dev:/home/workspace# conan list "bios/1.110.33@openubmc/stable#*" -r openubmc_opensource
openubmc_opensource
bios
bios/1.110.33@openubmc/stable
revisions
b3fd933fe31e7dc6f81fe4e6a2e89133 (2026-11-05 16:56:22 UTC)组件制品更新到manifest
发布到 Conan 仓只是组件可被公开获取了,产品是否集成这个版本的组件是由 manifest 仓的版本锁定机制(lockfile)决定的。manifest仓中lockfile 有两份:build/openubmc.lock与 build/sdk/openubmc_sdk.lock,构建时 bingo 会通过 conan lock merge 合并两份。
lockfile 更新命令
lockfile文件支持通过bingo lock实现交互式更新,按如下方式按需要更新lockfile以选择在产品中指定特定组件版本:
# 首次生成/覆盖本地 lockfile(manifest 根目录执行)
bingo lock -c
# 更新单个组件锁;
cd build/sdk
bingo lock -u <组件名> -r openubmc_opensourcebingo lock -u命令效果如下:查询当前需要更新的组件在lockfile中存在版本,选择A更新版本或B版本不变仅更新revision。A = 更新版本号,替换为仓库中最满足 range 的版本。B = 自动查询对应版本号下所有conan仓中的revision,要求用户输入需要更新到的revision。具体示例可以参考bingo支持产品使用lockfile构建