目次
-
クロスコンパイルが必要な理由
-
ユニバーサルビルドアーキテクチャ
-
ホストマシンセットアップ
-
Docker ビルドコンテナ(コアの部分)
-
Cargo 設定
-
ビルドスクリプト
-
マルチターゲット対応マトリックス
-
新しいターゲットデバイスを追加する
-
CI/CDテンプレート
-
デプロイメントパッケージ構成
-
検証とテスト
-
よくある落とし穴と修正方法
1. クロスコンパイルが必要な理由
Tinkerboard のような ARM SBC で直接コンパイルするには 1 ビルドあたり約 18 分かかります。x86_64 ホストでクロスコンパイルすると約 2~4 分で済みます。本番規模では、デバイス上でビルドすることはありません。高速マシンで一度ビルドしてバイナリをプッシュします。 このガイドの目的は、単一のビルドシステムを構築し、任意の Tauri アプリを実行する任意の ARM Linux デバイスをターゲットにできるようにすることで、アプリを変更したりハードウェアを切り替えたりするたびに再設定する必要がないようにすることです。
2. ユニバーサルビルドアーキテクチャ
YOUR CODE (any Tauri app)
│
▼
┌──────────────────────────────────────────┐
│ DOCKER BUILD CONTAINER │
│ │
│ x86_64 host kernel │
│ ┌────────────────────────────────────┐ │
│ │ Rust toolchain │ │
│ │ ├── native x86_64 compiler │ │
│ │ └── cross targets: │ │
│ │ ├── armv7-unknown-linux-gnueabihf (Tinkerboard, RPi 2/3/4 32-bit)
│ │ └── aarch64-unknown-linux-gnu (RPi 4/5 64-bit, Jetson)
│ │ │ │
│ │ ARM sysroots │ │
│ │ ├── armhf libs (WebKitGTK, GTK3) │ │
│ │ └── arm64 libs (WebKitGTK, GTK3) │ │
│ │ │ │
│ │ Cross linkers │ │
│ │ ├── arm-linux-gnueabihf-gcc │ │
│ │ └── aarch64-linux-gnu-gcc │ │
│ │ │ │
│ │ Node.js (frontend build) │ │
│ │ Tauri CLI │ │
│ └────────────────────────────────────┘ │
│ │
│ INPUT: /app (your project, mounted) │
│ OUTPUT: .deb package for target arch │
└──────────────────────────────────────────┘
│
▼
┌──────────────────────┐
│ .deb / binary │
│ ready for any │
│ ARM Linux device │
└──────────────────────┘
重要な洞察:Docker コンテナがビルドシステムそのものです。アプリコードはクロスコンパイルについて心配する必要がありません。コンテナが全てを処理します。ツールチェーン、sysroot、リンカー、環境変数。プロジェクトをマウントするだけで .deb が出力されます。
3. ホストマシンセットアップ
開発マシン(macOS、Linux、または WSL2 搭載 Windows)に必要なのは 2 つだけです。
3.1 Docker をインストール
# Linux
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# macOS — Docker Desktop をインストール
# Windows — WSL2 バックエンド付き Docker Desktop をインストール
3.2 Rust をインストール(ローカル開発/テストのみ)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
ホスト上にクロスコンパイルツールは不要です。全て Docker 内で実行されます。
4. Docker ビルドコンテナ(コアの部分)
これはシステム全体の中核です。ARMv7 と ARM64 ターゲットの両方をサポートする 1 つの Dockerfile です。
4.1 Dockerfile
# ============================================================
# Dockerfile.cross
# Universal Tauri cross-compilation container
# Supports: armv7 (armhf) and aarch64 (arm64)
# Base: Debian Bookworm (matches Debian 12 target devices)
# ============================================================
FROM debian:bookworm-slim
ARG DEBIAN_FRONTEND=noninteractive
# ── 1. Host build essentials ──
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gnupg2 \
ca-certificates \
build-essential \
pkg-config \
curl \
wget \
file \
python3 && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# ── 2. ARM cross-compiler toolchains ──
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf \
libc6-dev-armhf-cross \
gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu \
libc6-dev-arm64-cross && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# ── 3. Rust with both ARM targets ──
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- -y \
--target armv7-unknown-linux-gnueabihf \
--target aarch64-unknown-linux-gnu
ENV PATH="/root/.cargo/bin:${PATH}"
# ── 4. Node.js (for Tauri frontend builds) ──
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get update && \
apt-get install -y --no-install-recommends nodejs && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# ── 5. ARM sysroot libraries (the critical part) ──
# Enable both ARM architectures in dpkg
RUN dpkg --add-architecture armhf && \
dpkg --add-architecture arm64
# Install Tauri runtime dependencies for both architectures
RUN apt-get update && \
apt-get install -y --no-install-recommends \
# ── armhf (ARMv7: Tinkerboard, RPi 32-bit) ──
libwebkit2gtk-4.1-dev:armhf \
libssl-dev:armhf \
libgtk-3-dev:armhf \
libayatana-appindicator3-dev:armhf \
librsvg2-dev:armhf \
# ── arm64 (ARMv8: RPi 64-bit, Jetson, etc.) ──
libwebkit2gtk-4.1-dev:arm64 \
libssl-dev:arm64 \
libgtk-3-dev:arm64 \
libayatana-appindicator3-dev:arm64 \
librsvg2-dev:arm64 && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# ── 6. Tauri CLI ──
RUN cargo install tauri-cli
# ── 7. Cargo cross-compilation config ──
RUN mkdir -p /root/.cargo && \
printf '[target.armv7-unknown-linux-gnueabihf]\n\
linker = "arm-linux-gnueabihf-gcc"\n\
\n\
[target.aarch64-unknown-linux-gnu]\n\
linker = "aarch64-linux-gnu-gcc"\n' \
> /root/.cargo/config.toml
WORKDIR /app
# ── 8. Default build entrypoint ──
COPY build.sh /usr/local/bin/build.sh
RUN chmod +x /usr/local/bin/build.sh
ENTRYPOINT ["/usr/local/bin/build.sh"]
4.2 Debian vs Ubuntu ベースに関する注記
ベースとして debian:bookworm-slim を使用することは意図的です:
-
Tinkerboard の Debian 12 と一致します(glibc バージョンが同じ)
-
dpkg --add-architectureコマンドは Debian 上で/etc/apt/sources.listを変更せずに動作します -
Ubuntu ベースイメージを使用する場合は、
sources.listに ARM パッケージソースを手動で追加し、[arch=amd64]タグでネイティブソースを制限する必要があります。これは一般的なビルド失敗の原因です
5. Cargo 設定
このファイルはプロジェクト内の <project-root>/.cargo/config.toml に存在します。Docker イメージにも組み込まれていますが、プロジェクト内に存在することでローカル開発が簡単になります。
# .cargo/config.toml
# Cross-compilation linker mapping
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
# Uncomment to set a default target (optional)
# [build]
# target = "armv7-unknown-linux-gnueabihf"
6. ビルドスクリプト
これは Docker コンテナが実行するエントリーポイントスクリプトです。ターゲットごとに環境セットアップを自動的に処理します。
6.1 build.sh
#!/bin/bash
set -euo pipefail
# ============================================================
# build.sh — Universal Tauri cross-compilation build script
# Usage: ./build.sh \\<target> [extra cargo args]
#
# Targets:
# armv7 → armv7-unknown-linux-gnueabihf
# arm64 → aarch64-unknown-linux-gnu
# native → host architecture (for testing)
# ============================================================
TARGET="${1:-armv7}"
shift 2>/dev/null || true
case "$TARGET" in
armv7|armhf)
RUST_TARGET="armv7-unknown-linux-gnueabihf"
export PKG_CONFIG_SYSROOT_DIR="/usr/arm-linux-gnueabihf/"
export PKG_CONFIG_PATH="/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig"
;;
arm64|aarch64)
RUST_TARGET="aarch64-unknown-linux-gnu"
export PKG_CONFIG_SYSROOT_DIR="/usr/aarch64-linux-gnu/"
export PKG_CONFIG_PATH="/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig"
;;
native|host)
RUST_TARGET=""
;;
*)
echo "ERROR: Unknown target '$TARGET'"
echo "Usage: build.sh <armv7|arm64|native> [cargo args]"
exit 1
;;
esac
export PKG_CONFIG_ALLOW_CROSS=1
# Install frontend dependencies if package.json exists
if [ -f "package.json" ]; then
echo "==> Installing frontend dependencies..."
npm install --prefer-offline 2>/dev/null || npm install
fi
# Build
if [ -n "$RUST_TARGET" ]; then
echo "==> Cross-compiling for $RUST_TARGET..."
cargo tauri build --target "$RUST_TARGET" "$@"
echo ""
echo "==> Build complete. Output:"
find "target/$RUST_TARGET/release/bundle" -name "*.deb" 2>/dev/null || \
find "target/$RUST_TARGET/release" -maxdepth 1 -type f -executable
else
echo "==> Building for native host..."
cargo tauri build "$@"
fi
6.2 使用方法
# Docker イメージをビルド(1 回限り)
docker build -f Dockerfile.cross -t tauri-cross .
# Tinkerboard(ARMv7)用にビルド
docker run --rm -v "$(pwd):/app" -v cargo-cache:/root/.cargo/registry \
tauri-cross armv7
# 64 ビット ARM(RPi 4/5、Jetson)用にビルド
docker run --rm -v "$(pwd):/app" -v cargo-cache:/root/.cargo/registry \
tauri-cross arm64
以上です。任意の Tauri プロジェクト。マウントして、ターゲットを選択して、.deb を取得します。
7. マルチターゲット対応マトリックス
Docker コンテナは以下のターゲットをデフォルトでサポートしています:
| 短縮名 | Rust ターゲットトリプル | デバイス | Debian アーキテクチャ |
|---|---|---|---|
armv7 | armv7-unknown-linux-gnueabihf | Tinkerboard、RPi 2/3/4(32 ビット)、BeagleBone | armhf |
arm64 | aarch64-unknown-linux-gnu | RPi 4/5(64 ビット)、Jetson Nano/Orin、Rock Pi | arm64 |
native | (ホスト) | 開発マシン | amd64 |
より多くのターゲットを追加
新しいアーキテクチャ(例:RISC-V)を追加するには、Dockerfile に 3 つのものを拡張します:
-
クロスコンパイラツールチェーン(
gcc-riscv64-linux-gnu) -
Rust ターゲット(
rustup target add riscv64gc-unknown-linux-gnu) -
sysroot ライブラリ(
libwebkit2gtk-4.1-dev:riscv64) その後、build.shに case を追加します。それだけです。
8. 新しいターゲットデバイスを追加する
新しい SBC または組み込みボードを取得したら、このチェックリストに従います:
ステップ 1 — アーキテクチャを特定
デバイスに SSH して実行します:
uname -m # 表示: armv7l, aarch64, x86_64, riscv64 など
cat /etc/os-release # 表示: Debian バージョン、Ubuntu バージョン など
ldd --version # 表示: glibc バージョン(互換性に重要)
ステップ 2 — Rust ターゲットにマッピング
uname -m の出力 | Rust ターゲット | Debian アーキテクチャ |
|---|---|---|
armv7l | armv7-unknown-linux-gnueabihf | armhf |
aarch64 | aarch64-unknown-linux-gnu | arm64 |
x86_64 | x86_64-unknown-linux-gnu | amd64 |
riscv64 | riscv64gc-unknown-linux-gnu | riscv64 |
ステップ 3 — glibc 互換性を確認
Docker ビルドコンテナの glibc バージョンは、ターゲットデバイスの glibc バージョン以下である必要があります。debian:bookworm-slim(glibc 2.36)を使用することは、任意の Debian 12+ デバイスで安全です。
# ターゲットデバイス上で
ldd --version | head -1
# 出力: ldd (Debian GLIBC 2.36-9+deb12u9) 2.36
# Docker コンテナ内で
ldd --version | head -1
# 同じバージョン以上であることを確認
デバイスが古い OS を実行している場合(例:Debian 11)、Docker ベースとして debian:bullseye-slim を使用してください。
ステップ 4 — デバイスにランタイム依存関係をインストール
# ターゲットデバイス上 — Tauri アプリが実行するのに必要なものをインストール
sudo apt install \
libwebkit2gtk-4.1-0 \
libgtk-3-0 \
libayatana-appindicator3-1 \
librsvg2-2
ステップ 5 — ビルドとデプロイ
# ホストマシン上で
docker run --rm -v "$(pwd):/app" tauri-cross armv7
# デバイスにコピー
scp target/armv7-unknown-linux-gnueabihf/release/bundle/deb/*.deb user@device:~/
# デバイスにインストール
ssh user@device 'sudo dpkg -i ~/your-app*.deb'
9. CI/CD テンプレート
GitHub Actions — 全ターゲット用にビルド
# .github/workflows/build.yml
name: Cross-Compile
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
target: [armv7, arm64]
steps:
- uses: actions/checkout@v4
- name: Cache Docker image
uses: actions/cache@v4
with:
path: /tmp/docker-image.tar
key: tauri-cross-${{ hashFiles('Dockerfile.cross') }}
- name: Build or load Docker image
run: |
if [ -f /tmp/docker-image.tar ]; then
docker load < /tmp/docker-image.tar
else
docker build -f Dockerfile.cross -t tauri-cross .
docker save tauri-cross > /tmp/docker-image.tar
fi
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: cargo-cache
key: cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
- name: Cross-compile
run: |
docker run --rm \
-v "${{ github.workspace }}:/app" \
-v "$(pwd)/cargo-cache:/root/.cargo/registry" \
tauri-cross ${{ matrix.target }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: deb-${{ matrix.target }}
path: target/*/release/bundle/deb/*.deb
10. デプロイメントパッケージ構成
ビルドが出力するもの、およびデバイス上のどこに配置されるか:
Build Output (.deb package)
│
├── /usr/bin/your-app # Tauri バイナリ
├── /usr/share/applications/your-app.desktop # デスクトップエントリ
├── /usr/share/icons/.../your-app.png # アプリアイコン(複数サイズ)
│
└── (オプション、tauri.conf.json > bundle > linux > deb > files 経由)
├── /etc/your-app/config.toml # デフォルト設定
└── /usr/lib/systemd/system/your-app.service # 自動起動サービス
tauri.conf.json バンドル設定
{
"bundle": {
"identifier": "com.yourcompany.your-app",
"targets": ["deb"],
"linux": {
"deb": {
"depends": [
"libwebkit2gtk-4.1-0",
"libgtk-3-0",
"libayatana-appindicator3-1",
"librsvg2-2"
],
"files": {
"/etc/your-app/config.toml": "./config/default.toml"
}
}
}
}
}
11. 検証とテスト
11.1 バイナリを検証
ビルド後、常に出力バイナリを確認します:
# 正しいアーキテクチャであるか確認
file target/armv7-unknown-linux-gnueabihf/release/your-app
# 期待される出力: ELF 32-bit LSB pie executable, ARM, EABI5, ... dynamically linked
file target/aarch64-unknown-linux-gnu/release/your-app
# 期待される出力: ELF 64-bit LSB pie executable, ARM aarch64, ... dynamically linked
11.2 動的依存関係を確認
# Docker コンテナ内から(ARM リンカーを使用)
# armv7 用:
arm-linux-gnueabihf-readelf -d target/armv7-unknown-linux-gnueabihf/release/your-app | grep NEEDED
# 期待される出力: libwebkit2gtk、libgtk、libc など をリスト
# これらはすべてターゲットデバイス上に存在する必要があります
11.3 デバイス上でクイック動作確認
scp target/armv7-unknown-linux-gnueabihf/release/your-app user@device:~/
ssh user@device 'ldd ~/your-app'
# すべてのライブラリが解決される → 実行できます
# 任何のライブラリが「見つかりません」表示 → デバイスに不足パッケージをインストール
12. よくある落とし穴と修正方法
pkg-config がライブラリを見つけられない
error: failed to run custom build command for `webkit2gtk-sys`
--- stderr
`pkg-config` could not find `webkit2gtk-4.1`
原因: クロスコンパイルの環境変数が設定されていません。
修正: ビルド前にこれらをエクスポートしていることを確認してください:
export PKG_CONFIG_SYSROOT_DIR=/usr/arm-linux-gnueabihf/
export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig
export PKG_CONFIG_ALLOW_CROSS=1
build.sh スクリプトが自動的にこれを処理します。
リンカーが見つからない
error: linker `arm-linux-gnueabihf-gcc` not found
原因: クロスコンパイラがインストールされていない、または .cargo/config.toml がありません。
修正: gcc-arm-linux-gnueabihf をインストールし、.cargo/config.toml に [target.armv7-unknown-linux-gnueabihf] セクションが正しい linker 値で設定されていることを確認してください。
OpenSSL ヘッダーが見つからない
Failed to find OpenSSL development headers
修正(オプション A — システム):
sudo apt install libssl-dev:armhf
修正(オプション B — vendored、sysroot 依存関係なし):
Cargo.toml に追加:
[dependencies]
openssl-sys = { version = "0.9", features = ["vendored"] }
バイナリがデバイス上で実行されない:「ファイルまたはディレクトリが見つかりません」
./your-app
-bash: ./your-app: No such file or directory
原因: バイナリに組み込まれた動的リンカーパスがデバイス上に存在しません。通常、ターゲットトリプルが間違っているか、armhf ランタイムがありません。
修正: file ./your-app を実行して正しいアーキテクチャであることを確認してください。次に ldd ./your-app を実行して、どのライブラリが不足しているかを確認してください。
Ubuntu sources.list が armhf と競合
E: Failed to fetch http://archive.ubuntu.com/.../armhf/Packages 404 Not Found
原因: Ubuntu は ARM パッケージを archive.ubuntu.com ではなく ports.ubuntu.com から提供します。dpkg --add-architecture armhf を実行すると、apt はすべてのソースから armhf をフェッチしようとします。
修正: Dockerfile ベースとして Debian を使用します(これを完全に回避)、または全てのソース行でアーキテクチャをピン留めします:
deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ...
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ ...
Dockerfile が debian:bookworm-slim を使用するのはこのためです。
ビルドが遅い(10分以上)
修正 — Cargo レジストリをキャッシュ:
docker run --rm \
-v "$(pwd):/app" \
-v cargo-registry:/root/.cargo/registry \
-v cargo-git:/root/.cargo/git \
tauri-cross armv7
修正 — ターゲットディレクトリをキャッシュ(注意:大きくなる可能性あり):
-v target-armv7:/app/target
修正 — 開発中はコンパイル速度に最適化されたリリースプロファイルを使用:
# Cargo.toml — 高速な開発ビルド、最適化されたリリースビルド
[profile.dev]
opt-level = 0
debug = false
[profile.release]
lto = true
codegen-units = 1
opt-level = "s"
strip = true
ファイルチェックリスト
任意の新しい Tauri プロジェクトでクロスコンパイルをセットアップするには、これらのファイルが必要です:
your-project/
├── .cargo/
│ └── config.toml # リンカーマッピング(セクション 5)
├── Dockerfile.cross # ビルドコンテナ(セクション 4)
├── build.sh # ビルドエントリーポイント(セクション 6)
└── src-tauri/
├── Cargo.toml # 必要に応じて openssl-sys vendored を追加
└── tauri.conf.json # deb depends 付きバンドル設定
4 ファイル。任意の Tauri プロジェクトにコピーして実行:
docker build -f Dockerfile.cross -t tauri-cross .
docker run --rm -v "$(pwd):/app" tauri-cross armv7
完了。
参考資料
-
Tauri v2 公式 ARM クロスコンパイル — https://v2.tauri.app/distribute/debian/
-
Tauri コミュニティ ARM Docker ビルド — https://github.com/tauri-apps/tauri/discussions/13246
-
Rust クロスコンパイルガイド — https://github.com/japaric/rust-cross
-
cross-rs(Docker ベース Rust クロスコンパイル) — https://github.com/cross-rs/cross
-
Debian Multiarch — https://wiki.debian.org/Multiarch/HOWTO
ドキュメントバージョン: 1.0
最終更新日: 2026 年 4 月
スコープ: ユニバーサル — 任意の Tauri アプリで任意の ARM Linux ターゲットで動作