Bundle Development Specifications
Overview
This document describes the basic concepts of a bundle and how to define it in compliance with specifications.
Definition
OpenHarmony software is developed on a per-bundle basis. In terms of the operating system, all software running on OpenHarmony are bundles. Generally, bundles are classified into the following types based on their application scopes:
- Board-level bundles: device hardware-specific bundles, such as board, arch, and mcu
- System-level bundles: a set of bundles with independent features, such as the kernel, file system, and framework
- Application-level bundles: applications that provide services to users, such as wifi_iot and ip_camera
Bundles are designed for reuse purposes. Any reusable modules can be defined as bundles. They are classified into the following types based on their forms:
- Source code
- Binary system
- Code snippet
- Distribution
Bundle Division Rules
In principle, bundles should be grouped at a fine-grained granularity as much as possible to achieve maximum reuse. The following factors are taken into account regarding bundle division:
- Independence: Bundles provide relatively independent features and can be independently built. Each bundle is capable of providing its own APIs and services for external systems.
- Coupling: If a bundle must depend on another bundle to provide services, they can be coupled to one bundle.
- Correlation: If a group of bundles jointly implement a feature, and if other bundles never depend on them, the group of bundles can be combined into one bundle.
Bundle Dependency
A bundle dependency can be mandatory or optional.
- Mandatory dependency: If bundle A must depend on bundle B to implement a feature (the APIs or services specific to bundle B must be invoked), bundle B is a mandatory dependency of bundle A.
- Optional dependency: If bundle C or bundle D is required for bundle A to implement a feature and bundle C and bundle D are interchangeable, bundle C and bundle D are optional dependencies of bundle A.
Bundle Composition
A bundle contains the following:
-
src directory for storing code files or code library of the bundle
-
ohos_bundles folder for storing dependent bundles (It is automatically generated during bundle installation, without the need to submit to the code library.)
-
README.md file for describing the bundle
-
bundle.json file for declaring metadata of the bundle
-
LICENSE file for open-source code
my-bundle
|_ohos_bundles |_src |_bundle.json |_README.md |_LICENSE ```
Code Files
Bundle code files are the same as those in a common code directory. The only difference lies in the open APIs (declared in header files) of a bundle, which are likely to be referenced by other bundles and need to be declared in dirs of bundle.json.
README File
README.md is a bundle self-description file using the markdown syntax. For details, see Syntax Reference.
To help you easily find and use the desired bundle on the HarmonyOS Package Manager (HPM) platform, a README file is provided in the root directory of each bundle.
The README file may include instructions on how to install, configure, and use the instance code in the bundle, as well as any other information helpful to you.
The README file is available in the bundle details page of the HPM platform.
Metadata Description File
The bundle.json file describes the metadata of a bundle. Each bundle has its own bundle.json file.
{
"name": "@myorg/demo-bundle",
"version": "1.0.0",
"license": "MIT",
"description": "bundle description",
"keywords": ["hos"],
"tags": ["applications", "drivers"],
"author": {"name":"","email":"","url":""},
"contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}],
"homepage": "http://www.foo.bar.com",
"repository": "https://git@gitee.com:foo/bar.git",
"publishAs": "code-segment",
"segment":{
"destPath":"/the/dest/path"
},
"dirs": {
"src": ["src/**/*.c"],
"headers": ["headers/**/*.h"],
"bin": ["bin/**/*.o"]
},
"scripts": {
"build": "make"
},
"envs": {},
"ohos": {
"os": "2.0.0",
"board": "hi3516",
"kernel": "liteos-a"
},
"rom": "10240",
"ram": "1024",
"dependencies": {
"@myorg/net":"1.0.0"
}
}
Each bundle.json file has the following fields:
-
name: a bundle name, which starts with @ and is separated by /, for example, @myorg/mybundle
-
version: a bundle version number, for example, 1.0.0. The version number must comply with the Semantic Versioning Specification (SemVer) standards.
-
description: a brief description of a bundle
-
dependencies: bundles on which this bundle depends.
-
envs: parameters required for bundle compilation, including global parameters and dependency parameters.
-
scripts: commands executable to a bundle, such as commands for compiling, building, testing, and burning
-
publishAs: bundle publishing type, which can be source, binary, distribution, or code-segment
-
segment: destination path of the code-segment bundle. That is, the destination path of the files contained in the bundle package after the bundle is installed.
-
dirs: directory structure (such as the header file) generated for publishing
-
ram&rom: statistical information about the estimated read-only memory (ROM) and random access memory (RAM) usage
-
ohos: mappings among OpenHarmony versions, development boards, and kernels, separated by commas (,).
-
Extended information: author, home page, code repository, license, tags, and keywords
-
base (only for a distribution): a base distribution which others inherit from.
Bundle Management
Dependency
A basic bundle.json file needs to be enriched by bundle dependencies to implement more complex features. Bundle names and version numbers should be defined in the dependencies field of bundle.json.
{
"name": "my-bundle",
"version": "1.0.0",
"dependencies": {
"net": "1.0.0"
}
}
In the preceding example, the my-bundle bundle depends on the net 1.0.0 bundle. After you globally install the hpm-cli tool, run the following command to obtain bundle dependencies from the remote repository:
hpm install
Bundle dependencies are then stored in the ohos_bundles folder in the root directory of the current bundle. A tree structure illustrating the bundle and its dependencies will be generated. You need to run the following command in the root directory of the bundle:
username@server MINGW64 /f/showcase/demo/demo
$ hpm list
+--demo@1.0.0
| +--@huawei/media@1.0.2
| +--@demo/sport_hi3518ev300_liteos_a@1.0.0
| | +--@demo/app@4.0.1
| | | +--@demo/build@4.0.1
| | | +--@demo/arm_harmonyeabi_gcc@4.0.0
| | +--@demo/liteos_a@4.0.0
| | | +--@demo/third_party_fatfs@4.0.0
| | | +--@demo/arm_harmonyeabi_gcc@4.0.0
| | +--@demo/init@4.0.0
| | +--@demo/dist_tools@4.0.0
Alternatively, you can run the following command to view the dependencies of the current bundle in a visualized way:
hpm ui
A web service is started on the local host (by default, the browser is open and the project page is displayed). Click the project dependency icon on the sidebar. The list of dependent bundles is displayed. Click the button on the right to switch to the tree view. The bundle dependencies are displayed as shown in the following figure.
HPM Command Reference
You can use the hpm-cli tool to manage the lifecycle of a bundle. The following table describes available HPM commands. (You can run the hpm -h command to get the command details).
Table 1 HPM commands
Bundle Version
Version Number Naming Specifications
Each version name allows only lowercase letters, which can be separated by hyphens (-) or underscores (_). For example, bundle and my_bundle are allowed.
A bundle version number is in the format of major version number.minor version number.revision version number or major version number.minor version number.revision version number-pre-release version number, for example, 1.0.0 and 1.0.0-beta. For details, see https://semver.org.
Version Publishing
You should upload bundles to the remote repository so that your peers have an option to use them. You can run the following command to upload the bundles:
hpm publish
After this command is executed, the system checks the bundle dependencies and downloads the missing dependencies. If the bundles you uploaded are in binary, the system compiles the entire bundle, generates a binary file, packs the file, and uploads it. If the bundles you uploaded are in another format, the system packs the bundle file in compliance with the defined packing rules and then uploads the file.
Note: To publish a bundle, you need an HPM account for login. After logging in to the HPM platform, register with an organization and apply for authentication. After successful authentication, you will have the permission to publish the bundle.
Distribution
A distribution refers to an image file of an executable OpenHarmony solution composed of a group of bundles. It contains many dependent bundles and provides scripts to illustrate how to compile and link these bundles.
Generally, a distribution does not require code but contains only the bundle.json description (publishAs set to distribution) and some compilation scripts.
As system-provided environment variables are required during distribution compiling, run the dist command in scripts.
{
"publishAs":"distribution",
"scripts": {
"dist": "script compile command"
}
}
Run the following command:
hpm dist
As it is rather complex to redefine the functionality of a distribution, OpenHarmony allows inheritance from a distribution so that you can make a tailored distribution based on the existing functionality. To inherit from a distribution, you need to define the base field in bundle.json.
{
"base": {
"name": "dist_wifi_iot",
"version": "1.0.0"
}
}
In this example, the current bundle inherits from the Bundledist-wifi-iot 1.0.0 bundle of the distribution.
Each distribution consists of many dependent bundles, which are represented by the dependencies field in bundle.json. Some dependencies are mandatory, and others can be added or removed required. In the bundle.json file, bundle names prefixed with a question mark (?) represent optional dependent bundles. If you want to inherit from a distribution involving such bundles, you can remove them and then add other bundles.
{
"dependencies": {
"?my_bundle": "1.0.0"
}
}
In this example, my_bundle is an optional dependent bundle that can be removed by using the keyword excludes.
{
"excludes": [ "my_bundle" ]
}
The removed my-bundle will not be involved in the build process. If you forcibly remove mandatory dependent bundles, an error message will be displayed.
Environment Variables
During bundle compilation, system-provided environment variables are required to define the output and link the required binary files. These variables are injected into the context for executing scripts based on service requirements. Therefore, their values can be directly obtained from the scripts. The following environment variables are available:
Global variables are defined by the envs attribute in bundle.json. All dependent bundles can obtain the values of global variables.
{
"envs": {
"compileEnv": "arm"
}
}
Different parameters can be passed to bundles when introducing dependencies so that the compilation of dependent bundles can meet the requirements of the current bundle. The parameters defined in the dependencies can be obtained from the context for executing the corresponding scripts.
{
"dependencies": {
"my-bundle": {
"version": "1.0.0",
"mode": "debug"
}
}
}
When linking to a binary file, the bundle needs to know the file path regarding the dependencies. Therefore, the path (as an environment variable) is passed to the bundle for compiling.
The passed environment variable is in DEP_BundleName format, where BundleName indicates the name of the dependent bundle, for example, DEP_first_bundle.
Tags can be defined to group dependent bundles. You can obtain the path of a group of dependent bundles based on their tag. A tag starts with a number sign (#) and is defined as follows:
{
"dependencies": {
"#tool": {
"first-bundle": "1.0.0",
"second-bundle": "1.0.0"
},
"#drivers": {
"xx-bundle": "1.0.0",
"yy-bundle": "1.0.0"
}
}
}
There are two fixed environment variables:
- DEP_OHOS_BUNDLES: path of the ohos_bundles folder
- DEP_BUNDLE_BASE: path of the outermost bundle