読者です 読者をやめる 読者になる 読者になる

テクニカルプア

備忘録と若干の補足

crfppを正しくインストールするためのパッチ書いた&"pkgdir"と"startdir/pkg"の違い

 昨夜、cabochaで遊ぼうと思ってkonsoleからコマンドを叩いたら以下のようなエラーを吐かれた。

cabocha: error while loading shared libraries: libcrfpp.so.0: cannot open shared object file: No such file or directory

 libcrfpp.so.0がないんですって。早速findで検索かけたがたしかに見つからない。crfpp(CRF++)はcabochaの依存関係に含まれるものであるのでインストールされてあるはずなのだが。

 浅薄なのはわかっているがここでcabochaの再インストールを試みた。が、今度はcabochaのコンパイルで以下のエラーが出てきた。

chunk_learner.cpp:6:19: fatal error: crfpp.h: No such file or directory

 これcrfppがどうにかなっているんじゃないか。ということでcrfppのPKGBUILDを見てみる事にした。すると現在は使用が非推奨になってる変数であるstartdir*1を用いてbuild()とかpackage()を書いていることがわかったので、startdir/pkgをpkgdirに、startdir/srcをsrcdirに変更してmakepkg、インストールした。この結果、cabochaのコンパイルも無事成功してきちんとcabochaが動いてくれた。

 AURのcrfppでもいちおうこの旨をコメントしておいたので重複するが、きちんと使えるcrfppのパッケージを作るためのパッチを下のリンクにおいておく。

 さて、なんでstartdirを使うとダメでpkgverおよびsrcdirを使うといいのかちょっと観察してみることにした。

まずtreeを用いてstartdirを使った場合とpkgdirおよびsrcdirを使った場合のディレクトリの様子をみた。通常makepkgするとPKGBUILDが存在するディレクトリ内にpkgとsrcの2つのディレクトリができるが、src下についてはstartdir/srcとsrcdirで内容に差異がなかったので省略する。

  • startdir/pkgの場合
.
├── CRF++-0.58.tar.gz
├── PKGBUILD
├── crfpp-0.58-1-x86_64.pkg.tar.xz
├── pkg
│   ├── crfpp
│   └── usr
│       ├── bin
│       │   ├── crf_learn
│       │   └── crf_test
│       ├── include
│       │   └── crfpp.h
│       └── lib
│           ├── libcrfpp.a
│           ├── libcrfpp.la
│           ├── libcrfpp.so -> libcrfpp.so.0.0.0
│           ├── libcrfpp.so.0 -> libcrfpp.so.0.0.0
│           └── libcrfpp.so.0.0.0
└── src

 

  • pkgdirの場合
.
├── CRF++-0.58.tar.gz
├── PKGBUILD
├── crfpp-0.58-1-x86_64.pkg.tar.xz
├── crfpp.patch
├── pkg
│   └── crfpp
│       └── usr
│           └── local
│               ├── bin
│               │   ├── crf_learn
│               │   └── crf_test
│               ├── include
│               │   └── crfpp.h
│               └── lib
│                   ├── libcrfpp.a
│                   ├── libcrfpp.la
│                   ├── libcrfpp.so -> libcrfpp.so.0.0.0
│                   ├── libcrfpp.so.0 -> libcrfpp.so.0.0.0
│                   └── libcrfpp.so.0.0.0
└── src

 PKGBUILDがあるディレクトリをカレントディレクトリとして.(ドット)、インストールするプログラムの名前をfooと表せば、startdirはそのままカレントディレクトリを指し、結果startdir/pkgは./pkgを指す。しかしpkgdirは./pkg/fooを指す。startdirをつかってインストール先を直接指定するよりは、pkgdirを用いて動的にインストール先を指定してもらったほうが便利だよ、という話のようだ。

 また、ふたつのtreeの結果をみるとわかるが、startdirを使った方はインストール先が./pkg/usr/binとなっているのに、pkgdirを使うと./pkg/crfpp/usr/local/binとなっている。crfppのMakefileには"prefix = /usr/local"が宣言してあり、pkgdirを使うとこのprefixが使用されるがstartdirではこれが使用されないようだ。結果、インストール先のディレクトリ構成が異なってしまう。ただ、Arch Linuxはすべてのパッケージは/usrを使用すべきとしており*2、その場合"prefix = /usr/local"という宣言は殺してしまうのがいいのかもしれない。./configureで--prefix=/usrしてるだけだった。

*1:startdir

           This contains the absolute path to the directory where the PKGBUILD is located, which is usually the output of $(pwd) when makepkg is started. Use of this variable is deprecated and strongly discouraged.

(PKGBUILDのman(pacman 4.1.2, 2013-06-18)より)

*2:https://wiki.archlinux.org/index.php/Creating_Packages