太田一樹。さんのサイトでAndroidのエミュレーターについて書かれていて、この中でNative C applications for Android が紹介されていました。
何やらC言語でソース書いて、クロスコンパイルしてバイナリ作ったらエミュレーターで動いたらしい。
ということで、実際にLinux上でC言語で書いたソースをコンパイルしてエミュレーターで動かしてみました。
なお、私の環境ではAndroidはLinuxとは別のマシンのWindowsで稼動しています。なので、LinuxでコンパイルしてWindowsへコンパイルしたファイルを持ってきて動作させました。
それでは、さっそく。
まずは、Linux上でエミュレーター用のバイナリを作るためのクロスコンパイラーをダウンロードします。
こちらCodeSourcery からダウンロードできます。「On what system will your program run?」で「ARM GNU/Linux」にチェック。「On what system will you run the tools?」で「IA32 GNU/Linux」をチェックします。
なぜかダウンロード完了でブラウザ(Firefox)がフリーズしました。謎。
ダウンロードしてきたら、まずは解凍します。Linux上での解凍は以下の通り。
[root@localhost src]# bunzip2 arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
[root@localhost src]#
[root@localhost src]# tar xf arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar
[root@localhost src]#
rootユーザーでダウンロード解凍したので解凍したディレクトリをgoogleユーザーのディレクトリに移動して、オーナーとグループを変えておきます。このソフト、インストールする必要が無いのでrootで落とす必要なかった…。
[root@localhost src]# mv arm-2007q3 /home/google/
[root@localhost google]# chown -R google:google arm-2007q3/
[root@localhost google]# su - google
シンボリックリンクをはっておきます。
[google@localhost ~]$ ln -s arm-2007q3 arm
C言語のソースを置く場所としてsrc_cディレクトリを作成します。
[google@localhost android]$ mkdir src_c
[google@localhost android]$ cd src_c/
[google@localhost src_c]$ ls
[google@localhost src_c]$
[google@localhost src_c]$ pwd
/home/google/android/src_c
画面に「Hello,Android!」と表示するCプログラムを書きます。
[google@localhost src_c]$ vi hello.c
中はこんな感じ。
[google@localhost src_c]$ more hello.c
#include <stdio.h>
int main(void) {
printf("Hello, Android!\n");
return 0;
}
/home/google/arm/binにパスを通しておきます。
[google@localhost ~]$ vi .bashrc
[google@localhost ~]$
[google@localhost ~]$ more .bashrc
# .bashrc
# User specific aliases and functions
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
#PAHT
export PATH=$PATH:/home/google/android/android_sdk/tools
export PATH=$PATH:/home/google/arm/bin
export ANT_HOME=$ANT_HOME:/home/google/ant
export PATH=$PATH:$ANT_HOME/bin
追加したパスを有効にします。
[google@localhost ~]$ source .bashrc
パスが通っているか確認。
[google@localhost ~]$ which arm-none-linux-gnueabi-gcc
~/arm/bin/arm-none-linux-gnueabi-gcc
Androidエミュ上でhello.cが動作するようにコンパイルします。
(コンパイルというよりAndroidエミュ上で動くようにLinux上でソースをコンパイルするのでクロスコンパイルですが…)
[google@localhost src_c]$ arm-none-linux-gnueabi-gcc -static hello.c -o hello
[google@localhost src_c]$ ls
hello hello.c
無事コンパイルできてhelloというファイルができました。このhelloをLinuxからエミュレーターの動作しているWindowsに持ってきて、エミュレーター上で動作させてみます。
最初にAndroidエミュレーターを起動しておきます。それからコマンドプロンプトを起動させます。
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
コマンドプロンプトが起動したらhelloファイルの置いてある場所に移動します。
C:\cd C:\eclipse\android_sdk_windows_m3-rc20a\tools
ちゃんとhelloがあるか確認します。
C:\eclipse\android_sdk_windows_m3-rc20a\tools>dir
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は 98FF-5459 です
C:\eclipse\android_sdk_windows_m3-rc20a\tools のディレクトリ
2007/11/21 11:27 <DIR> .
2007/11/21 11:27 <DIR> ..
2007/11/11 13:41 11,390,753 aapt.exe
2007/11/11 13:41 44,693 acp.exe
2007/11/11 13:41 720 activityCreator.bat
2007/11/11 13:41 2,238,153 adb.exe
2007/11/11 13:41 106,496 AdbWinApi.dll
2007/11/11 13:41 1,223,792 aidl.exe
2007/11/11 13:41 1,532 ddms.bat
2007/11/11 13:41 1,331 dx.bat
2007/11/11 13:41 1,719,296 emulator.exe
2007/11/21 11:27 568,045 hello
2007/11/14 09:25 <DIR> lib
2007/11/11 13:41 65,024 mgwz.dll
2007/11/11 13:41 28,443 mksdcard.exe
2007/11/11 13:01 111,549 NOTICE
2007/11/14 09:26 582 tools へのショートカット.lnk
14 個のファイル 17,500,409 バイト
3 個のディレクトリ 17,413,636,096 バイトの空き領域
helloファイルをエミュ上のdataディレクトリ下に送ります。
C:\eclipse\android_sdk_windows_m3-rc20a\tools>adb push hello data/hello
563 KB/s (0 bytes in 568045.000s)
dataディレクトリに置いたhelloを実行してみます。
C:\eclipse\android_sdk_windows_m3-rc20a\tools>adb shell data/hello
data/hello: permission denied
おふっ!「パーミッションがダメです。」って…
Androidエミュのシェルにログインしてdataディレクトリのhelloを見てみます。
C:\eclipse\android_sdk_windows_m3-rc20a\tools>adb shell
#
# su
su
# ls data
ls data
-rw-rw-rw- root root 568045 2007-11-21 02:27 hello
drwxrwxrwx root root 2007-11-14 00:27 dalvik-cache
drwxrwxrwx root root 2007-11-14 00:27 system
drwxrwxrwx system system 2007-11-14 00:27 drm
drwxrwxrwx system system 2007-11-14 00:27 logs
drwxrwxrwx system system 2007-11-11 20:57 misc
drwxrwxrwx system system 2007-11-14 00:27 download
drwxrwx--x system system 2007-11-14 00:27 data
drwxrwx--x system system 2007-11-11 20:59 app
drw-rw-rw- root root 2007-11-21 02:27 lost+found
-rw-rw-rw- hello 思いっきり実行権限無いですねw
実行権限を与えます。
# chmod 775 data/hello
chmod 775 data/hello
# ls data
ls data
-rwxrwxr-x root root 568045 2007-11-21 02:27 hello
drwxrwxrwx root root 2007-11-14 00:27 dalvik-cache
drwxrwxrwx root root 2007-11-14 00:27 system
drwxrwxrwx system system 2007-11-14 00:27 drm
drwxrwxrwx system system 2007-11-14 00:27 logs
drwxrwxrwx system system 2007-11-11 20:57 misc
drwxrwxrwx system system 2007-11-14 00:27 download
drwxrwx--x system system 2007-11-14 00:27 data
drwxrwx--x system system 2007-11-11 20:59 app
drw-rw-rw- root root 2007-11-21 02:27 lost+found
#
実行してみます。
# data/hello
data/hello
Hello, Android!
#
動いた!
調子にのってshobo_cat.cという引数で指定したファイルの中身を標準出力へ書き出すプログラムをエミュレーター上で動作させてみます。オプションの無いcatコマンドなので、しょぼいcatということで、shobo_cat.cです。
さきほどと同じ要領でLinux上でプログラム書いて、コンパイルします。
[google@localhost src_c]$ vi shobo_cat.c
[google@localhost src_c]$ more shobo_cat.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static void do_cat(const char *path);
static void die(const char *s);
int main (int argc, char *argv[]) {
int i;
if (argc < 2) {
fprintf(stderr, "%s: No such file or directory!\n", argv[0]);
exit(1);
}
for (i = 1; i < argc ; i++ ) {
do_cat(argv[i]);
}
exit(0);
}
#define BUFFER_SIZE 2048
static void do_cat(const char *path) {
int fd;
unsigned char buf[BUFFER_SIZE];
int n;
fd = open(path, O_RDONLY);
if (fd < 0) die(path);
for (;;) {
n = read(fd, buf, sizeof buf);
if (n < 0) die(path);
if (n == 0) break;
if (write(STDOUT_FILENO, buf, n) < 0) die(path);
}
if (close(fd) < 0) die(path);
}
static void die(const char *s) {
perror(s);
exit(1);
}
[google@localhost src_c]$ arm-none-linux-gnueabi-gcc -static shobo_cat.c -o shobo_cat
[google@localhost src_c]$ ls -lt
合計 576
-rwxrwxr-x 1 google google 5689 11月 21 12:04 shobo_cat
-rw-rw-r-- 1 google google 806 11月 21 12:04 shobo_cat.c
-rwxrwxr-x 1 google google 568045 11月 21 11:23 hello
-rw-rw-r-- 1 google google 83 11月 21 11:07 hello.c
shobo_catができました。
*shobo_catについて、参考 ふつうのLinuxプログラミング
helloと同じ要領で、shobo_catをWindowsに持ってきてエミュレーター上で動作させます。
C:\eclipse\android_sdk_windows_m3-rc20a\tools>adb push shobo_cat data/shobo_cat
634 KB/s (0 bytes in 568440.000s)
C:\eclipse\android_sdk_windows_m3-rc20a\tools>adb shell
# cd data
cd data
# ls
ls
-rw-rw-rw- root root 568440 2007-11-21 03:12 shobo_cat
-rw-rw-rw- root root 4 2007-11-21 02:51 hoge.txt
-rw-rw-rw- root root 568045 2007-11-21 02:27 hello
drwxrwxrwx root root 2007-11-14 00:27 dalvik-cache
drwxrwxrwx root root 2007-11-14 00:27 system
drwxrwxrwx system system 2007-11-14 00:27 drm
drwxrwxrwx system system 2007-11-14 00:27 logs
drwxrwxrwx system system 2007-11-11 20:57 misc
drwxrwxrwx system system 2007-11-14 00:27 download
drwxrwx--x system system 2007-11-14 00:27 data
drwxrwx--x system system 2007-11-11 20:59 app
drw-rw-rw- root root 2007-11-21 02:27 lost+found
# chmod 775 shobo_cat
chmod 775 shobo_cat
# ./shobo_cat hoge.txt
./shobo_cat hoge.txt
hoge#
↑
動いた!けど、なんか改行ができてねええ
以上です。頑張ればWEBサーバーだろうが、何だろうが動きそうですね。