クロスコンパイルツールパッケージガイドライン

提供: ArchWiki
2023年6月28日 (水) 17:42時点におけるKgx (トーク | 投稿記録)による版 (他言語へのリンクを追加)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動
ヒント: クロスコンパイラのパッケージを作成しなくても crosstool-ng を使えば自分用のツールチェインを自動で作成することができます。crosstool-ng は crosstool-ngAUR パッケージでインストールできます。

特記事項

このページでは [community] に入っている以下のパッケージに基づいた、新しいパッケージ方法を説明しています:

バージョン互換性

警告: 互換性がないバージョンのパッケージを使用してツールチェインをコンパイルすると必ず問題が起きます。基本的には全てのバージョンに互換性がないと考えてください。

以下の方針に従うことで互換性のあるバージョンの gcc, binutils, カーネル, C ライブラリを選択できます:

  • 一般的なルール:
    • gcc と binutils のリリースには相関関係があります。同時にリリースされたバージョンを使ってください。
    • libc をコンパイルするときは最新のカーネルヘッダーを使用したほうが良いですが --enable-kernel スイッチを使うことで古いカーネルでも動作するようになります (あくまで glibc の話で、他の C ライブラリでは事情が異なります)。
  • 公式リポジトリ: 修正や変更を加える必要がある場合もありますが、基本的には Arch Linux が使用しているバージョンを使うほうが動作する可能性が高くなります。
  • ソフトウェアドキュメント: 全ての GNU ソフトウェアには READMENEWS ファイルが存在し、最低要件として必要とするソフトウェアのバージョンなどが記載されています。
  • 他のディストリビューション: 他のディストリビューションもクロスコンパイラを行っています。
  • http://clfs.org にはクロスコンパイラをビルドするのに必要な手順や最新バージョンについて説明があります。

クロスコンパイラのビルド

クロスコンパイラは一般的に以下の手順でビルドされます:

  1. binutils: クロスコンパイル用の binutils をビルド。
  2. headers: ターゲットアーキテクチャの C ライブラリとカーネルヘッダをインストール。
    1. リファレンスヘッダーとして linux-api-headers を使用して makeARCH=target-architecture と指定してください。
    2. libc ヘッダーパッケージの作成 (Glibc の場合は こちら に手順が書かれています)。
  3. gcc-stage-1: 基本の (stage 1) gcc クロスコンパイラをビルド。C ライブラリをコンパイルするのに使用します。C ライブラリ以外のものをビルドすることはできません (C ライブラリが使えないため)。
  4. libc: クロスコンパイル用の C ライブラリをビルド (stage 1 のクロスコンパイラを使用)。
  5. gcc-stage-2: 完全な (stage 2) C クロスコンパイラをビルド。

ヘッダーや libc のソースはプラットフォームによって変わります。

ヒント: あなたが何をしたいかによって実際の作業は大きく違ってきます。例えば、Arch Linux とカーネルや glibc のバージョンが同じであるクローン環境を作成したいのであれば、ヘッダーをビルドしたり configure--with-build-sysroot=/ と指定する手順は省けます。

パッケージの名前

パッケージの名前の前に cross- という単語は付けません (昔はそういった話もありましたが、パッケージの名前が長くなるという理由で公式パッケージには取り入れられませんでした)。パッケージ名には GNU triplet によって付けられる名前を前に付けるだけでベンダーフィールドは入りませんしベンダーフィールドを "unknown" としたりはしません。例: arm-linux-gnueabihf-gcc。さらに短い名前を付ける例もありますが (例: mips-gcc)、推奨されません。

ファイルの保存場所

最新版の gcc や binutils は sysroot やライブラリのパスが衝突することはありません。実行ファイルは /usr/bin/ に置くことができます。衝突しないように実行ファイルにはアーキテクチャの名前を前に付けます。

基本的に ./configure には最低でも以下のパラメータが必要です:

_target=<your-target> # e.g. i686-pc-mingw32
_sysroot=/usr/lib/${_target}
...
./configure \
    --prefix=${_sysroot} --sysroot=${_sysroot} \
    --bindir=/usr/bin

サンプル

以下は MinGW 用の binutils の PKGBUILD です。特に参考になる点は:

  • クロス環境のルートディレクトリを指定しています。
  • ${_pkgname} , ${_target} , ${_sysroot} 変数を使用してコードを読みやすいようにしています。
  • 重複・衝突するファイルを消しています。
# Maintainer: Allan McRae <allan@archlinux.org>

# cross toolchain build order: binutils, headers, gcc (pass 1), w32api, mingwrt, gcc (pass 2)

_target=i686-pc-mingw32
_sysroot=/usr/lib/${_target}

pkgname=${_target}-binutils
_pkgname=binutils
pkgver=2.19.1
pkgrel=1
pkgdesc="MinGW Windows binutils"
arch=('i686' 'x86_64')
url="https://www.gnu.org/software/binutils/"
license=('GPL')
depends=('glibc>=2.10.1' 'zlib')
options=('!libtool' '!distcc' '!ccache')
source=(http://ftp.gnu.org/gnu/${_pkgname}/${_pkgname}-${pkgver}.tar.bz2)
md5sums=('09a8c5821a2dfdbb20665bc0bd680791')

build() {
  cd ${srcdir}/${_pkgname}-${pkgver}
  mkdir binutils-build && cd binutils-build

  ../configure --prefix=${_sysroot} --bindir=/usr/bin \
    --with-sysroot=${_sysroot} \
    --build=$CHOST --host=$CHOST --target=${_target} \
    --with-gcc --with-gnu-as --with-gnu-ld \
    --enable-shared --without-included-gettext \
    --disable-nls --disable-debug --disable-win32-registry
  make
  make DESTDIR=${pkgdir}/ install
  
  # clean-up cross compiler root
  rm -r ${pkgdir}/${_sysroot}/{info,man}
}
ノート: クロスコンパイルのツールチェインをビルドするときは専用のディレクトリから configuremake コマンドを実行するようにして (いわゆる out-of-tree コンパイル)、PKGBUILD に変更を加えた後は src ディレクトリを削除してください。

その方法と理由

/opt にインストールしない理由

2 つの理由:

  1. まず、ファイル階層標準によれば、これらのファイルは /usr のどこかに属しているだけです。
  2. 次に、/opt へのインストールは、他に選択肢がない場合の最後の手段です。

"パス外の実行可能ファイル" とは何ですか?

この奇妙な機能により、クロスコンパイルが容易になります。場合によっては、プロジェクト Makefile が CC & co を使用しないことがあります。変数を使用せず、代わりに gcc を直接使用してください。このようなプロジェクトをクロスコンパイルしたいだけの場合、Makefile の編集は非常に時間がかかる操作になる可能性があります。ただし、最初に 私たちの 実行可能ファイルを使用するように $PATH を変更するのが非常に簡単な解決策です。次に、make の代わりに PATH=/usr/arch/bin/:$PATH make を実行します。

トラブルシューティング

コンパイルが失敗したときのメッセージの意味がわからない

configure の実行時に発生するエラーについては $srcdir/pkgname-build/config.log を読んでください。コンパイル時に発生するエラーについてはコンソールのログを上まで見るか "error" という単語で検索するしかありません。

よくあるエラーの原因

  • コンパイルフラグが多すぎるか少なすぎる。問題ないとわかっているフラグを使ってみてください。
  • 依存関係が壊れている。例えば binutils のファイルが欠けていたり保存場所が間違っていると gcc の configure 時に謎めいたエラーが発生します。
  • build() 関数に export CFLAGS="" を追加していない (GCC Bugzilla の bug 25672 を参照)。
  • --prefix/--with-sysroot で指定したディレクトリに書き込む権限がない (clfs のガイドでわかりにくいところです)。
  • sysroot にカーネルや libc のヘッダーが存在しない。
  • Google で検索しても解決しない場合、今の構成を諦めて、もっと安定している、動作することが確認されている設定を使ってみてください。

ファイルが間違った場所にインストールされる

make install を実行するときの作法は様々であり結果も違います。例えば、プラットフォームによっては DESTDIR がサポートされておらず代わりに install_root を使う必要があります。tooldirprefix などの引数も同じです。環境変数のかわりに引数としてパラメータを指定することもあります。例えば以下のようにするところを:

CC=arm-elf-gcc ./configure

以下のように実行することがあります:

./configure CC=arm-elf-gcc

逆にすることでコンパイル結果が変わります (configure/make が再帰的に自己実行されることが原因です)。

参照