cpanm
で Cache::Memcached::libmemcached モジュールを入れようとしたら入らなかったので、build.log を見ていたら、それが依存している Memcached::libmemcached モジュールのインストールに失敗しているので色々試行錯誤してみました。
__2014年4月の情報__です。環境は以下。
- Mac OS X Mavericks
- Perl 5.18 on plenv and/or perlbrew
- このときのMemcached::libmemcachedのバージョンは 1.001702
この辺りの情報はすぐ陳腐化するので、1年以上前の場合はあまりアテにしないほうがいいかもしれません(この記事をみる未来のみなさんへのメッセージでもあります)。また各種モジュールのバージョンの詳細は各種Changelogも参照ください。
前提条件
memcached にアクセスするモジュールには色々あって、 今の時代であればあえてCache::Memcached::libmemcached (つまるところ Memcached::libmemcached) を使う必要は無い と各所から言われました。今であれば
- Cache::Memcached Pure Perlで遅いと言われるかもしれないけど、それゆえインストールでハマりどころが少ない
- Cache::Memcached::Fast XS実装だけど自前で書かれているし多くの採用事例があるので情報が多い
を使うべきでしょう。
私の場合、以前からある業務アプリケーションの改修のため、Cache::Memcached::libmemcached を入れる必要がありました。
結果的に
今回は 1.001702 が Mac OS X 環境 (Xcode 5.2) でダメだという結論に至ったので、一つ古いバージョンをインストールすることでお茶を濁しています。なので以下の多くのトラブルシューティングは、もしかしたら 1.001702 で問題解決にたどり着こうという人のヒントにしかなっていません。
一つ古いバージョンの Memcached::libmemcached のインストール方法は下の方にスクロールしてみてください。
普通にcpanmしてみる
とりあえず普通にcpanm
してみます。
$ cpanm Memcached::libmemcached
--> Working on Memcached::libmemcached
Fetching http://www.cpan.org/authors/id/W/WO/WOLFSAGE/Memcached-libmemcached-1.001702.tar.gz ... OK
Configuring Memcached-libmemcached-1.001702 ... N/A
! Configure failed for Memcached-libmemcached-1.001702. See /Users/ogata/.cpanm/build.log for details.
失敗しました。
build.log を見てみると最後のほうにエラーの内容が書かれています。私の場合は以下のようなものでした。
./libmemcached-1.0/memcached.h:46:12: fatal error: 'tr1/cinttypes' file not foun
d
# include <tr1/cinttypes>
^
CXX libhashkit/libhashkit_libhashkitinc_la-has.lo
CXX libhashkit/libhashkit_libhashkitinc_la-hashkit.lo
1 error generated.
make[1]: *** [libtest/dream.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [install] Error 2
Unable to build libmemcached: Error running cd src/libmemcached && make install
Aborted.
-> N/A
-> FAIL Configure failed for Memcached-libmemcached-1.001702. See /Users/ogata/.
cpanm/build.log for details.
Expiring 3 work directories.
tr1/cinnttypes がないと言われています。
Perl の Memcached::libmemcached 自体の問題というよりも libmemcached 自体の問題であることが以下のようにしてわかります。
$ pwd
/Users/ogata/.cpanm/latest-build/Memcached-libmemcached-1.001702/src/libmemcached
Memcached::libmemcached は libmemcached 自体のソースコードを同梱しているようです。
libmemacached自体を単体でビルドしてみる
おもむろにこのディレクトリ内で ./configure
してみると特に問題なく Makefile ができます。
この状態で make
してみると
$ make
(中略)
In file included from libmemcached/csl/context.cc:38:
In file included from ./libmemcached/csl/common.h:50:
In file included from ./libmemcached/common.h:114:
./libmemcached-1.0/memcached.h:46:12: fatal error: 'tr1/cinttypes' file not
found
# include <tr1/cinttypes>
^
1 error generated.
CXX libmemcached/csl/libmemcached_libmemcached_la-parser.lo
make[1]: *** [libmemcached/csl/libmemcached_libmemcached_la-context.lo] Error 1
make[1]: *** Waiting for unfinished jobs....
In file included from libmemcached/csl/parser.yy:39:
In file included from ./libmemcached/csl/common.h:50:
In file included from ./libmemcached/common.h:114:
./libmemcached-1.0/memcached.h:46:12: fatal error: 'tr1/cinttypes' file not
found
# include <tr1/cinttypes>
^
1 error generated.
make[1]: *** [libmemcached/csl/libmemcached_libmemcached_la-parser.lo] Error 1
make: *** [all] Error 2
tr1/cinttypes がないと言っているのは libmemcached のビルドです。
libmemcached のビルドについて調べていると、このgistにヒントがありました。
Homebrew の formula のようですが、環境変数を設定している部分があります。
if MacOS.version > :mountain_lion
ENV.append 'CXXFLAGS', "-I#{MacOS.sdk_path}/usr/include/c++/4.2.1"
ENV.append 'LIBS', "#{MacOS.sdk_path}/usr/lib/libstdc++.dylib"
end
真似てみましょう。対象ファイルやディレクトリがどこにあるかは、Spotlightのコマンドラインインターフェース mdfind
を使うことでなんとなくわかります。
$ mdfind -name 4.2.1
/Library/Developer/CommandLineTools/usr/lib/llvm-gcc/4.2.1
/usr/include/c++/4.2.1
自分の環境の沿った場所を見つけたら、それを環境変数として設定します。
$ export CXXFLAGS=-I/usr/include/c++/4.2.1
$ export LIBS=/usr/lib/libstdc++.6.0.9.dylib
さて、libmemcached のビルド結果は変わるでしょうか。
$ ./configure
(略)
$ make
(中略)
ld: file not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/lib/darwin/libclang_rt.ubsan_osx.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [libtest/abort] Error 1
make[1]: *** Waiting for unfinished jobs....
1 warning generated.
1 warning generated.
1 warning generated.
make: *** [all] Error 2
色々とwarningラッシュになりますが、とりあえずさっきよりはmake
コマンドの実行が長くなります。とはいえ、私の環境ではエラーが出てビルドは途中で停止してしまいました。
内容は ld
コマンドが、長大なディレクトリパスの中に libclang_rt.ubsan_osx.a
が見つからなかったというもの。
確かに確認してみると、私のXcode (5.2) 環境にはありませんでした。
$ ls -l /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/lib/darwin/
total 304
-rw-r--r-- 1 root wheel 7832 3 11 09:16 libclang_rt.10.4.a
-rw-r--r-- 1 root wheel 272468 3 11 09:16 libclang_rt.cc_kext.a
-rw-r--r-- 1 root wheel 131548 3 11 09:16 libclang_rt.cc_kext_ios5.a
-rw-r--r-- 1 root wheel 1824 3 11 09:16 libclang_rt.eprintf.a
-rw-r--r-- 1 root wheel 20812 3 11 09:16 libclang_rt.ios.a
-rw-r--r-- 1 root wheel 6000 3 11 09:16 libclang_rt.osx.a
-rw-r--r-- 1 root wheel 81420 3 11 09:16 libclang_rt.profile_ios.a
-rw-r--r-- 1 root wheel 38448 3 11 09:16 libclang_rt.profile_osx.a
libclang_rt.ubsan_osx.a が存在してどこかにあれば、それのシンボリックリンクをここに作るなどして対応できるとは思いますが、私の環境では見つかりませんでした。また、これで検索してみたものの、clang関連の英語の資料が見つかったくらいで、思ったような手がかりが見つからなかったので、結局ここで諦めてしまいました。
古いバージョンのMemcached::libmemcachedを試す
検索してもこういった情報が見つからなかったので、Xcode か Memcached::libmemcached (libmemcached) の以前のバージョンであればこういった問題がなかったんじゃないかと推察して、古いバージョンを試してみることにしました。CPANで見つかる一つ前のバージョンは 0.4406。番号が1より小さくなりました。
CPANから Memcached-libmemcached-0.4406.tar.gz をダウンロードしてきます。
(cpanm
コマンドには cpanm Module@version
という指定があるのですが、ここでは *.tar.gz をダウンロードすることにします。詳細は perldoc cpanm
を参照)
おもむろに cpanm
でこの .tar.gz ファイルを指定します。
$ cpanm Downloads/Memcached-libmemcached-0.4406.tar.gz
$ cpanm Downloads/Memcached-libmemcached-0.4406.tar.gz
--> Working on Downloads/Memcached-libmemcached-0.4406.tar.gz
Fetching file:///Users/ogata/Downloads/Memcached-libmemcached-0.4406.tar.gz ... OK
Configuring Memcached-libmemcached-0.4406 ... N/A
! Configure failed for Memcached-libmemcached-0.4406. See /Users/ogata/.cpanm/build.log for details.
失敗したので build.log を見てみます。
Wide character in printf at /Users/ogata/perl5/perlbrew/perls/perl-5.18/lib/5.18
.0/Pod/Simple.pm line 539.
memslap.pop around line 78: Non-ASCII character seen before =encoding in 'don’t'
. Assuming UTF-8
POD document had syntax errors at /Users/ogata/perl5/perlbrew/perls/perl-5.18/bi
n/pod2man line 71.
make[3]: *** [memslap.1] Error 255
make[2]: *** [install] Error 2
make[1]: *** [install-recursive] Error 1
make: *** [install] Error 2
Unable to build libmemcached: Error running cd src/libmemcached && make install
Aborted.
-> N/A
-> FAIL Configure failed for Memcached-libmemcached-0.4406. See /Users/ogata/.cp
anm/build.log for details.
読んでみると、PODの中にASCIIじゃない文字があるのにencoding指定がなかったという些細なもの。
伸長して直してみましょう。
$ find Memcached-libmemcached-0.4406 -name memslap\*
Memcached-libmemcached-0.4406/src/libmemcached/clients/memslap.c
Memcached-libmemcached-0.4406/src/libmemcached/docs/memslap.pod
memslap.pop の元ネタは memslap.pod だとあたりをつけて直します。Vim か何かで開いて、冒頭に =encoding utf8
と加えるだけの簡単な仕事です。
$ head -n 5 Memcached-libmemcached-0.4406/src/libmemcached/docs/memslap.pod
=encoding utf8
=head1 NAME
memslap - Load testing and benchmarking tool for memcached
こうなるようにします。
再びこれを tar
で戻して cpanm
します。
$ tar zcf Memcached-libmemcached-0.4406.tar.gz Memcached-libmemcached-0.4406/
$ cpanm Memcached-libmemcached-0.4406.tar.gz
--> Working on Memcached-libmemcached-0.4406.tar.gz
Fetching file:///Users/ogata/Memcached-libmemcached-0.4406.tar.gz ... OK
! Bad archive: Memcached-libmemcached-0.4406.tar.gz
! Failed to unpack Memcached-libmemcached-0.4406.tar.gz: no directory
! Failed to fetch distribution
Bad archive って言われる場合。Mac OS X の tar
コマンド、伸長は問題無いのですが、圧縮をすると cpanm
にとって Bad archive になってしまうようですね。このMacのtar
の問題は割とよく知られているようです。Homebrew で gnu-tar を入れて使っている人は問題無いかもしれません。Linux 環境で作業を行うことでも回避できます。
$ cpanm Memcached-libmemcached-0.4406.tar.gz
--> Working on Memcached-libmemcached-0.4406.tar.gz
Fetching file:///Users/ogata/Memcached-libmemcached-0.4406.tar.gz ... OK
Configuring Memcached-libmemcached-0.4406 ... FAIL
! Timed out (> 60s). Use --verbose to retry.
! Configure failed for Memcached-libmemcached-0.4406. See /Users/ogata/.cpanm/build.log for details.
こんなことを言われた場合には素直に --verbose
を付けてみます。
$ cpanm Memcached-libmemcached-0.4406.tar.gz
(中略)
Successfully installed Memcached-libmemcached-0.4406
1 distribution installed
無事入りました。
Cache::Memcached::libmemcache の 2014年4月現在 の最新バージョン 0.04001 の Makefile.PL を見ると、問題と格闘した Memcached::libmemcached のバージョンを要求しています。
use strict;
use inc::Module::Install;
name('Cache-Memcached-libmemcached');
all_from('lib/Cache/Memcached/libmemcached.pm');
requires('Memcached::libmemcached', '1.001701');
requires('Storable');
requires('Carp');
requires('Task::Weaken');
recommends('Compress::Zlib');
build_requires('Test::More', 0.80);
auto_include;
WriteAll;
なのでこれもまた、一つ前の古いバージョン 0.02011 の *.tar.gz をダウンロードしてインストールをすることになります。
$ cpanm Downloads/Cache-Memcached-libmemcached-0.02011.tar.gz
--> Working on Downloads/Cache-Memcached-libmemcached-0.02011.tar.gz
Fetching file:///Users/ogata/Downloads/Cache-Memcached-libmemcached-0.02011.tar.gz ... OK
Configuring Cache-Memcached-libmemcached-0.02010 ... OK
Building and testing Cache-Memcached-libmemcached-0.02010 ... OK
Successfully installed Cache-Memcached-libmemcached-0.02010
1 distribution installed
特に問題なく入りました。こちらは cpanm Cache::Memcached::libmemcached@0.02011
でもよいかもしれません。
インストールできて安堵したので、現時点で重点的に動作確認はしていません。ご了承下さい。
XcodeかPerlモジュール、どちらかのバージョンが上がってすんなり入るようになってくれると嬉しいなと感じます。
前述ですが、PerlでMemcachedにアクセスしたいのであれば、今使うのであれば Cache::Memcached::Fast や、それに依存したモジュールを使いましょう。
- この件に関して tokuhiromu さんがブログを書いてくださいました。 How do I install Memcached::libmemcached on OSX. - blog.64p.org