Android 系统源码——下载到编译
剛才有個朋友問我,博主發生什么事了,給我發了幾張截圖,我一看,哦,原來是有個大帥嗶看了文章,說是,博主,我能白嫖你的文章,我說年輕人,點個贊再走,他說不點,我說點一個,他說不點,我說點一個,他說不點,我說我這文章對你有用,他不服氣,說要先看看。我說可以,很快啊,看完后,就是一個復制,一個粘貼,一個網頁關閉,我大意了啊,沒有刪除文章。按傳統博客的有用為止,他說已經輸了啊。 后來他說他是亂點的,這可不是亂點的啊,訓練有素。我勸年輕人好好點贊,耗子尾汁,謝謝朋友們
一直想下載、編譯、調試一下Android源碼 ,加強對一些framework的理解,搞了好多次,終于可以正常調試了。這里進行一些總結和分享。
Android源碼到模擬器運行,主要有的四個步驟:
我使用的環境是Ubuntu16.04 、openJDK8、Android 8.0.0
硬件軟件要求
官方文檔:要求
硬件要求:
- 如果是 Android 2.3.x (Gingerbread) 及更高版本(包括 master 分支),需要使用 64 位環境。如果是較低的版本,則可以在 32 位系統中進行編譯。
- 如果要檢出代碼,至少需要 250GB 可用磁盤空間;如果要進行編譯,則還需要 150GB。如果要進行多次編譯,則需要更多空間。
- 如果在虛擬機中運行 Linux,則至少需要 16GB 的 RAM/交換空間。
我的電腦是雙系統,ubuntu 空間劃分不集中,分區空間不夠,導致編譯失敗。我在實踐過程中,發現不需要官方聲明的那么多空間,下載初始化包.repo 40G左右,檢出代碼(Android 8.0.0),又占用了40G左右,編譯用了60G左右。總共算下來160G的分區空間應該是夠用了。
一、 下載源碼
Android 源碼是非常龐大的,而且每個模塊都是用git來進行管理 ,整個Android源碼是由很多個git項目構成,Google對Android代碼的更新也是更新到相應模塊的git項目上。
那對于需要編譯Android的開發者來說,要分別clone 每個git項目而且還要放到固定的位置確實是件慘絕人寰的事,所以Google就開發了一個基于Python編寫的幫助開發者管理多個項目的工具,這個工具就叫repo,repo就是封裝了git命令的python腳本。
由于國內網絡的原因,我們使用國內的清華源下載源碼和repo工具
1.1、下載repo
下面的命令,是從清華源下載repo工具,這樣腳本中的路徑就是指向清華源的aosp
mkdir ~/bin # 在home下創建bin文件夾 PATH=~/bin:$PATH # 把bin文件夾加入環境變量的 curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo #下載repo腳本 chmod a+x ~/bin/repo #添加權限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
在mainfest文件夾中,執行git branch -a 就可以看到所有的分支
1.2、下載源碼
下載源碼有兩種方法:
1)Android 官方下載源代碼
官方文檔:下載源代碼
2)使用初始化包(建議)
初始化包每月都會進行更新,由于首次同步需要下載約 30GB 數據,如果上面的方法,過程中任何網絡故障都可能造成同步失敗,我第一次是使用官方的方法,失敗過一次。后來都是用這個方法。
下載 https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar,下載完成后記得根據 checksum.txt 的內容校驗一下。
由于所有代碼都是從隱藏的 .repo 目錄中 checkout 出來的,所以我們只保留了 .repo 目錄,下載后解壓 再 repo sync 一遍即可得到完整的目錄。
使用方法如下:
wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下載初始化包 tar xf aosp-latest.tar cd AOSP # 解壓得到的 AOSP 工程目錄 # 這時 ls 的話什么也看不到,因為只有一個隱藏的 .repo 目錄 repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-8.0.1_r1 # 可選命令,指定版本,如果未指定,則使用最新的版本 repo sync # 正常同步一遍即可得到完整目錄 # 或 repo sync -l 僅checkout代碼Android各版本列表:https://source.android.google.cn/setup/start/build-numbers.html#source-code-tags-and-builds
二、搭建編譯環境
官方文檔:搭建編譯環境
安裝openJDK8
sudo apt-get update sudo apt-get install openjdk-8-jdk安裝軟件包
官方文檔沒有介紹Ubuntu 16.04所需的軟件包。使用Ubuntu 16.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-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三、準備編譯
設置環境
使用 envsetup.sh 腳本初始化環境。請注意,將 source 替換成 .(一個點)可以省去一些字符,這種簡寫形式在文檔中更為常用。
source build/envsetup.sh或者
. build/envsetup.sh選擇目標
使用 lunch 選擇要編譯的目標。確切的配置可作為參數進行傳遞。例如,以下命令表示針對模擬器進行完整編譯,并且所有調試功能均處于啟用狀態。
lunch aosp_arm-eng直接運行 lunch (沒有參數),會列出所有支持的類型,輸入對應的序號來進行選擇。
所有編譯目標都采用 BUILD-BUILDTYPE 形式,其中 BUILD 是表示特定功能組合的代號。BUILDTYPE 是以下類型之一:
| user | 權限受限;適用于生產環境 |
| userdebug | 與“user”類似,但具有 root 權限和可調試性;是進行調試時的首選編譯類型 |
| eng | 具有額外調試工具的開發配置 |
源碼編譯
您可以使用 make 編譯任何代碼。GNU make 可以借助 -jN 參數處理并行任務,通常使用的任務數 N 介于編譯時所用計算機上硬件線程數的 1-2 倍之間。例如,在一臺雙核 E5520 計算機(2 個 CPU,每個 CPU 4 個內核,每個內核 2 個線程)上,要實現最快的編譯速度,可以使用介于 make -j16 到 make -j32 之間的命令。
make -j4如果編譯完一個版本后想重新編譯一個,可以使用 make clobber清除之前編譯生成的文件。我們編譯產生的文件都在 out文件夾下。
啟動模擬器
編譯成功后,輸入emulator可啟動模擬器
四、如何查看源碼的版本
方法一:
每次執行完lunch后下次進入基本就忘記上次編譯的參數設置,可以使用printconfig命令顯示當前的設置
方法二:
1、 從代碼中查看當前版本,找到如下文件
build\make\core\version_defaults.mk搜索關鍵字 PLATFORM_VERSION
# This is the canonical definition of the platform version, # which is the version that we reveal to the end user. # Update this value when the platform version changes (rather # than overriding it somewhere else). Can be an arbitrary string.# When you add a new PLATFORM_VERSION which will result in a new # PLATFORM_SDK_VERSION please ensure you add a corresponding isAtLeast* # method in the following java file: # frameworks/support/compat/gingerbread/android/support/v4/os/BuildCompat.java# When you change PLATFORM_VERSION for a given PLATFORM_SDK_VERSION # please add that PLATFORM_VERSION to the following text file: # cts/tests/tests/os/assets/platform_versions.txt PLATFORM_VERSION.OPR1 := 8.0.0五、錯誤及解決方法
由于在Ubuntu上開發,很多常用軟件都沒有,所以后來又在mac上編譯源碼,遇到不少問題,下面來分享一下
錯誤 1、Could not find a supported mac sdk: [“10.10” “10.11” “10.12” “10.13” “10.14”]
兩種解決方法:
具體操作,下載地址,可以參考這里
錯誤 2、在mac 10.15.4 上編譯Android 8.0.0_r1 ,出現bad cpu type in executable
這篇文章 也遇到這個錯誤,但是報錯細節、Android版本號 和我的不一樣,所以我暫時沒有去嘗試
在蘋果官網看到 關于bad cpu type in executable 回復 的,
想了一下,既然Mac 10.15 支持64位,不支持32位,那就用新版Android吧,免得Android 8.0.0_r1 上越改問題越多
錯誤3、在mac 10.15.4上編譯Android10.0.0_r1,
Android10.0.0_r1 是支持64位的,但是在編譯過程中一定會遇到這個錯誤
FAILED: build out/target/product/generic_x86_64/obj/ETC/sepolicy_tests_intermediates/sepolicy_tests Outputs: out/target/product/generic_x86_64/obj/ETC/sepolicy_tests_intermediates/sepolicy_tests Error: exited with code: 1 Command: /bin/bash -c "(out/host/darwin-x86/bin/sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86_64/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86_64/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -p out/target/product/generic_x86_64/obj/ETC/sepolicy_intermediates/sepolicy ) && (touch out/target/product/generic_x86_64/obj/ETC/sepolicy_tests_intermediates/sepolicy_tests )" Output: /bin/bash: line 1: 28159 Segmentation fault: 11 ( out/host/darwin-x86/bin/sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86_64/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86_64/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -p out/target/product/generic_x86_64/obj/ETC/sepolicy_intermediates/sepolicy )這個錯誤是與mac 10.15 兼容問題,可通過這個臨時解決
make SELINUX_IGNORE_NEVERALLOWS=true還有個官方方案,打上下面的patch:(我是使用這個方法解決的)
1f944107a3341ab593c93bbdf09e22436cc0e3d3
官方就是修改 system/sepolicy/tests/Android.bp 去掉stl: “libc++_static”,
下面這個是Catalina MacOS SDK 10.15的patch:
89dad60ed5ec30b0f732b612d454151abdb4e449
出自這篇文章:AOSP SELinux error
錯誤4、Mac 下編譯 關于 文件格式
注意在mac 上編譯,磁盤格式最好使用 Mac OS擴展(區分大小寫,日志式),我在APFS 上解壓aosp-laster.rar、同步代碼、編譯,完整操作了兩次都不行。遇到同樣的錯誤,也沒再網上找到答案。也有可能是其它原因,按照官方的最好
六、使用Android studio 查看源碼
Android Studio 導入 Android 源碼
IntelliJ IDEA導入Android源碼
注意:執行命令的時候,需要在bash 環境下,不能再zsh 環境下
請點贊、收藏,感謝大家的支持,有任何疑問可在評論區回復
參考:
官方文檔:準備編譯
自己動手編譯Android源碼(超詳細)
Android 源碼下載 到 編譯全過程
從源碼中查看當前android版本
android aosp編譯的一些輔助命令
總結
以上是生活随笔為你收集整理的Android 系统源码——下载到编译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【代码笔记】多线程游戏开发——伏魔记:第
- 下一篇: Android 中文 API (29)