Docker環境下編譯android源碼|編譯可運行xposed


前言

因為我的電腦是Ubuntu18的版本,成功編譯xposed刷入手機之后無法啟動,檢查了所有的環境,沒有問題,發現可能是Ubuntu系統的兼容庫的問題,但是我不可能重新安裝系統吧,畢竟有點蠢,所以最好的方式就是在docker的Ubuntu容器中編譯,統一環境問題,也可以隔離環境平時
工作開發環境,下面開始操作

安裝配置docker

docker加速,采用對國人友好的鏡像地址

通過修改daemon配置文件/etc/docker/daemon.json來使用加速器,執行以下命令:

您可以配置 Docker 守護進程默認使用 Docker 官方鏡像加速。這樣您可以默認通過官方鏡像加速拉取鏡像,而無需在每次拉取時指定 registry.docker-cn.com

臨時生效:您可以在 Docker 守護進程啟動時傳入 --registry-mirror 參數:$ docker --registry-mirror=https://registry.docker-cn.com daemon

永久性保留更改,您可以修改 /etc/docker/daemon.json 文件並添加上 registry-mirrors 鍵值。

$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

拉取Ubuntu鏡像

由於我們編譯的是Android 6.0系統,推薦使用Ubuntu 14.04 x64系統去編譯,可以省去很多麻煩(比如:編譯器版本、構建套件版本、依賴庫版本等不兼容的問題),這也是我們使用docker的原因。

執行以下命令獲取鏡像:
$ sudo docker pull ubuntu:14.04 # docker默認都是64位系統

查詢本地鏡像

查詢本地已有的鏡像(注意 鏡像編號-IMAGE ID)

$ sudo docker images

misty@ubuntu:/etc/docker$ sudo docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               14.04               2c5e00d77a67        6 weeks ago         188MB
rethinkdb            latest              cc5badcd88e8        7 weeks ago         184MB
nginx                latest              53f3fd8007f7        7 weeks ago         109MB
openstf/stf          latest              f8f8d84596a0        7 weeks ago         784MB
sorccu/adb           latest              7123ee61b746        15 months ago       30.5MB
openstf/ambassador   latest              b1f0eb8297cf        3 years ago         6.46MB

查看本地的容器

misty@ubuntu:/etc/docker$ sudo docker ps -a

啟動鏡像

這里使用倉庫:標簽的方式 sudo docker run -it ubuntu:14.04 /bin/bash 這樣就可以得到一個偽終端

# 啟動鏡像,並獲取一個偽終端
# 注意:實際啟動的是容器,啟動鏡像時會自動創建新容器並啟動。
$ sudo docker run -it <REPOSITORY:TAG> /bin/bash   # 使用  倉庫名+標簽 啟動
$ sudo docker run -it <IMAGE ID> /bin/bash     # 使用 IMAGE ID 啟動
# 退出鏡像
>> $ exit   # 或使用快捷鍵 Ctrl + D

更換系統源

好像這里使用vi會有點問題,所以建議使用重定向的方式寫入,參考修改配置docker鏡像地址

>> # cp /etc/apt/sources.list /etc/apt/sources.list.bak
>> # echo "新的數據源" > /etc/apt/sources.list  // 使用新的數源替換
>> # apt-get update
>> # exit
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse

添加中文語言支持

添加中文語言支持
啟動指定容器后進入Ubuntu容器內部執行操作:

>> $ locale       #查詢當前語言
>> $ locale -a    #查詢支持的語言
# 若不支持UTF-8,則添加UTF-8語言支持
>> $ apt-get install language-pack-zh-hant language-pack-zh-hans # 中文
>> $ language-pack-en # 英文
# 修改 /etc/profile 文件,添加:
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN:zh
# 重新加載資源
>> $ source /etc/profile

更正時區時間

啟動指定容器后進入Ubuntu容器內部執行操作:

>> $ date  # 查看當前時間
>> $ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
>> $ echo 'Asia/Shanghai' >/etc/timezone

配置編譯專用鏡像

使用以下命令創建一個容器,並掛載 ~/share 目錄到容器中的 /home/share 目錄:
$ docker run -it -v ~/share:/home/share ubuntu:14.04 /bin/bash

說明:此處掛載一個目錄到容器中方便以后操作。

添加64位系統對32位的支持
1> 檢查是否已經支持

>> $ dpkg --print-architecture     # 若支持,輸出 amd64
>> $ dpkg --print-foreign-architectures    # 若支持,輸出 i386

手動開啟支持

>> $ sudo dpkg --add-architecture i386
>> $ sudo apt-get update

更新所有的軟件(沒必要)
>> $ sudo apt-get dist-upgrade

只安裝支持庫(原來需要安裝 ia32-libs,目前被以下三個庫取代)

$ sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0

添加編譯Android源碼需要的依賴
安裝編譯工具以及構建套件:

$ sudo apt-get install gcc-multilib g++-multilib build-essential

安裝必要的工具軟件

>> $ sudo apt-get install git-core gnupg bison flex gperf pngcrush bc zip curl lzop 
>> $ sudo apt-get install schedtool libxml2 libxml2-utils xsltproc squashfs-tools 

安裝其他需要的庫

>> $ sudo apt-get install libesd0-dev libsdl1.2-dev libwxgtk2.8-dev libswitch-perl 
>> $ sudo apt-get install libssl1.0.0 libssl-dev lib32readline-gplv2-dev libncurses5-dev

附:命令說明:

bc           命令行計算器
lzop             快速壓縮工具
flex             詞法分析器生成器
curl             基於URL的文件傳輸工具
gperf            哈希函數生成器
bison            語法分析器生成器
xsltproc         快速XSLT引擎,可以通過XSL文件把XML轉為HTML,XHTML,PDF...
schedtool        查詢或設置CPU狀態
squashfs-tools       linux內核壓縮工具,只讀式壓縮文件系統Image
pngcrush         批量壓縮PNG圖片
libxml2 libxml2-utils    操作XML文檔工具

提交容器保存為鏡像

配置好環境之后,保存此容器為一個鏡像:

$ sudo docker commit -m "xxx" <CONTAINER ID> <TEPO:TAG>

例如,使用$ docker ps -a指令查詢剛才的容器編號為1a61adfb1953,我們保存為一個本地鏡像,則可執行:

$ sudo docker commit -m "local_ubuntu14" 7e242d3a00ae local_ubuntu14:ubuntu_v1.0

使用$ docker images可以查看剛生成的鏡像:

misty@ubuntu:~/share$ sudo docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
local_ubuntu14       ubuntu_v1.0         97793b37c017        15 seconds ago      796MB
ubuntu               14.04               2c5e00d77a67        6 weeks ago         188MB
rethinkdb            latest              cc5badcd88e8        7 weeks ago         184MB
nginx                latest              53f3fd8007f7        7 weeks ago         109MB
openstf/stf          latest              f8f8d84596a0        7 weeks ago         784MB
sorccu/adb           latest              7123ee61b746        15 months ago       30.5MB
openstf/ambassador   latest              b1f0eb8297cf        3 years ago         6.46MB

根據提交的本地鏡像啟動容器,將宿主主機的Android的源碼目錄掛載到鏡像的aosp目錄
sudo docker run -it -v ~/bin:/home/aosp local_ubuntu14 /bin/bash

編譯前環境准備 - 環境列表

主機系統:ubuntu18.0.4LTS
主機 :java version "1.8.0_211"
docker Server Version: 18.09.5
Kernel Version: 4.18.0-25-generic
鏡像:ubuntu 14.04
容器內源碼版本:android-6.0.1_r11
容器內java版本:java version "1.7.0_201"

編譯前須知

  • docker相關的文件都在/var/lib/docker目錄下

開始編譯Android源碼和xposed

  1. 進入容器內部sudo docker exec -it [容器id] /bin/bash

2.. 配置perl環境參考Android源碼編譯文章配置

  1. 這里我是在Ubuntu里面編譯的XposedBridge,容器里面編譯xposed(注意修改配置文件和輸出目錄),這樣好處就是可以分離環境,Ubuntu里面配置Java8,容器里面配置Java7,其實主要是懶得再安裝配置一遍環境了,反正映射的都是同一個源碼目錄
    • 宿主主機XposedTools項目下./buile.pl -a java 開始編譯XposedBridge
  2. 開始編譯Xposed
    • 編譯前需要檢查XposedBridge放在輸出目錄的Java文件夾下,xposed項目在$aosp/frameworker/bash/cmds/xposed,xposed_art在$aosp/art下替換原來的源碼目錄下的art,並且切換到對應的的源碼版本分支;
    • 宿主主機XposedTools項目下./buile.pl -t arm64:23 開始編譯Xposed,

常見問題解決

USER問題(由於運行的docker沒有配置USER環境變量)

including ./tools/external/fat32lib/Android.mk ...
Install: out/host/linux-x86/framework/jack.jar
out/host/linux-x86/bin/jack-admin: line 27: USER: unbound variable
make: *** [out/host/linux-x86/framework/jack.jar] Error 1
make: *** Deleting file `out/host/linux-x86/framework/jack.jar'

#### make failed to build some targets (41 seconds) ####

解決辦法 :

  • export USER=$(whoami)
  • 或者ENV USER root //也可以是自己需要的名字

錯誤日志詳細

Last 10 lines from the log:
   target Unpacked: patchoat (out/target/product/generic_arm64/obj_arm/EXECUTABLES/patchoat_intermediates/PACKED/patchoat)
   target Symbolic: patchoat (out/target/product/generic_arm64/symbols/system/bin/patchoat)
   target Strip: patchoat (out/target/product/generic_arm64/obj_arm/EXECUTABLES/patchoat_intermediates/patchoat)
   Install: out/target/product/generic_arm64/system/bin/patchoat
   collect2: error: ld returned 1 exit status
   make: *** [out/target/product/generic_arm64/obj_arm/SHARED_LIBRARIES/libxposed_art_intermediates/LINKED/libxposed_art.so] Error 1
   make: *** Waiting for unfinished jobs....
   
   #### make failed to build some targets (04:32 (mm:ss)) ####

因為之前在Ubuntu18上編譯過的源碼直接拿過來出現了這個問題,在源碼目錄執行git status發現改了cang編輯器,算了,直接還原環境,重新拉取guthub上xposed_art的art6.0對應的分之,重新編譯果然沒有這個問題了,並且成功編譯通過

卡開機界面的解決

編譯成功之后刷入手機卡在開機界面,獲取日志

Failed to dlopen libart.so: dlopen failed: cannot locate symbol "__android_log_error_write" referenced by "/system/lib64/libart.so"...

在你報錯的庫libxxx.so的編譯腳本Android.mk請加上:LOCAL_LDFLAGS += -fuse-ld=bfd

# 直接追加的方式
ifeq (1,$(strip $(shell expr $(PLATFORM_SDK_VERSION) \>= 22)))
  LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
  LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
  LOCAL_LDFLAGS += -fuse-ld=bfd
endif

這樣改過之后,可能會報:unrecognized option ‘–icf=safe’

果然修改之后編譯出現如下錯誤

Last 10 lines from the log:
   target Symbolic: xposed (out/target/product/generic_arm64/symbols/system/bin/app_process64_xposed)
   target Strip (keep symbols): xposed (out/target/product/generic_arm64/obj/EXECUTABLES/xposed_intermediates/app_process64_xposed)
   /home/aosp/WORKING_DIRECTORY/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld.bfd: unrecognized option '--icf=safe'
   /home/aosp/WORKING_DIRECTORY/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld.bfd: use the --help option for usage information
   collect2: error: ld returned 1 exit status
   make: *** [out/target/product/generic_arm64/obj_arm/EXECUTABLES/xposed_intermediates/LINKED/app_process32_xposed] Error 1
   make: *** Waiting for unfinished jobs....

   #### make failed to build some targets (43 seconds) ####

解決辦法:
修改TARGET_linux-arm.mk中P134行對TARGET_GLOBAL_LDFLAGS的賦值,去掉–icf=safe
img

這個路徑采用如下命令查找出來的,源碼目錄下執行find ./ -iname TARGET_linux-arm.mk
路徑是$aosp/build/core/combo/TARGET_linux-arm.mk

以上兩種只是嘗試方法,實際上並不能解決問題,第二種更是直接導致編譯無法通過 ;通過重新配置統一的環境之后成功解決問題,刷入手機完美運行

將成功編譯好的容器提交為鏡像 導致根分區爆滿

sudo docker commit "commit images" [containerId] myaosp:v1.0 ;

執行到一半,將根目錄爆滿,呵呵,趕緊ctrl +c終止,可能跟我掛載了主機的aosp目錄並且在容器內部拉取了新的AOSP有關系,數據量太大,
解決辦法:
臨時解決:網上找了很多清理Linux的方法感覺可操作性都不強,畢竟涉及到清理文件還是謹慎一些的好,一招回到解放前可是不願意的,先重啟docker釋放一部分吧

啟動 systemctl start docker (這條命令即可)
守護進程重啟 sudo systemctl daemon-reload
重啟docker服務 systemctl restart docker
重啟docker服務 sudo service docker restart
關閉docker service docker stop
關閉docker systemctl stop docker

寫在最后

感謝這位博主提供的參考資料使用Docker編譯Android系統源碼

小確幸

每一絲靈感都值得被記錄,每一筆記錄都是成長,每一點成長都值得歡呼

博主個人站: www.imisty.cn
CSDN博客: https://blog.csdn.net/lookinthefog
博客園 :https://imist.cnblogs.com/

希望能夠認識一些熱愛技術的小伙伴,歡迎友鏈接喲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM