LineageOS is a free and open-source Android distribution. To port LineageOS to a new device, to add a kernel module such as WireGuard, or to make your own version, you need to setup a build environment.
Android is composed of a multitude of software, with a build process tested on Ubuntu. If you do not use Ubuntu as your main distribution, you can still build Android inside a container. systemd-nspawn is a container runtime shipped with systemd. This tutorial explains how to setup a LineageOS build environment in a systemd-nspawn container.
I encourage you to consult the LineageOS wiki alongside this article. The references to the wiki point to the Google Pixel XL pages, code name marlin, but the instructions for all the devices are based on a common template.
§Prerequisites
Building Android requires a decent machine and network connection:
- RAM: at least 8 GB (along with some swap space).
- Storage: around 200 GiB (including the source code, cache, and output files).
- Network: approximately 30 GB of data for the initial download.
The last resource you need is a lot of time. The first download and build are unbearably long (as in hours, or even days with a slow network connection). Subsequent builds are much quicker.
§Setup the build environment
The LineageOS developers recommend Ubuntu 20.04 LTS (Focal Fossa). The system is installed inside a systemd-nspawn container. The purpose is to keep a clean build environment, separate from your main system, while avoiding the overhead associated with virtual machines.
§Install Ubuntu
You need debootstrap to install the base system, and optionally the Ubuntu archive keyring so it can verify package signatures. On Arch Linux, they can be installed with the following command:
Then, you can bootstrap the base system in /var/lib/machines/ubuntu
(but you
can choose any other directory for this tutorial):
Once installed, you can start the machine:
Use the --bind
option to mount the cache and build directories from
another location on the host:
This is useful if you have a secondary hard drive with more available space.
§Install the build dependencies
debootstrap only adds the main Ubuntu repository. To get access to all the
required packages, you need to add the focal-updates and focal-security
repositories and the universe branch to APT's sources.list
configuration
file:
You can now run the upgrade procedure:
Finally, install the LineageOS build dependencies:
§Add an unprivileged user
Since building things as root is not recommanded, create an unpriviliedged user:
No need to set any password since you can log into this account from root:
§Install ccache
ccache helps to speed up the build time thanks to a cache. Start by increasing its maximum size to 50 GB:
Then, set USE_CCACHE=1
in ~/.bashrc
:
§Download the LineageOS source files
repo downloads and manages the hundreds git repositories required to build LineageOS.
§Install repo
Create the directory for the user's local binaries:
Download repo and make it executable:
To use repo, you need to set a git name and email:
§Fetch the source code
Create the source directory:
Next, initialize the repository (specify a valid branch for your device, e.g.,
lineage-17.1
):
Finally, you can download the source files (this may take a while):
repo automatically fetches its latest version, so you can replace the previous binary with a symlink to it:
§Download the device-specific source files
The first step is to source the build environment, which includes the main
commands for the build process (such as breakfast
and brunch
):
You can now download the device-specific source files, including the kernel
(replace marlin
with your device code name):
If you encounter an error, continue to the next section to extract the
proprietary blobs. Then, you should be able to run breakfast
again without
errors.
§Extract the proprietary blobs
If you already have LineageOS installed on your device, you can extract the
blobs from it. Install the Android platform
tools, connect
the device to your computer through ADB, and run the following command (replace
google/marlin
with the device path):
If you do not have LineageOS installed on your device, then you will have to follow the instructions for extracting proprietary binary blobs from the installation zip.
§Build the system image
If you encountered an error the first time you ran breakfast
, run it again:
With the minimum system requirements of 8 GB of RAM + 8 GB of SWAP, the build process may stay stuck for hours on some Metalava documentation targets until it finally runs out of heap memory:
The solution is to increase the Java heap size and to build the offending targets sequentially:
Then you can continue with brunch
.
Close uneeded application to free up some RAM and start the build (this may take a while):
If you encounter an error with resize2fs
not being able to open
/etc/mtab
, create the following symlink before restarting the build:
If the build succeeded, you can head to the output directory:
You will find the following files:
boot.img
: the boot image (kernel, ramdisk).lineage-17.1-202XXXXX-UNOFFICIAL-<DEVICE>.zip
: the system installation package.