1e41f4b71Sopenharmony_ci# OpenHarmony Build Specifications 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## Overview 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciThis topic aims to guide OpenHarmony developers to enhance the build reproducibility, maintainability, and quality. The build standards team has analyzed a variety of typical build issues and summarized the build guidelines and recommendations in this topic. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci## General Build Principles 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci**P01 Automate the entire build process.** 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciManual operations are error-prone and time-consuming. Automate all the build operations to make the build process more efficient and reliable. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci**P02 Make build projects and build environments code-based.** 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ciUse a high-level build framework such as CMake, Maven, and Gradle to describe build projects, and use Ansible or Dockerfile to describe build environments. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ciThis principle helps hide the complexity of the build system from developers. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci**P03 Make the build process reproducible and traceable.** 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ciManage build dependencies and always explicitly specify fixed dependency versions to ensure version consistency. Incorporate build environments and build projects into the configuration file as configuration options to ensure that the build projects are traceable. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci**P04 Ensure that the build scripts are simple, clear, and easy to maintain.** 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ciBuild scripts are also code and should be easy to read. 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci**P05 Standardize the build process.** 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ciThe build directory structure, dependencies, initialization, entry, and naming must be standardized to ensure consistency among all OpenHarmony products, platforms, and components for easier management and maintenance. 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci## Build Projects 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci### General Guidelines 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci#### One-Click Build 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci##### G.COM.01 Use build scripts to implement one-click, automated build by delivery unit. 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ciOne-click, automated build means that no manual interventions are allowed throughout the entire build process (until the final delivery package is generated) in a build environment. 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ciManual interventions include but are not limited to: manual parameter setting on the IDE; file directory creation or deletion; file creation, copying, moving, deletion, or renaming; manual setting of file attributes; file compression/decompression. 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ciDelivery unit refers to a product, platform, or component that can be independently compiled, loaded, deployed, and run. 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci[Type] Requirement 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci[Description] One-click build improves operation efficiency while greatly reducing the possibility of operation errors. 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci[Negative Example] The one-click build of a component can be triggered only by the CI system but cannot be triggered locally. 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci[Negative Example] Manually set the memory mapping address on the Xplorer IDE UI for a component, and then perform manual build. 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci[Negative Example] Manually create the **r6c03_view\r6c03_client_view** directory for a component. 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci[Positive Example] Use the python script to automatically create a directory. 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ci```python 58e41f4b71Sopenharmony_cidir_src = os.getcwd() 59e41f4b71Sopenharmony_cidir_client_view = r"r6c03_client_view" 60e41f4b71Sopenharmony_ci# os.path is used to shield system differences. 61e41f4b71Sopenharmony_cidir_mk = os.path.join(dir_src, dir_client_view) 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_cicmd = "{0} {1}".format("mkdir", dir_mk) 64e41f4b71Sopenharmony_cicmd_re = subprocess.run(cmd) 65e41f4b71Sopenharmony_ci``` 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci#### Build Directory 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci##### G.COM.02 DO NOT delete or modify source code files and their directory structures during build. 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci[Type] Forbidden 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci[Description] 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci- If the source code directory structure is deleted or modified during the build, the build process will be non-reproducible. 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci- During the build, the build output (including the target files, temporary files, and build logs) should not pollute the source code directory. 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci- During the build, do not modify source files, including but not limited to copying, moving, and running **dos2unix** to convert the source code format. Any modification to the source files must be completed in the code preparation phase before the build. 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci- The tool-triggered, automatic generation of source code must also be completed in the preparation phase before the build. If tools are used to automatically generate source code during the build, the source code generated (low-value and reproducible) must be isolated from the existing source code directory for better distinguishing, so as to reduce the complexity of the build system. 82e41f4b71Sopenharmony_ci 83e41f4b71Sopenharmony_ci[Exception] Some source code may be added or adjusted during patch build. 84e41f4b71Sopenharmony_ci 85e41f4b71Sopenharmony_ci##### G.COM.12 Provide appropriate permissions for files and directories created during the build. 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci[Type] Requirement 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ci[Description] Directories or files of the target system that are created during the build must comply with the design of least privilege. For example, do not create directories or files with the **777** permission in the Linux system during the build. 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ciFor details about common directory files and permissions in the Linux system, see the *Linux Security Configuration Standard*. 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci#### Build Initialization 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci##### G.COM.03 Provide the clean command for each component. 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci- If the **clean** command is executed with no arguments specified, all target files, temporary files, and build logs in the build project of the current level will be cleared, and the **clean** commands of the lower-level build project are recursively called to restore the build projects to the initial state. 98e41f4b71Sopenharmony_ci- If the **clean** command is executed with certain arguments specified, only the corresponding target files, temporary files, and build logs generated in the specified build will be cleared. 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci[Type] Requirement 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci[Description] The **clean** command prevents a build from being affected by historical build files and build logs, ensuring build reproducibility. The **clean** command without any arguments must be supported. The **clean** command with arguments applies only to internal delivery and local build. 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci[Positive Example] 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci``` 107e41f4b71Sopenharmony_cibase_dir 108e41f4b71Sopenharmony_ci |---build.suffix 109e41f4b71Sopenharmony_ci |---logs 110e41f4b71Sopenharmony_ci |---component_depository_1 111e41f4b71Sopenharmony_ci |---build.suffix 112e41f4b71Sopenharmony_ci |---logs 113e41f4b71Sopenharmony_ci |---component_depository_2 114e41f4b71Sopenharmony_ci |---build.suffix 115e41f4b71Sopenharmony_ci |---logs 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ci# No arguments 118e41f4b71Sopenharmony_cibase_dir/build.suffix clean 119e41f4b71Sopenharmony_ci#....Call clean of component_depository_1 and component_depository_2. 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci# With arguments: component name 122e41f4b71Sopenharmony_cibase_dir/build.suffix clean component_depository_1 123e41f4b71Sopenharmony_ci#....Call clean of component_depository_1 only. 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci# With arguments 126e41f4b71Sopenharmony_cicomponent_depository_1/build.suffix clean makebin hert umpt 127e41f4b71Sopenharmony_ci#....Call clean of the umpt board of component_depository_1. 128e41f4b71Sopenharmony_ci``` 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci##### G.COM.04 Clear legacy build files in the build environment before the build of a component. 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci[Type] Requirement 133e41f4b71Sopenharmony_ci 134e41f4b71Sopenharmony_ci[Description] If code is downloaded for the first time and the build environment has been initialized, the build environment does not have legacy build files. In this case, you do not need to run the **clean** command. If build has been performed, run the **clean** command to clear legacy build files. 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci#### Full Build 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci##### G.COM.05 For a version release build, recompile all the archived deliverables (including all dependent platforms and components). DO NOT use incremental build. DO NOT change the installation disk by manually replacing files. 139e41f4b71Sopenharmony_ci 140e41f4b71Sopenharmony_ciA version release build refers to the build of a formally released product version (including all dependent platforms and components). 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ci[Type] Requirement 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ci[Description] Conducting incremental build after file modification may cause failures in updating some binary files and integrating new security build options into the version, causing inconsistent build results. Manually replacing files may make the build unreproducible and inconsistent. 145e41f4b71Sopenharmony_ci 146e41f4b71Sopenharmony_ci 147e41f4b71Sopenharmony_ci#### Build Configurations 148e41f4b71Sopenharmony_ci 149e41f4b71Sopenharmony_ciSeparate the build configuration data from the build script to prevent the build project architecture from decaying. Store configuration data, such as the source code path, build options, and target file path, in a file different from the file that stores the build script to minimize the maintenance cost of build scripts. 150e41f4b71Sopenharmony_ci 151e41f4b71Sopenharmony_ci##### G.COM.06 DO NOT use a file that is strongly bound to the operating system (for example, an Excel file) as a build configuration file. Use a file format recognized by different platforms, such as an XML file, as the build configuration file. 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci[Type] Requirement 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ci[Description] Using an Excel configuration file brings the following problems: 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci- The file calls Microsoft Office APIs during the build. Each time the Excel file is accessed, the Excel program is started in the background, causing slow responding. 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci- A large number of Excel configurations require manual operations on the GUI, resulting in poor manageability. 160e41f4b71Sopenharmony_ci 161e41f4b71Sopenharmony_ci#### Build Logs 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ci##### G.COM.07 Generate simple and clear build logs, and use the format "timestamp + [module name](optional) + log level + log content" for each log record. 164e41f4b71Sopenharmony_ci[Type] Requirement 165e41f4b71Sopenharmony_ci 166e41f4b71Sopenharmony_ciYou are advised to set the timestamp in the format of date and time, for example, *MM/dd/yyyy HH:mm:ss*. 167e41f4b71Sopenharmony_ci 168e41f4b71Sopenharmony_ciLog levels are classified into error, warning (warn), and information (info), either in lowercase or uppercase. 169e41f4b71Sopenharmony_ci 170e41f4b71Sopenharmony_ciYou are advised to use square brackets ([]) to enclose each part of a log record. 171e41f4b71Sopenharmony_ci 172e41f4b71Sopenharmony_ci[Positive Example] 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci[05/21/2020 00:12:40] [ERROR] mkdir: cannot create directory Permission denied. 175e41f4b71Sopenharmony_ci 176e41f4b71Sopenharmony_ci[Exception] If the entire log is automatically generated by a tool, you can skip the log file in the following way: Output "This project is built using + *tool name*" at the beginning of the log, for example, "This project is built using CMake." 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ci##### G.COM.08 Stop the build if error is displayed in the log. 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci[Type] Requirement 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ci[Description] An error log indicates a build error that requires manual intervention, for example, an incorrect environment variable, tool version error, operating system error, or incorrect software source code. For a version release build, all errors generated during the build must be eliminated. DO NOT shield build errors. 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci[Negative Example] A component is successfully built, but the build log contains a large amount of exception information, such as "fail", "critical", "cannot", "not found", "missing" and "no input files". 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci##### G.COM.09 Retain only the logs of the current build in the build log file. 187e41f4b71Sopenharmony_ci 188e41f4b71Sopenharmony_ci[Type] Requirement 189e41f4b71Sopenharmony_ci 190e41f4b71Sopenharmony_ci[Description] Retaining historical build logs in the build log file may cause confusing. For example, when a new build fails, users may confuse the logs of historical successful builds with those of the new build and mistakenly consider the new build successful. 191e41f4b71Sopenharmony_ci 192e41f4b71Sopenharmony_ci##### G.COM.10 Add the corresponding module name to each log for quick fault locating. 193e41f4b71Sopenharmony_ci 194e41f4b71Sopenharmony_ci[Type] Recommendation 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci[Description] If there are a large number of logs, it is difficult to quickly locate the module involved in a specific fault. Adding the corresponding module name facilitates quick fault locating. 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_ci[Exception] The native logs of tools such as CMake contain the module paths, which can be used to locate the modules. For such logs, you do not need to add the module name information. 199e41f4b71Sopenharmony_ci 200e41f4b71Sopenharmony_ci#### Build Users 201e41f4b71Sopenharmony_ci 202e41f4b71Sopenharmony_ci##### G.COM.11 DO NOT use the super administrator **root** or system user for build. Instead, use a common user account. 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci[Type] Requirement 205e41f4b71Sopenharmony_ci 206e41f4b71Sopenharmony_ci[Description] The super administrator **root** and system user have high system permissions. Using such an account for the build may cause the build environment to be tampered with. 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ciIn the installation state, the **root** user account can be used. In the running state, use a common user account. If you need to run the **sudo** command for privilege escalation, comply with *IAM Security Design Specifications*. 209e41f4b71Sopenharmony_ci 210e41f4b71Sopenharmony_ci#### Build Output Files 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ci##### G.COM.12 Follow the industry conventions for build output file name extensions. 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ci[Type] Requirement 215e41f4b71Sopenharmony_ci 216e41f4b71Sopenharmony_ci[Description] An incorrect file name extension is misleading. 217e41f4b71Sopenharmony_ci 218e41f4b71Sopenharmony_ciThe file name extensions of the output files, such as .lib and .obj files, must comply with the default naming rules of the build tools. 219e41f4b71Sopenharmony_ci 220e41f4b71Sopenharmony_ci[Negative Example] A text file is named ***Example*.lib**. 221e41f4b71Sopenharmony_ci 222e41f4b71Sopenharmony_ci[Negative Example] An object file is named ***Example*.a**. 223e41f4b71Sopenharmony_ci 224e41f4b71Sopenharmony_ci[Negative Example] A static library is named **lib*Example***, without a file name extension. 225e41f4b71Sopenharmony_ci 226e41f4b71Sopenharmony_ci[Positive Example] Query the common file name extension conventions at http://www.fileextension.org/, https://fileinfo.com/, https://www.file-extensions.org/, and http://file-extension.net/. 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ciConventions about common file name extensions are as follows: 229e41f4b71Sopenharmony_ci 230e41f4b71Sopenharmony_ci| File Name Extension| Type Convention | File Name Extension| Type Convention | 231e41f4b71Sopenharmony_ci| ---------- | -------------------- | ---------- | --------------- | 232e41f4b71Sopenharmony_ci| .a | Static library | .so | Dynamic library | 233e41f4b71Sopenharmony_ci| .o | Object file | .7z | 7-zip compressed file | 234e41f4b71Sopenharmony_ci| .tar | TAR archive file | .gz/.gzip | GNU zip archive file| 235e41f4b71Sopenharmony_ci| .pack | Java pack200 compressed file| .rar/.rar5 | RAR compressed file | 236e41f4b71Sopenharmony_ci 237e41f4b71Sopenharmony_ci### C/C++ Build Projects 238e41f4b71Sopenharmony_ci 239e41f4b71Sopenharmony_ci#### Build Directory 240e41f4b71Sopenharmony_ci 241e41f4b71Sopenharmony_ci##### G.C&C++.01 Standardize the build directory structure. 242e41f4b71Sopenharmony_ci 243e41f4b71Sopenharmony_ciBuild directories are classified into Source Tree, Build Tree, and Install Tree by functionality. 244e41f4b71Sopenharmony_ci 245e41f4b71Sopenharmony_ci- Source Tree is the directory for storing source code and build scripts. 246e41f4b71Sopenharmony_ci- Build Tree is the directory for storing build middleware. Generally, the directory name is **build**. 247e41f4b71Sopenharmony_ci- Install Tree is the directory for storing build deliverables. The directory name is fixed at **output**. 248e41f4b71Sopenharmony_ci 249e41f4b71Sopenharmony_ciThe Source Tree, Build Tree, and Install Tree directories should be isolated from each other and should not overlap. One directory cannot be used for two or more purposes. For example, it is prohibited that a directory is used as both Source Tree to store source code and Build Tree to store build middleware. 250e41f4b71Sopenharmony_ci 251e41f4b71Sopenharmony_ciSource Tree contains the following files and directories: 252e41f4b71Sopenharmony_ci 253e41f4b71Sopenharmony_ci- Build tool entry file, such as **CMakeLists.txt**. After the **add_subdirectory()** command is executed in the upper-level **CMakeLists.txt** file, the CMake automatically invokes the **CMakeLists.txt** files in the subdirectory and lower-level subdirectories. 254e41f4b71Sopenharmony_ci- **build.*suffix*** script file, which is the one-click build entry. You only need to invoke this script to complete the build. In the build entry file name, *.suffix* (such as .bat, .sh, or .py) indicates the programming language used by the build script. 255e41f4b71Sopenharmony_ci- **config.*suffix*** configuration file, which is used to store build options and is the unique entry for configuration. 256e41f4b71Sopenharmony_ci- Build script directory, which is optional. For example, the **cmake** directory is used to store CMake scripts. CMake script files include macros, functions, and the toolchain. The **CMakeLists.txt** script contains CMake script files by executing the **include()** command, and invokes the macros and functions in the script files. 257e41f4b71Sopenharmony_ci- Component code directory, which is used to store source code and build scripts of each component. 258e41f4b71Sopenharmony_ci 259e41f4b71Sopenharmony_ciAmong the preceding files and directories, only the **CMakeLists.txt**, **build.*suffix***, and **config.*suffix*** files are mandatory. Other files and directories are optional and provided as examples for your better understanding. 260e41f4b71Sopenharmony_ci 261e41f4b71Sopenharmony_ciBuild Tree contains the following directories: 262e41f4b71Sopenharmony_ci 263e41f4b71Sopenharmony_ci- **build** directory, which is used to store the build middleware. This directory may be created during the build process and may not exist in the Git repository. If the **build** directory is used to store build scripts, you can create another directory as Build Tree. 264e41f4b71Sopenharmony_ci 265e41f4b71Sopenharmony_ciInstall Tree contains the following directories: 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ci- **output** directory, which is used to store deliverables. This directory may be created during the build process and may not exist in the Git repository. 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ci[Type] Requirement 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_ci[Description] 272e41f4b71Sopenharmony_ci 273e41f4b71Sopenharmony_ciA typical directory structure is as follows: 274e41f4b71Sopenharmony_ci 275e41f4b71Sopenharmony_ci``` 276e41f4b71Sopenharmony_cibase_dir 277e41f4b71Sopenharmony_ci |---CMakeLists.txt ---| 278e41f4b71Sopenharmony_ci |---build.suffix | 279e41f4b71Sopenharmony_ci |---config.suffix | 280e41f4b71Sopenharmony_ci |---cmake |--> Source Tree 281e41f4b71Sopenharmony_ci |---component_1 | 282e41f4b71Sopenharmony_ci |---component_2 | 283e41f4b71Sopenharmony_ci |---...... | 284e41f4b71Sopenharmony_ci |---component_n ---| 285e41f4b71Sopenharmony_ci |---build ------> Build Tree 286e41f4b71Sopenharmony_ci |---output ------> Install Tree 287e41f4b71Sopenharmony_ci``` 288e41f4b71Sopenharmony_ci 289e41f4b71Sopenharmony_ciThe directory structure of each component is similar to the top directory structure. Example: 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci``` 292e41f4b71Sopenharmony_cicomponent_1 293e41f4b71Sopenharmony_ci |---CMakeLists.txt ---| 294e41f4b71Sopenharmony_ci |---build.suffix | 295e41f4b71Sopenharmony_ci |---config.suffix | 296e41f4b71Sopenharmony_ci |---cmake |--> Source Tree 297e41f4b71Sopenharmony_ci |---module_1 | 298e41f4b71Sopenharmony_ci |---module_2 | 299e41f4b71Sopenharmony_ci |---...... | 300e41f4b71Sopenharmony_ci |---module_n ---| 301e41f4b71Sopenharmony_ci |---build ------> Build Tree 302e41f4b71Sopenharmony_ci |---output ------> Install Tree 303e41f4b71Sopenharmony_ci``` 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci##### G.C&C++.02 DO NOT modify Source Tree in any form during the build process. 306e41f4b71Sopenharmony_ci 307e41f4b71Sopenharmony_ci[Type] Recommendation 308e41f4b71Sopenharmony_ci 309e41f4b71Sopenharmony_ci[Description] If Source Tree is modified during the build, the build process will be non-reproducible. 310e41f4b71Sopenharmony_ci 311e41f4b71Sopenharmony_ciThe common operations for modifying Source Tree are as follows: 312e41f4b71Sopenharmony_ci 313e41f4b71Sopenharmony_ci- Patch installation 314e41f4b71Sopenharmony_ci- Dotting 315e41f4b71Sopenharmony_ci- Tailoring 316e41f4b71Sopenharmony_ci- Automatic source code generation 317e41f4b71Sopenharmony_ci- Modifying source code and then restoring it 318e41f4b71Sopenharmony_ci- Adding, modifying, or deleting temporary files or directories 319e41f4b71Sopenharmony_ci- Modifying the attribute or format of a file or directory (For example, modify the execute permission of a file or **dos2unix**.) 320e41f4b71Sopenharmony_ci 321e41f4b71Sopenharmony_ciRecommended operations are as follows: 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ci(1) Copy code to Build Tree, install a patch, and build the code. 324e41f4b71Sopenharmony_ci 325e41f4b71Sopenharmony_ci(2) As the dotting tool modifies source code and makes the build process untrustworthy, do not use the dotting tool during the build. Instead, upload the dotted code to the code repository and use the dotted code for the build. 326e41f4b71Sopenharmony_ci 327e41f4b71Sopenharmony_ci(3) Tailoring is an independent source code delivery requirement and can be considered as the code preparation phase. Source Tree in the versions before and after tailoring must not be modified during the build. 328e41f4b71Sopenharmony_ci 329e41f4b71Sopenharmony_ci(4) The automatically generated source code must be stored in Build Tree. 330e41f4b71Sopenharmony_ci 331e41f4b71Sopenharmony_ci(5) Modifying and then restoring source code is prohibited because the source code has changed during the build. 332e41f4b71Sopenharmony_ci 333e41f4b71Sopenharmony_ci(6) Temporary files or directories must be stored in Build Tree. 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci(7) Ensure that the attributes and formats of files in the code repository are correct to prevent modifying them during the build. 336e41f4b71Sopenharmony_ci 337e41f4b71Sopenharmony_ciTo check for Source Tree changes, run the **git status** command in the source code directory after the build. Source Tree should not have any change. The **git status** command may fail to detect changes to Source Tree where source code is modified and then restored. 338e41f4b71Sopenharmony_ci 339e41f4b71Sopenharmony_ci[Exception] 340e41f4b71Sopenharmony_ci 341e41f4b71Sopenharmony_ci(1) Changes in the Build Tree and Install Tree directories detected by the **git status** command are allowed. 342e41f4b71Sopenharmony_ci 343e41f4b71Sopenharmony_ci(2) Tailoring-caused changes detected by the **git status** command are allowed. 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci##### G.C&C++.03 Use D:\*deliveryUnitName + versionNumber (optional)* and /usr1/*deliveryUnitName + versionNumber (optional)* as the build root directory in Windows and Linux, respectively. 346e41f4b71Sopenharmony_ci 347e41f4b71Sopenharmony_ci[Type] Recommendation 348e41f4b71Sopenharmony_ci 349e41f4b71Sopenharmony_ci[Description] Name the build root directory in the format of *deliveryUnitName + versionNumber*, where *versionNumber* is optional. DO NOT use the directory name that cannot identify a specific delivery unit, such as **build** or **code**. 350e41f4b71Sopenharmony_ci 351e41f4b71Sopenharmony_ciA clear build directory structure helps test personnel set build parameters, execute one-click build entries, and compare build results. 352e41f4b71Sopenharmony_ci 353e41f4b71Sopenharmony_ciThe following are two root directory examples: 354e41f4b71Sopenharmony_ci 355e41f4b71Sopenharmony_ci``` 356e41f4b71Sopenharmony_ciD:\Offering [Version (optional)] or /usr1/Offering [Version (optional)] 357e41f4b71Sopenharmony_ci``` 358e41f4b71Sopenharmony_ci 359e41f4b71Sopenharmony_ci##### G.C&C++.04 Store all middleware generated during the build in Build Tree. 360e41f4b71Sopenharmony_ci 361e41f4b71Sopenharmony_ci[Type] Requirement 362e41f4b71Sopenharmony_ci 363e41f4b71Sopenharmony_ci[Description] The middleware generated during the build includes the makefile automatically generated by the build tool CMake, the source code automatically generated by the build script, the source code and patches copied by the build script, as well as the object files, repository files, executable programs, and build logs generated during the build. Store the middleware in Build Tree only, to avoid pollution to Source Tree or Install Tree. Do not store anything else in Build Tree. 364e41f4b71Sopenharmony_ciCreate the **logs** subdirectory under Build Tree and name build log files in .log format. 365e41f4b71Sopenharmony_ci 366e41f4b71Sopenharmony_ci##### G.C&C++.05 You can specify any directory except Source Tree and Install Tree as Build Tree. 367e41f4b71Sopenharmony_ci 368e41f4b71Sopenharmony_ci[Type] Requirement 369e41f4b71Sopenharmony_ci 370e41f4b71Sopenharmony_ci[Description] You can specify any directory other than Source Tree and Install Tree as Build Tree. In this way, the build process is irrelevant to the directory. The directory where the build is executed is Build Tree, and the build middleware is stored in this directory. Generally, the Build Tree directory name is **build**. You can also use another name. 371e41f4b71Sopenharmony_ci 372e41f4b71Sopenharmony_ci[Positive Example] Use CMake system variables **CMAKE_BINARY_DIR** and **CMAKE_CURRENT_BINARY_DIR** to access Build Tree to prevent coupling between Build Tree and Source Tree. 373e41f4b71Sopenharmony_ci 374e41f4b71Sopenharmony_ci##### G.C&C++.06 Store all deliverables in Install Tree. 375e41f4b71Sopenharmony_ci 376e41f4b71Sopenharmony_ci[Type] Requirement 377e41f4b71Sopenharmony_ci 378e41f4b71Sopenharmony_ci[Description] In the local build scenario, deliverables are directly installed on the host computer and run. In the cross-build scenario, deliverables run on the target computer. 379e41f4b71Sopenharmony_ci 380e41f4b71Sopenharmony_ciThe deliverables include library files, executable programs, package files, and header files. They are binary interfaces provided by components. All the deliverables must be stored in Install Tree. 381e41f4b71Sopenharmony_ci 382e41f4b71Sopenharmony_ciDo not place any file other than deliverables (such as build middleware) in Install Tree. 383e41f4b71Sopenharmony_ci 384e41f4b71Sopenharmony_ci##### G.C&C++.07 You can specify any directory except Source Tree and Build Tree as Install Tree. 385e41f4b71Sopenharmony_ci 386e41f4b71Sopenharmony_ci[Type] Requirement 387e41f4b71Sopenharmony_ci 388e41f4b71Sopenharmony_ci[Description] You can specify any directory other than Source Tree and Build Tree as Install Tree. In this way, the build process is irrelevant to the directory. The Install Tree directory name is fixed at **output**. 389e41f4b71Sopenharmony_ci 390e41f4b71Sopenharmony_ci[Positive Example] The CMake build project supports the function of specifying the Install Tree directory through the system variable **CMAKE_INSTALL_PREFIX**. 391e41f4b71Sopenharmony_ci 392e41f4b71Sopenharmony_ci#### Build Entry 393e41f4b71Sopenharmony_ci 394e41f4b71Sopenharmony_ci##### G.C&C++.08 Provide a unique build entry for each delivery unit. Name all the build entry scripts in the **build.*suffix*** format, and store them in the build root directory. 395e41f4b71Sopenharmony_ci 396e41f4b71Sopenharmony_ci[Type] Requirement 397e41f4b71Sopenharmony_ci 398e41f4b71Sopenharmony_ci[Description] A unique build entry allows for a more efficient and automated build process. Each delivery unit has a unique build entry, making one-click, automated build possible. 399e41f4b71Sopenharmony_ci 400e41f4b71Sopenharmony_ci[Negative Example] The following build has multiple entry points. If no description document is provided, it is difficult to determine which entry point is correct. 401e41f4b71Sopenharmony_ci 402e41f4b71Sopenharmony_cibuild.bat 403e41f4b71Sopenharmony_ci 404e41f4b71Sopenharmony_cibuild_all.sh 405e41f4b71Sopenharmony_ci 406e41f4b71Sopenharmony_cibuild_v6.sh 407e41f4b71Sopenharmony_ci 408e41f4b71Sopenharmony_ci[Positive Example] A typical one-click build script **build.sh** is as follows: 409e41f4b71Sopenharmony_ci 410e41f4b71Sopenharmony_ci```bash 411e41f4b71Sopenharmony_ci#!/bin/bash 412e41f4b71Sopenharmony_ci 413e41f4b71Sopenharmony_ciif [ -d "build" ]; then 414e41f4b71Sopenharmony_ci rm -fr build/* 415e41f4b71Sopenharmony_cielse 416e41f4b71Sopenharmony_ci mkdir build 417e41f4b71Sopenharmony_cifi 418e41f4b71Sopenharmony_ci 419e41f4b71Sopenharmony_ciif [ -d "output" ]; then 420e41f4b71Sopenharmony_ci rm -fr output/* 421e41f4b71Sopenharmony_cielse 422e41f4b71Sopenharmony_ci mkdir output 423e41f4b71Sopenharmony_cifi 424e41f4b71Sopenharmony_ci 425e41f4b71Sopenharmony_cicd build 426e41f4b71Sopenharmony_cicmake .. 427e41f4b71Sopenharmony_ci 428e41f4b71Sopenharmony_cicpu_processor_num=$(grep processor /proc/cpuinfo | wc -l) 429e41f4b71Sopenharmony_cijob_num=$(expr "$cpu_processor_num" \* 2) 430e41f4b71Sopenharmony_ciecho Parallel job num is "$job_num" 431e41f4b71Sopenharmony_cimake -j"$job_num" 432e41f4b71Sopenharmony_ci``` 433e41f4b71Sopenharmony_ci 434e41f4b71Sopenharmony_ci##### G.C&C++.09 You can specify the build target. 435e41f4b71Sopenharmony_ci 436e41f4b71Sopenharmony_ci[Type] Requirement 437e41f4b71Sopenharmony_ci 438e41f4b71Sopenharmony_ci[Description] In routine development scenarios, you can specify the target to build modified code. A project can be built by specifying the target to meet flexible build and debugging requirements. 439e41f4b71Sopenharmony_ci 440e41f4b71Sopenharmony_ci[Positive Example] A typical command is as follows: 441e41f4b71Sopenharmony_ci 442e41f4b71Sopenharmony_ci``` 443e41f4b71Sopenharmony_cibase_dir # cd build 444e41f4b71Sopenharmony_cibase_dir/build # cmake .. 445e41f4b71Sopenharmony_ci# Build all targets. 446e41f4b71Sopenharmony_cibase_dir/build # make 447e41f4b71Sopenharmony_ci# Build a specific target. 448e41f4b71Sopenharmony_cibase_dir/build # make target_name 449e41f4b71Sopenharmony_ci``` 450e41f4b71Sopenharmony_ci 451e41f4b71Sopenharmony_ci##### G.C&C++.10 Reproducible build is supported. 452e41f4b71Sopenharmony_ci 453e41f4b71Sopenharmony_ci[Type] Requirement 454e41f4b71Sopenharmony_ci 455e41f4b71Sopenharmony_ci[Description] If you do not modify the source code, clear the middleware and deliverables, or modify the build environment after the last successful build, you can perform a new round of build and obtain the same result. 456e41f4b71Sopenharmony_ci 457e41f4b71Sopenharmony_ci##### G.C&C++.11 Incremental build is supported. 458e41f4b71Sopenharmony_ci 459e41f4b71Sopenharmony_ci[Type] Recommendation 460e41f4b71Sopenharmony_ci 461e41f4b71Sopenharmony_ci[Description] In routine development scenarios, incremental build can improve development efficiency. Therefore, it is advised to support incremental build. 462e41f4b71Sopenharmony_ci 463e41f4b71Sopenharmony_ci##### G.C&C++.12 Parallel build is supported. 464e41f4b71Sopenharmony_ci 465e41f4b71Sopenharmony_ci[Type] Requirement 466e41f4b71Sopenharmony_ci 467e41f4b71Sopenharmony_ci[Description] You can run the **make -jN** command for quicker parallel build. This guideline applies only to projects that use the make tool. 468e41f4b71Sopenharmony_ci 469e41f4b71Sopenharmony_ciSupport unified scheduling in jobserver mode to optimize the project load to the best level. The following alarms are not allowed: 470e41f4b71Sopenharmony_ci 471e41f4b71Sopenharmony_ci``` 472e41f4b71Sopenharmony_ciwarning: jobserver unavailable: using -j1. Add '+' to parent make rule. 473e41f4b71Sopenharmony_ciwarning: -jN forced in submake: disabling jobserver mode. 474e41f4b71Sopenharmony_ci``` 475e41f4b71Sopenharmony_ci 476e41f4b71Sopenharmony_ciTo support the jobserver mode, perform any of the following operations: 477e41f4b71Sopenharmony_ci 478e41f4b71Sopenharmony_ci1. Use **$(MAKE)** to directly invoke the **make** command. 479e41f4b71Sopenharmony_ci 480e41f4b71Sopenharmony_ci ```cmake 481e41f4b71Sopenharmony_ci ExternalProject_Add(foo 482e41f4b71Sopenharmony_ci SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/foo 483e41f4b71Sopenharmony_ci CONFIGURE_COMMAND sh configure_ext.sh 484e41f4b71Sopenharmony_ci BUILD_COMMAND $(MAKE) 485e41f4b71Sopenharmony_ci ) 486e41f4b71Sopenharmony_ci ``` 487e41f4b71Sopenharmony_ci 488e41f4b71Sopenharmony_ci2. Use the shell script to invoke the **make** command. 489e41f4b71Sopenharmony_ci 490e41f4b71Sopenharmony_ci ```cmake 491e41f4b71Sopenharmony_ci ExternalProject_Add(foo 492e41f4b71Sopenharmony_ci SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/foo 493e41f4b71Sopenharmony_ci CONFIGURE_COMMAND sh configure_ext.sh 494e41f4b71Sopenharmony_ci BUILD_COMMAND sh build_ext.sh $(MAKE) 495e41f4b71Sopenharmony_ci ) 496e41f4b71Sopenharmony_ci ``` 497e41f4b71Sopenharmony_ci 498e41f4b71Sopenharmony_ci The content of **build_ext.sh** is as follows: 499e41f4b71Sopenharmony_ci 500e41f4b71Sopenharmony_ci ```bash 501e41f4b71Sopenharmony_ci #!/bin/bash 502e41f4b71Sopenharmony_ci 503e41f4b71Sopenharmony_ci make 504e41f4b71Sopenharmony_ci ``` 505e41f4b71Sopenharmony_ci 506e41f4b71Sopenharmony_ci Note: **build_ext.sh** does not need to parse or use the **$(MAKE)** parameter. 507e41f4b71Sopenharmony_ci 508e41f4b71Sopenharmony_ci3. Use the python script to invoke the **make** command. 509e41f4b71Sopenharmony_ci 510e41f4b71Sopenharmony_ci ```cmake 511e41f4b71Sopenharmony_ci ExternalProject_Add(foo 512e41f4b71Sopenharmony_ci SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/foo 513e41f4b71Sopenharmony_ci CONFIGURE_COMMAND sh configure_ext.sh 514e41f4b71Sopenharmony_ci BUILD_COMMAND python build_ext.py $(MAKE) 515e41f4b71Sopenharmony_ci ) 516e41f4b71Sopenharmony_ci ``` 517e41f4b71Sopenharmony_ci 518e41f4b71Sopenharmony_ci The content of **build_ext.py** is as follows: 519e41f4b71Sopenharmony_ci 520e41f4b71Sopenharmony_ci ```bash 521e41f4b71Sopenharmony_ci #!/usr/bin/python 522e41f4b71Sopenharmony_ci # -*- coding: UTF-8 -*- 523e41f4b71Sopenharmony_ci 524e41f4b71Sopenharmony_ci import subprocess 525e41f4b71Sopenharmony_ci 526e41f4b71Sopenharmony_ci def main(): 527e41f4b71Sopenharmony_ci child = subprocess.Popen("make", close_fds=False) 528e41f4b71Sopenharmony_ci ret = child.wait() 529e41f4b71Sopenharmony_ci return 530e41f4b71Sopenharmony_ci 531e41f4b71Sopenharmony_ci if __name__ == '__main__': 532e41f4b71Sopenharmony_ci main() 533e41f4b71Sopenharmony_ci ``` 534e41f4b71Sopenharmony_ci 535e41f4b71Sopenharmony_ci Note: **build_ext.py** does not need to parse or use the **$(MAKE)** parameter. 536e41f4b71Sopenharmony_ci 537e41f4b71Sopenharmony_ci 538e41f4b71Sopenharmony_ci#### Build Dependencies 539e41f4b71Sopenharmony_ci 540e41f4b71Sopenharmony_ci##### G.C&C++.13 Define a build dependency file **dependence.xml** to describe all components on which the build depends. The build script automatically reads the dependency file to produce the final software package. 541e41f4b71Sopenharmony_ci 542e41f4b71Sopenharmony_ci[Type] Recommendation 543e41f4b71Sopenharmony_ci 544e41f4b71Sopenharmony_ci[Description] Make software packages based on the dependency file, so that you do not need to define dependency components in the build scripts. This improves the build process maintainability. 545e41f4b71Sopenharmony_ci 546e41f4b71Sopenharmony_ci#### Build Configurations 547e41f4b71Sopenharmony_ci 548e41f4b71Sopenharmony_ci##### G.C&C++.14 Use the configuration file **config.*suffix*** in the build root directory as the unique configuration entry for the entire delivery project. 549e41f4b71Sopenharmony_ci 550e41f4b71Sopenharmony_ci[Type] Requirement 551e41f4b71Sopenharmony_ci 552e41f4b71Sopenharmony_ci[Description] Expose the least configuration options in the top-level **config.*suffix*** file. Configure only the information about the build environment and build tool in this file. 553e41f4b71Sopenharmony_ci 554e41f4b71Sopenharmony_ci[Exception] If there are a small number of build options and key-value pairs are used, the configuration file can be named **config.conf**. 555e41f4b71Sopenharmony_ci 556e41f4b71Sopenharmony_ci### GN Build Specifications 557e41f4b71Sopenharmony_ci 558e41f4b71Sopenharmony_ci#### Build Rules 559e41f4b71Sopenharmony_ci 560e41f4b71Sopenharmony_ci##### Rule 1.1 DO NOT use GN to invoke external build tools to build software modules. 561e41f4b71Sopenharmony_ci 562e41f4b71Sopenharmony_ci[Type] Forbidden 563e41f4b71Sopenharmony_ci 564e41f4b71Sopenharmony_ci[Description] Port external components to the GN build mode to avoid unnecessary dependencies on the environment during the build and obtain common capabilities, such as compiler security options and AddressSanitizer (ASan), provided by the build framework. 565e41f4b71Sopenharmony_ci 566e41f4b71Sopenharmony_ci[Negative Example] In GN, use **action** to invoke **automake** and **Make** to build third-party components. 567e41f4b71Sopenharmony_ci 568e41f4b71Sopenharmony_ci[Exception] The Linux kernel build framework builds user-mode programs. The kernel can be independently built outside the build framework. It is acceptable that some platforms use GN to include the kernel build in the build process to deliver one-click builds. 569e41f4b71Sopenharmony_ci 570e41f4b71Sopenharmony_ci##### Rule 1.2 DO NOT add compiler security options that have been added to the build system to the GN file of the module. 571e41f4b71Sopenharmony_ci 572e41f4b71Sopenharmony_ci[Type] Forbidden 573e41f4b71Sopenharmony_ci 574e41f4b71Sopenharmony_ci[Description] The default options that have been added globally should not be added again to meet internal and external rules. 575e41f4b71Sopenharmony_ci 576e41f4b71Sopenharmony_ci| Option| Parameter | Default Value | 577e41f4b71Sopenharmony_ci|---------|------------|------------| 578e41f4b71Sopenharmony_ci| Stack protection | -fstack-protector-strong| Enabled| 579e41f4b71Sopenharmony_ci| Fortify Source | -D_FORTIFY_SOURCE=2 -O2 | Enabled| 580e41f4b71Sopenharmony_ci 581e41f4b71Sopenharmony_ci[Negative Example] Add **-fstack-protector-strong** to the GN file of the module. 582e41f4b71Sopenharmony_ci 583e41f4b71Sopenharmony_ci##### Rule 1.3 DO NOT add build options that are opposite to the default build options to GN. 584e41f4b71Sopenharmony_ci 585e41f4b71Sopenharmony_ci[Type] Forbidden 586e41f4b71Sopenharmony_ci 587e41f4b71Sopenharmony_ci[Description] The default build options represent the default capabilities of the build system. If your module needs to remove some default build options, there must be sufficient reasons. 588e41f4b71Sopenharmony_ci 589e41f4b71Sopenharmony_ci[Negative Example] Add **-wno-unused** to a module to clear build alarms. 590e41f4b71Sopenharmony_ci 591e41f4b71Sopenharmony_ci[Exception] When porting or using a third-party component, you can overwrite the default build options based on the component requirements. 592e41f4b71Sopenharmony_ci 593e41f4b71Sopenharmony_ci##### Rule 2.1 Use **gn format** to format GN files to meet the format and typesetting requirements. 594e41f4b71Sopenharmony_ci 595e41f4b71Sopenharmony_ci[Type] Requirement 596e41f4b71Sopenharmony_ci 597e41f4b71Sopenharmony_ci##### Rule 2.2 Use Python instead of shell to compile **action**. 598e41f4b71Sopenharmony_ci 599e41f4b71Sopenharmony_ci[Type] Recommendation 600e41f4b71Sopenharmony_ci 601e41f4b71Sopenharmony_ci[Description] The Python environment is easier to keep code unified and can run on multiple operating systems. It also provides better scalability, readability, and testability. 602e41f4b71Sopenharmony_ci 603e41f4b71Sopenharmony_ci##### Rule 2.3 DO NOT modify the content in the source code directory during the execution of GN and Ninja. 604e41f4b71Sopenharmony_ci 605e41f4b71Sopenharmony_ci[Type] Forbidden 606e41f4b71Sopenharmony_ci 607e41f4b71Sopenharmony_ci[Description] The forbidden operations include but are not limited to installing patches for, copying files to, performing build tasks in, and generating intermediate files in the source code directory. 608e41f4b71Sopenharmony_ci 609e41f4b71Sopenharmony_ci##### Rule 2.4 Set the encoding format of the build script to UTF-8 and the newline character to UNIX format. 610e41f4b71Sopenharmony_ci 611e41f4b71Sopenharmony_ci[Type] Requirement 612e41f4b71Sopenharmony_ci 613e41f4b71Sopenharmony_ci[Negative Example] After a script is compiled on Windows, Chinese comments are used and saved as local codes.