首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
Windows下用WSL2编译Android 14源码全指南
📅 2026/10/19 13:40:07
✍️ 爱科研究院
👁 阅读 3,247
在 Windows 上编译 Android 14 源码放到五六年前真的是吃力不讨好要么装双系统要么挂虚拟机磁盘、内存随便一个不够就卡到怀疑人生。自从 WSL2 成熟之后情况完全变了——你可以在 Windows 10/11 的窗口下开一个轻量 Linux 环境用近乎原生的 I/O 速度跑完 repo sync 和整套 AOSP 构建流程最后把镜像拷出来刷机或者丢给模拟器。这篇指南就是围绕这件事写的从 WSL2 发行版的规划迁移、工具链安装到 Android 14 源码的下载与编译再到我踩过的各种坑。适合想在 Windows 机器上研究 AOSP、做 Framework 或 ROM 定制、又不想额外搭 Linux 服务器的开发者照着做基本能一次性走通。1. 动手之前WSL2 到底行不行磁盘内存怎么规划1.1 为什么选 WSL2而不是 WSL1 或者传统虚拟机先把结论放前面WSL2 的时候AOSP 这套庞大代码树的下载和编译体验明显好于 WSL1 和传统虚拟机但这不代表无脑闭眼选前置条件得满足。WSL1 本质上是 Windows 内核上跑一个 Linux API 翻译层它没有真正的 Linux 内核文件系统、符号链接、文件权限等行为都和原生 Linux 有差异。AOSP 构建里有大量操作依赖 Linux 语义比如符号链接的创建与解析、inotify 文件监听、某些脚本对权限位的敏感处理。WSL1 在这些地方容易出诡异问题轻则某个模块编译失败重则整个 checkout 就跨掉。我有一次在 WSL1 下 repo sync 完成后源码数量看起来都对一编译就大量报错最后排查到是符号链接行为不一致白白耗掉一晚上。传统虚拟机VMware、VirtualBox、Hyper-V性能接近原生 Linux磁盘占用却十分夸张一个虚拟机系统盘就是几十 GBAOSP 源码加 out 目录再来几百 GBWindows 本机还要留空间整体成本很高。更难受的是 Windows 与虚拟机之间的文件交换共享文件夹的 I/O 效率太低编译时如果把源码放在共享目录里Ninja 会慢到怀疑人生。WSL2 就不一样了它相当于一个轻量虚拟机跑的是真正的 Linux 内核但由 Windows 统一管理虚拟化资源。你不需要给发行版单独分配固定磁盘代码直接通过 \wsl$ 路径从 Windows 访问反过来 WSL 里也能挂载 /mnt/c 读写 Windows 盘开发和分发产物都很顺手。代价是它确实不是原生 LinuxI/O 和进程调度会有少量损耗但编译 AOSP 这种以 CPU 密集和文件 I/O 为主的任务实际损耗已经可以接受。有个前提必须提WSL2 要求 Windows 开启虚拟化平台功能并且 CPU 要在 BIOS 里打开虚拟化选项。Windows 11 用户基本是现成的Windows 10 2004 以上版本也能用只是有些老机器默认没开虚拟化启动 WSL2 后 Ubuntu 会报“请启用虚拟机平台”这时候去 BIOS 里把 Intel VT-x / AMD SVM 打开就行。1.2 磁盘和内存到底要准备多少很多人一开始低估了 AOSP 的胃口等到磁盘满了才回头清空间非常痛苦。我给出一个参考值Android 14 全量源码下载加编译磁盘空闲最好有 500GB 以上最低也别低于 400GB。拆开看repo sync拉下来的.repo目录大概是 40~60GB这些是各项目的 Git 仓库本体。checkout 之后的源码树也就是你实际看到的 aosp 工作目录再加 80~120GB。out目录就看构建目标了只构建 x86_64 模拟器镜像通常要 150~250GB如果中途还切过 target、换过分支out 目录里堆多个产物空间消耗会更大。再有 ccache 缓存我一般给 50GB 左右如果你磁盘富裕可以给到 80GB复用效果明显。内存方面32GB 体验最好16GB 也能跑但必须配合 swap编译时长会明显拉长。AOSP 编译时 Soong/Ninja 会开大量并发任务物理内存不够就直接触发 OOMNinja 进程可能带着半条构建记录一起崩掉。我第一次用 16GB 内存机器编译 Android 14中途加了 32GB swapfile 才勉强跑完整体时间比 32GB 内存环境多花了将近一倍。动手之前先在 WSL 里敲两个命令看看家底free -h查内存df -h /查磁盘。如果磁盘和内存都不满足后面流程别急着走先做扩展再说。1.3 把 WSL2 发行版从 C 盘迁出去WSL2 默认把发行版虚拟磁盘文件放在 C 盘的用户目录下一个 Ubuntu 虚盘初始也就几 GB但放上 AOSP 源码和 out 产物之后直接就是几百 GB 的大块头C 盘是系统盘一旦塞满 Windows 会出各种怪毛病。解决办法是把整个发行版迁移到 D 盘或其它大容量分区推荐开工前就做。整个迁移分四步先备份再卸载再导入。PowerShell 里执行wsl --shutdown wsl --export Ubuntu-22.04 D:\wsl\ubuntu-22.04.tar wsl --unregister Ubuntu-22.04 wsl --import Ubuntu-22.04 D:\wsl\ubuntu-22.04 D:\wsl\ubuntu-22.04.tar --version 2说明一下每步的目的。wsl --shutdown是先彻底关掉发行版否则导出时文件可能还在写入会导出失败或损坏。wsl --export生成一个 tar 包可以理解成整个系统盘的快照。wsl --unregister会删除原来的发行版及其所有数据这一刻开始 C 盘空间就释放了所以务必等 export 成功再执行。wsl --import把 tar 包导入到 D:\wsl\ubuntu-22.04 这个目录--version 2明确指定 WSL2。导入完成后重新进入发行版默认用户会变成 root这不太利于日常操作。解决方式是编辑 WSL 内的 /etc/wsl.conf写入[user] default你的用户名然后回到 PowerShell 执行wsl --shutdown再重新进身份就恢复正常了。这个迁移动作做完后面跑 repo sync 和 m 编译时所有大文件都会落在 D 盘再也不慌系统盘爆红。新版 WSL 在安装发行版时也会询问安装位置如果你还没装 WSL直接选择自定义目录会省掉后面这趟折腾。1.4 用 .wslconfig 分配资源WSL2 默认只拿物理内存的一部分给虚拟机具体比例和你机器配置有关但 AOSP 编译这种高内存需求场景不显式配置很容易卡在内存瓶颈上。Windows 用户可以在%UserProfile%\.wslconfig文件里手动分配资源没有这个文件就新建一个。一个相对稳妥的示例配置[wsl2] memory32GB processors8 swap32GB localhostForwardingtruememory是 WSL2 可用的最大内存按你物理内存总量留出 Windows 的余量。如果物理内存是 64GB给 WSL 分 32GBWindows 还剩 32GB 跑 IDE、浏览器、杀毒软件够用。如果物理内存只有 16GB分 12GB 给 WSL再配合后面的 swapfile 也能勉强跑但别开太多其它 Windows 程序。processors限制 WSL 可以使用的核心数不设置默认全部核心编译确实更快但 Windows 侧若有其它负载会抢资源设一个 6~8 的数值比较均衡。swap设 32GB作用是给 WSL2 虚拟一个额外内存区域物理内存不够时顶上去。所有配置修改都要在 PowerShell 里执行wsl --shutdown后再进发行版才会生效。进入 WSL 后用free -h确认内存和 swap 是否符合预期。2. WSL2 环境搭建依赖包、JDK17、repo 工具一次到位2.1 安装 Ubuntu 与基础依赖包我习惯用 Ubuntu 22.04 作为 WSL2 发行版它默认自带 Python 3.10软件源里的 OpenJDK 17 也是现成的和 Android 14 的构建要求非常匹配。在 Windows 11 上装 Ubuntu直接执行wsl --install -d Ubuntu-22.04首次启动会让你设置用户名和密码记好这两个信息后面 sudo 要用。进入发行版后先更新软件源和系统包sudo apt update sudo apt upgrade -y然后安装 AOSP 编译需要的基础依赖我实际使用的安装清单是sudo apt install -y \ git-core gnupg flex bison build-essential zip curl \ zlib1g-dev libc6-dev-i386 lib32z1 libgl1-mesa-dev \ libxml2-utils xsltproc unzip fontconfig \ python3 python3-pip openjdk-17-jdk ccache \ lz4 libssl-dev libelf-dev这些包的作用大致分几类build-essential提供编译器和基础 make 工具flex和bison是构建语法分析器时会用到的工具libxml2-utils、xsltproc参与文档和配置生成unzip、zip、curl处理压缩与网络下载python3是 repo 工具和其它脚本的运行时。openjdk-17-jdk是 Android 14 的硬性要求后面单独说。如果你用的是更新的 Ubuntu比如 24.04官方依赖列表里那些旧库可能存在改名或缺失的情况常见的是libncurses5这类老库在新版源里不一定同名。但别慌先跳过编译时真有模块引用它再单独解决。为了应付历史脚本对python命令的依赖建议顺手做一条软链sudo ln -s /usr/bin/python3 /usr/bin/pythonAndroid 14 里大部分逻辑已经切换到 python3但总有一些角落脚本写死调用 python软链能省一次排查时间。2.2 确认 Java 环境是 17Android 14 构建系统对 Java 版本卡得很严必须是 OpenJDK 17。版本不对的话编译会在很早期就冒出类似Unsupported major.minor version 61.0的错误看着像代码问题实际上就是 JDK 版本没对上。Ubuntu 22.04 下直接安装sudo apt install openjdk-17-jdk java -version正常情况下java -version会输出openjdk version 17.0.x之类的内容。如果你的系统原本装了其它 JDK 版本比如 Ubuntu 24.04 默认可能是 JDK 21可以用sudo update-alternatives --config java把默认 java 切到 17。这里有个提示AOSP 官方构建用的是特定 JDK 发行版但一般场景下安装标准的 OpenJDK 17 就够了。不要图新鲜去装 JDK 21 或其它预览版构建系统里有些字节码库是严格按 JDK 17 设计的版本升上去反而会报你没有见过的错。2.3 安装 repo 工具repo 是 AOSP 下载源码的核心工具它本身就是一个 Python 脚本负责按照 manifest 文件批量调度各个 Git 仓库的拉取与 checkout。你当然可以自己写脚本去逐仓 git clone但几百个仓库的地址、分支、依赖关系靠手工维护不现实。安装 repo 比较简单国内云环境下直接从你选用的开源镜像站拿 repo 引导脚本最省事。镜像站一般都会提供/git-repo/repo路径下的脚本实际地址以你选用的镜像站文档为准。命令思路是mkdir -p ~/bin curl -sSL https://镜像站/git-repo/repo -o ~/bin/repo chmod x ~/bin/repo接着把~/bin加进 PATH 并写入 shell 配置文件echo export PATH$HOME/bin:$PATH ~/.bashrc source ~/.bashrc repo --versionrepo --version能正常输出版本信息说明工具链 OK。有些教程会让你用apt install repo也能装但软件源里的 repo 版本往往偏旧对比较新的 Android 14 manifest 处理可能不兼容遇到问题还是优先用引导脚本版。2.4 Git 配置和系统参数AOSP 的每个子项目都是独立 Git 仓库repo 在执行操作时离不开 Git 的用户信息。如果之前没配过repo init阶段可能直接报“Please tell me who you are”所以要先把 Git 全局身份配置好git config --global user.name Your Name git config --global user.email youexample.com强烈建议再加一条核心配置git config --global core.filemode false这条配置让 Git 忽略文件权限位的变化。WSL2 的文件权限虽然比 WSL1 靠谱但在 Windows 和 Linux 目录互相访问的过程中仍可能出现权限位漂移开着 filemode 会产生大量无意义的 diff甚至污染源码工作区false 能避免这类干扰。系统参数方面AOSP 仓库数量和构建文件都非常大默认的 inotify 上限和文件描述符上限可能不够用。可以先手动调一下echo 524288 | sudo tee /proc/sys/fs/inotify/max_user_watches echo 524288 | sudo tee /proc/sys/fs/inotify/max_queued_events ulimit -n 65535这两个 inotify 参数对 IDE 和大规模文件监听的场景尤其重要不调的话编译过程中可能冷不丁报一个 inotify limit 相关的错误。ulimit 提升文件描述符上限repo sync 高并发时不容易碰到Too many open files。3. 下载 Android 14 源码repo init 与 repo sync 实操3.1 选一个合适的分支AOSP 的版本标签并不只有一个Android 14 发布后陆续有很多补丁和安全更新标签格式大致是android-14.0.0_r1、android-14.0.0_r2到后面会有android-14.0.0_rXX以及android-security-14.0.0_rXX这类安全更新版。分支选得好不好直接影响源码的整体稳定性和后续体验。对于大多数学习和开发场景我的建议是选一个相对靠后的稳定 tag比如android-14.0.0_r1之后的某个版本安全更新标签适合那些关注漏洞修复、准备做长期维护的人。如果你只是想体验一下编译流程选 r1 这种早期稳定 tag 也完全够用。实际操作中可以先到 AOSP 的 tag 列表页查看有哪些可选标签然后挑一个发布日期合适的。这里提醒一句分支选定后整个工作目录里的所有子仓库都会 checkout 到对应版本中途换分支的成本很高轻则重新 sync 几十 GB重则大量冲突所以动手前想清楚目标是什么。如果只是研究某个模块的代码r1 还是 r2 差别不大如果打算长期跟踪安全补丁就直接选最新的 security tag。3.2 用镜像站完成 repo init在国内环境下直连 AOSP 官方仓库下载源码基本不可行速度、稳定性都是灾难。绝大多数开发者用的是高校开源镜像站提供的 AOSP 镜像这也是目前比较成熟的做法。整个流程把官方地址替换成镜像站地址即可。创建源码目录并初始化mkdir -p ~/aosp/android-14 cd ~/aosp/android-14 repo init -u https://镜像站/platform/manifest.git -b android-14.0.0_r1把镜像站替换成你实际使用的镜像站地址。不同镜像站的 manifest 路径格式通常都类似公开文档里都有写明。repo init的作用是拉取一个描述“项目清单”的 manifest 仓库其中记录了 AOSP 全部子项目的 Git 地址和分支信息然后生成.repo目录结构和初始配置。如果你的磁盘空间极度紧张可以考虑在 repo init 时加上--depth1做浅克隆每个仓库只拉取当前分支的最新提交体积能省不少。但代价是后续切换分支、查历史提交记录会非常麻烦经常出现缺对象的情况。我不是很推荐第一次编译的新手加这个参数除非你确认自己只是一次性编译体验。repo init 执行成功后会显示类似repo initialized的信息同时.repo/manifests目录会存在。这时候还能做一个快速自查repo manifest -r可以输出当前的 manifest 内容确认分支号是否是你选的那个。3.3 执行 repo sync 并控制资源初始化完成后就开始正式拉代码这是整个流程里最耗时间的环节repo sync -c --no-tags -j4解释下这三个参数。-c表示只同步当前分支的代码不去把所有分支都拉下来能少拉很多无用数据。--no-tags跳过获取 Git 标签Android 源码调试一般用不到 tag这个参数对下载体积的缩减非常可观。-j4控制并发数4 是个稳妥值机器强可以尝试-j8机器弱就-j2。首次 repo sync 是没有那种“整体进度条”的它逐个项目打印Fetching project xxx每个项目内部会显示它自己的对象传输进度。不要以为卡在某个项目就是死机了查看整体进度最靠谱的方法是另开一个终端观察.repo目录的体积增长du -sh .repo watch -n 5 du -sh .repo如果.repo目录在稳定增长说明网络和磁盘都没问题整体只是时间问题。按照正常家用宽带和 SSDAndroid 14 全量源码拉取大概需要 2 到 5 小时具体看带宽和镜像站的负载。如果你是千兆带宽加 NVMe几十分钟到一个小时也有可能。这里要特别控制并发数。并发开太大一下子建立大量 Git 连接内存和文件句柄都会迅速吃紧。我见过有人在 8GB 内存的机器上直接repo sync -j32结果系统卡死最后只能强制关机。3.4 同步中断后怎么续repo sync 在拉取过程中因为网络波动、镜像站负载高、电脑断电等原因中断是非常正常的。好消息是 repo sync 本身是增量续传的失败后重新执行同样的命令即可已经拉取完成的仓库不会重新下载而是从断点继续。如果某个项目反复卡在Fetching之后失败处理方法有以下几步从轻到重依次尝试先降并发重试repo sync -c --no-tags -j1单线程虽然慢但对网络的冲击小容易穿透不稳定链路。接着检查 Git 的网络低速度限制默认情况下 Git 遇到低速连接会超时可以调低限制甚至关闭git config --global http.lowSpeedLimit 0 git config --global http.lowSpeedTime 999999 git config --global http.postBuffer 524288000这三条配置本质上是告诉 Git“给这个连接更大的耐心”。多数反复失败是网络对小文件请求的响应不稳定把超时调宽能有效减少中断次数。如果是特定仓库损坏导致无法继续少数情况下需要删掉.repo/projects下对应的项目目录再重试但这种情况很罕见。同步完成的标志是命令结束后没有报错源码树的顶层目录能看到build/、art/、frameworks/、packages/等子目录。源码下载到这里就算完成了下一节进入编译阶段。4. 编译 Android 14从 envsetup 到镜像产物4.1 加载编译环境AOSP 编译环境通过一条命令加载source build/envsetup.sh这条命令会注册m、mm、mmm、lunch、croot等一批便捷命令。其中m是编译整个源码树的命令相当于旧版文档里的make但它不需要你手动 cd 到根目录系统会自动向上查找 Android 源码根目录。croot可以一键回到源码根目录。lunch是选择构建目标的命令下一步就用它。加载环境之前可以先把 ccache 打开。如果你已经安装了 ccache执行export USE_CCACHE1 ccache -M 80GUSE_CCACHE1告诉构建系统启用缓存ccache -M 80G把缓存上限设为 80GB。这个操作对首次编译没有加速效果真正的价值在后续增量编译这个后面单独展开说。4.2 lunch 选择构建目标lunch 决定了你编译出来的系统镜像跑在什么平台上。直接指定目标lunch aosp_x86_64-eng也可以不带参数运行lunch会弹出交互式菜单列出全部可选 target手动输入编号选择。aosp_x86_64-eng是 64 位 x86 平台的可调试镜像适合在模拟器里跑也适合日常学习源码——eng 版本自带 root调试权限不受限制开发时改代码、push 文件都很方便。target 名字里的后缀含义要理解eng是工程版本带完整调试工具和 root适合开发调试userdebug是接近正式版的调试版本保留 adb root 能力但更贴近用户机器user是正式发布版本权限收紧通常用于最终交付。一般学习用 eng 就够了想做真机体验版就用针对具体设备的 userdebug 版本。如果编译的是特定真机固件比如某个设备代号是 xxxlunch 目标写成aosp_xxx-userdebugAOSP 会生成对应的 boot、system、vendor 镜像。但第一次接触 WSL2 编译我还是推荐先跑通aosp_x86_64-eng等全流程熟络了再换真机 target。lunch 成功后终端会打印一排环境变量信息包括TARGET_PRODUCT、TARGET_BUILD_VARIANT、PRODUCT_OUT等。这时候可以执行echo $PRODUCT_OUT它会告诉你最终编译产物会落在哪个目录这个信息后面有用。4.3 启动编译代码在源码根目录环境也已经加载好直接开跑m 21 | tee build.logm默认会用当前机器的全部核心并行编译速度最快。如果内存偏小可以先限制并行数比如m -j4或m -j8宁慢勿崩。tee build.log会把编译过程的输出同时写到终端和文件里终端实时滚动文件留档备查。编译中途如果断开了终端build.log 里也能保留完整日志方便事后排查。首次编译的流程大致是先启动 Soong 构建系统生成一批依赖描述文件接着调用 Ninja 执行实际的编译和链接任务。当你看到类似[ 3% 123/4567]的百分比输出说明已经进入真正的编译阶段这个阶段会持续很长时间。启另一个终端进去cd到源码目录后可以实时观察资源占用和日志free -h df -h / tail -f build.logfree -h判断内存是否见底df -h /判断磁盘是否爆满tail -f build.log看当前输出。首次全量构建的时间没有固定值NVMe SSD 16 核 32GB 内存x86_64 eng 镜像大约 1 到 3 小时机械硬盘加低端 CPU奔着大半天甚至一天去都很正常。编译过程中最忌讳的是中途强行杀进程Ninja 不是每次都能从断点高效恢复。真遇到非停不可的情况宁可让它自然报错也别乱 CtrlC否则重跑时可能残留脏文件花费时间反而更多。4.4 编译产物与镜像文件构建成功的标志是 build.log 末尾出现类似#### build completed successfully的提示。用echo $PRODUCT_OUT查看输出目录cd 进去就能看到system.img、userdata.img、vendor.img、ramdisk.img、boot.img等镜像文件。具体路径因 lunch target 而异所以别死记硬背直接看$PRODUCT_OUT最准确。每个 img 的用途不同system.img是系统分区镜像vendor.img是厂商分区镜像userdata.img是用户数据分区镜像boot.img包含内核和启动相关文件。刷机时一般会在 fastboot 模式下执行fastboot flashall一键刷入前提是设备已经解锁 bootloader。如果在 Windows 侧需要使用这些镜像可以把它们拷到 /mnt/c 下的目录mkdir -p /mnt/c/Users/你的用户名/Desktop/android14-images cp $PRODUCT_OUT/system.img $PRODUCT_OUT/userdata.img $PRODUCT_OUT/vendor.img /mnt/c/Users/你的用户名/Desktop/android14-images/WSL 里写 /mnt/c 的路径其实就是访问 C 盘速度受 NTFS 文件系统限制复制几个大 img 可能要等一会儿但比反过来把源码放 C 盘里编译要快得多。日常改代码后再编译不需要重新全量构建。AOSP 的构建系统支持增量编译你只改了某个模块再执行一次mNinja 会只重建受影响的部分速度非常快。如果某些改动牵涉到全局配置或者你想彻底清理产物可以执行m clean等价于清空整个 out 目录重新来过。这个命令慎用一旦执行下次编译又是全量几小时起步。4.5 ccache 让二次编译提速ccache 的作用是缓存编译过程中的目标文件避免相同代码重复编译。AOSP 这种巨型工程里增量编译的实际体验有没有 ccache 差别极大。我实测只改 Framework 层的某个小模块有 80GB 缓存的ccache增量编译时间从十几分钟压到几分钟提升非常明显。使用 ccache 时要注意三点。第一USE_CCACHE1要加进 shell 配置或每次编译前 export构建系统才会真正启用它。第二ccache 缓存目录默认在家目录下同样占用磁盘空间我习惯显式指定缓存目录和容量上限避免无节制膨胀。可以在 ~/.bashrc 加export USE_CCACHE1 export CCACHE_DIR$HOME/.ccache ccache -M 80G第三如果你有多个构建目录共用同一个 ccache 缓存并发编译时可能出现锁竞争性能反而下降。最稳妥的做法是每个工作目录单独设置CCACHE_DIR或者错开编译时间不要同时跑两个 m。5. 踩坑实录Windows WSL2 下编译 AOSP 的典型问题5.1 repo sync 相关症状与解法repo sync 阶段的问题最磨人我把高频现象和对应解法整理成一个速查表按顺序排查就能解决大多数情况。现象可能原因处理办法某个项目一直卡在 Fetching网络对长连接不稳定降低并发到 -j1重跑 repo sync报错 RPC failed; curl 56网络中断或代理干扰调大 Git 超时参数重跑 sync报错 Too many open files文件描述符上限不足执行 ulimit -n 65535 后再 sync提示无法连接镜像站镜像站地址拼错核对 manifest 地址拼写换成备用镜像站同步完成后有项目无法 checkout部分仓库损坏删除对应 .repo/projects 目录重试这里实际经验很重要repo sync 失败后立刻重跑是默认动作不要因为失败一次就想去删 .repo。绝大多数情况就是网络抖动同一命令多跑几轮自然就补上了。我在公司内网环境里就遇到过某几个大仓库反复 56 号错误排查到最后是公司出口防火墙对大流量连接有限制。解决办法就是降并发跑到单线程配一条git config --global http.lowSpeedLimit 0问题立刻缓解。如果你是学校或者公司的网络环境这类问题尤其常见先把超时参数放宽再看是不是网络出口策略的问题。5.2 内存不足与 Ninja 崩溃内存不足是编译阶段最经典的问题现象一般是 ninja 直接报internal error或者整个终端卡死查看系统日志会出现Out of memory。如果 WSL2 默认内存分配不够就算m -j4也扛不住尤其是同时开着 IDE 和浏览器的时候。首选方案是给 WSL2 内部手动挂一个 swapfile我自己实测 32GB swapfile 能让 16GB 物理内存的机器跑完 Android 14 全量编译。操作如下sudo fallocate -l 32G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile如果希望重启后自动挂载再往 /etc/fstab 里加一行echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstabswapfile 的作用是当物理内存不够时把一部分不活跃的内存页换到磁盘上AOSP 构建过程中会产生大量中间产物和缓存这些数据并不需要全部常驻内存swap 能有效平滑峰值。缺点就是 SSD 磨损和速度下降但总比编译到一半崩溃强。我也测试过完全不开 swap 的结果32GB 物理内存机器在编译 x86_64 的 user 版本时内存峰值能到 28GB 左右勉强不崩16GB 物理内存不开 swap几乎百分之百在 Ninja 阶段挂掉。所以内存小的机器swap 是必须的。另外也可以把m -j$(nproc)换成m -j4减少并发任务数量内存压力会小很多。5.3 编译报错的通用排查思路编译阶段遇到报错先别急着重整整个环境。AOSP 编译输出非常长从头翻到尾既不现实也没必要。我自己的排查顺序是先看日志尾部执行tail -n 200 build.log大多数错误在上千行输出之后只占最后几行前面的进度信息都是噪音。如果有明显报错关键字再执行grep -E error:|FAILED: build.log | tail -n 50这样能快速定位到具体是哪个模块出错、报了什么错误。接着根据错误类型分类处理。Java 相关的版本错误回看 JDK 是否 17找不到 python检查软链接是否存在缺少 32 位库把 2.1 节列出的lib32z1、libc6-dev-i386装上权限相关的报错检查源码目录是否在 WSL 内部 ext4 而非 /mnt/c。如果是一个具体模块编译失败还差一个高效调试技巧用m 模块名单独编译出错模块而不是每次都全量跑。比如 Framework 某个 Java 类报错先m framework或m services构建系统会把目标范围缩小到该模块日志量小很多定位也更快。要警惕一个常见心态一碰到报错就觉得是环境配置问题想rm -rf out重来。out 目录重删确实干净但代价是几小时的编译时间。除非是构建系统配置文件坏了否则优先增量修复别动不动重开。5.4 WSL2 特有的坑WSL2 环境下编译 AOSP 有它自己的特殊性这些坑在原生 Linux 上不多见但在这套环境下几乎人人都会碰到。第一源码和产物绝不能放在 Windows 文件系统/mnt/c、/mnt/d里。WSL2 访问 /mnt/c 走的是 9P 协议I/O 性能比访问 Linux 内部 ext4 低了一个量级而且 NTFS 上符号链接和文件行为跟 Linux 不一致AOSP 构建会报符号链接相关错误。不管磁盘规划多麻烦AOSP 工作目录一定要放在 WSL 内部路径比如~/aosp/android-14。第二Windows Defender 实时扫描会给编译拖后腿。WSL2 的发行版实际上是一个 vhdx 文件Windows 杀毒软件会实时扫描这个文件里的内容源码文件和编译中间文件越多扫描开销越大。我实测把 vhdx 所在目录比如迁移后的 D:\wsl和源码目录加入 Defender 排除列表之后编译速度快了不少。这一步虽然不是必需但在大项目上是性价比极高的一次操作。第三WSL2 的内存不自动释放。构建完成后你看到 Windows 任务管理器里 vmmem 进程仍然占着大量内存这是 WSL2 虚拟机的正常表现它不会在构建结束后立刻归还内存。如果接下来不需要继续使用 WSL在 PowerShell 里执行wsl --shutdown就能立即释放全部内存。注意这会终止所有发行版里的进程编译任务还没写完日志的话记得先保存。第四vhdx 文件体积膨胀。源码和 out 产物会不断往 vhdx 里写入虚拟磁盘占用只增不减即使删除内部文件宿主机上的 vhdx 也不一定会缩小。新版 WSL 支持稀疏 vhdx 特性可以用wsl --manage Ubuntu-22.04 --set-sparse true让虚拟磁盘在删除文件后自动回收空间。如果 WSL 版本较老不支持这个命令那就只能通过 diskpart 或第三方工具对 vhdx 执行 compact 操作相对麻烦但思路是一致的。第五如果想在 WSL2 里启动 AOSP 模拟器跑编译出来的镜像需要处理嵌套虚拟化。WSL2 虽然支持嵌套虚拟化但性能、图形兼容性都比较一言难尽。我自己的习惯是编译完把 system.img 等产物拷到 Windows 侧用 Windows 版 Android 模拟器或直接刷真机体验反而更好。如果你真的需要渲染截图、跑 UI 自动化测试这条建议能帮你省下大量折腾时间。我个人在实际操作中的体会是WSL2 并不是编译 AOSP 的性能最优解真要说极致速度还是原生 Linux 物理机或 Linux 服务器但作为 Windows 用户的日常学习、源码阅读、模块编译场景它已经足够合格了。这套流程我从 Android 11 一路跑到 Android 14稳定性一次比一次好现在基本是把 WSL2 当作随身 Linux 工作站来用了。最后再分享一个小技巧repo sync 和 m 编译这两个重活尽量只开一个会话去跑别同时再挂其它 WSL 任务AOSP 对资源的渴求是持续的多任务并行反而容易把自己卡死。如果编译中途遇到问题别急着删环境重来先看 build.log 最后几百行九成答案都在里面。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/19 13:40:07
农业AI智能体实战指南:技术架构、落地场景与避坑要点
2026/10/19 13:40:07
【晋级答辩复盘哪个软件好】2小时答辩录音不用反复重听:6款AI记录工具实测横评
2026/10/19 13:40:07
Polyspace嵌入式C/C++形式化验证实战:从配置到CI集成
2026/10/19 14:30:25
LR-TB5000工业激光传感器光路与抗干扰部署指南
2026/10/19 14:30:25
恶劣天气下YOLO目标检测:数据集解析与训练调优指南
2026/10/19 14:30:25
联机对战消息收发实战:WebSocket可靠通信与断线重连设计
2026/10/19 14:30:25
WebSocket消息收发机制:联机卡牌对战客户端状态同步与断线重连实战
2026/10/19 14:30:25
双臂具身VLA模型从零到落地:架构、数据与真机部署实战解析
2026/10/19 14:25:23
无线AP故障排查全指南:从物理链路到配置优化的十种实战方法
2026/10/19 0:01:13
频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现
2026/10/19 0:01:13
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道
2026/10/19 0:01:13
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统
2026/10/19 14:00:16
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/19 2:04:59
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/18 0:02:43
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/17 10:15:50
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/16 18:46:48
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/16 18:46:46
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)