目录
一、编译Android系统
二、普通编译指令
三、快速编译指令
四、新建lunch项和编译类型说明
五、Android编译系统的整体架构
六、编译后的输出目录和生成文件
七、Android常用编译命令总结
一、编译Android系统
1.Android系统全编译(Android5.1以后mtk都是这种方式,Google原生也是这样)
source build/envsetup.sh
lunch msm8953_64-userdebug
make –j32
2.高通平台Android11.0以后系统全编译
source build/envsetup.sh
lunch msm8953_64-userdebug
./build.sh dist -j32
二、普通编译指令
在服务器上编译AOSP(Android Open Source Project)代码通常涉及以下步骤:
Step 1: 准备服务器环境在服务器上安装所需的软件和工具,包括Java JDK、Git、Python、make、gcc等。确保服务器具备编译AOSP所需的依赖项。
Step 2: 克隆AOSP代码库使用Git命令克隆AOSP代码库到服务器上的本地目录。例如:
git clone https://android.googlesource.com/platform/manifest
这将下载AOSP代码库到本地目录。
Step 3: 配置环境变量设置环境变量,包括设置Java JDK的路径、Android SDK的路径等。这些环境变量的设置可以根据服务器环境和具体需求进行调整。
Step 4: 初始化编译环境进入AOSP代码库所在的目录,并运行以下命令来初始化编译环境:
source build/envsetup.sh
这将设置必要的编译环境变量和函数。
source 引入了 build/envsetup.sh脚本,该脚本的作用是初始化编译环境,并引入一些辅助的 Shell 函数,这其中就包括下一步使用 lunch 函数。除此之外,该文件中还定义了其他一些常用的函数,如:m、mm、mmm,mma,mmma。
Step 5: 选择目标设备和构建类型使用lunch命令选择要编译的目标设备和构建类型。例如:
lunch aosp_arm-eng
这将设置编译环境为针对ARM架构的eng(工程师)版本。
“lunch aosp_arm-eng”是调用 lunch 函数,并指定参数为“aosp_arm-eng”。lunch 函数的参数用来指定此次编译的目标设备以及编译类型。在这里,这两个值分别是“aosp_arm”和“eng”。“aosp_arm”是 Android 源码中已经定义好的一种产品,是为模拟器而设置的。而编译类型会影响最终系统中包含的模块。如果调用 lunch 函数的时候没有指定参数,那么该函数将输出列表以供选择,该列表如下图中的内容,此时可以通过输入编号或者名称进行选择。
Step 6: 开始编译运行以下命令开始编译AOSP代码:
make -j<threads>
其中<threads>
表示使用的并发线程数,可以根据服务器的配置进行调整。编译过程可能会耗时较长,请耐心等待。
Step 7: 获取编译结果编译完成后,编译输出位于out
目录下。根据需求,可以获取生成的系统镜像、应用程序包等。
三、快速编译指令
使用如下指令来编译AOSP的单个模块:
./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm-eng.ninja SnapdragonCamera -j32
该指令是AOSP的快编指令,用于快速编译单个模块。
下面是该指令生成的步骤解释:
-
./prebuilts/build-tools/linux-x86/bin/ninja
: 这部分指定了要使用的构建工具,即Ninja构建系统。该指令通过在AOSP预构建工具链目录下找到Ninja可执行文件进行调用。 -
-f out/combined-aosp_arm-eng.ninja
: 这部分指定了Ninja构建系统要使用的构建文件的路径和名称。在AOSP编译过程中,生成的构建文件会存储在out
目录中,且命名通常包含目标设备的相关信息。 -
SnapdragonCamera
: 这部分指定了要构建的目标模块或子模块的名称。在这种情况下,目标是构建SnapdragonCamera
模块,该模块是相机应用的一部分。 -
-j32
: 这部分指定了并发构建的线程数。-j32
表示同时使用32个线程进行构建,以加快构建速度。
综上所述,该指令的作用是使用Ninja构建系统,通过给定的构建文件路径和名称,在指定的线程数下构建SnapdragonCamera
模块。这样可以快速生成相机应用所需的构建结果。
下面是编译其它模块的快编指令:
#编译Settings
./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm-eng.ninja Settings -j32
#编译selinux
./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm-eng.ninja selinux_policy -j32
#编译Framework
./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm-eng.ninja frameworks -j32
#全编译
./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm-eng.ninja -j32 2>&1 |tee ninja_build.log
#WIFI-service
./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm-eng.ninja com.android.wifi -j32
四、新建lunch项和编译类型说明
1.vendorsetup.sh(以前)
add_lunch_combo xxxx-user
add_lunch_combo xxxx-userdebug
add_lunch_combo xxxx-eng
2.AndroidProducts.mk(现在)
在AndroidProducts.mk中COMMON_LUNCH_CHOICES添加对应的lunch选项
3. 编译类型说明
1. eng:默认类型,该编译类型适用于开发阶段。
当选择这种类型时,编译结果将:
a. 安装包含 eng, debug, user,development 标签的模块b. 安装所有没有标签的非 APK 模块
c. 安装所有产品定义文件中指定的 APK 模块
2. user:该编译类型适合用于最终发布阶段。
当选择这种类型时,编译结果将:
a.安装所有带有 user 标签的模块
b.安装所有没有标签的非 APK 模块
c.安装所有产品定义文件中指定的 APK 模块,APK 模块的标签 将被忽略
3. userdebug 该编译类型适合用于 debug 阶段。
该类型和 user 一样,除了:
a.会安装包含 debug 标签的模块
b.编译出的系统具有 root 访问权限
五、Android编译系统的整体架构
1.build/core/config.mk
该文件根据lunch命令所配置的产品信息在build/target/board、vendor或者device目录中找到对应的BoradConfig.mk文件,以及通过加载build/core/product_config.mk文件在build/target/product、vendor或者device目录中找到对应的AndroidProducts.mk文件,来进一步对编译环境进行配置,以便接下来编译指定模块时可以获得必要的信息。
2.build/core/definitions.mk
该文件定义了在编译过程需要调用到的各种自定义函数。
3.指定的Android.mk
这些指定的Android.mk环境是由mmm命令通过环境变量ONE_SHOT_MAKEFILE传递给build/core/main.mk文件使用的。这些Android.mk文件一般还会通过环境变量BUILD_PACKAGE、BUILD_JAVA_LIBRARY、BUILD_STATIC_JAVA_LIBRARY、BUILD_SHARED_LIBRARY、BUILD_STATIC_LIBRARY、BUILD_EXECUTABLE和BUILD_PREBUILT将build/core/package.mk、build/core/java_library.mk、build/core/static_java_library.mk、build/core/shared_library.mk、build/core/static_library.mk、build/core/executable.mk和build/core/prebuilt.mk等编译片段模板文件加载进来,来表示要编译是APK、Java库、Linux动态库/静态库/可执行文件或者预先编译好的文件等等。
4.build/core/Makefile
该文件包含了用来制作system.img、ramdisk.img、boot.img和recovery.img等镜像文件的脚本。
六、编译后的输出目录和生成文件
1.Build结果的目录结构
所有的编译产物都将位于 /out 目录下,该目录下主要有以下几个子目录:
/out/host/:该目录下包含了针对主机的 Android 开发工具的产物。即 SDK 中的各种工具,例如:emulator,adb,aapt 等。
/out/target/common/:该目录下包含了针对设备的共通的编译产物,主要是 Java 应用代码和 Java 库。
/out/target/product/<product_name>/:包含了针对特定设备的编译结果以及平台相关的 C/C++ 库和二进制文件。其中,<product_name>是具体目标设备的名称。
2.Build生成的镜像文件
Build 的产物中最重要的是四个镜像文件,它们都位于 /out/target/product/<product_name>/ 目录下;这四个文件是:
system.img:包含了 Android OS 的系统文件,库,可执行文件以及预置的应用程序,将被挂载为根分区。
ramdisk.img:在启动时将被 Linux 内核挂载为只读分区,它包含了 /init 文件和一些配置文件。它用来挂载其他系统镜像并启动 init 进程。
userdata.img:将被挂载为 /data,包含了应用程序相关的数据以及和用户相关的数据。
boot.img: 是手机启动所必须加载的文件。简单的说,boot.img包含两部分,分别为kernel 和ramdisk。
七、Android常用编译命令总结
常用编译命令:make、m、mm、mmm、mma、mmma
与lunch命令一样,m、mm、mmm、mma、mmma命令也分别是由定义在build/envsetup.sh文件中的函数m、mm和mmm提供的,而这三个函数又都是通过make命令来对源代码进行编译的。事实上,命令m就是对make命令的简单封装,并且是用来对整个Android源代码进行编译,而命令mm、mmm 、mma、mmma都是通过make命令来对Android源码中的指定模块进行编译。
- m:编译所有的模块,与make功能等同;
- mm:编译当前目录下的模块,当前目录下需要有Android.mk这个makefile文件,否则就往上找最近的Android.mk文件;
- mma:编译当前目录下的模块,并且编译相关的依赖库,如果当前目录新增或删除文件后,可以用mma重新编译;
- mmm:编译指定路径下的模块,指定的路径下面需要有Android.mk这个makefile文件;
- mmma:编译指定路径下的模块,并且编译相关的依赖库,如果指定目录下新增或删除文件后,可以用mmma重新编译。
我们经常习惯于使用mmm编译,而6.0以后经常会报依赖库的编译错误,我们可以先使用mmma编译,第二次编译时可以使用mmm编译。
本文只是对Android系统的编译指令作简要介绍,难免存在不足之处。如有任何错误或改进意见,请不吝指正和建议。