Module
Configuration Rules
The Compilation and Building subsystem implements compilation and packaging by module, component, and product. A module is an target to build. It can be a dynamic library, static library, configuration file, or prebuilt module. A module must belong to a component and can belong to only one component. OpenHarmony uses customized GN templates to configure modules. For details about the GN basics, see https://gn.googlesource.com/gn/+/main/docs/reference.md.
The common templates for module configuration are as follows:
# C/C++ templates
ohos_shared_library
ohos_static_library
ohos_executable
ohos_source_set
# Prebuilt templates
ohos_prebuilt_executable
ohos_prebuilt_shared_library
ohos_prebuilt_static_library
# HAP templates
ohos_hap
ohos_app_scope
ohos_js_assets
ohos_resources
# Other templates
# Configuration file
ohos_prebuild_etc
# SA profile
ohos_sa_profile
You are recommended to use the OpenHarmony customized templates.
C/C++ Template Example
The .gni file corresponding to the templates starting with ohos is located in openharmony/build/templates/cxx/cxx.gni.
ohos_shared_library example:
import("//build/ohos.gni")
ohos_shared_library("helloworld") {
sources = ["file"]
include_dirs = [] # If there are duplicate header files, the header files defined earlier take effect.
cflags = [] # If there are duplicate or conflict settings, the settings in cflags take effect.
cflags_c = []
cflags_cc = []
ldflags = [] # If there are duplicate or conflict definitions, the settings in ohos_template take effect.
configs = []
deps = [] # Define dependent modules that belong to the same component.
external_deps = [ # Define dependent modules that belong to different components.
"part_name:module_name", # The value is in the Component_name:Module_name format.
] # The dependent modules must be declared in inner_kits by the dependent component.
output_name = [string] # Name of the module output.
output_extension = [] # Extension name of the module.
module_install_dir = [] # Module installation directory. The default directory is /system/lib64 or /system/lib. Specify the directory from system/ or vendor/.
relative_install_dir = [] # Relative module installation directory (relative to /system/lib64 or /system/lib). If module_install_dir is configured, the parameter does not take effect.
part_name = [string] # (Mandatory) Component name.
output_dir
# Sanitizer variables
cfi = [boolean]
scs = [boolean]
scudo = []
ubsan = []
boundary_sanitize = []
integer_overflow_sanitize = []
testonly = [boolean]
license_as_sources = []
license_file = [] # A .txt file.
remove_configs = []
no_default_deps = []
install_images = []
install_enable = [boolean]
symlink_target_name = []
version_script = []
use_exceptions = []
}
ohos_static_library example:
import("//build/ohos.gni")
ohos_static_library("helloworld") {
sources = ["file"] # Source code in .c format.
include_dirs = ["dir"] # Directories to be included.
configs = [] # Configuration.
deps = [] # Define dependent modules that belong to the same component.
part_name = [string] # Component name.
subsystem_name = [string] # Subsystem name.
cflags = []
external_deps = [ # Define dependent modules that belong to different components.
"part_name:module_name", # The value is in the Component_name:Module_name format.
] # The dependent modules must be declared in inner_kits by the dependent component.
lib_dirs = []
public_configs = []
# Sanitizer variables
cfi = [boolean]
scs = [boolean]
scudo = []
ubsan = []
boundary_sanitize = []
integer_overflow_sanitize = []
remove_configs = []
no_default_deps = []
license_file = [] # A .txt file.
license_as_sources = []
use_exceptions = []
}
ohos_executable example:
import("//build/ohos.gni")
ohos_executable("helloworld") {
configs = [] # Configuration.
part_name = [string] # Component name.
subsystem_name = [string] # Subsystem name.
deps = [] # Define dependent modules that belong to the same component.
external_deps = [ # Define dependent modules that belong to different components.
"part_name:module_name", # The value is in the Component_name:Module_name format.
] # The dependent modules must be declared in inner_kits by the dependent component.
ohos_test = []
test_output_dir = []
# Sanitizer variables
cfi = [boolean]
scs = [boolean]
scudo = []
ubsan = []
boundary_sanitize = []
integer_overflow_sanitize = []
testonly = [boolean]
license_as_sources = []
license_file = [] # A .txt file.
remove_configs = []
static_link = []
install_images = []
module_install_dir = [] # Module installation directory, starting from system/ or vendor/.
relative_install_dir = []
symlink_target_name = []
output_dir = [directory] # Directory in which output files are located.
install_enable = [boolean]
version_script = []
use_exceptions = []
}
ohos_source_set example:
import("//build/ohos.gni")
ohos_source_set("helloworld") {
sources = ["file"] # Source code in .c format.
include_dirs = [] # Directories to be included.
configs = [] # Configuration.
public = [] # Header files.
defines = []
public_configs = []
part_name = [string] # Component name.
subsystem_name = [string] # Subsystem name.
deps = [] # Define dependent modules that belong to the same component.
external_deps = [ # Define dependent modules that belong to different components.
"part_name:module_name", # The value is in the Component_name:Module_name format.
] # The dependent modules must be declared in inner_kits by the dependent component.
# Sanitizer variables
cfi = [boolean]
scs = [boolean]
scudo = []
ubsan = []
boundary_sanitize = []
integer_overflow_sanitize = []
testonly = [boolean]
license_as_sources = []
license_file = []
remove_configs = []
no_default_deps = []
license_file = [] # A .txt file.
license_as_sources = []
use_exceptions = []
}
NOTE
Only sources and part_name are mandatory.
Prebuilt Template Example
The .gni file of the prebuilt templates is located in openharmony/build/templates/cxx/prebuilt.gni.
ohos_prebuilt_executable example:
import("//build/ohos.gni")
ohos_prebuilt_executable("helloworld") {
sources = ["file"] # Source.
output = []
install_enable = [boolean]
deps = [] # Define dependent modules that belong to the same component.
public_configs = []
subsystem_name = [string] # Subsystem name.
part_name = [string] # Component name.
testonly = [boolean]
visibility = []
install_images = []
module_install_dir = [] # Module installation directory, starting from system/ or vendor/.
relative_install_dir = [] # Relative module installation directory (relative to system/etc). If module_install_dir is configured, the parameter does not take effect.
symlink_target_name = []
license_file = [] # A .txt file.
license_as_sources = []
}
ohos_prebuilt_shared_library example:
import("//build/ohos.gni")
ohos_prebuilt_shared_library("helloworld") {
sources = ["file"] # .so files.
output = []
install_enable = [boolean]
deps = [] # Define dependent modules that belong to the same component.
public_configs = []
subsystem_name = [string] # Subsystem name.
part_name = [string] # Component name.
testonly = [boolean]
visibility = []
install_images = []
module_install_dir = [] # Module installation directory, starting from system/ or vendor/.
relative_install_dir = [] # Relative module installation directory (relative to system/etc). If module_install_dir is configured, the parameter does not take effect.
symlink_target_name = [string]
license_file = [string] # A .txt file.
license_as_sources = []
}
ohos_prebuilt_static_library example:
import("//build/ohos.gni")
ohos_prebuilt_static_library("helloworld") {
sources = ["file"] # .so files.
output = []
deps = [] # Define dependent modules that belong to the same component.
public_configs = []
subsystem_name = [string] # Subsystem name.
part_name = [string] # Component name.
testonly = [boolean]
visibility = []
license_file = [string] # A .txt file.
license_as_sources = []
}
NOTE
Only sources and part_name are mandatory.
HAP Templates
See HAP Build Guide.
Other Templates
ohos_prebuilt_etc example:
import("//build/ohos.gni")
ohos_prebuilt_etc("helloworld") {
# The most common attributes of the ohos_prebuilt_etc template.
sources = ["file"]
module_install_dir = [] # Module installation directory, starting from system/ or vendor/.
subsystem_name = [string] # Subsystem name.
part_name = [string] # (Mandatory) Component name.
install_images = []
relative_install_dir = [] # Relative module installation directory (relative to system/etc). If module_install_dir is configured, the parameter does not take effect.
# Uncommon attributes of the ohos_prebuilt_etc template:
deps = [] # Define dependent modules that belong to the same component.
testonly = [boolean]
visibility = []
public_configs = []
symlink_target_name = [string]
license_file = [string]
license_as_sources = []
}
ohos_sa_profile example:
import("//build/ohos.gni")
ohos_sa_profile("helloworld") {
sources = [".xml"] # .xml file.
part_name = [string] # Component name.
subsystem_name = [string] # Subsystem name.
}
NOTE: Only sources and part_name are mandatory.
Adding and Building a Module
The figure below illustrates the process for adding a module. A module belongs to a component, which belongs to a subsystem. Please note that the chipset solution, as a special component, does not have a subsystem. You may need to:
-
Add a module to an existing component.
-
Add a module to a new component.
-
Add a module to a new subsystem.
Adding a Module to an Existing Component
-
Configure the BUILD.gn file in the module directory and select the GN template.
-
Modify the bundle.json file.
{ "name": "@ohos/<component_name>, # HPM component name, in the "@Organization/Component_name" format. "description": "xxxxxxxxxxxxxxxxxxx", # Description of the component functions. "version": "3.1", # Version, which must be the same as the version of OpenHarmony. "license": "MIT", # Component license. "publishAs": "code-segment", # HPM package release mode. The default value is code-segment. "segment": { "destPath": "third_party/nghttp2" }, # Code restoration path (source code path) set when publishAs is code-segment. "dirs": {}, # Directory structure of the HPM package. This field is mandatory and can be left empty. "scripts": {}, # Scripts to be executed. This field is mandatory and can be left empty. "licensePath": "COPYING", "readmePath": { "en": "README.rst" }, "component": { # Component attributes. "name": "<component_name>", # Component name. "subsystem": "", # Subsystem to which the component belongs. "syscap": [], # System capabilities provided by the component for applications. "features": [], # List of configurable features of the component. Generally, this parameter corresponds to sub_component in build. "adapted_system_type": [], # Types of adapted systems. The value can be mini, small, standard, or their combinations. "rom": "xxxKB" # ROM baseline. If there is no baseline, enter the current value. "ram": "xxxKB", # RAM baseline. If there is no baseline, enter the current value. "deps": { "components": [ # Other components on which this component depends. "third_party": [ # Third-party open-source software on which this component depends. }, "build": { # Build-related configuration. "sub_component": [ "//foundation/arkui/napi:napi_packages", # Existing module 1. "//foundation/arkui/napi:napi_packages_ndk" # Existing module 2. "//foundation/arkui/napi:new" # Module to add. ], # Component build entry. Configure the module here. "inner_kits": [], # APIs between components. "test": [] # Entry for building the component's test cases. } } }
NOTE
The bundle.json file must be in the folder of the corresponding subsystem. -
Start the build and check whether a .so file or binary file is generated.
Creating a Component and Adding a Module
-
Configure the BUILD.gn file in the module directory and select the corresponding GN template. Note that part_name in the BUILD.gn file is the name of the component to add.
-
Create a bundle.json file in the folder of the corresponding subsystem.
-
Add the new component to the end of existing components in vendor/{product_company}/{product_name}/config.json.
"subsystems": [ { "subsystem": "Subsystem to which the component belongs", "components": [ {"component": "Component 1 name", "features":[]}, # Existing component 1 in the subsystem { "component": "Component 2 name", "features":[] }, # Existing component 2 in the subsystem {"component": "New component name", "features":[]} # New component in the subsystem ] }, . ]
-
Start the build and check whether a .so file or binary file is generated.
Creating a Subsystem and Adding a Module
-
Configure the BUILD.gn file in the module directory and select the corresponding GN template. This step is the same as Step 1 in "Creating a Component and Adding a Module."
-
Create a bundle.json file in the folder of the component of the subsystem. This step is the same as Step 2 in "Creating a Component and Adding a Module."
-
Modify the subsystem_config.json file in the build directory.
{ "Subsystem 1 name": { # Existing subsystem 1 "path": "Subsystem 1 directory", "name": "Subsystem 1 name" }, "Subsystem 2 name": { # Existing subsystem 2 "path": "Subsystem 2 directory", "name": "Subsystem 2 name" }, "Subsystem name new": { # Subsystem to add "path": "New subsystem directory", "name": "New subsystem name" }, }
The subsystem_config.json file defines the subsystems and their directories. When adding a subsystem, specify path and name for the subsystem.
-
If product_name in the vendor/{product_company}/{product_name} directory is hispark_taurus_standard, add the new component information to the end of existing components in the config.json file.
"subsystems": [ { "subsystem": "arkui", # Name of the existing subsystem "components": [ # All components of the subsystem { "component": "ace_engine_standard", # Name of the existing component "features": [] }, { "component": "napi", # Name of the existing component "features": [] } { "component": "component_new1", # Name of the new component to add "features": [] } ] }, { "subsystem": "subsystem_new", # Name of the new subsystem to add "components": [ { "component": "component_new2", # Name of the component to be added to the new subsystem "features": [] } ] }, ]
-
Start the build and check whether a .so file or binary file is generated.
Building a Module
You can start the build by using the CLI or hb tool. The following uses the CLI as an example:
You can run the --build-target Module_name command to build a module separately.
./build.sh --build-target Module_name
You can also build a product. For example, to build hispark_taurus_standard, run the following command:
./build.sh --product-name hispark_taurus_standard --build-target Module_name --ccache
You can also build the component to which the module belongs.
./build.sh --product-name hispark_taurus_standard --build-target musl --build-target Module_name --ccache