# OpenHarmony编译规范

## 目的和范围

OpenHarmony编译规范用于指导开发者规范地编写和修改编译相关的源码、脚本和工具，保证编译过程正确，可信，可重复和高效。

## 术语

### 编译框架

OpenHarmony的编译系统就是用来构建OpenHarmony操作系统的一组软件，主要由模块编译模板，配置框架、发布框架组成。

OpenHarmony的编译系统主要由GN(Generate Ninja)语言和Python编写完成，通常GN用于描述编译过程和依赖关系，Python用于执行特定的编译目标

本文主要描述GN的相关编写要求。

### GN

GN : Generate Ninja,   开源的编译工具，使用.gn文件定义和描述编译过程，并生成最终的编译过程清单，即ninja文件。

### Ninja

Ninja: 开源的编译执行工具，高效执行ninja文件描述的编译过程清单。

## GN 编写规范

### 规则1.1  

**禁止** ：在gn中调用外部编译工具编译软件模块。
**反例** ：在gn中使用action调用automake和Make来编译三方组件。
**要求**  ：需要将外部组件移植成gn的编译形式，避免编译过程对环境产生不必要的依赖，而且可获得编译框架提供的公共能力，包括不限于：安全编译选项，ASAN等。
**例外**  ：Linux Kernel 编译框架实际完成的用户态程序编译，内核完全可以在编译框架之外完成独立编译。某些平台实现为了实现一键编译，使用gn将内核编译加在编译过程中，是可以接受的。

### 规则1.2

**禁止** ：禁止在模块的gn文件中，再次添加编译系统已经添加的安全编译选项。
**反例** ：在模块的编译添加 `` -fstack-protector-strong``	
**要求**  ：对于全局已经添加的默认选项，模块开发者应当知晓，不需要为了满足内外部规则再次添加。

| 安全编译选项 | 编译参数  | 实施建议 | 作用阶段 |
|:-:|:-:|:-:|:-:|
| 栈保护  | -fstack-protector-all or -fstack-protector-strong | 必选 | 编译选项 |
| 立即绑定 | -Wl,-z,now | 必选 | 链接选项 |
|  堆栈不可执行  |                -Wl,-z,noexecstack                 |   必选   |      链接选项      |
| 地址无关 | -fPIC or -fpic | 必选 | 编译选项 |
| 随机化 | -fPIE or -fpie、-pie | 必选 | 编译选项、链接选项 |
| GOT表保护 | -Wl,-z,relro | 必选 | 链接选项 |
| 动态库搜索路径 | -Wl,-rpath、-Wl,-rpath-link | 禁选 | 链接选项 |
| 删除符号表 | -s or strip工具 | 必选 | 链接选项 |
| Fortify Source | -D_FORTIFY_SOURCE=2 -O2 | 可选 | 编译选项 |
| 整数溢出检查 | -ftrapv | 可选 | 编译选项 |

### 规则1.3

**禁止** ：在gn中添加和默认编译选项相反的编译选项。
**反例** ：在自研模块中添加 ``-wno-unused`` 以消除编译告警。
**要求**  ：默认的编译选项代表了系统的默认能力，自研模块有特殊情况需要去掉部分能力，必须有足有的理由。
**例外**  ：移植三方组件，或者使用因为三方组件时，可根据三方组件的要求覆盖默认的编译选项。

### 规则 2.1

**要求** ：使用gn format 对添加或者修改的gn文件进行格式化，满足格式和排版的需求。

### 规则 2.2

**建议** ：编写action时，使用Python而不是shell。
**说明** :  Python 环境更容易保持统一，可以比较容易的多重操作系统上运行，并且扩展性可读性可测试更好。

### 规则 2.3
**规则**：禁止在gn和ninja执行过程修改源码目录的内容。
**说明**：包括但不限于给源码目录打patch，向源码目录中拷贝，在源码目录中执行编译，在源码目录生成中间文件等。

### 规则 2.4
**规则**：编译脚本的编码格式设置为utf-8，换行符设置为unix格式。
**反例** ：在windows上编写脚本后，使用了中文注释并保存为本地编码。



