简介这是一份adb工具源码包面向嵌入式Linux开发、Android系统调试以及需要深度定制adb工具的工程师。源码包可直接下载后交叉编译适配arm、arm64、x86等不同架构平台作者已在arm机器上实测编译通过生成可正常使用的adb工具解决了从零搭建编译环境、收集适配代码的困扰。压缩包采用tgz格式整体约41.9MB体积适中内部包含完整源码和README编译说明按提示操作即可完成交叉编译适合有一定交叉编译经验的中高级开发者快速上手。与从AOSP中手工抽取adb源码相比这份打包好的源码更省时省力便于二次开发与排错也是理解adb内部原理的典型样例可帮助分析调试工具的运行机制。目前已有180人学习下载对于需要深入理解adb实现、移植到特定设备或定制调试功能的场景这份资源能提供直接可用的起点。1. 直接编译 ADB 源码包ARM 机器上的工具自救干嵌入式和物联网的开发者总有一刻会被同一个问题卡住——设备上跑的是 ARM Linux手里的 adb 工具却是 x86 架构编译的跑不起来。台式机上adb devices一切正常拿到板子上直接报 Exec format error。这个 adb 工具源码包解决的就是这个问题在目标架构机器上直接编译或者交叉编译得到本地原生的 adb 二进制可用于系统调试、文件推送和串口维护。整个编译过程由 README 驱动不需要复杂配置我实测在 ARM 的板子上正常编译通过。这个场景通常出现在智能硬件调试、安卓车机方案开发或者嵌入式 Linux 的软件维护阶段。当系统的 rootfs 里没有现成 adb而且你不能轻易刷入一个 deb 包时自己编译一个静态或动态依赖合适的 adb 就成了正经路子。适合拿来即用或定制后集成进固件不只是拿到源码看两眼。2. ADB 源码包的结构与本地编译准备为什么编译会有这么多依赖2.1 源码包目录的构成和编译入口下载源码包后解压出来的目录结构比较清晰核心的模块分布在system/core/adb与system/core/libcutils等位置。这个源码包不是谷歌官方一次性导出的完整 AOSP 源码而是精简过的可独立编译的 ADB 源码工程README 文件里已经标记了编译入口。在 ARM 机器上编译时需要先确认当前环境已安装必需的依赖包括gcc、make、zlib、openssl-devel与ncurses-devel。ADB 源码在编译过程中会用到 OpenSSL 相关的头文件因为它要支持 adb 的传输加密和鉴权。如果系统缺少某个依赖编译会在中途停下并提示找不到某个头文件或库。一个典型的执行流程如下# 查看源码包根目录结构与编译说明 tar -xzf arm_adb-master_default.tgz cd arm_adb-master_default ls -la cat README # 确认编译工具链 gcc --version make --version这套命令没有任何特殊之处但要注意执行顺序先检查 README再确认编译器版本。部分 ARM 板子的系统中 gcc 是 4.9 老版本ADB 源码要求至少 6.0 以上的编译器否则 C 新标准特性无法通过编译。2.2 为什么要在 ARM 机器上原生编译而不是直接交叉编译很多开发者习惯在 x86 机器上直接用交叉编译工具链拉一套arm-linux-gnueabihf-gcc来编译 ADB。这个思路本身没问题但在实际项目里并不建议第一部分就直接走交叉编译。答复很简单交叉编译会引入独立于源码本身的问题——工具链安装位置、sysroot 路径、库版本不匹配等。在 ARM 机器上用./configure make流程直接编虽说不一定能得到静态二进制但至少把源码包本身的构建兼容性验证了一遍。源码包很小几十秒就能编译完成直接在板上跑./adb version不依赖任何宿主机环境调试链路最短。之后再根据实际发布形态和运行环境决定要不要交叉编译。如果目标板后续要量产固件里的 adb 是需要随 rootfs 刷进去的这时交叉编译省时省力。但如果只是临时调试十几块板子直接放到 ARM 机器上编一次就够了最大程度避免折腾工具链。2.3 README 里隐藏的编译开关README 中除了基础的编译命令以外其实标记了几个关键的配置开关。这些开关决定了编译出的 adb 是否带 adbd、是否支持网络 adb、以及是否同时生成 host 和 target 两个版本的二进制。很多新手会忽略 README 末尾的编译参数说明直接执行第一行make命令结果编出来的 adb 只有客户端能力没有服务端 adbd。如果你的目标是在开发调试时让板子作为一个 adb 设备连接到电脑那么必须确认编译产物中包含adbd。# 编译并指定目标版本为 adbd make adbd重新看 README 里的关键信息它有几行明确指出编译 adbd 需要开启特定的宏定义。宏定义在源码包根目录的Android.mk或makefile里以-DADB_HOST0方式控制。当ADB_HOST1时产出的是运行在电脑上的 adb 客户端ADB_HOST0时产出的是板端 adbd 服务端。如果只看了一遍 README 就去make很有可能生产出 host 版在板子上怎么执行都是提示找不到设备原因就是服务端根本没编进去。# 在编译前查看默认开关 grep -rn ADB_HOST makefile Android.mk上面这一步应该放在编译之前不要编译之后才去排查。实际排查中遇到过这样的问题源码包默认值就是 host 版本作者在板子上跑通的应该也是 host 版配合外部 adbd 使用而调试场景中常需要设备上的 adbd。3. 在 ARM 板卡上执行编译从 configure 到 make 的全过程3.1 环境准备用 configure 脚本探测依赖进入源码根目录后第一步是确认是否有configure或自动生成 makefile 的脚本。ADB 源码包中常见的构建系统有两种一种是直接使用源码树根目录的自定义 Makefile另一种是基于 autotools 的 configure 脚本。对第二种情况执行./configure --prefix/opt/adb-build--prefix参数指定安装路径。在 ARM 板卡上编译时这个参数并不影响编译过程但会影响到后续make install的安装位置。调试阶段一般不需要指定这个参数直接把产物留在源码树内即可。configure 执行完成后它会在终端输出当前系统已安装的库信息。此时重点关注 openssl 和 zlib 是否被正确找到如果输出中出现checking for EVP_aes_128_cbc... no这类提示说明 openssl 开发包有问题需要先安装libssl-dev。# 在 Debian/Ubuntu 系的 ARM 系统上安装编译依赖 apt-get install -y build-essential libssl-dev zlib1g-dev这是在普通 ARM Linux 板卡上的常规做法但某些板厂的 BSP 里没有 apt 或 yum 可用。可执行包管理器缺失时需要把 libssl-dev 的 .deb 或 .rpm 下载到本地手动解压并把头文件路径与库路径手动指定给 configure./configure CPPFLAGS-I/usr/local/include LDFLAGS-L/usr/local/lib3.2 编译执行与产物路径确认环境配置完成之后进入编译环节。不推荐直接用make -j$(nproc)因为 ADB 源码有限编译过程中的错误不适合被海量日志冲掉。make -j2若在树莓派或 RK3399 这类低配板卡上编译两个并行任务已经足够。观察编译输出的末尾如果出现adb、adbd两个可执行文件说明编译已经完成。写代码的过程如下# 确认编译产物位置 find . -name adb -type f find . -name adbd -type f # ADB 版本探测 ./adb versionadb version的输出至少应包含Android Debug Bridge version 1.0.x的信息。如果输出的是-sh: ./adb: not found则需要检查执行权限运行chmod x adb即可。3.3 本地依赖的动态库问题在 ARM 板卡上编译出来的 adb 默认是动态链接直接拷贝到同架构的其他板子时可能会出现动态库缺失的问题。解决方式是编译时加静态链接选项但官方 Makefile 不一定提供现成的开关需要手动修改# 若 LDFLAGS 不生效可直接编辑 makefile # 在 LDFLAGS 行追加 -static-libstdc -static-libgcc make LDFLAGS-static-libstdc -static-libgcc -j2这里只静态链接了 C 和 GCC 运行库没有静态链接 libc编译出的 adb 仍然依赖 glibc 版本。如果目标板上的 libc 版本与编译环境差异太大是无法运行。完全静态化的方法是改用-static参数但这可能遇到 glibc 对 NSS 模块的兼容问题编译能过执行时才报错。4. 交叉编译 adb 到 arm64 与 x86 平台工具链选择与编写4.1 交叉编译工具链的选择标准如果需要把 adb 编到 arm64 平台而手里的开发机是 x86_64 的那就得用交叉编译工具链。工具链版本选择直接影响生成二进制的系统兼容性通常选择目标平台上 glibc 版本接近的工具链。比如目标板为 aarch64 且系统 glibc 为 2.28那么工具链就不宜使用 glibc 2.35 的版本否则二进制拷到板子上会报version GLIBC_2.33 not found。使用aarch64-linux-gnu-gcc或arm-linux-gnueabihf-gcc编译 ADB 的操作步骤没有标准答案一般先尝试./configure --hostaarch64-linux-gnu --prefix/opt/adb-arm64 make -j4configure 里指定--host参数后必须验证 C 编译器是否真的切换为交叉工具链。有些源码包的 configure 逻辑不严谨不管你指定什么--host它内部仍然是使用系统自带 gcc。强制指定编译器才是可信做法make CCaarch64-linux-gnu-gcc CXXaarch64-linux-gnu-g \ ARaarch64-linux-gnu-ar \ STRIPaarch64-linux-gnu-strip -j44.2 树外构建千万不要污染原目录交叉编译时强烈建议新建一个独立的构建目录保留源码树不被污染。这也是后续排查问题时能快速切换编译链的前提条件不然编译一次失败后整个目录就乱了。mkdir build-arm64 cd build-arm64 ../configure --hostaarch64-linux-gnu \ CFLAGS-O2 -fPIC \ LDFLAGS-L/path/to/target/libs \ --prefix/opt/adb-arm64 make -j4-O2优化级别可以保证调试信息与运行性能的相对平衡。这里的-fPIC对生成 adb 静态二进制不是必需品但如果后续要把它链接进别的服务保留位置无关是稳妥选择。4.3 x86 目标平台的特殊处理适配 x86 平台时如果编译宿主机本身就是 x86_64直接使用-m32编译 32 位版本会遇到缺少 32 位库的问题。这时需要先安装gcc-multilib否则无法找到bits/libc-header-start.hapt-get install -y gcc-multilib g-multilib使用-m32编译代码如下make CFLAGS-m32 CXXFLAGS-m32 LDFLAGS-m32这样编译出来的二进制可以直接在 32 位 x86 环境的嵌入式工控机上运行。不过按我的经验目前纯 32 位 x86 平台的新项目已经很少了基本都是 armhf、arm64 或 amd64如果确认目标环境是 64 位就无需添加-m32编译参数。5. 编译与使用避坑三个最常见的麻烦与排查方案5.1 遇到 cannot find -lssl 错误现象执行make约 20 秒后报错提示cannot find -lssl或openssl/ssl.h: No such file or directory。原因编译机器上没有安装 openssl 开发包或者已安装的是 openssl 3.x 而源码里写的是 1.1 的接口。部分源码包只适配了 1.0/1.1 的头文件路径。解决安装与系统匹配的 libssl-dev 包。若没有包管理器可以用源码编译的 openssl 指定路径make CFLAGS-I/opt/openssl/include \ LDFLAGS-L/opt/openssl/lib -Wl,-rpath,/opt/openssl/lib使用-Wl,-rpath是必要的这样可执行文件运行时能找到正确版本的 libssl.so否则编译通过后一运行还是找不到版本符号。5.2 在板子上运行 adb 提示adb: error while loading shared libraries现象编出来的 adb 与 adbd 拷贝到另一块同架构板子直接执行提示缺少libcrypto.so.1.1。原因源码包默认动态链接且目标板里没有对应的 OpenSSL 运行库。嵌入式系统 rootfs 精简过后经常会删掉这类库。解决方案一是在目标板上安装 libssl 运行库方案二是编译静态版本# 在源码根目录编译完全静态版本可能需要改 makefile make LDFLAGS-static -j2注意完全静态的 adb 可能在某些内核上存在 DNS 解析问题实测可用性尚可。主要风险是发送文件大小超过几 MB 时内存复制异常概率较低。推荐优先保证动态库完整静态方案作为兜底。5.3 adb 编译成功但 adbd 在目标板上无法启动现象编译产物放在板子上执行./adbd后没有输出进程退出了。原因没有以 root 权限运行。adbd 需要监听本机 tcp 端口并操作 USB 或 socket 文件普通用户权限不足。或者内核里/dev/android_adb设备节点不存在这是内核驱动的配置原因。解决先确认权限su root -c /data/adbd ss -lnt端口 5555 正常监听之后再从电脑执行adb connect 板子IP:5555。如果监听端口 5555 的进程确实存在但电脑连接不上需要检查板载防火墙常见于使用 iptables 的 BSP 系统。6. 编译后验证的四个关键指标确保 adb 不是白编的编译完一个 adb 工具不能只看它能跑./adb version就万事大吉。需要做一个相对完整的功能验证清单完整跑完一遍才确认编译可用。验证第一项在目标设备上启动 adbd 后回到宿主机执行以下命令adb kill-server adb connect 192.168.1.100:5555 adb devices在adb devices输出中确认状态为device而不是offline。如果offline通常是 adb 协议版本不匹配仓库源码里的版本不妨重新编译最新远端分支。验证第二项跑一次真实的文件传输adb push /home/builder/test.txt /data/local/tmp/ adb shell ls -l /data/local/tmp/test.txt传输 100MB 以上文件确保缓冲区处理没有内存泄漏。ADB 的 sync 协议在大文件场景中表现不稳定多个源码版本都已经提供修复。验证第三项使用 shell 管道检查重定向输出是否会挂死adb shell cat /proc/cpuinfo | head -n 20这一项专门验证 adb 的 stdout 与本地管道交互是否正常如果你只是静态编译却忘记了 pty 相关的 link 库这一关就会出现看不到输出的问题。验证第四项检查 fastboot 支持adb reboot bootloader这条命令验证 adb 对设备重启指令协议的支持是否完整。如果源码包裁剪过某些命令reboot bootloader 可能被执行成普通 reboot。在我这边实际编译使用的过程中还遇到过一个问题源码包默认生成的 adb 并不是包含 adbd 的全量版本我从 README 与其他分发版本对比后才知道这一区别。从那以后我每次拿到 adb 源码包都强制走一遍两版本确认的流程读 README 时首先搜索关键词adbd。希望你在这套源码上编出自己的可用 adb 时也能把这些步骤当成固定流程来执行。希望能帮到你快速拿到可用的 ADB 工具。本文还有配套的精品资源点击获取