• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Component Building Specifications
2
3## About This Document
4
5### Purpose
6
7Compilation and building is an important part for implementing the component-based design. A component in the compiled state should be maintainable, portable, and loosely coupled. This document provides guidelines for writing build scripts so that the components to build are configurable, reusable, and tailorable, with reasonable dependencies.
8
9### Basic Concepts
10
11**Component**
12
13A component is a basic unit that constitutes OpenHarmony system capabilities. It contains the minimum required source code and has independent repositories and directories. It can be instantiated into different libraries or binary files on different devices.
14
15**Feature**
16
17Component features are configurable options in the build of a product. A component can be configured with different features to adapt to different product form factors. The configuration of component features affects only the implementations of component internal functions. It does not affect the public APIs (APIs provided by the component for applications) or inner APIs (APIs between components).
18
19**Dependency**
20
21A component in the compiled state has the following dependencies:
22
23- Conditional dependency: The dependency can be tailored in specific scenarios, and the removal of the dependency does not affect the public or inner APIs of the component. For example, audio has conditional dependency on Bluetooth.
24- Strong dependency: The dependency between components cannot be tailored. For example, the syscap component has strong dependency on the security library functions.
25
26### General Principles
27
28The compilation and building of components must comply with the following:
29
30**Independent and Autonomous**
31
32The component in the compiled state must be highly cohesive. Exercise caution when adding external dependencies, and minimize static dependencies in build.
33
34**Reasonable Dependency**
35
36Set up inter-component dependency based on the interfaces between components. Avoid the dependency on the modules or header files of other components.
37
38**Product Independent**
39
40The component in the compiled state should be applicable to multiple products. Do not use product names in build scripts.
41
42### Conventions
43
44**Rule**: a convention that must be complied with
45
46**Suggestion**: a convention that must be taken into consideration
47
48### Guarding Method
49
50The gated check-in conducts the following checks on the build configuration files:
51
52Prebuild check: The files are checked in the prebuild phase. If an error is detected, the build stops.
53
54Static check: The check tool scans and checks configuration files for errors.
55
56### Exception
57
58An exception is allowed only with sufficient reasons as long as the general principles are not violated.
59
60However, exceptions compromise code consistency and should be avoided as far as possible. Exceptions to the "rules" should be rare.
61
62## Naming
63
64The names of variables and build targets in build scripts, templates, gni files, and objects and data in component description files must be in the kernel style (unix_like). That is, the words are in lowercase and separated by underscores (_). For example, **startup_init**.
65
66### Rule 1.1 Use consistent format for component names.
67- The component name must reflect the functions of the component.
68- The component name must be globally unique in the system.
69- The component name cannot exceed 63 valid characters.
70- The component name consists of lowercase letters and underscores (_), for example, **unix_like**.
71
72> ![icon-note.gif](public_sys-resources/icon-note.gif) **Exception**: Third-party open-source software can use the native naming format, for example, **cJson**.
73
74### Rule 1.2 Name features in the *component name*_*feature name* format.
75
76A feature is a configurable option declared by a component. Adding a component name prefix can prevent duplicate feature names.
77
78Example:
79
80```py
81declare_args() {
82  dsoftbus_conn_p2p = true # dsoftbus is the component name, and conn_p2p is the feature name.
83  dsoftbus_conn_ble = false # dsoftbus is the component name, and conn_ble is the feature name.
84}
85```
86
87Guarding method: prebuild check
88
89### Suggestion 1.1: Name the build targets in the *component name*_*module name* format.
90
91A component may have multiple build targets (modules). The component and module names help you quickly locate the component based on the output (library or executable file) and prevents duplicate names.
92
93Example:
94```py
95ohos_shared_library("data") # Inaccurate, too general, and easy to duplicate
96```
97Example:
98```py
99ohos_shared_library("cellular_data_napi") # Good example
100```
101
102## Description File
103
104The **bundle.json** file defines a component. It contains information, such as the root directory, name, function description, version number, interface definition, and build entry of a component. The information in **bundle.json** file must be correct.
105
106### Rule 2.1 Ensure correct component information in the file.
107
108| Field| Type| Mandatory| Description| Guarding Method|
109|---|---|---|---|---|
110|name|String|Yes|OpenHarmony package manager (HPM) package name of the component.<br>Naming rule: @{organization}/{component_name}<br>{component_name} must comply with **Rule 1.1**.|Static check|
111|version|String|Yes|Component version number, which must be consistent with that of OpenHarmony.|Static check|
112|destPath|String|Yes|Root directory of the component source code. The root directory of each component must be unique.|Static check|
113|component:name|String|Yes|Component name, which must comply with **Rule 1.1**.|Static check|
114|component:subsystem|String|Yes|Subsystem to which the component belongs.<br>The subsystem name consists of lowercase letters and cannot contain underscores (_).|Static check|
115|component:syscap|String list|No|System capabilities.<br>Naming rule: **SystemCapability**.*Subsystem*.*Component capability*.*Sub-capability* (optional) in upper camel case<br>Example: **SystemCapability.Media.Camera,SystemCapability.Media.Camera.Front**|Static check|
116|component:features|String list|No|Features that can be configured for the component.<br>The feature name must comply with **Rule 1.2**.|Static check|
117|component:adapted_system_type|String list|Yes|Type of the system to which the component applies.<br>The value can be **mini**, **small**, **standard**, or their combination.|Static check|
118|component:rom|String|Yes|ROM size, in KB.|Static check|
119|component:ram|String|Yes|RAM size, in KB.|Static check|
120|component:deps|String list|Yes|Dependencies of the component, including other components and third-party open-source software.<br>The dependencies must be the same as that in the component build script.|Prebuild check|
121
122
123### Suggestion 2.1 Place the component description file in the root directory of the component.
124
125The component directory is independent. Place the **bundle.json** file in the root directory of the component.
126
127## Variables
128
129The built-in variable values of the build target determine the content to compile, dependencies, and data to package.
130
131### Rule 3.1 Do not include the absolute or relative paths of other components in the build script of a component.
132
133Use **external_deps** to include the dependency between components. The variables **sources**, **include_dirs**, **configs**, **public_configs**, **deps**, and **public_deps** of the component build target cannot reference the relative or absolute paths of other components.
134
135- sources
136
137  **Sources** can contain only the source code of a component. If **sources** contain the source code of other components, the independence of the component's source code directories will be violated.
138
139- include_dirs
140
141  **include_dirs** can contain only the header file paths of a component. The dependencies on other components are automatically imported through **external_deps**.
142
143- configs
144
145  **configs** can reference only the configuration paths of a component. Referencing the **configs** of other components may cause interface dependency.
146
147- pulic_configs
148
149  **public_configs** can reference only the configuration paths of a component. Referencing the **configs** of other components may cause interface dependency.
150
151- deps
152
153  **deps** can contain only dependencies between the modules in a component. Referencing a module in another component may cause dependency on the module and interfaces of the referenced component.
154
155  Example:
156
157  base/foos/foo_a/BUILD.gn
158
159  ```py
160  deps = [ "//base/foo/foo_b:b" ] # Not recommended. deps contains the absolute path of another component.
161  deps = [ "../../foo_b:b" ] # Not recommended. deps contains the relative path of another component.
162  deps = [ "a" ] # Recommended.
163  ```
164
165  > ![icon-note.gif](public_sys-resources/icon-note.gif) **Exception**: References to third-party open-source software are allowed.
166
167- public_deps
168
169  **Public_deps** can contain only dependencies between the modules in a component. Referencing a module in another component may cause dependency on the module and interfaces of the referenced component.
170
171  > ![icon-note.gif](public_sys-resources/icon-note.gif) **Exception**: References to third-party open-source software are allowed.
172
173
174Guarding method: static check
175
176### Rule 3.2 The component name and subsystem name must be specified for the component build target.
177
178**part_name** and **subsystem_name** are mandatory for **ohos_shared_library**, **ohos_static_library**, **ohos_executable_library**, and **ohos_source_set** of a component.
179
180The following uses **ohos_shared_library** in **developtools/syscap_codec/BUILD.gn** as an example.
181
182```py
183ohos_shared_library("syscap_interface_shared") {
184  include_dirs = [
185    "include",
186    "src",
187  ]
188  public_configs = [ ":syscap_interface_public_config" ]
189  sources = [
190    "./interfaces/inner_api/syscap_interface.c",
191    "./src/endian_internal.c",
192    "./src/syscap_tool.c",
193  ]
194  deps = [
195    "//third_party/bounds_checking_function:libsec_static",
196    "//third_party/cJSON:cjson_static",
197  ]
198
199  subsystem_name = "developtools" # subsystem_name is mandatory.
200  part_name = "syscap_codec" # part_name is mandatory.
201}
202```
203
204Guarding method: static check
205
206### Suggestion 3.1 Use relative paths for internal references of a component.
207
208Using relative paths for references within a component can:
209
210- Make the script simpler.
211
212- Decouple the build script of a component from the root directory of the component.
213
214Example:
215
216base/foos/foo_a/BUILD.gn
217
218```py
219include_dirs = [
220    "./include", # Recommended.
221    "//base/foo/foo_a/include" # Not recommended.
222]
223
224deps = [
225    "sub_module:foo", # Recommended.
226    "base/foo/foo_a/sub_module:foo" # Not recommended.
227]
228```
229
230Guarding method: static check
231
232### Suggestion 3.2 Make the internal modules of a component only visible to the component.
233
234Set **visibility** for the internal modules of a component to prevent them from being dependencies of other components.
235
236Example:
237
238base/foos/foo_a/BUILD.gn
239
240```py
241ohos_shared_library("foo_a") {
242    visibility = [ "./*" ] # foo_a is visible only to base/foo/foo_a and its subdirectories.
243}
244
245ohos_shared_library("foo_a") {
246    visibility = [ ":*" ] # foo_a is visible only to this BUILD.gn.
247}
248```
249
250## Others
251
252### Rule 4.1 Do not use the product name variable in the component build script.
253
254A component is a common system capability and is irrelevant to a specific product. If the product name is used in the build script, the component functions are bound to the product, which violates the commonality of the component. Abstract the differences between components in different product forms as features or runtime plug-ins.
255
256> ![icon-note.gif](public_sys-resources/icon-note.gif) **Exception**: The build scripts of third-party components in the **vendor** and **device** directories are excluded.
257
258Guarding method: static check
259
260### Suggestion 4.1 Do not import .gni files in directories of other components.
261
262The **.gni** file declares the internal build variables and templates of the component. Importing the **.gni** file of another component means to use the internal variables and templates of another component, which introduces the dependency on that component. The variables, args, and templates that affect multiple components should be defined in the **.gni** file of the build framework.
263
264> ![icon-note.gif](public_sys-resources/icon-note.gif) **Exception**: The .gni file (containing global build options) of the build framework in the **build** directory can be imported by all components.
265
266Guarding method: static check
267
268### Suggestion 4.2 Use a unified template for component build units.
269
270Use **ohos_** templates, such as **ohos_shared_library**, **ohos_static_library**, **ohos_executable**, and **ohos_source_set**, for the build units of mini, small, and standard systems.
271
272Example:
273
274```py
275  executable ("foundation") {# The built-in template is not recommended.
276    ...
277  }
278
279  ohos_executable("foundation") {# The ohos template is recommended.
280    ...
281  }
282```
283