Advanced phone customization/Building your own ROM
Building your ROM is one of the most rewarding experiences you can have. Imagine having your own version of Android on your own phone!
We'll take the popular custom OS LineageOS as a guiding reference.
What you'll need
[edit | edit source]- The phone which you need to develop.
- A relatively recent 64-bit computer (Linux, OS X, or Windows) with a reasonable amount of RAM and about 100 GB of free storage (more if you enable
ccache
or build for multiple devices). The less RAM you have, the longer the build will take (aim for 8 GB or more). Using SSDs results in considerably faster build times than traditional hard drives. - A USB cable compatible with your phone.
- A decent internet connection and reliable electricity :)
- Some familiarity with basic Android operation and terminology. It would help if you’ve installed custom roms on other devices and are familiar with recovery. It may also be useful to know some basic command line concepts such as
cd
, which stands for “change directory”, the concept of directory hierarchies, and that in Linux they are separated by /, etc.
Build LineageOS and LineageOS Recovery
[edit | edit source]Install the Android SDK
[edit | edit source]If you haven’t previously installed adb
and fastboot
, you can download them from Google. Extract it running:
unzip platform-tools-latest-linux.zip -d ~
Now you have to add adb
and fastboot
to your PATH. Open ~/.profile
and add the following:
# add Android SDK platform tools to path
if [ -d "$HOME/platform-tools" ] ; then
PATH="$HOME/platform-tools:$PATH"
fi
Then, run source ~/.profile
to update your environment.
Install the build packages
[edit | edit source]Several packages are needed to build LineageOS. You can install these using your distribution’s package manager.
In arch linux you can install all the needed packages by installing lineageos-devel
from the AUR.
To build LineageOS, you'll need
bc bison build-essential ccache curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libwxgtk3.0-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev
(take libwxgtk2.8-dev
instead of libwxgtk3.0-dev
if you're on older than Ubuntu 16.04)
(libwxgtk3.0-dev
Was changed to libwxgtk3.0-gtk3-dev
in Ubuntu 20.04)
You'll also need Java. Different versions of LineageOS require different JDK (Java Development Kit) versions.
- LineageOS 14.1-15.1: OpenJDK 1.8 (install
openjdk-8-jdk
) - LineageOS 11.0-13.0: OpenJDK 1.7 (install
openjdk-7-jdk
)*
* Ubuntu 16.04 and newer do not have OpenJDK 1.7 in the standard package repositories. See the Ask Ubuntu question “How do I install openjdk 7 on Ubuntu 16.04 or higher?”. Note that the suggestion to use PPA openjdk-r is outdated (the PPA has never updated their offering of openjdk-7-jdk, so it lacks security fixes); skip that answer even if it is the most upvoted.
Create the directories
[edit | edit source]You’ll need to set up some directories in your build environment.
To create them:
mkdir -p ~/bin
mkdir -p ~/android/lineage
The ~/bin
directory will contain the git-repo tool (commonly named “repo”) and the ~/android/lineage
directory will contain the source code of LineageOS.
Install the repo command
[edit | edit source]Enter the following to download the repo binary and make it executable (runnable):
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
Put the ~/bin
directory in your path of execution
[edit | edit source]In recent versions of Ubuntu, ~/bin
should already be in your PATH. You can check this by opening ~/.profile
with a text editor and verifying the following code exists (add it if it is missing):
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
Then, run source ~/.profile
to update your environment.
In arch linux do the same but name the file ~/.bashrc
Initialize the LineageOS source repository
[edit | edit source]Enter the following to initialize the repository:
cd ~/android/lineage
repo init -u https://github.com/LineageOS/android.git -b lineage-X --git-lfs
where X
is the LineageOS version supported by your device.
You need to initialize git for this to work:
git config --global user.name "abc"
git config --global user.email "abc@example.com"
Download the source code
[edit | edit source]To start the download of the source code to your computer, type repo sync
.
The LineageOS manifests include a sensible default configuration for repo, which we strongly suggest you use (i.e. don’t add any options to sync). For reference, our default values are -j 4
and -c
. The -j 4
part means that there will be four simultaneous threads/connections. If you experience problems syncing, you can lower this to -j 3
or -j 2
. On the other hand, -c
will ask repo to pull in only the current branch instead of all branches that are available on GitHub.
Prepare the device-specific code
[edit | edit source]This depends on your device.
Turn on caching to speed up build
[edit | edit source]Make use of ccache
if you want to speed up subsequent builds by running:
export USE_CCACHE=1
and adding that line to your ~/.bashrc
file. Then, specify the maximum amount of disk space you want ccache
to use by typing this:
ccache -M 50G
where 50G
corresponds to 50GB of cache. This needs to be run once. Anywhere from 25GB-100GB will result in very noticeably increased build speeds (for instance, a typical 1hr build time can be reduced to 20min). If you’re only building for one device, 25GB-50GB is fine. If you plan to build for several devices that do not share the same kernel source, aim for 75GB-100GB. This space will be permanently occupied on your drive, so take this into consideration. See more information about ccache on Google’s Android build environment initialization page.
You can also enable the optional ccache
compression. While this may involve a slight performance slowdown, it increases the number of files that fit in the cache. To enable it, run:
export CCACHE_COMPRESS=1
or add that line to your ~/.bashrc
file.
Build it!
[edit | edit source]Type source ./build/envsetup.sh
Type hmm
to get the help text, currently (2020-11-16):
Run "m help" for help with the build system itself. Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment: - lunch: lunch <product_name>-<build_variant> Selects <product_name> as the product to build, and <build_variant> as the variant to build, and stores those selections in the environment to be read by subsequent invocations of 'm' etc. - tapas: tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user] - croot: Changes directory to the top of the tree, or a subdirectory thereof. - m: Makes from the top of the tree. - mm: Builds all of the modules in the current directory, but not their dependencies. - mmm: Builds all of the modules in the supplied directories, but not their dependencies. To limit the modules being built use the syntax: mmm dir/:target1,target2. - mma: Builds all of the modules in the current directory, and their dependencies. - mmma: Builds all of the modules in the supplied directories, and their dependencies. - provision: Flash device with all required partitions. Options will be passed on to fastboot. - cgrep: Greps on all local C/C++ files. - ggrep: Greps on all local Gradle files. - jgrep: Greps on all local Java files. - resgrep: Greps on all local res/*.xml files. - mangrep: Greps on all local AndroidManifest.xml files. - mgrep: Greps on all local Makefiles files. - sepgrep: Greps on all local sepolicy files. - sgrep: Greps on all local source files. - godir: Go to the directory containing a file. - allmod: List all modules. - gomod: Go to the directory containing a module. - pathmod: Get the directory containing a module. - refreshmod: Refresh list of modules for allmod/gomod. .... (there's more, omitted for brevity) ...
Running m help
outputs:
# m help The basic Android build process is: cd /mnt/aosp/lineage source build/envsetup.sh # Add "lunch" (and other utilities and variables) # to the shell environment. lunch [<product>-<variant>] # Choose the device to target. m -j [<goals>] # Execute the configured build. Usage of "m" imitates usage of the program "make". See /mnt/aosp/lineage/build/make/Usage.txt for more info about build usage and concepts. Common goals are: clean (aka clobber) equivalent to rm -rf out/ checkbuild Build every module defined in the source tree droid Default target nothing Do not build anything, just parse and validate the build structure java Build all the java code in the source tree native Build all the native code in the source tree host Build all the host code (not to be run on a device) in the source tree target Build all the target code (to be run on the device) in the source tree (java|native)-(host|target) (host|target)-(java|native) Build the intersection of the two given arguments snod Quickly rebuild the system image from built packages Stands for "System, NO Dependencies" vnod Quickly rebuild the vendor image from built packages Stands for "Vendor, NO Dependencies" pnod Quickly rebuild the product image from built packages Stands for "Product, NO Dependencies" psnod Quickly rebuild the product_services image from built packages Stands for "ProductServices, NO Dependencies" onod Quickly rebuild the odm image from built packages Stands for "ODM, NO Dependencies" So, for example, you could run: cd /mnt/aosp/lineage source build/envsetup.sh lunch aosp_arm-userdebug m -j java to build all of the java code for the userdebug variant of the aosp_arm device. #### build completed successfully (16 seconds) ####
Install the build
[edit | edit source]Assuming the build completed without errors (it will be obvious when it finishes), type the following in the terminal window the build ran in:
cd $OUT
There you’ll find all the files that were created. The two files of more interest are:
recovery.img
, which is the LineageOS recovery image.lineage-14.1-20180808-UNOFFICIAL-a5y17lte.zip
, which is the LineageOS installer package. This will vary depending on your phone and version.
And that's it! You can use your ROM as any other custom ROM that you'll download off the internet.
References
[edit | edit source]This article was taken mainly from LineageOS's wiki.