ことの起こり
ubuntuでlibusbを使うプログラムを作成中
$ gcc -c testUsb.c
$ gcc testUsb.o testUsb -lusb
普通はこんな感じでビルドできると思うんですが、
これを実行ファイルではなく共有ライブラリ(.so)にしようと思ったらビルドエラーが出るのですね。
$ gcc -c testUsb.c
$ gcc -shared -fPIC testUsb.o -o libTestUsb.so -lusb
/usr/bin/ld: testUsb.o: relocation R_X86_64_PC32 against symbol `devInfo' can not be used when making a shared object。 -fPIC を付けて再コンパイルしてください。
/usr/bin/ld: 最終リンクに失敗しました: bad value
collect2: error: ld returned 1 exit status
なんですかこれ。初めて見ました。
調べてみる
エラーの内容としては「libusb が -fPIC つけてビルドされてないんで、この文脈では使えませんよ。使いたいなら libusb を -fPIC つけてビルドしなおしてください」って意味かな。
いやいや、こんなことで libusb ビルドしなおしとかそりゃないでしょう。
え? これで解決?
色々試してみたのだけど、ことごとく失敗だったので(libusb の再ビルドはしない方向で、、)あまりここで細かく書く必要はないと思うのだけど、最終的に解決したのは以下のようにビルド。
$ gcc -shared -fPIC testUsb.c -o libTestUsb.so -lusb
.o ファイルを作らないで、.c ファイルから直接コンパイル&リンク。
これでエラーが起きずにちゃんと動作する .so ファイルができたのだけど、.o ファイルを生成する場合と何が違うんだっけ。。
普段なんとなくやっちゃってることを正しく理解できてないなぁ、、
今度はこれでなぜうまくいくのかを調べないと。
追記
あ、これ、、
$ gcc -c testUsb.c
$ gcc -shared -fPIC testUsb.o -o libTestUsb.so -lusb
こうじゃなくて、、
$ gcc -fPIC -c testUsb.c
$ gcc -shared testUsb.o -o libTestUsb.so -lusb
こうか。コンパイルするときに -fPIC
つけないといけないのね。
答えが分かってみると当たり前すぎた。。