WSL2+Ubuntu20.04编译AOSP踩坑实录:从清华源配置到模拟器启动

📅 发布时间:2026/7/11 9:27:02 👁️ 浏览次数:
WSL2+Ubuntu20.04编译AOSP踩坑实录:从清华源配置到模拟器启动
WSL2环境下编译AOSP一次从环境搭建到模拟器启动的深度排雷之旅如果你是一名Android系统开发者或者对AOSPAndroid Open Source Project的内部构造充满好奇那么在自己的开发机上搭建一个可编译、可调试的AOSP环境无疑是深入理解Android的最佳途径。近年来随着Windows Subsystem for Linux 2WSL2的成熟在Windows上获得接近原生Linux的开发体验已成为现实这也让在Windows平台上编译AOSP变得前所未有的可行。然而这条路上布满了“坑”——从基础的软件源配置到复杂的依赖库冲突再到编译过程中的各种诡异报错每一步都可能让你耗费数小时甚至数天。本文不是一份按部就班的操作手册而是一份聚焦于实战中真实问题与解决思路的深度指南。我们将以WSL2 Ubuntu 20.04 LTS为舞台还原从零开始到成功启动模拟器的完整过程重点分享那些官方文档不会告诉你、搜索引擎也难以直接给出答案的“踩坑”经验与排错逻辑目标是让你不仅能成功编译更能理解背后的原因从而具备独立解决问题的能力。1. 基石WSL2与Ubuntu环境的精准搭建在开始任何AOSP相关操作之前一个稳定、高效且配置正确的WSL2环境是重中之重。很多后续编译失败的问题其根源往往可以追溯到环境搭建阶段的不严谨。1.1 WSL2的安装与关键配置首先确保你的Windows 10版本为2004及以上内部版本19041及以上或Windows 11。以管理员身份打开PowerShell执行以下命令启用WSL和虚拟机平台功能# 启用适用于 Linux 的 Windows 子系统 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart # 启用虚拟机平台 dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart重启计算机后将WSL 2设置为默认版本wsl --set-default-version 2接下来从Microsoft Store安装Ubuntu 20.04 LTS。安装完成后首次启动会要求设置用户名和密码。这里有一个关键点避免使用具有特殊字符或空格的用户名因为AOSP的构建脚本对路径非常敏感复杂的路径可能导致难以排查的失败。安装完成后建议立即进行两项优化配置。第一调整WSL2的内存和CPU限制。在用户目录C:\Users\你的用户名\下创建或编辑文件.wslconfig内容如下[wsl2] memory16GB # 根据你的物理内存调整建议至少12GB编译AOSP需要大量内存 processors8 # 分配给你的CPU核心数建议不超过物理核心数的80% swap4GB localhostForwardingtrue这个配置能有效防止编译过程中因内存不足OOM导致的进程被杀死。第二将AOSP源码放在WSL2的文件系统内即/home/目录下绝对不要放在Windows的挂载目录如/mnt/c/下。跨文件系统的I/O性能损耗巨大会使代码同步和编译速度慢到无法忍受。1.2 Ubuntu系统源的优化与基础包安装系统安装后第一件事就是更换软件源以加速后续包的下载。使用国内镜像源是基本操作但细节决定成败。# 备份原始源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak # 使用sed命令快速替换为清华源适用于Ubuntu 20.04 Focal sudo sed -i shttp://.*.ubuntu.comhttps://mirrors.tuna.tsinghua.edu.cng /etc/apt/sources.list更新软件包列表并升级现有软件sudo apt update sudo apt upgrade -y接下来安装编译AOSP所必需的基础开发工具链。Google官方文档会给出一个很长的包列表但根据实际经验以下组合更为可靠能覆盖绝大多数依赖sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3注意libncurses5这个包在Ubuntu 20.04的默认源中可能已经不存在被libncurses6取代。但一些较旧的构建工具可能仍然依赖它。如果遇到相关错误可以尝试从其他Ubuntu版本源安装或者寻找替代方案有时并非必需。我们会在后续编译问题章节详细讨论。2. 获取AOSP源码策略与效率的平衡下载超过100GB的AOSP源码是对网络和耐心的双重考验。选择正确的镜像源和同步策略至关重要。2.1 初始化Repo工具与镜像选择Repo是Google用于管理多个Git仓库的工具。首先获取Repo脚本并为其配置国内镜像源以加速# 在计划存放AOSP的目录下操作例如 /home/username/aosp mkdir ~/aosp cd ~/aosp # 下载Repo脚本 curl -sSL https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo chmod ax repo # 设置Repo镜像源环境变量这对后续所有repo命令生效 export REPO_URLhttps://mirrors.tuna.tsinghua.edu.cn/git/git-repo接下来初始化仓库。这里面临第一个重要选择Android版本和构建目标。对于初次尝试建议选择相对稳定、社区资料较多的版本如android-13.0.0_r1。同时必须指定国内知名的AOSP镜像源./repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r1如果初始化成功你会看到repo has been initialized in ...的提示。此时项目根目录下会生成一个隐藏的.repo文件夹。2.2 高效同步代码的实战技巧执行./repo sync开始同步代码。这个过程极其漫长任何网络波动都可能导致失败。以下是几个提升成功率的技巧使用-j参数控制并发数默认并发数可能过高导致连接被限制。建议根据网络状况调整。./repo sync -j4 # 使用4个并发线程应对同步中断同步过程很可能中途失败。Repo支持断点续传直接重新运行./repo sync即可。但有时会遇到某个仓库卡死可以尝试./repo sync -c --no-tags --prune # -c只同步当前分支--prune删除已不存在的远程分支终极方案使用初始化包。对于国内用户最稳定快速的方法是下载清华大学提供的AOSP镜像初始化包。这是一个包含所有.git对象的tar包下载后解压再执行一次轻量级的repo sync即可完成更新能节省90%以上的时间。提示具体方法为从清华镜像站下载对应版本的aosp-版本代号.tar文件解压到仓库目录然后执行repo sync -l仅检查本地文件再执行repo sync同步最新更改。这几乎是目前最可靠的源码获取方式。3. 编译配置绕开依赖与环境陷阱源码就绪后真正的挑战才刚刚开始。source和lunch这两个命令背后隐藏着诸多细节。3.1 构建环境初始化与目标选择进入AOSP根目录初始化构建环境source build/envsetup.sh这个脚本定义了一系列有用的命令如lunch,m,mm,mma等。接着使用lunch选择构建目标lunch你会看到一个长长的菜单。对于在WSL2中运行模拟器正确的选择是aosp_x86_64-eng或sdk_phone_x86_64-userdebug。aosp_x86_64-eng工程版带有root权限和更多调试工具适合深度开发。sdk_phone_x86_64-userdebug用户调试版更接近用户设备同样支持调试。在WSL2中务必选择x86_64架构的目标因为WSL2虚拟机本身就是x86_64架构运行ARM目标需要复杂的交叉编译和模拟极易失败。3.2 依赖库缺失问题的系统化解决执行lunch或后续m编译时你很可能会遇到各种“找不到库”的错误。这是WSL2环境下的常见痛点因为桌面环境相关的32位库可能不完整。典型错误1libncurses.so.5: cannot open shared object file尽管我们在第一步安装了libncurses5但构建系统可能需要32位i386版本。解决方法# 启用多架构支持如果尚未启用 sudo dpkg --add-architecture i386 sudo apt update # 安装32位库 sudo apt install libncurses5:i386 libstdc6:i386 zlib1g:i386典型错误2与X11、OpenGL相关的库缺失这些错误信息可能包含libX11,libGL,libdrm等。需要安装相应的开发包sudo apt install libx11-dev:i386 libxext-dev:i386 libxtst-dev:i386 libxrandr-dev:i386 libxrender-dev:i386 libxi-dev:i386 sudo apt install libgl1-mesa-dev:i386 libglu1-mesa-dev:i386一个更彻底的方法是在安装完所有基础包后运行构建系统自带的依赖检查脚本如果存在或者直接尝试编译根据第一个报错信息使用apt search和apt install来逐个解决。记住安装包时同时考虑:i386架构的版本是解决WSL2下AOSP编译依赖问题的核心心法。4. 执行编译与启动模拟器当所有依赖问题解决后就可以开始漫长的编译过程了。4.1 利用多核并行编译使用m命令开始编译它默认会使用所有可用的CPU核心。为了更优的资源控制可以使用-j参数指定并行任务数。一个常见的经验公式是CPU核心数 * 2m -j16 # 假设你的CPU有8个核心编译过程可能持续数小时。期间可能会遇到一些警告通常可以忽略。但如果遇到错误Error编译会停止。最常见的错误仍然是依赖缺失或内存不足。内存不足OOM如果编译进程被杀死请回头检查并调整.wslconfig中的memory设置并确保没有其他大型程序占用内存。也可以尝试减少-j参数的值。Java版本问题AOSP不同版本需要特定版本的OpenJDK。Android 13需要OpenJDK 11。确保你的系统默认Java版本正确sudo apt install openjdk-11-jdk sudo update-alternatives --config java # 选择Java 114.2 在WSL2中启动Android模拟器编译成功后的输出目录是out/target/product/generic_x86_64/具体路径因lunch选择而异。启动模拟器emulator -verbose -show-kernel # 使用-verbose查看详细日志便于排错在WSL2中直接运行emulator很可能失败因为WSL2默认不支持完整的GUI。你需要在Windows端安装一个X Server。推荐使用开源的 VcXsrv。安装后启动XLaunch在设置中务必勾选“Disable access control”禁用访问控制否则WSL2中的应用无法连接。在WSL2中配置DISPLAY环境变量。在启动emulator之前告诉WSL2图形界面显示到哪里export DISPLAY$(awk /nameserver / {print $2; exit} /etc/resolv.conf 2/dev/null):0 export LIBGL_ALWAYS_INDIRECT1可以将这两行添加到你的~/.bashrc文件中以便每次启动Shell时自动设置。确保KVM加速可用。WSL2基于Hyper-V其内置的Windows Hypervisor Platform提供了类似KVM的加速功能。通常只要你的系统支持虚拟化并在BIOS/UEFI中已开启WSL2就能利用它。可以通过cat /proc/cpuinfo | grep svmAMD或cat /proc/cpuinfo | grep vmxIntel来检查CPU虚拟化支持。完成以上设置后再次运行emulator命令。你应该能看到Windows端弹出模拟器窗口。首次启动会较慢因为需要创建用户数据分区。4.3 进阶排错当模拟器依然黑屏或崩溃时如果模拟器窗口出现但一直黑屏或者很快崩溃可以尝试以下命令启用软件渲染并关闭GPU加速这对于WSL2的图形兼容性更友好emulator -gpu swiftshader_indirect -no-audio -no-snapshot -memory 4096-gpu swiftshader_indirect: 使用SwiftShader进行软件渲染绕过可能的GPU驱动问题。-no-audio: 禁用音频WSL2的音频支持可能不稳定。-no-snapshot: 不加载快照全新启动。-memory 4096: 为模拟器分配4GB内存。这个过程充满了不确定性每个开发者的环境都有细微差别。关键是要学会阅读错误日志。无论是emulator的-verbose输出还是系统日志dmesg | tail或是查看~/.android/avd/下的日志文件都能提供解决问题的关键线索。例如一个常见的权限错误可以通过sudo chmod 777 /dev/kvm来解决不推荐生产环境但可用于测试。从WSL2环境准备到模拟器窗口最终亮起这整条链路涉及操作系统、虚拟化、网络、包管理、编译工具链和图形显示等多个层面的知识。成功编译并运行AOSP不仅仅是执行了一系列命令更是对这些组件如何协同工作的一次深刻理解。每一次“踩坑”和“排雷”都是对开发者系统调试能力的有效锤炼。当你看到自己编译的系统在模拟器中启动那种成就感或许就是驱动我们不断深入技术深渊的最大乐趣。