• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Building Mini and Small Systems<a name="EN-US_TOPIC_0000001060646620"></a>
2
3## Overview<a name="section10958256161119"></a>
4
5The Compilation and Building subsystem is a build framework that supports module-based OpenHarmony development using Generate Ninja \(GN\) and Ninja. You can use this subsystem to:
6
7-   Assemble modules for a product and build the product.
8
9-   Build chipset source code independently.
10-   Build a single module independently.
11
12### Basic Concepts<a name="section1732301411128"></a>
13
14Learn the following concepts before you start compilation and building:
15
16-   Subsystem
17
18    A subsystem is a logical concept. It consists of one or more modules. OpenHarmony is designed with a layered architecture, which consists of the kernel layer, system service layer, framework layer, and application layer from bottom to top. System functions are developed by the level of system, subsystem, and module. In a multi-device deployment scenario, you can customize subsystems and modules as required.
19
20
21-   Module
22
23    A module is a reusable, configurable, and tailorable function unit. Each module has an independent directory, and multiple modules can be developed concurrently and built and tested independently.
24
25-   **GN**
26
27    Generate Ninja \(GN\) is used to generate Ninja files.
28
29-   **Ninja**
30
31    Ninja is a small high-speed build system.
32
33-   **hb**
34
35    hb is a command line tool for OpenHarmony to execute build commands.
36
37
38### Directory Structure<a name="section1588744014121"></a>
39
40```
41build/lite
42├── components                  # Module description file
43├── figures                     # Figures in the readme file
44├── hb                          # hb pip installation package
45├── make_rootfs                 # Script used to create the file system image
46├── config                      # Build configuration
47│   ├── component               # Module-related template definition
48│   ├── kernel                  # Kernel-related build configuration
49│   └── subsystem               # Subsystem build configuration
50├── platform                    # ld script
51├── testfwk                     # Test build framework
52└── toolchain                   # Build toolchain configuration, which contains the compiler directories, build options, and linking options
53```
54
55### **Build Process**<a name="section15761735134"></a>
56
57[Figure 1](#fig9744112715161)  shows the build process.
58
59**Figure  1**  Build process<a name="fig9744112715161"></a>
60![](figure/build-process.jpg "build-process")
61
621.  Use  **hb set **to set the OpenHarmony source code directory and the product to build.
632.  Use  **hb build**  to build the product, development board, or module. The procedure is as follows:
64    -   Read the  **config.gni**  file of the development board selected. The file contains the build toolchain, linking commands, and build options.
65    -   Run the  **gn gen**  command to read the product configuration and generate the  **out**  directory and  **ninja**  files for the solution.
66    -   Run  **ninja -C out/board/product**  to start the build.
67    -   Package the build result, set the file attributes and permissions, and create a file system image.
68
69
70## Configuration Rules<a name="section2345183962710"></a>
71
72To ensure that the chipset and product solutions are pluggable and decoupled from OpenHarmony, the paths, directory trees, and configuration of modules, chipset solutions, and product solutions must comply with the following rules:
73
74### **Module**<a name="section142532518308"></a>
75
76The source code directory for a module is named in the  _\{Domain\}/\{Subsystem\}/\{Module\}_  format. The module directory tree is as follows:
77
78>![](../public_sys-resources/icon-caution.gif) **CAUTION:**
79>Define module attributes, such as the name, source code directory, function description, mandatory or not, build targets, RAM, ROM, build outputs, adapted kernels, configurable features, and dependencies, in the JSON file of the subsystem in the  **build/lite/components**  directory. When adding a module, add its definition to the JSON file of the corresponding subsystem. The module configured for a product must have been defined in a subsystem. Otherwise, the verification will fail.
80
81```
82component
83├── interfaces
84│   ├── innerkits  # APIs exposed internally among modules
85│   └── kits       # App APIs provided for app developers
86├── frameworks     # Framework implementation
87├── services       # Service implementation
88└── BUILD.gn       # Build script
89```
90
91The following example shows how to define attributes of the sensor module of the pan-sensor subsystem:
92
93```
94{
95  "components": [
96    {
97      "component": "sensor_lite",                # Module name
98      "description": "Sensor services",          # Brief description of the module
99      "optional": "true",                        # Whether the module is mandatory for the system
100      "dirs": [                                  # Source code directory of the module
101        "base/sensors/sensor_lite"
102      ],
103      "targets": [                               # Build entry of the module
104        "//base/sensors/sensor_lite/services:sensor_service"
105      ],
106      "rom": "92KB",                             # Module ROM
107      "ram": "~200KB",                           # Module RAM (estimated)
108      "output": [ "libsensor_frameworks.so" ],   # Module build outputs
109      "adapted_kernel": [ "liteos_a" ],          # Adapted kernel for the module
110      "features": [],                            # Configurable features of the module
111      "deps": {
112        "components": [                          # Other modules on which the module depends
113          "samgr_lite",
114          "ipc_lite"
115
116        ],
117        "third_party": [                         # Open-source third-party software on which the module depends
118          "bounds_checking_function"
119        ]
120      }
121    }
122  ]
123}
124```
125
126Observe the following rules when building the  **BUILD.gn**  module:
127
128-   The build target name must be the same as the module name.
129-   Define the configurable features in the  **BUILD.gn**  file of the module. Name the configurable features in the  **ohos\_**\{_subsystem_\}**\_**\{_module_\}**\_**\{_feature_\} format. Define the features in module description and configure them in the  **config.json**  file.
130-   Define macros in the  **OHOS\_**\{_SUBSYSTEM_\}**\_**\{_MODULE_\}**\_**\{_FEATURE_\} format.
131
132    >![](../public_sys-resources/icon-note.gif) **NOTE:**
133    >GN is used as the build script language for modules. For details about how to use GN, see https://gn.googlesource.com/gn/+/master/docs/quick_start.md. In GN, a module is a build target, which can be a static library, a dynamic library, an executable file, or a group.
134
135
136The following example shows how to build the  **foundation/graphic/ui/BUILD.gn**  file for a graphics UI module:
137
138```
139	# Declare the configurable features of the module
140	declare_args() {
141  enable_ohos_graphic_ui_animator = false # Animation switch
142  ohos_ohos_graphic_ui_font = "vector"    # Configurable font type, which can be vector or bitmap
143	}
144
145	# Basic module functions
146	shared_library("base") {
147	  sources = [
148	    ......
149	  ]
150	  include_dirs = [
151	    ......
152	  ]
153	}
154
155	# Build only when the animator is enabled
156	if(enable_ohos_graphic_ui_animator ) {
157	  shared_library("animator") {
158	    sources = [
159	      ......
160	    ]
161	    include_dirs = [
162              ......
163	    ]
164	    deps = [ :base ]
165	  }
166	}
167	......
168	# It is recommended that the target name be the same as the module name, which can be an executable .bin file, shared_library (.so file), static_library (.a file), or a group.
169	executable("ui") {
170	  deps = [
171	    ":base"
172	  ]
173
174	  # The animator feature is configured by the product.
175	  if(enable_ohos_graphic_ui_animator ) {
176	      deps += [
177	        "animator"
178	      ]
179	  }
180	}
181```
182
183### **Chipset**<a name="section121501451143710"></a>
184
185-   The chipset solution is a complete solution based on a development board. The solution includes the drivers, API adaptation, and SDK.
186-   The chipset solution is a special module, whose source code directory is named in the  _**device**/\{Chipset solution vendor\}/\{Development board\}_  format.
187-   The chipset solution module is built by default based on the development board selected by the product.
188
189The chipset solution directory tree is as follows:
190
191```
192device
193└── company                         # Chipset solution vendor
194    └── board                       # Name of the development board
195        ├── BUILD.gn                # Build script
196        ├── hals                    # Southbound APIs for OS adaptation
197        ├── linux                   # Linux kernel version (optional)
198        │   └── config.gni          # Build options for the Linux version
199        └── liteos_a                # LiteOS kernel version (optional)
200            └── config.gni          # Build options for the LiteOS Cortex-A version
201```
202
203>![](../public_sys-resources/icon-note.gif) **NOTE:**
204>The  **config.gni**  file contains build-related configurations of the development board. The parameters in the file are globally visible to the system and can be used to build all OS modules during the build process.
205
206The  **config.gni**  file contains the following key parameters:
207
208```
209kernel_type:            kernel used by the development board, for example, liteos_a, liteos_m, or linux.
210kernel_version:         kernel version used by the development board, for example, 4.19.
211board_cpu:              CPU of the development board, for example, cortex-a7 or riscv32.
212board_arch:             chipset architecture of the development board, for example, armv7-a or rv32imac.
213board_toolchain:        name of the customized build toolchain used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used by default.
214board_toolchain_prefix: prefix of the build toolchain, for example, gcc-arm-none-eabi.
215board_toolchain_type:  build toolchain type, for example, gcc or clang. Currently, only GCC and clang are supported.
216board_cflags:          build options of the .c file configured for the development board.
217board_cxx_flags:       build options of the .cpp file configured for the development board.
218board_ld_flags:        link options configured for the development board.
219```
220
221### **Product**<a name="section134549283435"></a>
222
223The product solution is a complete product based on a development board. It includes the OS adaptation, module assembly configuration, startup configuration, and file system configuration. The source code directory of a product solution is named in the  **vendor**/\{_Product solution vendor_\}/\{_Product name_\} format. A product solution is also a special module.
224
225The product solution directory tree is as follows:
226
227```
228vendor
229└── company                         # Product solution vendor
230    ├── product                     # Product name
231    │   ├── init_configs
232    │   │     ├── etc               # Startup configuration of the init process (only required for the Linux kernel)
233    │   │     └── init.cfg          # System service startup configuration
234    │   ├── hals                    # OS adaptation
235    │   ├── BUILD.gn                # Product build script
236    │   └── config.json             # Product configuration file
237    │   └── fs.yml                  # File system packaging configuration
238    └── ......
239```
240
241>![](../public_sys-resources/icon-caution.gif) **CAUTION:**
242>Create directories and files based on the preceding rules for new products. The Compilation and Building subsystem scans the configured products based on the rules.
243
244The key directories and files are described as follows:
245
2461.  **vendor/company/product/init\_configs/etc**
247
248    This folder contains the  **rcS**,  **S**_xxx_, and  **fstab**  scripts. The  **init**  process runs the  **rcS**,  **fstab**, and  **S**_00_-_xxx_  scripts in sequence before starting system services. The  **S**_xxx_  script contains content related to the development board and product. It is used to create device nodes and directories, scan device nodes, and change file permissions. These scripts are copied from the  **BUILD.gn**  file to the  **out**  directory of the product as required and packaged into the  **rootfs**  image.
249
2502.  **vendor/company/product/init\_configs/init.cfg**
251
252    This file is the configuration file for the  **init**  process to start services. Currently, the following commands are supported:
253
254    -   **start**: starts a service.
255    -   **mkdir**: creates a folder.
256    -   **chmod**: changes the permission on a specified directory or file.
257    -   **chown**: changes the owner group of a specified directory or file.
258    -   **mount**: mounts a device.
259
260    The fields in the file are described as follows:
261
262    ```
263    {
264        "jobs" : [{                                                     # Job array. A job corresponds to a command set. Jobs are executed in the following sequence: pre-init > init > post-init.
265                "name" : "pre-init",
266                "cmds" : [
267                    "mkdir /storage/data",                              # Create a directory.
268                    "chmod 0755 /storage/data",                         # Change the permission, which is in 0xxx format, for example, 0755.
269                    "mkdir /storage/data/log",
270                    "chmod 0755 /storage/data/log",
271                    "chown 4 4 /storage/data/log",                      # Change the owner group. The first number indicates the UID, and the second indicates the GID.
272                    ......
273                    "mount vfat /dev/mmcblock0 /sdcard rw, umask=000"    # The command is in the mount [File system type][source] [target] [flags] [data] format.
274                                                                        # Currently, flags can only be nodev, noexec, nosuid, or rdonly.
275                ]
276            }, {
277                "name" : "init",
278                "cmds" : [                                              # Start services based on the sequence of the cmds array.
279                    "start shell",                                      # Note that there is only one space between start and the service name.
280                    ......
281                    "start service1"
282                ]
283            }, {
284                "name" : "post-init",                                   # Job that is finally executed. Operations performed after the init process is started, for example, mounting a device after the driver initialization.
285                "cmds" : []
286            }
287        ],
288        "services" : [{                                                 # Service array. A service corresponds to a process.
289                "name" : "shell",                                       # Service name
290                "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"],    # Full path of the executable file. It must start with "path".
291                "uid" : 0,                                              # Process UID, which must be the same as that in the binary file.
292                "gid" : 0,                                              # Process GID, which must be the same as that in the binary file.
293                "once" : 0,                                             # Whether the process is a one-off process. 1: The proces is a one-off process. The init process does not restart it after the process exits. 0: The process is not a one-off process. The init process restarts it if the process exits.
294                "importance" : 0,                                       # Whether the process is a key process. 1: The process is a key process. If it exits, the init process restarts the board. 0: The process is not a key process. If it exits, the init process does not restart the board.
295                "caps" : [4294967295]
296            },
297            ......
298        ]
299    }
300    ```
301
3023.  **vendor/company/product/init\_configs/hals**
303
304    This file stores the content related to OS adaptation of the product. For details about APIs for implementing OS adaptation, see the readme file of each module.
305
3064.  **vendor/company/product/config.json**
307
308    The  **config.json**  file is the main entry for the build and contains configurations of the development board, OS modules, and kernel.
309
310    The following example shows the  **config.json**  file of the IP camera developed based on the hispark\_taurus development board:
311
312    ```
313    {
314    	"product_name": "ipcamera",                       # Product name
315		"version": "3.0",                                 # config.json version, which is 3.0
316        "type": "small",                                  # System type, which can be mini, small, or standard
317    	"ohos_version": "OpenHarmony 1.0",                # OS version
318    	"device_company": "hisilicon",                    # Chipset vendor
319    	"board": "hispark_taurus",                        # Name of the development board
320    	"kernel_type": "liteos_a",                        # Kernel type
321     	"kernel_version": "3.0.0",                        # Kernel version
322    	"subsystems": [
323    	  {
324        "subsystem": "aafwk",                         # Subsystem
325    	    "components": [
326          { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] }   # Module and its features
327    	    ]
328    	  },
329    	  {
330    	   ......
331    	  }
332    	  ......
333      More subsystems and modules
334    	}
335    }
336    ```
337
3385.  **vendor/company/product/fs.yml**
339
340    This file packages the build result to create a configuration file system image, for example,  **rootfs.img**  \(user-space root file system\) and  **userfs.img**  \(readable and writable file\). It consists of multiple lists, and each list corresponds to a file system. The fields are described as follows:
341
342    ```
343    fs_dir_name: (Mandatory) declares the name of the file system, for example, rootfs or userfs.
344    fs_dirs:     (Optional) configures the mapping between the file directory in the out directory and the system file directory. Each file directory corresponds to a list.
345    source_dir:  (Optional) specifies the target file directory in the out directory. If this field is missing, an empty directory will be created in the file system based on target_dir.
346    target_dir:  (Mandatory) specifies the corresponding file directory in the file system.
347    ignore_files: (Optional) declares ignored files during the copy operation.
348    dir_mode:    (Optional) specifies the file directory permission, which is set to 755 by default.
349    file_mode: (Optional) declares permissions of all files in the directory, which is set to 555 by default.
350    fs_filemode: (Optional) configures files that require special permissions. Each file corresponds to a list.
351    file_dir:    (Mandatory) specifies the detailed file path in the file system.
352    file_mode:   (Mandatory) declares file permissions.
353    fs_symlink:  (Optional) configures the soft link of the file system.
354    fs_make_cmd: (Mandatory) creates the file system script. The script provided by the OS is stored in the build/lite/make_rootfs directory. Linux, LiteOS, ext4, jffs2, and vfat are supported. Chipset vendors can also customize the script as required.
355    fs_attr:     (Optional) dynamically adjusts the file system based on configuration items.
356    ```
357
358    The  **fs\_symlink**  and  **fs\_make\_cmd**  fields support the following variables:
359
360    -   $\{root\_path\}
361
362        Code root directory, which corresponds to  **$\{ohos\_root\_path\}**  of GN
363
364    -   $\{out\_path\}
365
366        **out**  directory of the product, which corresponds to  **$\{root\_out\_dir\}**  of GN
367
368    -   $\{fs\_dir\}
369
370        File system directory, which consists of the following variables
371
372        -   $\{root\_path\}
373        -   $\{fs\_dir\_name\}
374
375    >![](../public_sys-resources/icon-note.gif) **NOTE:**
376    >**fs.yml**  is optional and does not need to be configured for devices without a file system.
377
3786.  **vendor/company/product/BUILD.gn**
379
380    This file is the entry for building the source code of the solution vendor and copying the startup configuration file. The  **BUILD.gn**  file in the corresponding product directory will be built by default if a product is selected. The following example shows how to build the  **BUILD.gn**  file of a product:
381
382    ```
383    group("product") { # The target name must be the same as the product name (level-3 directory name under the product directory).
384      deps = []
385      # Copy the init configuration.
386      deps += [ "init_configs" ]
387      # Others
388      ......
389    }
390    ```
391
392
393## Usage Guidelines<a name="section13754457192211"></a>
394
395### Prerequisites<a name="section31651120233"></a>
396
397The development environment has GN, Ninja, Python 3.7.4 or later, and hb available. For details about installation methods, see  [Environment Setup](../quick-start/quickstart-lite-env-setup.md).
398
399### Using hb<a name="section1133304172313"></a>
400
401**hb**  is a command line tool for OpenHarmony to execute build commands. Common hb commands are described as follows:
402
403**hb set**
404
405```
406hb set -h
407usage: hb set [-h] [-root [ROOT_PATH]] [-p]
408
409optional arguments:
410  -h, --help            show this help message and exit
411  -root [ROOT_PATH], --root_path [ROOT_PATH]
412                        Set OHOS root path
413  -p, --product         Set OHOS board and kernel
414```
415
416-   **hb set**  \(without argument\): starts the default setting process.
417-   **hb set -root** _dir_: sets the root directory of the code.
418-   **hb set -p**: sets the product to build.
419
420**hb env**
421
422Displays the current configuration.
423
424```
425hb env
426[OHOS INFO] root path: xxx
427[OHOS INFO] board: hispark_taurus
428[OHOS INFO] kernel: liteos
429[OHOS INFO] product: ipcamera
430[OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera
431[OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19
432```
433
434**hb build**
435
436```
437hb build -h
438usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]]
439                [--dmverity] [--tee] [-p PRODUCT] [-f] [-n]
440                [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch]
441                [component [component ...]]
442
443positional arguments:
444  component             name of the component
445
446optional arguments:
447  -h, --help            show this help message and exit
448  -b BUILD_TYPE, --build_type BUILD_TYPE
449                        release or debug version
450  -c COMPILER, --compiler COMPILER
451                        specify compiler
452  -t [TEST [TEST ...]], --test [TEST [TEST ...]]
453                        compile test suit
454  --dmverity            Enable dmverity
455  --tee                 Enable tee
456  -p PRODUCT, --product PRODUCT
457                        build a specified product with
458                        {product_name}@{company}, eg: camera@huawei
459  -f, --full            full code compilation
460  -n, --ndk             compile ndk
461  -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
462                        Compile single target
463  -v, --verbose         show all command lines while building
464  -shs, --sign_haps_by_server
465                        sign haps by server
466  --patch               apply product patch before compiling
467
468  --dmverity            Enable dmverity
469  -p PRODUCT, --product PRODUCT
470                        build a specified product with
471                        {product_name}@{company}, eg: ipcamera@hisilcon
472  -f, --full            full code compilation
473  -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
474                        Compile single target
475```
476
477-   **hb build**  \(without argument\): builds the code based on the configured code directory, product, and options. The  **-f**  option deletes all products to be built, which is equivalent to running  **hb clean**  and  **hb build**.
478-   **hb build** _\{module\_name\}_: builds a product module separately based on the development board and kernel set for the product, for example,  **hb build kv\_store**.
479-   **hb build -p ipcamera@hisilicon**: skips the  **set**  step and builds the product directly.
480-   You can run  **hb build**  in  **device/device\_company/board**  to select the kernel and start the build based on the current development board and the selected kernel to generate an image that contains the kernel and driver only.
481
482**hb clean**
483
484You can run  **hb clean**  to clear the build result of the product in the  **out**  directory and retain the  **args.gn**  and  **build.log**  files only. To clear files in a specified directory, add the directory parameter to the command, for example,  **hb clean out/xxx/xxx**.
485
486```
487hb clean
488usage: hb clean [-h] [out_path]
489
490positional arguments:
491  out_path    clean a specified path.
492
493optional arguments:
494  -h, --help  show this help message and exit
495```
496
497### Adding a Module<a name="section167110415315"></a>
498
499To add a module, determine the subsystem to which the module belongs and the module name, and then perform the following steps:
500
5011.  Add the module build script after the source code development is complete.
502
503    The following example adds the  **BUILD.gn**  script \(stored in the  **applications/sample/hello\_world**  directory\) to build the  **hello\_world**  module \(as an executable file\).
504
505    ```
506    executable("hello_world") {
507      include_dirs = [
508        "include",
509       ]
510      sources = [
511        "src/hello_world.c"
512      ]
513    }
514    ```
515
516    The above script is used to build  **hello\_world**  that can run on OpenHarmony.
517
518    To build the preceding module separately, select a product via the  **hb set**  command and run the  **-T**  command.
519
520    ```
521    hb build -f -T //applications/sample/hello_world
522    ```
523
524    After the module functions are verified on the development board, perform steps  [2 to 4](#li11471037297)  to configure the module to the product.
525
5262.  <a name="li11471037297"></a>Add module description.
527
528    The module description is stored in the  **build/lite/components**  directory. New modules must be added to the JSON file of the corresponding subsystem. The module description must contain the following fields:
529
530    -   **module**: name of the module
531    -   **description**: brief description of the module
532    -   **optional**: whether the module is optional
533    -   **dirs**: source code directory of the module
534    -   **targets**: module build entry
535
536    For example, to add the  **hello\_world**  module to the application subsystem, add the  **hello\_world**  object to the  **applications.json**  file.
537
538    ```
539    {
540      "components": [
541        {
542          "component": "hello_world",
543          "description": "Hello world.",
544          "optional": "true",
545          "dirs": [
546            "applications/sample/hello_world"
547          ],
548          "targets": [
549            "//applications/sample/hello_world"
550          ]
551        },
552        ...
553       ]
554    }
555    ```
556
5573.  Configure the module for the product.
558
559    The  **config.json**  file is stored in the  **vendor/company/product/**  directory. The file must contain the product name, OpenHarmony version, device vendor, development board, kernel type, kernel version, and the subsystem and module to configure. The following example adds the  **hello\_world**  module to the  **my\_product.json**  configuration file:
560
561    ```
562    {
563        "product_name": "hello_world_test",
564        "ohos_version": "OpenHarmony 1.0",
565        "device_company": "hisilicon",
566        "board": "hispark_taurus",
567        "kernel_type": "liteos_a",
568        "kernel_version": "1.0.0",
569        "subsystems": [
570          {
571            "subsystem": "applications",
572            "components": [
573              { "component": "hello_world", "features":[] }
574            ]
575          },
576          ...
577        ]
578    }
579    ```
580
5814.  Build the product.
582
583    1. Run the  **hb set**  command in the root code directory and select the product.
584
585    2. Run the  **hb build**  command.
586
587
588### Adding a Chipset Solution<a name="section1474718565412"></a>
589
590The following uses the RTL8720 development board provided by Realtek as an example. To a chipset solution, perform the following steps:
591
5921.  <a name="li1970321162111"></a>Create a directory for the chipset solution.
593
594    To create a directory based on  [Configuration Rules](#section2345183962710), run the following command in the root code directory:
595
596    ```
597    mkdir -p device/realtek/rtl8720
598    ```
599
6002.  Create a directory for kernel adaptation and build the  **config.gni**  file of the development board.
601
602    For example, to adapt the LiteOS-A kernel to the RTL8720 development board, configure the  **device/realtek/rtl8720/liteos\_a/config.gni**  file as follows:
603
604    ```
605    # Kernel type, e.g. "linux", "liteos_a", "liteos_m".
606    kernel_type = "liteos_a"
607
608    # Kernel version.
609    kernel_version = "3.0.0"
610
611    # Board CPU type, e.g. "cortex-a7", "riscv32".
612    board_cpu = "real-m300"
613
614    # Board arch, e.g. "armv7-a", "rv32imac".
615    board_arch = ""
616
617    # Toolchain name used for system compiling.
618    # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf.
619    # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain.
620    board_toolchain = "gcc-arm-none-eabi"
621
622    # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc.
623    board_toolchain_path =
624        rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin",
625                    root_build_dir)
626
627    # Compiler prefix.
628    board_toolchain_prefix = "gcc-arm-none-eabi-"
629
630    # Compiler type, "gcc" or "clang".
631    board_toolchain_type = "gcc"
632
633    # Board related common compile flags.
634    board_cflags = []
635    board_cxx_flags = []
636    board_ld_flags = []
637    ```
638
6393.  Build the script.
640
641    Create the  **BUILD.gn**  file in the development board directory. The target name must be the same as that of the development board. The content in the  **device/realtek/rtl8720/BUILD.gn**  file is configured as follows:
642
643    ```
644    group("rtl8720") { # The target can be shared_library, static_library, or an executable file.
645      # Content
646      ......
647    }
648    ```
649
6504.  Build the chipset solution.
651
652    Run the  **hb build**  command in the development board directory to start the build.
653
654
655### Adding a Product Solution<a name="section1097623294220"></a>
656
657You can use the Compilation and Building subsystem to customize product solutions by assembling chipset solutions and modules. The procedure is as follows:
658
6591.  Create a product directory.
660
661    The following uses the Wi-Fi IoT module on the RTL8720 development board as an example. Run the following command in the root code directory to create a product directory based on  [Configuration Rules](#section2345183962710):
662
663    ```
664    mkdir -p vendor/my_company/wifiiot
665    ```
666
6672.  Assemble the product.
668
669    Create the  **config.json**  file in the product directory. The  **vendor/my\_company/wifiiot/config.json**  file is as follows:
670
671    ```
672    {
673        "product_name": "wifiiot",                        # Product name
674        "version": "3.0",                                 # config.json version, which is 3.0
675        "type": "small",                                  # System type, which can be mini, small, or standard
676        "ohos_version": "OpenHarmony 1.0",                # OS version
677        "device_company": "realtek",                      # Name of the chipset solution vendor
678        "board": "rtl8720",                               # Name of the development board
679        "kernel_type": "liteos_m",                        # Kernel type
680        "kernel_version": "3.0.0",                        # Kernel version
681        "subsystems": [
682          {
683            "subsystem": "kernel",                        # Subsystem
684            "components": [
685              { "component": "liteos_m", "features":[] }  # Module and its features
686            ]
687          },
688          ...
689          {
690             More subsystems and modules
691          }
692        ]
693    }
694    ```
695
696    Before the build, the Compilation and Building subsystem checks the validity of fields, including  **device\_company**,  **board**,  **kernel\_type**,  **kernel\_version**,  **subsystem**, and  **component**. The  **device\_company**,  **board**,  **kernel\_type**, and  **kernel\_version**  fields must match the current chipset solution, and  **subsystem**  and  **component**  must match the module description in the  **build/lite/components**  file.
697
6983.  Implement adaptation to OS APIs.
699
700    Create the  **hals**  directory in the product directory and store the source code as well as the build script for OS adaptation in this directory.
701
7024.  Configure the system service.
703
704    Create the  **init\_configs**  directory in the product directory and then the  **init.cfg**  file in the newly created directory. Configure the system service to be started.
705
7065.  \(Optional\) Configure the init process only for the Linux kernel.
707
708    Create the  **etc**  directory in the  **init\_configs**  directory, and then the  **init.d**  folder and the  **fstab**  file in the newly created directory. Then, create the  **rcS**  and  **S**_xxx_  files in the  **init.d**  file and edit them based on product requirements.
709
7106.  \(Optional\) Configure the file system image only for the development board that supports the file system.
711
712    Create the  **fs.yml**  file in the product directory and configure it as required. A typical  **fs.yml**  file is as follows:
713
714    ```
715    -
716      fs_dir_name: rootfs # Image name
717      fs_dirs:
718        -
719          # Copy the files in the out/my_board/my_product/bin directory to the rootfs/bin directory and ignore the .bin files related to testing.
720          source_dir: bin
721          target_dir: bin
722          ignore_files:
723            - Test.bin
724            - TestSuite.bin
725        -
726          # Copy the files in the out/my_board/my_product/libs directory to the rootfs/lib directory, ignore all .a files, and set the file permissions to 644 and folder permissions 755.
727          source_dir: libs
728          target_dir: lib
729          ignore_files:
730            - .a
731          dir_mode: 755
732          file_mode: 644
733        -
734          source_dir: usr/lib
735          target_dir: usr/lib
736          ignore_files:
737            - .a
738          dir_mode: 755
739          file_mode: 644
740        -
741          source_dir: config
742          target_dir: etc
743        -
744          source_dir: system
745          target_dir: system
746        -
747          source_dir: sbin
748          target_dir: sbin
749        -
750          source_dir: usr/bin
751          target_dir: usr/bin
752        -
753          source_dir: usr/sbin
754          target_dir: usr/sbin
755        -
756          # Create an empty proc directory.
757          target_dir: proc
758        -
759          target_dir: mnt
760        -
761          target_dir: opt
762        -
763          target_dir: tmp
764        -
765          target_dir: var
766        -
767          target_dir: sys
768        -
769          source_dir: etc
770          target_dir: etc
771        -
772          source_dir: vendor
773          target_dir: vendor
774        -
775          target_dir: storage
776
777      fs_filemode:
778        -
779          file_dir: lib/ld-uClibc-0.9.33.2.so
780          file_mode: 555
781        -
782          file_dir: lib/ld-2.24.so
783          file_mode: 555
784        -
785          file_dir: etc/init.cfg
786          file_mode: 400
787      fs_symlink:
788        -
789          # Create the soft link ld-musl-arm.so.1 -> libc.so in the rootfs/lib directory.
790          source: libc.so
791          link_name: ${fs_dir}/lib/ld-musl-arm.so.1
792        -
793          source: mksh
794          link_name: ${fs_dir}/bin/sh
795        -
796          source: mksh
797          link_name: ${fs_dir}/bin/shell
798      fs_make_cmd:
799        # Create an ext4 image for the rootfs directory using the script.
800        - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
801    -
802      fs_dir_name: userfs
803      fs_dirs:
804        -
805          source_dir: storage/etc
806          target_dir: etc
807        -
808          source_dir: data
809          target_dir: data
810      fs_make_cmd:
811        - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
812
813    ```
814
8157.  \(Optional\) Configure patches if the product and modules need to be patched.
816
817    Create the  **patch.yml**  file in the product directory and configure it as required. A typical  **patch.yml**  file is as follows:
818
819    ```
820    # Directory in which the patch is to be installed
821    foundation/communication/dsoftbus:
822      # Directory in which the patch is stored
823      - foundation/communication/dsoftbus/1.patch
824      - foundation/communication/dsoftbus/2.patch
825    third_party/wpa_supplicant:
826      - third_party/wpa_supplicant/1.patch
827      - third_party/wpa_supplicant/2.patch
828      - third_party/wpa_supplicant/3.patch
829    ...
830    ```
831
832    If you add  **--patch**  when running the  **hb build**  command, the patch file can be added to the specified directory before the build.
833
834    ```
835    hb build -f --patch
836    ```
837
8388.  Build the script.
839
840    Create the  **BUILD.gn**  file in the product directory and write the script. The following  **BUILD.gn**  file uses the Wi-Fi IoT module in  [1](#li1970321162111)  as an example:
841
842    ```
843    group("wifiiot") { # The target name must be the same as the product name.
844      deps = []
845      # Copy the init configuration.
846      deps += [ "init_configs" ]
847      # Build the hals directory.
848      deps += [ "hals" ]
849      # Others
850      ......
851    }
852    ```
853
8549.  Build the product.
855
856    Run the  **hb set**  command in the code root directory, select the new product as prompted, and run the  **hb build**  command.
857
858
859## Troubleshooting<a name="section19909721104319"></a>
860
861### Invalid -- w Option<a name="section138233464318"></a>
862
863-   **Symptom**
864
865    The build fails, and "usr/sbin/ninja: invalid option -- w" is displayed.
866
867-   **Cause**
868
869    The Ninja version in the build environment is outdated and does not support the  **--w**  option.
870
871-   **Solution**
872
873    Uninstall Ninja and GN and follow the instructions provided in  [IDE](../get-code/gettools-ide.md)  to install Ninja and GN of the required version.
874
875
876### Library ncurses Not Found<a name="section151033911442"></a>
877
878-   **Symptom**
879
880    The build fails, and "/usr/bin/ld: cannot find -lncurses" is displayed.
881
882-   **Cause**
883
884    The ncurses library is not installed.
885
886-   **Solution**
887
888    ```
889    sudo apt-get install lib32ncurses5-dev
890    ```
891
892
893### mcopy not Found<a name="section19811838104418"></a>
894
895-   **Symptom**
896
897    The build fails, and "line 77: mcopy: command not found" is displayed.
898
899-   **Cause**
900
901    mcopy is not installed.
902
903-   **Solution**
904
905    ```
906    sudo apt-get install dosfstools mtools
907    ```
908
909
910### No riscv File or Directory<a name="section03111118451"></a>
911
912-   **Symptom**
913
914    The build fails, and the following information is displayed:
915
916    riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory.
917
918-   **Cause**
919
920    Permission is required to access files in the  **riscv**  compiler directory.
921
922-   **Solution**
923
924    Run the following command to query the directory where  **gcc\_riscv32**  is located:
925
926    ```
927    which riscv32-unknown-elf-gcc
928    ```
929
930    Run the  **chmod**  command to change the directory permission to  **755**.
931
932
933### No Crypto<a name="section69981127125013"></a>
934
935-   **Symptom**
936
937    The build fails, and "No module named 'Crypto'" is displayed.
938
939-   **Cause**
940
941    Crypto is not installed in Python 3.
942
943-   **Solution**
944    1.  Run the following command to query the Python version:
945
946        ```
947        python3 --version
948        ```
949
950    2.  Ensure that Python 3.7 or later is installed, and then run the following command to install pycryptodome:
951
952        ```
953        sudo pip3 install pycryptodome
954        ```
955
956
957
958### Unexpected Operator<a name="section967617530505"></a>
959
960-   **Symptom**
961
962    The build fails, and "xx.sh \[: xx unexpected operator" is displayed.
963
964-   **Cause**
965
966    The build environment is shell, not bash.
967
968-   **Solution**
969
970    ```
971    sudo rm -rf /bin/sh
972    sudo ln -s /bin/bash /bin/sh
973    ```
974
975