# release/v2.3 源码编译

**说明：** release/v2.3 之前版本（包括v2.3版本）的源码编译请参考本文档

**注意：** OpenCL、华为NPU、FPGA、CUDA、X86预测库、CV模块的编译，请见进阶使用指南的对应章节。

如果您还没有配置好相应的源码编译环境，请先根据[编译环境准备](compile_env)中的内容，根据您的开发环境安装源码编译所需的编译环境。

### 下载代码

```shell
git clone https://github.com/PaddlePaddle/Paddle-Lite.git
cd Paddle-Lite
git checkout <release-version-tag>
```

### 编译模式与参数

编译脚本`./lite/tools/build.sh`，支持三种编译模式：

| 编译模式 | 介绍 | 适用对象 |
|:-------:|-----|:-------:|
| tiny_publish | 编译移动端部署库，无第三方库依赖 | 用户 |
| full_publish | 编译移动端部署库，有第三方依赖如protobuf、glags等，含有可将模型转换为无需protobuf依赖的naive buffer格式的工具，供tiny_publish库使用 | 用户 |
| test | 编译指定`arm_os`、`arm_abi`下的移动端单元测试 | 框架开发者 |

编译脚本`./lite/tools/build.sh`，追加参数说明：

|   参数     |     介绍     |     值     |
|-----------|-------------|-------------|
| --arm_os   |必选，选择安装平台     | `android`、`ios`、`ios64`、`armlinux` |
| --arm_abi  |必选，选择编译的arm版本，其中`armv7hf`为ARMLinux编译时选用| `armv8`、`armv7`、`armv7hf`(仅`armlinux`支持) |
| --arm_lang |arm_os=android时必选，选择编译器 | `gcc`、`clang`(`clang`当前暂不支持) |
| --android_stl |arm_os=android时必选，选择静态链接STL或动态链接STL | `c++_static`、`c++_shared`|
| --build_java | 可选，是否编译java预测库（默认为ON） | `ON`、`OFF` |
| --build_extra | 可选，是否编译全量预测库（默认为OFF）。详情可参考[with_extra参数说明](./library.html)。 | `ON`、`OFF` |
| target |必选，选择编译模式，`tiny_publish`为编译移动端部署库、`full_publish`为带依赖的移动端部署库、`test`为移动端单元测试、`ios`为编译ios端`tiny_publish` | `tiny_publish`、`full_publish`、`test`、 `ios` |

### 编译代码

**提示：** 编译过程中，如出现源码编译耗时过长，通常是第三方库下载过慢或失败导致。请在git clone完Paddle-Lite仓库代码后，手动删除本地仓库根目录下的third-party目录。编译脚本会自动下载存储于国内 CDN 的第三方依赖的压缩包，节省从git repo同步第三方库代码的时间。

#### 编译`tiny publish`动态库

##### Android
```shell
./lite/tools/build.sh \
  --arm_os=android \
  --arm_abi=armv8 \
  --build_extra=OFF \
  --arm_lang=gcc \
  --android_stl=c++_static \
  tiny_publish
```
##### iOS

**注意：** mac环境编译iOS 时，cmake版本需要高于cmake 3.15；mac环境上编译Android时，cmake版本需要设置为cmake 3.10。

```shell
./lite/tools/build.sh \
  --arm_os=ios64 \
  --arm_abi=armv8 \
  --build_extra=OFF \
  ios

# 编译选项说明
--arm_os   可选ios或者ios64
--arm_abi  可选armv7和armv8
          （注意：当arm_os=ios时只能选择arm_abi=armv7，当arm_os=ios64时只能选择arm_abi=armv8）
```

如果mac编译过程中报错："Invalid CMAKE_DEVELOPER_ROOT: does not exist", 运行：

```shell
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
```

##### ARMLinux

```shell
./lite/tools/build.sh \
  --build_extra=OFF \
  --arm_os=armlinux \
  --arm_abi=armv7hf \
  --arm_lang=gcc \
  tiny_publish

# 编译选项说明
--arm_abi     树莓派3b使用armv7hf，RK3399使用armv8
```
  
#### 编译`full publish`动态库

##### Android
```shell
./lite/tools/build.sh \
  --arm_os=android \
  --arm_abi=armv8 \
  --build_extra=OFF \
  --arm_lang=gcc \
  --android_stl=c++_static \
  full_publish
```

##### ARMLinux
```shell
./lite/tools/build.sh \
  --arm_os=armlinux \
  --arm_abi=armv7hf \
  --arm_lang=gcc \
  --build_extra=OFF \
  full_publish

# 编译选项说明
--arm_abi     树莓派3b使用armv7hf，RK3399使用armv8
```
  
### 编译结果说明

**编译最终产物位置**在 `build.lite.xxx.xxx.xxx` 下的 `inference_lite_lib.xxx.xxx` ，如 Android 下 ARMv8 的产物位于`inference_lite_lib.android.armv8`：

![](https://user-images.githubusercontent.com/45189361/65375706-204e8780-dccb-11e9-9816-ab4563ce0963.png)

**目录内容**（可能）如下：

**Full_publish编译结果:**

![](https://user-images.githubusercontent.com/45189361/65375704-19c01000-dccb-11e9-9650-6856c7a5bf82.png)

**Tiny_publish结果:**

![](https://user-images.githubusercontent.com/45189361/65375726-3bb99280-dccb-11e9-9903-8ce255371905.png)

**IOS编译结果:**

![](https://user-images.githubusercontent.com/45189361/65375726-3bb99280-dccb-11e9-9903-8ce255371905.png)


**具体内容**说明 (供参考)：

```shell
inference_lite_lib.xxx.xxx
├── bin                                           可执行工具文件
│   ├── paddle_code_generator
│   └── test_model_bin
├── cxx                                           C++ 预测库和头文件
│   ├── include                                   C++ 头文件
│   │   ├── paddle_api.h
│   │   ├── paddle_image_preprocess.h
│   │   ├── paddle_lite_factory_helper.h
│   │   ├── paddle_place.h
│   │   ├── paddle_use_kernels.h
│   │   ├── paddle_use_ops.h
│   │   └── paddle_use_passes.h
│   └── lib                                       C++ 库文件
│       ├── libpaddle_api_full_bundled.a          包含 full_api 和 light_api 功能的静态库
│       ├── libpaddle_api_light_bundled.a         只包含 light_api 功能的静态库
│       ├── libpaddle_full_api_shared.so          包含 full_api 和 light_api 功能的动态库
│       └── libpaddle_light_api_shared.so         只包含 light_api 功能的动态库
│
├── demo                                          C++ 和 Java 示例代码
│   ├── cxx                                       C++ 预测库demo
│   └── java                                      Java 预测库demo
│
├── java                                          Java 预测库
│   ├── jar
│   │   └── PaddlePredictor.jar                   Java JAR 包
│   ├── so
│   │   └── libpaddle_lite_jni.so                 Java JNI 动态链接库
│   └── src
│
└── third_party                                   第三方库文件gflags
```

**注意：**

- 只有当`--arm_os=android` 时才会编译出：
  - Java库文件与示例：`Java`和`demo/java`
  - 动态库文件:`libpaddle_full_api_shared.so`,`libpaddle_light_api_shared.so`
- `tiny_publish`编译结果不包括 C++ demo和 C++ 静态库，但提供 C++ 的 light_api 动态库、 Jni 动态库和Java demo
