# Module ## Configuration Rules The Compilation and Building subsystem implements compilation and packaging by module, component, and product. A module is a 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 provides customized GN templates to configure modules. For details about the GN basics, see [GN Reference](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_prebuilt_etc # SA profile ohos_sa_profile ``` You are advised to use the OpenHarmony customized templates. ### C/C++ Template Examples The .gni file corresponding to the templates starting with **ohos** is located in **openharmony/build/templates/cxx/cxx.gni**. **ohos_shared_library** example: ```shell 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 configuration. Each item is optional, and set to false or left unspecified by default. sanitize = { # Sanitizer settings cfi = [boolean] # Whether to enable the control-flow integrity (CFI) check. cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. integer_overflow = [boolean] # Whether to enable the integer overflow check. boundary_sanitize = [boolean] # Whether to enable the bounds check. ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. all_ubsan = [boolean] # Whether to enable all UBSAN options. ... debug = [boolean] # Whether to enable the debug mode. blocklist = [string] # Path of the blocklist. } 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: ```shell 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 configuration. Each item is optional, and set to false or left unspecified by default. sanitize = { # Sanitizer settings cfi = [boolean] # Whether to enable the CFI check. cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. integer_overflow = [boolean] # Whether to enable the integer overflow check. boundary_sanitize = [boolean] # Whether to enable the bounds check. ubsan = [boolean] # Whether to enable some UBSAN options. all_ubsan = [boolean] # Whether to enable all UBSAN options. ... debug = [boolean] # Whether to enable the debug mode. blocklist = [string] # Path of the blocklist. } remove_configs = [] no_default_deps = [] license_file = [] # A .txt file. license_as_sources = [] use_exceptions = [] } ``` **ohos_executable** example: ```shell 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 configuration. Each item is optional, and set to false or left unspecified by default. sanitize = { # Sanitizer settings cfi = [boolean] # Whether to enable the CFI check. cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. integer_overflow = [boolean] # Whether to enable the integer overflow check. boundary_sanitize = [boolean] # Whether to enable the bounds check. ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. all_ubsan = [boolean] # Whether to enable all UBSAN options. ... debug = [boolean] # Whether to enable the debug mode. blocklist = [string] # Path of the blocklist. } 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: ```shell 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 configuration. Each item is optional, and set to false or left unspecified by default. sanitize = { # Sanitizer settings cfi = [boolean] # Whether to enable the CFI check. cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. integer_overflow = [boolean] # Whether to enable the integer overflow check. boundary_sanitize = [boolean] # Whether to enable the bounds check. ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. all_ubsan = [boolean] # Whether to enable all UBSAN options. ... debug = [boolean] # Whether to enable the debug mode. blocklist = [string] # Path of the blocklist. } 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. > - For details about the Sanitizer configuration, see [Using Sanitizer](subsys-build-reference.md#using-sanitizer). ### Prebuilt Template Examples The .gni file of the prebuilt templates is located in **openharmony/build/templates/cxx/prebuilt.gni**. **ohos_prebuilt_executable** example: ```shell 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: ```shell 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: ```shell 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 For details, see [HAP Build Guide](subsys-build-gn-hap-compilation-guide.md). ### Other Templates **ohos_prebuilt_etc** example: ```shell 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: ```shell 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 following figure shows the logic for adding a module. Generally, you need to add a module to a component of a subsystem. If there is no subsystem or component, you must add the subsystem and component first. Note that the chip solution is a special component and does not have a subsystem. - Add a module to an existing component. - Add a module to a new component. - Add a module to a new subsystem. ![](figures/module_addition_process.png) **Adding a Module to an Existing Component** 1. Configure the **BUILD.gn** file in the module directory and select the GN template. 2. Modify the **bundle.json** file. ```shell { "name": "@ohos/, # 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. "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. 3. Start the build and check whether a .so file or binary file is generated. **Creating a Component and Adding a Module** 1. 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. 2. Create a **bundle.json** file in the folder of the corresponding subsystem. 3. Add the new component to the end of existing components in **vendor/{product_company}/{product_name}/config.json**. ```shell "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 ] }, . ] ``` 4. Start the build and check whether a .so file or binary file is generated. **Creating a Subsystem and Adding a Module** 1. 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." 2. 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." 3. Modify the **subsystem_config.json** file in the **build** directory. ```shell { "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. 4. 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. ```shell "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": [] } ] }, ] ``` 4. 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](subsys-build-all.md#build-commands). The following uses the CLI as an example: You can run the **--build-target** *Module_name* command to build a module separately. ```shell ./build.sh --build-target Module_name ``` You can also build a product. For example, to build hispark_taurus_standard, run the following command: ```shell ./build.sh --product-name hispark_taurus_standard --build-target Module_name --ccache ``` You can also build the component to which the module belongs. ```shell ./build.sh --product-name hispark_taurus_standard --build-target musl --build-target Module_name --ccache ```