Tuesday 17 September 2013

Android Build FAQ

= FAQ =

In general, the key thing to note is that android build system is non-recursive. For more on recursive vs non-recursive, please see:

All the commands mentioned here are from top of the tree and assume, you've already setup your environment with:
        $ source build/envsetup.sh
        $ choosecombo



== What java version is my build using? ==

In Gingerbread, your JAVA_HOME is set to '''/usr/lib/jvm/java-6-sun''' by build/envsetup.sh. You may see errors if you do not have JAVA 1.6 installed.
$ echo $JAVA_HOME # should return empty
$ source build/envsetup.sh # will set your JAVA_HOME if it's empty, will honor the existing value otherwise
$ which java
$ java -version
$ javac -version

== Related Build Error: method does not override a method from its superclass. @Override ==

This "error" is due to a difference in the meaning of @Override between Java 1.5 and Java 1.6: Java 1.6 added the ability to use @Override to indicate that a method implements an interface method
[which this code does].
You should be able to compile this code without error if you use a Java 1.6 compiler (the 'java -version' command only shows the JRE version. Use 'javac -version' to get the compiler version and adjust your path accordingly).

== What are the various build variants and their usage ==

Android build system supports the following build variants
*user
*userdebug
*eng
*tests

You can build these variants as follows
$ cd WORKSPACE
$ source build/envsetup.sh
$ choosecombo 1 1 <product-name> user
$ choosecombo 1 1 <product-name> userdebug
$ choosecombo 1 1 <product-name> eng
Alternatively, you can run
$ make PRODUCT-<product-name>-user
$ make PRODUCT-<product-name>-eng
$ make PRODUCT-<product-name>-tests
Note that '''choosecombo''' doesn't support tests variant.

== Where is the build log? ==

You can save one for yourself with
$ make 2>&1 | tee log

== How do I clean the build? ==

You can use '''dataclean''' to clean the staging area for your data partition
$ make dataclean # will rm -rf $(PRODUCT_OUT)/data/*, data-qemu/*, userdata-qemu.img

You can use '''installclean''' while switching between build variants
$ choosecombo 1 1 <product-name> user
$ make installclean # deletes all of the files that change between
different build types
$ choosecombo 1 1 <product-name> eng
Clean and clobber, both will remove the entire build dir
$ make clean # Remove all builds for current and past targets, does
rm -rf
$(OUT_DIR)
$ make clobber # Remove all builds for current and past targets

== What is a module? ==

In android build system, an Android.mk file defines how you build. An
android module is the entity you are building and is specified by
variable LOCAL_MODULE in the Android.mk
A single Android.mk can build multiple modules.

== How do I rebuild my module? ==

If you have a 'LOCAL_MODULE := foobar' in your Android.mk, you should be able to do
$ make foobar

== What are m, mm, mmm? ==

These are build utilities provided by build/envsetup.sh. Here's a
description of all the available utilities
- 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.
- mmm: Builds all of the modules in the supplied directories.
- cgrep: Greps on all local C/C++ files.
- jgrep: Greps on all local Java files.
- mgrep: Greps on all makefiles
- resgrep: Greps on all local res/*.xml files.
- godir: Go to the directory containing a file
- printconfig: tells you what configuration you are currently building
Note that 'm' and 'mm' need a toplevel Android.mk in the directory you use them on.
Example usage
$ cd dalvik/tests
$ mm
$ mmm ../tools
$ godir Atomic.h
$ m
$ croot

== How do I turn off prelinking for my module? ==

Add
LOCAL_PRELINK_MODULE := false
For the module in your Android.mk LOCAL_PRELINK_MODULE is set to false
by default for executables (built using BUILD_EXECUTABLE)

== How do I see what commands make is running? ==

You can use the '''showcommands''' modifier target.
What is does (build/core/config.mk)
# The 'showcommands' goal says to show the full command
# lines being executed, instead of a short message about
# the kind of operation being done.
SHOW_COMMANDS:= $(filter showcommands,$(MAKECMDGOALS))
Usage
$ make showcommands
$ cd $some_dir_with_an_Android.mk
$ mm showcommands

== How do I find out what are the available modules? ==

$ cd $some_dir_with_an_Android.mk
$ mm modules
You can also run 'make' to see the list of all the modules available
in your tree
$ croot
$ make modules

== How do I clean a single module/package? ==

$ croot
$ make clean-$(LOCAL_MODULE)

== How do I rebuild system image for an existing build? ==

$ make snod

=== What is snod? ===

'snod' is a pseduo-target provided by build/core/Makefile. You can use
it to rebuild your system image without following it's dependencies
and rebuilding everything else, apart from what you provide to make.
Example use cases
$ make framework snod  # rebuilds framework module, and system image

== How do I build multiple variants and targets? ==

Note: this script is broken in gingerbread.
$ source build/tools/check_builds.sh
$ golden_builds <product1>-eng <product2>-user <product3>-eng
Additionally you can run
$ check_builds <product1>-eng <product2>-user <product2>-eng
What this will do for you, according to check_build.sh comments:
# Go get dinner, and when you get back, there will be a file
# test-builds/sizes.html that has a pretty chart of which files are
# in which tree, and how big they are.

== How do I find what build properties are available for my build and how they were derived? ==

Post a full build, build properties can be examined in
out/target/product/$(TARGET_PRODUCT)/build.prop
This file is created/updated by build/core/Makefile (invoked by build/core/main.mk). The file is a concatentation of build/tools/buildinfo.sh output + your system.prop + $ADDITIONAL_BUILD_PROPERTIES

== App development ==

$ cd your_app_folder
$ mmm
$ adb sync
If you don't use the same machine for compilation and loading it is
possible to forward the port used by adb (5037) to the PC connected to the device.
If it's a linux machine, it is a lot easier, but it is possible to
forward ports from windows.
Fastboot still has to be run on the connected machine, but since it
only needs a few image files it is easier to coordinate.

== How do I build my binary/library/applicaton? ==

In general, refer to the build cookbook "http://source.android.com/
porting/build_cookbook.html" You can also look at existing Android.mk
files in your source tree. If you are tagging your module with
"optional".
In summary, 'user' tags cannot be used, they are used only for legacy
modules (Grandfathered).
'optional' tags makes sure that the module gets installed into user
and eng builds as long as you add that module name to the list of
packages (PRODUCT_PACKAGES).
PRODUCT_PACKAGES for proprietary modules is defined in the device-
vendor.mk
file, e.g. vendor/<vendor-name>/prop/common/config/device-vendor.mk
Opensource modules are defined in device/<vendor-name>/common/
common.mk
The 'eng' tag implies that the module will be picked up only by 'eng'
variant of the build.
The tests tag implies that the module will be picked up by tests variant of the
build. The tests variant is not available from choosecombo.
Do not use development (or any other tags not sanctioned by the android build system)

== My binary/library isn't available on target, whats wrong? ==

Check if you've updated the appropriate .mk configuration file to include
a PRODUCT_PACKAGES entry for the module.
Check the build log to see if your module got built. You can also use
'mm' with 'showcommands' to see if the module is being built & installed.

== I don't want to build everything, takes too long. What do I do? ==

You can build "tiny android," an Android build with a limited
userspace that
is useful for kernel development and verification. The tiny android
build will
not boot into the full UI. It will stay at one of the loading screens
(ANDROID_ - not the boot animation). ADB will be active, allowing you to run unit tests, etc. The build time for tiny android is significantly less than a full Android build. Tiny Android builds complete in less than 2 minutes,
whereas a full Android build takes over 20 minutes.
$ BUILD_TINY_ANDROID=true make -j4

=== How do I use a prebuilt kernel? ===

The kernel objects, vmlinux and zImage will be at <platform>/out/
target/product/<TARGET>/obj/KERNEL_OBJ and its subdirectories, where
<TARGET> is the target device you selected in choosecombo above. You
can override the TARGET_PREBUILT_KERNEL flag with your own kernel
image to build android with your kernel, as follows:
$ make -j4 TARGET_PREBUILT_KERNEL="<your_kernel_tree>/arch/arm/boot/zImage"

=== error: do_inode_allocate_extents: Failed to allocate blocks ===

One way to workaround this is to increase the system image size.
Please see
BOARD_*_PARTITION_SIZE variables in device/<vendor>/$(TARGET_PRODUCT)/
BoardConfig.mk in your workspace.


== Misc ==

=== If you want to see all warnings in a pretty format, do ===

$ build/tool/warn.py my_build_log > warn.html
See the html page for a nice classification for all the warnings on your product.

=== What is the 'simulator' in lunch for? ===

"the simulator is somewhat maintained, but it's a very specialized and very fragile tool which is only used by a handful of people at Google. It is likely to require the very precise environment that those people" use, which is specific to Google and isn't publicly available."
See this thread for more detail
"http://groups.google.com/group/android-building/browse_thread/thread/55521a7849bbac1a/e4e020a8213cf7c7?lnk=gst&q=generic+product#e4e020a8213cf7c7"

=== How do I rebuild the sdk? ===

$ make PRODUCT-sdk-sdk

== What is the difference between board, target, product and device?==

Android build system supports hierarchical layering of product,
device, board, and arch in a one to many relationship as described at
"/development/pdk/"

=== TARGET ===

In Android Build System, 'target' or 'TARGET' refers to your build
target. There are a bunch of variables associated with a target.
From a Build perspective, these are

TARGET_PRODUCT: identifies the product that you are building
TARGET_BUILD_TYPE: identifies the build type from one of
'release,
debug'
TARGET_BUILD_VARIANT: identifies the build variant from one of
'user,
userdebug,
 eng,
tests'
From a PRODUCT perspective, these are
TARGET_PRODUCT: identifies the product, for example, full_crespo,passion_us, passion_eu
TARGET_DEVICE: identifies the device, for example, full_crespo,passion
TARGET_BOARD_PLATFORM: can be used for a family of boards, for example, qsd8k, msm7k
TARGET_BOOTLOADER_BOARD_NAME: used by OEMs for their boards, and by chipset_variants. for example, mahimahi of htc, full_crespo
TARGET_ARCH: arm/x86
TARGET_ARCH_VARIANT: armv5/armv7

=== BOARD ===

In Android Build System, BOARD refers to the schematics of a product

=== DEVICE ===

For OEMs, DEVICE refers to the physical layer of plastic on the device
Each of these devices may result
into multiple products. Examples
* crespo # Samsung
* passion # HTC

=== PRODUCT ===

The product layer represents a complete specification of a shipping
product
"/development/pdk/docs/guide/build_system.jd"

== How do I add a new target? ==

Adding a new target means adding a new product. You can name your product as chipset_variant. Note that if one product may suffice for all your chipset variants.

== How do I add a new product? ==

Android products use inheritance, you can generate a nice product graph using
$ sudo apt-get install graphviz
$ make product-graph # pdf goes in out/product.pdf

== PRODUCT CONFIGURATION ==

In general, android build system builds products, and allows you to configure what goes into a product. It doesn't explicitly support configuration at a build level, in allowing you to choose what to
build. A typical android build is supposed to build all possible code
that is available see build/core/main.mk.
You can choose what goes into a product, by adding to the
PRODUCT_PACKAGES list which is used to specify what additional
packages go into a product, as follows.

=== How do I generate a product graph ===
$ sudo apt-get install graphviz
$ make product-graph # pdf goes in out/product.pdf

=== What is device-vendor.mk, when do I modify it? ===

device-vendor.mk allows you to configure proprietary modules to be installed on the target images.
Starting with Gingerbread the Android build system enforces an explicit
LOCAL_MODULES_TAGS for all modules which aren't in the GRANDFATHERED MODULES
and recommends using "optional" tag for modules which are expected to be in all builds of a product.
When LOCAL_MODULE_TAGS of a module is defined with an "optional" tag,
the module will not be available in the generated final image/s (which will be flashed on Target).
To get the module available in final image/s, module has to be part of PRODUCT_PACKAGES list.

=== What is device/<vendor>/common/common.mk, when do I modify it? ===

The opensource counter part of device-vendor.mk [prev question] is
device/<vendor>/common/common.mk and should be used for adding
opensource modules to PRODUCT_PACKAGES.

=== How do I configure (enable/disable) a module? ===

Configuration has two aspects with respect to Android Build System
* What gets installed
* What gets built
What gets installed can be configured at a product level using the
device-vendor.mk and common.mk configuration files, described above
[prev questions].
Controlling what get's built, is a more complicated story. Presently,
for a typical build android build system builds all modules it can
find using findleaves.py [See modules_to_install and modules_to_check in build/core/main.mk].
The two ways to enable/disable a module then are
* Add/Remove Android.mk
* Wrap the Android.mk in TARGET_PRODUCT if you don't want to build your
* modules for products like generic, emulator etc.
If you want your module to not be built for variants not supported by
your LOCAL_MODULE_TAGS, you can define LOCAL_DONT_CHECK_MODULE, though
it is not recommended by android build system as of now. Example,
$(CLEAR_VARS)
LOCAL_DONT_CHECK_MODULE := true
LOCAL_MODULE := foo
LOCAL_MODULE_TAGS := eng
What this will do for you is
* For all non-eng builds, your module will only be built if it's a dependency
* of another module
* Else, it will be ignored


== Emulator ==

=== What is the emulator? ===

From the AOSP WIKI documentation: "The Android SDK includes a mobile
device emulator -- a virtual mobile device that runs on your computer.
The emulator lets you develop and test Android applications without using a physical device."

=== How is it used? ===

The emulator is provided by
external/qemu
sdk/emulator
prebuilt/linux-x86/emulator
The one in external/qemu produces an executable called "emulator"
which can be used from the commandline. It get's built and installed
in out/host/linux-x86/bin/emulator and can be used with the images
generated by building the 'generic' products provided in the AOSP tree.
The AOSP tree provides "non-hardware-specific targets" which can be used "to build entire user-level system and work with emulator".
There are two such target products available
target/product/generic
target/product/generic_x86
They use the following boards from target/board, respectively
target/board/generic
target/board/generic_x86
(There's also an 'emulator' board available under target/board for
which there's no emulator.mk under target/product, device/ or vendor/ which is where envsetup.sh looks for product makefiles, and so it doesn't show up in choosecombo)
target/board/*/README.txt explains the existence and usage of all three, generic, generic_x86, emulator.
Emulator usage example
"http://groups.google.com/group/android-platform/browse_thread/thread/b115c4cadbfdb333/488ca1b48bc546d8?lnk=gst&q=generic+product#488ca1b48bc546d8"

== How do I rebuild the emulator? ==

"http://groups.google.com/group/android-building/browse_thread/thread/f8f0c3bacd6efae/05ec2449d4e5dc6f?lnk=gst&q=emulator#05ec2449d4e5dc6f"

No comments:

Post a Comment