Ubuntu 14.04でarm 64bit(aarch64)のコードをコンパイルして動かしてみる
先日リリースされたqemu 2.0でaarch64がサポートされました。これをソースからビルドして試そうと思ったのですが、実はUbuntu 14.04ではすでにqemu 2.0が入っていました。なので、以下のように簡単にセットアップできます。
$ sudo apt-get install qemu-user-static $ sudo apt-get install g++-aarch64-linux-gnu
テストプログラム
$ cat a.c #includeint main() { int i; for (i = 5; i >=0; i--) { printf("count down: %d\n", i); } return 0; }
まずはこれを普通のnativeのgccでビルドして動かしてみます。
$ gcc a.c $ file a.out a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=34c5e280db12d36ed6cd54264843f8bc3ad95f9e, not stripped $ ./a.out count down: 5 count down: 4 count down: 3 count down: 2 count down: 1 count down: 0
aarch64 static link
qemu-user-staticをインストールしたときにbinfmtの設定も行われているので、aarch64のELFオブジェクトを実行しようとすると自動的にqemu-aarch64-user-staticを経由して実行されるようになっています。
$ aarch64-linux-gnu-gcc -static a.c $ file a.out a.out: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=ed63c597eb6c059a968c91ef21ba4e132376fd32, not stripped $ ./a.out count down: 5 count down: 4 count down: 3 count down: 2 count down: 1 count down: 0
このようにstatic linkされたaarch64の実行ファイルは問題なく実行することができました。
aarch64 dynamic link
次は普通にダイナミックリンクした場合を試してみます。
$ aarch64-linux-gnu-gcc a.c $ file a.out a.out: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.7.0, BuildID[sha1]=8e0f52789566a1c1535495dd4a01805bf3034ed3, not stripped $ ./a.out /lib/ld-linux-aarch64.so.1: No such file or directory
/lib/ld-linux-aarch64.so.1が無いと言われました。このファイルは/usr/aarch64-linux-gnu/にあるので、環境変数QEMU_LD_PREFIXでqemuにそれを伝えることにします。
$ export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/ $ ./a.out count down: 5 count down: 4 count down: 3 count down: 2 count down: 1 count down: 0
これでdynamic linkでも動作するようになりました。
clangでaarch64をクロスビルド
clang/llvmも以下のように簡単にインストールできます。
$ sudo apt-get install clang
これで、さきほどと同じa.cをaarch64向けにクロスビルドしてみます。
$ clang --target=aarch64-linux-gnu a.c In file included from a.c:1: In file included from /usr/include/stdio.h:27: /usr/include/features.h:374:12: fatal error: 'sys/cdefs.h' file not found # include^ 1 error generated.
このようにsys/cdefs.hが見つからないというエラーになってしまいました。
このファイルは/usr/aarch64-linux-gnu/includeにあるので-Iオプションでヘッダファイルの検索パスに追加します。
$ clang --target=aarch64-linux-gnu -I/usr/aarch64-linux-gnu/include a.c $ file a.out a.out: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.7.0, BuildID[sha1]=358fac21a5776ec914d6abfbd67fc2958415261a, not stripped koba@ubuntu1404server:~/aarch64$ ./a.out count down: 5 count down: 4 count down: 3 count down: 2 count down: 1 count down: 0
これでclang/llvmでビルドしたaarch64の実行オブジェクトも動作することが確認できました。