Build Android ICS on Mac OS 10.8

在mac上build Android需要一些"折騰",記錄一下收集來的資訊以及個人試驗的結果。
google docs為準:

Test environment

  1. Mac OS 10.8
  2. Xcode 4.4
  3. Homebrew 0.9.2
  4. Android 4.1.1_r3

Set build environment

create case-sensitive build environment

原因:
default的OS X是 case-insensitive,Android會不給compile:
In a default installation, OS X runs on a case-preserving but case-insensitive filesystem. This type of filesystem is not supported by git and will cause some git commands (such as "git status") to behave abnormally. Because of this, we recommend that you always work with the AOSP source files on a case-sensitive filesystem. This can be done fairly easily using a disk image, discussed below.
解法:
  1. 用Disk Utility建立一個25GB的"case sensitive, journaled" DMG disk image
或是 You can also create it from a shell with the following command:
  1. hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg
之後把source code拷貝到這個image裡面build

change compiler to gcc 4.2

原因:
Xcode 4.3 default compiler 是 llvm-gcc
會有一些缺少 this->xxx 的問題,例如:
external/srec/tools/thirdparty/OpenFst/fst/lib/map.h:367:7: error: use of undeclared identifier 'AddArc'
解法:
可以將compiler換成GCC 4.2
之後在compile前export下列參數
export CC=/usr/local/bin/gcc-4.2&&export CXX=/usr/local/bin/g++-4.2
參考:
UPADTE (MAY 29TH) : The Xcode 4.3 default compiler (llvm-gcc) used to be incompatible with CM9. Thanks to jocelyn and topprospect, the LLVM compatibility patches from mainline AOSP are now merged into CM9. Therefore, you can now use Xcode 4.3 and its command line tools without installing another compiler. However, since GCC is still the only officially supported compiler, incompatibilites with llvm-gcc could still be introduced with future updates. Therefore, if your build fails, it might be worth it to try installing and compiling with GCC 4.2. See the Troubleshooting section for more info.
Troubleshooting:
  1. The extract script for maguro seems to be a little outdated, as it doesn't pull the gps proprietary blob. You can either use the google provided scripts, or add koush's git repository for your device to your local_manifest.xml.
  1. As explained above, the CM9 source is currently compatible with llvm-gcc. In the future, if llvm-gcc fails to build correctly, you should try installing and compiling using GCC4.2 (the Xcode 3 compiler). You can install apple-gcc4.2 from homebrew:
  2. brew install https://raw.github.com/Homebrew/homebrew-dupes/master/apple-gcc42.rb
  3. This version of gcc can happily coexist with Xcode 4.x .
  4. So now you have GCC 4.2 installed, but it won't be used unless we update the corresposing environment variables:
  5. export CC=/usr/local/bin/gcc-4.2&&export CXX=/usr/local/bin/g++-4.2
  6. Notice that using the export command is temporary. If you relaunch Terminal, you will need to set these again. However, this is a good thing, because changing these values permanently (by putting them in ~/.bash_profile) can interfere with other builds.
  7. If you use this method, the build might fail while compiling "external/zlib/x86/adler32.c". It appears that a recent change in zlib has introduced an incompatibility with gcc 4.2. you have to revert the following 2 commits:cd external/zlib
  8. git revert dd6786cae3f4493faa6661d5f74db587932f15d7
  9. git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0
  10. Alternatively, you can add topprospect's zlib on github (which has those commits reverted) to your local_manifast.xml. Simply run:
  11. nano /Volumes/android/cm9/.repo/local_manifest.xml
  12. and add the following line
  13. <projectname="dferg/android_external_zlib"path="external/zlib"remote="github"/>
  14. If you get a build error, and your error is not covered here, copy the last 20-30 lines of the build output AND the output from the following command into pastebin and post the link. Hopefully me or someone else will help you.echo -e "\nENV:\n$(env)\n\nWHICH GCC\n:$(which gcc)\n\nWHICH G++:\n$(which g++)\n\nWHICH CC:\n$(which cc)\n\nWHICH C++:\n$(which c++)\n\nBREW DOCTOR:\n$(brew doctor)\n\nBREW LIST:\n$(brew list)\n\n/USR/BIN:\n$(ls -l /usr/bin | grep gcc)\n\n/USR/LOCAL/BIN:\n$(ls -l /usr/local/bin | grep gcc)\n\n"
Notes/Extras:
  1. To quickly setup your environment, add an alias like the following to ~/.bash_profile:
  2. alias cm9env="hdiutil attach PATH-TO-DISK-IMAGE -mountpoint /Volumes/android && cd /Volumes/android/cm9 && source ./build/envsetup.sh && export USE_CCACHE=1"
  3. alias cm9build="cm9env && make clobber && reposync && brunch maguro"
  4. Now you can save time by using "cm9env" to get your environment setup or "cm9build" to compile a clean updated build.
  5. To clear your output directory for a new build, run "make clobber". You probably don't need this if you've only changed a few lines of code.
  6. To cherry pick yet-to-be-merged changes from the gerrit instance:

Troubleshooting

xt_DSCP.h not exist

因為之前沒在case-sensitive環境下載,
inux/netfilter/xt_DSCP.h 和 inux/netfilter/xt_dhcp.h 會被當同一個檔案
out/target/product/eeepc/obj/STATIC_LIBRARIES/libext_intermediates/libxt_DSCP.c:15:37: error: linux/netfilter/xt_DSCP.h: No such file or directory

indexOfKey error

原因:
也是跟llvm-gcc compile不會補this有關
解法:
cd frameworks/base
git cherry-pick 7a4d92a
Re: [android-building] Build Android 4.0.3 in mac os lion
> i want to building android source on mac os lion
It's always a good idea to specify which version of Android you're
having issues with.
> it post me a error
>
> frameworks/base/include/utils/KeyedVector.h:193:17: error: use of
> undeclared identifier 'indexOfKey'
>         ssize_t i = indexOfKey(key);
>
> any ideas?
You've probably been bitten by the same problem that commit 7a4d92a in
frameworks/base solves. That commit is already present in Jellybean and
the master branch, but if upgrading isn't an option it should be a clean
cherrypick onto whatever codebase you're working on.

No module named libxml2

原因:
python需要libxml2
解法:
要先裝 brew
之後
First, you cannot install libxml2 because you already successfully installed it, so you will first need to uninstall it.
  1. brew uninstall libxml2
Next you will need to edit the brew formula - which is simple enough to do --
type
  1. brew edit libxml2
and change the line
  1. system "./configure", "--prefix=#{prefix}", "--without-python"
to this:
  1. system "./configure", "--prefix=#{prefix}", "--with-python"
This does not fix the problem with the brew formula, but it does force the flag "--with-python", so the next time you type brew install libxml2 it will install the python libraries.
If you need to reset the formula (undo your changes), simply type
  1. brew update
安裝訊息:
==> ./configure --prefix=/usr/local/Cellar/libxml2/2.8.0 --with-python
==> make
==> make install
==> Caveats
This formula is keg-only, so it was not symlinked into /usr/local.
Mac OS X already provides this program and installing another version in
parallel can cause all kinds of trouble.
Generally there are no consequences of this for you.
If you build your own software and it requires this formula, you'll need
to add its lib & include paths to your build variables:
    LDFLAGS  -L/usr/local/Cellar/libxml2/2.8.0/lib
    CPPFLAGS -I/usr/local/Cellar/libxml2/2.8.0/include

static declaration of 'strnlen' follows non-static declaration error

錯誤訊息
./external/elfutils/config-compat-darwin.h:42: error: static declaration of 'strnlen' follows non-static declaration
/usr/include/string.h:143: error: previous declaration of 'strnlen' was here
make: *** [out/host/darwin-x86/obj/STATIC_LIBRARIES/libelf_intermediates/lib/xmalloc.o] Error 1
原因:
strnlen重複定義
解法:
修改external/elfutils/config-compat-darwin.h, 註解掉strnlen:
#if 0
static inline size_t strnlen (const char *__string, size_t __maxlen)
{
     int len = 0;
     while (__maxlen-- && *__string++)
     len++;
     return len;
}
#endif
Well, at the end of the process I just edited the Android.mk makefile into external/skia adding a new entry for BUILD_STATIC_LIBRARY and the next command was simply:
mmm external/skia
which produced the required libskia.a file to be linked in my project.

libSDL_intermediates/libSDL.a

錯誤訊息:
ld: warning: ignoring file out/host/darwin-x86/obj/STATIC_LIBRARIES/libSDL_intermediates/libSDL.a, file was built for archive which is not the architecture being linked (i386)
Undefined symbols for architecture i386
原因:
qemu
translator_tests
依賴的是i386的libSDL.a
解法一:
先把 external/qemu/Android.mk 的所有內容註釋掉
#ifeq ($(DEFAULT_GOAL),droid)
#    LOCAL_PATH:= $(call my-dir)
#    include $(LOCAL_PATH)/Makefile.android
#else
#    include Makefile.qemu
#endif
再把 sdk/emulator/opengl/Android.mk 下面兩行註解掉
include $(EMUGL_PATH)/tests/translator_tests/MacCommon/Android.mk
#include $(EMUGL_PATH)/tests/translator_tests/GLES_CM/Android.mk
#include $(EMUGL_PATH)/tests/translator_tests/GLES_V2/Android.mk
解法二:
編譯universal版本的libSDL.a
參考下面連結
參考連結

SSE2 instruction set not enabled

錯誤訊息:
error: #error "SSE2 instruction set not enabled
原因:
跟intel cpu有關
所以只出現在android-x86
參考:

MacOSX10.5.sdk

錯誤訊息:
Please install the 10.5 SDK on this machine at /Developer/SDKs/MacOSX10.5.sdk
原因:
此版本android在snow leopard上開發,所以需要10.5 SDK
參考:

Other reference

留言

這個網誌中的熱門文章

Mac起步:常用軟體及設定

台灣可用線上音樂串流網站

醍醐味