Target Device: OnePlus 7 · Codename: guacamoleb · SoC: Snapdragon 855 (SM8150)
Android is built from a massive collection of git repositories — thousands of them — managed by a tool called repo. You'll pull all that source code to your machine, drop in device-specific code (device tree, kernel, vendor blobs), then compile the entire OS from scratch. The result is a flashable .zip image.
This takes real hardware. Don't attempt it on anything under-spec'd.
| Resource | Minimum | Recommended |
|---|---|---|
| OS | Ubuntu 20.04 LTS | Ubuntu 22.04 LTS |
| CPU | 8-core | 16-core or more |
| RAM | 16 GB | 32 GB+ |
| Disk (SSD strongly preferred) | 300 GB free | 500 GB+ free |
| Internet | Stable broadband | High-speed (initial sync is ~80–100 GB) |
Why SSD? Android builds perform thousands of small file reads and writes. A spinning hard drive will make your build take 3–5× longer and risks timeouts during
repo sync.
~/android— your source tree root (all ROM source lives here)~/bin— where standalone tools likerepoare storedCODENAME— always refers toguacamolebin this guide- Commands are meant to be run as your regular user unless
sudois explicitly shown
Android's build system expects a specific set of tools to be present. Install them all at once.
sudo apt update && sudo apt upgrade -ysudo apt install -y \
git git-core gnupg flex bison \
build-essential zip curl rsync \
zlib1g-dev gcc-multilib g++-multilib \
libc6-dev-i386 libncurses-dev libncurses5-dev libncursesw5-dev \
lib32z1 lib32stdc++6 libssl-dev liblz4-tool \
bc libxml2-utils xsltproc unzip fontconfig \
python3 python3-pip python3-venv python-is-python3 \
ccache lzop schedtool openssl \
clang lld lldb axel jq \
android-sdk-libsparse-utilsAkhil Narang's setup script handles additional environment configuration that the above misses. Run it:
cd ~/
git clone https://github.com/akhilnarang/scripts
cd scripts
./setup/android_build_env.shLineageOS 23.1 (and anything based on it) requires exactly OpenJDK 17. Other versions will cause build failures.
sudo apt install -y openjdk-17-jdkAdd Java to your environment permanently by appending to ~/.profile:
echo 'export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"' >> ~/.profile
echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.profile
source ~/.profileVerify the correct version is active:
java -version
# Expected output: openjdk version "17.x.x" ...If you see a different version, you may have multiple JDKs installed. Set the correct one with sudo update-alternatives --config java.
mkdir -p ~/bin
mkdir -p ~/android~/bin is where the repo binary lives. ~/android is your source root — everything lives under here. Keep both paths consistent; the rest of this guide assumes them.
repo is a Python wrapper around git that manages the hundreds of individual repositories that make up Android. Google hosts the canonical version.
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repoMake sure ~/bin is in your PATH. Add this to ~/.profile if it isn't already:
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.profile
source ~/.profileConfirm it's working:
repo --versionrepo communicates with remote git servers and requires you to have a name and email set. These don't need to match any real account — they're just used for commit metadata.
git config --global user.email "you@example.com"
git config --global user.name "Your Name"Navigate into your working directory and initialize the repo manifest. This tells repo which project to pull and from which branch.
cd ~/android
repo init -u https://github.com/LineageOS/android.git -b lineage-23.1 --git-lfsWhat is
--git-lfs? Git LFS (Large File Storage) is used for large binary files like prebuilts. This flag ensures they're fetched correctly. If your system doesn't havegit-lfsinstalled, runsudo apt install git-lfsfirst.
Now sync the source. This downloads everything — expect it to take 1–4 hours depending on your connection:
repo sync -c -j$(nproc --all) --force-sync --no-clone-bundle --no-tagsFlag breakdown:
| Flag | Effect |
|---|---|
-c |
Only sync the currently checked-out branch, not all branches |
-j$(nproc --all) |
Use all available CPU threads for parallel downloads |
--force-sync |
Overwrites local changes if repos are out of sync |
--no-clone-bundle |
Skips bundle files, which can cause sync failures |
--no-tags |
Doesn't download git tags — saves time and space |
If the sync fails partway through (common on slower connections), just re-run the same command. It will resume where it left off.
The ROM source you just synced is device-agnostic. To build for a specific phone, you need to add hardware-specific code. All of these repositories are cloned inside your ~/android source root into specific paths — the build system expects them at exact locations.
cd ~/androidThese contain build configuration, BoardConfig, and makefile rules specific to your device.
# Device-specific tree for the OnePlus 7 (guacamoleb)
git clone https://github.com/LineageOS/android_device_oneplus_guacamoleb \
-b lineage-23.1 device/oneplus/guacamoleb
# Common tree shared by all OnePlus SM8150 devices
git clone https://github.com/LineageOS/android_device_oneplus_sm8150-common \
-b lineage-23.1 device/oneplus/sm8150-commonThe Linux kernel for the Snapdragon 855 (SM8150) platform. This is compiled from source during the build — no prebuilt kernel is used.
git clone https://github.com/LineageOS/android_kernel_oneplus_sm8150 \
-b lineage-23.1 kernel/oneplus/sm8150These are proprietary binaries — Wi-Fi firmware, camera HAL, DSP blobs, etc. — that cannot be open-sourced. They're provided by TheMuppets, who extract them from official OEM firmware.
# Device-specific vendor blobs
git clone https://github.com/TheMuppets/proprietary_vendor_oneplus_guacamoleb \
-b lineage-23.1 vendor/oneplus/guacamoleb
# Platform-level vendor blobs shared across SM8150 devices
git clone https://github.com/TheMuppets/proprietary_vendor_oneplus_sm8150-common \
-b lineage-23.1 vendor/oneplus/sm8150-commonOnePlus devices use a shared hardware module for display, touch, and other subsystems not covered by the common Qualcomm HAL.
git clone https://github.com/LineageOS/android_hardware_oplus \
-b lineage-23.1 hardware/oplusccache is a compiler cache. On your second and subsequent builds, it can cut build time by 50–70% by reusing previously compiled objects. Set it up before your first build so it starts warming on the very first run.
export USE_CCACHE=1
export CCACHE_EXEC=/usr/bin/ccache
ccache -M 50GTo make these persistent across terminal sessions, add them to ~/.profile:
echo 'export USE_CCACHE=1' >> ~/.profile
echo 'export CCACHE_EXEC=/usr/bin/ccache' >> ~/.profile
source ~/.profile50 GB is a reasonable cache size for a single device. If you're building for multiple devices, consider increasing it to 100 GB. ccache uses space lazily — it won't allocate 50 GB immediately, only as the cache fills.
Check your cache statistics at any time:
ccache -scd ~/android
source build/envsetup.sh
breakfast guacamoleb
croot
brunch guacamoleb | tee log.txtWhat each command does:
| Command | Purpose |
|---|---|
source build/envsetup.sh |
Loads Android build functions (lunch, brunch, croot, etc.) into your shell |
breakfast guacamoleb |
Configures the build environment for your specific device (calls lunch under the hood) |
croot |
Changes directory to the root of your source tree — important if you've navigated elsewhere |
brunch guacamoleb |
Runs the full build: compiles everything and assembles the flashable zip |
| ` | tee log.txt` |
Your first build will take anywhere from 1 to 5 hours depending on your hardware. This is normal.
After the first build, you don't need to set ccache again:
source build/envsetup.sh
breakfast guacamoleb
croot
brunch guacamoleb | tee log.txtWith a warm ccache, subsequent builds typically complete in 20–60 minutes.
The built ROM will be in:
~/android/out/target/product/guacamoleb/
Look for a file named something like lineage-*.zip. That's your flashable image.
To pull in the latest upstream changes from LineageOS:
cd ~/android
repo sync -c -j$(nproc --all) --force-sync --no-clone-bundle --no-tagsAfter syncing, you'll usually want to do a dirty build rather than a full clean build:
source build/envsetup.sh
breakfast guacamoleb
croot
make installclean
brunch guacamoleb | tee log.txtOnly run make clobber if you suspect something is fundamentally broken, or after major tree-level changes (like a branch switch or major component update). A full clean build throws away all cached work.
| Command | What it removes | When to use it |
|---|---|---|
make installclean |
Installed files only; keeps compiled objects | After most updates — faster rebuild |
make clobber |
Everything in out/ |
After major changes, branch switches, or mysterious failures |
ccache -C |
All ccache entries | Only if you suspect cache corruption |
Android build jobs run in parallel and can exhaust RAM. Add a swap file:
sudo fallocate -l 32G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfileTo make it permanent across reboots, add this line to /etc/fstab:
/swapfile none swap sw 0 0
You can also reduce parallelism. By default brunch uses all cores. Override it:
make -j4 baconNetwork interruptions are common during a large sync. Simply re-run the sync command — it picks up where it left off. If a specific repository is consistently failing, try with fewer threads:
repo sync -c -j4 --force-sync --no-clone-bundle --no-tagsThe build will fail with cryptic errors if the JDK isn't 17. Check what's active:
java -version
update-java-alternatives --listSwitch if needed:
sudo update-alternatives --config java
# Select the entry for java-17-openjdkSome build scripts call python (Python 2 style). The python-is-python3 package you installed handles this, but verify:
python --version
# Should report Python 3.x.xLook at the last few lines of log.txt — Ninja errors typically point to the real failure above them. Search for FAILED: in the log:
grep -n "FAILED:" log.txt | tail -20Then look at the lines around the first FAILED: entry for the actual error.
adb devices
fastboot devicesIf nothing shows:
- Ensure USB Debugging is enabled on the phone (Settings → Developer Options → USB Debugging)
- Accept the RSA key prompt on your phone if one appears
- Try a different cable (use a data cable, not a charge-only cable)
- Try a different USB port (USB 2.0 ports can sometimes work better than USB 3.0 for older devices)
- Run
lsusbto confirm the OS sees the device at all
After everything is in place, your source tree should look roughly like this:
~/android/
├── art/ # Android Runtime (ART)
├── bionic/ # C library, math, and dynamic linker
├── build/ # Build system (Soong, Make)
├── device/
│ └── oneplus/
│ ├── guacamoleb/ # Device tree (your clone)
│ └── sm8150-common/ # Platform-common device tree (your clone)
├── frameworks/ # Android framework (Java APIs)
├── hardware/
│ └── oplus/ # Hardware abstraction (your clone)
├── kernel/
│ └── oneplus/
│ └── sm8150/ # Kernel source (your clone)
├── out/ # Build output (generated during build)
├── packages/ # System apps
├── vendor/
│ └── oneplus/
│ ├── guacamoleb/ # Device vendor blobs (your clone)
│ └── sm8150-common/ # Platform vendor blobs (your clone)
└── ...
The build system ingests all of this and produces a single flashable image. The device tree is the glue that tells the build system which kernel, which blobs, and which feature flags to use.
- Use
repo syncregularly. LineageOS is actively developed. Weekly syncs keep you current. - Don't edit files in the source tree directly unless you intend to maintain a patch. Changes will be overwritten on the next sync. Use proper Android patch management (topic branches +
repo upload) if you want to contribute upstream. - Monitor your disk. The
out/directory grows with every build.make clobberreclaims it when needed. - Save your
log.txtfiles. When asking for help in forums or Telegram groups, a build log is essential context. The LineageOS Telegram and XDA thread for guacamoleb are good resources. - Check the LineageOS wiki for guacamoleb — device-specific guidance there applies here too.
- Shantanu Sarkar — original guide
- LineageOS — upstream base
- Akhil Narang — build environment scripts
- TheMuppets — vendor blob repositories