LineageOS is a popular and highly customizable open-source operating system for mobile devices, often considered a great alternative to stock firmware. It’s the foundation for many other custom ROMs, showcasing its versatility and widespread adoption. However, only the latest few versions are officially available for download. For older or less common devices, users often need to build it themselves, which requires some technical expertise. Therefore, I setup a Docker image to build LineageOS from stratch.
Requirements #
- Docker
- At least 300GB free disk space
Build #
Prepare the image #
Note: It has to be Ubuntu 20.04, as there seems to be breaking changes in some of the build tools when I tried with Ubuntu 22+.
FROM ubuntu:20.04
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
bc bison build-essential ccache curl flex g++-multilib gcc-multilib git git-lfs \
gnupg gperf imagemagick lib32readline-dev lib32z1-dev libelf-dev liblz4-tool libsdl1.2-dev \
libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev \
lib32ncurses5-dev libncurses5 libncurses5-dev
RUN curl -L -o platform-tools.zip https://dl.google.com/android/repository/platform-tools-latest-linux.zip \
&& unzip platform-tools.zip -d /opt \
&& ln -sf /opt/platform-tools/adb /usr/local/bin/adb \
&& ln -sf /opt/platform-tools/fastboot /usr/local/bin/fastboot \
&& rm platform-tools.zip
RUN curl https://storage.googleapis.com/git-repo-downloads/repo > /usr/local/bin/repo \
&& chmod a+x /usr/local/bin/repo \
&& ln -sf `which python3` /usr/local/bin/python
RUN DEBIAN_FRONTEND=noninteractive \
apt-get install -y python3-protobuf python3-six vim
Run the image #
The image should have all the tools required for initializing and building Lineage repositories.
Note: replace <image_name>
, optionally for Git committer information.
docker run --rm -it \
-e "USE_CCACHE=1" \
-e "CCACHE_EXEC=/usr/bin/ccache" \
-e "CCACHE_DIR=/ccache" \
-e "CCACHE_MAXSIZE=50G" \
-e "CCACHE_COMPRESS=1" \
-e "CCACHE_COMPRESSLEVEL=0" \
-e "GIT_COMMITTER_NAME=Sam" \
-e "GIT_COMMITTER_EMAIL=dev@ahxshum.com" \
-e "EDITOR=vim" \
-e "WITH_GMS=true" \
-v "$PWD/.data/ccache:/ccache" \
-v "$PWD:$PWD" \
-w "$PWD" \
--privileged \
<image_name> bash
Download the source code #
As I was building v18, replace the branch to the version you are looking for.
repo init -u https://github.com/LineageOS/android.git -b lineage-18.1 --git-lfs
repo sync
Device-specific code #
You will need to find the code name of the device at https://wiki.lineageos.org/devices/
For me I was building for OnePlus 8T, which the code name is kebab
.
source build/envsetup.sh
breakfast kebab
Extract proprietary blobs #
This may not be straight forward if you’re upgrading or downgrading. For kebab
, I have to download the OxygenOS of OnePlus 8 Pro for the shared blobs and that of OnePlus 8T for the rest.
Once you got the official build, extract the blobs.
git clone https://github.com/LineageOS/android_tools_extract-utils android/tools/extract-utils
git clone https://github.com/LineageOS/android_system_update_engine android/system/update_engine
python3 android/tools/extract-utils/extract_ota.py path/to/oxygen.zip
mkdir system
mount -o ro system.img system/
mount -o ro vendor.img system/vendor/
mount -o ro odm.img system/odm/
mount -o ro product.img system/product/
mount -o ro system_ext.img system/system_ext/
cd device/oneplus/kebab
./extract-files.sh dump/system/
umount -R -l system/
Start building #
croot
brunch kebab
Install #
This is specifically for kebab
. Steps may be varied for a different device.
Update firmware #
fastboot flash --slot=all abl abl.img
fastboot flash --slot=all aop aop.img
fastboot flash --slot=all bluetooth bluetooth.img
fastboot flash --slot=all cmnlib64 cmnlib64.img
fastboot flash --slot=all cmnlib cmnlib.img
fastboot flash --slot=all devcfg devcfg.img
fastboot flash --slot=all dsp dsp.img
fastboot flash --slot=all featenabler featenabler.img
fastboot flash --slot=all hyp hyp.img
fastboot flash --slot=all imagefv imagefv.img
fastboot flash --slot=all keymaster keymaster.img
fastboot flash --slot=all logo logo.img
fastboot flash --slot=all mdm_oem_stanvbk mdm_oem_stanvbk.img
fastboot flash --slot=all modem modem.img
fastboot flash --slot=all multiimgoem multiimgoem.img
fastboot flash --slot=all qupfw qupfw.img
fastboot flash --slot=all spunvm spunvm.img
fastboot flash --slot=all storsec storsec.img
fastboot flash --slot=all tz tz.img
fastboot flash --slot=all uefisecapp uefisecapp.img
# check ddr type
adb shell getprop ro.boot.ddr_type
# if 0
fastboot flash --slot=all xbl_config xbl_config.img
fastboot flash --slot=all xbl xbl.img
# if 1
fastboot flash --slot=all xbl_config xbl_config_lp5.img
fastboot flash --slot=all xbl xbl_lp5.img
Start flashing #
fastboot flash dtbo dtbo.img
fastboot flash vbmeta vbmeta.img
fastboot flash recovery recovery.img
adb sideload copy-partitions-20220613-signed.zip
adb sideload lineageos.zip
adb sideload mindthegapps.zip
adb sideload magisk.zip
Note #
Signing builds #
As the device is not primary device, I didn’t go through the signing process. However it is always a good practice to signing builds before installing as this ensures the security and integrity of the application or system.