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  ![](figures/module_addition_process.png)
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