共有ライブラリの作成時に発生したエラーと解決方法

このQ&Aのポイント
  • 共有ライブラリを作成する際にシンボリックリンクを省略する方法とは?
  • エラーの原因はgccのオプションの使い方が誤っていたことである。
  • gccのオプションを正しく設定することで問題を解決できる。
回答を見る
  • ベストアンサー

共有ライブラリ作成時の -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; です。 どちらかでも回答できるかたがいらっしゃれば、お願いします。

noname#182748
noname#182748

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

  • ベストアンサー
  • entree
  • ベストアンサー率55% (405/735)
回答No.3

ライブラリの探索パスは、コンパイル時と実行時で違うからです。 -Lはあくまでコンパイル時の探索パスを指定するオプションです。 実行時の探索パスを設定する場合は-Wl,-rpathを使用します。 gcc -o main main.c -L/root/libsub1.so -L/root/libsub2.so -Wl,-rpath,/root -Wl,-rpathを設定せずにコンパイルされた実行ファイル(main)をとりあえず動かすには、 export LD_LIBRARY_PATH=/root としてから、lddすれば「not found」は無くなり、実行もできるはずです。 他にも、ld.so.confに/rootを追加してldconfigコマンドを実行する方法もあるのですが、 テスト目的以外ではお勧めしません。 詳細はNo.1様が張られたリンク先を参照されるのがよいと思います。

noname#182748
質問者

お礼

解答ありがとうございます。 助かりました。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

マニュアルを読んで -L の意味が分かれば疑問は氷解するはず.

noname#182748
質問者

お礼

解答ありがとうございます。 助かりました。

  • chie65535
  • ベストアンサー率43% (8520/19368)
回答No.1

-Lついては http://okwave.jp/qa/q2006656.html のANo.2を参照。 上記の回答にもあるが、-Lだけでは、実行時にlibsub1.so、libsub2.soを探せずにエラーになるので、ANo.2の「4つの方法」のどれか1つを用いて解決する事。 あと、main関数でprint()を呼び出す前に void print(void); と、関数プロトタイプ宣言をしておく事。

noname#182748
質問者

お礼

解答ありがとうございます。 助かりました。

関連する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 $@ $< ここはどのように記述したらいいのでしょうか? 回答お願いします。

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

    静的ライブラリについて教えて下さい。作成方法は大体わかったのですが、使い方と利用シーンがわかりません。例えば、 -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も含めるべきものでしょうか?初歩的な質問ですみません。宜しくお願いします。

  • 動的ライブラリ中のグローバル変数

    以下の3行を前提条件とします。 メインのプログラムmainと動的ライブラリsub1.soとsub2.soがあります。 sub1.cとsub2.cにはsub.hというヘッダをインクルードしています。 mainはsub1.soおよびsub2.soを実行時に動的にリンクします。 ここでsub1.c中で int TEST=10;と変数を定義しました。 さらにsub.h中にextern int TEST;と変数を宣言しました。 そしてsub2.h中で if(TEST){…}と記述しました。 この状態でコンパイルを実行しました。 ここでmainを実行すると動きません。 調べてみるとsub2.soがTESTがundefined symbolとなっていました。 動的ライブラリ間での変数の共有の仕方は上の書き方では不正確なのでしょうか?

  • execlp関数で「grep -lr hoe /home/root」が実行させるには?

    RedHat9で以下のようにexeclp関数使って 「grep -lr hoe /home/root」 を実行させる実験をしています。でも $ cat ./test1.c #include<stdio.h> int main(void){ execlp("hoge1","-lr","hoe","/home/root"); return 0; } $ cat ./hoge1.c #include<stdio.h> int main(int argc,char *argv[]){ system("grep,argv[0],argv[1],argv[2]"); return 0; } $ gcc -o test1 test1.c $ gcc -o hoge1 hoge1.c $ ./test1 sh: line 1: grep,argv[0],argv[1],argv[2]: command not found となってしまいます。 どのようにコーディングすればいいのでしょうか?

  • OpenSSLの共有ライブラリ(libcrypto.so)動的リンクにつきまして

    [環境] Linux version 2.6.9-67.EL gcc version 3.4.6 (Red Hat 3.4.6-8)) 以下のように、OpenSSLの共有ライブラリlibcrypto.soをロードする プログラムを書いているのですが、 ------ #include <stdio.h> #include <dlfcn.h> #include <errno.h> void main(void) { void* hSO; hSO = DLL_OPEN("/usr/local/ssl/lib/libcrypto.so", RTLD_NOW); if( hSO == NULL ) { printf("%s\n", dlerror()); } else { // 処理 } } ------ hSO = DLL_OPEN("/usr/local/ssl/lib/libcrypto.so", RTLD_NOW); で、NULLが返って来てしまいます。 [dlerror内容] /usr/local/ssl/lib/libcrypto.so: cannot open shared object file: No such file or directory しかし、このパスには、シンボリックリンクされたlibcrypto.soファイルが存在します。 試しに、同ディレクトリにあるlibcrypto.so.0.9.8mも試しましたが、同じエラーが出力されました。 パスの指定方法に、何か行う必要があるのでしょうか。

  • cygwinのgccが、エラーになってしまいます。

    テストプログラム $ cat test.c #include <stdio.h> int main (void) { printf("Hello, World!\n"); return 0; } これを、コンパイルすると $ gcc test.c gcc: error trying to exec '/usr/lib/gcc/i686-pc-cygwin/4.5.3/cc1.exe': execv: Bad address /usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../libcygwin.a(libcmain.o):(.text+0xba): undefined reference to `_WinMain@16' collect2: ld はステータス 1 で終了しました と、このようなエラーが出てきました。 ファイルを確認しても、何も作られていません。 $ ls test.c 対処方法を、ご教示願います。

  • GNU gettext が変なライブラリを参照している

    Solaris 2.7 に GNU gettext 0.14.5 をインストールしようとしています.gmake は通るのですが,出来上がった xgettext や msgfmt などのバイナリを ldd すると, .libs/libgettextsrc-0.14.5.so => .libs/libgettextsrc-0.14.5.so .libs/libgettextlib-0.14.5.so => (file not found) .libs/libintl.so.3.4.3 => (file not found) libiconv.so.2 => /usr/local/lib/libiconv.so.2 libc.so.1 => /usr/lib/libc.so.1 libexpat.so.0 => /usr/local/lib/libexpat.so.0 .libs/libgettextlib-0.14.5.so => (file not found) .libs/libintl.so.3.4.3 => (file not found) libdl.so.1 => /usr/lib/libdl.so.1 /usr/platform/SUNW,Ultra-4/lib/libc_psr.so.1 となり,どうやら一時ディレクトリである .libs 以下のライブラリを参照してしまっているようです.当然,gettext を用いて make した他のプログラムも動かなくなってしまうため,とても困っています. 試しに gettext 0.10.40 という古いものを入れてみたところ,問題は起こりませんでした. libintl.so.1 => /usr/local/lib/libintl.so.1 libiconv.so.2 => /usr/local/lib/libiconv.so.2 libc.so.1 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 /usr/platform/SUNW,Ultra-4/lib/libc_psr.so.1 回避策等あれば教えていただきたいです. なお,gcc は 2.7.2.3 です.よろしくお願いいたします.

  • 共有ライブラリが見つからない

     お世話になります。  xxxxxというソフトウェアを動作させようとしたところ、下記のようなエラーメッセージが出ました。 > ld.so.1: xxxxx: fatal: libsasl.so: version `SUNWprivate1.1' not found (required by file /usr/lib/mps/libldap60.so) > ld.so.1: xxxxx: fatal: libsasl.so: open failed: No such file or directory > rc = 9 ■質問1  これは、 ・ld.so.1という共有モジュールが ・内部的にrequired by file /usr/lib/mps/libldap60.so というモジュールを呼んでいて ・それがlibsasl.soを呼ぼうとしたときに ・`SUNWprivate1.1'というバージョンのものがない というエラーだと解釈してよろしいでしょうか。 ■質問2  findでlibsasl.soを検索したところ、下記の場所にありました。 > /usr/lib/sparcv9/libsasl.so > /usr/lib/libsasl.so crleコマンドで共有ライブラリの検索パスを見てみたところ、/usr/libは含まれていました。 > @root# crle -v > > 構成ファイル [バージョン 4]: /var/ld/ld.config > デフォルトライブラリパス (ELF): /usr/lib:/usr/local/ssl/lib/:/usr/lib/mps > トラステッドディレクトリ (ELF): /usr/lib/secure:/opt/SUNWmsgsr/lib:/usr/lib/mps > > コマンド行: > crle -c /var/ld/ld.config \ > -l /usr/lib:/usr/local/ssl/lib/:/usr/lib/mps \ > -s /usr/lib/secure:/opt/SUNWmsgsr/lib:/usr/lib/mps  それでもエラーが出るのは ・このディレクトリにあるlibsasl.soが`SUNWprivate1.1'というバージョンではないから という解釈でよろしいでしょうか。 ■質問3 `SUNWprivate1.1'というバージョンのlibsasl.soを検索する方法があるでしょうか。  いろいろですみません。よろしくお願いいたします。

  • reallocでエラー

    reallocを使うとエラーがでます。 簡単なreallocのプログラムでもエラーがでて、realloc自体が使えないような感じです。 どうしたらよいでしょうか? 試したプログラムは #include<stdlib.h> #include<stdio.h> #include<string.h> int main(void){ char *p; p=malloc(17); if(!p){ printf("error\n"); exit(1); } strcpy(p,"これは16文字です"); p=realloc(p,18); if(!p){ printf("error\n"); exit(1); } strcat(p,"."); printf(p); free(p); return 0; } というもので、 *** glibc detected *** ./test: realloc(): invalid next size: 0x09b61008 *** ======= Backtrace: ========= /lib/libc.so.6[0x43ca2f] /lib/libc.so.6(realloc+0xfe)[0x43e68e] /lib/libc.so.6[0x43ea61] /lib/libc.so.6(realloc+0x3c)[0x43e5cc] ./test[0x8048512] /lib/libc.so.6(__libc_start_main+0xe0)[0x3e8f70] ./test[0x80483e1] ======= Memory map: ======== 00235000-0023f000 r-xp 00000000 fd:00 360450 /lib/libgcc_s-4.1.2-20070626.so.1 0023f000-00240000 rwxp 00009000 fd:00 360450 /lib/libgcc_s-4.1.2-20070626.so.1 003d3000-00521000 r-xp 00000000 fd:00 360473 /lib/libc-2.6.so 00521000-00522000 r-xp 0014e000 fd:00 360473 /lib/libc-2.6.so 00522000-00524000 rwxp 0014f000 fd:00 360473 /lib/libc-2.6.so 00524000-00527000 rwxp 00524000 00:00 0 00616000-00631000 r-xp 00000000 fd:00 360466 /lib/ld-2.6.so 00631000-00632000 r-xp 0001a000 fd:00 360466 /lib/ld-2.6.so 00632000-00633000 rwxp 0001b000 fd:00 360466 /lib/ld-2.6.so 006c0000-006c1000 r-xp 006c0000 00:00 0 [vdso] 08048000-08049000 r-xp 00000000 fd:00 3473718 /home/gucchi/test/test 08049000-0804a000 rw-p 00000000 fd:00 3473718 /home/gucchi/test/test 09b61000-09b82000 rw-p 09b61000 00:00 0 b7e00000-b7e21000 rw-p b7e00000 00:00 0 b7e21000-b7f00000 ---p b7e21000 00:00 0 b7fd6000-b7fd8000 rw-p b7fd6000 00:00 0 bfb07000-bfb1c000 rw-p bfb07000 00:00 0 [stack] アボートしました というエラーがでます。 試しに他の環境でコンパイルしたら実行できちゃいました。 glibcに問題があったりするんでしょうか? ご教授ください。

  • GCCでライブラリが足りない

    はじめまして。 LindowsOS4.0を使っています。 コンパイルができずに困っています。 GCCとMAKEをインストールしました(Lindowsはどちらも入っていないのです。Debian/Woodyベースと言われています)。 gcc 2.95.4 make 3.79.1 which gcc とすると、/usr/bin/gcc と表示されます。 で、./configure すると、 ..... checking whether the C compiler works ... no と表示されコンパイルエラーになります。 configure.log を見ると、 ------------------- checking for gcc configure:916: checking whether the C compiler (gcc ) works configure:932: gcc -o conftest conftest.c 1>&5 /usr/bin/ld: cannot open crt1.o: No such file or directory collect2: ld returned 1 exit status configure: failed program was: #line 927 "configure" #include "confdefs.h" main(){return(0);} --------------------- とか --------------------- checking for gcc configure:905: checking whether the C compiler (gcc ) works configure:921: gcc -o conftest conftest.c 1>&5 /usr/bin/ld: cannot open crt1.o: No such file or directory collect2: ld returned 1 exit status configure: failed program was: #line 916 "configure" #include "confdefs.h" main(){return(0);} ---------------------- とかなっています。 confdefs.hというのは何かのライブラリなのでしょうか?これが無いとconfigureできないのでしょうか?? よろしくお願いいたします。

専門家に質問してみよう