openUBMC integrates the Conan package manager with the CMake build system to achieve independent build and release of components. Conan is a C/C++ build framework composed of commands, attributes, and methods. It is primarily responsible for encapsulating and providing consistent external interfaces and completing component delivery based on the Conan repository. CMake defines how to generate executables or libraries from source code, and its main task is managing the project build process. For details about CMake, see the CMake Official Documentation. For details about Conan, see the Conan Official Documentation.
The build process of an openUBMC component consists of CMake script cmakelists.txt and Conan scripts conaninfo.py, conanfile.py, and conanbase.py:
CMakeLists.txt: CMake build configuration file used to define build rules, dependencies, and compilation options for the project, simplifying the compilation and build process.conaninfo.py: defines basic Conan information, including the package name, version number, and Git repository.conanbase.py: defines the unified Conan build script.conanfile.py: Conan script that inherits fromconanbase.pyand can override methods inconanbase.
Basic Usage of CMake
CMake is an open-source cross-platform software tool for software build automation and management using a compiler-independent method. It supports directory hierarchies and applications that depend on multiple function libraries.
All CMake statements are written in a CMakeLists.txt file. Once the CMakeLists.txt file is finalized, run the cmake command directly in the directory containing CMakeLists.txt. CMake then automatically generates a Makefile. You can then run the make command to compile and build the results.
In simpler terms, CMake exists to generate a Makefile. Developers do not need to write the Makefile themselves. They only need to write a simple CMakeLists.txt. Developers can add references to required C/C++ libraries in CMakeLists.txt.
The following example uses the CMakeLists.txt of the new_app component to introduce the CMake commands used in openUBMC:
-- Minimum CMake version requirement
cmake_minimum_required(VERSION 3.14)
-- Set the project name. You can add supported languages later. The default languages are C and C++.
project(new_app)
-- Find the PkgConfig module and use it to find the desired third-party libraries.
find_package(PkgConfig REQUIRED)
-- Used to find library information in PkgConfig format.
pkg_search_module(GLIB REQUIRED glib-2.0)
...
-- Set variable values.
set(TARGET_LIB ${PROJECT_NAME})
...
-- Specify rules for running during installation.
install(DIRECTORY src/lualib DESTINATION ${APP_INSTALL_DIR} OPTIONAL)
...For custom components, add custom build items based on the general component configuration:
## customized resource deployment options
set(CUSTOMER new_app)
set(CUSTOM_INSTALL_DIR opt/bmc/extend/${CUSTOMER})
-- SR files or directories required for the customized repository
install(DIRECTORY sr DESTINATION ${CUSTOM_INSTALL_DIR} OPTIONAL)
...
message(STATUS "new_app customized resource deployment is completed.")Introduction to Conan
Conan is an open-source C/C++ package manager used to download, manage, and build dependency libraries required by projects. Simply put, Conan can act as both a package user and a package creator. It uses the conanfile.py file to automate package building. In openUBMC, Conan is integrated with the CMake build tool to achieve project compilation and building.
The conanfile.py file must define a class that inherits from ConanFile. This class includes two parts: attributes and methods. Attributes are used to set read-only information, while methods are used for automated packaging logic. After writing the conanfile.py file, run the conan create command of the Conan tool. The system automatically executes the methods of the ConanFile class in the following order by default:
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()The following introduces methods like export, generate, build, and package defined in conanbase. The functions of these methods are as follows:
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" # Define package name.
version = "0.0.1"
url = "https://www.huawei.com"
settings = "os", "compiler", "build_type", "arch" # Define configurations for different binary packages. Any modification to the definitions of the OS, compiler, build type, or architecture will generate a different binary package.
generators = "cmake"
language = "lua"
_cmake = None
_codegen_version = 14
scm = {
"type": "git",
"url": "",
"revision": "auto"
}
options = { # Package-specific configurations. Default values can be defined in default_options.
"asan": [True, False],
"gcov": [True, False],
"manufacture": [True, False],
}
default_options = {
"asan": False,
"gcov": False,
"manufacture": False,
}
def generate(self):
# Creates a conan_toolchain.cmake file that maps Conan and CMake syntax.
...
# During building, this method automatically generates the export directory.
def export(self):
# This method defines copy of files to the export directory.
...
def requirements(self):
# References dependency packages for the component.
...
# During building, this method automatically generates the build directory.
def build(self):
# Calls the build method under cmake, which is equivalent to running the cmake build command to complete the entire process from preprocessing to linking.
...
cmake = self._configure_cmake()
cmake.build()
# During building, this method automatically generates the package directory.
def package(self):
# Runs the cmake install command and moves compiled files to the specified location based on the install command in the CMakeLists.txt file.
cmake = self._configure_cmake()
cmake.install()
...The bingo engineering tool of openUBMC integrates the function of automatically generating conanbase.py in the bingo build command. This file defines the conanbase class, which inherits from ConanFile and implements basic build methods. Therefore, in the conanfile.py file of each component, you only need to define a class that inherits from conanbase. If you need to customize package files, you can override relevant methods in the class defined in conanfile.py.
The settings field of the conanfile.py file defines configurations for different binary packages. In this example, any modification to the OS, compiler, build type, or architecture will generate a different binary package. The values of these configuration items are centrally stored in the profile file. During building, the Conan tool obtains all information from the configuration file based on the set --profile parameter and applies it to the package to be built or installed. If this parameter is not specified, it is equivalent to calling --profile=default.
When you run a command to build a package in the component directory, a Conan package named in the format <package name>/<version>@<user>/<channel> is generated.
You can run conan cache path <component name> to obtain the specific directory where the Conan generated package is located. Each generated Conan package contains five important folders, each corresponding to a method of the matching name in the ConanFile class.
e: stores the package, which is the default target folder for theexportmethod.es: stores files copied using theexports_sourcesmethod in the class defined inconanfile.pyby default.s: stores source code files, which is the default target folder for thesourcemethod.b: completes actual source code compilation, which is the default target folder for thebuildmethod.p: stores the the final built package. Each different binary configuration will have a subfolder. It is the default target folder for thepackagemethod.
Build and Release
The engineering tool of openUBMC automates the generation of relevant files for CMake and Conan tools. It also supports one-click component building through CLI commands. The entire build process executed by running the bingo build command can be described as follows:
- Automatically generates the
conanbase.pyfile. Theconanfile.pyfile of the component inherits from theconanbaseclass defined inconanbase.py. - Obtains configuration information required for cross-compilation based on command parameters.
- Clears component lock files. For component dependencies not specifying a version in the
service.jsonfile, the latest version of the dependency package is used. - Runs the
conan createcommand to achieve customized component building and packaging according to theconanfile.pyfile.
The relevant options of the bingo build command are as follows:
Build conan
optional arguments:
-h, --help show this help message and exit
-bt BUILD_TYPE, --build_type BUILD_TYPE
Build type. Options: dt, debug, release
Default value: debug
--stage STAGE Component package release stage. Options: dev (developer), pre, rc, stable
Default value: dev
-r REMOTE, --remote REMOTE
Conan repository alias. Run conan remote list to view configured Conan repositories.
Default value: openUBMC_dev
-nc, --no_cache Does not use the cache package in the ~/.conan/data directory (deletes the cache before building).
-o OPTIONS, --options OPTIONS
Define options values (host machine), e.g.: -o Pkg:with_qt=true
--user USER Specifies the user field for the Conan package. Attempts to read the conan.user field from the /etc/bingo.conf file. Otherwise, it is managed by the program.
-as, --asan Enable address sanitizerThe bingo build command integrates the use of Conan and CMake tools to achieve automated component compilation and packaging. For individual development, the component Conan package generated by this command will be released and stored in the local root/.conan2/p directory.