My Avatar

Shilong ZHAO

Start Android Build Environment

2015-07-22 00:00:00 +0200

In case you have any questions or suggestions, you can leave comments HERE . Thanks!

It is assumed that you are familiar with Linux and Android. It will be very helpful if you are familiar with GNU toolchain (Autotools, Make, etc), since the concepts here in Android are quite comparable with that in Linux.

The first thing we need to do is make sure that all the dependent packages, including JDK, are installed and properly configured on your work station. Then download the Android source code. Detailed instructions are available on the Android site.

After these step have been done, go to the directory where Android source code is stored and run build/

$ cd path/to/aosp
$ source build/

including device/asus/deb/
including device/generic/mini-emulator-arm64/
including device/generic/mini-emulator-armv7-a-neon/
including device/samsung/manta/
including sdk/bash_completion/adb.bash

In these script files, there is actually only one line command, for example the effective contents in mini-emulator-arm64/ is simply

add_lunch_combo mini_emulator_arm64-userdebug

Function add_lunch_combo is defined in build/ and serves to check if a lunch combination has been added into LUNCH_MENU_CHOICES and if not, it will be appended to the menu:

function add_lunch_combo()
  local new_combo=$1
  local c
  for c in ${LUNCH_MENU_CHOICES[@]} ; do
    if [ "$new_combo" = "$c"] ; then
# add the default one here
add_lunch_combo aosp_arm-eng
add_lunch_combo aosp_arm64-eng
add_lunch_combo aosp_x86_64-eng

But does more than just adding lunch combinations, there are also some auxiliary functions to make life easier.

$ hmm

Invoke ". build/" from your shell to add the following functions to your environment:
- lunch:   lunch <product_name>-<build_variant>
- tapas:   tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
- croot:   Changes directory to the top of the tree.
- 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.
- cgrep:   Greps on all local C/C++ files.

If you are in a deep subdirectory under AOSP source tree, then running croot in shell will directly lead to path\to\aosp. We will see the usage of lunch immediately, and other commands like m, mm in the following parts.

Function lunch is also defined in It reads the choice, find the lunch combo, and in the end set environmental variables. The product is the the part before the dash - in a lunch combo, e.g. mini_emulator_arm64, and variant is the part after -, e.g. userdebug:

function lunch()
  product=$(echo -n $selection | sed -e "s/-.*$//")
  variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
  export TARGET_PRODUCT=$product
  export TARGET_BUILD_VARIANT=$variant
  export TARGET_BUILD_TYPE=release

Type lunch in the terminal

$ lunch

You are building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     6. aosp_x86_64-eng
     7. aosp_deb-userdebug
     13. mini_emulator_arm64-userdebug

Which would you like? [aosp_arm-eng]

Here all the lunch combinations previously added by add_lunch_combo are listed. Type the corresponding number of the build target you’ve chosen. If only press enter, aosp_arm-eng will be the default choice. A set of environmental varaibles will be set.

Which would you like? [aosp_arm-eng]

PLATFORM_VERSION is the Android platform version, which is 5.0.1 or Lollipop. TARGET_BUILD_VARIANT is eng, so all the modules tagged with eng, user, debug will be installed. TARGET_ARCH is the target CPU architecture. All the build output will be put into OUT_DIR which is path/to/aosp/out.

$ env | grep ANDROID


ANDROID_BUILD_TOP is the root directory for Android source code. ANDROID_PRODUCT_OUT is where you will find all the built libraries. ANDROID_BUILD_TOOLCHAIN defines the toolchain that is gonna be used for compilation, linking, etc.

Now the environment is set up, and it’s time to build Android:

$ m -j16

Function m’s implementation is shown in the following code block. It calls make, change the directory to the source root, and use build/core/ as the makefile, appending other user specified parameters, i.e. spawning 16 jobs in this case.

function m()
  local T=$(gettop)
  local DRV=$(getdriver $T)
  if [ "$T" ]; then
    $DRV make -C $T -f build/core/ $@
    echo "Couldn't locate the top of the tree. Try setting TOP."

It will take a long time to finish. After that you will have a customized Android image. You can start you own Android by

$ emulator &

Notice that every time when you close the terminal where you’ve configured the environment. You’ll have to rerun

$ source ./build/
$ lunch

If you lunch the same configuration which you’ve built, there will be no need to run m -j16 anymore. However, if you want to build for a new target, say x86, you really have to run m -j16 once again.

In the next post I will write something about how to port libcurl to Android.