组件的构建与发布
更新时间:2024/12/16
在Gitcode上查看源码

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

openUBMC组件构建由CMake脚本cmakelists.txtConan脚本conaninfo.pyconanfile.py以及conanbase.py组成:

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

-- 告诉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中,ConanCMake构建工具集成实现项目的编译和构建。

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

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/data路径下。开发者可以通过所需依赖的组件包名定义依赖等。

Conan生成的包将会存放在~/.conan/data目录下,构建生成的每一个Conan包都会包含五个重要文件夹,每个文件夹都在confile类中有对应同名的方法。

  • export: 用于存储包的文件夹。
  • export_source: 在conanfile.py文件定义的类中,使用exports_sources方法copy的文件默认存放于此文件夹中。
  • source: 存储源码文件。
  • build: 完成实际源代码编译的文件夹。
  • package: 最终构建生成的包所在的文件夹。每个不同的二进制配置将有一个子文件夹。

构建、发布

openUBMC的工程工具实现了CMakeConan工具的相关文件自动生成。同时,支持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

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命令集成了ConanCMake工具的使用,实现组件自动化编译出包。 开发者进行个人开发时,使用此命令生成的组件Conan包,将会发布并存放于本地的root/.conan/data目录下。