30
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

libtool

Posted at

前回力尽きたlibtoolについて。

/usr/local/libにあるライブラリを見ていると、.laとか、.so.1.1.0 みたいなファイルがあることに気づく。
こう言ったライブラリをリンクするときは、たとえば -lhoge とか書くとlibhoge.laを見てリンクが実行される。
この、*.laが何者なのか?と言う疑問がこのエントリを書いた動機である。

答えを先に言ってしまえば、これは GNU libtoolが作成したファイルである。
libtoolは、おそらく直接呼ぶことは少なくて、autoconf/automakeが生成したMakefileから呼び出されるツールである。
が、libtool単体でも使うことができるので、ここでは簡単なサンプルを挙げて説明してみる。
詳細なマニュアルは、http://www.gnu.org/software/libtool/manual/ から参照することができる。

前回、直接ccを呼び出して動的ライブラリを作成する方法について説明したが、「-fPICつけるんだっけ?」とか、「-rpathと-rpath-linkを適切に指定しないと・・・」とか、「とりあえずビルドはできたけど、インストール前に試しに実行しようと思っても.soが見つからなくてエラーになる」とかいろいろ問題がある。

そんな問題を解決してくれるのがlibtoolである。

libtoolのインストール

FreeBSDのbaseシステムには、libtoolは入っていない。pkgngを使っている場合は、以下のコマンドでインストールできる

% sudo pkg install libtool

今日時点では、libtool 2.4.5 がインストールされた。

libtoolの使い方

ライブラリに入れるソースのコンパイル

今回もソースを用意しよう。

func4.c
int func4(void)
{
    return 7;
}

ビルドするときのコマンドは、以下。

% libtool --mode=compile cc -c func4.c
libtool: compile:  cc -c func4.c  -fPIC -DPIC -o .libs/func4.o
libtool: compile:  cc -c func4.c -o func4.o >/dev/null 2>&1

libtool --mode=compileに続けて、通常のコンパイルコマンドを書けば良い。

libtoolを使うと、2回コンパイルされる。1度目は動的ライブラリ用に-fPICがついたもの、2度目は静的ライブラリ用に-fPICがつかないもの。
このコマンドにより、以下のファイルが生成される。

func4.o
静的ライブラリ用のオブジェクト
func4.lo
libtoolオブジェクト(テキストファイル)
.libs/func4.o
動的ライブラリ用のオブジェクト

ライブラリの生成

ライブラリの生成は、以下のコマンドで行う

% libtool --mode=link cc -o libfunc4.la func4.lo -rpath /usr/local/lib
libtool: link: cc -shared  -fPIC -DPIC  .libs/func4.o      -Wl,-soname -Wl,libfunc4.so.0 -o .libs/libfunc4.so.0.0.0
libtool: link: (cd ".libs" && rm -f "libfunc4.so.0" && ln -s "libfunc4.so.0.0.0" "libfunc4.so.0")
libtool: link: (cd ".libs" && rm -f "libfunc4.so" && ln -s "libfunc4.so.0.0.0" "libfunc4.so")
libtool: link: ar cru .libs/libfunc4.a  func4.o
libtool: link: ranlib .libs/libfunc4.a
libtool: link: ( cd ".libs" && rm -f "libfunc4.la" && ln -s "../libfunc4.la" "libfunc4.la" )

libtool --mode=linkに続けて、cc -o 出力するライブラリ名(.la)、入力となるlibtoolオブジェクト(.lo)を並べた後、-rpathオプションを指定する。

このコマンドにより生成されるファイルは以下

libfunc4.la
libtool control file
.libs/libfunc4.a
静的ライブラリ
.libs/libfunc4.la
../libfunc4.laへのシンボリックリンク
.libs/libfunc4.lai
インストール用のlaファイル
.libs/libfunc4.so
libfunc4.so.0.0.0へのシンボリックリンク
.libs/libfunc4.so.0
libfunc4.so.0.0.0へのシンボリックリンク
.libs/libfunc4.so.0.0.0
動的ライブラリ

実行ファイルの生成

test4.c
int func4(void);
int main(int argc, char *argv[])
{
    return func4();
}
% libtool --mode=link cc -o test4 test4.c libfunc4.la
libtool: link: cc -o .libs/test4 test4.c  ./.libs/libfunc4.so -Wl,-rpath -Wl,/usr/local/lib

libtool --mode=linkに続けて、通常のコンパイルコマンドを書くが、ライブラリの指定は-lオプションではなく*.laファイルを指定する。-rpathオプション等は気にしなくて良い。

このコマンドにより生成されるファイルは以下

test4
実行ファイルのwrapper script
.libs/test4
実行ファイルの実体

前回の例と違うのは、ここで生成されるtest4が実行可能であると言うこと。
インストール前に、思う存分テストができる。

インストール

ライブラリのインストール

% sudo libtool --mode=install install -c libfunc4.la /usr/local/lib/
libtool: install: install -c .libs/libfunc4.so.0.0.0 /usr/local/lib/libfunc4.so.0.0.0
libtool: install: (cd /usr/local/lib && { ln -s -f libfunc4.so.0.0.0 libfunc4.so.0 || { rm -f libfunc4.so.0 && ln -s libfunc4.so.0.0.0 libfunc4.so.0; }; })
libtool: install: (cd /usr/local/lib && { ln -s -f libfunc4.so.0.0.0 libfunc4.so || { rm -f libfunc4.so && ln -s libfunc4.so.0.0.0 libfunc4.so; }; })
libtool: install: install -c .libs/libfunc4.lai /usr/local/lib/libfunc4.la
libtool: install: install -c .libs/libfunc4.a /usr/local/lib/libfunc4.a
libtool: install: chmod 644 /usr/local/lib/libfunc4.a
libtool: install: ranlib /usr/local/lib/libfunc4.a

実行ファイルのインストール

% sudo libtool --mode=install install -c test4 /usr/local/bin/
libtool: install: install -c .libs/test4 /usr/local/bin/test4

lddで見てみる

% ldd /usr/local/bin/test4
/usr/local/bin/test4:
        libfunc4.so.0 => /usr/local/lib/libfunc4.so.0 (0x80081d000)
        libc.so.7 => /lib/libc.so.7 (0x800a1e000)

libtoolを使ってインストールしたライブラリを使う

普通に/usr/local/libにあるライブラリを使うときと同じ

% cc -o test4-2 test4.c -L/usr/local/lib -lfunc4
% ldd test4-2
test4-2:
        libfunc4.so.0 => /usr/local/lib/libfunc4.so.0 (0x80081d000)
        libc.so.7 => /lib/libc.so.7 (0x800a1e000)

.aもインストールされているので、静的リンクも可

% cc -o test4-3 -static test4.c -L/usr/local/lib -lfunc4
% ldd test4-3
ldd: test4-3: not a dynamic ELF executable
30
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?