.
.
.
.
.
adb 的源码在 Android 源码树中,所以只能在 Linux 下编译,而在 Linux 下编译 windows 版本的应用就需要使用交叉编译器 MinGW 了。
环境:
Ubuntu 16.04
Android 4.3 r2
>$ uname -aLinux 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-w64Reading package lists... DoneBuilding dependency tree Reading state information... Donemingw-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.shincluding device/asus/flo/vendorsetup.shincluding device/asus/grouper/vendorsetup.shincluding device/asus/tilapia/vendorsetup.shincluding device/generic/armv7-a-neon/vendorsetup.shincluding device/generic/mips/vendorsetup.shincluding device/generic/x86/vendorsetup.shincluding device/lge/mako/vendorsetup.shincluding device/samsung/maguro/vendorsetup.shincluding device/samsung/manta/vendorsetup.shincluding device/samsung_slsi/arndale/vendorsetup.shincluding device/samsung/toroplus/vendorsetup.shincluding device/samsung/toro/vendorsetup.shincluding device/ti/panda/vendorsetup.shincluding sdk/bash_completion/adb.bash>$ lunchYou're building on LinuxLunch 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-userdebugWhich would you like? [aosp_arm-eng] 2============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.3TARGET_PRODUCT=aosp_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86TARGET_CPU_VARIANT=HOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-4.4.2-x86_64-with-Ubuntu-16.04-xenialHOST_BUILD_TYPE=releaseBUILD_ID=JSR78DOUT_DIR=out============================================>$
2.配置好编译环境后,第一次编译的话需要先编译一下 Linux 版的 adb,不然编译的时候会有一些库找不到,以后再编译就可以跳过这一步了。
>$ make -j8 adb============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.3TARGET_PRODUCT=aosp_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86TARGET_CPU_VARIANT=HOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-4.4.2-x86_64-with-Ubuntu-16.04-xenialHOST_BUILD_TYPE=releaseBUILD_ID=JSR78DOUT_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 Linuxifneq ($(findstring Linux,$(UNAME)),)ifneq ($(strip $(USE_MINGW)),)HOST_ACP_UNAVAILABLE := trueTOOLS_EXE_SUFFIX :=HOST_GLOBAL_CFLAGS += -DUSE_MINGWifneq ($(strip $(BUILD_HOST_64bit)),)TOOLS_PREFIX := /usr/bin/amd64-mingw32msvc-HOST_C_INCLUDES += /usr/lib/gcc/amd64-mingw32msvc/4.4.2/includeHOST_GLOBAL_LD_DIRS += -L/usr/amd64-mingw32msvc/libelse# TOOLS_PREFIX := /usr/bin/i586-mingw32msvc-TOOLS_PREFIX := /usr/bin/i686-w64-mingw32-# HOST_C_INCLUDES += /usr/lib/gcc/i586-mingw32msvc/3.4.4/includeHOST_C_INCLUDES += /usr/i686-w64-mingw32/include# HOST_GLOBAL_LD_DIRS += -L/usr/i586-mingw32msvc/libHOST_GLOBAL_LD_DIRS += -L/usr/i686-w64-mingw32/libendif # BUILD_HOST_64bitendif # USE_MINGWendif # LinuxHOST_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=RELPLATFORM_VERSION=4.3TARGET_PRODUCT=aosp_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86TARGET_CPU_VARIANT=HOST_ARCH=x86HOST_OS=windowsHOST_OS_EXTRA=Linux-4.4.2-x86_64-with-Ubuntu-16.04-xenialHOST_BUILD_TYPE=releaseBUILD_ID=JSR78DOUT_DIR=out============================================... 省略 n 行...host Prebuilt: AdbWinUsbApi (out/host/windows-x86/obj/EXECUTABLES/AdbWinUsbApi_intermediates/AdbWinUsbApi.dll)Install: out/host/windows-x86/bin/AdbWinUsbApi.dllhost Prebuilt: AdbWinApi (out/host/windows-x86/obj/EXECUTABLES/AdbWinApi_intermediates/AdbWinApi.dll)Install: out/host/windows-x86/bin/AdbWinApi.dllhost 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 位版本的办法,在网上找了好久,最后只能选择安装兼容库的方式了。