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 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> **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 > **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> **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> **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 > **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