代码仓
中
组件的构建与发布
更新时间: 2026/11/12
在AtomGit上查看源码

openUBMC采用Conan包管理器与CMake构建系统集成的方式,实现组件的独立构建和发布。Conan是一个C/C++构建框架,由命令、属性和方法构成,主要负责封装并对外提供一致的接口,并基于Conan仓库完成组件交付。CMake定义了如何从源代码生成可执行文件或库,主要任务是负责项目的构建过程。关于CMake的详细介绍请参考Cmake官方文档;Conan的详细介绍请参考Conan官方文档。

openUBMC组件构建由CMake脚本cmakelists.txt和Conan脚本conaninfo.py、conanfile.py以及conanbase.py组成:

  1. cmakelists.txt:CMake构建配置文件,用于定义项目的构建规则、依赖关系、编译选项等,简化项目的编译和构建过程。
  2. conaninfo.py:定义了Conan基本信息,包括包名,版本号和git仓。
  3. conanbase.py:定义了统一的Conan构建脚本。
  4. 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最低版本需求
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)
...

若为定制组件,则在通用组件配置的基础上,新增定制组件构建项

cmake
## 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类的方法:

python
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等方法。各方法的函数体功能简要介绍如下

python
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命令来查看支持的构建参数

shell
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菜单:

shell
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:

shell
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命令所执行的整个构建流程可以描述为:

  1. 主动生成conanbase.py文件。组件的conanfile.py文件继承自conanbase.py定义的类conanbase。
  2. 根据命令参数获取交叉编译所需的配置信息。
  3. 清除组件锁文件,对于组件在service.json文件中未指明特定版本的依赖,使用最新版本的依赖包。
  4. 执行conan create命令,依据conanfile.py文件实现构组件定制化构建出包。

bingo build命令的相关参数如下:

shell
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相关的参数有很多,常需要使用的参数只有其中几个,以具体实例来讲解:

shell
# -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包配方文件夹,示例如下:

shell
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制品文件夹,示例如下:

shell
root@dev:/home/workspace/forks/iam# conan cache path iam/1.140.4@openubmc/rc#f2704a56483dd41f9eb9a84ce01d9f4f:946abd1454eb585d02b9f4d8766f3e74f3d4b750#7160200fcfbda08eea20470a460a63dc
/root/.conan2/p/b/iama9b8a57790aa5/p

bingo会根据组件的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,查看其涉及的参数:

shell
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社区当前提供下述两种方法进行组件的发布。

  1. PR 合入之前评论 /publish:PR 合入后自动触发组件构建 ,即由流水线执行 conan upload 将制品发布到社区中心仓,成功后 openUBMC-robot 在 PR 下评论 "This component has been successfully published."即为发布成功。
  2. openlibing 平台手动触发流水线(仅 maintainer/committer):在openlibing中的构建-流水线下找到 PublishComponent ,选择仓库和分支后可以手动触发发布流水线,效果与方案一一致。

值得注意的是,组件支持同版本重复发布,同一版本号下重复发布由产生的 recipe revision 区分不同的制品。recipe revision由组件的源码与构建时由bingo生成的配方共同决定。完成发布后可以通过如下方式查看社区中心仓中新发布的组件制品:

  1. conan search "<组件名>/" -r openubmc_opensource 查询所有该组件的制品
  2. conan list "<组件名>/<版本>@openubmc/stable#*" -r openubmc_opensource 查询所有该组件特定版本号下的revision

以bios组件为例:

shell
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以选择在产品中指定特定组件版本:

bash
# 首次生成/覆盖本地 lockfile(manifest 根目录执行)
bingo lock -c

# 更新单个组件锁;
cd build/sdk
bingo lock -u <组件名> -r openubmc_opensource

bingo lock -u命令效果如下:查询当前需要更新的组件在lockfile中存在版本,选择A更新版本或B版本不变仅更新revision。A = 更新版本号,替换为仓库中最满足 range 的版本。B = 自动查询对应版本号下所有conan仓中的revision,要求用户输入需要更新到的revision。具体示例可以参考bingo支持产品使用lockfile构建