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
============================================
>$
3.配置好编译环境后,第一次编译的话需要先编译一下 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
>$
4.接下来要把我们刚才安装的交叉编译器的相关路径配置到 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)
5.接下来要修改 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 文件还原回去。
6.经过了上面的一系列准备,现在终于可以编译我们的主角了。
>$ 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 里面试试吧。