Stupid pet tricks with Android

Posted: February 1, 2013 in android, linaro, open_source

Or how to do some fairly useful things with the Android build system that were not intuitively obvious to me.

I’ve been working with Android a fair amount this week, both the upstream Android Open Source Project sources and the Linaro sources. For both I’ve been getting piglit to build which has required me to construct a number of files. In this case, piglit and waffle are the two packages that need to build. Waffle for it’s library and piglit for it’s library, testcases and test case data.

How do you build a number of binaries in a loop using Android’s

I wondered the same. As the google examples go, for each binary you want to build, you need to specify several LOCAL_* values. If you had to do this for each and every test binary in piglit, it’d be quite quite tedious.  Here’s example how to it the easy way:

include $(call all-subdir-makefiles)

LOCAL_PATH:= $(call my-dir)

piglit_top := $(LOCAL_PATH)/../../..
piglit_shared_libs := libGLESv2 libwaffle-1 libpiglitutil_gles2
piglit_c_includes := $(piglit_top)/tests/util \
bionic \
$(piglit_top)/src \
external/waffle/include/waffle \
external/mesa3d/include \


module_name = piglit-spec-gles2

define $(module_name)_etc_add_executable
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := $(piglit_shared_libs)
LOCAL_C_INCLUDES := $(piglit_c_includes)
LOCAL_CFLAGS := $(piglit_c_flags)
LOCAL_MODULE := $1_gles2
systemtarball: $1_gles2

test_names := invalid-es3-queries minmax
$(foreach item,$(test_names),$(eval $(call $(module_name)_etc_add_executable, $(item))))

It’s fairly straightforward once you have the solution but getting there isn’t exactly documented in the google docs from what I could see. So let me talk you through it.

At the top, I have the list of shared libs that will be linked in and the directories that should be searched.

Within define $(module_name)_etc_add_executable are the set of values  we need to specify for each testcase. Observe that $1 is a parameter passed in. We have to keep to a pattern of test_case.c  will end up as name of the test_case binary, but who cares, this is quite acceptable.

Last test_names is the list of all the test cases we’re going to build. Followed last but not least by the loop that iterates over the test case list.

Next. Data!

How do you copy test case user data to the data partition in an file?

Again this was something I scratched my head about, looking through the docs, googled often and came up empty. It’s not hard but it’s not necessarily intuitive.

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE:= sanity.shader_test
LOCAL_SRC_FILES := sanity.shader_test
userdatatarball: $(LOCAL_MODULE)

In this example there is but one data file. But I think you can see where it’s going. Combine with the loop example above and things get quite useful.

Some things to point out.  We need BUILD_PREBUILT since we’re not building anything. The LOCAL_SRC_FILES is our list of data. LOCAL_MODULE_PATH is where to install to.  TARGET_OUT_DATA is /data. It will create the directories for you if they don’t exist.

userdatatarball: is rule to make sure that the datafile ends up in the tarball. I couldn’t figure out a way to not have this but perhaps there is a way. I didn’t run across it.

So there you have it. There might be bugs yet. There might be a better more official way. Based on what I figured out this is what works for me.

Leave a Reply

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

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

Google photo

You are commenting using your Google 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 )

Connecting to %s