android源码下载及编译(2)-编译

目录

一、前言

源码下载完后,真正的编译步骤只有以下几步:

cd android 			        //切到android目录下,即下载的源码根目录	 
source build/envsetup.sh	//也可以. build/envsetup.sh
lunch       				//选择编译版本类型
23          		       //针对不同类型选择序号,我这里选择23 user版
make clean		           //清除out目录,谨慎操作,会删除之前的所有编译,如果是第一次编译就无所谓                        
make -j8   		    //真正的源码编译,多线程编译:8为同时编译的线程数,一般Google推荐执行源码编译的线程数 = CPU核心数x 2 + 2,比如4核,就推荐10线程编译,执行make –10
mmm packages/apps/Helloword/         //源码编译完后可以执行单模块编译

源码编译跟源码下载一样是个很漫长的过程。但是编译前的准备不足或有些配置不完整,会导致编译中断或出错,需要重新编译,会浪费很多时间,以下就上面的编译命令作具体讲解。

二、初始化编译环境

编译前对编译环境的配置,是我们编译源码的必行之路。介于不同的源码定制厂商对环境配置可能会有一定的出入,因此,这里只是介绍几个基本通用的环境配置命令,供大家参考: 

        1.1 在 .bashrc文件中添加相关属性:

             echo export USE_CCACE=1 >> ~/.bashrc 

        1.2 为了提高编译效率,我们需要设置编译器高速缓存,执行以下命令:

              prebuilts/misc/linux-x86/ccache/ccache -M 50G

              -M 50G 两个参数表示设置50G大小的空间作为编译缓存,这个数值可以根据自己的硬盘空间大小进行调整。

       (以上两步可以不做)

1.3 导入编译Android源码所需的环境变量和其它参数,运行以下命令:

  source build/envsetup.sh		//source可以用.代替 

  1.4 运行lunch命令选择编译目标:

  lunch

android源码下载及编译(2)-编译_第1张图片

所有编译目标都采用 BUILD-BUILDTYPE形式,其中 BUILD 是表示特定功能组合的代号。

BUILDTYPE 是以下类型之一:

         android源码下载及编译(2)-编译_第2张图片

三者具体差异Google也在官方文档中给出了说明:https://source.android.com/source/building

          android源码下载及编译(2)-编译_第3张图片

模拟器一般选eng,调试功能全开。

调试真机的话选userdebug

发行最终版本用user

官方给出了一份自己出厂设备的代号和编译配置选项

           android源码下载及编译(2)-编译_第4张图片

刚开始接触源码时,没有真机,所以第一次选择的是“1”,用的模拟器运行的,在模拟器上折腾了一段时间后果断淘了一台二手的NEXUS 5 ,所以后来又重新选泽aosp_hammerhead-userdebug编译,每次编译都需要很漫长的等待。

三、源码编译

通过make指令进行代码编译,该指令通过-j参数来设置参与编译的线程数量,以提高编译速度.比如这里我们设置8个线程同时编译:

make -j8

【执行make -j8, 8为同时编译的线程数,一般Google推荐执行源码编译的线程数 = CPU核心数x 2 + 2,比如4核,就推荐10线程编译,执行make –10。】

    关于cpu个数,可以用下面命令查看:

cat /proc/cpuinfo |  grep processor

可看到自己创建的虚拟机CPU核心共有 4 个,那么要实现最快的编译速度,可以使用介于 make -j4到 make -j8之间的命令。

(说明:以上CPU详情是参考网上截图,我用的公司电脑,CPU是单核,执行编译命令make -j4,但是执行到libwebviewchromium.so时执行不下去了,百度之后说是因为内存不足,需增加内存或虚拟内存,所以建议在编译之前增加2GSWAP,具体参考《android源码编译(3)-编译中常见问题》第二点)

然后就是漫长的等待过程……

编译完会生成out目录,out 文件夹内生成 img 文件
system.img:由out/target/product/PRODUCT_OUT/system目录生成 
ramdisk.img:由out/target/product/PRODUCT_OUT/root目录生成
userdata.img:由out/target/product/PRODUCT_OUT/data目录生成
boot.img:包含kernel.img和ramdisk.img
recovery.img:我们可以通过boot.img和recovery_from_boot.p文件生成一个recovery.img文件

四、运行模拟器

如果没有真机,只想看下源码或只想先在模拟器上试跑一下,可以通过执行

emulator打开模拟器,如果是真机,可以跳过这一步。

既然谈到了模拟器运行,这里我们顺便介绍模拟器运行所需要四个文件:

Linux Kernel

system.img

userdate.img

ramdisk.img

如果你在使用lunch命令时选择的是aosp_arm-eng,那么在执行不带参数的emualtor命令时,Linux Kernel默认使用的是/source/prebuilds/qemu-kernel/arm/kernel-qemu目录下的kernel-qemu文件;而android镜像文件则是默认使用source/out/target/product/generic目录下的system.img,userdata.img和ramdisk.img,也就是我们刚刚编译出来的镜像文件.

上面我在使用lunch命令时选择的是aosp_arm64-eng,因此linux默认使用的/source/prebuilds/qemu-kernel/arm64/kernel-qemu下的kernel-qemu,而其他文件则是使用的source/out/target/product/generic64目录下的system.img,userdata.img和ramdisk.img.

当然,emulator指令允许你通过参数制定使用不同的文件,具体用法可以通过emulator --help查看

五、模块编译及打包

1.模块编译

除了通过make命令编译整个android源码外,Google也为我们提供了相应的命令来支持单独模块的编译.

编译环境初始化(即执行source build/envsetup.sh)之后,我们可以得到一些有用的指令,除了上边用到的lunch,还有以下: 

android源码下载及编译(2)-编译_第5张图片

简单解释一下:
--mm:         编译当前目录中的所有模块(如果要编译某个模块,需先切换到模块目录中,直接执行mm)。
--mmm:    编译指定目录中的所有模块。

区别:通常来说,每个目录即代表一个模块.比如这里我们要编译Launcher2模块,可以执行指令:

mmm    packages/apps/Launcher2/

也可以切换到Launcher2目录中,然后执行:

xxx@ubuntu:~ /android/packages/apps/ Launcher2$ mm

稍等一会之后,如果提示:

### make completed success fully ###

即表示编译完成,此时在out/target/product/gereric/system/app就可以看到编译的Launcher2.apk文件了。

我们也可以将自己的项目复制到packages/apps目录中,通过以上两种任意命令编译,生成的apk同样会放入out/target/product/gereric/system/app中,记得项目根目录添加Android.mk文件,否则编译不过。关于Android.mk的介绍以后会整理。

2.打包

make bootimage			//用这条命令可以生成boot.img,这个镜像文件中包含Linux Kernel,Ram disk,生成的boot.img只能通过fastboot进行烧写
make recoveryimage		//生成 recovery.img
make systemimage 		//生成 system.img
make userdataimage 		//生成userdata.img
make ramdisk 			//生成ramdisk.img	
make snod 			// 快速打包system.img从已经编译出的包快速重建系统镜像。

如果只是修改out/target/product/xxxx/system目录下内容,可以直接通过make snod快速打包system.img镜像文件。如:将任一apk放入out/target/product/xxxx/system/app目录下,或编译好指定模块后,想要将该模块对应的apk集成到系统镜像中,直接通过make snod指令重新打包系统镜像,这样我们新生成的system.img中就包含了刚才编译的Launcher2模块.重启模拟器之后生效。刷机到手机也是一样。

参考:

自己动手编译Android 8.0源码

https://blog.csdn.net/dl6655/article/details/78869501/

二、Android系统源码编译及刷机实战

https://blog.csdn.net/u012417380/article/details/73196722

Android系统篇(一)——建立Android系统开发环境

https://blog.csdn.net/qq_26787115/article/details/79543340


你可能感兴趣的:(android源码,android,源码编译,打包)