M1 Mac(ARM 64bit)で32bit用にクロスコンパイルして実行する方法


今回は、M1 Mac32bitC/C++ライブラリを実行できるようにします。

準備

M1 MacUbuntu 20.04を簡単に扱えるハイパーバイザー型のVMであるmultipassを使う。

Ubuntu20.04ubutu20という名前のインスタンスで立ち上げる。

$ multipass launch 20.04 --name ubuntu20 
$ multipass shell ubuntu20
$ sudo apt install build-essential
.
├── sample.c
├── lib
│   └── libsample.a

1 directories, 2 files

さぁ、やるぞ!

ARMアーキテクチャーは、そのままでは32bitをコンパイルすることはできないため、クロスコンパイルする必要がある。

アーキテクチャ追加

$ sudo dpkg --add-architecture armhf

アップデート

$ sudo apt update

32bit環境用の標準ライブラリをインストールする。

$ sudo apt install libc6:armhf libstdc++6:armhf

シンボリックリンクを追加

$ cd ~
$ cd /lib
$ sudo ln -s arm-linux-gnueabihf/ld-2.23.so ld-linux.so.3

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

$ sudo apt install gcc-arm-linux-gnueabihf

gccarm-linux-gnueabihf-gccに変更

コンパイル実行

$ arm-linux-gnueabihf-gcc -c ./sample.c

リンク実行

libhoge.aの場合、ライブラリ名はhogeになる。

$ arm-linux-gnueabihf-gcc -o sample sample.o -Lライブラリ(lib)の絶対パス -lm -lライブラリ名

QEMUのインストール

そのままでは実行することができない。
そこでQEMUでエミュレートする。

$ sudo apt install qemu-user-binfmt

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

$ qemu-arm -L /usr/arm-linux-gnueabihf/ ./sample

シンボリックリンクを貼ることでそのまま実行できるようにする。

$ sudo ln -s arm-linux-gnueabihf/lib /lib/arm-linux-gnueabihf
$ ./sample

できた!

以上の手順でARM 64bit環境にて32bitライブラリのコンパイル・実行ができた。