完整指引如何編譯AOSP (Build Android P),整合GMS及刷機 (Pixel 2)

前言

本文是說明一個Android Framework研發人員,如何利用Google的Pixel手機進行系統程式的客製化。本文的工作如下:

  • 解鎖Pixel2
  • 取得AOSP原始碼
  • 編譯AOSP (Build AOSP)
  • 將Pixel 2刷機自己編譯的ROM
  • 修改Framework後,重編譯,再刷機,完成!
  • 安裝GMS
本文針對Pixel 2進行刷機,理論上Pixel2 XL/Pixel 3/Pixel 3 XL應該都適用。

前置工作


解鎖Pixel 2,讓手機允許刷機

首先必須知道,官方釋出的手機的開機載入程序(Bootloader)會阻止你刷入任何客製ROM。所以所謂「解鎖」就是解鎖Bootloader,讓它允許你可以進行刷機動作。
其次要注意是在刷機後,所有使用者資料(User data)都會消失。所以刷機前要先備份重要資料。

網路上有很多教解鎖Pixel手機的文章,都可以參考,實際上在Android官網已經有教導你如何解鎖Pixel 2的Bootloader,我個人是比較習慣直接看官網來做:

https://source.android.com/setup/build/running

如果你懶得看一大堆英文,根據官網的描述,以下的命令就可以讓你解鎖Bootloader。

adb reboot bootloader
#等重開機後會看到一個躺著且肚子打開的機器人
fastboot flashing unlock 
#進入清除資料階段,螢幕顯示Erasing data...

所以解鎖其實只有兩個命令:

1. adb reboot bootloader重開機以進入“開機載入程序”,畫面如下
adb reboot bootloader後的實機畫面



2. fastboot flashing unlock進行Bootloader解鎖。
Pixel2手機解鎖畫面
fastboot flashing unlock後的畫面,按音量上鍵後按電源鍵,確認解鎖
手機進入解鎖畫面後,按音量鍵選擇「UNLOCK THE BOOTLOADER」,進行解鎖。
之後手機進行資料清除後重開。

很多文章寫了一大堆步驟,主要是為了要取得Root權限。但在本文中這是不必要的,因為等你刷入了自己Build出來的ROM,自然可以取得Root權限。

刷入官網的ROM

先刷一次官網的ROM,目的有兩個:1. 確定解鎖後的Pixel2可以刷機。 2. 刷特定版本的Pixel2 官方ROM,以確保Kernel和之後我們要編譯的系統映像(System Image)是在同一版本。

官網的ROM的位置在:
https://developers.google.com/android/images#walleye

Walleye就是Pixel2的代號,這很重要,因為會牽涉到之後取得AOSP原始碼時所要選擇的原始碼分枝 (Branch)。在本文中,下載的版本為:


PQ2A.190205.002

選擇PQ2A.190205.002

選擇PQ2A.190205.002做為官方ROM刷機

記得你要刷機的版本,之後一致的版本可以讓你少走一些冤枉路。之後你想要取得更新的版本當然也沒問題,只要確保 官方ROMAOSP Branch原始碼版本Binary Driver 的版本一致就可以。


下載後解開tgz,一樣進入Bootloader模式 (adb reboot bootloader),執行fastboot.sh (或在Windows下執行fastboot.bat),則Script開始執行刷機的動作。

adb reboot bootloader
./flash-all.sh 
< waiting for any device >
target reported max download size of 536870912 bytes
Sending 'bootloader_a' (38680 KB)...
OKAY [  1.421s]
Writing 'bootloader_a'...
(bootloader) Updating: partition:0   @00002000 sz=0000B000
(bootloader) Updating: partition:1   @0000D000 sz=0000B000
(bootloader) Updating: partition:2   @00018000 sz=0000B000
(bootloader) Updating: partition:3   @00023000 sz=0000B000
...
Sending 'userdata' (4497 KB)...
OKAY [  0.163s]
Writing 'userdata'...
OKAY [  0.000s]
Rebooting...

Finished. Total time: 166.501s

順利的話,完成刷機動作,系統重新開機。此時你進入 [系統]->[關於手機] 的畫面

刷機後在系統》關於手機中,確認Build Number與下載ROM一致


你可以看到版本號碼(Build number)為PQ2A.190205.002,這和我們從Android官網取得的官方ROM一致。

取得AOSP原始碼


確認AOSP Branch/Tag

AOSP有很多Branch,那一個Branch才是Android P Pixel2必須先找到。

首先根據Android官網指令,把編譯環境設定好,確保你可以編譯Android AOSP:
https://source.android.com/setup/build/initializing

之後要選定AOSP版本及分枝,在以下官方連結中,列出了所有的分枝
https://source.android.com/setup/start/build-numbers.html#source-code-tags-and-builds

記得我們是選定PQ2A.190205.002這個版本來實作,所以可以找到對映的分枝:android-9.0.0_r32
PQ2A.190205.002對映的Tag為android-9.0.0_r32


下載AOSP Android原始碼 (及私有函式庫)


所以找到的AOSP是android-9.0.0_r32,現在我們就根據官網來下載這個原始碼:
https://source.android.com/setup/build/downloading

順著官網執行設定工作後,最重要就是下載AOSP原始碼了。主要的不同也只有在這一行

repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r32 #-b是branch取得android-9.0.0_r32這個分枝
repo sync #開始下載

下載完成(視網路狀況,資料量約90Gbytes)後,接下來下載Pixel2 Driver。
為什麼還有Driver? 因為AOSP是完成Open Source,但實機上有些原始碼是私有Proprietary的,受版權保護及有安全疑慮而不放開原始碼。例如和無線通訊/圖形加速晶片相關,這些是以Binary形態存在,所以必須也要下載,我們才能完整編譯出一個可以刷入實機的ROM。(否則只能編譯Emulator而已)。

Pixel2 (Walleye) 的Binary Driver在: https://developers.google.com/android/drivers#walleye

同樣我們必須保持版本一致。找到PQ2A.190205.002這個版本
PQ2A.190205.002有兩個Binary包,都要下載

我們看到兩個Binary,一個是Vendor Image,另一個是Driver。這兩個都是必要的,都下載並且存放至你剛剛下載AOSP的目錄下。以下命令是使用wget取回Pixel2 DriverBinary。

wget https://dl.google.com/dl/android/aosp/google_devices-walleye-pq2a.190205.002-a5b43ffa.tgz
--2019-04-10 17:07:08--  https://dl.google.com/dl/android/aosp/google_devices-walleye-pq2a.190205.002-a5b43ffa.tgz
Resolving dl.google.com (dl.google.com)... 172.217.24.14, 2404:6800:4008:801::200e
Connecting to dl.google.com (dl.google.com)|172.217.24.14|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 153576317 (146M) [application/x-gtar]
Saving to: ‘google_devices-walleye-pq2a.190205.002-a5b43ffa.tgz’

100%[==============================================================================================================================================>] 153,576,317 31.6MB/s   in 4.6s   

2019-04-10 17:07:12 (31.9 MB/s) - ‘google_devices-walleye-pq2a.190205.002-a5b43ffa.tgz’ saved [153576317/153576317]

wget https://dl.google.com/dl/android/aosp/qcom-walleye-pq2a.190205.002-d5cc3341.tgz
--2019-04-10 17:07:19--  https://dl.google.com/dl/android/aosp/qcom-walleye-pq2a.190205.002-d5cc3341.tgz
Resolving dl.google.com (dl.google.com)... 172.217.24.14, 2404:6800:4008:801::200e
Connecting to dl.google.com (dl.google.com)|172.217.24.14|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1196171 (1.1M) [application/x-gtar]
Saving to: ‘qcom-walleye-pq2a.190205.002-d5cc3341.tgz’

100%[==============================================================================================================================================>] 1,196,171   --.-K/s   in 0.04s   

2019-04-10 17:07:20 (26.3 MB/s) - ‘qcom-walleye-pq2a.190205.002-d5cc3341.tgz’ saved [1196171/1196171]
  

2019-04-10 11:30:02 (25.1 MB/s) - ‘qcom-walleye-pq1a.181205.002-c199ac9d.tgz’ saved [1196259/1196259]

接下來直接用tar解開,會解出兩個script:
tar xvfz google_devices-walleye-pq2a.190205.002-a5b43ffa.tgz 
extract-google_devices-walleye.sh
tar xvfz qcom-walleye-pq2a.190205.002-d5cc3341.tgz 
extract-qcom-walleye.sh


然後執行兩個script,解出Binary:

./extract-google_devices-walleye.sh
./extract-qcom-walleye.sh

它會要你看完版權宣告後,輸入 I ACCEPT,才真正解開來,解出的Binary都存在vendor目錄下。


可以看到google_devices目錄中有個vendor.img,這是OEM廠商私有的映像檔,主要包含和硬體相關的程式及函式庫,以及硬體啟動時所需的設定檔。
qcom表示Qualcomm,看起來這些Binary主要是和IMS (IP Multimedia Subsystem)相關的函式庫以及框架層所需的JAR檔。

完全不懂Binary Drivers也無所謂,知道這些檔案是必須的就行了。
至此所需的檔案和原始碼已完全下載完畢。再來接下來就可以開始編譯AOSP了。

進行編譯AOSP


首先建立環境變數,就是告訴AOSP要如何編譯這整包原始碼,你可以把它編輯成模擬器Emulator也可以編譯成Pixel2的ROM。
我們設定為編譯Pixel2 ROM

sh ./build/envsetup.sh 
including device/generic/car/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
...
including sdk/bash_completion/adb.bash
lunch aosp_walleye-userdebug 
============================================
PLATFORM_VERSION_CODENAME=REL
...
OUT_DIR=out
============================================

編譯環境的建立就兩個命令 sh ./build/envsetup.sh建立通用環境變數,而lunch aosp_walleye-userdebug則是指定之後下make編譯時,編譯出符合Pixel2的映像檔(image)。

那如果要編譯Pixel 3呢?你可以到官網:https://source.android.com/setup/build/running#selecting-device-build

Google硬體對映Build configuration (編譯組態)
所以如果你的硬體是Pixel 3,則命令就是lunch aosp_blueline-userdebug。

之後下make就開始編譯了。
所以完整下編譯的命令為:
#建立通用環境
sh ./build/envsetup.sh 
#指定編譯組態
lunch aosp_walleye-userdebug 
#開始編譯,時間視PC速度而定
make -j16

一切順利後完成編譯,輸出目錄在環境變數$ANDROID_PRODUCT_OUT所指定的位置。你可以直接下cd $ANDROID_PRODUCT_OUT到輸入目錄。

再來檢視你編譯出來的結果:
cd $ANDROID_PRODUCT_OUT
ls -al *.img
-rw-rw-r-- 1 user user   33554432  4月 10 14:26 boot.img
-rw-rw-r-- 1 user user    8388608  4月 10 12:04 dtbo.img
-rw-rw-r-- 1 user user    1569523  4月 10 14:26 ramdisk.img
-rw-rw-r-- 1 user user    8720084  4月 10 14:26 ramdisk-recovery.img
-rw-rw-r-- 1 user user 1175118152  4月 10 14:29 system.img
-rw-rw-r-- 1 user user   84722016  4月 10 14:28 system_other.img
-rw-rw-r-- 1 user user    4952764  4月 10 14:20 userdata.img
-rw-rw-r-- 1 user user       4096  4月 10 14:29 vbmeta.img
-rw-r--r-- 1 user user  370045136  4月 10 12:04 vendor.img

可以比較一下你編譯出來的映像檔(*.img)是否相同。 完成編譯後,接下來就是刷機了。

用自己編譯的ROM來刷機

最後就是刷機,刷機就簡單了,先下adb reboot bootloader重新將手機進入Bootloader,再執行fastboot flashall

#進入Bootloader Mode
adb reboot bootloader
#進行刷機
fastboot flashall -w

刷機完成後會完全清除使用者資料,如果想要保留資料,則之後刷機不加-w參數。
刷機後開機,如果一切順利,你會發現,怎麼和官方ROM的畫面完全不同??官方的ROM是包含GMS,而自己編譯的ROM則沒有GMS,所以自己編譯的ROM看起來就很像開發Android APP的模擬器。
自行編譯Build Pixel2 AOSP ROM並刷機,沒有GMS
Pixel2刷自製ROM後,沒有GMS的主畫面

修改AOSP

實作耳機圖示


我們來做簡單的一個小功能(其實只是小改一下),功能為「插入耳機時,在狀態列Status Bar上顯示耳機圖示小Icon」,像這樣:

Android P顯示耳機圖示
耳機插入小圖示

你可以看到在插入耳機後,在Wi-Fi信號左邊一個耳機圖示。這是在耳機插入時才會顯示。在Google的原生AOSP設計中,預設是不顯示這個Icon。

在Android 8.0(Android Oreo)時,你可以下拉Status Bar後,長按設定鍵(齒輸小Icon),進入System Tuner UI,然後手動將耳機Headset圖示開啟。但Android 9.0 (Android Pie)之後,System Tuner的功能預設關掉了,所以我們的工作根本不用開發什麼,就是把它找回來就可以了!!

首先開啟:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
把第三行的Code從false改為true:

public class SettingsButton extends AlphaOptimizedImageButton {

    private static final boolean TUNER_ENABLE_AVAILABLE = true; //原始AOSP的值為false

    private static final long LONG_PRESS_LENGTH = 1000;
    private static final long ACCEL_LENGTH = 750;;

再重新下make命令再Build一次,然後重刷一次機。完成後下拉Status Bar,長按右下角的設定鍵會發現小齒輪一直轉動(如下圖指標所示),放開後進入Settings畫面。

開啟Android P System UI Tunner設定
開啟System UI Tuner,客製圖示顯示設定

進入Settings之後,進入System->Advanced->System UI Tunner->Status bar後,開啟Headset。
再找個耳機插入USB Type-C孔,就會看到耳機圖示出現了。

把GSM整合進你的Codebase!


畢竟純AOSP對於一般使用者是不用夠,無法做為日常使用,所以必須有GMS的套件,才算完整。接下來我們就把GSM整合回來!

GMS就是Google Map/Chrome/Youtube等等Google軟體,是Google私有的套件。只有和Google有合約的手機廠商可以預載GMS。所以雖然我們編譯AOSP是Android官方釋出,並不會包含GMS預載。這造成了一個很矛盾的問題,第三方ROM,例如Lineage OS,很受歡迎,對於推廣Google服務很有幫助,但它並不是有合約的手機廠商,所以拿不到GMS? 可是他又有也有可以刷GMS,難道沒侵權啊?!

理論上Google為了要同時保持開放性及服務可靠性,所以算是放水。它讓解鎖後的手機可對Android系統安裝GMS。而重點在「解鎖後」,所以Google不會告你侵權,只要不是預載在市售ROM就可以。於是Open GAPP的計劃就產生了,它讓第三方ROM可以使用GMS及其服務。Open Gapps官網:https://opengapps.org/

一般像是LineageOS這種第三方ROM會教你如何刷GSM進去 (通常是TWRP加上OpenGapps)。不過要整進AOSP有點特別,AOSP預設「沒有」GMS。整個AOSP Codebase並沒有和GMS整合的相關編輯設定。如果直接用TWRP來刷GMS並不是不行,但在Android系統權限和WebView設定等等方面,都會出問題。

OpenGapps也有教你如何把GMS整合進整個原始碼
 https://github.com/opengapps/aosp_build (但這說明有些不完整,有幾個Issue我要Submit給作者,請他修正了)

1. 安裝lunzip

首先安裝lunzip,這是Open Gapps在整合AOSP所需的命令工具。

sudo apt-get install lunzip

2. 修改manifest.xml

將Open Gapps的專案下載至你的AOSP Codebase。(這些Open Gapps專案很大,約20G,因為他是一個專案支援所有Android版本)

在.repo/manifest.xml的最後,把以下的Open Gapps專案Projects加入

<remote name="opengapps" fetch="https://github.com/opengapps/"  />
  <remote name="nezor" fetch="https://gitlab.nezorfla.me/opengapps/"  />

  <project path="vendor/opengapps/build" name="aosp_build" revision="master" remote="opengapps" />

  <project path="vendor/opengapps/sources/all" name="all" clone-depth="1" revision="master" remote="nezor" />

  <!-- arm64 depends on arm -->
  <project path="vendor/opengapps/sources/arm" name="arm" clone-depth="1" revision="master" remote="nezor" />
  <project path="vendor/opengapps/sources/arm64" name="arm64" clone-depth="1" revision="master" remote="nezor" />

  <project path="vendor/opengapps/sources/x86" name="x86" clone-depth="1" revision="master" remote="nezor" />
  <project path="vendor/opengapps/sources/x86_64" name="x86_64" clone-depth="1" revision="master" remote="nezor" />


接下來在.repo/mainfests/目前下,執行git commit -a -m "add open gapps",將修改commit進git。

3. 修改aosp_walleye.mk及device.mk

修改檔案:device/google/muskie/aosp_walleye.mk,將:
PRODUCT_RESTRICT_VENDOR_FILES := owner
改為
PRODUCT_RESTRICT_VENDOR_FILES := false

否則在編輯時會發生
error: Error: Product "aosp_walleye" cannot have overlay in vendor tree:...

再修改檔案:device/google/wahoo/device.mk,在檔案最後加入

GAPPS_VARIANT := stock
$(call inherit-product, vendor/opengapps/build/opengapps-packages.mk)

編譯AOSP時,就會呼叫vendor/opengapps/build/opengapps-packages.mk將Open Gapps編入system.img中

4. 修改原始碼

修改frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6001,8 +6001,8 @@ public class WindowManagerService extends IWindowManager.Stub
 
     @Override
     public void setShelfHeight(boolean visible, int shelfHeight) {
-        mAmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
-                "setShelfHeight()");
+        //mAmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
+        //        "setShelfHeight()");
         synchronized (mWindowMap) {
             getDefaultDisplayContentLocked().getPinnedStackController().setAdjustedForShelf(visible,
                     shelfHeight)

把setShelfHeight所需要的權限移除,否則刷入ROM之後Pixel Launcher會因權限不足發生錯誤。

5. 重編譯及刷機

再下make之後,重新刷機,結果如下:

自行媥譯AOSP Android P並刷機進Pixel2
刷入最後自行客製ROM,AOSP Android P + Open Gapps


如此完成了一次,從取得AOSP,編譯,刷機,修改,加入GMS,再編譯,再刷機的完整工作!

最後一哩


有了完整的AOSP + GMS,其實還缺內核原始碼的部份。因為Pixel的內核在AOSP中採取預編內核,在device/google/wahoo-kernel下可以看到預編的內核(prebuilt kernel)。如果是內核開發者必須更動其原始碼,最必須也將內核核心整合進來。詳細方法可以參考:如何編譯AOSP內核Kernel並整合進AOSP (Android P/Pixel 2)

留言

  1. 跟下面的整合内核Kernel一起,这个帖子给我示范了一个完整的AOSP 编译与刷机过程。是个好教程。
    另外请教有个问题。我现在基于Android Preview(即Android Q的预览版)在写一个东西,但我已经忘记这个Q的源码是如何得到的,更不知道它对应于Walleye的Driver Binary在哪里,所以我现在遇到了一个十分棘手的问题:无法成功将我所编写的软件基于Q来刷Pixel 2的真机。请问,有办法吗?

    回覆刪除
    回覆
    1. 取得AOSP Q Preview源碼是容易的,如果沒錯,我看了一下,應該是用 "repo init -u https://android.googlesource.com/platform/manifest -b android-q-preview-2.5" 來取得。
      但Device Binary就麻煩了,官方還沒釋出,所以只能先刷官方的Android Q Preview之後(https://developer.android.com/preview/download#flash),比較一下AOSP System和官方釋出Binary Image刷機完之後的檔案差別。
      把官方Image多出來的檔案抓出來到vendor/qcom/walleye/proprietary下,官方的Binary Image解開後,原本就有vendor.img了,這部份就容易整合了。
      這只是理論,有空我會試一下,但這就很花時間,所以對我而言,玩AOSP在工作上沒這麼急迫,所以不如等官方發佈出來再來玩。

      刪除
  2. Hi, Thanks for your great job!!

    现在我有一个疑问的地方. 执行下面这个命令的时候是 cd $ANDROID_PRODUCT_OUT 在这个目录里面吗?
    fastboot flashall -w
    $ANDROID_PRODUCT_OUT 这个目录里面有很多文件. 当然也有你说的*.img 文件. 执行这个命令的时候会出问题吗?

    回覆刪除
  3. 執行fastboot flashall時,fastboot自然根據$ANDROID_PRODUCT_OUT的環境變數找到該目錄下的image來刷入。所以不一定要先cd $ANDROID_PRODUCT_OUT

    回覆刪除
  4. 写的太详细了,感谢分享~~

    回覆刪除
  5. 非常感谢您细致的说明。将整个过程用在Pixel3上会遇到两个问题:1. 编译内核刷机之后,没有驱动,需要额外添加驱动。这个问题已经解决。2. 最后一步整合GMS的时候,编译没有问题,但是刷机之后停在开机界面。 请问如果是pixel 3 对一GMS这一步的具体修改有哪些呢?我只对应修改了device/google/wahoo/device.mk ——》device/google/crosshatch/device.mk

    回覆刪除
    回覆
    1. 停在開機界面通常是System Server反覆Exception。所以可能要先看看adb shell能不能進入,並且用adb shell logcat -b crash來看問題出在哪裏?如果adb shell不能用,主要是因為還沒和主機認證,這時用lunch aosp_walleye-eng來Build engineering build,就可以直接進入adb,再找出問題。
      有可能是Pixel3有新的Permission Req,必須有Log確認!

      刪除
  6. 刷机完启动,会进入bootloader界面,最下面一行提示:
    ERROT: LoadImageAndAuth Failed: Load Error
    这个错误有遇到吗?

    回覆刪除
    回覆
    1. 有過,就是刷壞了。有可能刷到一半usb連結不好時斷線沒刷完整,也可能沒有全刷所有Images, 例如先刷官方image,後來只刷自己build的system image之類的戕況造成的。

      刪除
    2. 我的情况找到原因了:是因为我驱动(google和qcom)版本和AOSP不一致导致的。

      刪除
  7. android 10 一样吗?有没有教程,thanks

    回覆刪除
  8. 刷玩pixel3后, 开机一直死在fastboot mode界面, 是怎么回事?

    回覆刪除
    回覆
    1. 把opengapps 在mainfest中添加的内容删除,然后重新repo sync -c,再编再刷

      刪除
  9. Hello, 謝謝你的教學分享,我在刷opengapps到Pixel 2 Android 10時一直出現

    16% 560/3440] Check prebuilt ELF binary: vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so
    FAILED: out/target/product/walleye/obj/SHARED_LIBRARIES/libsketchology_native_intermediates/check_elf_files.timestamp
    /bin/bash -c "(rm -f out/target/product/walleye/obj/SHARED_LIBRARIES/libsketchology_native_intermediates/check_elf_files.timestamp ) && (build/make/tools/check_elf_file.py --skip-bad-elf-magic --skip-unknown-elf-machine --soname libsketchology_native.so --shared-lib out/target/product/walleye/obj/SHARED_LIBRARIES/libc++_intermediates/libc++.so --shared-lib out/target/product/walleye/obj/SHARED_LIBRARIES/libc_intermediates/libc.so --shared-lib out/target/product/walleye/obj/SHARED_LIBRARIES/libm_intermediates/libm.so --shared-lib out/target/product/walleye/obj/SHARED_LIBRARIES/libdl_intermediates/libdl.so --llvm-readobj=prebuilts/clang/host/darwin-x86/clang-r353983c1/bin/llvm-readobj vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so ) && (touch out/target/product/walleye/obj/SHARED_LIBRARIES/libsketchology_native_intermediates/check_elf_files.timestamp )"
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: error: DT_NEEDED "libEGL.so" is not specified in shared_libs.
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: error: DT_NEEDED "libGLESv2.so" is not specified in shared_libs.
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: error: DT_NEEDED "libandroid.so" is not specified in shared_libs.
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: error: DT_NEEDED "libjnigraphics.so" is not specified in shared_libs.
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: error: DT_NEEDED "liblog.so" is not specified in shared_libs.
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: error: DT_NEEDED "libGLESv1_CM.so" is not specified in shared_libs.
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note:
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note: Fix suggestions:
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note: Android.bp: shared_libs: ["libEGL", "libGLESv1_CM", "libGLESv2", "libandroid", "libc", "libdl", "libjnigraphics", "liblog", "libm"],
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note: Android.mk: LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM libGLESv2 libandroid libc libdl libjnigraphics liblog libm
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note:
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note: If the fix above doesn't work, bypass this check with:
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note: Android.bp: check_elf_files: false,
    vendor/opengapps/sources/arm64/lib64/29/libsketchology_native.so: note: Android.mk: LOCAL_CHECK_ELF_FILES := false

    但找不到應該要修改哪隻Android.bp or Android.mk,不知道你有沒有遇過這個問題? 謝謝

    回覆刪除
  10. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 你好,你寫的太好了,我有一些問題還想請教你,能否給個聯系方式或給我發一封郵件,我的邮箱是duanming6699@gmail.com謝謝

      刪除

張貼留言

這個網誌中的熱門文章

架設Gerrit Server : 架設本地AOSP Gerrit Server完整指引 PART1

將AOSP加入Gerrit Server : 架設本地AOSP Gerrit Server完整指引 PART2