本文的主要内容是解决在Android源代码的编译过程中出现的各种问题。

大家都知道,Android是开源的,可以在Android Open Source Project(点击打开链接)下载。下载的流程与方法,可以访问上述网页查看详细说明。

「编译原理」

首先,我们应该对Android的编译原理有所了解。普通的Android应用开发,多数是在eclipse中开发的。在eclipse中,Android Project是通过安装在eclipse中ADT插件进行编译的。这种编译方式与在Liunx系统下的编译方式是不同的。

在Liunx系统下,Android源代码的编译方式是通过make file(Android.mk)来实现的。也就是说,在编译过程中,编译命令会查找每个文件夹中是否存在Android.mk文件,如果存在,那么系统就会按照Android.mk文件中的编译规则进行编译。

「jdk版本不符合」

我们都知道,Android编译的命令是make -j*(*代表CPU的核发数)。执行make -j*后,执行的文件就是build/core/main.mk。在开始编译之前,会检测系统是否符合编译需要的要求。例如检测系统是否安装jdk以及jdk的版本等。

不同的Android版本对jdk的版本要求也不尽相同。本文将以android-4.1.2_r1为例进行讲解。

Android 4.1规定的jdk版本是1.6,也就是说,如果Linux系统安装的jdk版本不是1.6的话,编译将无法继续进行。

在终端在会出现以下提示信息:

You are attempting to build with the incorrect version

Your version is:  1.7.0_21.
The correct version is: Java SE 1.6.

解决这个问题的方法就是修改Android源代码中的文件,将其规定的版本号改为本机中已安装的jdk的版本号即可。

修改文件:

android-4.1.2_r1/build/core/main.mk

[html] view plaincopy
  1. <span style="font-size:14px;"># Check for the correct version of java
  2. java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')
  3. ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
  4. java_version :=
  5. endif
  6. ifeq ($(strip $(java_version)),)
  7. $(info ************************************************************)
  8. $(info You are attempting to build with the incorrect version)
  9. $(info of java.)
  10. $(info $(space))
  11. $(info Your version is: $(shell java -version 2>&1 | head -n 1).)
  12. $(info The correct version is: Java SE 1.6.)
  13. $(info $(space))
  14. $(info Please follow the machine setup instructions at)
  15. $(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
  16. $(info ************************************************************)
  17. $(error stop)
  18. endif</span>

如果本机中安装的jdk版本为1.7,那么只需将

java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')

修改为

java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.7[\. "$$]')

即可。

同样,javac的版本号也需要修改。

[html] view plaincopy
  1. <span style="font-size:14px;"># Check for the correct version of javac
  2. javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')
  3. ifeq ($(strip $(javac_version)),)
  4. $(info ************************************************************)
  5. $(info You are attempting to build with the incorrect version)
  6. $(info of javac.)
  7. $(info $(space))
  8. $(info Your version is: $(shell javac -version 2>&1 | head -n 1).)
  9. $(info The correct version is: 1.6.)
  10. $(info $(space))
  11. $(info Please follow the machine setup instructions at)
  12. $(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
  13. $(info ************************************************************)
  14. $(error stop)
  15. endif</span>

javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')

修改为

javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.7[\. "$$]')

「编译中常见问题」

解决了jdk版本的问题后,随着编译的进行可能会出现其他错误(主要为command not found),导致编译中止。

如果在没有修改过的源代码中编译,出现错误的话,绝大部分是由于系统中缺少必要的软件造成的。

经过本人亲身实践,编译中会用到下列软件:

bison
 zlib1g-dev
 flex
 libncurses-dev
 gperf
 xsltproc
 build-essential
 g++
 g++-multilib
 ia32-libs
 libxml2-utils

解决办法就是在编译之前,提前安装上述软件,安装命令如下:

[html] view plaincopy
  1. sudo apt-get install bison
  2. sudo apt-get install zlib1g-dev
  3. sudo apt-get install flex
  4. sudo apt-get install libncurses-dev
  5. sudo apt-get install gperf
  6. sudo apt-get install xsltproc
  7. sudo apt-get install build-essential
  8. sudo apt-get install g++
  9. sudo apt-get install g++-multilib
  10. sudo apt-get install ia32-libs
  11. sudo apt-get install libxml2-utils

安装完上述软件后,再重新进行编译,就可以正常编译了。普通的4核电脑整个编译过程大约会需要4个小时。

「out文件夹」

编译成功后,会在android-4.1.2_r1目录下生成一个out文件夹。out里面的文件就是编译后的产物。

下面对out文件夹的构成做简单的讲解。

out下有两个文件夹

host

target

其中,target文件夹中有我们需要的东西。

target下又有两个文件夹

common

product

common 文件夹中用的最多的就是取得编译生成的java libraries。因为在sdk中所有标记为@hide的方法或变量都是无法访问的,所以当你需要访问他们的时候,就必须使用下面文件夹内的library。

out/target/common/obj/JAVA_LIBRARIES

product文件夹,顾名思义,就是编译后最终生成的文件的存放位置。

标准Android源代码中,生成的文件夹叫generic。厂商定制之后,这个文件夹的名字会发生变化,会变成手机的型号。

在generic文件夹内,有两个地方是比较重要的。

一个是system.img

这是编译生成的system文件夹的镜像文件,制作ROM必不可少的文件。

另一个就是system文件夹

这里面有我们需要的apk文件,存放在system/app文件夹下。

「odex与dex」

需要说明的是,默认情况下sytem/app文件夹下的apk包括两个文件:

Launcher2.apk

Launcher2.odex

这是因为编译过程中没有将classes.jar与资源文件打在同一个文件中(classes.dex),而是单独生成了odex文件。

关闭odex化的方法是

修改android-4.1.2_r1/build/core/package.mk

[html] view plaincopy
  1. ifneq (true,$(WITH_DEXPREOPT))
  2. LOCAL_DEX_PREOPT :=
  3. else
  4. ifeq (,$(TARGET_BUILD_APPS))
  5. ifneq (,$(LOCAL_SRC_FILES))
  6. ifndef LOCAL_DEX_PREOPT
  7. #feizl mod start
  8. #LOCAL_DEX_PREOPT := true
  9. LOCAL_DEX_PREOPT := false
  10. #feizl mod end
  11. endif
  12. endif
  13. endif
  14. endif
  15. ifeq (false,$(LOCAL_DEX_PREOPT))
  16. LOCAL_DEX_PREOPT :=
  17. endif

LOCAL_DEX_PREOPT := true

修改为

LOCAL_DEX_PREOPT := false

同样,如果想让framework也不生成odex文件的话,就可以修改以下文件

android-4.1.2_r1/build/core/java_library.mk

[html] view plaincopy
  1. ifneq (true,$(WITH_DEXPREOPT))
  2. LOCAL_DEX_PREOPT :=
  3. else
  4. ifeq (,$(TARGET_BUILD_APPS))
  5. ifndef LOCAL_DEX_PREOPT
  6. #feizl mod start
  7. #LOCAL_DEX_PREOPT := true
  8. LOCAL_DEX_PREOPT := false
  9. #feizl mod end
  10. endif
  11. endif
  12. endif
  13. ifeq (false,$(LOCAL_DEX_PREOPT))
  14. LOCAL_DEX_PREOPT :=
  15. endif

LOCAL_DEX_PREOPT := true

修改为

LOCAL_DEX_PREOPT := false

修改之后,重新执行编译命令,但要注意提前删除system/app和system/framework下的文件。

在编译完成后,上述文件夹内的文件就是classes与资源文件合二为一了。

以上就是本文的全部内容,希望对大家有所帮助。

其他与编译相关的内容将在以后推出,敬请期待。

Android源代码编译的准备工作相关推荐

  1. Android源代码编译命令m/mm/mmm/make分析

    Android源代码编译命令m/mm/mmm/make分析 2014-03-10     我来说两句    来源:Android源代码编译命令m/mm/mmm/make分析   收藏    我要投稿 ...

  2. 鸟人的Android揭秘(4)——Android 源代码编译

    前文主要讲解了 Android 编译环境的搭建,接下来我们正式开始 Android 源代码的编译,主要涉及两部分内容:源代码的下载和源代码编译. 一.Android源代码下载 1)      配置 G ...

  3. Android源代码编译原理与前期准备

    本文的主要内容是解决在Android源代码的编译过程中出现的各种问题. 大家都知道,Android是开源的,可以在Android Open Source Project(点击打开链接)下载.下载的流程 ...

  4. Android10.0 系统解析(02)——搭建Android源代码编译调试环境

    1.前言 Android的编译环境作为深入学习Android的基础,不可或缺,能够完整下载Android源代码并编译成功,对深入学习Android是非常关键和重要的一步.Android环境搭建比较繁琐 ...

  5. linux 源码目录结构,分析Android 源代码编译前后的目录结构

    我们看没有编译前的项目目录大致的情况如下 : 在树结构中我们可以了解的有如下一些信息分析: 1.        getSplashy                项目名称: 2.        sr ...

  6. 简诉android源代码编译过程,Android源码编译过程及原理(二)

    在未来等风也等你 本节主要记录的内容anroid 编译系统的结构 编译中枢中main.mk的基本解析 除非特别说明本节中的目录都是基于android的源码目录 1. android 编译系统的结构 a ...

  7. 简诉android源代码编译过程,详解Android源码的编译

    在这里我们将介绍的是Android源码的编译,主要基于Android 1.0环境下.希望对大家有所帮助. 本文将为大家介绍的是如何设置Android源码的编译环境,包括Linux下的配置.主要基于An ...

  8. 如何单独编译Android源代码中的模块

    第一次下载好Android源代码工程后,我们通常是在android源代码工程目录下执行make命令,经过漫长的等待之后,就可以得到Android系统镜像system.img了.以后如果我们修改了And ...

  9. 编译 Android 源代码 之路一

    编译Android源代码 很久之前就想编译Android源代码试试,一直没有尝试,这几天利用业余时间尝试编译一下Android源代码. 虽然网络上有很多作者,写过编译Android源代码的过程,基本上 ...

最新文章

  1. 2021年编程语言趋势预测:Python和JavaScript仍火热,Go不可小觑
  2. android中进程的优先级
  3. 小逗比机器人聊天接口api
  4. 谈谈垃圾回收机制方式及内存管理
  5. 排序算法 JavaScript
  6. jQuery常用方法一览
  7. c# excel导出png_c#根据html模板导出excel
  8. unittest单元测试框架—基本实例
  9. Phaser都不懂,还学什么多线程
  10. guava限流器RateLimiter原理及源码分析
  11. 光伏补贴新政出台 投资机会解析
  12. linux 进程 cpu 100,清理linux中占用CPU 100%的病毒
  13. java你如何调字体大小_eclipse怎样调整代码字体大小 值得一看
  14. 解决 未能为数据库 '数据库用户名' 中的对象 '表名' 分配空间,因为文件组 'PRIMARY' 已满...
  15. tap10.app cn.html,Tap连点器
  16. 《信息安全概论》总结(1)
  17. 批量将txt文件转为csv文件
  18. ios中获得UUID的方法,ios怎么获得uuid
  19. [MySQL 源码] Innodb Pessimistic Insert流程
  20. takes 1 positional argument but 2 were given

热门文章

  1. 用python判断所输入的任意一个正整数是否为素数
  2. 看雪3万课程笔记-Frida 辅助分析ollvm字符串加密(一)
  3. 春招进行中,想进外企?500强资深程序员谈谈外企真实感受!
  4. Java是剑客-飘逸;.NET是刀客-霸道 (一)
  5. 全极化SAR图像freeman分解
  6. python+scrapy爬取斗鱼图片
  7. 还原一个真实的银行待遇
  8. 区块链技术在银行业的运用
  9. 7月18日服务器维护时,2018年7月18日维护公告
  10. html怎么混合颜色,在CSS中为背景混合两种颜色