Compiling Android Master on Mac OS X Lion With Xcode 4

[Update: The patches have been merged into the AOSP master branch, so as of the 22nd of December AOSP master should compile on OS X 10.7 with Xcode 4 straight from checkout]

My company has worked on some Android firmware projects in the past, but, due to the closed source nature of Honeycomb, that work pretty much dried up. Recently though Google released Android 4.0 to the masses and we’ve had a few enquiries about firmware work again, so I thought I’d see what the current state of building Android was for our default machine configuration.

The first problem I hit was the Android build system wasn’t compatible with Mac OS X 10.7 (Lion) and Xcode 4 (The Xcode version available for Lion), so I decided to use a bit of spare time to seeing if it could be fixed.

The following are the steps I found necessary to allow the build to complete on the current master branch (the android-4.0.3_r1 branch has some additional issues which I haven’t resolved yet, so please don’t assume this will work for that branch as well);

  1. Install Xcode from the Mac App Store (this gave me Xcode version 4.2).

  2. Install version 2.0.3 of MacPorts using the DMG installer image for Lion which is available from the MacPorts site. During the installation process you’ll be asked to install Java if you don’t already have it installed, select the install option.

  3. Follow the Android build environment setup instructions skipping the instructions on installing Xcode & MacPorts (because you’ve already done that)

[Note: The instructions on the Android site indicate a reversion of the version of Make may be required, but the configuration I was left with straight after installing Xcode & MacPorts gave me make 3.81 by default, so you probably won’t need to revert the make version either. I also noticed that my Lion installation didn’t require the ulimit modification due to it already being unlimited.]

  1. Apply the following patches I created for three different projects in the source tree to fix build issues;

build project;

diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
index 544a29e..407c74f 100644
--- a/core/combo/HOST_darwin-x86.mk
++ b/core/combo/HOST_darwin-x86.mk
@@ -53,7 53,11 @@ HOST_JNILIB_SUFFIX := .jnilib

 HOST_GLOBAL_CFLAGS = \
        -include $(call select-android-config-h,darwin-x86)
-HOST_RUN_RANLIB_AFTER_COPYING := true
ifneq ($(filter 10.7.%, $(build_mac_version)),)
       HOST_RUN_RANLIB_AFTER_COPYING := false
else
       HOST_RUN_RANLIB_AFTER_COPYING := true
endif
 HOST_GLOBAL_ARFLAGS := cqs

 HOST_CUSTOM_LD_COMMAND := true

development project;

diff --git a/tools/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk b/tools/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk
index deb11b6..a73f6b8 100644
--- a/tools/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk
++ b/tools/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk
@@ -8,6 8,15 @@ LOCAL_SDL_CONFIG ?= prebuilt/$(PREBUILT)/sdl/bin/sdl-config
 LOCAL_SDL_CFLAGS := $(shell $(LOCAL_SDL_CONFIG) --cflags)
 LOCAL_SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(LOCAL_SDL_CONFIG) --static-libs))

ifeq ($(HOST_OS),darwin)
  DARWIN_VERSION := $(strip $(shell sw_vers -productVersion))
  ifneq ($(filter 10.7 10.7.%,$(DARWIN_VERSION)),)
    # Lion needs to be forced to link dylib to avoid problems
    # with the dynamic function lookups in SDL 1.2
    LOCAL_SDL_LDLIBS = /usr/lib/dylib1.o
  endif
endif

 LOCAL_SRC_FILES:= \
         triangleCM.cpp

diff --git a/tools/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk b/tools/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk
index ae0064f..efbe6bd 100644
--- a/tools/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk
++ b/tools/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk
@@ -17,6 17,12 @@ LOCAL_LDLIBS = $(LOCAL_SDL_LDLIBS)
 LOCAL_STATIC_LIBRARIES = libSDL libSDLmain

 ifeq ($(HOST_OS),darwin)
DARWIN_VERSION := $(strip $(shell sw_vers -productVersion))
ifneq ($(filter 10.7 10.7.%,$(DARWIN_VERSION)),)
  # Lion needs to be forced to link dylib to avoid problems
  # with the dynamic function lookups in SDL 1.2
  LOCAL_LDLIBS = /usr/lib/dylib1.o
endif
 $(call emugl-import,libMac_view)
 endif

external/qemu project;

diff --git a/Makefile.android b/Makefile.android
index e58f984..d638640 100644
--- a/Makefile.android
++ b/Makefile.android
@@ -74,8 74,8 @@ ifeq ($(HOST_OS),darwin)
     ifneq ($(filter 10.1 10.2 10.3 10.1.% 10.2.% 10.3.% 10.4 10.4.%,$(DARWIN_VERSION)),)
         $(error Building the Android emulator requires OS X 10.5 or above)
     endif
-    ifeq ($(filter 10.5 10.5.%,$(DARWIN_VERSION)),)
-        # We are on Snow Leopard or above
    ifneq ($(filter 10.6 10.6.%,$(DARWIN_VERSION)),)
        # We are on Snow Leopard
         LEOPARD_SDK := /Developer/SDKs/MacOSX10.5.sdk
         ifeq ($(strip $(wildcard $(LEOPARD_SDK))),)
             $(info  Please install the 10.5 SDK on this machine at $(LEOPARD_SDK))
@@ -191,6 191,11 @@ endif

 ifeq ($(HOST_OS),darwin)
   QEMU_SYSTEM_LDLIBS = -Wl,-framework,Cocoa,-framework,QTKit,-framework,CoreVideo
  ifneq ($(filter 10.7 10.7.%,$(DARWIN_VERSION)),)
    # Lion needs to be forced to link dylib to avoid problems
    # with the dynamic function lookups in SDL 1.2
    QEMU_SYSTEM_LDLIBS = /usr/lib/dylib1.o
  endif
 endif

 include $(LOCAL_PATH)/Makefile.common
  1. Follow the build instructions and watch the build complete :).

This process should be enough to get you a working environment to build for devices and has allowed me to build a fully functioning version of the master branch (as of 20th December 2011) for my Galaxy Nexus using the full_maguro-userdebug lunch target.

There are still some some runtime issues with some of the host scripts which are produced during a build. The main issue seems to be with auto-detection of their environment and not finding the 64bit variants of some libraries (e.g. the android script fails saying it doesn’t have any x86_64 SWT libraries available), but that’s a problem for another day….

If you have any questions about building the Android source code please use the android-building Google group to discuss them so that others can either help out or see how to resolve similar issues.