rpmなクロスコンパイル環境の構築


 browncat.org
  Top 
     Palm Gadgetry 
     自宅サーバを立ち上げよう! 
     >Linuxのページ 
     blog@browncat.org 
     wiki@browncat.org 
 Linuxのページ
     Top/日記 
 Penguin Memos
       VAIO-U1インストール&設定メモ 
       Fivaインストール&設定メモ 
       MX3S(i815e)インストール&設定メモ 
       カスタムインストールセット作成メモ 
       Linuxでiアプリを作ってみる 
       シグマリオンでLinux-vrを使ってみる 
>        rpmなクロスコンパイル環境の構築 
         Redhat7.1のインストール 
         linux-vr向け再構築版Redhat7.1 
         ps2向けVineSeedを試してみる 
         ちょこっとしたTipみたいなこと 
 Palm関連
     CLIE NR70とLinux 
 逆Links
    
 Social Bookmarks
 Contact
  このサイトの作者にMail! 
 Search

 Link
    
  
改定履歴

●はじめに

rpmベースのLinuxを使用していて、 Linux-VRなんかを触っているとrpmパッケージを利用して クロスコンパイルが出来ないものかと考えてしまいます。 rpmはあまりcrossが得意ではなさそうですが、出来ないこともないので src.rpmからcrossで対象アーキテクチャ向けのバイナリrpmパッケージを 作成する方法をツツいて見ました。

また出来れば以下の条件も考慮します

  • ユーザの権限でコンパイルする
  • 出来るだけ普通にrpm -rebuildとか-baなどのコマンドだけでやりたい

●rpmを使ってcrossコンパイルする方法

rpmコマンドでは"--target"オプションで対象のアーキテクチャを指定できます。 これによってコンパイル環境を切替えることが出来ます。 しかし、実際にはビルド時に使用するconfigureスクリプトやパッケージ固有の ツールなどがうまく扱えないことが多く、素直にはいきません。

しかしconfigureはconfig.cacheをうまく使えばクリアできるので、 一般的なGNUのconfigureを使用するもので、かつビルド時に自前のバイナリなどの ツールを使わないものはコンパイルできる可能性大です。

●クロス開発環境の準備

ここでは開発環境の構築などの手順自体の説明はしません(^^。 いろいろなアーキテクチャ向けのcrossコンパイラがrpmで入手出来ますし、 gnuのツールチェインを利用すれば自力でも構築可能です。 それらをご利用ください。 なを、対象アーキテクチャ向けの以下のツールなどが必要となります。

  • cross binutils
  • cross gcc
  • ライブラリ及びヘッダファイル
  • (cross gdb)
ここでは例としてクロスツール類が

   <arch>-linux-<command>

という形式で作成されているものとします。 <arch>にはmips, mipsel, mips64, sh4, i686などが入ります。 また、commandにはgcc, ld, stripなどが入ります。

●mips向けコンパイラ

ここで、私の使っている環境は、Sigmarionなので、 当然mips向けコンパイラを利用することになります。

簡単に紹介すると

  • linux-vrではegcs1.0.3aがメインのコンパイラとなっています。
  • SGIなどのサイトをみるとegcs-1.1.2もあり、組み込みや他のプロジェクトでの使用実績もあるようです
  • SGIから入手できるRH7.1では2.96です。

基本的に対象ディストリビューションに合わせるのが良いと思います。

●クロスでrpmファイルを作成する際の問題点

以下にクロス環境でrpmファイルを作成する際の問題についてもう少し考えてみます。

(1) configureスクリプトが環境の調査時に失敗する

configureは実際にコンパイルしてヘッダファイルなどを チェックします。クロスコンパイルだとほとんど失敗します。

(2) ツール名やオプションが決めうちになっている

これは

  • ccなどのツールが見付からないことがある。 また、コマンド名をあわせても、どのコンパイラがコンパイルしたか 分からなくなったり混乱の元となりやすい
  • 以下では間違ってネイティブでコンパイルする危険を下げるため、 出来る限り <arch>-linux-<command> という形式でツールを使うように 各種ファイル類を設定してみます。

また、多くのパッケージではconfigureで調べたCCの名前を使ってくれなかったりしますので、 環境変数やspecファイル、makeの引数に"CC=クロスコンパイラ"と指定するのも 必要でしょう。

(3) 他のパッケージに依存している

ホストOSとターゲットのOSが近いか同一の場合、ホスト側に依存パッケージや そのdevelパッケージをインストールすれば大丈夫かも知れません。 結局やってみないと分からない所です。

(4) 間違えてホストシステムのファイルを書き換えてしまう

なるべくユーザ権限で作業を行い、rootにならずに済ませます。

●configureスクリプトの設定

Linuxのバージョンが同じであれば以下の方法が楽でしょう。

  • ホスト環境で普通にconfigureする。
  • そのディレクトリ内のconfig.cacheファイルを適当な場所にコピーする。
  • ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no}をyesにする。
  • その他ヘッダ類など適当に見てみる。問題なさそうならそのままでOKです。

とりあえずの修正点としては gcc,ld,ranlib,strip,ar,nmなどのコンパイラ、 binutils類のファイル名の設定を長い名前に書き換えます。

  • gcc -> mipsel-linux-gcc

これで準備したconfig.cacheを適当な場所に置いておき、

  • setenv CONFIG_SITE /<path-to-conf>/config.cache

等と指定します。 これで普通にGNUのconfigureを使っているものはある程度コンパイルが 通るようになります。

●ツールの名前問題の解決 その1

オブジェクトが混じる危険を避けるため、なるべくは長い名前でツールを使いたいが、 configureを使っていなかったりして、コンパイラやツールが決め打ちになっている ソースも多いため、やはり通常のツール名でもコンパイルできるようにしておいた方が いいでしょう。

ツールの実行ファイルのシンボリックリンクを適当なディレクトリに アーキテクチャ名を取り去った名前で作成します

例
   /usr/bin/<arch>-linux-gcc      ->   /usr/local/<arch>/bin/gcc
   /usr/bin/<arch>-linux-strip    ->                         strip
   /usr/bin/<arch>-linux-ld       ->                         ld
      ...

rpmのビルド前に実行パスの先頭にリンクを作成したディレクトリを指定したり specファイルに書き込んだりしたらよいでしょう。

例
   set path=(/usr/local/<arch>/bin/ $path)

など

●ツールの名前問題の解決 その2

rpmにもツール名を指定するマクロがあります。 この設定を書き換えることでよりより長い名前対応をします。 とりあえずrpm関連でいじるところは以下の所です。

  1. rpmの関連設定ファイル/スクリプトの一覧

    rpmは /usr/lib/rpm に設定ファイル類やスクリプトをもち、 rpmコマンドはこれらを利用してプログラムのビルド、インストールを行います。

    ここで関係するrpmツールの主な設定ファイルは以下の通りです。 それぞれの詳細は実際にファイルを見てみるかJFなどをお読みください。

    rpmの設定ファイル

    以下の3ファイル

    /etc/rpmrc
    /usr/lib/rpm/rpmrc
    ~/.rpmrc
    マクロ定義のファイル

    specファイル内で使われるマクロ定義など

    /usr/lib/rpm/macros
    /usr/lib/rpm/%{_target}/macros
    /etc/rpm/macros.specspo
    /etc/rpm/macros
    /etc/rpm/%{_target}/macros
    ~/.rpmmacros
    スクリプト

    依存チェックやバイナリのストリップなどのツール

    find-provides
    find-requires
    brp-compress
    brp-redhat
    brp-strip
    brp-strip-comment-note
  2. 対象アーキテクチャの追加

    1. /usr/lib/rpm/rpmrc

      おそらく/usr/lib/rpm/rpmrcに対象となるCPUが書かれているはずです。
      あればラッキーなのでそっとしておきます。
      無ければ他のものを参考に同じように記述します。
    2. アーキテクチャ毎ディレクトリの作成

      設定を分けるためアーキテクチャのディレクトリを作成します。
      • /etc/rpm/ディレクトリに入り
      • mkdir <arch>-redhat-linux
      • ln -s <arch>-linux
    3. macroとスクリプトの設定

      まずは元となるオリジナルをコピーします。
      スククリプトの書き換えは
      • cd /etc/rpm/<arch>-redhat-linux
      • cp /usr/lib/rpm/macros .
      • cp /usr/lib/rpms/find-provides .
      • cp /usr/lib/rpms/find-requires .
      • cp /usr/lib/rpms/brp-* .

      次にmacrosファイルを開き %__ar, %__cc, %__cpp, %__ldなどのgccとbinutilsに関連する マクロに<arch>-linuxを追加します

      • %__strip /usr/bin/<arch>-linux-strip

      また %__os_install_post マクロに 以降に書き換えるbrp-XXX を指定しているところがあると思うので、 これを/usr/lib/rpm/<アーキテクチャ>-liunx/brp-XXX と書き換えます。

      同じくfind_provides, find_requiresを以下のように指定。

      • %__find_provides /etc/rpm/<arch>-linux/find-provides
      • %__find_requires /etc/rpm/<arch>-linux/find-requires

      brp-*, find-provides, find-requiresは内部でobjcopyやstripを 呼び出しているので<アーキテクチャ>-linux-objcopyなどと書き換える。

    以上でrpmに行う追加は終了です。

  3. ユーザ環境の作成

    さらに安全を期するためroot権限ではなくユーザ権限で
    パッケージを作成するようにします。

    ~/.rpmmacrosを新規に作成し、

    %_dbpath /home/<user>/cross-rpm/rpm
    %_topdir /home/<user>/cross-rpm/redhat

    などとします。 ホームディレクトリには cross-rpm/rpm, cross-rpm/redhatディレクトリを 作成します。 このパスは適当に準備してください。 またredhatディレクトリには BUILD,RPMS,SOURCES,SPECS,SRPMSの 各ディレクトリを作成します。

●テストビルド

適当なサイトからsrc.rpmかnosrc.rpmを入手し、

例
    rpm --target <arch> -ba hoge.src.rpm

などとしてコンパイルして見てください。

もしコンパイル途中でエラーがでる場合,5で作成したクロス環境のパスが 先頭であるかどうかを確かめてください。

●より完全なクロス環境へ

以上、かなりごちゃごちゃとしていますが、基本的なソフトのrpmはある程度作成できるようになると思います。 ただ、いろいろなものをインストールしようとすると、どうしても他のパッケージへの依存を解決せねばならない場合があります。 ところが、当然ながらホスト環境にターゲット向けのライブラリなどが入っているわけはないので、なんとか解決しないといけません。

素直にターゲットからホストをnfs mountしてネイティブコンパイラを使えば 問題なさげですが、今時のホストとの速度差はかなり大きいので、 なんとかPC上でコンパイルしたいと思うのですが...

で、現在その方策を模索中です。できるだけspecなどを書き換えずにそのままコンパイル出来ないかと思っています。

targetがVine 2.1ベース(Linux-MC)なのでホストのKondara2.0と パッケージングに違いがありなにかと不便です。 またconfigureの結果などもホストOSの側のconfigureを流用すること多いだろうから、 なるべくターゲットに近いほうがなにかと便利です。 そこでもっとも近い環境と思われるVine2.1を インストールしてやってみようと思っています。

Kondara 2.0のrpmのコンパイルも試しては見たのですが 何分環境がかなり異なります。 いずれはSGIのredhat 7.1のtoolchain(gcc 2.96)を使って Kondara環境を作ったりできないかと思ってはいるですが、これはまたいずれ。



ご意見ご要望などは yamap@browncat.org まで
このページは以下のソフトウェアを使用して作成しました:
Kondara/MNU Linux,FreeBSD,XEmacs,Mule,jed,w3m,Netscape Communicator,MetaHTML,apache,jweblint,efstat,Namazu...
Thank you for visiting this page