# Bundle Development Specifications - [Overview](#section1725818533344) - [Definition](#section4821219183514) - [Bundle Division Rules](#section1089794263513) - [Bundle Dependency](#section25701647163710) - [Bundle Composition](#section185538333914) - [Code Files](#section8431268393) - [README File](#section168121548173914) - [Metadata Description File](#section7107181819406) - [Bundle Management](#section32061634104110) - [Dependency](#section791115242423) - [HPM Command Reference](#section1183205411429) - [Bundle Version](#section12612142864316) - [Version Number Naming Specifications](#section1487612416432) - [Version Publishing](#section1548171014440) - [Distribution](#section1264139114413) - [Environment Variables](#section15352105174512) ## 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](https://www.markdownguide.org/getting-started/). 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. **Figure 1** Bundle dependencies ![](figure/en-us_image_0000001173313501.png) ### 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

Function

Command Line

Description

Querying version information

hpm -V or hpm --version

Displays the hpm-cli version number.

Querying help information

hpm -h or hpm --version

Displays the command list and help information.

hpm -h

Displays command help information.

Creating a project

hpm init bundle

Create a bundle project.

hpm init -t template

Creates a scaffolding project from a template.

Installing bundles

hpm install or hpm i

Installs dependent bundles in the bundle.json file.

hpm install bundle@version

Installs bundles of a specified version.

Uninstalling bundles

hpm uninstall bundle

Uninstalls dependent bundles.

hpm remove or hpm rm bundlename

Removes dependent bundles.

Viewing information

hpm list or hpm ls

Displays the bundle tree of available bundles and distributions.

hpm dependencies

Generates the dependency relationship data of a bundle or distribution. (This command is also integrated in the HPM UI to display the bundle dependencies intuitively.)

Searching for bundles

hpm search name

Searches for bundles. --json is used to specify the search result in JSON format, and -type is used to set the target type, which can be bundle, distribution, or code-segment.

Setting HPM configuration items

hpm config set key value

Sets configuration items, such as the server address and network proxy.

hpm config delete key

Deletes configurations.

Updating bundle versions

hpm update

Updates the versions of dependent bundles.

hpm check-update

Checks whether version updates are available to dependent bundles.

Building

hpm build

Builds a bundle or distribution.

hpm dist

Builds a distribution. The build depends on the dist script in scripts of bundle.json.

Packing

hpm pack

Packs dependencies of local bundles.

Burning

hpm run flash

Burns the firmware. The firmware burning depends on the flash script in scripts of bundle.json.

Publishing

hpm publish

Publishes a bundle, which must be unique in the repository and has a unique version. (An account is required for login.)

Running extended commands

hpm run

Runs the commands in scripts defined in bundle.json. Multiple commands can be executed at a time by using &&.

Decompressing

hpm extract

Decompresses files in zip, tar, tgz, or .tar.gz format.

Restarting GUI

hpm ui

Starts the HPM UI locally. You can use the -p parameter to specify a port. On the Windows platform, the default browser is used to open the HPM UI.

Changing language

hpm lang

Alternates between Chinese and English on the CLI and UI.

Converting to HPM format

hpm x2h

Converts a Maven or NPM package to an HPM package and publishes it to the HPM.

Code segment restoration or cleanup

hpm code clean|restore

Clears or restores the dependent code segment (code-segment). That is, copy or delete the code segment based on segment.destPath.

Generating a key

hpm gen-keys

Generates a public-private key pair and configures the public key on the HPM server, which enables password-free hpm-cli login for bundle publishing.

Generating third-party open source notice

hpm gen-notice

Generates a file providing the notice on third-party open source by combining the description of each bundle.

## 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](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