Android: ソースからシステムを構築しエミュレータで実行

ダウンロードしたAndroidのソースコードからシステムをBuildして、エミュレータで動かしてみました。
実行したホストのOSはScientific Linux 6.1(i386)です。

   

[ダウンロード] ← ソースツリーのURLが変更されていました。こちら を参照して下さい。(11/5/2011 追記)

以前(Aug./2011)に以下の手順でダウンロードしたソースを使いました。

# mkdir /usr/local/mydroid
# cd /usr/local/mydroid
# curl https://android.git.kernel.org/repo > /usr/local/bin/repo
# chmod 755 /usr/local/bin/repo  ←(11/3/2011 追加。実行権を付ける必要がありました。)
# repo init -u git://android.git.kernel.org/platform/manifest.git
# repo sync

(備考)
上記の手順でソースコードのmasterをダウンロード(チェックアウト)する。
master以外のブランチをチェックアウトする場合は-b で指定すれば良いようです。
例1)
repo init -u https://android.googlesource.com/platform/manifest -b android-2.3.7_r1
例2)
repo init -u https://android.googlesource.com/platform/manifest -b gingerbread

[コンパイル]

$ cd /usr/local/mydroid
 (注: このディレクトリ以下に、実行するユーザのアクセス権を設定)
$ . build/envsetup.sh
including device/htc/passion/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
including device/samsung/crespo4g/vendorsetup.sh
including sdk/bash_completion/adb.bash

(備考)
これにより、次のステップで実行されるlunchコマンドがシェルの関数として定義される。

$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. full-eng
     2. full_x86-eng
     3. vbox_x86-eng
     4. full_passion-userdebug
     5. full_crespo-userdebug
     6. full_crespo4g-userdebug

Which would you like? [full-eng] 1

============================================
PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=3.1.4.1.5.9.2.6.5
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=OPENMASTER
============================================

(備考)
ところで、何で "lunch" コマンドなんだろう? メニューが全然ランチ・メニューらしくないように思うのだが。。

$ make -j2
============================================
PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=3.1.4.1.5.9.2.6.5
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=OPENMASTER
============================================
......................
(途中でnon-fatalなエラーやWarningが出るが、とりあえず無視。)
......................
Install: out/target/product/generic/system/framework/monkey.jar
Install: out/target/product/generic/system/framework/pm.jar
Install: out/target/product/generic/system/framework/sqlite-jdbc.jar
Install: out/target/product/generic/system/framework/svc.jar
Install: out/target/product/generic/system/app/Mms.apk
Copying: out/target/common/obj/APPS/SystemUI_intermediates/noproguard.classes.jar
target Dex: SystemUI
Copying: out/target/common/obj/APPS/SystemUI_intermediates/noproguard.classes.dex
target Package: SystemUI (out/target/product/generic/obj/APPS/SystemUI_intermediates/package.apk)
 'out/target/common/obj/APPS/SystemUI_intermediates//classes.dex' as 'classes.dex'...
Processing target/product/generic/obj/APPS/SystemUI_intermediates/package.apk
Done!
Install: out/target/product/generic/system/app/SystemUI.apk
 'out/target/common/obj/APPS/Settings_intermediates//classes.dex' as 'classes.dex'...
Processing target/product/generic/obj/APPS/Settings_intermediates/package.apk
Done!
Install: out/target/product/generic/system/app/Settings.apk
Finding NOTICE files: out/target/product/generic/obj/NOTICE_FILES/hash-timestamp
Combining NOTICE files: out/target/product/generic/obj/NOTICE.html
Target system fs image: out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img
Install system fs image: out/target/product/generic/system.img
Installed file list: out/target/product/generic/installed-files.txt
(備考)

  • 引数を付けずに単にmakeとするとシングルプロセッサで実行される。-jの後に数値を指定すると、その個数のプロセッサにより並列処理される。
    複数のプロセッサで並列処理するとエラーが出た時はその箇所が若干わかりにくいのでその時は-jを付けずに再実行すると良い。

  • 上記の最後のメッセージにある通り、ramdisk.imgとsystem.imgは < ソースのルート >/out/target/product/generic ディレクトリの下に生成される。
  • Androidのクロスコンパイル環境以外に、ホストの開発環境も必要になる。
    Androidのクロスコンパイル環境はまったく問題なかったが、Scientific Linux 6.1の私が使っている環境では、パッケージ2つを追加でインストールし、ライブラリのシンボリックリンクの設定が1つ必要だった。

    # yum install gperf
    # yum install gcc-c++

    makeの実行途中で次のようなエラーが出たので、

    host Executable: sqlite3
    (out/host/linux-x86/obj/EXECUTABLES/sqlite3_intermediates/sqlite3)
    /usr/bin/ld: cannot find -lhistory
    collect2: ld returned 1 exit status

    以下のようにシンボリックリンクを作成して解決。
    # cd /usr/lib
    # ln -s libhistory.so.6 libhistory.so

[エミュレータで実行]

$ emulator

  • emulatorコマンドは< ソースのルート >/out/host/linux-x86/bin/emulator でも SDKの中のemulatorでも、どちらでも良い。
  • Warningが2つほど出るが、とりあえず無視。
  • lunchコマンドではmakeが参照する上記の環境変数以外に以下のような環境変数も設定する。
    このうち、ANDROID_PRODUCT_OUTによってramdisk.img, system.imgなど、emulatorが参照するファイルの置かれているディレクトリが指定されているので、emulatorコマンドの引数は無しで良い。
    skinは< ソースのルート >/development/tools/emulator/skinsが参照されているようです。

  • $ env | grep ANDROID
    ANDROID_PRE_BUILD_PATHS=/usr/lib/jvm/java-6-sun/bin
    ANDROID_BUILD_TOP=/usr/local/mydroid
    ANDROID_PRODUCT_OUT=/usr/local/mydroid/out/target/product/generic
    ANDROID_JAVA_TOOLCHAIN=/usr/lib/jvm/java-6-sun/bin
    ANDROID_BUILD_PATHS=:/usr/local/mydroid/out/host/linux-x86/bin:/usr/local/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:/usr/local/mydroid/development/emulator/qtools:/usr/local/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:/usr/local/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin
    ANDROID_QTOOLS=/usr/local/mydroid/development/emulator/qtools
    ANDROID_TOOLCHAIN=/usr/local/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin
    ANDROID_EABI_TOOLCHAIN=/usr/local/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin
    ANDROID_HOST_OUT=/usr/local/mydroid/out/host/linux-x86

[adbコマンドでエミュレータにログインして確認]

$ adb -e shell
root@android:/ # df
Filesystem             Size   Used   Free   Blksize
/dev                    45M    32K    45M   4096
/mnt/asec               45M     0K    45M   4096
/mnt/obb                45M     0K    45M   4096
/system                 94M    94M     0K   4096
/data                   64M     3M    60M   4096
/cache                  64M     1M    62M   4096

root@android:/ # mount
rootfs / rootfs ro 0 0
tmpfs /dev tmpfs rw,mode=755 0 0
devpts /dev/pts devpts rw,mode=600 0 0
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
none /acct cgroup rw,cpuacct 0 0
tmpfs /mnt/asec tmpfs rw,mode=755,gid=1000 0 0
tmpfs /mnt/obb tmpfs rw,mode=755,gid=1000 0 0
none /dev/cpuctl cgroup rw,cpu 0 0
/dev/block/mtdblock0 /system yaffs2 ro 0 0
/dev/block/mtdblock1 /data yaffs2 rw,nosuid,nodev 0 0
/dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0
root@android:/ #

[ 参考URL ]
http://source.android.com/source/downloading.html
http://source.android.com/source/building.html
http://source.android.com/source/building-devices.html
http://source.android.com/source/using-eclipse.html