Building Android from source seems like a daunting task at first, but it’s really not that hard. I’ll walk through the steps as simply as possible to get your first AOSP build running on your handset. This is a rite of passage for many, and guaranteed to give insights on the inner workings of Android. First, let’s do a few push-ups and jumping jacks to mentally and physically prepare for the journey, and at the end of it, you’d wonder why you even had to do that.
What you need:
- A 64-bit environment
- ~150 GB of disk space
- A working Linux installation (I use Debian, but take your pick). I suggest going with bare metal over virtual machines in the interest of sanity and general well being
- A decent broadband connection (to download a significant portion of the internet)
- Some time and patience
- A healthy belief in the supernatural, and their inevitable involvement in the building of large complex codebases
Everything you need to know about the process is right here. Feel free to skimp through these docs first to get an overview of the entire process. What’s below is mostly a summary + a few things not explicitly mentioned that would stump the newbies.
Step 1
Prep your OS and install any dependencies. At the minimum you’re going to need java, python, C/C++, make, and git so make sure they’re installed using your favorite package manager. If you’re on Debian/Ubuntu, you’d run something similar to below:
sudo apt-get install openjdk-8-jdk git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip
If you find that you need something else down the line that’s not mentioned above, be a man/woman, and just apt-get it. Also, your package names may vary depending on your choice of distribution.
Run the commands manually to do a quick sanity test that things are installed properly.
Step 2
Linux may require some configuration to udev to allow non-root users to work with USB devices, which is going to be required later on, so execute this command:
wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules
Step 3 (Optional)
Setup ccache to get extract some performance out of the build, by putting the following into your .bashrc:
export USE_CCACHE=1
export CCACHE_DIR=/path/to/empty/ccache/directory/where/cache/is/kept
Set the cache size to 50G using the following:
prebuilts/misc/linux-x86/ccache/ccache -M 50G
Step 4
The Android Open Source Project is a behemoth of a code base with multiple third party open source components and frameworks included such that it required its own layer on top of git just to manage the dependencies. That’s what repo is. On the positive side, it’s quite easy to get it working.
Download the repo tool to your ~/bin directory as follows:
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
Make sure that ~/bin is in your $PATH. Type repo a few times and watch it barf in your face while saying:
error: repo is not installed. Use "repo init" to install it here.
Do not fret, this is normal.
You see, you have to initialize repo and give it a manifest which will tell repo where to download the source from and help it initialize itself. You do this by navigating to an empty directory and executing:
repo init -u https://android.googlesource.com/platform/manifest
If you do not specify a branch name with -b parameter, it will fetch the master branch, which is what we’re going to do here.
You should now see an empty directory, apart from a .repo with the metadata that it downloaded from the manifest file. Now I’m assuming that you’re probably at home and do not have complicated proxy arrangements to get to the internet so I’m going to avoid talking about the HTTP_PROXY environment variable that you have to set if you do, but I guess it’s all redundant now that I’ve already said it, so I’m just going to move on:
repo sync
This will download the internet. This will run for an inordinate amount of time. A few things you can do while this executes:
- knit
- write a book
- have kids
- watch the poles melt
A rough approximation, and the internet is very divided on this topic, is that it will require anywhere from 12 to 15 GB which will automatically expand to around 34GB on disk after it’s downloaded. In my experience, I’ve only been awake till about the 13GB mark, so didn’t quite get to see the transformation to its final glory. Add 50GB for the ccache and with some room to spare and you see why you need a lot of disk space to go through this.
Now you wait.
Step 5
In my case, I needed to run the build on my Nexus 5. The AOSP source tree doesn’t have everything you need to build images specifically for Nexus 5, so I had to go to this link, scroll down to Nexus 5 and download the Broadcom, LG and Qualcomm binary blobs for the hardware on the Nexus 5. Put them in the root of the Android source tree, and execute it, where it self extracts. This is a needed step if you want to run the image on the device later on.
Step 6
Now comes the compilation step. This is actually the easiest part.
Initialize the build environment by sourcing a script, you can use the bash source command or the good old dot command — whatever strikes your fancy:. build/envsetup.sh
This will inject a bunch of build related environment variables to your current shell. Note that you have to run this in every shell that you want to run a build from.
Next…
lunch
This will give a list of targets and allow you to select one. In my case, I selected “aosp_hammerhead-userdebug”. Hammerhead being the code name for the Nexus 5.
One more step, and that’s to start the build.time make -j4
You could easily just say “make”, but I would like to know how long the build took when it eventually finished running, and with the -j4 flag indicate the concurrency level for make (rule of thumb: 2 x number of cores). Now you can go for lunch.
Things to do while this runs:
- Read Game of Thrones (all the books)
- Have a fabulous mid-life crisis
- Watch Lawrence of Arabia
To be fair, it’s not that bad, just a few hours depending on your setup.
Step 7
Once the building is done, you will have a bunch of files under out/target/product/{device} which you can now start flashing.
Connect your Android phone to the computer and assuming that all the drivers and Android SDK is setup (a dependency that I somehow failed to mention before), you should be able to run the following command:
adb reboot bootloader
This can also be achieved by shutting down the device and starting it while pressing a combination of buttons (such as volume down + power on the Nexus 5). This would put you into fastboot mode. On the fastboot screen, pay attention to whether the bootloader is locked or not, if it is, execute the following to unlock it:fastboot oem unlock
This would wipe the data on the device. To further clean things up, execute the following:
fastboot format cache
fastboot format userdata
Step 8
Navigate once again to the out/target/product/{device} directory and execute the following to flash the built images to the device:
fastboot flash boot boot.img
fastboot flash system system.img
fastboot flash userdata userdata.img
fastboot flash recovery recovery.img
Reboot the device and you’re all set.
This is just the tip of the iceberg, and hopefully you’ll be able to now play with the internals of Android to understand how things are really stitched together. Good luck on your journey.
Building Android from source seems like a daunting task at first, but it’s really not that hard. I’ll walk through the steps as simply as possible to get your first AOSP build running on your handset. This is a rite of passage for many, and guaranteed to give insights on the inner workings of Android. First, let’s do a few push-ups and jumping jacks to mentally and physically prepare for the journey, and at the end of it, you’d wonder why you even had to do that.
What you need:
Everything you need to know about the process is right here. Feel free to skimp through these docs first to get an overview of the entire process. What’s below is mostly a summary + a few things not explicitly mentioned that would stump the newbies.
Step 1
Prep your OS and install any dependencies. At the minimum you’re going to need java, python, C/C++, make, and git so make sure they’re installed using your favorite package manager. If you’re on Debian/Ubuntu, you’d run something similar to below:
If you find that you need something else down the line that’s not mentioned above, be a man/woman, and just apt-get it. Also, your package names may vary depending on your choice of distribution.
Run the commands manually to do a quick sanity test that things are installed properly.
Step 2
Linux may require some configuration to udev to allow non-root users to work with USB devices, which is going to be required later on, so execute this command:
Step 3 (Optional)
Setup ccache to get extract some performance out of the build, by putting the following into your .bashrc:
Set the cache size to 50G using the following:
Step 4
The Android Open Source Project is a behemoth of a code base with multiple third party open source components and frameworks included such that it required its own layer on top of git just to manage the dependencies. That’s what repo is. On the positive side, it’s quite easy to get it working.
Download the repo tool to your ~/bin directory as follows:
Make sure that ~/bin is in your $PATH. Type repo a few times and watch it barf in your face while saying:
Do not fret, this is normal.
You see, you have to initialize repo and give it a manifest which will tell repo where to download the source from and help it initialize itself. You do this by navigating to an empty directory and executing:
If you do not specify a branch name with -b parameter, it will fetch the master branch, which is what we’re going to do here.
You should now see an empty directory, apart from a .repo with the metadata that it downloaded from the manifest file. Now I’m assuming that you’re probably at home and do not have complicated proxy arrangements to get to the internet so I’m going to avoid talking about the HTTP_PROXY environment variable that you have to set if you do, but I guess it’s all redundant now that I’ve already said it, so I’m just going to move on:
This will download the internet. This will run for an inordinate amount of time. A few things you can do while this executes:
A rough approximation, and the internet is very divided on this topic, is that it will require anywhere from 12 to 15 GB which will automatically expand to around 34GB on disk after it’s downloaded. In my experience, I’ve only been awake till about the 13GB mark, so didn’t quite get to see the transformation to its final glory. Add 50GB for the ccache and with some room to spare and you see why you need a lot of disk space to go through this.
Now you wait.
Step 5
In my case, I needed to run the build on my Nexus 5. The AOSP source tree doesn’t have everything you need to build images specifically for Nexus 5, so I had to go to this link, scroll down to Nexus 5 and download the Broadcom, LG and Qualcomm binary blobs for the hardware on the Nexus 5. Put them in the root of the Android source tree, and execute it, where it self extracts. This is a needed step if you want to run the image on the device later on.
Step 6
Now comes the compilation step. This is actually the easiest part.
Initialize the build environment by sourcing a script, you can use the bash source command or the good old dot command — whatever strikes your fancy:. build/envsetup.sh
This will inject a bunch of build related environment variables to your current shell. Note that you have to run this in every shell that you want to run a build from.
Next…
This will give a list of targets and allow you to select one. In my case, I selected “aosp_hammerhead-userdebug”. Hammerhead being the code name for the Nexus 5.
One more step, and that’s to start the build.time make -j4
You could easily just say “make”, but I would like to know how long the build took when it eventually finished running, and with the -j4 flag indicate the concurrency level for make (rule of thumb: 2 x number of cores). Now you can go for lunch.
Things to do while this runs:
To be fair, it’s not that bad, just a few hours depending on your setup.
Step 7
Once the building is done, you will have a bunch of files under out/target/product/{device} which you can now start flashing.
Connect your Android phone to the computer and assuming that all the drivers and Android SDK is setup (a dependency that I somehow failed to mention before), you should be able to run the following command:
This can also be achieved by shutting down the device and starting it while pressing a combination of buttons (such as volume down + power on the Nexus 5). This would put you into fastboot mode. On the fastboot screen, pay attention to whether the bootloader is locked or not, if it is, execute the following to unlock it:fastboot oem unlock
This would wipe the data on the device. To further clean things up, execute the following:
Step 8
Navigate once again to the out/target/product/{device} directory and execute the following to flash the built images to the device:
Reboot the device and you’re all set.
This is just the tip of the iceberg, and hopefully you’ll be able to now play with the internals of Android to understand how things are really stitched together. Good luck on your journey.
Read Next
Windows of Opportunity: Microsoft's Open Source Renaissance
Twenty years ago, it was easy to dislike Microsoft. It was the quintessential evil MegaCorp that was quick to squash competition, often ruthlessly, but in some cases slowly through a more insidious process of embracing, extending, and exterminating anything that got in the way. This was the signature personality of
US-11604662-B2
I’m happy to announce, that after a long wait, patent US-11604662-B2 has been issued.
Parallelizing and running distributed builds with distcc
Parallelizing the compilation of a large codebase is a breeze with distcc, which allows you to spread the load across multiple nodes and…
Getting started with Linkerd
If you’ve done anything in the Kubernetes space in recent years, you’ve most likely come across the words “Service Mesh”. It’s backed by a…