「Raspberry Pi 用のバイナリを手元の Ubuntu マシンでビルドしたい」「ARM64向けのDockerイメージを x86 環境で作りたい」——そんな場面で役立つのがクロスコンパイルです。Ubuntu には gcc-aarch64-linux-gnu というクロスコンパイラが apt で1コマンド入ります。私の環境(Ubuntu 24.04 LTS / Docker上)で実際に aarch64 向けバイナリを生成して確認しました。
この記事のポイント
apt-get install gcc-aarch64-linux-gnuで x86_64 ホストに ARM64クロスコンパイラが入る- コンパイル後は
fileコマンドで「ARM aarch64」と表示されるか確認する -staticオプションで依存なし単体バイナリを作れる(ただしサイズは約9倍)- Ubuntu 24.04 では GCC 13.3.0 / Binutils 2.42 が入る(22.04 は GCC 11.4.0 / Binutils 2.38)
- Makefile に
CC = aarch64-linux-gnu-gccを書けばプロジェクトで使い回せる
クロスコンパイルとは
通常のコンパイルは「ビルドするマシン」と「実行するマシン」が同じアーキテクチャです。クロスコンパイルはこの2つが異なる場合に使います。たとえば x86_64 の Ubuntu マシンで、ARM64(aarch64)向けのバイナリを作ることがこれにあたります。

ARM64(aarch64)は ARMv8 アーキテクチャの64bit版で、Raspberry Pi 4/5、Apple M1/M2、AWS Graviton、Ampere Altra などが採用しています。x86_64 マシンしか手元にない場合でも、クロスコンパイラがあれば実機なしに ARM64 バイナリを生成できます。
前提環境
動作確認環境
Ubuntu 24.04 LTS(Docker公式イメージ ubuntu:24.04)で検証しています。Ubuntu 22.04 でも同じ手順で動きますが、インストールされる GCC バージョンが異なります(後述)。
クロスコンパイラをインストールする
手順1:パッケージリストを更新する
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Fetched 30.9 MB in 2s (19.4 MB/s)
Reading package lists… Done
手順2:クロスコンパイラとリンカをインストールする
Setting up gcc-13-aarch64-linux-gnu (13.3.0-6ubuntu2~24.04.1cross1) …
Setting up binutils-aarch64-linux-gnu (2.42-4ubuntu2.10) …
Setting up gcc-aarch64-linux-gnu (4:13.2.0-7ubuntu1) …

インストールが終わったらバージョンを確認します。
aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0
Copyright (C) 2023 Free Software Foundation, Inc.
$ aarch64-linux-gnu-ld –version | head -1
GNU ld (GNU Binutils for Ubuntu) 2.42

Ubuntu 24.04 では GCC 13.3.0 と GNU Binutils 2.42 が入りました。これで ARM64 向けの C/C++ プログラムをビルドする準備が整っています。
実際にクロスコンパイルしてみる
手順3:サンプルの C プログラムを作る
#include <stdio.h>
int main(void) {
printf(“Hello from aarch64!\n”);
return 0;
}
手順4:aarch64向けにコンパイルする
コンパイラ名の先頭に aarch64-linux-gnu- をつけることがポイントです。ここを省略すると x86_64 バイナリが生成されてしまいます。
(エラーなし・正常終了)
手順5:file コマンドで ARM64 バイナリか確認する
hello_arm64: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux-aarch64.so.1,
for GNU/Linux 3.7.0, not stripped
$ ls -lh hello_arm64
-rwxr-xr-x 1 root root 69K Jun 22 04:05 hello_arm64

「ARM aarch64」という表記が出れば成功です。 x86_64 のホスト上で、ARM64向けの ELF バイナリが正しく生成できています。バイナリサイズは 69KB でした。

動的リンクと静的リンクの違い
クロスコンパイルで生成したバイナリには「動的リンク」と「静的リンク」の2種類があります。用途で使い分けが必要です。
動的リンクバイナリ(デフォルト)
$ file bench_dyn
bench_dyn: ELF 64-bit LSB pie executable, ARM aarch64 … dynamically linked
$ ls -lh bench_dyn
-rwxr-xr-x 1 root root 69K Jun 22 04:06 bench_dyn
静的リンクバイナリ(-static オプション)
$ file bench_static
bench_static: ELF 64-bit LSB executable, ARM aarch64 … statically linked
$ ls -lh bench_static
-rwxr-xr-x 1 root root 619K Jun 22 04:06 bench_static

静的リンクにするとサイズが 69KB → 619KB と約9倍になりますが、ターゲット環境に libc.so が不要になります。Alpine Linux ベースのコンテナや最小構成の組み込みシステムに転送する場合は静的リンクが楽です。Raspberry Pi OS(Debian ベース)のように libc が入っているなら動的リンクで十分です。
Makefile でクロスコンパイルをまとめる
毎回 aarch64-linux-gnu-gcc と打つのは手間なので、Makefile に CC 変数を定義しておくと便利です。私は環境変数で切り替えられるようにしています。
CC = aarch64-linux-gnu-gcc
CFLAGS = -Wall -O2
TARGET = app_arm64
$(TARGET): main.c
$(CC) $(CFLAGS) -o $(TARGET) main.c
clean:
rm -f $(TARGET)
$ make
aarch64-linux-gnu-gcc -Wall -O2 -o app_arm64 main.c
$ ls -lh app_arm64
-rwxr-xr-x 1 root root 69K Jun 22 04:07 app_arm64
make を実行すると aarch64-linux-gnu-gcc -Wall -O2 -o app_arm64 main.c が走り、正常に ARM64 バイナリが生成されました。既存の Makefile を流用するなら CC 変数を上書きするだけで済みます。
(既存Makefileの CC 変数を外から上書き)
Ubuntu 22.04 vs 24.04 — ツールチェーンのバージョン差
Docker コンテナで両バージョンを実際に確認しました。GCC のメジャーバージョンが変わっているので注意してください。

| ツール | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
|---|---|---|
| aarch64-linux-gnu-gcc | 11.4.0 | 13.3.0 |
| aarch64-linux-gnu-ld | 2.38 | 2.42 |
| gcc-aarch64-linux-gnu パッケージ | 4:11.2.0-1ubuntu1 | 4:13.2.0-7ubuntu1 |
Ubuntu 24.04 では GCC 13.3.0 が入り、C17 や C++23 の機能が使えます。22.04 の GCC 11.4.0 でも ARM64 クロスコンパイル自体は問題なく動きますが、新しい言語機能を使う場合は 24.04 を選ぶのが安全です。実際に docker コンテナで確認した数値なので、インターネット上のスクリーンショットと異なる場合はパッケージのアップデートが入った可能性があります。
よくあるエラーと解決策
①「cannot execute binary file: Exec format error」が出る
bash: ./hello_arm64: cannot execute binary file: Exec format error
これは正常です。ARM64 バイナリを x86_64 ホストで直接実行しようとするとこのエラーになります。ARM64 マシンや Raspberry Pi に転送して実行するか、qemu-user-static をインストールして qemu-aarch64-static ./hello_arm64 とすれば x86_64 ホストでもエミュレーション実行できます。
②「/usr/bin/aarch64-linux-gnu-gcc: No such file or directory」が出る
インストールが完了していないか、パッケージ名を間違えている場合です。apt-get install gcc-aarch64-linux-gnu(ハイフン2本で分かれている)を再度実行してください。apt-cache show gcc-aarch64-linux-gnu でパッケージが存在するか確認できます。
③静的リンクで「cannot find -lgcc」が出る
注意
-static オプションを使うとき、libgcc-s1-arm64-cross や libc6-dev-arm64-cross が不足するとリンクエラーになります。その場合は apt-get install libc6-dev-arm64-cross を追加でインストールしてください。
④「aarch64-linux-gnu-gcc: command not found」が出る
インストール後に hash -r(bash のコマンドキャッシュをリセット)を実行してみてください。それでも見つからない場合は ls /usr/bin/aarch64-linux-gnu-* でバイナリの存在を確認します。
まとめ
- Ubuntu 24.04 に
apt-get install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnuで ARM64 クロスコンパイル環境が整う - インストールされる GCC は 13.3.0、GNU Binutils は 2.42(Ubuntu 24.04 実測)
- コンパイルは
aarch64-linux-gnu-gcc -o 出力ファイル ソース.cで実行する fileコマンドで「ARM aarch64」と表示されたら ARM64 バイナリとして正しく生成されている- 静的リンク(
-static)にするとバイナリサイズが約9倍になる代わりに、ターゲット環境の libc が不要になる - Makefile の
CC変数を差し替えるだけで既存プロジェクトにも適用できる
VPS でクロスコンパイル環境を構築すると、Raspberry Pi への自動デプロイパイプラインと組み合わせて使えます。学習用 VPS の選び方は以下の記事が参考になります。



コメント