subsys-build-reference.md 12.6 KB
Newer Older
A
Annie_wang 已提交
1 2 3 4
# Reference

## deps and external_deps

A
Annie_wang 已提交
5
When adding a module, you must declare its dependencies in **BUILD.gn**. **deps** specifies dependent modules in the same component, and **external_deps** specifies dependent modules between components.
A
Annie_wang 已提交
6 7 8

**Dependency Types**

9
![Dependency Types](figures/dependency_types.png)
A
Annie_wang 已提交
10

A
Annie_wang 已提交
11
The dependency between modules can be classified into **deps** (left in the figure above) and **external_deps** (right in the figure above).
A
Annie_wang 已提交
12

A
Annie_wang 已提交
13
- **deps**: The dependent module to be added belongs to the same part with the current module. For example, module 2 depends on module 1, and both modules 1 and 2 belong to the same component.
A
Annie_wang 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

- **external_deps**: The dependent module to be added belongs to another component. For example, module 2 depends on module 1, and modules 1 and 2 belong to different components.

- Example of **deps**:

  ```shell
  import("//build/ohos.gni")
  ohos_shared_library("module1") {
    ...
    part_name = "part1"   # (Mandatory) Name of the component to which the module belongs.
    ...
  }
  ```

  ```shell
  import("//build/ohos.gni")
  ohos_shared_library("module2") {
    ...
    deps = [
      "GN target of module 1",
    ...
A
Annie_wang 已提交
35 36
   ]                      # Intra-component dependency
  part_name = "part1"     # (Mandatory) Name of the component to which the module belongs.
A
Annie_wang 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
  }
  ```

- Example of **external_deps**:

  ```shell
  import("//build/ohos.gni")
  ohos_shared_library("module1") {
    ...
    part_name = "part1"   # (Mandatory) Name of the component to which the module belongs.
    ...
  }
  ```

  ```shell
  import("//build/ohos.gni")
  ohos_shared_library("module2") {
    ...
    external_deps = [
      "part1:module1",
    ...
A
Annie_wang 已提交
58 59
    ]                      # Inter-component dependency. The dependent module must be declared in inner_kits by the dependent component.
    part_name = "part2"    # (Mandatory) Name of the component to which the module belongs.
A
Annie_wang 已提交
60 61 62
  }
  ```

A
Annie_wang 已提交
63
 > **NOTE**<br>The dependency between components must be written in the format of **Component name:Module name** in **external_deps**. The dependent module must be declared in **inner_kits**.
A
Annie_wang 已提交
64 65 66

## Using Sanitizer

A
Annie_wang 已提交
67
When adding a module, you can enable the Sanitizer, such as the integer overflow check and control-flow integrity (CFI), provided by the compiler as required. You can also enable the debug or release mode and configure a blocklist. Each configuration item is optional and **false** by default. You can also leave it empty. 
A
Annie_wang 已提交
68

A
Annie_wang 已提交
69
Sanitizer configuration example:
A
Annie_wang 已提交
70 71 72 73

``` shell
  ohos_shared_library("example") {
    sanitize = {
A
Annie_wang 已提交
74 75 76 77 78 79 80 81
      cfi = true                            # Enable the CFI check.
      cfi_cross_dso = true                  # Enable the cross-DSO CFI check.
      integer_overflow = true               # Enable the integer overflow check.
      boundary_sanitize = true              # Enable the bounds check.
      ubsan = true                          # Enable some UBSAN options.
      all_ubsan = true                      # Enable all UBSAN options.
      debug = true                          # Enable the debug mode, which is disabled by default.
      blocklist = "./blocklist.txt"         # Path of the blocklist.
A
Annie_wang 已提交
82 83 84 85 86
    }
    ...
  }
```

A
Annie_wang 已提交
87
**Supported Sanitizer Types**
A
Annie_wang 已提交
88

A
Annie_wang 已提交
89
Currently, Sanitizers provides the following functions:
A
Annie_wang 已提交
90

A
Annie_wang 已提交
91 92 93 94 95
- **integer_overflow**: provides check of unsigned integer overflow (unsigned_integer_overflow), check of signed integer overflow (signed_integer_overflow), or both (integer_overflow).
- CFI: provides CFI and cross-DSO CFI checks.
- **boundary_sanitize**: provides the bounds check.
- **ubsan**: checks some Undefined Behavior Sanitizer (UBSAN) options, including **bool**, **integer-divide-by-zero**, **return**, **returns-nonnull-attribute**, **shift-exponent**, **unreachable**, and **vla-bound**.
- **all_ubsan**: checks all UBSAN options.
A
Annie_wang 已提交
96

A
Annie_wang 已提交
97
**Release and Debug Modes**
A
Annie_wang 已提交
98

A
Annie_wang 已提交
99
**Debug** specifies whether the debug mode or the release mode is used. The default value **false** indicates that the release mode is used. The value **true** explicitly declares the debug mode. The **debug** option takes effect only for the Sanitizer and does not determine whether a module is debuggable. In the build configuration for a module in release version, you are advised to set **debug** to **false** (enable the release mode) or leave it unspecified.
A
Annie_wang 已提交
100

A
Annie_wang 已提交
101
- Debug mode: If debug mode is enabled, abundant error-related information is provided to help locate faults. When an error occurs, the application will be resumed instead of being interrupted to further identify subsequent errors.
A
Annie_wang 已提交
102

A
Annie_wang 已提交
103
- Release mode: If release mode is enabled, the application will be directly interrupted when an error occurs. This can protect the system against errors or maliciously attacks.
A
Annie_wang 已提交
104

A
Annie_wang 已提交
105

A
Annie_wang 已提交
106
**Blocklist**
A
Annie_wang 已提交
107

A
Annie_wang 已提交
108
The blocklist specifies the functions or source programs that are not affected by Sanitizer in the module. It prevents benign behavior from being identified as errors or prevents hotspot functions from generating unreasonable and unacceptable overheads. Exercise caution when using this function. 
A
Annie_wang 已提交
109

A
Annie_wang 已提交
110
Blocklist example:
A
Annie_wang 已提交
111

A
Annie_wang 已提交
112 113 114 115 116 117 118 119
```
[cfi]
fun:*([Tt]est|TEST)*
fun: main

[integer]
src:example/*.cpp
```
A
Annie_wang 已提交
120

A
Annie_wang 已提交
121 122 123 124 125 126 127 128 129

## Information Collected by the Open Source Software Notice

An open source software notice is a file related to the project open source. It collects license information to comply with open source specifications.

**Information to Collect**

The notice collects only the licenses of the modules packaged in the image. For example, the licenses of the tools (such as Clang, Python, and Ninja) used during the build process are not collected.

A
Annie_wang 已提交
130
A static library itself is not packaged. However, if it is packaged into the system as part of a dynamic library or an executable file, the license of the static library will be collected for completeness.
A
Annie_wang 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

The final **Notice.txt** file must include all licenses used by the files in the image and the mapping between modules and licenses.

The **Notice.txt** file is located in the **/system/etc/** directory.

**Rules for Collecting Information**

Licenses are collected by priority, which ranges from 1 to 4 in descending order of seniority.

1. Licenses that are directly declared in a module's **BUILD.gn** are given the top priority. The following is an example:

   ```shell
   ohos_shared_library("example") {
       ...
       license_file = "path-to-license-file"
       ...
   }
   ```

2. If there is no explicitly declared license, the build script searches for the **Readme.OpenSource** file in the directory of **BUILD.gn**, parses the file, and collects the obtained licenses. If the **Readme.OpenSource** file does not contain license information, an error will be reported.

A
Annie_wang 已提交
152
3. If the **Readme.OpenSource** file does not exist, the build script searches for the **License**, **Copyright**, and **Notice** files from the current directory to the root directory of the source code by default. The obtained license information will be used as the licenses of the module.
A
Annie_wang 已提交
153 154 155 156 157

4. If no license is found, the default license (Apache License 2.0) will be used.

Pay attention to the following:

A
Annie_wang 已提交
158 159
- For third-party open-source software, such as OpenSSL and ICU, **Readme.OpenSource** must be configured in the source code directory. Check whether **Readme.OpenSource** is in the same directory as **BUILD.gn** and whether the licenses configured in **Readme.OpenSource** are valid.
- If the source code is not licensed under Apache License 2.0, the corresponding license file must be provided in the source code directory or declared in **license_file** for the module.
A
Annie_wang 已提交
160 161 162 163 164 165 166
- If the source code file added to **BUILD.gn** is not from the current directory, check whether the license in the repository where the source code file is located is the same as that in the repository of **BUILD.gn**.

## Parameters for Accelerating Local Build

The following parameters can be added to the build command to speed up the build process:

- **--ccache**
A
Annie_wang 已提交
167
  - Ccache caches the output of C/C++ compilation. If the compilation input remains unchanged the next time, the compilation can be skipped and the output can be taken from the cache.
A
Annie_wang 已提交
168 169 170
  - Installing ccache:
    - Quick installation: Run the **sudo apt-get install ccache** command.
    - Download the binary file from the [official website](https://ccache.dev/download.html) and configure the ccache path to the environment variable.
A
Annie_wang 已提交
171
  - Usage: Run the **./build.sh --product-name** *Product_name* **--ccache** command.
A
Annie_wang 已提交
172 173
- **--fast-rebuild**
  - The compilation process includes preloader -> loader -> GN -> Ninja. If the GN and product configuration files are not modified locally, adding **--fast-rebuild** will start from Ninja directly.
A
Annie_wang 已提交
174
  - Usage: Run the **./build.sh --product-name** *Product_name* **--fast-rebuild** command.
A
Annie_wang 已提交
175 176
- **enable_notice_collection=false**
  - Adding this parameter can skip the process of collecting the module licenses of the open-source software.
A
Annie_wang 已提交
177
  - Usage: Run the **./build.sh --product-name** *Product_name* **--gn-args --enable_notice_collection=false --ccache** command.
A
Annie_wang 已提交
178 179 180
- **--build-target**
  - This parameter specifies the module to compile. You can obtain the module name as follows:
    - Pay attention to keywords such as **group**, **ohos_shared_library**, and **ohos_executable** in **BUILD.gn**.
A
Annie_wang 已提交
181 182
    - Run **./build.sh --product-name** *Product_name* **--build-target** *Module_name* **--build-only-gn** to generate **build.ninja** and locate the related module name in the file.
  - Usage: Run the **./build.sh --product-name** *Product_name* **--build-target ark_js_host_linux_tools_packages** command.
A
Annie_wang 已提交
183 184 185 186 187 188 189

## Viewing Ninja Build Information

The **out/rk3568/.ninja_log** file records the build start time and end time (ms) of each module. A shorter interval indicates a faster build and higher compilation performance.

The four columns are start time, end time, modified timestamp (mtime), and command hash from left to right.

190
![Ninja_Trace](figures/Ninja_Trace.png)
A
Annie_wang 已提交
191 192 193 194 195 196 197 198 199 200

You can graphically display the build time as follows:

- Open **build.trace** locally.
  Decompress **out/rk3568/build.trace.gz** and drag **build.trace** to **chrome://tracing/**.
- Open **build.trace** at **ci.openharmony.cn/events**.
  You can open the **build.trace.html** file in each compilation output as follows:
  1. Click **Success** under **Static Check**.

  2. Click **Output** in the **Output** column. The **build.trace.html** file is displayed in the **build_trace** column on the left. Click the file to open it.
A
Annie_wang 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266

## Customizing the chip_prod Image

### When to Use

The different capabilities for the products in the same chip solution are placed in the **chip_prod** partition. You need to generate the **chip_prod.img** specific to the product.

### Procedure
1. Configure the **config.json** file.
   
   In the **config.json** file, add **chipprod_config_path**, which specifies the path of the product definition file.
   The file is named **chip_product_list.gni**, and in the **chip_product_list = ["productA", "productB", ...]** format.
   
   Example:
   
   To customize **chip_prod.img** for **MyProduct**, modify the **//vendor/Product vendor/MyProduct/config.json** as follows:
   
   ```shell
	{
        "product_name": "MyProduct",                                 # Product name.
        "version": "3.0",                                            # config.json version, which is 3.0.
        "chipprod_config_path": "",                                  # (Optional) Path of the chipprod configuration file.
   "subsystems": [
          {
            "subsystem": "arkui",                                    # Subsystem of the product. 
            "components": [
              {
                  "component": "ace_engine",
                  "features":[ "ace_engine_feature_enable_web = true",
                    "ace_engine_feature_enable_accessibility = true" ] }   
            ]
          },
          {
           ...
          }
         ...
      More subsystems and components.
        }
   }
   ```
   
2. Configure the module.

   If the configuration file has different product configurations, for example, to generate **chip_prod.img** for product A, you need to configure **install_images** and **module_install_dir** for module compilation.

   The following uses **ohos_prebuilt_executable** as an example:

   ```shell
   ohos_prebuilt_executable("moduleXXX"){
   install_images = [ "chip_prod" ]
   module_install_dir = "productA/etc/***"     # The path must start with productA.
   }
   ```

3. Run the build command.
```shell
./build.sh --product-name {product_name} --build-target chip_prod_image
```

4. Generate the images.
   If products A and B are defined (**chip_product_list = ["productA", "productB"]**) and a module is installed in the products, the following images are generated:
   
   ```
   images/productA/chip_prod.img
   images/productB/chip_prod.img
   ```