Ubuntu16.04编译Android源码7.1.2和4.4及踩坑

一、前言

        本文不涉及源码下载过程,主要记录自己的编译源码过程及其中遇到的问题,并最终运行在真机上。

二、预置环境

        1、ubuntu16.04,8G内存,2T硬盘

        2、手机真机nexus 5x, nexus 5

        3、编译源码版本为android-7.1.2_r18和android-4.4_r1两个

        版本选择参考链接:https://source.android.google.cn/setup/start/build-numbers#source-code-tags-and-builds,根据你的真机型号选择对应的源码版本。

三、编译要求

        由于两个源码版本不同,本文依次编译。

1、编译android-7.1.2版本

1)要求

参考链接:https://source.android.google.cn/setup/build/requirements

需要jdk、python、gnu make、git

由于本文在下载源码过程中已经配置了git,因此略过。

a、设置java环境

Ubuntu16.04编译Android源码7.1.2和4.4及踩坑_第1张图片

        如图所示,此时要编译源码7.1.2版本,Ubuntu下要求java环境为OpenJDK8

        执行命令安装:

//正常来说命令行配置jre即可
sudo apt-get install openjdk-8-jre
//但我同时安装了jdk
sudo apt-get install openjdk-8-jdk

        执行命令查看是否安装成功:

java -version
javac -version

        如果安装过程没有出错,那么此时应该能够看到openjdk1.8环境。

b、设置python

        ubuntu中自带python环境,且版本为2.7,可通过执行python命令查看。

c、设置gnu make

        ubuntu中自带gnu make,版本为4.1,但由于我们此时编译Android版本为7.1,可以在该版本执行,因此也不作改变。可通过执行make命令查看版本。

2)下载驱动

        因为本文编译系统最终需要刷到真机上,因此需要下载对应的驱动。google提供了 Nexus 和 Pixel 设备的驱动文件,链接:https://developers.google.cn/android/drivers,在链接中,可以根据下载源码的版本名称,搜索到对应的驱动。本文在该7.1.2版本中直接下载编译好的镜像文件,查看版本选择时的链接,7.1.2_r18对应的细分版本为N2G47Z,在https://developers.google.cn/android/images中搜索N2G47Z,找到对应压缩包下载。

3)安装需要的库文件

sudo apt install g++-multilib
sudo apt install gperf
sudo apt install libxml2-utils
sudo apt install curl
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt-get install m4

4)开始编译

进入源码根目录

a、初始化编译环境,执行以下命令,注意.和build之间有空格:

. build/envsetup.sh

b、使用lunch选择编译目标

lunch

执行此命令后,会出现当前可以编译的版本其对应的数字

Ubuntu16.04编译Android源码7.1.2和4.4及踩坑_第2张图片

运行版本查看链接:https://source.android.google.cn/source/running

在该链接中查看手机类型,选择对应的运行版本,这里我的手机是nexus5x,希望编译带有root权限的可调试版本,因此选择userdebug类型,选择aosp-bullhead-userdebug对应的数字即可。

c、执行编译

time make -j8

这里的工作线程数可以设置为物理内核数-逻辑内核数之间的数字,我的电脑物理内核为4,逻辑内核数为8,因此设置-j参数为8.

d、查看生成的镜像文件并刷入

进入源码目录下/out/target/product/bullhead,执行以下命令:

//进入手机bootloader
adb reboot bootloader

//开始刷机
fastboot flash boot boot.img

fastboot flash system system.img

fastboot flash cache cache.img

fastboot flash userdata userdata.img

fastboot flash recovery recovery.img

        参考链接:https://source.android.google.cn/source/running

        刷入过程中首先需要将手机解锁,否则无法刷入,同时打开手机调试,这里可能会遇到一些坑,如果是adb devices 命令udev问题可以参考踩坑7.1的问题e,如果是其他问题可参考官网链接https://source.android.google.cn/source/running或文末博客链接。

f、刷入vendor.img

        7.1.2版本的源码编译过程中,我们没有下载驱动二进制文件,因此在/out/target/product/bullhead目录中也不会有vendor.img,直接解压前面下载的镜像包,找到里面的image***.zip继续解压找到vendor.img,刷入vendor.img镜像。

g、手机重启

fastboot reboot

此时处于fastboot模式,执行该命令即可重启手机。手机重启后会报内部错误,由于用于自己调试,因此也没关系,需要解决的同学可以参考文末博客链接。

5)编译7.1踩坑

在我修复的过程中,有时候执行make命令会报同样的错,这个时候我通常执行make clobber命令清除之前编译生成的环境和文件,全部重新执行生效。

a、

[  1% 761/49025] Yacc: aidl <= system/tools/aidl/aidl_language_y.yy
FAILED: /bin/bash -c "prebuilts/misc/linux-x86/bison/bison -d  --defines=out/host/linux-x86/obj/STATIC_LIBRARIES/libaidl-common_intermediates/aidl_language_y.h -o out/host/linux-x86/obj/STATIC_LIBRARIES/libaidl-common_intermediates/aidl_language_y.cpp system/tools/aidl/aidl_language_y.yy"
/bin/bash: prebuilts/misc/linux-x86/bison/bison: No such file or directory
[  1% 761/49025] Lex: aidl <= system/tools/aidl/aidl_language_l.ll
FAILED: /bin/bash -c "prebuilts/misc/linux-x86/flex/flex-2.5.39 -oout/host/linux-x86/obj/STATIC_LIBRARIES/libaidl-common_intermediates/aidl_language_l.cpp system/tools/aidl/aidl_language_l.ll"
flex-2.5.39: loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed.
Aborted (core dumped)
[  1% 761/49025] target Java: core-all (out/targe...bj/JAVA_LIBRARIES/core-all_intermediates/classes)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
ninja: build stopped: subcommand failed.
build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed
make: *** [ninja_wrapper] Error 1

修复:

在build/envsetup.sh脚本中最后添加一句话

export LC_ALL=C

这里需要从build/envsetup.sh重新执行

参考链接:https://stackoverflow.com/questions/49955137/error-when-build-lineageos-make-ninja-wrapper-error-1

b、

ninja: Entering directory `.'
bison/bison: m4 subprocess failed: No such file or directory
[  0% 1/34696] Yacc: aidl <= system/tools/aidl/aidl_language_y.yy
FAILED: /bin/bash -c "prebuilts/misc/linux-x86/bison/bison -d  --defines=out/host/linux-x86/obj/STATIC_LIBRARIES/libaidl-common_intermediates/aidl_language_y.h -o out/host/linux-x86/obj/STATIC_LIBRARIES/libaidl-common_intermediates/aidl_language_y.cpp system/tools/aidl/aidl_language_y.yy"
/bin/bash: prebuilts/misc/linux-x86/bison/bison: No such file or directory
ninja: build stopped: subcommand failed.
build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed
make: *** [ninja_wrapper] Error 1

修复:

sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
c、

FAILED: /bin/bash -c "prebuilts/misc/linux-x86/flex/flex-2.5.39 -oout/host/linux-x86/obj/STATIC_LIBRARIES/libaidl-common_intermediates/aidl_language_l.cpp system/tools/aidl/aidl_language_l.ll"
flex-2.5.39: fatal internal error, exec of /usr/bin/m4 failed
[  1% 760/49025] target Java: core-all (out/targe...bj/JAVA_LIBRARIES/core-all_intermediates/classes)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
ninja: build stopped: subcommand failed.
build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed
make: *** [ninja_wrapper] Error 1

修复:

sudo apt-get install m4

d、

Communication error with Jack server (52). Try 'jack-diagnose'

修复:

out/host/linux-x86/bin/jack-admin kill-server 
out/host/linux-x86/bin/jack-admin start-server

这里需要注意的是,当执行kill-server时,查看jack服务器是否已经成功停止。

启动时,查看启动是否成功。如果启动成功,可继续编译。通常如果机器配置不够,再次执行会报问题e错误。

e、

Out of memory error (version 1.2-rc4 'Carnac' (298900 f95d7bdecfceb327f9d201a1348397ed8a843843 by [email protected])).
GC overhead limit exceeded.

修复:

这也是Jack服务器编译过程中会报的错,修改启动参数即可。

打开文件prebuilts/sdk/tools/jack-admin

JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"

搜索JACK_SERVER_COMMAND关键字符串,在-cp参数前添加-Xmx4096m即可。

此时再按照d问题解决方案,首先kill-server,然后重新启动start-server,并查看启动返回日志中的参数是否有我们修改后的-Xm4096m。我在修改配置文件过程中,重启后参数未生效,最后执行了make clobber命令然后重新编译生效。

f、No command 'adb' found, did you mean:

修复:

没有安装adb,执行以下命令安装即可:

sudo apt-get install android-tools-adb

如果下载了sdk,也可以直接配置adb环境变量,参考链接:https://blog.csdn.net/u012554768/article/details/48344881

g、adb devices : no permissions(udev)或是fastboot devices:no permissions(udev)

后面跟了一长串udev,还有一个http链接,且使用sudo命令也是同样的结果

修复:

这个主要是udev文件的规则配置文件问题

进入etc/udev/rules.d目录,使用ls-al命令查看目录下文件

这里我的机器上是没有任何文件,不过这个目录下的udev配置文件优先级最高

因此在这里创建51-android.rules

.将以下字符串复制到创建的.rules文件中,这是一个比较齐全的规则配置

SUBSYSTEM=="usb", ATTR{idVender}=="0502", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0b05", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="413c", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0489", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="04c5", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="091e", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="18d1", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="109b", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0bb4", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="12d1", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="24e3", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="2116", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0482", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="17ef", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="1004", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="22b8", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0409", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="2080", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0955", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="2257", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="10a9", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="1d4d", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0471", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="04da", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="05c6", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="1f53", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="04e8", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="04dd", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="054c", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0fce", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="2340", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0930", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="19d2", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="1782", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="0a5c", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVender}=="22da", MODE="0666"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"

再依次执行以下命令。

sudo chmod a+rx /etc/udev/rules.d/51-android.rules
sudo service udev restart

最后重新插拔usb生效

h、fastboot < waiting for device >

查看命令fastboot devices,这里没有udev错误,若有参考上一问题g解决方案。

若结果显示no permission,使用which命令查看fastboot路径

which fastboot

通常这里的路径为源码编译目录新生成的文件。此时有两种解决方案:

i)使用sudo apt-get install android-tools-fastboot 命令安装fastboot工具,然后使用sudo 执行fastboot devices即可。

ii)进入which查看fastboot路径目录,执行以下命令:

sudo chown root:root fastboot
sudo chmod +s fastboot

此时再运行fastboot device命令成功。

2、编译android-4.4_r1版本

        在同一台机器上,编译4.4版本。假设机器已经存在4.4_r1的源码,且编译过7.1.2_r18,此时的环境为openjdk8和make 4.1

1)要求

a、javajdk6

Ubuntu16.04编译Android源码7.1.2和4.4及踩坑_第3张图片

在编译7.1.2时查询了对应版本的jdk要求,4.4要求的环境为javajdk6,而此时我们的电脑中环境为openjdk8,因此需要修改java环境。

点进官网链接:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html,下载电脑对应的jdk版本,我使用的版本如图

Ubuntu16.04编译Android源码7.1.2和4.4及踩坑_第4张图片

下载完成后,选择一个目录创建文件夹java,进入目录,将下载好的jdk复制到该目录中,并执行命令bin文件,此时会生成对应的java文件夹,使用pwd查看当前文件夹路径,假如路径为xxx,java文件夹目录为jdk-6u45-linux-x64,执行以下命令设置环境变量:

export JAVA_HOME=/xxx/jdk-6u45-linux-x64;
export PATH=$JAVA_HOME/bin:$PATH;

然后使用java -version和javac -version命令查看当前环境是否已经变为java 1.6

需要注意的是,使用这种方法生成的环境变量只能在当前控制台生效,一旦关闭则失效。也可以将环境变量设置代码加入配置文件中,使其长期有效。我是因为之后编译8.0源码时需要使用openjdk1.8所以这么设置。

b、make 3.82

android4.4版本较低,不支持make 4.1版本,因此需要降低make 版本。这里我下载的版本是make3.82,具体操作步骤可参考博客:https://blog.csdn.net/qq_29224775/article/details/46595209

2)下载驱动

7.1源码编译过程中,我直接下载的镜像文件,因此编译4.4_r1源码过程中,选择下载驱动二进制文件来直接编译出vendor.img文件。

查看下载源码版本号链接:https://source.android.google.cn/setup/start/build-numbers

由以上链接可查,4.4_r1对应的细分版本为KRT16M,在驱动镜像链接中下载KRT16M对应的二进制文件,二进制链接:https://developers.google.cn/android/drivers

Ubuntu16.04编译Android源码7.1.2和4.4及踩坑_第5张图片

如图所示,下载Broadcom、LG、Qualcomm三个链接,复制到编译路径下,分别解压得到三个.sh文件,分别执行.sh文件,每一个.sh文件需要阅读一些东西,然后最后会让你确认是否接受,输入I ACCEPT即可。执行完三个.sh文件后,会看到源码目录下新增文件夹vendor,并且vendor下包括了下载文件的三个同名文件夹。

3)下载需要的库文件

由于在编译7.1.2的过程中,已经安装了部分库文件,编译4.4源码时,只需要再安装以下三个库文件即可。

sudo apt-get install bison
sudo apt-get install lib32z1
sudo apt-get flex

4)编译执行(具体可参考7.1.2编译步骤)

a、执行. build/envsetup.sh初始化编译环境

b、执行lunch命令选择编译目标版本(本次运行在nexus 5手机上,因此选择hammerhead版本)

c、执行time make -j8开始编译

5)刷机

编译成功后,进入out/target/product/hammerhead目录,依次执行以下命令即可。


//进入手机bootloader
adb reboot bootloader
 
//开始刷机
fastboot flash boot boot.img
 
fastboot flash system system.img
 
fastboot flash cache cache.img
 
fastboot flash userdata userdata.img
 
fastboot flash recovery recovery.img
//启动
fastboot reboot

5)编译4.4踩坑

a、

out/target/product/mx3/obj/GYP/shared_intermediates/content/jni/HashSet_jni.h:10:26: error: extra tokens at end of #ifndef directive [-Werror]
out/target/product/mx3/obj/GYP/shared_intermediates/content/jni/HashSet_jni.h:11:26: error: missing whitespace after the macro name [-Werror]
target thumb C++: content_content_common_gyp <= external/chromium_org/content/common/android/surface_texture_peer.cc
In file included from external/chromium_org/content/common/android/hash_set.cc:5:0:
out/target/product/mx3/obj/GYP/shared_intermediates/content/jni/HashSet_jni.h:24:20: error: expected initializer before '<' token
out/target/product/mx3/obj/GYP/shared_intermediates/content/jni/HashSet_jni.h:26:17: error: expected initializer before '<' token
out/target/product/mx3/obj/GYP/shared_intermediates/content/jni/HashSet_jni.h:29:22: error: expected '{' before '<' token
out/target/product/mx3/obj/GYP/shared_intermediates/content/jni/HashSet_jni.h:29:22: error: expected unqualified-id before '<' token
external/chromium_org/content/common/android/hash_set.cc:30:1: error: expected '}' at end of input
cc1plus: all warnings being treated as errors
make: *** [out/target/product/mx3/obj/STATIC_LIBRARIES/content_content_common_gyp_intermediates/content/common/android/hash_set.o] 错误 1
make: *** 正在等待未完成的任务....

修复:

这个错误是由于之前使用sudo alternatives --install /usr/bin/javajava /usrjava/jdk1.7.0_25/bin/java 500这种方式设置的java jdk和javac环境,但是没有设置javap,因此出错。

保险起见,使用前文所述直接设置环境变量的方式即可。如果出现此错误,修改环境变量后,需要执行make clobber并重新build编译执行。

b、error while loading shared libraries: libz.so.1: cannot open shared object file:No such file or directory

提示缺少库libz.so.1

修复:

首先安装apt-file管理器

sudo apt-get install apt-file

更新apt-file的缓存

apt-file update

搜索文件依赖

apt-file search libz.so.1

这里将会得到一个匹配libz.so.1字符串的包列表

ib32z1: /usr/lib32/libz.so.1

lib32z1: /usr/lib32/libz.so.1.2.8

libx32z1: /usr/libx32/libz.so.1

libx32z1: /usr/libx32/libz.so.1.2.8

搜索对应的库进行安装即可。

apt-get install lib32z1

c、之后还会遇到一些flex和bison文件找不到问题,安装对应的库文件即可。

sudo apt-get install bison
sudo apt-get install flex

以上就是本次编译过程中所遇问题及解决方案,如果有什么问题请指出。

参考链接:https://blog.csdn.net/fuchaosz/article/details/52473660

 

你可能感兴趣的:(源码编译)