• Ubantu18.04环境下编译android源码(转)


    最近在看金泰延老师写的《Android 框架揭秘》一书,第一章就是下载并编译android源码,书中内容较为陈旧,所以不得不到网上收罗各种资料,最后总算是大功告成,现在总结如下。

    1、安装git和repo并配置
    安装git通过下面命令实现

    sudo apt-get install git
    1
    另外还需要配置好git的user.email和user.name,这个自己随便写就行了

    git config --global user.name "your name"
    git config --global user.email "XXX@XXX.com"
    1
    2
    然后由于我们是通过repo来拉取android源码的,git配置好后,还得安装配置repo

    git clone https://aosp.tuna.tsinghua.edu.cn/git-repo/
    chmod a+x git-repo/repo
    1
    2
    然后添加repo(路径目录如:~/git-repo/repo)到PATH环境变量

    export PATH=~/git-repo:$PATH
    1
    然后到打开~/git-repo/repo文件,将REPO_URL替换为清华镜像地址,以避免下载android源码时可能出现的无法连接到 gerrit.googlesource.com问题。

    REPO_URL = 'https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
    1
    2、下载andriod源码
    首先创建一个自己存放源码的目录,我是放在~/Android/source路径下的,然后cd到对应的路径下执行下面命令

    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest
    1
    然后执行如下命令可以查看可以下载的android源码分支,目前我看到的已经可以获取android-9.x的分支了。

    cd .repo/manifests.git/
    git branch -a
    1
    2
    这里同步android-8.1.0_r41分支并拉取对应分支源码

    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-8.1.0_r41
    repo sync
    1
    2
    这个过程时间较长,可能需要几个小时,期间该干嘛干嘛。

    3、Ubuntu 18.04编译环境配置
    首先得配置java8

    sudo apt-get install openjdk-8-jdk
    sudo apt-get install openjdk-8-jre
    1
    2
    注意这里是配置openjdk,不要弄错了,我之前是按照一篇教程配置了android studio环境,结果配置的jdk不是openjdk,执行java -version时有如下提示

    实际上在执行java -version有如下的openjdk提示时(版本号不一定相同),才算是jdk配置成功

    然后配置在ubantu 18.04中编译android源码需要的一些依赖,这些依赖包在ubantu 16.04中编译android源码时也是需要的

    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-dev
    sudo 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 m4
    sudo apt-get install lib32z-dev ccache
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    到这里编译环境配置就算是完成了。

    4、编译Android源码
    这里到了最关键也是最容易出问题的一步了,首先cd到应的源码目路,初始化编译环境

    . build/envsetup.sh
    1
    初始化编译环境后,引入了一些执行脚本,其中就包括马上要使用的lunch指令。通过lunch指令可以设置编译目标,所谓的编译目标就是生成的镜像要运行在什么样的设备上。这里我们设置的编译目标是aosp_arm64-eng,因此执行指令

    lunch aosp_arm64-eng
    1
    简单的说明下,aosp表示Android Open Source Project,arm64表示是使用arm64 cpu的设备,eng表示engineer版本,其直接开放了一些root等权限。当然直接使用lunch命令会列出所有可选的编译目标。

    最后,我们便可通过如下命令来开始编译andriod源码

    make -j8
    1
    这里的j8表示可以开启8个线程来参与编译源码,这里指定的线程数一般应该遵从cpu内核数的2倍这个规律,可以通过cat /proc/cpuinfo查看相关cpu信息。

    5、编译错误集锦
    如果以为第四小节的三步走战略就可以直接编译出可用的Android image来那就too young啦,实际上在编译过程中,我遇到很多故障,同时由于编译过程需要话费很多时间,所以整个编译花费了我大把时间,这个童鞋们一定要作好心理准备。下面是我在编译过程遇到的问题以及解决办法总结

    故障1:You are attemping to build with the incorrect version

    这个就是在编译高版本android源码时,可能出现的jdk版本问题,我之前是使用上面命令介绍的方式配置了openjdk却在java -version发现还是不是open jdk版本,究其原因竟是我在更之前配置android studio时在/etc/profile 中配置了另一个jdk版本导致该问题发生,后面在/etc/profile中删除对应配置就好了。

    故障2:Out of memory error

    这个问题是因为编译过程中JVM heap size太小而导致的,解决办法比较简单

    export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m"
    ~/Android/source/prebuilts/sdk/tools/jack-admin kill-server
    ~/Android/source/prebuilts/sdk/tools/jack-admin start-server
    1
    2
    3
    通过这个配置可以讲JVM heap size调整为4g,这个应该是够用的,这里我们看到了jack-admin工具,后面可能还会使用这个工具,所以这里直接建议配置jack-admin的环境变量

    export PATH=$PATH:~/Android/source/prebuilts/sdk/tools
    1
    之后就可以直接使用如下命令来启动jack-admin了

    jack-admin start-server
    1
    故障3:sizeof (_nl_value_type_LC_TIME[0]))’ ???

    这里图片我是从其它博客哪里拷过来的,但是的确碰到这个故障,通过下面配置去除本地化配置解决

    export LC_ALL=C
    1
    故障4:No Jack server running. Try ‘jack-admin start-server’

    这个错误碰到的还不止一次,看到这个提示我们都知道是jack-admin没有启动的原因,重启便可

    jack-admin kill-server
    jack-admin start-server
    1
    2
    比较奇怪的是,有时自己明明开启了jack-admin,但是在编译的过程中,jack-admin却挂掉了,这个得多注意。

    我在编译过程中主要是遇到了以上几个故障,实际上其它博客上还有一些其它故障可以参考的,也只能在遇到具体故障的时候再百度google了,总之是编译android源码需要一定的耐心。

    6、运行模拟器
    在完成编译后,我们可以直接通过emulator命令来运行模拟器

    emulator
    1
    运行模拟器实际上需要四个组件

    1、Linux Kernel
    2、system.img
    3、userdata.img
    4、ramdisk.img
    1
    2
    3
    4
    如果你在使用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命令后,正常的话,我们可以启动模拟器,我这里启动的模拟器信息如下

    这里可以看出启动的是我们编译时指定的aosp_arm64-eng模拟器,实际上emulator还有很多其它指令可以选择,这个可以通过它的help命令来查看

    emulator -help
    1
    7、单独编译模块及SDK
    除了通过make命令编译可以整个android源码外,Google也为我们提供了相应的命令来支持单独模块的编译。

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

    其中的mmm指令就可以用来编译指定模块,

    mmm packages/apps/StorageManager/
    1
    稍等一会之后,如果提示编译完成,此时便可在out/target/product/gereric_arm64/system/priv-app就可以找到编译的StorageManager.apk文件了。


    编译好指定模块后,如果我们想要将该模块对应的apk集成到系统镜像中,需要借助make snod指令重新打包系统镜像,这样我们新生成的system.img中就包含了刚才编译的Launcher2模块了,重启模拟器之后生效。

    我们在不断的修改某些模块,总不能每次编译完成后都要重新打包system.img,然后重启手机吧?有没有什么简单的方法呢?
    在编译完后,借助adb install命令直接将生成的apk文件安装到设备上即可,相比使用make snod,会节省很多时间。

    直接执行make是不包括make sdk的,如果要编译自己的sdk则十分简单,只需要执行如下命令便可

    . build/envsetup.sh
    lunch sdk-eng
    make sdk
    1
    2
    3
    如果编译成功,不出意外,在out/host/linux-x86/sdk就可以看到了。
    补充
    我们简单的来介绍out/target/product/generic_arm64/system目录下的常用目录:
    Android系统自带的apk文件都在out/target/product/generic_arm64/system/priv-app目录下
    一些可执行文件(比如C编译的执行),放在out/target/product/generic_arm64/system/bin目录下
    动态链接库放在out/target/product/generic_arm64/system/lib目录下
    硬件抽象层文件都放在out/targer/product/generic_arm64/system/lib/hw目录下

    这里需要注意的就是由于我们这里编译的是aosp_arm64-eng编译目标,所以这里的路径中是generic_arm64,如果是编译的其它目标路径可能不一样,比如当编译的是aosp_arm-eng时,则路径中就是generic。

    到这里Ubantu18.04环境下编译android源码基本介绍就算完成了。

    参考文献
    1、自己动手编译Android 8.0源码
    2、Ubuntu 18.04编译Android8.1 automotive
    3、自己动手编译最新Android源码及SDK(Ubuntu)
    4、Linux Out of memory error
    5、 Android 编译命令
    6、通过清华大学镜像下载Android源码并编译源码
    7、Ubuntu环境中的Android源代码下载
    8、ERROR: No Jack server running
    ————————————————
    版权声明:本文为CSDN博主「小草的胖冬瓜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Yoryky/java/article/details/81813717

  • 相关阅读:
    jsp九大内置对象和4个域对象
    小甜点
    response编码
    request请求编码处理
    防盗链模拟
    request浏览器判断
    request获取ip
    ServletConfig
    HttpServlet原理
    Servlet,GenericServlet,httpServlet区别
  • 原文地址:https://www.cnblogs.com/weizhxa/p/13084531.html
Copyright © 2020-2023  润新知