gnuplotのクロスコンパイル for LS-GL

シリアルをつけ、クロスコンパイル環境を作ったLS-GLid:NeoCat:20070808, id:NeoCat:20070819あたりを参照)ですが、引き続きいくつかソフトをクロスコンパイルしました。というわけで、クロスコンパイルmemo、gnuplot編。ちなみに、導入の目的はとあるセンサから収集した24/7な監視データをグラフ化した画像を返すCGIを作ることです。デフォルトでApacheが動いているしperlも使えるので、gnuplotさえ入れればOK。

gnuplotで画像を生成させるためには、GDライブラリが必要、GDを作るためにはlibjpegとlibpngのインストールが必要です。作るものが多いですが、順番に攻略していきます。なお、基本的に作業時点での最新版を入れるようにしています。

0. 準備

あらかじめパス等を設定しておきます。

export PATH=/usr/local/arm/bin:/usr/local/arm/arm-none-linux-gnueabi/usr/local/bin:$PATH
export CC=arm-none-linux-gnueabi-gcc
export CXX=arm-none-linux-gnueabi-g++
export F77=none
export LD=arm-none-linux-gnueabi-ld
export AS=arm-none-linux-gnueabi-as
export AR=arm-none-linux-gnueabi-ar
export NM=arm-none-linux-gnueabi-nm
export RANLIB=arm-none-linux-gnueabi-ranlib
export STRIP=arm-none-linux-gnueabi-strip

※2007/12/24追記。以下も追加しておくと良い。

export CPPFLAGS='-I/usr/local/arm/arm-none-linux-gnueabi/usr/include/c++/3.4.4 -I/usr/local/arm/arm-none-linux-gnueabi/usr/include/c++/3.4.4/arm-none-linux-gnueabi'

1. libjpeg-6gのビルド

http://www.ijg.org/files/jpegsrc.v6b.tar.gz からソースを入手、展開したディレクトリで以下を実行。

% ./configure --build=powerpc-apple-darwin8.10.0 --host=arm-none-linux-gnueabi \
    --target=arm-none-linux-gnueabi --enable-shared --with-gcc=gcc

ログを見ていると、libtoolsが自動で作られないようなので作っておきます。あとは普通に。

% ./ltconfig ltmain.sh arm-none-linux-gnueabi
% make
% make install prefix=~/Desktop/packages/usr/local
% cd ~/Desktop/packages/
% sudo chown -R root:wheel usr
% tar czf libjpeg-6g-arm-none-linux-gnueabi.tar.gz usr

2. libpng-1.2.19のビルド

まず、zlibのヘッダ・ライブラリをソースCDからコピーしておく必要があります。

% cd ~/Desktop/
% tar ${SRC_CDROM}/zlib-1.2.3_arm.tgz
% cd /usr/local/arm/arm-none-linux-gnueabi/usr
% cp ~/Desktop/zlib-1.2.3/{zlib.h,zconf.h} include
% cp ~/Desktop/zlib-1.2.3/libz.a lib

libpngのソースは http://www.libpng.org/pub/png/libpng.html から。至って普通にコンパイルが通りました。素晴らしい。

% ./configure --build=powerpc-apple-darwin8.10.0 --host=arm-none-linux-gnueabi \
    --target=arm-none-linux-gnueabi --enable-shared
% make
% make install prefix=~/Desktop/packages/usr/local
% cd ~/Desktop/packages/
% sudo chown -R root:wheel usr
% tar czf libpng-1.2.19-arm-none-linux-gnueabi.tar.gz usr

3. gd-2.0.35のビルド

まず、上記ライブラリをビルド環境の/usr/local/arm/arm-none-linux-gnueabi/にて展開しておきます。その上で、libgdのソースは http://www.libgd.org/ から入手しました。意外と楽にコンパイルできました。素晴らしい。

% ./configure --build=powerpc-apple-darwin8.10.0 --host=arm-none-linux-gnueabi \
    --target=arm-none-linux-gnueabi --enable-shared --without-x --without-freetype --enable-shared 
% make
% make install prefix=~/Desktop/packages/usr/local
% cd ~/Desktop/packages/
% sudo chown -R root:wheel usr
% tar czf gdlib-2.0.35-arm-none-linux-gnueabi.tar.gz usr

4. gnuplot-4.2.2のビルド

いよいよ本番ですが、クロスコンパイルはあんまり意識されていないようで、何回か途中で引っかかりました。
一番困ったのが、システムネイティブのgdlib-configがパスの通ったところにあると、configureスクリプトのバグで必ずそれが使われてしまうという問題です。ネイティブ版のライブラリとは当然リンクできないので、リンク時にこけてしまいます。これを回避するために、/usr/local/arm/arm-none-linux-gnueabi/usr/local/bin/gdlib-config-arm-none-linux-gnueabi を gdlib-config という名前で(システムネイティブより早い段階で)パスの通ったところにコピーし、中身のprefix, ldflags等をクロスコンパイル環境に合わせて書き換えておきます。pkg-configもネイティブのものに反応してしまいますが、こちらはPKG_CONFIG環境変数を適当に設定して無視させます。

% PKG_CONFIG=none ./configure --build=powerpc-apple-darwin8.10.0 --host=arm-none-linux-gnueabi \
    --target=arm-none-linux-gnueabi --without-lisp-files --without-tutorial --without-x
% make

ところが、うちの環境ではsrc/matrix.cのコンパイル中にARM用gccがBus errorで落ちてしまいました。多分最適化コードのバグだろうと見当をつけ、makeの吐いたコマンドの真似をしてそこだけ手動で最適化オプション(-02)を外した状態でgccを実行し、再度makeします。

% cd src
% arm-none-linux-gnueabi-gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../term -I../term -DBINDIR=\"/usr/local/bin\" \
    -DX11_DRIVER_DIR=\"/usr/local/libexec/gnuplot/4.2\" -DGNUPLOT_PS_DIR=\"/usr/local/share/gnuplot/4.2/PostScript\" \
    -DCONTACT=\"http://sourceforge.net/projects/gnuplot\" -DHELPFILE=\"/usr/local/share/gnuplot/4.2/gnuplot.gih\" \
    -I/usr/local/arm/arm-none-linux-gnueabi/usr/local/include -g -MT matrix.o -MD -MP -MF ".deps/matrix.Tpo" \
    -c -o matrix.o matrix.c
% cd ..
% make

次にdocsの中でエラーになるので、docs/Makefile内のファイルを編集し、CCやCPP、インクルードパスをビルド環境用のネイティブgcc用に設定し直してmake clean, makeします。
そのあとは、demoのビルド中、bf_testを実行しようとしてエラーになります。クロスコンパイル中なので、ビルド環境ではもちろん動かない。。。仕方がないので、srcディレクトリ以下で、bf_testを構成している alloc.c, binary.c, bf_test.cから、makeした時の引数を真似して、ビルド環境用のネイティブgccでbf_testをコンパイルし直します。

% cd src
% gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../term -I../term -DBINDIR=\"/usr/local/bin\" \
    -DX11_DRIVER_DIR=\"/usr/local/libexec/gnuplot/4.2\" \
    -DGNUPLOT_PS_DIR=\"/usr/local/share/gnuplot/4.2/PostScript\" \
    -DCONTACT=\"http://sourceforge.net/projects/gnuplot\" \
    -DHELPFILE=\"/usr/local/share/gnuplot/4.2/gnuplot.gih\" \
    -I/usr/local/arm/arm-none-linux-gnueabi/usr/local/include  \
    -g -O2 -MT alloc.o -MD -MP -MF ".deps/alloc.Tpo" -o bf_test alloc.c binary.c bf_test.c

これでトップディレクトリ内でmakeすると、ようやく全てのmakeが通りました。あとはtarball化します。インストール先の指定は prefixでは駄目で、DESTDIR環境変数で行うようです。ここでもハマった…。

% DESTDIR=~/Desktop/packages make install
% cd ~/Desktop/packages/
% rm -rf usr/local/share/texmf-local
% rm -rf usr/local/lib/X11
% sudo chown -R root:wheel usr
% tar czf gnuplot-4.2.2-arm-none-linux-gnueabi.tar.gz usr

5. インストー

上記で作ったtarballを全てLS-GLにコピー、tar xzf hoge.tar.gz -C / で展開すればインストール完了。ヽ(´ー`)ノ
なお、gnuplotの実行時は、環境変数LD_LIBRARY_PATH に /usr/local/lib が入っている必要があります。デフォルトでは入っていないので、/etc/profile内に

LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

を追記しておきます。

6. 実行

ちなみにグラフを吐くCGIスクリプトは下のような感じ。これはsensor.logというファイルから一日のデータをプロットしたPNGイメージを出力してくれるというものです。無駄に色指定に凝ってます。^^;

#!/usr/bin/perl
print "Content-Type: image/png\n\n";

$cmd = <<EOF;
set terminal png size 640,120 x081108 x11ff11 x228822 xff0000 x0066ff
set grid
set xdata time
set timefmt "%s"
set format x "%H:%M"
set xtics 10800
set mxtics 3
set ticscale 4 2
set y2range [0:1000]
plot [0:24*60*60][20:40] "../sensor.log" u (\$1-$start):(\$2+($temp_correct)) w line t "S1", "../sensor.log" u (\$1-$start):3 axis x1y2 w line t "S2"
EOF

open(PLOT, "|gnuplot");
print PLOT $cmd;
close PLOT;
wait;

出力例。