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