0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ビルドシステム入門#4】クロスコンパイル入門 ― Makefile・Autotools・CMakeでARM Linux向けビルドを理解する

0
Last updated at Posted at 2026-06-16

はじめに

組み込みLinux開発では「手元のx86_64マシンでARM向けバイナリを作る」という作業が日常的に発生します。これがクロスコンパイルです。本記事では第1〜3回で使ったサンプルプロジェクトをそのまま使い、各ビルドシステムでクロスコンパイルをどう設定するかを比較します。

本シリーズは当初、第3回(CMake入門)で完結とする予定でした。しかし「ビルドシステムの基本を理解した上で、実際に手を動かして具体的な成果物を作ってみたい」という目的のもと、当初の計画には無かった第4回を追加することにしました。

本記事はシリーズの第4回です。


クロスコンパイルとは

通常のビルドは「ビルドするマシン」と「実行するマシン」が同じです。クロスコンパイルはこれらが異なります。

【通常のビルド】
x86_64 PC  →  ビルド  →  x86_64向けバイナリ  →  x86_64 PCで実行

【クロスコンパイル】
x86_64 PC  →  ビルド  →  ARM向けバイナリ  →  Raspberry Pi等で実行

組み込み機器はCPUパワーが限られるため、高性能な開発機でビルドして機器に転送するのが一般的です。


ターゲットトリプルとは

クロスコンパイルでは「何向けのバイナリを作るか」をターゲットトリプルという文字列で表します。

arm - linux - gnueabihf
 ↑      ↑        ↑
CPU   OS      ABI(Application Binary Interface)
フィールド 今回の値 意味
CPU arm ARMアーキテクチャ
OS linux Linux上で動作
ABI gnueabihf GNU libc、ハードウェア浮動小数点

本記事では arm-linux-gnueabihf をターゲットとします。Raspberry Pi 2/3/4(32bitモード)向けのバイナリが生成されます。


ツールチェーンのインストール

Ubuntu / Debian

32ビットARM Linux向けのクロスコンパイラは以下でインストールできます。

sudo apt update
sudo apt install gcc-arm-linux-gnueabihf

macOS

brew install arm-linux-gnueabihf-binutils
# GCC本体はHomebrewのtapから
brew tap messense/macos-cross-toolchains
brew install arm-unknown-linux-gnueabihf

インストール確認

arm-linux-gnueabihf-gcc --version
# arm-linux-gnueabihf-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

動作確認はQEMUで

実機がなくてもQEMUでARMバイナリを実行できます。

# Ubuntu
sudo apt install qemu-user

# macOS
brew install qemu
# ARMバイナリをx86_64マシン上で実行
qemu-arm ./hello

サンプルプロジェクト

第1〜3回と同じ構成を使います。

sample/
├── include/
│   └── greet.h
└── src/
    ├── main.c
    └── greet.c

Cのソースコードは変更不要です。ビルドシステム側の設定だけを変えます。


1. Makefileでクロスコンパイル

Makefileでのクロスコンパイルは非常にシンプルです。CC 変数をクロスコンパイラに差し替えるだけです。

方法①:変数を直接書き換える

# ターゲット名
TARGET   = hello

# クロスコンパイラを指定
CC       = arm-linux-gnueabihf-gcc
CFLAGS   = -Wall -Wextra -I./include
DEPFLAGS = -MMD -MP

SRCS     = src/main.c src/greet.c
OBJS     = $(SRCS:.c=.o)
DEPS     = $(OBJS:.o=.d)

.PHONY: all clean
all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) -o $@ $^

%.o: %.c
	$(CC) $(CFLAGS) $(DEPFLAGS) -c $< -o $@

-include $(DEPS)

clean:
	rm -f $(TARGET) $(OBJS) $(DEPS)

方法②:コマンドラインから上書きする(推奨)

Makefileはネイティブビルド用のままにしておき、実行時に CC を上書きする方法が柔軟で使いやすいです。

# ネイティブビルド(従来通り)
make

# クロスコンパイル(CCを上書き)
make CC=arm-linux-gnueabihf-gcc

方法③:CROSS_COMPILE変数を使う

Linuxカーネルのビルドなどで広く使われている慣習です。

CROSS_COMPILE ?=
CC = $(CROSS_COMPILE)gcc
# ネイティブビルド
make

# クロスコンパイル
make CROSS_COMPILE=arm-linux-gnueabihf-

CROSS_COMPILE にプレフィックスを設定すると $(CROSS_COMPILE)gccarm-linux-gnueabihf-gcc になります。

ビルドと動作確認

make CC=arm-linux-gnueabihf-gcc

# ARMバイナリであることを確認
file hello
# hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)...

# QEMUで実行
qemu-arm ./hello
# Hello, World!
# Hello, Qiita!

2. Autotoolsでクロスコンパイル

Autotoolsは ./configure--host オプションを渡すだけでクロスコンパイルに対応できます。これがAutotoolsの大きな利点のひとつです。

クロスコンパイル時は --host オプションに実行するターゲットマシンを指定します。

./configure --host=arm-linux-gnueabihf
make

--host を指定すると ./configure は自動的に arm-linux-gnueabihf-gcc をCコンパイラとして使用します。configure.acMakefile.am変更不要です。

実際の手順

# Autotoolsファイルを生成(開発者側の作業)
autoreconf -i

# out-of-sourceビルドディレクトリを作成
mkdir build_arm && cd build_arm

# クロスコンパイル向けにconfigureを実行
../configure --host=arm-linux-gnueabihf

# ビルド
make

# 確認
file src/hello
# src/hello: ELF 32-bit LSB executable, ARM...

# QEMUで実行
qemu-arm src/hello

--build / --host / --target の違い

Autotoolsには似た名前のオプションが3つあります。

オプション 意味 今回の例
--build ビルドを実行するマシン x86_64-linux-gnu(省略可、自動検出)
--host 生成したバイナリが動くマシン arm-linux-gnueabihf
--target コンパイラ自体が生成するコードの対象 コンパイラをビルドする場合のみ使用

通常のクロスコンパイルでは --host だけ指定すれば十分です。


3. CMakeでクロスコンパイル

CMakeのクロスコンパイルはツールチェーンファイル.cmake ファイル)を使うのが標準的なやり方です。

ツールチェーンファイルはCMakeにターゲットプラットフォームのすべての情報を伝えるための別ファイルです。CMAKE_SYSTEM_NAME、コンパイラへのパス、CMAKE_FIND_ROOT_PATH の設定が必須の要素です。

ツールチェーンファイルを作成する

# toolchain-arm-linux-gnueabihf.cmake

# ターゲットOSとCPUアーキテクチャを指定
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# クロスコンパイラを指定
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)

# find_*コマンドの検索先をターゲット環境に限定する
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)   # ツール類はホスト環境を使う
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)    # ライブラリはターゲット環境のみ
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)    # ヘッダはターゲット環境のみ
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)    # パッケージはターゲット環境のみ

ツールチェーンファイルは -DCMAKE_TOOLCHAIN_FILE オプションで指定します。最初の cmake 実行時に1度指定すれば、以降はキャッシュから読み込まれます。

ビルド手順

# ツールチェーンファイルを指定してconfigureステップを実行
cmake -S . -B build_arm \
    -DCMAKE_TOOLCHAIN_FILE=toolchain-arm-linux-gnueabihf.cmake

# ビルド
cmake --build build_arm

# 確認
file build_arm/src/hello
# build_arm/src/hello: ELF 32-bit LSB executable, ARM...

# QEMUで実行
qemu-arm build_arm/src/hello
# Hello, World!
# Hello, Qiita!

CMakeLists.txt変更不要です。ツールチェーンファイルを差し替えるだけで別のターゲットに対応できます。

ツールチェーンファイルを使う利点

ツールチェーンファイルを使うことで、CMakeLists.txt はクロスコンパイルの存在を意識せずに書けます。if(WIN32)if(UNIX) といった条件分岐もツールチェーンファイルの設定に基づいて正しく評価されます。

複数のターゲット向けにビルドする場合も、ターゲットごとにツールチェーンファイルを用意するだけです。

toolchains/
├── toolchain-arm-linux-gnueabihf.cmake    # ARM 32bit Linux
├── toolchain-aarch64-linux-gnu.cmake      # ARM 64bit Linux
└── toolchain-x86_64-linux-gnu.cmake       # x86_64 Linux(ネイティブ)

3つのビルドシステムの比較

項目 Makefile Autotools CMake
設定方法 CC 変数を上書き --host オプション ツールチェーンファイル
ソースの変更 不要(方法②③の場合) 不要 不要
記述量 最小 最小 ツールチェーンファイルが必要
複数ターゲット対応 工夫が必要 オプションで切り替え ファイルを差し替えるだけ
再利用性 低い 中程度 高い(ファイルを使い回せる)

Makefileは手軽ですが、複数ターゲットを管理するとMakefileが複雑になります。CMakeのツールチェーンファイルはターゲットごとに独立しているため、プロジェクトが大きくなるほど管理しやすくなります。


まとめ

ビルドシステム クロスコンパイルのキーワード
Makefile CC=arm-linux-gnueabihf-gcc または CROSS_COMPILE=arm-linux-gnueabihf-
Autotools ./configure --host=arm-linux-gnueabihf
CMake -DCMAKE_TOOLCHAIN_FILE=toolchain-arm-linux-gnueabihf.cmake

どのビルドシステムも CMakeLists.txtMakefile.am などのビルド定義ファイルを変更せずにクロスコンパイルできる点が重要なポイントです。「どこでビルドするか」と「何をビルドするか」を分離するのがクロスコンパイル設定の基本的な考え方です。


参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?