自己可以编译安卓源码吗?

发布网友 发布时间:2022-04-20 20:01

我来回答

2个回答

热心网友 时间:2023-06-27 19:04

用最新的Ubuntu 16.04,请首先确保自己已经安装了Git.没安装的同学可以通过以下命令进行安装:

sudo apt-get install git git config –global user.email “test@test.com” git config –global user.name “test”

其中test@test.com为你自己的邮箱.

简要说明

android源码编译的四个流程:1.源码下载;2.构建编译环境;3.编译源码;4运行.下文也将按照该流程讲述.

源码下载

由于某墙的原因,这里我们采用国内的镜像源进行下载.
目前,可用的镜像源一般是科大和清华的,具体使用差不多,这里我选择清华大学镜像进行说明.(参考:科大源,清华源)

repo工具下载及安装

通过执行以下命令实现repo工具的下载和安装

mkdir ~/binPATH=~/bin:$PATHcurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+x ~/bin/repo

补充说明
这里,我来简单的介绍下repo工具,我们知道AOSP项目由不同的子项目组成,为了方便进行管理,Google采用Git对AOSP项目进行多仓库管理.在聊repo工具之前,我先带你来聊聊多仓库项目:

我们有个非常庞大的项目Pre,该项目由很多个子项目R1,R2,...Rn等组成,为了方便管理和协同开发,我们为每个子项目创立自己的仓库,整个项目的结构如下:


这里写图片描述

将一个项目Pre进行分库后会遇到这么一个问题:如果我们想要创建Pre分支来做feature开发,这就意味着,我们需要到每个子项目中分别创建对应的分支,这个过程如果纯粹靠手工做,那简直是个灾难,利索当然我们会想写个自动化处理程序(我们假设这个工具叫做RepoUtil)来帮助我们解决这个问题.这个RepoUtil也会有版本管理之类的需求,因此我们也用Git对其管理,并为其创建对应的仓库.此时整个项目的结构如下:


这里写图片描述


这里RepoUtil知道整个项目Pre下的每个子项目(即维护子项目的列表),同时需要提供对这些子项目的管理功能,比如统一创建分支等.但是从"单一职责"角度来看,RepoUitl这个工具的功能过于复杂,我们完全可以将维护子项目列表这个功能抽取出来作为一个新项目sub_projects,因为子项目也会变化,因此,为其创建对应的仓库,并用Git管理,这样的化,RepoUtil只需要通过简单的对ub_projects进行依赖即可,此时整个项目的结构如下:


这里写图片描述

AOSP项目结构和我上文的描述非常类似.repo工具对应RepoUtil,mainfest对应sub_projects.
总结一下:repo就是这么一种工具,由一系列python脚本组成,通过调用Git命令实现对AOSP项目的管理.

建立源码文件夹

熟悉Git的同学都应该知道,我们需要为项目在本地创建对应的仓库.同样,这里为了方便对代码进行管理,我们为其创建一个文件夹.这里我在当前用户目录下创建了source文件夹,后面所有的下载的源码和编译出的产物也都放在这里,命令如下:

mkdir sourcecd source

初始化仓库

我们将上面的source文件夹作为仓库,现在需要来初始化这个仓库了.通过执行初始化仓库命令可以获取AOSP项目master上最新的代码并初始化该仓库,命令如下:

repo init -u https://aosp.tuna.tsinghua.e.cn/platform/manifest

或者使用:

repo init -u git://aosp.tuna.tsinghua.e.cn/aosp/platform/manifest

两者实现的效果一致,仅仅只是协议不同.
如果执行该命令的过程中,如果提示无法连接到 gerrit.googlesource.com,那么我们只需要编辑 ~/bin/repo文件,找到REPO_URL这一行,然后将其内容修改为:

REPO_URL = 'https://gerrit-google.tuna.tsinghua.e.cn/git-repo'

然后重新执行上述命令即可.

补充说明
不带参数的manifest命令用于获取master上最新的代码,但是可以通过-b参数指定获取某个特定的android版本,比如我们想要获取android-4.0.1_r1分支,那么命令如下:

repo init -u https://aosp.tuna.tsinghua.e.cn/platform/manifest -b android-4.0.1_r1

(AOSP项目当前所有的分支列表参看:分支列表)

同步源码到本地

初始化仓库之后,就可以开始正式同步代码到本地了,命令如下:

repo sync

以后如果需要同步最新的远程代码到本地,也只需要执行该命令即可.在同步过程中,如果因为网络原因中断,使用该命令继续同步即可.不出意外,5个小时便可以将全部源码同步到本地.所以呢,这个过程可以放在晚上睡觉期间完成.

(提示:一定要确定代码完全同步了,不然在下面编译过程出现的错误会让你痛不欲生,不确定的童鞋可以多用repo sync同步几次)

构建编译环境

源码下载完成后,就可以构建编译环境了.在开始之前,我们先来看看一些编译要求:

1. 硬件要求:
位的操作系统只能编译2.3.x以上的版本,如果你想要编译2.3.x以下的,那么需要32位的操作系统.
磁盘空间越多越好,至少在100GB以上.意思就是,你可以去买个大点的硬盘了啊
如果你想要在是在虚拟机运行linux,那么至少需要16GB的RAM/swap.
(实际上,我非常不推荐在虚拟机中编译2.3.x以上的代码.)

2. 软件要求:
1. 操作系统要求
在AOSP开源中,主分支使用Ubuntu长期版本开发和测试的,因此也建议你使用Ubuntu进行编译,下面我们列出不同版本的的Ubuntu能够编译那些android版本:

Android版本

编译要求的Ubuntu最低版本

Android 6.0至AOSP master    Ubuntu 14.04    

Android 2.3.x至Android 5.x    Ubuntu 12.04    

Android 1.5至Android 2.2.x    Ubuntu 10.04    

2. JDK版本要求
除了操作系统版本这个问题外,我们还需要关注JDK版本问题,为了方便,同样我们也列出的不同Android版本的源码需要用到的JDK版本:

Android版本

编译要求的JDK版本

AOSP的Android主线    OpenJDK 8    

Android 5.x至android 6.0    OpenJDK 7    

Android 2.3.x至Android 4.4.x    Oracle JDK 6    

Android 1.5至Android 2.2.x    Oracle JDK 5    

更具体的可以参看:Google源码编译要求

我现在在Ubuntu 16.04下编译AOSP主线代码,因此需要安装OpenJDK 8,执行命令如下:
sudo apt-get install openjdk-8-jdk
如果你需要在Ubuntu 14.04下编译AOSP主线代码,同样需要安装OpenJDK 8,此时需要执行如下命令:

sudo apt-get updatesudo apt-get install openjdk-8-jdk

如果你要编译的是Android 5.x到android 6.0之间的系统版本,需要采用openjdk7.但是在Ubuntu 15.04及之后的版本的在线安装库中只支持openjdk8和openjdk9的安装.因此,如果你想要安装openjdk 7需要首先设置ppa:

sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update

然后再执行安装命令:

sudo apt-get install openjdk-7-jdk

有时候,我们需要编译不同版本的android系统,就可能使用不同的jdk版本.关于jdk版本切换,可以使用如下命令:

sudo update-alternative --config javasudo update-alternative --config javac

3. 其他要求

Google官方构建编译环境指南中已经说明了Ubuntu14.04,Ubuntu 12.04,Ubuntu 10.04需要添加的依赖,这里我们就不做介绍了.我原先以为,Ubuntu16.04的设置和Ubuntu14.04的依赖设置应该差不多,但是只能说too young too simple.
下面是Ubuntu16.04中的依赖设置:

sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386 sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-devsudo apt-get install git-core gnupg flex bison gperf build-essential  sudo apt-get install zip curl zlib1g-dev gcc-multilib g++-multilib sudo apt-get install libc6-dev-i386 sudo apt-get install lib32ncurses5-dev x11proto-core-dev libx11-dev sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4sudo apt-get install lib32z-dev ccache

(其中几个命令中参数是重复的,但不妨碍我们)

初始化编译环境

确保上述过程完成后,接下来我们需要初始化编译环境,命令如下:

source build/envsetup.sh

执行该命令结果如下:


这里写图片描述

不难发现该命令只是引入了其他执行脚本,至于这些脚本做什么,目前不在本文中细说.
该命令执行成功后,我们会得到了一些有用的命令,比如最下面要用到的lunch命令.

编译源码

初始化编译环境之后,就进入源码编译阶段.这个阶段又包括两个阶段:选择编译目标和执行编译.

选择编译目标

通过lunch指令设置编译目标,所谓的编译目标就是生成的镜像要运行在什么样的设备上.这里我们设置的编译目标是aosp_arm-eng,因此执行指令:

lunch aosp_arm-eng

编译目标格式说明
编译目标的格式:BUILD-BUILDTYPE,比如上面的aosp_arm-eng的BUILD是aosp_arm,BUILDTYPE是eng.

什么是BUILD

BUILD指的是特定功能的组合的特定名称,即表示编译出的镜像可以运行在什么环境.其中,aosp(Android Open Source Project)代表Android开源项目;arm表示系统是运行在arm架构的处理器上,arm则是指位arm架构;处理器,x86则表示x86架构的处理器;此外,还有一些单词代表了特定的Nexus设备,下面是常用的设备代码和编译目标,更多参考官方文档
|受型号|设备代码|编译目标|
|---|----|---|
|Nexus 6P|angler|aosp_angler-userdebug|
|Nexus 5X|bullhead|aosp_bullhead-userdebug|
|Nexus 6|shamu|aosp_shamu-userdebug|
|Nexus 5|hammerhead|aosp_hammerhead-userdebug|

提示:如果你没有Nexus设备,那么通常选择arm或者x86即可

什么是BUILDTYPE

BUILD TYPE则指的是编译类型,通常有三种:
-user:代表这是编译出的系统镜像是可以用来正式发布到市场的版本,其权限是被*的(如,没有root权限,不鞥年deg等)
-userdebug:在user版本的基础上开放了root权限和debug权限.
-eng:代表engineer,也就是所谓的开发工程师的版本,拥有最大的权限(root等),此外还附带了许多debug工具

了解编译目标的组成之后,我们就可以根据自己目前的情况选择了.那不知道编译目标怎么办?
我们只需要执行不带参数的lunch指令,稍后,控制台会列出所有的编译目标,如下:


这里写图片描述


接着我们只需要输入相应的数字即可.

来举个例子:你没有Nexus设备,只想编译完后运行看看,那么就可以选择aosp_arm-eng.
(我在ubuntu 16.04(位)中编译完成后启动虚拟机时,卡在黑屏,尝试编译aosp_arm-eng解决.因此,这里我使用了aosp_arm-eng)

开始编译

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

make -j8

需要注意的是,参与编译的线程并不是越多越好,通常是根据你机器cup的核心来确定:core*2,即当前cpu的核心的2倍.比如,我现在的笔记本是双核四线程的,因此根据公式,最快速的编译可以make -j8.
(通过cat /proc/cpuinfo查看相关cpu信息)

如果一切顺利的化,在几个小时之后,便可以编译完成.看到### make completed successfully (01:18:45(hh:mm:ss)) ###表示你编译成功了.

运行模拟器

在编译完成之后,就可以通过以下命令运行Android虚拟机了,命令如下:

source build/envsetup.shlunch(选择刚才你设置的目标版本,比如这里了我选择的是2)emulator

如果你是在编译完后立刻运行虚拟机,由于我们之前已经执行过source及lunch命令了,因此现在你只需要执行命令就可以运行虚拟机:

emulator

不出意外,在等待一会之后,你会看到运行界面:


这里写图片描述

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

热心网友 时间:2023-06-27 19:05

你是说的反编译吗?
拿到apk文件--经过 脱壳(脱掉APP本身的加固)--反编译(apktool)就可以反编译到源码了,一般都是混淆后的,用来学习了解作者的思路还是可以的

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com