• ベストアンサー

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する 以上、ご存知のかた、どうぞよろしくお願いします。

  • secma
  • お礼率57% (27/47)

質問者が選んだベストアンサー

  • ベストアンサー
  • onosuke
  • ベストアンサー率67% (310/456)
回答No.3

いやいやいや。 gcc -shared -fPIC -o libxxx.so xxx.c gcc ./libxxx.so -o testcall testcall.c というのならOKです。(-fPICを付けよう!) ライブラリを直接指定するのはNGじゃありません。 -fPIC 無しだと、ライブラリだけ差し替えたときに ちゃんと動くのか、怪しげなので。

secma
質問者

お礼

またまた回答ありがとうございます。 ということは、「呼び出し側アプリ起動時にロードされる共有ライブラリを生成」するには、 >gcc -shared -fPIC -o libxxx.so xxx.c >gcc ./libxxx.so -o testcall testcall.c >というのならOKです。(-fPICを付けよう!) で良い、ということですね? これならsoname、linkernameの設定も不要ですから、できればこの方法でライブラリを生成したいなぁと思っています。 とりあえず、会社でやってみますね。 またきっと疑問が出てくると思いますので、引き続きよろしくお願いします♪

その他の回答 (3)

  • shige_70
  • ベストアンサー率17% (168/946)
回答No.4

#1です。 すみません、先ほどは間違ったことを書いてしまいました。その1のやり方でも、soは実行時ロードとなりました。 大変失礼致しました。#1の回答は忘れて戴ければと思います。 ちなみに、私も-fPICは必要と思います。

secma
質問者

お礼

また回答ありがとうございます!ということは、 「その1の方法で-fPICをつければ、呼び出し側起動時にロードされる共有ライブラリ」 を生成することができるのですね。 ふぅ~ん、なるほど。でも何故、共有ライブラリ生成は2とおりの方法があるのでしょうね? soname、linkernameを使うのかどうか?ということだけの違いなんでしょうか? さ~て、これから-fPICをつけて再テスト開始です!またご報告します。ありがとうございました。

secma
質問者

補足

onosukeさん、sige_70さん、本当に丁寧な回答をありがとうございました。 おかげさまで、お2人に教えていただいた方法でテストが絶好調ですすんでいます。 これからもペンギンのWebサイトで疑問難問にぶちあたると思いますので、そのときまたどうぞよろしくお願いしま~す♪ ありがとうございました!

  • onosuke
  • ベストアンサー率67% (310/456)
回答No.2

-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の設定は自動) と結構お手軽です。

secma
質問者

お礼

>その1は駄目駄目ですね。 ありゃりゃ~。ダメダメなんですか・・・。私はてっきり、こっちのほうが手順がらくちんなので、コレでいこう!と思ってました。 >その2 - 2) の -fPIC も必要ないオプションです。 そうなんですかぁ。なにしろLinuxでの開発は初めてなので、ペンギンがウィンクしている日本のLinux情報というWebサイトで情報を拾い集めて奮闘している、という状態なのです。明日、このオプションなしでやってみます。 >どうせなら、GNUのlibtool使いませんか? そういうものがある、というのは、見かけたことがあります。でも、上記のとおりまるきりのLinuxシロウトが暴れている状態ですので、今からそれを導入するとなると納期に間に合いそうになく、不安が増大してしまいそうです。とりあえず明日から、その2の方法で再テストをやっていきます。またご報告します。そしてまたいろいろ教えてください♪ ありがとうございました!

secma
質問者

補足

どこかで見かけたIDだなぁと思ったら、前回もお世話になっていましたね。いつもありがとうございます!ではまた明日~。

  • shige_70
  • ベストアンサー率17% (168/946)
回答No.1

その1ではライブラリ側のコードが実行モジュールに含まれます。 その2では実行モジュールには含まれず、実行時に動的にsoがメモリにロードされます。 つまり、その1ではso形式にする意味がないということです。 その2では同じライブラリを使用する実行モジュールがたくさんあるとディスク容量を節約できるわけですが、そのライブラリをインストールしていない環境では実行できないと言う欠点があります。

secma
質問者

お礼

回答ありがとうございます! >その1ではライブラリ側のコードが実行モジュールに含まれます。 えぇっ?そうなんですか!でも、libxxx.soを変更して実行して、呼び出し側とのリンクを必要とせずにlibxxx.so変更結果が反映されていたのですが、勘違いだったのでしょうかね。明日会社で、も一度確認してみます。 >その2では同じライブラリを使用する実行モジュールがたくさんあるとディスク容量を節約できるわけですが たくさんあるってワケではないですが、いつなんどきライブラリが呼ばれても実行できるような、マルチスレッド対応はしてあるつもりです。(というふうに作れということなので) 明日また頑張って、その2でやってみます。ありがとうございました♪

関連するQ&A

  • Makefileと共有ライブラリ

    main.c sub1.c sub2.cに対して 共有ライブラリlibsub1.soとlibsub2.soを生成して それをもちいてmainをコンパイルするMakefileを以下のように記述しました。 CC=gcc LIB= CFLAGS=-Wall TARGET = main SHAD = -shared .SUFFIXES:.so .o SRCS = main.c libsub1.so libsub2.so $(TARGET):$(SRCS) $(CC) -o $@ $(SRCS) @echo "make finished!!" #.o.so: # $(CC) $(SHAD) -o $@ $< libsub1.so:sub1.o gcc -shared -o libsub1.so sub1.o libsub2.so:sub2.o gcc -shared -o libsub2.so sub2.o .c.o: $(CC) -c $< #sub1.o:sub1.c # gcc -c -fPIC sub1.c #sub2.o:sub2.c # gcc -c -fPIC sub2.c clean: @rm -f libsub?.so sub?.o ここで.oから.cを生成するのはサフィックスでできたのですが、同じように.oから.soを生成するのは できませんでした。 #.o.so: # $(CC) $(SHAD) -o $@ $< ここはどのように記述したらいいのでしょうか? 回答お願いします。

  • プログラム作成(コンパイル、リンク)でのコマンド

    プログラム素人です。 コンパイルオプション、あるいはコマンドなどいろいろとあり判らずにいます。 例えば、 $ gcc -fPIC -c xxx.c $ gcc -shared -Wl,-soname,libxxx.so.1 -o libxxx.so.1.0 xxx.o # cp libxxx.so.1.0 /usr/lib # /sbin/ldconfig /usr/lib # ln -s /usr/lib/libxxx.so.1 /usr/lib/libxxx.so とか $ ar rv libxxx.a xxx.o $ ranlib libxxx.a $ strip libxxx.a など(ほんの一部だと思いますが)これらのコマンドの意味役割など知りたいのですが、書籍などありますでしょうか。 ネット上で検索してみましたがキーワードが悪いのかよいサイトに出会えません。 皆様、よいアドレス、書籍あればご紹介下さい。

  • 共有ライブラリ作成時の -L

    sub1.c sub2.cからlibsub1.so libsub2.soを作成し、main.cをコンパイルします。 いずれのファイルも/rootにあります。 ここで gcc -c sub1.c gcc -shared -o libsub1.so sub1.o gcc -c sub2.c gcc -shared -o libsub2.so sub2.o gcc -o main main.c libsub1.so  libsub2.so だけでは [root@localhost ~]# ldd main linux-gate.so.1 => (0x0020d000) libsub1.so.1 => not found libsub2.so.1 => not found libc.so.6 => /lib/libc.so.6 (0x003e3000) /lib/ld-linux.so.2 (0x003c4000) でロードされていないので ln -s /root/libsub1.so /usr/lib/libsub1.so ln -s /root/libsub2.so /usr/lib/libsub2.so で/usr/libにシンボリックリンクを張る必要があります。 このリンクをはる作業をなんとかしてコンパイラのオプションを用いて省略したいとおもっています。 そこで gcc -o main main.c -L/root/libsub1.so -L/root/libsub2.so としたのですが /tmp/cc4Ccfom.o: In function `main': main.c:(.text+0x12): undefined reference to `print' collect2: ld はステータス 1 で終了しました make: *** [main] エラー 1 になってしまいました。 上の状況で質問は2つあります。 (1)gccのオプションを用いてシンボリックリンクを張る作業を省略するにはどうすればいいでしょうか?(私はーLの使い方を見よう見まねで用いたのですがまずかったようでエラーがでました。) (2)上のエラーは何が原因だったのでしょうか? ソースは //sub1.c #include "sub.h" int TEST=10; //sub2.c #include "sub.h" #include <stdio.h> void print(void) { if(TEST) printf("TEST is HOGE!\n"); } //main.c #include "sub.h" #include <stdio.h> int main(void) { print(); return 0; } //sub.h extern int TEST; です。 どちらかでも回答できるかたがいらっしゃれば、お願いします。

  • 共有ライブラリの作成について

    呼び出した関数名の名前を表示させる、 テスト用共有ライブラリ「testLib.so」を作成しようと思っています。 そしてそのライブラリを他のプログラムから呼び出すというものです。 以下、内容。 int test1(void){ printf("test1 program."); } int test2(void){ printf("test2 program."); } int test3(void){ printf("test3 program."); } 【パターン1】 上記関数毎でファイル分けし、 test1.c、test2.c、test3.c と言うファイルを作成。 これらの各オブジェクトを取り込んで共有ライブラリを作成するパターン。 【パターン2】 全ての関数を「testDisp.c」と言うファイルに記述し、 このオブジェクトファイルで共有ライブラリを作成するパターン。 上記パターン1と2では用途によって使い分け方法があると言う話を先日聞いたのですが、どの様な場合に1、どの様な場合に2のパターンを使用するのでしょうか。 宜しくお願い致します。

  • 共有ライブリの作成。-fPICオプションは必須?

    http://0xcc.net/blog/archives/000107.html http://linuxjf.sourceforge.jp/JFdocs/Program-Library-HOWTO/shared-libraries.html UnixやLinuxで共有ライブラリのコンパイル・ビルドに-fPICや-KPICのオプションは必須ですか? 共有ライブラリ(起動時自動的にロード)で必須で、 動的ライブラリ(実行中に関数を使ってロード。)の場合、不要という事でしょうか?

  • gccでの共有ライブラリのver指定

    表題の件に関して質問させていただきます。 たとえば/usr/libにある;libA.soをリンクしたい時、gccでは gcc -lA としますが、libA.so.1,libA.so.2‥と複数バージョンがある場合、バージョンまで指定してコンパイルすることは可能でしょうか? サーバー権限を持っていないので、シンボリックリンクを張り直すという手は使えません。 また、自分のアカウントで同共有ライブラリを用意したのですが、/usr/libが優先されてしまい、自分のアカウントのライブラリを設定することは出来ません。 解決法をご存知の方、ご教授お願い致します。

  • Linuxの動的ライブラリをMacで使いたい

    64bit Linux用に提供されたライブラリ(*.a, *.so)をMac(Snow Leopard)で使いたいと思っています。Mac環境でコンパイルをしたところ、リンク時に以下のwarningが出てしまいました。 ld: warning: in xxx.so, file is not of required architecture Webで調査し、gccのオプションに-arch i386 -arch x86_64を付けてみましたが解決できませんでした。そもそも、Linux用のライブラリをMacで使うというのは無理なのでしょうか?ご回答どうぞよろしく御願いいたします。

  • DLL作成で外部参照エラー?

    VC歴1週間です。 現在VC++2010で動的ライブラリ(DLL)を作ろうとしていますが、 作成しようとしているDLL内部で使用している関数がLIB提供されていません。 このような場合、win32プロジェクト→dll作成 を選択した状態でプロパティ変更しないで、 DLLを作ろうとするとその関数が外部参照エラーになるかと思います。 このような場合、/FORCEで強制出力してしまって良いものでしょうか? それともVC++側の設定でエラーにならずDLL生成ができるようになるものでしょうか? linuxなら cc -shared -o foo.so foo.c でライブラリ等何も気にせずシェアードライブラリが作れたので困惑しています。 よろしくご教示お願いいたします。

  • 静的ライブラリについて教えて下さい

    静的ライブラリについて教えて下さい。作成方法は大体わかったのですが、使い方と利用シーンがわかりません。例えば、 -main.c- #include <stdio.h> #include "abc.h" int main(){ a(); b(); c(); } -a.c- #include <stdio.h> void a(void){ printf("a\n"); } -b.c- #include <stdio.h> void b(void){ printf("b\n"); } -c.c- #include <stdio.h> void c(void){ printf("c\n"); } -abc.h- void a(void); void b(void); void c(void); というファイルを作成した上で以下のようにコンパイルしました。 gcc -c a.c gcc -c b.c gcc -c c.c これで、a.o, b.o, c.oというオブジェクトファイルが出来ました。 次にar rcs static a.o b.o c.oとコマンドを打ったところ、問題なくstaticという静的ライブラリと思われるファイルが出来ました。で、そもそもですがこの使い方がわかりません。main.cをコンパイルする際に使うのでしょうか?そもそも上で作成した静的ライブラリにはmain.oも含めるべきものでしょうか?初歩的な質問ですみません。宜しくお願いします。

  • C++言語でのライブラリファイルの作成と使用法

    よろしくお願いします。 C言語において、例えばMinGWのCコンパイラのLibディレクトリには、拡張子が「.a」のライブラリファイルがたくさん存在しています。これらは、arコマンドで ar crv libMine.a 1.o 2.o のように作成されるものだと認識しています。 一方、C++言語において、例えばBorlandのC++コンパイラのLibディレクトリには、拡張子が「.lib」というライブラリファイルがたくさん存在します。 これらのファイブラリファイルは、C言語のaファイルと同じ役割をする考えてよいのでしょうか? また、C++において自作のライブラリファイル(libファイル)を作成するにはどうすればよいのでしょうか? 次に、C++における自作ライブラリの使用法についてですが、Cではコンパイル時に gcc -o 1.exe 1.c libMine.a のようにして、自作のライブラリファイルを使うことができますが C++のコンパイルコマンド、例えばbcc32コマンドを使ってコンパイルする時に、 自分が作成したlibファイルを使うにはどのようにすればよいのでしょうか? 最後に、Borland C++コンパイラをインストールするときに、Binディレクトリにあるbcc.cfgファイルに -L"c:\Borland\Bcc55\lib" と記述したのですが、これは、 c:\Borland\Bcc55\libにあるlibファイルをコンパイル時に自動的に読み込むということなのでしょうか?

専門家に質問してみよう