N01 — Build and boot AOSP
Check out AOSP, pick a target, build it and boot it in a virtual device. The guide every other nerd project depends on, and the one that needs the most disk, RAM and patience.
A full AOSP checkout and build is a serious machine operation. Before anything else, be honest about the hardware. The AOSP build documentation states a minimum of 400 GB of free disk space — roughly 250 GB to check out the code and 150 GB to build it — and a minimum of 64 GB of RAM on a 64-bit x86 system.1 That is hundreds of gigabytes and hours of build time on a fast machine, not a coffee-break download. If you do not have that machine, read Building AOSP instead; it explains the pipeline without asking you to run it.
TL;DR#
- AOSP is many Git repositories described by one manifest.
repois the tool that manages them as a single tree. source build/envsetup.shthenlunchselects a product, a release configuration and a build variant.mbuilds it. Soong turns the tree into a Ninja graph; Ninja executes it.- The build produces images, not a running system. You boot the images in a virtual device.
- A single-module build is much cheaper than
m. Use it while iterating.
What you are building#
A bootable AOSP system image for a virtual target, plus a working adb connection to it. Nothing
here is a phone-only skill: the same checkout and the same m command build every later project in
this track.
Steps#
- Check the host
The published minimums are 400 GB of free disk and 64 GB of RAM on a 64-bit x86 host. Check both before you start; a build that runs out of either fails in ways that are hard to diagnose.1
You should seeEnough disk and RAM for one checkout plus one build. - Install repo
repois a Python wrapper around Git that reads the AOSP manifest. Install it from your distribution or the AOSP instructions, then put it onPATH. Note that it is a tool for the tree, not part of the build.You should see`repo --version` prints a version. - Initialise the tree
mkdir aosp && cd aosp repo init --partial-clone --no-use-superproject -b android-latest-release \ -u https://android.googlesource.com/platform/manifestThe branch and the manifest URL define which tree you get.
--partial-clonefetches file contents on demand, which makes the first sync smaller but keeps the network in the loop later.You should seeA `.repo` directory appears in the new checkout. - Sync
repo sync -c -j8-crestricts to the current branch, and-j8sets the number of parallel jobs. This is the step people underestimate; it moves a lot of data.You should seeA very large download that eventually finishes. - Load the build environment
source build/envsetup.shThis must be sourced, not executed, because it defines shell functions in your current shell. Do it again in every new terminal.
You should see`lunch` and `m` exist in this shell. - Choose a target
lunch aosp_cf_x86_64_only_phone-aosp_current-userdebugThis is the Cuttlefish phone target used in the AOSP build documentation.1 The string has three parts: product, release configuration and build variant, separated by dashes. If you want the plain emulator instead of Cuttlefish, the exact target is listed on the AOSP "Create an AVD" page — check it there rather than guessing, because target names change between releases.
You should seelunch prints the product, release configuration and variant. - Build
mmbuilds the default target for the lunch selection. It invokessoong_ui, which reads everyAndroid.bp, resolves the graph, emits Ninja files and runs Ninja. Output lands underout/target/product/, where the system, vendor and boot images are assembled.You should seeImage files under `out/target/product/<target>/`. - Boot the target
For Cuttlefish, use the Cuttlefish launch tooling that matches your AOSP release; the command has changed across releases, so take it from the Cuttlefish documentation rather than from memory. For the emulator, the AOSP page documents building the AVD image and running the
emulatorcommand; the exact sequence belongs to that page. Either way, success looks the same:adb deviceslists the device and the screen shows a launcher.You should seeThe virtual device reaches a home screen and shows in `adb devices`. - Confirm what you booted
adb shell getprop ro.build.version.sdk adb shell getprop ro.build.typero.build.typeshould sayuserdebugif you lunched auserdebugvariant. If it does not, you booted a different image than you built.You should seeProperties that match the target you built.
mkdir aosp && cd aosp
repo init --partial-clone --no-use-superproject -b android-latest-release -u https://android.googlesource.com/platform/manifest
repo sync -c -j8
source build/envsetup.sh
lunch aosp_cf_x86_64_only_phone-aosp_current-userdebug
mExample output
Illustrative — no build was executed in this run.The files you touched#
Once it boots, the tree is readable in the browser as well as on disk. Every path below is open on Android Code Search, which is where you should read it.2 The platform layout — kernel, HAL, native libraries, runtime, framework, system apps — is the subject of the architecture overview.3
- the Soong build system that reads Android.bp and emits Ninja
- the legacy Make build and the Kati compatibility layer
- README.mdthe init language, useful once the build boots
- init.rcthe platform init.rc, which starts the first services
- where every later nerd project edits code
If you want to change one of these rather than read it, contributions go through the Android Gerrit, not through a pull request.4
Verification#
A build is not a boot. The build succeeded when the images exist under out/target/product/; the
boot succeeded when the device appears in adb devices and reaches a launcher. If the build passes
and the boot fails, the problem is usually the target, the virtualisation setup or an incomplete
sync — not the source.1
Once it does boot, the boot itself becomes readable: init parses the .rc files in the tree and
starts the first services, which is what the next two projects change.5
What can go wrong#
- You run out of disk. The published minimum is 400 GB for checkout plus build, and build output
grows.
repo syncfailing partway with input/output errors is the usual symptom. - The build is OOM-killed. 64 GB of RAM is the stated minimum; less than that will fail with the linker or a compiler killed by the kernel, not with a compiler error.
lunchrejects the target. Target names differ between releases. Copy the target from the AOSP page for the branch you synced instead of reusing a string from a blog post.mis not found. You did not sourcebuild/envsetup.shin this shell, or you opened a new terminal.- The sync is incomplete.
repo synccan stop on a network error and look finished. Re-run it; it is incremental. - The device boots but
adbsees nothing. That is a host problem (virtualisation, networking or udev), not a build problem.
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsBuild Androidsource.android.comaccessed 2026-10-27↩
- sourceAndroid Code Search (cs.android.com)cs.android.comaccessed 2026-10-27↩
- docsAndroid platform architecture (AOSP)source.android.comaccessed 2026-10-27↩
- sourceAndroid Gerrit code reviewandroid-review.googlesource.comaccessed 2026-10-27↩
- sourcesystem/core/rootdir/init.rcandroid.googlesource.comaccessed 2026-10-27↩