Tuesday, March 17, 2009

Building, running, and debugging Android source

There is a lot of confusion surrounding the work flow in the Android source tree, so allow me to simplify:
  1. Follow the initial instructions for downloading the source at:

    http://source.android.com/download

  2. Set up your environment to build the engineering build for the generic device and generic product. This is similar to the SDK, but with a few pieces missing.

    $ source build/envsetup.sh
    $ lunch 1

  3. To build for the first time:

    $ make

    If you have a multi-core system, you can build with make -jN where N is twice the number of cores on your machine. This should speed up the first build considerably.

  4. To launch the emulator from your build:

    $ ./out/host/<your-machine-type>/bin/emulator

    On my system <your-machine-type> is linux-x86.

    NOTE: The emulator knows where to find system and data images as a result of running lunch 1 above. This sets the environment variable ANDROID_PRODUCT_OUT to point to the target directory. For this example, it should be out/target/product/generic/.

  5. If you wish to make changes to the source code, there are handy utilities that have been exposed to your environment by source build/envsetup.sh above. For example, if you modify the Email app and just want to rebuild it:

    $ mmm packages/apps/Email

  6. To see your changes in the emulator you can run:

    $ adb remount
    $ adb sync


    Which will copy the regenerated Email.apk file into the emulator's /system/app folder, triggering the PackageManager to automatically reinstall it.

  7. Or if you change framework resources in frameworks/base/core/res/res/ you could regenerate framework-res.apk with:

    $ mmm frameworks/base/core/res

    Or if you modified even the framework itself you could run:

    $ mmm frameworks/base

    To sync these changes you must restart the running framework and sync, as with this handy sequence:

    $ adb remount
    $ adb shell stop
    $ adb sync
    $ adb shell start

  8. Finally, to debug your changes you can use the DDMS tool to select a process for debug and then attach Eclipse to it. If you have the Eclipse Android Development plugin installed, there is a special DDMS perspective which you can use to choose the process for debug. To attach Eclipse to it, see these instructions:

    http://source.android.com/using-eclipse

    This document also describes how to use Eclipse for development. Any IDE should work with the proper finagling though. Just note that the IDE won't really be an integrated environment: the final output of APKs, system.img, and even the generation of R.java files will have to be done by make!

    A note about the processes in Android:

    • system_process houses all things under frameworks/base/services. This includes the PackageManagerService, StatusBarService, etc. It has many, many threads (one for each service, and then one main UI thread), so be wary when debugging.
    • com.android.acore hosts Launcher (home), Contacts, etc. You can determine the apps/providers that run here by looking for android:process="android.process.acore" in the various AndroidManifest.xml files in packages/.

    Also remember that the "framework" (under frameworks/base/core/java) is not hosted by any one process. It is a library used by most processes, so to debug code there you can usually use a simple demo app that takes advantage of whatever you changed and debug that app's process. A useful trick for setting up your debug connection is to call Debug.waitForDebugger() during some startup part of an application or system service.

UPDATE 2009-07-24: The original ONE_SHOT_MAKEFILE line I gave for rebuilding the framework has been deprecated. mmm frameworks/base is now the recommended way to rebuild the framework code.

21 comments:

Jeffrey Sharkey said...

Awesome guide :) I've been putting the sync onto one line to make it easy in command history:

adb shell stop && adb sync && adb shell start

Unknown said...

Very informative. I have a related question. I need to make changes to a java file in the framework without changing the interface. Is it possible to build just that java file without building the whole framework?

Kovendan said...

Thats a great post ,very comprehensive.... great work ... and thanks for the post .

Unknown said...
This comment has been removed by the author.
Unknown said...

@George, sounds like you're trying to debug a project which is connected to the Eclipse ADT plugin. This will not work with framework debugging as the ADT plugin does not contain or allow references to the Android source code. You'll need to follow the instructions on Google's page to download and connect Android source code directly to Eclipse. The ADT is not involved.

Unknown said...

This is the only guide I have found so far on the internet that actually works, even the Google guide doesn't work.
Good job!

Unknown said...

I would like to build the complete source.

After giving linux@ubuntu:~/mydroid$ make
I'm getting the following output. It seems that the build stopped. Can anyone help in how to proceed further.

build/core/base_rules.mk:117: *** git:/android.git.kernel.org/platform/packages/apps/Browser.git: MODULE.TARGET.APPS.AlarmClock already defined by AlarmClock. Stop.

Thanks, Vijay

ctate said...

Omar, you can't build only that .java file, but you can build just the framework and system image without (unnecessarily) rebuilding all of the apps etc. Use something like this command, all on one line, with a -j setting appropriate for the number of cpus you have:

mmm -j6 frameworks/base frameworks/base/core/res snod

ctate said...

Omar, you can't build only that .java file, but you can build just the framework and system image without (unnecessarily) rebuilding all of the apps etc. Use something like this command line, with a -j setting appropriate for the number of cpus you have:

mmm -j6 frameworks/base frameworks/base/core/res snod

Unknown said...

Is there a way to take a google App like the Browser/Calculator from the source and move it over to another project and then use it with the SDK in Eclipse?

Unknown said...

Is it possible to move applications out of the package directory (e.g. Browser) and then create a stand alone project out of it? I want to step through the browser with a debugger in eclipse to see how the components interact with each other.

Unknown said...

Very Good Post. I was not able to find the middle ware documentation any where. Being a fresher to Android. It helped me a lot.. Thanks.. If you have anything to share about middle ware then please mail me at hallurspoorti@yahoo.in

guycole said...

Great job. Thanks for the effort. Google should have a href to this blog as part of the documentation.

bharat pawar said...

great post!!!

Unknown said...

Thanks a lot for this Guide! It helped me a lot...I've a problem in using the mmm command. If I'm running mmm on a specific package, I'm not able to start the Emulator again...I can't do a remount adb because it doesn't find the emulator...and that's also why I'm not able to run the adb sync command...any suggestions?

Ritu Srivastava said...

Good post. I noticed that the link to using eclipse is changed to: http://source.android.com/source/using-eclipse.html

You might want to update the link location in your post.

Unknown said...

Thanks for taking the effort to put this post. Once question though - My shell doesn't seems to find 'launch'. What am I missing?

celeritas said...

Great blog man! Just awesome!

SimpleSwami1985 said...

Can we write an app to launch in the system_process ? I get INSTALL_PARSE_FAILED_MANIFEST_MALFORMED error , by using
android:process ="system_process"
android:sharedUserId = "android.uid.system" >

Android app development said...

This is one of the well organized and nice post.I like your blog analyse.This is one of the pleasurable post.
Android app developers

Unknown said...

Hi,

Thanks a lot for this information.
I have similar question on building the code in framework/base.

I have added an implementation code in the framework/base/core/java/android/content/test.java. I am building the framework/base with mmm command and after sync command, I am not able to see the changes on the device.

I am building for msm8060 device.

Thanks again,