天天看點

Ubuntu 18.04 編譯安卓系統源碼 及 adb連接配接手機遇到的問題詳解一、編譯前的準備工作二、開始編譯三、編譯錯誤的解決三、adb連接配接手機問題

轉載請注明出處:https://blog.csdn.net/turtlejj/article/details/89328174,謝謝~

    最近在自己的電腦上重裝了系統,把Ubuntu 16.04更新成了Ubuntu 18.04,不得不說,性能真的提升了好多(至少心理上感覺提升了╮(╯▽╰)╭)。

    但在更新之後,編譯安卓系統源碼的過程中卻遇到了各種各樣16.04上沒有遇到過的問題。是以在這裡把解決的過程記錄一下,既算是給自己做一個筆記,同時希望能讓其他遇到這些問題的朋友少走一些彎路。

    關于Ubuntu如何下載下傳Android源碼,網上有很多文章在寫,大家可以自行百度,我這裡就不多說了。我們隻關注編譯安卓源碼及adb連接配接手機兩方面的問題解決方案。

    如果有同學希望了解如何使用Android Studio導入安卓系統源碼,并進行單步調試的話,也可以參考我的另外兩篇文章。

  《使用Android Studio導入Android系統源碼》

  《使用Android Studio對Android系統源碼進行單步調試》

    好,廢話不多說,下面我們就開始吧~

一、編譯前的準備工作

    1. 運作以下指令安裝編譯所需的工具

sudo apt-get install git-core ccache automake lzop bison gperf build-essential zip curl zlib1g-dev zlib1g-dev:i386 g++-multilib python-networkx libxml2-utils bzip2 libbz2-dev \
    libbz2-1.0 libghc-bzlib-dev squashfs-tools pngcrush schedtool dpkg-dev liblz4-tool make optipng maven
           

    2. 安裝openjdk8

        順序執行以下兩條指令安裝openjdk8

sudo apt-get update

sudo apt-get install openjdk-8-jdk
           

        我的Ubuntu 18.04自帶的java版本是openjdk11,是以,在安裝完openjdk8以後,需要手動做以下切換:

sudo update-alternatives --config java
有 2 個候選項可用于替換 java (提供 /usr/bin/java)。

  選擇       路徑                                          優先級  狀态
------------------------------------------------------------
* 0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1101      自動模式
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1101      手動模式
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      手動模式

要維持目前值[*]請按<Enter鍵>,或者鍵入選擇的編号:2 (回車)
           

        javac的版本可能也需要做一下切換(我的電腦上不需要):

sudo update-alternatives --config javac
連結組 javac (提供 /usr/bin/javac)中隻有一個候選項:/usr/lib/jvm/java-8-openjdk-amd64/bin/javac
無需配置。
           

二、開始編譯

    關于編譯的方法,我們此處以Android 8.0為例。

    在編譯的過程中,需要執行以下三條指令:

    1. "source build/envsetup.sh" (source可以用 . 代替,即". build/envsetup.sh")

    2. "lunch",并選擇要編譯的項目(或在lunch指令後鍵入空格,并直接連接配接編号,即"lunch 編号")

    3. 全編 "make -j4" (這裡的 -j4 表示用4線程來編譯,可以不加)

        或子產品編譯 "make framework -j4"(其中framework為子產品名,後面我們詳細講解如何查找要編譯的子產品名)

    下面進行分布講解:

    1. 進入系統源碼的根目錄(即可以看到frameworks、kernel等等檔案夾的那一級目錄),執行". build/envsetup.sh"指令:

[email protected]:~/code/android$ . build/envsetup.sh 
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/qcom/common/vendorsetup.sh
including vendor/qcom/proprietary/common/vendorsetup.sh
including sdk/bash_completion/adb.bash
           

    2. 而後,繼續執行"lunch"指令,并選擇你想要編譯的那個項目,這裡我選了2,即編譯 aosp_arm64-eng:

[email protected]:~/code/android$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng

Which would you like? [aosp_arm-eng] 2

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.1.0
TARGET_PRODUCT=aosp
TARGET_BUILD_VARIANT=arm64-eng
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPM1
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo300
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.15.0-38-generic-x86_64-with-Ubuntu-18.04-bionic
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=OPM1.171019.026
OUT_DIR=out
AUX_OS_VARIANT_LIST=
============================================
           

    3. 前面兩步是對編譯環境進行配置,接下來執行"make -j4",并等待,這個過程可能會很漫長,取決于電腦的性能,幾十分鐘至幾小時不等,該過程中螢幕會輸出很多log,這裡隻貼出了最後一句:

[email protected]:~/code/android$ make -j4

......

#### build completed successfully (32:57 (mm:ss)) ####
           

    4. 那麼對于子產品編譯,我們可以用以下方法找到子產品名

      (1) 編譯産物作為依賴的子產品(一般編譯産物為.jar或.so檔案)

        比如,我修改了“frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaCall.java”這個檔案,那麼我們就可以從本級目錄,一級一級向上找,看在哪級目錄中可以找到Android.mk檔案。

        最終,我們發現,在"frameworks/opt/telephony/"目錄下,找到了Android.mk檔案。打開該檔案,我們可以搜尋“LOCAL_MODULE”這個變量的定義,其後面的“telephony-common”,即為該子產品的名字。

        是以,想編譯該子產品,要使用的指令即為"make telephony-common -j4"。

      (2) 編譯産物是應用程式的子產品(編譯産物為.apk檔案)

        比如,我修改了“packages/apps/Dialer/java/com/android/dialer/calling/ui/NewCallLogFragment.java”這個檔案,同理,我們從本級目錄向上找,可以發現,在"packages/apps/Dialer/"目錄下,存在Android.mk檔案。打開該檔案,我們可以搜尋“LOCAL_PACKAGE_NAME”這個變量的定義,其後面的“Dialer”,即為該子產品的名字。

        是以,想編譯該子產品,要使用的指令即為"make Dialer -j4"。

三、編譯錯誤的解決

    順利的話,在執行 "make -j4" 或 "make moduleName -j4" 後就可以等待編譯完成了。但Ubuntu 18.04在編譯的過程中會遇到各種各樣的編譯錯誤。下面我就将我所遇到的問題及解決方法共享給大家,以便大家在遇到以下問題時,能夠更友善的解決問題,而不用像我當時一樣再去搜尋并嘗試網上的各種方案及解決辦法。

    1. "loadlocale.c"檔案報錯

flex-2.5.39: loadlocale.c:130: _nl_intern_locale_data: Assertioncnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed.
           

        解決方法如下:

1. 打開.bashrc檔案
[email protected]:~/code/android$ gedit ~/.bashrc &

2. 在檔案最下面添加以下内容并儲存
export LC_ALL=C

3. 執行以下指令使修改生效
[email protected]:~/code/android$ source ~/.bashrc
           

    2. 如果編譯了"bootable/bootloader/edk2"目錄下的代碼,可能會遇到以下問題

......

g++  -I Pccts/h -I .. -I ../Include/Common -I ../Include/ -I ../Include/IndustryStandard -I ../Common/ -I .. -I . -I ../Include/X64/   -c -o VfrUtilityLib.o VfrUtilityLib.cpp
VfrUtilityLib.cpp: In member function ‘CHAR8* CVfrStringDB::GetVarStoreNameFormStringId(EFI_STRING_ID)’:
VfrUtilityLib.cpp:3288:26: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
   if (mStringFileName == '\0' ) {
                          ^~~~
<内置>: recipe for target 'VfrUtilityLib.o' failed
make[3]: *** [VfrUtilityLib.o] Error 1

......
           

        解決方法如下:

在"bootable/bootloader/edk2/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp"檔案中
搜尋"mStringFileName == '\0'",将其修改為"mStringFileName == NULL",如下:

@@@ -3284,7 -3284,7 +3284,7 @@@ CVfrStringDB::GetVarStoreNameFormString
    UINT8       BlockType;
    EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
    
--  if (mStringFileName == '\0' ) {
++  if (mStringFileName == NULL ) {
      return NULL;
    }
           

    3. 在編譯secimage時,可能會報以下錯誤

......

FAILED: gensecimage_target

......

install_base_dir=out/target/product/FJDEV061 > out/target/product/FJDEV061/secimage.log 2>&1 ) && (echo Completed secimage signed appsbl \\(logs in out/target/product/arm64-eng/secimage.log\\) )"

......

ninja: build stopped: subcommand failed.
11:38:32 ninja failed with: exit status 1
           

        該問題是由于Ubuntu 18.04自帶的openssl版本過高所導緻的,解決方法如下:

        這裡建議不要删除Ubuntu18.04自帶的openssl,而是更換低版本的openssl

        我參考了這篇文章中替換openssl版本的步驟,隻不過他裝的是1.1.0e,而我安裝的1.0.1f (Ubuntu 16.04自帶的是1.0.1f版本的openssl,可以確定其可以另編譯通過)。

        PS: (1) 關于openssl的1.0.1f版本,可以從這裡下載下傳到

               (2) 在上面提到的文章中,如果在運作其中的指令時,發生權限不足的問題,可以在指令前加上"sudo"

               (3) 在執行上面提到的文章中"sudo make install"的過程中,會報如下錯誤:

POD document had syntax errors at /usr/bin/pod2man line 71.
           

                    可以參考這篇文章裡的解決方法。

    4. 如果源代碼在"repo sync"後移動了位置,或是源代碼是從别的地方拷貝而來的,可能會報以下錯誤

makefile:68: recipe for target 'ABL_FV_IMG' failed
make: *** [ABL_FV_IMG] Error 127
make: Leaving directory '/home/xxxxxx/code/android/bootable/bootloader/edk2'
           

        問題分析:

            (1) 進入目錄 bootable/bootloader/edk2

            (2) 執行 "./edksetup.sh BashTools" 指令

                 觀察列印可以看到如下資訊:

WORKSPACE: 
/home/xxxxxx/code/android/bootable/bootloader/edk2

EDK_TOOLS_PATH: 
/home/xxxxxx/code/myDisk/android/bootable/bootloader/edk2/BaseTools

CONF_PATH: 
/home/xxxxxx/code/android/bootable/bootloader/edk2/Conf

           

        代碼在被移動後,EDK_TOOLS_PATH所儲存的目錄依舊是代碼下載下傳時的路徑,與WORKSPACE和CONF_PATH不一緻 (其中EDK_TOOLS_PATH中多了一級myDisk目錄)。

        此時執行"which build“ 指令,無任何列印。

        解決方法如下:

1) 進入 "bootable/bootloader/edk2/" 目錄下
2) 删除 "Conf/BuildEnv.sh" 檔案
3) 執行 "unset EDK_TOOLS_PATH" 指令
4) 執行 ". ./edksetup.sh BaseTools" 指令 (兩個點之間有空格)
5) 最後使用 which build 指令檢視,目錄正确
/home/xxxxxx/code/android/bootable/bootloader/edk2/BaseTools/BinWrappers/PosixLike/build
           

三、adb連接配接手機問題

    Ubuntu 18.04在連接配接手機時可能會遇到以下問題:

[email protected]:~$ adb devices
List of devices attached
1234abcd	device

[email protected]:~$ adb shell
error: insufficient permissions for device
           

    解決方法如下:

(1) 在/etc/udev/rules.d/目錄下建立一個叫做"51-android.rules"的檔案
    

(2) 執行 "sudo vim 51-android.rules" 并在檔案中添加以下内容
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"
儲存
PS: 這裡就預設大家會使用vim了,如果不會,也可以執行"sudo gedit 51-android.rules",并添加上述内容,用圖形化界面來解決問題

(3) 重新開機系統即可
           

    以上就是我在安裝了Ubuntu 18.04後,在編譯安卓源碼及adb連接配接手機進行調試過程中遇到的所有問題,希望能對大家有所幫助。

繼續閱讀