在ninja构建系统中,“rule”和“build”这两个词通常关联但扮演着不同的角色。下面我会详细解释它们的区别:
### Rule (规则)
在构建系统中,“rule”通常指的是构建系统用来指导如何构建文件或者目标的指令集。它定义了一组转换输入到输出的操作,这些操作可以包括编译源代码、链接库、运行预处理脚本等。Rule可以被看作是一种模板,用于说明当特定类型的输出尚未存在时,构建系统应该执行什么操作来生成这个输出。规则通常包含以下元素:
- **条件**:确定何时应用规则。
- **动作**:要执行的命令或操作。
- **依赖关系**:输入文件或其他目标,它们必须先构建完成才能开始当前规则的执行。
### Build (构建)
“Build”则指的是实际执行构建过程的行为,即按照构建系统中定义的规则来创建或更新软件产品的实例。构建过程涉及解析构建配置文件(比如Makefile、build.gradle、CMakeLists.txt等),识别需要构建的目标,然后根据定义的规则执行相应的操作。构建的结果通常是可执行文件、库、文档、测试报告等具体产物。
#### 区别总结:
- **Rule**:是构建系统中的逻辑描述,规定了构建过程中的行为和转换。
- **Build**:是根据构建规则执行的实际操作,产生具体的构建输出。
### 示例
假设你正在使用`make`构建系统,你可能有一个`Makefile`,其中定义了多个`rules`,比如一个规则可能是用于编译`.c`文件成`.o`文件,另一个规则可能是链接所有的`.o`文件生成最终的可执行文件。当你运行`make`命令时,它会读取`Makefile`中的规则,并根据你的请求(构建目标)执行必要的构建步骤,这个执行过程就是`build`。
简而言之,**rule**是在构建中必须遵守的规则,而**build**是基于这些规则执行的实际构建动作,旨在生成具体的产品或副产品。
举例:
rule rule36586
description = GoogleOneTimeInitializer dexpreopt gen
command = /bin/bash -c "out/host/linux-x86/bin/dexpreopt_gen -global_soong out/soong/dexpreopt_soong.config -global out/soong/dexpreopt_arm64/dexpreopt.config -module out/target/product/a523-y83/obj/APPS/GoogleOneTimeInitializer_intermediates/dexpreopt.config -dexpreopt_script out/target/product/a523-y83/obj/APPS/GoogleOneTimeInitializer_intermediates/dexpreopt.sh -out_dir out"
restat = 1
build out/target/product/a523-y83/obj/APPS/GoogleOneTimeInitializer_intermediates/dexpreopt.sh: rule36586 out/target/product/a523-y83/obj/APPS/GoogleOneTimeInitializer_intermediates/dexpreopt.config out/soong/dexpreopt_soong.config out/soong/dexpreopt_arm64/dexpreopt.config out/host/linux-x86/bin/dexpreopt_gen
build GooglePackageInstaller-target: phony device_GooglePackageInstaller_all_targets
phony_output = true
build device_GooglePackageInstaller_all_targets: phony out/target/product/a523-y83/obj/APPS/GooglePackageInstaller_intermediates/package.apk out/target/product/a523-y83/system/priv-app/GooglePackageInstaller/GooglePackageInstaller.apk out/target/product/a523-y83/obj/APPS/GooglePackageInstaller_intermediates/dexpreopt.zip
phony_output = true
解析:
### rule rule36586
- **描述**: `GoogleOneTimeInitializer`模块的`dexpreopt`生成规则。
- **命令**: 执行`dexpreopt_gen`工具来生成`dexpreopt.sh`脚本和配置文件。这个命令指定了多个参数,包括全局的Soong和ARM64架构的`dexpreopt`配置,以及特定模块的配置文件路径。输出目录设置为`out`。
- **restat**: 设置为1,表示如果输入文件发生变化,则重新执行此规则。
### build out/target/product/a523-y83/obj/APPS/GoogleOneTimeInitializer_intermediates/dexpreopt.sh
- **规则**: 根据`rule36586`构建`dexpreopt.sh`脚本。
- **输入**: 包括模块的`dexpreopt.config`、全局的`dexpreopt_soong.config`、ARM64的`dexpreopt.config`以及`dexpreopt_gen`工具本身。
- **输出**: `dexpreopt.sh`脚本。
### build GooglePackageInstaller-target
- **类型**: 虚拟目标(phony),用于表示`GooglePackageInstaller`的构建和安装过程。
- **描述**: `GooglePackageInstaller`的所有构建目标。
- **输出**: 由于是虚拟目标,输出标记为`true`。
### build device_GooglePackageInstaller_all_targets
- **类型**: 虗拟目标(phony),用于表示设备上`GooglePackageInstaller`的所有构建目标。
- **依赖**: 包括`GooglePackageInstaller`的未优化APK (`package.apk`)、已优化的APK (`GooglePackageInstaller.apk`)以及`dexpreopt.zip`文件。
- **输出**: 由于是虚拟目标,输出标记为`true`。
### 总结
这段构建规则说明了`GoogleOneTimeInitializer`模块的`dexpreopt`优化过程,以及`GooglePackageInstaller`的构建和安装流程。`dexpreopt`是一个重要的Android优化步骤,用于在部署前对Dalvik字节码进行优化,以提高应用的运行效率。`GooglePackageInstaller`的构建流程涉及到生成未优化的APK,对其进行`dexpreopt`优化,然后安装到设备的`/system/priv-app/`目录中。此外,构建规则还生成了`dexpreopt.zip`文件,这通常包含优化后的DEX文件,可以用于快速启动和性能分析。