- ベストアンサー
Linux C言語共有ライブラリを作成するときの
RedHatLinux7.3(2.96-110)、gcc(2.96 20000731)です。 C言語で共有ライブラリを作成しています。このライブラリは呼び出し側のプログラム起動時にロードされるものなのですが、以下の2つの手順で生成されたライブラリは、どのような違いがあるのでしょうか? どちらも呼び出し側からは関数コールで実行できるのですが、どちらが正しいのでしょうか? 【その1】 1) gcc -shared -o libxxx.so xxx.c (ライブラリ生成) 2) gcc ./libxxx.so -o testcall testcall.c (呼び出し側とライブラリをリンクして実行ファイル生成) 【その2】 1) gcc -fPIC -c libxxx.c(ライブラリのオブジェクト生成) 2) gcc -fPIC -c -shared -Wl,-soname,libxxx.so.0 -o libxxx.so.0.0 xxx.o(共有ライブラリ生成) 3) soname設定 4) linkername設定 5) gcc -c -o testcall.o testcall.c(呼び出し側オブジェクト生成) 6) gcc -o testcall testcall.o -lxxx 7) LD_LIBRARY_PATH設定、exportする 以上、ご存知のかた、どうぞよろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
いやいやいや。 gcc -shared -fPIC -o libxxx.so xxx.c gcc ./libxxx.so -o testcall testcall.c というのならOKです。(-fPICを付けよう!) ライブラリを直接指定するのはNGじゃありません。 -fPIC 無しだと、ライブラリだけ差し替えたときに ちゃんと動くのか、怪しげなので。
その他の回答 (3)
- shige_70
- ベストアンサー率17% (168/946)
#1です。 すみません、先ほどは間違ったことを書いてしまいました。その1のやり方でも、soは実行時ロードとなりました。 大変失礼致しました。#1の回答は忘れて戴ければと思います。 ちなみに、私も-fPICは必要と思います。
お礼
また回答ありがとうございます!ということは、 「その1の方法で-fPICをつければ、呼び出し側起動時にロードされる共有ライブラリ」 を生成することができるのですね。 ふぅ~ん、なるほど。でも何故、共有ライブラリ生成は2とおりの方法があるのでしょうね? soname、linkernameを使うのかどうか?ということだけの違いなんでしょうか? さ~て、これから-fPICをつけて再テスト開始です!またご報告します。ありがとうございました。
補足
onosukeさん、sige_70さん、本当に丁寧な回答をありがとうございました。 おかげさまで、お2人に教えていただいた方法でテストが絶好調ですすんでいます。 これからもペンギンのWebサイトで疑問難問にぶちあたると思いますので、そのときまたどうぞよろしくお願いしま~す♪ ありがとうございました!
- onosuke
- ベストアンサー率67% (310/456)
-shared というのは リンク時に 「これから共有ライブラリを作るぞ!」とするオプション。 -fPIC というのは、コンパイル時に 「共有ライブラリで使えるようにコンパイルしろ!」「共有ライブラリ用に使えるオブジェクトファイルを作れ!」とするオプションです。 その1は駄目駄目ですね。 その2 - 2) の -fPIC も必要ないオプションです。 どうせなら、GNUのlibtool使いませんか? 上記と同じことするにも libtool --mode=compile gcc -prefer-pic -c libxxx.c libtool --mode=link gcc -version-info 0 -rpath /usr/lib -o libxxx.so libxxx.lo (soname, linkernameの設定は自動) libtool --mode=link gcc -o testcall testcall.c libxxx.la ./testcall (LD_LIBRARY_PATHの設定は自動) と結構お手軽です。
お礼
>その1は駄目駄目ですね。 ありゃりゃ~。ダメダメなんですか・・・。私はてっきり、こっちのほうが手順がらくちんなので、コレでいこう!と思ってました。 >その2 - 2) の -fPIC も必要ないオプションです。 そうなんですかぁ。なにしろLinuxでの開発は初めてなので、ペンギンがウィンクしている日本のLinux情報というWebサイトで情報を拾い集めて奮闘している、という状態なのです。明日、このオプションなしでやってみます。 >どうせなら、GNUのlibtool使いませんか? そういうものがある、というのは、見かけたことがあります。でも、上記のとおりまるきりのLinuxシロウトが暴れている状態ですので、今からそれを導入するとなると納期に間に合いそうになく、不安が増大してしまいそうです。とりあえず明日から、その2の方法で再テストをやっていきます。またご報告します。そしてまたいろいろ教えてください♪ ありがとうございました!
補足
どこかで見かけたIDだなぁと思ったら、前回もお世話になっていましたね。いつもありがとうございます!ではまた明日~。
- shige_70
- ベストアンサー率17% (168/946)
その1ではライブラリ側のコードが実行モジュールに含まれます。 その2では実行モジュールには含まれず、実行時に動的にsoがメモリにロードされます。 つまり、その1ではso形式にする意味がないということです。 その2では同じライブラリを使用する実行モジュールがたくさんあるとディスク容量を節約できるわけですが、そのライブラリをインストールしていない環境では実行できないと言う欠点があります。
お礼
回答ありがとうございます! >その1ではライブラリ側のコードが実行モジュールに含まれます。 えぇっ?そうなんですか!でも、libxxx.soを変更して実行して、呼び出し側とのリンクを必要とせずにlibxxx.so変更結果が反映されていたのですが、勘違いだったのでしょうかね。明日会社で、も一度確認してみます。 >その2では同じライブラリを使用する実行モジュールがたくさんあるとディスク容量を節約できるわけですが たくさんあるってワケではないですが、いつなんどきライブラリが呼ばれても実行できるような、マルチスレッド対応はしてあるつもりです。(というふうに作れということなので) 明日また頑張って、その2でやってみます。ありがとうございました♪
お礼
またまた回答ありがとうございます。 ということは、「呼び出し側アプリ起動時にロードされる共有ライブラリを生成」するには、 >gcc -shared -fPIC -o libxxx.so xxx.c >gcc ./libxxx.so -o testcall testcall.c >というのならOKです。(-fPICを付けよう!) で良い、ということですね? これならsoname、linkernameの設定も不要ですから、できればこの方法でライブラリを生成したいなぁと思っています。 とりあえず、会社でやってみますね。 またきっと疑問が出てくると思いますので、引き続きよろしくお願いします♪