1# Module 2## Configuration Rules 3 4The 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). 5 6The common templates for module configuration are as follows: 7 8``` 9# C/C++ templates 10ohos_shared_library 11ohos_static_library 12ohos_executable 13ohos_source_set 14 15# Prebuilt templates 16ohos_prebuilt_executable 17ohos_prebuilt_shared_library 18ohos_prebuilt_static_library 19 20# HAP templates 21ohos_hap 22ohos_app_scope 23ohos_js_assets 24ohos_resources 25 26# Rust templates 27ohos_rust_executable 28ohos_rust_shared_library 29ohos_rust_static_library 30ohos_rust_proc_macro 31ohos_rust_shared_ffi 32ohos_rust_static_ffi 33ohos_rust_cargo_crate 34ohos_rust_systemtest 35ohos_rust_unittest 36 37# Other templates 38# Configuration file 39ohos_prebuilt_etc 40 41# SA profile 42ohos_sa_profile 43``` 44 45You are advised to use the OpenHarmony customized templates. 46 47### C/C++ Template Example 48 49The .gni file corresponding to the templates starting with **ohos** is located in **openharmony/build/templates/cxx/cxx.gni**. 50 51**ohos_shared_library** example: 52 53```shell 54import("//build/ohos.gni") 55ohos_shared_library("helloworld") { 56 sources = ["file"] 57 include_dirs = [] # If there are duplicate header files, the header files defined earlier take effect. 58 cflags = [] # If there are duplicate or conflict settings, the settings in cflags take effect. 59 cflags_c = [] 60 cflags_cc = [] 61 ldflags = [] # If there are duplicate or conflict definitions, the settings in ohos_template take effect. 62 configs = [] 63 deps = [] # Define dependent modules that belong to the same component. 64 65 external_deps = [ # Define dependent modules that belong to different components. 66 "part_name:module_name", # The value is in the Component_name:Module_name format. 67 ] # The dependent modules must be declared in inner_kits by the dependent component. 68 69 output_name = [string] # Name of the module output. 70 output_extension = [] # Extension name of the module. 71 module_install_dir = [] # Module installation directory. The default directory is /system/lib64 or /system/lib. Specify the directory from system/ or vendor/. 72 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. 73 74 part_name = [string] # (Mandatory) Component name. 75 output_dir 76 77 # Sanitizer configuration. Each item is optional, and set to false or left unspecified by default. 78 sanitize = { 79 # Sanitizer settings 80 cfi = [boolean] # Whether to enable the control-flow integrity (CFI) check. 81 cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. 82 integer_overflow = [boolean] # Whether to enable the integer overflow check. 83 boundary_sanitize = [boolean] # Whether to enable the boundary check. 84 ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. 85 all_ubsan = [boolean] # Whether to enable all UBSAN options. 86 ... 87 88 debug = [boolean] # Whether to enable the debug mode. 89 blocklist = [string] # Path of the blocklist. 90 } 91 92 testonly = [boolean] 93 license_as_sources = [] 94 license_file = [] # A .txt file. 95 remove_configs = [] 96 no_default_deps = [] 97 install_images = [] 98 install_enable = [boolean] 99 symlink_target_name = [] 100 version_script = [] 101 use_exceptions = [] 102} 103``` 104 105**ohos_static_library** example 106 107```shell 108import("//build/ohos.gni") 109ohos_static_library("helloworld") { 110 sources = ["file"] # .c files. 111 include_dirs = ["dir"] # Directories to be included. 112 configs = [] # Configuration. 113 deps = [] # Define dependent modules that belong to the same component. 114 part_name = [string] # Component name. 115 subsystem_name = [string] # Subsystem name. 116 cflags = [] 117 118 external_deps = [ # Define dependent modules that belong to different components. 119 "part_name:module_name", # The value is in the Component_name:Module_name format. 120 ] # The dependent modules must be declared in inner_kits by the dependent component. 121 122 lib_dirs = [] 123 public_configs = [] 124 125 # Sanitizer configuration. Each item is optional, and set to false or left unspecified by default. 126 sanitize = { 127 # Sanitizer settings 128 cfi = [boolean] # Whether to enable the control-flow integrity (CFI) check. 129 cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. 130 integer_overflow = [boolean] # Whether to enable the integer overflow check. 131 boundary_sanitize = [boolean] # Whether to enable the boundary check. 132 ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. 133 all_ubsan = [boolean] # Whether to enable all UBSAN options. 134 ... 135 136 debug = [boolean] # Whether to enable the debug mode. 137 blocklist = [string] # Path of the blocklist. 138 } 139 140 remove_configs = [] 141 no_default_deps = [] 142 license_file = [] # A .txt file. 143 license_as_sources = [] 144 use_exceptions = [] 145} 146``` 147 148**ohos_executable** example: 149 150```shell 151import("//build/ohos.gni") 152ohos_executable("helloworld") { 153 configs = [] # Configuration. 154 part_name = [string] # Component name. 155 subsystem_name = [string] # Subsystem name. 156 deps = [] # Define dependent modules that belong to the same component. 157 158 external_deps = [ # Define dependent modules that belong to different components. 159 "part_name:module_name", # The value is in the Component_name:Module_name format. 160 ] # The dependent modules must be declared in inner_kits by the dependent component. 161 ohos_test = [] 162 test_output_dir = [] 163 164 # Sanitizer configuration. Each item is optional, and set to false or left unspecified by default. 165 sanitize = { 166 # Sanitizer settings 167 cfi = [boolean] # Whether to enable the control-flow integrity (CFI) check. 168 cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. 169 integer_overflow = [boolean] # Whether to enable the integer overflow check. 170 boundary_sanitize = [boolean] # Whether to enable the boundary check. 171 ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. 172 all_ubsan = [boolean] # Whether to enable all UBSAN options. 173 ... 174 175 debug = [boolean] # Whether to enable the debug mode. 176 blocklist = [string] # Path of the blocklist. 177 } 178 179 testonly = [boolean] 180 license_as_sources = [] 181 license_file = [] # A .txt file. 182 remove_configs = [] 183 static_link = [] 184 install_images = [] 185 module_install_dir = [] # Module installation directory, starting from system/ or vendor/. 186 relative_install_dir = [] 187 symlink_target_name = [] 188 output_dir = [directory] # Directory in which output files are located. 189 install_enable = [boolean] 190 version_script = [] 191 use_exceptions = [] 192} 193``` 194 195**ohos_source_set** example 196 197```shell 198import("//build/ohos.gni") 199ohos_source_set("helloworld") { 200 sources = ["file"] # .c files. 201 include_dirs = [] # Directories to be included. 202 configs = [] # Configuration. 203 public = [] # .h header files. 204 defines = [] 205 public_configs = [] 206 part_name = [string] # Component name. 207 subsystem_name = [string] # Subsystem name. 208 deps = [] # Define dependent modules that belong to the same component. 209 210 external_deps = [ # Define dependent modules that belong to different components. 211 "part_name:module_name", # The value is in the Component_name:Module_name format. 212 ] # The dependent modules must be declared in inner_kits by the dependent component. 213 214 # Sanitizer configuration. Each item is optional, and set to false or left unspecified by default. 215 sanitize = { 216 # Sanitizer settings 217 cfi = [boolean] # Whether to enable the control-flow integrity (CFI) check. 218 cfi_cross_dso = [boolean] # Whether to enable the cross-DSO CFI check. 219 integer_overflow = [boolean] # Whether to enable the integer overflow check. 220 boundary_sanitize = [boolean] # Whether to enable the boundary check. 221 ubsan = [boolean] # Whether to enable some Undefined Behavior Sanitizer (UBSAN) options. 222 all_ubsan = [boolean] # Whether to enable all UBSAN options. 223 ... 224 225 debug = [boolean] # Whether to enable the debug mode. 226 blocklist = [string] # Path of the blocklist. 227 } 228 229 testonly = [boolean] 230 license_as_sources = [] 231 license_file = [] 232 remove_configs = [] 233 no_default_deps = [] 234 license_file = [] # A .txt file. 235 license_as_sources = [] 236 use_exceptions = [] 237} 238``` 239 240**NOTE**<br> 241 - Only **sources** and **part_name** are mandatory. 242 - For details about the Sanitizer configuration, see [Using Sanitizer](subsys-build-reference.md#using-sanitizer). 243 244### Prebuilt Template Example 245 246The .gni file of the prebuilt templates is located in **openharmony/build/templates/cxx/prebuilt.gni**. 247 248**ohos_prebuilt_executable** example 249 250```shell 251import("//build/ohos.gni") 252ohos_prebuilt_executable("helloworld") { 253 sources = ["file"] # Source. 254 output = [] 255 install_enable = [boolean] 256 257 deps = [] # Define dependent modules that belong to the same component. 258 public_configs = [] 259 subsystem_name = [string] # Subsystem name. 260 part_name = [string] # Component name. 261 262 testonly = [boolean] 263 visibility = [] 264 265 install_images = [] 266 module_install_dir = [] # Module installation directory, starting from system/ or vendor/. 267 relative_install_dir = [] # Relative module installation directory (relative to system/etc). If module_install_dir is configured, the parameter does not take effect. 268 symlink_target_name = [] 269 270 271 license_file = [] # A .txt file. 272 license_as_sources = [] 273} 274``` 275 276**ohos_prebuilt_shared_library** example 277 278```shell 279import("//build/ohos.gni") 280ohos_prebuilt_shared_library("helloworld") { 281 sources = ["file"] # .so files. 282 output = [] 283 install_enable = [boolean] 284 285 deps = [] # Define dependent modules that belong to the same component. 286 public_configs = [] 287 subsystem_name = [string] # Subsystem name. 288 part_name = [string] # Component name. 289 290 testonly = [boolean] 291 visibility = [] 292 293 install_images = [] 294 module_install_dir = [] # Module installation directory, starting from system/ or vendor/. 295 relative_install_dir = [] # Relative module installation directory (relative to system/etc). If module_install_dir is configured, the parameter does not take effect. 296 symlink_target_name = [string] 297 298 299 license_file = [string] # A .txt file. 300 license_as_sources = [] 301} 302``` 303 304**ohos_prebuilt_static_library** example 305 306```shell 307import("//build/ohos.gni") 308ohos_prebuilt_static_library("helloworld") { 309 sources = ["file"] # .so files. 310 output = [] 311 312 deps = [] # Define dependent modules that belong to the same component. 313 public_configs = [] 314 subsystem_name = [string] # Subsystem name. 315 part_name = [string] # Component name. 316 317 testonly = [boolean] 318 visibility = [] 319 320 license_file = [string] # A .txt file. 321 license_as_sources = [] 322} 323``` 324 325 **NOTE**: Only **sources** and **part_name** are mandatory. 326 327### HAP Templates 328 329For details about the HAP templates, see [HAP Build Guide](subsys-build-gn-hap-compilation-guide.md). 330 331### Rust Templates 332 333For details about the Rust templates, see [Rust Module Configuration Rules and Guide](subsys-build-rust-compilation.md). 334 335### Other Templates 336 337**ohos_prebuilt_etc** example: 338 339```shell 340import("//build/ohos.gni") 341ohos_prebuilt_etc("helloworld") { 342 # The most common attributes of the ohos_prebuilt_etc template. 343 sources = ["file"] 344 module_install_dir = [] # Module installation directory, starting from system/ or vendor/. 345 subsystem_name = [string] # Subsystem name. 346 part_name = [string] # (Mandatory) Component name. 347 install_images = [] 348 relative_install_dir = [] # Relative module installation directory (relative to system/etc). If module_install_dir is configured, the parameter does not take effect. 349 350 # Uncommon attributes of the ohos_prebuilt_etc template: 351 deps = [] # Define dependent modules that belong to the same component. 352 testonly = [boolean] 353 visibility = [] 354 public_configs = [] 355 symlink_target_name = [string] 356 license_file = [string] 357 license_as_sources = [] 358} 359``` 360 361**ohos_sa_profile** example: 362 363```shell 364import("//build/ohos.gni") 365ohos_sa_profile("helloworld") { 366 sources = [".xml"] # .xml file. 367 part_name = [string] # Component name. 368 subsystem_name = [string] # Subsystem name. 369} 370``` 371 372 **NOTE**: Only **sources** and **part_name** are mandatory. 373 374## Adding and Building a Module 375 376The 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. 377 378- Add a module to an existing component. 379 380- Add a module to a new component. 381 382- Add a module to a new subsystem. 383 384  385 386**Adding a Module to an Existing Component** 387 3881. Configure the **BUILD.gn** file in the module directory and select the GN template. 389 3902. Modify the **bundle.json** file. 391 392 ```shell 393 { 394 "name": "@ohos/<component_name>, # HPM component name, in the "@Organization/Component_name" format. 395 "description": "xxxxxxxxxxxxxxxxxxx", # Description of the component functions. 396 "version": "3.1", # Version, which must be the same as the version of OpenHarmony. 397 "license": "MIT", # Component license. 398 "publishAs": "code-segment", # HPM package release mode. The default value is code-segment. 399 "segment": { 400 "destPath": "third_party/nghttp2" 401 }, # Code restoration path (source code path) set when publishAs is code-segment. 402 "dirs": {}, # Directory structure of the HPM package. This field is mandatory and can be left empty. 403 "scripts": {}, # Scripts to be executed. This field is mandatory and can be left empty. 404 "licensePath": "COPYING", 405 "readmePath": { 406 "en": "README.rst" 407 }, 408 "component": { # Component attributes. 409 "name": "<component_name>", # Component name. 410 "subsystem": "", # Subsystem to which the component belongs. 411 "syscap": [], # System capabilities provided by the component for applications. 412 "features": [], # List of configurable features of the component. Generally, this parameter corresponds to sub_component in build. 413 "adapted_system_type": [], # Types of adapted systems. The value can be mini, small, standard, or their combinations. 414 "rom": "xxxKB" # ROM baseline. If there is no baseline, enter the current value. 415 "ram": "xxxKB", # RAM baseline. If there is no baseline, enter the current value. 416 "deps": { 417 "components": [ # Other components on which this component depends. 418 "third_party": [ # Third-party open-source software on which this component depends. 419 }, 420 421 "build": { # Build-related configuration. 422 "sub_component": [ 423 "//foundation/arkui/napi:napi_packages", # Existing module 1. 424 "//foundation/arkui/napi:napi_packages_ndk" # Existing module 2. 425 "//foundation/arkui/napi:new" # Module to add. 426 ], # Component build entry. Configure the module here. 427 "inner_kits": [], # APIs between components. 428 "test": [] # Entry for building the component's test cases. 429 } 430 } 431 } 432 ``` 433 434 >  **NOTE** 435 > 436 > The **bundle.json** file must be in the folder of the corresponding subsystem. 437 4383. Start the build and check whether a .so file or binary file is generated. 439 440**Creating a Component and Adding a Module** 441 4421. 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. 443 4442. Create a **bundle.json** file in the folder of the corresponding subsystem. 445 4463. Add the new component to the end of existing components in **vendor/{product_company}/{product-name}/config.json**. 447 448 ```shell 449 "subsystems": [ 450 { 451 "subsystem": "Subsystem to which the component belongs", 452 "components": [ 453 {"component": "Component 1 name", "features":[]}, # Existing component 1 in the subsystem 454 { "component": "Component 2 name", "features":[] }, # Existing component 2 in the subsystem 455 {"component": "New component name", "features":[]} # New component in the subsystem 456 ] 457 }, 458 . 459 ] 460 ``` 461 4624. Start the build and check whether a .so file or binary file is generated. 463 464 465**Creating a Subsystem and Adding a Module** 466 4671. 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." 468 4692. 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." 470 4713. Modify the **subsystem_config.json** file in the **build** directory. 472 473 ```shell 474 { 475 "Subsystem 1 name": { # Existing subsystem 1 476 "path": "Subsystem 1 directory", 477 "name": "Subsystem 1 name" 478 }, 479 "Subsystem 2 name": { # Existing subsystem 2 480 "path": "Subsystem 2 directory", 481 "name": "Subsystem 2 name" 482 }, 483 "Subsystem name new": { # Subsystem to add 484 "path": "New subsystem directory", 485 "name": "New subsystem name" 486 }, 487 488 } 489 ``` 490 491 The **subsystem_config.json** file defines the subsystems and their directories. When adding a subsystem, specify **path** and **name** for the subsystem. 492 4934. 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. 494 495 ```shell 496 "subsystems": [ 497 { 498 "subsystem": "arkui", # Name of the existing subsystem 499 "components": [ # All components of the subsystem 500 { 501 "component": "ace_engine_standard", # Name of the existing component 502 "features": [] 503 }, 504 { 505 "component": "napi", # Name of the existing component 506 "features": [] 507 } 508 { 509 "component": "component_new1", # Name of the new component to add 510 "features": [] 511 } 512 ] 513 }, 514 { 515 "subsystem": "subsystem_new", # Name of the new subsystem to add. 516 "components": [ 517 { 518 "component": "component_new2", # Name of the component to be added to the new subsystem 519 "features": [] 520 } 521 ] 522 }, 523 524 ] 525 ``` 526 5274. Start the build and check whether a .so file or binary file is generated. 528 529 530**Building a Module** 531 532You 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: 533 534 You can run the **--build-target** *Module_name* command to build a module separately. 535 536 ```shell 537 ./build.sh --build-target Module_name 538 ``` 539 540 You can also build a product. For example, to build hispark_taurus_standard, run the following command: 541 542 ```shell 543 ./build.sh --product-name hispark_taurus_standard --build-target Module_name --ccache 544 ``` 545 546 You can also build the component to which the module belongs. 547 548 ```shell 549 ./build.sh --product-name hispark_taurus_standard --build-target musl --build-target Module_name --ccache 550 ``` 551