dポイントプレゼントキャンペーン実施中!

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;

です。

どちらかでも回答できるかたがいらっしゃれば、お願いします。

A 回答 (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様が張られたリンク先を参照されるのがよいと思います。
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/11/03 14:18

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

    • good
    • 0
この回答へのお礼

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

お礼日時:2011/11/03 14:18

-Lついては


http://oshiete.goo.ne.jp/qa/2006656.html
のANo.2を参照。

上記の回答にもあるが、-Lだけでは、実行時にlibsub1.so、libsub2.soを探せずにエラーになるので、ANo.2の「4つの方法」のどれか1つを用いて解決する事。

あと、main関数でprint()を呼び出す前に
void print(void);
と、関数プロトタイプ宣言をしておく事。
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/11/03 14:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!