スタティックおよび共有ライブラリについて

スタティックライブラリ

ライブラリの作成(後からオブジェクトを追加)

> ar r libhoge.a hoge.o huga.o

ライブラリの中身を確認

> ar t libhoge.a
hoge.o
huga.o

共有ライブラリ

ライブラリの作成

-sharedオプションを追加すると共有ライブラリになる。名称は慣例として「lib+ファイル名+.so」とする。注意点は、リンクするライブラリは作成するモジュール(libhoge.so)よりも後ろで指定しないと、参照エラーになる。

> clang $(LDFLAGS) -shared hoge.o huga.o -o libhoge.so $(LIBS)

依存先の参照はlddコマンドで確認できる

> ldd hoge.so
	linux-vdso.so.1 =>  (0x00007fffbe9b7000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5f8893a000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5f88631000)
  :

ビルドモジュールの中身を確認

中身の参照は、nmreadelfコマンドで確認できる

> readelf -s -w libhoge.so | grep string
    1269  	std::move<std::__cxx11::basic_string<char> &>
    <2f2>   DW_AT_name        : (間接文字列、オフセット: 0x54b): basic_string<char, std::char_traits<char>, std::allocator<char> >
    <2f8>   DW_AT_name        : (間接文字列、オフセット: 0x58d): basic_stringstream<char, std::char_traits<char>, std::allocator<char> >
    <303>   DW_AT_name        : (間接文字列、オフセット: 0xeab): string
:
> nm libhoge.so
0000000000208210 d DW.ref.__gxx_personality_v0
0000000000007334 r GCC_except_table0
0000000000007354 r GCC_except_table1
0000000000007308 r GCC_except_table10
0000000000007454 r GCC_except_table17
0000000000007374 r GCC_except_table2
:

共有ライブラリの使い方

コンパイルリンクが完了して、モジュールを実行すると、以下のようにリンクした共有ライブラリが見つからないというエラーが発生する。

> ./test
./test: error while loading shared libraries: libhoge.so: cannot open shared object file: No such file or directory

> ldd test
	linux-vdso.so.1 =>  (0x00007ffc6ab15000)
	libhoge.so => not found
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb722d4c000)

共有ライブラリパス設定ファイルを追加

Linuxは、どうやらWindowsと異なっておりパスの通った場所にファイルを置いても見つけられない。ライブラリのキャッシュファイルが存在しており、このファイルにライブラリの存在を追加する必要がある。

1つ目の方法としては、/etc/ld.so.conf.d/以下に任意のファイルを作成し、そこに共有ライブラリ用のパスを追加する。そして、ldconfigコマンドでキャッシュを更新する。

デフォルトの状態でもいくつかのファイルが存在している。(以下はRaspbianのケース)

> ls /etc/ld.so.conf.d/
00-vmcs.conf  arm-linux-gnueabihf.conf  fakeroot-arm-linux-gnueabihf.conf  libc.conf 

> cat /etc/ld.so.conf.d/*
/opt/vc/lib
# Multiarch support
/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabihf/libfakeroot
# libc default configuration
/usr/local/lib

ここに今回作成した共有ライブラリ(libhoge.so)を置いておくディレクトリ(/home/share/test)を追加する。/etc/ld.so.conf.dフォルダにmy.confというファイルを作成してライブラリのディレクトリパスを追記する。

> sudo vi /etc/ld.so.conf.d/my.conf

/home/share/test/

ldconfigコマンドを実行すると、上記の設定ファイルに記載された検索パス以下にある共有ライブラリファイルを検索してキャッシュファイルを再作成する。

> sudo ldconfig -v
ldconfig: Path `/lib/arm-linux-gnueabihf' given more than once
ldconfig: Path `/usr/lib/arm-linux-gnueabihf' given more than once
/opt/vc/lib:
        libcontainers.so -> libcontainers.so
        libvcsm.so -> libvcsm.so
        libvchiq_arm.so -> libvchiq_arm.so
        libmmal_components.so -> libmmal_components.so
        libbrcmGLESv2.so -> libbrcmGLESv2.so
        libdebug_sym.so -> libdebug_sym.so
        libmmal_core.so -> libmmal_core.so
        libvcos.so -> libvcos.so
        libmmal_vc_client.so -> libmmal_vc_client.so
:

もう一度モジュールを実行してみる。

> ./test
Hello world!