gdを完全に/usrから離れて作る

できねええええええ

詳細はまた今度。

      • -

さて、また今度の今日は9/22。結果から言うと、できた。

でもMakefile修正が必要。

仕事でやる話だから、だいたい誰にでも(やってる内容が理解出来る範囲で)出来るようにしておきたいという意図と、バージョンアップ後にもなるべく同じ手順で出来るように、という意図から configure オプションやらせいぜいCFLAGS,LDFLAGSの指定で事足りるように、と思っていたんだけど、やっぱり手でMakefileを修正しないと出来なかった。

今回gdを作る目的は、Perlスクリプトから use GD; などとやって使わせる目的。

site_perlの下にがんがんモジュールを突っ込んで行くのもいいけど、モジュール間の依存関係をちゃんと気にして突っ込むのはちょっと無理。

だから、Perlプログラマに使いたいライブラリを選ばせることにした。プログラマは、次のような手順で使いたいライブラリを選ぶ。

#!/path/to/perl
use lib qw(/mylib/v1.0);

use GD;
use hoge;

こういう書き方をさせると、/mylib/v1.0を凍結させることが出来る。新しいモジュールがいれたくなったら、/mylib/v1.1でも作れば良い。それが使いたいプログラムは、use lib qw(/mylib/v1.1); とやれば良い。依存するライブラリもそこに入れてしまえば良い。

Perlみたいなプログラムはできるだけポータブルじゃなきゃいけない。プログラムを書くほうは本当に意識をしないらしいが、Perlモジュールのアーキテクチャ依存やバージョン依存は本当に悩ましいものなのだ。最新のモジュールが少し前のPerlでは使えないなんてことはザラにあるのだ。

さて、/mylib/v1.0はNFSサーバに置いてしまおうかと思っている。サーバは何台もあるから、ファイルを配布するのは面倒だ。

・あるx86 Solaris10 64bitサーバでは
/mylib/v1.0 -> /path/to/nfs/mylib/v1.0/Solaris10_i386_64
・とある x86_64 Linux 2.6 サーバでは
/mylib/v1.0 -> /path/to/nfs/mylib/v1.0/Linux_2.6_x86_64

などとやっておけば、アーキテクチャ依存も回避できないかね?

さて、gdというかGDを/usr以下のライブラリに極力依存せずに作りたいのは上記のような理由による。/mylibの下にPerlのバージョン番号だっていれちゃうぞ。俺ライブラリバージョンは1.0から始めよう。依存するライブラリ(↓には書いてないけどlibzだって同様だ)も全て/mylibに入れてしまおう。

以下手順。 x86 Solaris 10でやったログを加工したもの。いろんなアーキテクチャでこの作業をやって、ちょっとづつ手順が違って本当にやっかいだったが、詳しくは書かない。意図を組んで勝手にやんなさい。

libiconv

/configure \
  --prefix=/mylib/5.8.8/1.0/local
make
make install

freetype

GNUMAKE=/usr/sfw/bin/gmake \
CFLAGS="-I/mylib/5.8.8/1.0/local/include" \
LDFLAGS="-L/mylib/5.8.8/1.0/local/lib -R/mylib/5.8.8/1.0/local/lib"
./configure \
  --prefix=/mylib/5.8.8/1.0/local
gmake
gmake install

libpng

このライブラリは本当にアーキテクチャ依存がヒドイ。まさにnightmareだ。(gdのconfigureスクリプトのコメントにそう書いてある。俺もそう思う。)

cp scripts/makefile.solaris-x86 ./makefile
vi makefile
makefileを以下の通り書き換える。
--- scripts/makefile.solaris-x86        Thu Aug 21 19:54:14 2008
+++ makefile    Sat Sep  6 10:51:06 2008
@@ -28,7 +28,7 @@
 RM_F=/bin/rm -f

 # Where make install puts libpng.a, libpng12.so*, and png.h
-prefix=/usr/local
+prefix=/mylib/5.8.8/1.0/local
 exec_prefix=$(prefix)

 # Where the zlib library and include files are located
@@ -37,8 +37,8 @@
 #ZLIBLIB=../zlib
 #ZLIBINC=../zlib

-ZLIBLIB=/usr/local/lib
-ZLIBINC=/usr/local/include
+ZLIBLIB=/mylib/5.8.8/1.0/local/lib
+ZLIBINC=/mylib/5.8.8/1.0/local/include

 WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
        -Wmissing-declarations -Wtraditional -Wcast-align \
@@ -95,7 +95,7 @@
        ( cat scripts/libpng-config-head.in; \
        echo prefix=\"$(prefix)\"; \
        echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
-       echo cppflags=\""; \
+       echo cppflags=\"\"; \
        echo L_opts=\"-L$(LIBPATH)\"; \
        echo R_opts=\"-R$(LIBPATH)\"; \
        echo libs=\"-lpng12 -lz -lm\"; \

make
make install

makefile.solaris-x86 のcppflagsのところは配布ソースのバグ。\足りないんだよね。

libjpeg

./configure \
  --prefix=/mylib/5.8.8/1.0/local \
  --without-x \
  --enable-shared \
  --enable-static
make
make install

Linuxの場合はmake前に以下のおまじないが必要。jpegライブラリ同梱のautoconfが古いから?らしい。

ln -s `which libtool` libtool

libgd

やっとlibgdだ。

export CFLAGS="-I/mylib/5.8.8/1.0/local/include" \
       LDFLAGS="-L/mylib/5.8.8/1.0/local/lib \
                -R/mylib/5.8.8/1.0/local/lib" \
       CPPFLAGS="-DLIBICONV_PLUG -DJISX0208" \
       LIBPNG12_CONFIG=/mylib/5.8.8/1.0/local/bin/libpng12-config \
       LIBPNG_CONFIG=/mylib/5.8.8/1.0/local/bin/libpng-config

makeを叩くと、中でもう一度configureを実行するので、exportしてやる必要があった。

 ./configure \
  --prefix=/mylib/5.8.8/1.0/local \
  --without-x \
  --with-libiconv-prefix=/mylib/5.8.8/1.0/local \
  --with-png=/mylib/5.8.8/1.0/local \
  --with-freetype=/mylib/5.8.8/1.0/local \
  --with-jpeg=/mylib/5.8.8/1.0/local
 make
 make install
 unset CFLAGS LDFLAGS CPPFLAGS LIBPNG12_CONFIG LIBPNG_CONFIG

GD

ライブラリのリンクパス関連の問題ですげぇ面倒。もしかしたらアーキテクチャによって(LinuxとかHP-UXとか)は同じようにならないので、特に注意のこと。

PATH=$PATH":/mylib/5.8.8/1.0/local/bin" \
perl Makefile.PL \
 PREFIX=/mylib/5.8.8/1.0 \
 LIB=/mylib/5.8.8/1.0/lib \
  -options "JPEG,FT,PNG,GIF" \
  -lib_gd_path /mylib/5.8.8/1.0/local/lib \
  -lib_ft_path /mylib/5.8.8/1.0/local/lib \
  -lib_png_path /mylib/5.8.8/1.0/local/lib \
  -lib_jpeg_path /mylib/5.8.8/1.0/local/lib \
  -lib_zlib_path /mylib/5.8.8/1.0/local/lib

ここで出来るMakefileを以下のとおり編集する。

  # --- MakeMaker dynamic_lib section:
  
  # This section creates the dynamically loadable $(INST_DYNAMIC)
  # from $(OBJECT) and possibly $(MYEXTLIB).
  ARMAYBE = :
- OTHERLDFLAGS =
+ OTHERLDFLAGS = -R/mylib/5.8.8/1.0/local/lib
  INST_DYNAMIC_DEP =
  INST_DYNAMIC_FIX =

これをやらないと、実行時のライブラリ探索パスがOS標準になってしまうので、use GDしてもlibgdが見付かりません、っていうことになってしまう。

あとは以下のとおり。

make
ake install

そんなオプションはない、っていうエラーメッセージが出てしまうが、実害はないようだ。(ヘッダのincludeもライブラリのlinkも大丈夫)。