Building Android from source

Building android from source isn’t actually that hard as I shall try to demonstrate. This information has been gathered from various sources: android website, blogs, forums etc. I have done all this on ubuntu 10.04 within bash.

The first thing to do is get the source using the repo tool android supply. Google it and you will find it easily enough. It’s basically a wrapper around git for Android development. I don’t know much about it beyond checking out. You then init a repository and check out by doing:

repo init -u git://android.git.kernel.org/platform/manifest.git
repo sync

You can create your own branch if you like

repo start mybranch --all

Now you are ready to build. But, if like me, you have a 32 bit machine, google have decided to make life difficult for us. From what I can gather, because google just deals in 64 bit builds, they have disabled 32 bit builds. Not just stamped a health warning on them, but disabled them. However, with a little hackery dackery we can get around that. A patch is at the end of this post with some updates to makefiles.

Android have also kindly provided a shell script with various useful tools. To get them into your environment, from the root of where you got the source:

source build/envsetup.sh

One of those useful tools is called lunch, which we will use to configure the build. Run lunch and you will see:


stephen@stephen-laptop:~/src/android/platform$ lunch
You're building on Linux
Lunch menu... pick a combo:
1. full-eng
2. full_x86-eng
3. simulator
4. full_dream-userdebug
5. full_passion-userdebug
6. full_sapphire-userdebug
Which would you like? [generic-eng]

I went with the default, which is 1, but I’m sure the others do equally fascinating and useful things. This gives:

============================================
PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=AOSP
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=OPENMASTER
============================================

Then you do a make, which will take quite a while. Dont forget to take advantage of the -j flag for parallel jobs. It can really speed up big jobs like this. A good rule of thumb is twice the number of cores you have minus 1.

That should just work, at least it did for me. Then to run what you have, you need to define an environment variable to point at where you ramdisk and system image and all that stuff are. They should be in out/target/product/generic, for this configuration at least.

export ANDROID_PRODUCT_OUT=~/src/android/platform/out/target/product/generic/

Then you can run:

out/host/linux-x86/bin/emulator

And you should see your very own emulator. You can also stick gdb on this and break at main, which is the entry point of qemu.
This doesn’t build the kernel for you however. What we checked out comes with a prebuilt image for the kernel. To build your own, you first need the source code:

git clone git://android.git.kernel.org/kernel/common.git android-kernel
cd android-kernel

To see the branches in this:
$ git branch -r
origin/HEAD -> origin/android-2.6.27
origin/android-2.6.25
origin/android-2.6.27
origin/android-2.6.29
origin/android-2.6.32
origin/android-2.6.35
origin/android-2.6.36
origin/android-goldfish-2.6.27
origin/android-goldfish-2.6.29

For the emulator, the goldfish branch is the one we are interested in, so lets switch to it:

git checkout -t origin/android-goldfish-2.6.29 -b goldfish

Now configure it:
make ARCH=arm goldfish_defconfig

If you wish to debug, you will need to build it with the debug symbols. Using make menuconfig doesn’t seem to play nice so I went into my .config file after the above command and replaced:

# CONFIG_DEBUG_INFO is not set

with

CONFIG_DEBUG_INFO=y

And build it:
make ARCH=arm CROSS_COMPILE=arm-eabi-

Note that the arm-eabi-* tools should be on your path. If not, they reside in:

$ which arm-eabi-gcc
/home/stephen/src/android/platform/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gcc

When built, you will be left with arch/arm/boot/zImage. This is your kernel, and to boot it you do:

emulator -kernel arch/arm/boot/zImage

Now, to debug this, start the emulator as follows:
emulator -kernel android-kernel/arch/arm/boot/zImage -qemu -S -s
This tells qemu to launch a gdb server listening on port 1234 (-S) and to break on the first instruction (-s). This gives us time to connect with gdb.

Start up gdb (use the arm flavour) on vmlinux which will be in the root of your kernel checkout:
arm-eabi-gdb vmlinux

Connect to the remote gdbserver:
(gdb) target remote localhost:1234
Set your breakpoint (start_kernel is as good as any) any then resume the target with “c”. Enjoy!

Patch mentioned above:

project build/
diff –git a/core/main.mk b/core/main.mk
index 1cc54a9..87bb3be 100644
— a/core/main.mk
+++ b/core/main.mk
@@ -68,7 +68,7 @@ $(info Checking build tools versions…)

ifeq ($(BUILD_OS),linux)
build_arch := $(shell uname -m)
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq (i686,$(findstring i686,$(build_arch)))
$(warning ************************************************************)
$(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)
diff –git a/envsetup.sh b/envsetup.sh
old mode 100644
new mode 100755

project external/clearsilver/
diff –git a/cgi/Android.mk b/cgi/Android.mk
index 21c534b..acf08b2 100644
— a/cgi/Android.mk
+++ b/cgi/Android.mk
@@ -13,8 +13,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+#LOCAL_CFLAGS += -m64
+#LOCAL_LDFLAGS += -m64

LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

diff –git a/cs/Android.mk b/cs/Android.mk
index 9f0e30a..c36a1e1 100644
— a/cs/Android.mk
+++ b/cs/Android.mk
@@ -9,8 +9,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+#LOCAL_CFLAGS += -m64
+#LOCAL_LDFLAGS += -m64

LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

diff –git a/java-jni/Android.mk b/java-jni/Android.mk
index 21b4fd1..51d4c25 100644
— a/java-jni/Android.mk
+++ b/java-jni/Android.mk
@@ -34,8 +34,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS += -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+#LOCAL_CFLAGS += -m64
+#LOCAL_LDFLAGS += -m64

LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

diff –git a/util/Android.mk b/util/Android.mk
index 386f379..f15281b 100644
— a/util/Android.mk
+++ b/util/Android.mk
@@ -18,8 +18,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+#LOCAL_CFLAGS += -m64
+#LOCAL_LDFLAGS += -m64

LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s