.
.
.
.
.
adb 的源碼在 Android 源碼樹中,所以只能在 Linux 下編譯,而在 Linux 下編譯 windows 版本的應用就需要使用交叉編譯器 MinGW 了。
環境:
Ubuntu 16.04
Android 4.3 r2
>$ uname -a Linux yuhuashi-Linux 4.4.2 #2 SMP Sun Feb 21 21:38:05 CST 2016 x86_64 x86_64 x86_64 GNU/Linux >$
編譯步驟:
1.首先安裝交叉編譯器。由於 LZ 已經安裝過了,所以這里會提示已是最新版本。網上有的教程說要安裝 mingw32,但是 LZ 從源中搜索不到相關的包,所以 LZ 安裝的是 mingw-w64 這個包。
>$ sudo apt-get install mingw-w64 Reading package lists... Done Building dependency tree Reading state information... Done mingw-w64 is already the newest version (4.0.4-2). 0 upgraded, 0 newly installed, 0 to remove and 45 not upgraded. >$
2.接下來先不用管交叉編譯器,我們進入 Android 的源碼樹目錄,配置 adb 編譯的目標平台。LZ 選的是 aosp_x86-eng,當然也可以使用 choosecombo 命令來替代 lunch 命令進行詳細配置。
>$ cd android/ >$ source build/envsetup.sh including device/asus/deb/vendorsetup.sh including device/asus/flo/vendorsetup.sh including device/asus/grouper/vendorsetup.sh including device/asus/tilapia/vendorsetup.sh including device/generic/armv7-a-neon/vendorsetup.sh including device/generic/mips/vendorsetup.sh including device/generic/x86/vendorsetup.sh including device/lge/mako/vendorsetup.sh including device/samsung/maguro/vendorsetup.sh including device/samsung/manta/vendorsetup.sh including device/samsung_slsi/arndale/vendorsetup.sh including device/samsung/toroplus/vendorsetup.sh including device/samsung/toro/vendorsetup.sh including device/ti/panda/vendorsetup.sh including sdk/bash_completion/adb.bash >$ lunch You're building on Linux Lunch menu... pick a combo: 1. aosp_arm-eng 2. aosp_x86-eng 3. aosp_mips-eng 4. vbox_x86-eng 5. aosp_deb-userdebug 6. aosp_flo-userdebug 7. full_grouper-userdebug 8. full_tilapia-userdebug 9. mini_armv7a_neon-userdebug 10. mini_mips-userdebug 11. mini_x86-userdebug 12. full_mako-userdebug 13. full_maguro-userdebug 14. full_manta-userdebug 15. full_arndale-userdebug 16. full_toroplus-userdebug 17. full_toro-userdebug 18. full_panda-userdebug Which would you like? [aosp_arm-eng] 2 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=4.3 TARGET_PRODUCT=aosp_x86 TARGET_BUILD_VARIANT=eng TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=x86 TARGET_ARCH_VARIANT=x86 TARGET_CPU_VARIANT= HOST_ARCH=x86 HOST_OS=linux HOST_OS_EXTRA=Linux-4.4.2-x86_64-with-Ubuntu-16.04-xenial HOST_BUILD_TYPE=release BUILD_ID=JSR78D OUT_DIR=out ============================================ >$
2.配置好編譯環境后,第一次編譯的話需要先編譯一下 Linux 版的 adb,不然編譯的時候會有一些庫找不到,以后再編譯就可以跳過這一步了。
>$ make -j8 adb ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=4.3 TARGET_PRODUCT=aosp_x86 TARGET_BUILD_VARIANT=eng TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=x86 TARGET_ARCH_VARIANT=x86 TARGET_CPU_VARIANT= HOST_ARCH=x86 HOST_OS=linux HOST_OS_EXTRA=Linux-4.4.2-x86_64-with-Ubuntu-16.04-xenial HOST_BUILD_TYPE=release BUILD_ID=JSR78D OUT_DIR=out ============================================ # ...省略 n 行... target Executable: adb (out/target/product/generic_x86/obj/EXECUTABLES/adb_intermediates/LINKED/adb) target Symbolic: adb (out/target/product/generic_x86/symbols/system/bin/adb) target Strip: adb (out/target/product/generic_x86/obj/EXECUTABLES/adb_intermediates/adb) Install: out/target/product/generic_x86/system/bin/adb >$
3.接下來要把我們剛才安裝的交叉編譯器的相關路徑配置到 Android 源碼樹的 build/core/combo/HOST_windows-x86.mk 文件中。
綠色被注釋掉的是文件中原有的內容,紅色的是 LZ 修改后的內容。
你們修改后的內容不一定要與 LZ 的完全一樣,要自己去看看實際的路徑是什么,再根據實際情況進行配置。
這段腳本計較簡單,我們為什么只修改 else 里的內容呢,因為一會兒編譯 windows 版本的 adb 的時候,我們要給 make 傳一個叫做 USE_MINGW 的參數。
# Settings to use MinGW has a cross-compiler under Linux ifneq ($(findstring Linux,$(UNAME)),) ifneq ($(strip $(USE_MINGW)),) HOST_ACP_UNAVAILABLE := true TOOLS_EXE_SUFFIX := HOST_GLOBAL_CFLAGS += -DUSE_MINGW ifneq ($(strip $(BUILD_HOST_64bit)),) TOOLS_PREFIX := /usr/bin/amd64-mingw32msvc- HOST_C_INCLUDES += /usr/lib/gcc/amd64-mingw32msvc/4.4.2/include HOST_GLOBAL_LD_DIRS += -L/usr/amd64-mingw32msvc/lib else # TOOLS_PREFIX := /usr/bin/i586-mingw32msvc- TOOLS_PREFIX := /usr/bin/i686-w64-mingw32- # HOST_C_INCLUDES += /usr/lib/gcc/i586-mingw32msvc/3.4.4/include HOST_C_INCLUDES += /usr/i686-w64-mingw32/include # HOST_GLOBAL_LD_DIRS += -L/usr/i586-mingw32msvc/lib HOST_GLOBAL_LD_DIRS += -L/usr/i686-w64-mingw32/lib endif # BUILD_HOST_64bit endif # USE_MINGW endif # Linux HOST_CC := $(TOOLS_PREFIX)gcc$(TOOLS_EXE_SUFFIX) # HOST_CXX := $(TOOLS_PREFIX)g++$(TOOLS_EXE_SUFFIX) HOST_CXX := $(TOOLS_PREFIX)g++ -static-libgcc$(TOOLS_EXE_SUFFIX) HOST_AR := $(TOOLS_PREFIX)ar$(TOOLS_EXE_SUFFIX)
4.接下來要修改 MinGW 里面的一個頭文件:/usr/share/mingw-w64/include/wincrypt.h,這個路徑也要看你自己的 MinGW 路徑,不一定與 LZ 的相同。
把里面 OCSP_REQUEST 宏所在位置附近的一大段宏都注釋掉,LZ 猜測可能把所有的宏都注釋掉也可以,不過 LZ 沒有試過。
LZ 在這里被坑了一天的時間,由於 MinGW 里面的一些宏與 Android 源碼樹下的 external/openssl 里面的一些宏名稱重復了,導致編譯的時候出現各種奇怪的現象。
這一步 LZ 就不貼出代碼了,別忘了編譯完 windows 版本的 adb 之后,把 /usr/share/mingw-w64/include/wincrypt.h 文件還原回去。
5.經過了上面的一系列准備,現在終於可以編譯我們的主角了。
>$ make -j8 USE_MINGW=y adb ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=4.3 TARGET_PRODUCT=aosp_x86 TARGET_BUILD_VARIANT=eng TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=x86 TARGET_ARCH_VARIANT=x86 TARGET_CPU_VARIANT= HOST_ARCH=x86 HOST_OS=windows HOST_OS_EXTRA=Linux-4.4.2-x86_64-with-Ubuntu-16.04-xenial HOST_BUILD_TYPE=release BUILD_ID=JSR78D OUT_DIR=out ============================================ ... 省略 n 行... host Prebuilt: AdbWinUsbApi (out/host/windows-x86/obj/EXECUTABLES/AdbWinUsbApi_intermediates/AdbWinUsbApi.dll) Install: out/host/windows-x86/bin/AdbWinUsbApi.dll host Prebuilt: AdbWinApi (out/host/windows-x86/obj/EXECUTABLES/AdbWinApi_intermediates/AdbWinApi.dll) Install: out/host/windows-x86/bin/AdbWinApi.dll host Executable: adb (out/host/windows-x86/obj/EXECUTABLES/adb_intermediates/adb.exe) Install: out/host/windows-x86/bin/adb.exe >$
如果看到最終生成了 3 個文件:AdbWinUsbApi.dll、AdbWinApi.dll 和 adb.exe,那么恭喜你編譯成功了,快把這三個文件放到 windows 里面試試吧。
------------------------------ 20161205 附注 ------------------------------
若 Linux 版無法在 64 位系統中使用,需要安裝 32 位兼容庫,以 Ubuntu 為例:
>$ sudo apt-get install libncurses5:i386 libstdc++6:i386 zlib1g:i386
由於沒有找到編譯 64 位版本的辦法,在網上找了好久,最后只能選擇安裝兼容庫的方式了。
