Alien::RRDtoolをhomebrew使わずに入れてみる

Alien::RRDtool - RRDtoolをCPANから入れる - Perl Advent Calendar Japan 2011 Hacker Trackを見て、実際に自分のMac(OS X 10.6.8)でRRDtoolを入れてみた。
素直にhomebrewで依存ライブラリ入れてしまえば問題無くインストール出来るのだけど、「homebrewとかに頼らずに全部自前ビルドするのが好き」という厨二気質を出してチャレンジしてみた。

環境

まっさらな状態を作るためにアカウントを新規に追加("hoge"とする)。"/Users/hoge/"以下だけで構築するよう頑張る。

Perlの準備

まずはperlbrew。

$ curl -kL http://xrl.us/perlbrewinstall | bash
$ echo 'source ~/.bashrc' >> ~/.bash_profile
$ echo 'source ~/perl5/perlbrew/etc/bashrc' >> ~/.bashrc
$ echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc 

5.14.2あたりを入れておく。

$ source ~/perl5/perlbrew/etc/bashrc
$ perlbrew install perl-5.15.2
$ perlbrew switch perl-5.14.2

cpanmを入れる。

$ curl -kL http://cpanmin.us | perl - App::cpanminus

いきなりインストールしてみる

$ cpanm -v Alien::RRDtool

...

Find 3rd-Party Libraries
checking for libdbi... no
checking for libwrap... no
checking for cairo_font_options_create in -lcairo... no
checking for pkg-config... no
configure: WARNING:
----------------------------------------------------------------------------
* I could not find a working copy of cairo-png. Check config.log for hints on why
  this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
  so that compiler and the linker can find libcairo and its header files. If
  you have not installed cairo-png, you can get it either from its original home on

     http://cairographics.org/releases/

  You can find also find an archive copy on

     http://oss.oetiker.ch/rrdtool/pub/libs

  The last tested version of cairo-png is 1.4.6.

       LIBS=
   LDFLAGS=
  CPPFLAGS= -D_THREAD_SAFE

----------------------------------------------------------------------------

...

依存モジュール系を一通りインストールしてくれるが、その後でこういったメッセージで依存ライブラリが無いよ、と怒られる。親切ですね。

依存ライブラリを自力で入れる

適当にディレクトリ作ってそこで作業しつつ、$HOME/local以下にインストールしていく。

$ mkdir ~/temp

まずはpkg-config

$ cd ~/temp
$ curl -O http://pkgconfig.freedesktop.org/releases/pkg-config-0.26.tar.gz
$ tar zxvf pkg-config-0.26.tar.gz 
$ cd pkg-config-0.26
$ ./configure --prefix=$HOME/local

なんか"glibが無い"って怒られた。それはこれから入れるのに…と思ってよく読んでみると

A copy of glib 1.2.10 is shipped together with pkg-config versions prior to 0.25

http://www.freedesktop.org/wiki/Software/pkg-config

0.25以下の方が入れやすそう。

$ cd ~/temp
$ curl -O http://pkgconfig.freedesktop.org/releases/pkg-config-0.25.tar.gz
$ tar zxvf pkg-config-0.25.tar.gz 
$ cd pkg-config-0.25
$ ./configure --prefix=$HOME/local
$ make
$ make install

すんなり入った。次はcairo

$ cd ~/temp
$ curl -O http://oss.oetiker.ch/rrdtool/pub/libs/cairo-1.6.4.tar.gz
$ tar zxvf cairo-1.6.4.tar.gz 
$ cd cairo-1.6.4
$ ./configure --prefix=$HOME/local

pixmanが無い、と言われました。入れましょう。

$ cd ~/temp
$ curl -O http://oss.oetiker.ch/rrdtool/pub/libs/pixman-0.10.0.tar.gz
$ tar zxvf pixman-0.10.0.tar.gz 
$ cd pixman-0.10.0
$ ./configure --prefix=$HOME/local
$ make
$ make install

cairo再チャレンジ。

$ cd ~/temp/cairo-1.6.4
$ ./configure --prefix=$HOME/local

今度はlibpngが足りないそうです。入れる。

$ cd ~/temp
$ curl -O http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.18.tar.gz
$ tar zxvf libpng-1.2.18.tar.gz 
$ cd libpng-1.2.18
$ ./configure --prefix=$HOME/local
$ make
$ make install

どうだ。

$ cd ~/temp/cairo-1.6.4
$ ./configure --prefix=$HOME/local
$ make

...

cairo-quartz-font.c: In function 'cairo_quartz_font_face_create_for_cgfont':
cairo-quartz-font.c:247: warning: ignoring return value of '_cairo_error', declared with attribute warn_unused_result
cairo-quartz-font.c: In function '_cairo_quartz_init_glyph_metrics':
cairo-quartz-font.c:415: warning: unused variable 'textMatrix'
cairo-quartz-font.c: In function '_cairo_quartz_path_apply_func':
cairo-quartz-font.c:495: warning: ignoring return value of '_cairo_path_fixed_move_to', declared with attribute warn_unused_result
cairo-quartz-font.c:500: warning: ignoring return value of '_cairo_path_fixed_line_to', declared with attribute warn_unused_result
cairo-quartz-font.c:512: warning: ignoring return value of '_cairo_path_fixed_curve_to', declared with attribute warn_unused_result
cairo-quartz-font.c:522: warning: ignoring return value of '_cairo_path_fixed_curve_to', declared with attribute warn_unused_result
cairo-quartz-font.c:531: warning: ignoring return value of '_cairo_path_fixed_close_path', declared with attribute warn_unused_result
cairo-quartz-font.c: In function 'cairo_quartz_font_face_create_for_atsu_font_id':
cairo-quartz-font.c:781: error: implicit declaration of function 'FMGetATSFontRefFromFont'
cairo-quartz-font.c:781: warning: nested extern declaration of 'FMGetATSFontRefFromFont'
cairo-quartz-font.c:782: warning: 'CGFontCreateWithPlatformFont' is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGFont.h:60)
make[2]: *** [libcairo_la-cairo-quartz-font.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

configureは出来るけどmakeでコケる。エラーメッセージでググると以下の記事が見つかった。
http://hwat.sakura.ne.jp/note/201001/20-220000/
20005 – Quartz font backend fails to compile
どうやらこのバージョンのcairoはイケてないらしい。このpatchが入ったあとのバージョンである1.8.8にしてみる。

$ cd ~/temp
$ curl -O http://cairographics.org/releases/cairo-1.8.8.tar.gz
$ tar zxvf cairo-1.8.8.tar.gz 
$ cd cairo-1.8.8
$ ./configure --prefix=$HOME/local

...

checking whether cairo's image surface backend feature could be enabled... no (requires pixman-1 >= 0.12.0 http://cairographics.org/releases/)
configure: error: mandatory image surface backend feature could not be enabled

おっと…そしたら今度はpixmanが古すぎてダメ orz。新しいの入れ直します。

$ cd ~/temp
$ curl -O http://cairographics.org/releases/pixman-0.12.0.tar.gz
$ tar zxvf pixman-0.12.0.tar.gz 
$ cd pixman-0.12.0
$ ./configure --prefix=$HOME/local
$ make
$ make install

今度こそ、と再挑戦

$ cd ~/temp/cairo-1.8.8
$ ./configure --prefix=$HOME/local
$ make

...

cairo-xlib-display.c:41:35: error: fontconfig/fontconfig.h: No such file or directory
make[3]: *** [cairo-xlib-display.lo] Error 1
make[2]: *** [all] Error 2
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

fontconfigが無い、と。

$ cd ~/temp
$ curl -O http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig-2.4.2.tar.gz
$ tar zxvf fontconfig-2.4.2.tar.gz 
$ cd fontconfig-2.4.2
$ ./configure --prefix=$HOME/local
$ make
$ make install

これでどうだ…

$ cd ~/temp/cairo-1.8.8
$ ./configure --prefix=$HOME/local
$ make
$ make install

ようやくインストールできた。

次はglib

$ cd temp/
$ curl -O http://oss.oetiker.ch/rrdtool/pub/libs/glib-2.15.4.tar.gz
$ tar zxvf glib-2.15.4.tar.gz 
$ cd glib-2.15.4
$ ./configure --prefix=$HOME/local

...

checking libintl.h usability... no
checking libintl.h presence... no
checking for libintl.h... no
configure: error:
*** You must have either have gettext support in your C library, or use the
*** GNU gettext library. (http://www.gnu.org/software/gettext/gettext.html

gettextが必要です。入れる。

$ cd ~/temp
$ curl -O http://ftp.gnu.org/pub/gnu/gettext/gettext-0.18.1.1.tar.gz
$ tar zxvf gettext-0.18.1.1.tar.gz 
$ cd gettext-0.18.1.1
$ ./configure --prefix=$HOME/local
$ make
$ make install

再挑戦。

$ cd ~/temp/glib-2.15.4
$ ./configure --prefix=$HOME/local

どうもgettextpkg-configから情報を取ってこられない?自分でFLAGSを指定してやらないとうまくいかなかった。

$ ./configure --prefix=$HOME/local LDFLAGS="-L$HOME/local/lib" CPPFLAGS="-I$HOME/local/include"
$ make

...

gconvert.c:51:2: error: #error GNU libiconv not in use but included iconv.h is from libiconv
gconvert.c: In function 'g_convert_with_iconv':
gconvert.c:632: warning: format not a string literal and no format arguments
gconvert.c:669: warning: format not a string literal and no format arguments
gconvert.c: In function 'strdup_len':
gconvert.c:1017: warning: format not a string literal and no format arguments
gconvert.c: In function 'g_filename_to_uri':
gconvert.c:1893: warning: format not a string literal and no format arguments
make[4]: *** [gconvert.lo] Error 1
make[3]: *** [all-recursive] Error 1
make[2]: *** [all] Error 2
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

configureは出来たけどまたmakeでコケる。libiconvが無かった。

$ cd ~/temp
$ curl -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
$ tar zxvf libiconv-1.14.tar.gz 
$ cd libiconv-1.14
$ ./configure --prefix=$HOME/local
$ make
$ make install

で再挑戦。

$ cd ~/temp/glib-2.15.4
$ ./configure --prefix=$HOME/local LDFLAGS="-L$HOME/local/lib" CPPFLAGS="-I$HOME/local/include"
$ make
$ make install

入った! 最後にpango

$ cd ~/temp
$ curl -O http://oss.oetiker.ch/rrdtool/pub/libs/pango-1.17.5.tar.gz
$ tar zxvf pango-1.17.5.tar.gz 
$ cd pango-1.17.5
$ ./configure --prefix=$HOME/local
$ make
$ make install

これはすんなり。

Alien::RRDtoolに挑戦

依存ライブラリが揃ったので、改めてAlien::RRDtoolのインストールをしてみる。

$ cpanm -v Alien::RRDtool

...

->> /Users/hoge/perl5/perlbrew/perls/perl-5.14.2/bin/perl Makefile.PL LIBS=-L/usr/local/lib -L/Developer/SDKs/MacOSX10.6.sdk/usr/lib -L/Developer/SDKs/MacOSX10.6.sdk/usr/X11/lib -lxml2 -lcairo -lcairo -lcairo  -lcairo -lpng12   -lglib-2.0 -lintl -liconv   -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl -liconv   RPATH=/Users/hoge/.cpanm/work/1323056803.27527/Alien-RRDtool-0.02/rrdtool/src/.libs
Checking if your kit is complete...
Looks good
'RPATH' is not a known MakeMaker parameter name.
Note (probably harmless): No library found for -lglib-2.0
Note (probably harmless): No library found for -lintl
Note (probably harmless): No library found for -lpangocairo-1.0
Note (probably harmless): No library found for -lpango-1.0
Note (probably harmless): No library found for -lgobject-2.0
Note (probably harmless): No library found for -lgmodule-2.0
Note (probably harmless): No library found for -lglib-2.0
Note (probably harmless): No library found for -lintl
Writing Makefile for RRDp
Writing MYMETA.yml
->> make
cp RRDp.pm blib/lib/RRDp.pm
Manifying blib/man3/RRDp.3
In rrdtool/bindings/perl-shared:
->> make test
PERL_DL_NONLAZY=1 /Users/hoge/perl5/perlbrew/perls/perl-5.14.2/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/base.t .. 1/7 Can't load '/Users/hoge/.cpanm/work/1323056803.27527/Alien-RRDtool-0.02/rrdtool/bindings/perl-shared/blib/arch/auto/RRDs/RRDs.bundle' for module RRDs: dlopen(/Users/hoge/.cpanm/work/1323056803.27527/Alien-RRDtool-0.02/rrdtool/bindings/perl-shared/blib/arch/auto/RRDs/RRDs.bundle, 2): Symbol not found: _g_free
  Referenced from: /Users/hoge/.cpanm/work/1323056803.27527/Alien-RRDtool-0.02/rrdtool/bindings/perl-shared/blib/arch/auto/RRDs/RRDs.bundle
  Expected in: dynamic lookup
 at t/base.t line 20
Compilation failed in require at t/base.t line 20.
BEGIN failed--compilation aborted at t/base.t line 20.
t/base.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 7/7 subtests 

Test Summary Report
-------------------
t/base.t (Wstat: 65280 Tests: 1 Failed: 1)
  Failed test:  1
  Non-zero exit status: 255
  Parse errors: Bad plan.  You planned 7 tests but ran 1.
Files=1, Tests=1,  1 wallclock secs ( 0.03 usr  0.01 sys +  0.01 cusr  0.02 csys =  0.07 CPU)
Result: FAIL
Failed 1/1 test programs. 1/1 subtests failed.
make: *** [test_dynamic] Error 255
Failed to system(make test): No such file or directory at ./Build line 58
FAIL
! Installing Alien::RRDtool failed. See /Users/hoge/.cpanm/build.log for details.

ライブラリが足りない系のエラーは出ないけど、最後のビルドのところでNo library found for ...と言われて失敗している。LIBSで指定しているパスが足りていない…?
inc/MyBuilder.pmを見てみると、

    my @libdirs = (
        '/usr/local/lib',
        map { ("$_/usr/lib", "$_/usr/X11/lib") } </Developer/SDKs/MacOSX*>,
    );

    my $libs = do {
        open my $fh, '<', $self->notes('name') . '/Makefile';

        my $libs = '';
        while(<$fh>) {
            if(/ALL_LIBS \s+ = \s+ (.+) /xms) {
                chomp($libs = $1);
            }
        }
        join ' ', (map { "-L$_" } @libdirs),  $libs;
    };

    my $rpath = Cwd::abs_path($self->notes('name') . '/src/.libs') or die;

    $self->perl_bindings(sub {
        xsystem($self->perl,
            'Makefile.PL',
            "LIBS=$libs",
            "RPATH=$rpath");
        xsystem($Config{make});
    });

という指定になっていて、/usr/local/lib, /Developer/SDKs/MacOSX10.6.sdk/usr/lib, /Developer/SDKs/MacOSX10.6.sdk/usr/X11/libといったパスは入るけど、いままで自分でインストールしていた$HOME/local/libは含まれないことになる。
どうしたら良いのか分からないけど無理矢理書き加えてみた。

$ cd ~/temp
$ curl -LO http://search.cpan.org/CPAN/authors/id/G/GF/GFUJI/Alien-RRDtool-0.02.tar.gz
$ tar zxvf Alien-RRDtool-0.02.tar.gz
$ cd Alien-RRDtool-0.02
$ chmod u+w inc/MyBuilder.pm
$ vim inc/MyBuilder.pm

    my @libdirs = (
        '/Users/hoge/local/lib',
        '/usr/local/lib',
        map { ("$_/usr/lib", "$_/usr/X11/lib") } </Developer/SDKs/MacOSX*>,
    );

とダイレクトに指定。そうすると上手くいくようだ。

$ perl Build.PL
$ make
$ make test
$ make install
$ rrdtool 
RRDtool 1.4.5  Copyright 1997-2010 by Tobias Oetiker <tobi@oetiker.ch>
               Compiled Dec  6 2011 02:26:39

Usage: rrdtool [options] command command_options
Valid commands: create, update, updatev, graph, graphv,  dump, restore,
		last, lastupdate, first, info, fetch, tune,
		resize, xport, flushcached

RRDtool is distributed under the Terms of the GNU General
Public License Version 2. (www.gnu.org/copyleft/gpl.html)

For more information read the RRD manpages

結局

おそらくhomebrewなどのパッケージ管理ツールを使っていれば/usr/local/lib以下にライブラリが入るのでLIBSを書き換える必要ないと思うけど、自前でビルドして変なところにインストールしていると上手くいかない…のかな。
じゃあどうすれば良いのだろう?

$ pkg-config --libs-only-L cairo pango glib-2.0

の結果を$libsに足してもらうのが良いのかしら。