Build Guide

Introduction

You want to build for yourself? Awesome!
First things first, you're going to need a pretty decent computer if you want timely builds.

  • For builds under 3 hours you'll want to have at least a powerful quad core processor, 32GB of RAM, and a 7200RPM drive.
  • For builds under an hour you'll want to have a processor that gets a score of 30k+ or higher on Passmark, 64GB of RAM, and a large SSD.
  • Note: CFI enabled kernels will fail to compile with less than 64GB of RAM.
  • It may be possible to get by with 16GB + zram, regardless zram is recommended in all cases.
  • If you plan on building in a virtual machine, in terms of performance: KVM > Hyper-V > VMWare > VirtualBox
  • You'll need a lot of available free space on your drives
    • Source Code: 200GB + ~5GB per device
    • ~100GB per device for building
    • ~10GB per device for optional ccache
    • ~4GB for each resulting build
    • ~10GB for two target-files for a device to optionally generate incremental updates
    • Cheap: ~$60 2TB 7200RPM HDD (non-SMR)
    • Fast: ~$150 2TB SSD (MLC/"enterprise" preferred)
    • If you plan on having multiple versions available btrfs+zstd:1+duperemove is strongly recommended.

Second you'll want to have a fast Internet connection to download the source code and OS dependencies, 100Mbps is recommended.
Lastly you'll need to have an excellent cooling solution, your computer will be running at full load for quite some time.
There is a video of this process from start to finish here.

Installing Dependencies

Run the few commands below to get your system up to date and install all necessary dependencies. Of note the DivestOS build scripts are only tested on Fedora.

On Fedora Workstation/Server (strongly recommended)

The latest Fedora release is recommended.

sudo dnf update;
sudo dnf install @development-tools android-tools automake bc bison bzip2 bzip2-libs ccache curl dpkg-dev flex gcc gcc-c++ git git-lfs glibc-devel.{x86_64,i686} gnupg gperf ImageMagick ImageMagick-c++-devel ImageMagick-devel java-1.8.0-openjdk java-1.8.0-openjdk-devel libgcc.{x86_64,i686} libstdc++.{x86_64,i686} libX11-devel.{x86_64,i686} libxml2-devel libXrandr.{x86_64,i686} libXrender.{x86_64,i686} libxslt lz4-libs lzop make maven mesa-libGL-devel.{x86_64,i686} ncurses ncurses-compat-libs ncurses-devel.{x86_64,i686} ninja-build openssl-devel optipng jpegoptim perl-Digest-MD5-File perl-Switch pngcrush python python3-virtualenv python3 python3-mako python-mako python-markdown python-networkx readline-devel.{x86_64,i686} rsync schedtool SDL squashfs-tools syslinux-devel unzip wxGTK xml2 xz-lzma-compat zip zlib zlib-devel.{x86_64,i686} vim-common vboot-utils mozilla-fira-mono-fonts mozilla-fira-sans-fonts openssl1.1 nano htop;
mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo >> ~/bin/repo;
chmod a+x ~/bin/repo;
sudo ln -sf /usr/share/crypto-policies/LEGACY/java.txt /etc/crypto-policies/back-ends/java.config;

On Arch Linux (not recommended)

@p4block has created a handy metapackage for installing the necessary dependencies, use your favorite AUR helper to install it. There is also a more minimal one included in our build repository that you can install with makepkg.

sudo pacman -Syu;
aurman -S lineageos-devel firejail ttf-fira-mono ttf-fira-sans nano htop;
sudo paccache -rk0;

On Ubuntu (not recommended)

Ubuntu 18.04 is recommended, newer should work fine with little change.

sudo apt update && sudo apt upgrade && sudo apt full-upgrade && sudo apt -f install && sudo apt autoremove;
sudo ln -s /usr/include/asm-generic /usr/include/asm;
sudo apt install autoconf automake bc bison build-essential ccache curl expat flex g++ gawk gcc gcc-multilib git-core git-lfs g++-multilib gnupg gperf lib32ncurses5-dev lib32z1-dev lib32z-dev libc6-dev libc6-dev-i386 libcap-dev libcloog-isl-dev libesd0-dev libexpat1-dev libgcc1:i386 libgl1-mesa-dev libgmp-dev libmpc-dev libmpfr-dev libncurses5-dev libsdl1.2-dev libtool libx11-dev libxml2 libxml2-utils lzop maven ncurses-dev openjdk-8-jdk patch pkg-config pngcrush python-all-dev schedtool squashfs-tools subversion texinfo unzip x11proto-core-dev xsltproc zip zlib1g-dev imagemagick repo firejail optipng jpegoptim nano htop;
sudo apt clean;

Creating a Workspace

Setting up Firejail (optional)

For extra security of your host machine, you can run the entire build process in a fairly restricted sandbox with minimal performance impact. We've already upstreamed a profile for just this task.

echo 'if [ $container="firejail" ]; then unset PROMPT_COMMAND; fi;' >> .bashrc;
firejail --profile=/etc/firejail/aosp.profile bash;

Checking out the code

Okay, now you'll want to create the workspace. This is highly recommended to be on a separate drive from your system drive. Bash or a similar shell is required.

umask 0022; #correctness
#Git setup
git config --global user.name "Your Name";
git config --global user.email "you@example.com";
#Clone
git clone https://gitlab.com/divested-mobile/divestos-build.git DivestOS;
cd DivestOS;
#Submodules
sed -i 's|git@gitlab.com:|https://gitlab.com/|' .git/config .gitmodules; #Fixup
git submodule update --init --recursive; #Must have git-lfs installed
#Basic directories
mkdir -p Build/LineageOS-20.0/.repo/local_manifests Builds Signing_Keys .Signing_Keys;
#Encrypted key storage
gocryptfs -init .Signing_Keys; #Create the vault
gocryptfs .Signing_Keys/ Signing_Keys/; #Mount the vault
#Update settings
nano Scripts/init.sh; #Choose your options and update paths
nano Scripts/Generate_Signing_Keys.sh; #Update description
cd Build/LineageOS-20.0;
#Add the initial manifest
cat ../../Manifests/Manifest_LAOS-20.0.xml > .repo/local_manifests/local_manifest.xml;
#Add the vendor blobs!
##You must find these repos yourself. Extracting them is NOT correct.
##20.0 changed from per-vendor to per-device.
nano .repo/local_manifests/local_manifest.xml;
#Download!
repo init -u https://github.com/LineageOS/android.git -b lineage-20.0 --git-lfs;
repo sync; #This part will take a while
#Some systems have python3 set as default, the build scripts require python2
virtualenv venv --python=python2; #Not necessary for 20.0 and higher
#Generate signing keys
source ../../Scripts/init.sh;
awk -i inplace '!/enforce-product-packages-exist-internal/' vendor/lineage/config/common.mk; #Workaround for 20.0+ only
source build/envsetup.sh && breakfast lineage_sailfish-user && make -j20 generate_verity_key; #Edit device if not available, can be any
sh ../../Scripts/Generate_Signing_Keys.sh $device; #Repeat as needed for other devices
mv -nv $DOS_SIGNING_KEYS/NEW/* "$DOS_SIGNING_KEYS/"; #Move the new keys into place
#TODO: document how to include firmware
#TODO: document openssl1.1 requirement for avb signing?

Setting up ccache (Optional)

Use of ccache is highly recommended, it's an easy way to dramatically reduce build time and power usage. This is extremely recommended to be on a separate drive from your system drive and your build drive.

mkdir ccache; #Pick a place
echo "export USE_CCACHE=1;" >> ~/.bashrc;
echo "export CCACHE_COMPRESS=1;" >> ~/.bashrc;
echo "export CCACHE_COMPRESSLEVEL=1;" >> ~/.bashrc;
echo "export CCACHE_EXEC=/usr/bin/ccache;" >> ~/.bashrc;
echo "export CCACHE_DIR=[PATH TO CCACHE DIRECTORY];" >> ~/.bashrc; #The place you chose
source ~/.bashrc;
ccache -M 128GB; #Optionally set a size limit

About the Workspace

You should become familiar with the workspace.

  • /Build - This is where source code and working directory is stored
  • /Builds - This is where signed release builds are copied to
  • /Manifests - This is where working repo manifests are stored
  • /Misc - This is for storing misc. snippets of anything
  • /Patches - This is where all repo patches are stored
  • /Scripts - This is where all scripts are stored
  • /Signing_Keys - This is the default signing key store, it's recommended to store these using gocryptfs or similar.

Building

Now that you've got your workspace ready, lets make an image. Use of bash is required, and you may need to use a Python virtualenv.

cd Build/LineageOS-20.0;
source venv/bin/activate; #Only for python3 default systems, not needed for 18.1 and higher
source ../../Scripts/init.sh;
#Undo any previous changes
resetWorkspace;
rm -rf packages/apps/Fennec_DOS-Shim/ vendor/divested/ vendor/fdroid_prebuilt/ packages/apps/SupportDivestOS/; #Remove remenants
rm -rf out; #Remove the last build, keep to speedup builds at cost of cruft
#Apply the changes
patchWorkspace;
#Verify the changes applied
##There should be nine `[SCRIPT COMPLETE]` lines on 15.1 through 20.0 and ten on 14.1
##Check output for keywords like: err, fatal, fail, cannot, no such file, already applied, 3way, skip
##Check output for yellow or red text
##Real example outputs will be provided in the future
#Compile!
buildDevice [device]; #or buildAll for all supported devices

Afterwards you should have flashable zips located in $DOS_BUILDS

Installing

Follow the appropriate steps for your device listed here.