Gentoo Linuxな生活​/サーバ設定関連

Page Top

クロスコンパイルとは何ぞや?? anchor.png

そもそも、パソコンと言うのは、理解できる言語と言うのが限られています。何で区別されているかと言うと、パソコンの前頭葉とも言うべきCPU。このCPUのアーキテクチャというもので、既に生まれた瞬間から理解できる言葉が分かれています。Pentium4,PowerPC,SPARCなどなどなど。Pentum4で解釈できる言葉(実行プログラム)をPowerPCで分かってもらおう(実行させよう)としても無理。PowerPCならばPowerPC用に解釈できる言葉で書いてあげないといけません。

さて、ところでこのPentium4だの、PowerPCだのが理解できる言葉は、果たして人間様が理解できる言葉か?というと、到底理解できる言葉ではありません(まれに理解できる人も居るけど)。で、この人間様に理解できる言葉(プログラム言語)をCPUが分かる言葉(マシン語)に変換してあげるのがコンパイラ。コンパイラを動かす作業がコンパイル。

で、クロスとは、何がクロスするんじゃい?と。

あるCPUで動作する、別のCPUの言葉に変換するコンパイラの事をクロスコンパイラと言いますねん。例えばPentium4とか積んでるAT互換機上で動作する、プログラム言語をMacなんかのPowerPC上で動く言葉に変換してくれるコンパイラの事ですね。

Page Top

んなことして何がうれしいノン? anchor.png

普通は、組み込み開発なんかで使います。例えば、新しいエアコンを開発したとしましょう。最近のエアコンは、コンピュータとか搭載してるので、結構賢いソフトが動作します。さて。このエアコン上で動くソフトってどーやって開発するの?まさかエアコンのコンピュータ上で開発する?わけは~ない。パソコンとか使ってプログラムを書き書きします。で、このエアコンで理解できる言語に変換してやろーとするときに、パソコンで動くエアコン言語向けコンパイラを動かして、エアコン上で動作するプログラムを作り、エアコンにインストールして動作させるのですねー。

で、おいちゃんは何に使用するか。

玄箱はPowerPC。だけどこの玄箱君はPowerPC266MHzととっても遅い。どれぐらい遅いかと言うと、10年前のパソコンと同じくらいの遅さ(10年前なら超高速だったんだけどね…)。Gentooのコンパイルは異様に時間がかかってたまらない。さて、傍らには、Pentium4 3GHzとかの、現在では十分早いパソコンがおるではないですか。どーにかしてこいつにコンパイル作業をやらせられないか…となると、おお!クロスコンパイルだ!!と言うわけですね。

Page Top

クロスコンパイル環境の準備 anchor.png

Gentooの場合はチョー簡単。

# emerge crossdev

と打つと、crossdevというツールをインストールしてくださります。crossdevとただ打つと

Usage: crossdev [options] --target TARGET

Options:
   --b, --binutils ver   Specify version of binutils to use
   --g, --gcc ver        Specify version of gcc to use
   --k, --kernel ver     Specify version of kernel headers to use
   --l, --libc ver       Specify version of libc to use
   -C, --clean target    Uninstall specified target
   -b, -d, -p, -v, -q    Options to pass to emerge (see emerge(1))
Stage Options:
   -s0, --stage0         Build just binutils
   -s1, --stage1         Also build a C compiler (no libc/C++)
   -s2, --stage2         Also build kernel headers
   -s3, --stage3         Also build the C library (no C++)
   -s4, --stage4         Also build a C++ compiler [default]
Extra Fun (must be run after above stages):
   --ex-only             Skip the stage steps above
   --ex-gcc              Build extra gcc targets (gcj/ada/etc...)
   --ex-gdb              Build a cross gdb

Target (-t):   takes the form: ARCH-VENDOR-OS-LIBC
   Run 'crossdev -t help' for examples

どべべーっとヘルプが出てきます。このツールを使って作業していくですよ…

その前に、準備が必要。

Page Top

crossdevの為の準備 anchor.png

crossdevには、環境変数PORTAGE_OVERLAYが必要です。 仮に/usr/local/portageとしましょうか。ここに、クロスコンパイルを実施するパッケージを追加していきます。

# cd /usr/local/portage
# mkdir cross-<CPU名>-<サフィックス>-<OS名>-<libcタイプ>

ここで、CPU名はi686とか、armとか。サフィックスは何でも良い。OS名はlinux,libcタイプはglibcならばgnu,uclibcならばuclibcを指定します。但し、distccで玄箱からクロスコンパイルを実施させる都合上、玄箱君の側のgccのCHOSTとあわせる必要があります。なので、玄箱君の中のmake.confのCHOST項を参照してください。うちだと

# mkdir cross-powerpc-unknown-linux-gnu

になりますです。さらにその配下にクロスコンパイルに必要なbinutils,gcc,linux-headers.glibcをシンボリックリンクで作っておきます。

# cd cross-powerpc-unknown-linux-gnu
# ln -s /usr/portage/sys-devel/binutils
# ln -s /usr/portage/sys-devel/gcc
# ln -s /usr/portage/sys-libs/glibc
# ln -s /usr/portage/sys-kernel/linux-headers

で、さらに/etc/make.confに

PORTDIR_OVERLAY="/usr/local/portage"

を追加してあげましょう。するってーと

# emerge cross-powerpc-unknown-linux-gnu/gcc

と打つと、PowerPCクロスコンパイラ用のgccがパッケージとして管理される仕組み。ああー便利♪

Page Top

crossdevを使ってみる anchor.png

# crossdev --b <binutilsのバージョン> \
                 --g <gccのバージョン> \
                 --k <linuxheadersのバージョン>\ 
                 --l <glibcのバージョン> \
                 -t  powerpc-unknown-linux-gnu

ここで、各バージョンは、玄箱君が使用しているバージョンとあわせる必要あり。-t の後ろは玄箱君のCHOSTと合わせる必要あり、です。気をつけて!!

さらに、crossdevを実施していると、途中でエラー終了すると思いますです。gccの第2コンパイル中にlibstdc++をコンパイルしているときに、「/usr/powerpc-unknown-linux-gnu/usr/lib/libc.so.6が見つからん!」といわれて止まってしまうと思われます。これに対処するために

# cd  /usr/powerpc-unknown-linux-gnu/
# ln -s . usr

とやっておきましょう。でもう一度crossdevを実施すると、ちゃんとコンパイルが通るようになると、思いますよぅ~。

Page Top

distccの設定 anchor.png

さて、玄箱君とクロスコンパイル母艦マシンにそれぞれdistccをインストールします

# emerge distcc
Page Top

玄箱君側 anchor.png

で、玄箱君側で、他所のPCにコンパイルを依頼するように設定します

# distcc-config --set-hosts <コンパイル母艦のIPアドレス>

必要であれば、/etc/distcc/hostsを編集して、依頼するジョブの数とかを最適化してやりましょう。ここでもう一工夫。ふつーにdistccをインストールすると/usr/lib/distcc/binの下が

c++ -> /usr/bin/distcc
cc -> /usr/bin/distcc
g++ -> /usr/bin/distcc
gcc -> /usr/bin/distcc
powerpc-unknown-linux-gnu-c++ -> /usr/bin/distcc
powerpc-unknown-linux-gnu-g++ -> /usr/bin/distcc
powerpc-unknown-linux-gnu-gcc -> /usr/bin/distcc

こんな風にシンボリックリンクが張られます。これだと、distccが分散コンパイルを呼び出すときに、g++とかgccでコンパイルを呼び出すと、対向側でも普通にg++とかgccが呼ばれます。CPUが同じ場合にはなんの問題もないのですが、CPUが異なるホストでコンパイルする場合は、意図的にクロスコンパイラの方を呼んでくれないと困ります。なので、c++,cc,g++,gccでコンパイルを実行するパッケージのために、powerpc-unknown-linux-gnu-XXXというコマンドに化かすシェルを作ってやります。例えばpowerpc-unknown-linux-gnu-wrapperというシェル。中身は

#!/bin/bash
exec /usr/lib/distcc/bin/powerpc-unknown-linux-gnu-${0##*/} "$@"

こんな感じ。で、/usr/lib/distcc/binの中は

c++ -> powerpc-unknown-linux-gnu-wrapper
cc -> powerpc-unknown-linux-gnu-gcc
g++ -> powerpc-unknown-linux-gnu-wrapper
gcc -> powerpc-unknown-linux-gnu-wrapper
powerpc-unknown-linux-gnu-c++ -> /usr/bin/distcc
powerpc-unknown-linux-gnu-g++ -> /usr/bin/distcc
powerpc-unknown-linux-gnu-gcc -> /usr/bin/distcc
powerpc-unknown-linux-gnu-wrapper

こんな風にしておいてやる。すると、実行コマンドがgccでコンパイルされても、distccにはpowerpc-unknown-linux-gnu-gccというコマンドで実行され、コンパイル母艦側で意図的にクロスコンパイラが使えるようになるという寸法。

Page Top

コンパイル母艦側 anchor.png

/etc/conf.d/distccdでコンパイルを受け付けるホストとかを適切に設定しておいてやりましょう。で

# /etc/init.d/distccd

でdistccデーモンを立ち上げておいてやります。

Page Top

パッケージコンパイルの準備 anchor.png

玄箱君のmake.confに

FEATURES="distcc"
MAKEOPTS="-j4"

など、適切に入れておいてやりましょう。おいちゃんちでは、x86_64でHTなPentium4マシンをコンパイル母艦に使用しているので、並列コンパイル数を4に指定しております。

Page Top

コンパイルしてみよう anchor.png

# emerge -uD world

でパッケージのコンパイルとかをすると、パッケージの展開、configure実行あたりは玄箱君で実施するので猛烈に遅いのですが、コンパイルを開始すると、嵐のような勢いでコンパイルを実施して行きます。

対してコンパイル母艦側では、依頼されたコンパイルを裏でこなしているので、時々CPU負荷が上下動します。ん~やったね~♪これで玄箱君でのコンパイル運用はかなーり楽になるはずですよう。

Page Top

さらなる活用法 anchor.png

組み込み開発を行ってる御仁は、オープンソースパッケージを組み込むのに、かなり重宝すると思うデス。例えばARMで動作するネイティブマシンを作っておき、Linuxを駆動させておく。オープンソースパッケージはconfigureだけはネイティブで行わないとまともに通らなかったりします。なのでネイティブCPUでパッケージのコンパイルを実施しているふりして、強力な外部CPUでクロスコンパイルを実施させると言う活用が出来て、開発効率が飛躍的に増大すると思うだな~。試してみてちょ~~


Front page   Freeze Diff Backup Copy Rename ReloadPrint View   New Page Page list Search Recent changes   Help   RSS of recent changes (RSS 1.0) RSS of recent changes (RSS 2.0) RSS of recent changes (RSS Atom) Powered by xpWiki
Counter: 4947, today: 2, yesterday: 6
Princeps date: 2009-08-19 (Wed) 01:23:51
Last-modified: 2009-08-19 (Wed) 01:23:51 (JST) (4088d) by maruo
ページ内検索

ログイン

ユーザー名:


パスワード:





パスワード紛失

メインメニュー

サブメニュー
自宅鯖計画

Gentoo Linuxな生活

玄箱HGにGentoo格闘記

航空ショーへ行こう

モータースポーツな世界

奥深き写真の世界への誘い

我思う ゆえに我あり



携帯用QRコード