link もっと前
   2019年 4月 29日 -
      2019年 4月 20日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

クロスビルド用ツールチェーン - その 2

引き続き、超基本的な binutils + GCC + glibc の組み合わせのクロスビルド環境を作っています。やや苦戦したものの、ARM, AArch64, RISC-V 64 でビルドが通りました。良かった良かった。

残念ながら RISC-V 32 は glibc が対応しておらず、libc なしのベアメタル向けコンパイラしか作れませんでした。glibc does not yet support 32-bit systems と怒られます。glibc の代わりに newlib などを使えば、libc ありの Linux 向けコンパイラが作れるかもしれませんが、試していないのでわかりません。

環境

昔作ったクロスコンパイラをビルドする Makefile(GitHub へのリンク)を改造して、作りました。

前回(その 1)検討した通り、本格的に運用するなら独自のビルドツールより crosstool-NG か buildroot に切り替えた方が良いと思います。

ビルド方法

詳細は GitHub を見た方が良いですが、configure に指定しているオプションだけ、ざっと列挙しておきます。

変数の定義(イメージ)

CROSS_ARCH = riscv64-unknown-linux-gnu
TOP_DIR    = `pwd`
CROSS_ROOT = $TOP_DIR/buildroot

PREFIX  ?= $(CROSS_ROOT)
SYSROOT ?= $(CROSS_ROOT)/$(CROSS_ARCH)/sysroot

まず binutils は、

binutils の configure

./configure \
  --target=$(CROSS_ARCH) \
  --prefix=$(CROSS_ROOT) \
  --disable-nls \
  --disable-static \
  --disable-werror \
  --with-lib-path=$(CROSS_ROOT)/lib \
  --with-sysroot=$(CROSS_ROOT)

次に gcc は、

gcc 1回目 の configure

./configure \
  --target=$(CROSS_ARCH) \
  --prefix=$(PREFIX) \
  --enable-languages=c \
  --disable-libatomic \
  --disable-libitm \
  --disable-libgomp \
  --disable-libmudflap \
  --disable-libquadmath \
  --disable-libsanitizer \
  --disable-libssp \
  --disable-libstdcxx-pch \
  --enable-long-long \
  --enable-lto \
  --disable-multiarch \
  --disable-multilib \
  --disable-nls \
  --disable-plugin \
  --disable-shared \
  --disable-threads \
  --disable-__cxa_atexit \
  --without-headers \
  --with-local-prefix=$(SYSROOT) \
  --with-sysroot=$(SYSROOT) \
  --with-newlib

難関の glibc はこんな感じ、

glibc の configure

./configure \
  --host=$(CROSS_ARCH) \
  --prefix=$(SYSROOT)/usr \
  --disable-profile \
  --disable-multilib \
  --enable-add-ons \
  --enable-kernel=3.0.0 \
  --disable-multi-arch \
  --enable-obsolete-rpc \
  --with-binutils=$(PREFIX)/bin \
  --with-headers=$(SYSROOT)/usr/include \
  --with-sysroot=$(SYSROOT)

最後に glibc を動的リンク可能な gcc は、

gcc 2回目の configure

./configure \
  --target=$(CROSS_ARCH) \
  --prefix=$(PREFIX) \
  --enable-languages=c,c++,fortran \
  --enable-libatomic \
  --disable-libitm \
  --enable-libgomp \
  --enable-libmudflap \
  --enable-libquadmath \
  --disable-libsanitizer \
  --enable-libssp \
  --enable-libstdcxx-pch \
  --enable-long-long \
  --enable-lto \
  --disable-multiarch \
  --disable-multilib \
  --enable-nls \
  --enable-plugin \
  --enable-shared \
  --enable-threads=posix \
  --enable-__cxa_atexit \
  --with-local-prefix=$(SYSROOT)/usr \
  --with-build-sysroot=$(SYSROOT) \
  --with-sysroot=$(SYSROOT) \
  --with-native-system-header-dir=/usr/include

この設定が正しいかどうか確証は持てませんが、printf を呼び出す C ソースコードをエラーなくビルド可能なコンパイラが作成できるので、良しとします。

引っかかったポイント

色々引っかかったのですが、覚えている限りのエラーと自分が取った対策を列挙しておきます。

どのバージョンのライブラリを組み合わせれば良いかわからない
私は Debian などの既存 Linux ディストリビューションが採用しているバージョンを参考にしました。ホスト側のコンパイラのバージョンも影響するため、昔ビルドが通っていた組み合わせでもビルドが通らないことはあります。
AArch64 に変えると glibc ビルドエラー
エラーの内容は redefinition of 'struct user_regs_struct でした。何それ……??と思いきや、sysroot にインストールした Linux カーネルヘッダが RISC-V 向けになっていた凡ミスでした。
glibc ビルドエラー
エラーの内容は enable-multi-arch support require gcc, assembler and linker indirect-function support でした。これは解決方法がわからんので、GCC の configure に --disable-multi-arch を指定し、回避しています。
gcc ビルドエラー
エラーの内容は Pthreads are required to build libgomp でした。これはややこしいので、別建てで書きます。

gcc ビルドエラー(詳細)

エラーメッセージだけ読むとさっぱりですが、config.log に記録されたテストプログラムとテスト結果によれば、pthread.h が見当たらないと言っているようです。

  • GCC の configure に --enable-libgomp を指定したため、libgomp がビルドされている
  • libgomp は pthread.h が見つからないので Pthreads are required to build libgomp と文句を言っていた

もちろん GCC の前に glibc のクロスビルドに成功しているので、pthread.h は存在しているものの、

  • glibc のヘッダをインストールする場所を間違えていた
  • gcc の --with-native-system-header-dir に指定したパスが間違っていた

これらの原因によって、pthread.h が見えなくなっていたようです。

感想

ツールチェーン構築って大変です。実際に体験すると、crosstool-NG や buildroot のありがたさが身に沁みます。

[編集者: すずき]
[更新: 2019年 5月 7日 00:39]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

クロスビルド用ツールチェーン - その 1

先日(2019年 3月 27日の日記参照)クロスビルド向け LLVM のビルド方法がわかったので、今度はクロスビルド向け GCC のツールチェーン(超基本的な binutils + GCC + glibc の組み合わせ)を作ろうとしていますが、さっぱりうまくいかないです。

そもそもどのバージョンの組み合わせならビルドが通るのか全くわかりません……。対象となるクロス環境(ARM 向けなのか、RISC-V 向けなのか)と、ホスト側のコンパイラバージョンが影響するようで、昔ビルドが通っていた組み合わせを引っ張り出してきても、今の環境だとビルドが通らないなんてことがおきます。

やりたいこと

ビルドできる組み合わせは頑張れば見つけられるとは思いますが、本来やりたいことはクロスビルド用のコンパイラのソースコードリポジトリをダウンロードし、自分でソースコードに何か変更を入れ、変更した内容も含めてビルドすることです(ダウンロードは最悪手動でも良いですけど)。

世の中にはクロスビルド用のツールチェーンを作成できるツールはいくつかありますが、いずれも tarball からのビルドを想定していて、改変を入れて再ビルドする方法が良くわかりません。

ツールが想定しているリリース用のビルドは、

  • リリースバージョンの tarball か、ソースコードリポジトリのリリースタグを持ってきてビルド
  • 実機で使える形、インストーラなどにパッケージング

開発用は、リリース用に加え、

  • 最新のソースコードリポジトリを持ってくる
  • ソースコードに素早くアクセス、改変
  • 改変した部分だけ差分ビルド
  • (必要なら)モジュールを足す

が必要ですが、意外とできないです……。

クロスビルド用ツールチェーンを作成できるツール

いくつかツールを調べてみました。

Yocto
ソースコードはアクセスしづらいです。例えば AGL(Yocto を使っています)は、
agl/build/tmp/work-shared/gcc-8.2.0-r0/gcc-8.2.0/
に置かれます。何回見ても覚えられません

ソースコードの改変はできますが、bitbake はソースコードの変更を認識しないようです。bitbake にモジュールを明示的に指定すれば良さそうです。もしくはパッチを作ってレシピに足して bitbake するのが Yocto 的には正しいのかな?どちらにせよ面倒です。

新たにモジュールを足す方法は、レシピを足すだけなので簡単だと思いますが、それ以外が辛すぎます。開発用には向いていません。
crosstool-NG
ソースコードは、
crosstool-ng/.build/src/gcc-8.2.0/
にあります。アクセスしやすいです。

ソースコードの改変は反映されますが、差分ビルドはしないようで、./ct-ng build とすると全てビルドしなおされます。ちょっと微妙です。

新たなモジュールの追加はどうやるのかわかりません。Yocto などとは違い、コンパイラなどのツールチェーンをビルドする専用ツールなので、Linux カーネルや busybox はビルドしません。足すものはあまりないんじゃないでしょうか。
buildroot
ソースコードは、
buildroot/output/build/host-gcc-final-7.4.0/
にあります。Yocto よりわかりやすいです。

ソースコードの改変は認識されていないように見えます。ソースコードを変更して make しても何もビルドされません

新たなモジュールの追加方法は知らないですが、比較的簡単なのかな…?

ツールチェーン単体だと crosstool-NG ですし、将来的に追加するものを考えると buildroot が良さそうですけど。変更を反映して差分ビルドする方法ないのかな……??

[編集者: すずき]
[更新: 2019年 5月 7日 00:39]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2019年 4月 29日 -
      2019年 4月 20日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 5/22 01:47

カレンダー

<2019>
<<<04>>>
-123456
78910111213
14151617181920
21222324252627
282930----

最近のコメント 5件

  • link 19年04月01日
    すずき 「どの CPU というかシステムでも同じ傾...」
    (更新:04/05 11:03)
  • link 19年04月01日
    hdk 「去年Ryzen 7 1700で測りました...」
    (更新:04/02 22:48)
  • link 19年03月05日
    すずき 「> オシロの波形見てて気がつかなか...」
    (更新:03/21 17:45)
  • link 19年03月05日
    kml 「> 自分が持っている RockPr...」
    (更新:03/20 21:30)
  • link 19年03月10日
    すずき 「ありがとー!!」
    (更新:03/13 09:46)

最近の記事 3件

link もっとみる
  • link 19年05月17日
    すずき 「[GCC を調べる - その 2 - デバッグ環境] GCC をデ...」
    (更新:05/22 01:47)
  • link 19年05月13日
    すずき 「[GCC を調べる - その 1 - ビルド] 最近 GCC のコ...」
    (更新:05/22 01:38)
  • link 19年05月09日
    すずき 「[RockPro64 の PCIe] RockPro64 の PC...」
    (更新:05/11 15:12)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報