48
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

x86_64のUbuntuでC/C++のソースコードをARM/ARM64用にクロスコンパイルしてQEMUで実行する方法のまとめ

はじめに

x86_64のLinux上でQEMUを使ってarm用の実行ファイルを動かす方法は以前に書いたことがあるのですが、最近は「マルチプラットフォームのライブラリをビルドしたときにCIを回す」というユースケースが出てきたので再度まとめてみました。

題材とするソースコードはこれ。

hello.c
#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
}

Ubuntu 16.04 を使用しています。

ネイティブのコンパイルと実行

$ gcc -o hello_native hello.c
$ file hello_native 
hello_native: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ffce96d91ecac8524b1d8af9f37c9e719364df7e, not stripped
$ ./hello_native 
Hello, world!

クロスコンパイラのインストール

sudo apt install g++-arm-linux-gnueabihf

gccしか必要なくても、あえてg++をインストールするのがコツです。そうするとクロスのlibcなど必要な物が全て芋づる式にインストールされます。

クロスコンパイル

$ arm-linux-gnueabihf-gcc -o hello_arm hello.c 
$ file ./hello_arm 
./hello_arm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=9719544312d6cdfb69a31ca70a4655c12e5596d8, not stripped
$ ./hello_arm
-bash: ./hello_arm: cannot execute binary file: Exec format error

そのままではx86_64のUbuntuの上ではARM用の実行ファイルは実行することができません。

QEMUのインストール

sudo apt install qemu-user-binfmt

これでスタティックリンクされたARMの実行ファイルならそのまま実行できるようになります。

$ arm-linux-gnueabihf-gcc -o hello_arm_static -static hello.c 
$ file ./hello_arm_static 
./hello_arm_static: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=72d599d8f0e385a6daa8ebe6216f8fbe8755bda2, not stripped
$ ./hello_arm_static 
Hello, world!

ダイナミックリンクされたARMの実行ファイルは以下のようにクロスのルートディレクトリをQEMUに明示的に指定すれば実行できるようになります。

$ qemu-arm -L /usr/arm-linux-gnueabihf/ ./hello_arm
Hello, world!

ダイナミックリンクされたARMの実行ファイルもそのまま実行できるようにする

sudo ln -s /usr/arm-linux-gnueabihf/lib /lib/arm-linux-gnueabihf
sudo ln -s /lib/arm-linux-gnueabihf/ld-2.23.so /lib/ld-linux-armhf.so.3
$ ./hello_arm
Hello, world!

arm64の場合

arm64のツールチェインの名前が違うだけで同様にできます。

sudo apt install g++-aarch64-linux-gnu qemu-user-binfmt
sudo ln -s /usr/aarch64-linux-gnu/lib/ /lib/aarch64-linux-gnu
sudo ln -s /lib/aarch64-linux-gnu/ld-2.23.so /lib/ld-linux-aarch64.so.1
$ aarch64-linux-gnu-gcc -o hello_arm64 hello.c
$ file ./hello_arm64 
./hello_arm64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=776d40691c4192c0521c641f17b3754b37b73109, not stripped
$ ./hello_arm64 
Hello, world!

参考

QEMUのもうひとつの使い方: ユーザーモードエミュレーションとbinfmtとchrootの組み合わせ
Ubuntu 12.04LTS Beta2でMultiarchを試す
Ubuntu 12.04LTS 正式版でMultiarchを試す

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
48
Help us understand the problem. What are the problem?