• 締切済み

名前が lib で始まらない so のリンク

linux(CENTOS 6.4)で、命名規約が lib で始まらない so のリンクで困ってます。 ld -share -L /XXXXXX -lfoo -o bar.so (各種オブジェクト) (foo.so というso が/XXXXXX にある。) とすると、必ず cannot find -lfoo になります。 foo100.so は元々 dlopen でロードするために作られたライブラリ(C++)で 名称がlibから始まらないのですが、foo.so内部の C++ のクラスを 継承したクラスを含む bar.so を作るため、リンクが必要になりました。 foo.so を libfoo.so に名称変更すればリンクできるのですが、命名は 規約で決まっています。そのままの名称を指定する手段は ないのでしょうか? ld -share -o bar.so /XXXXXX/foo.so (各種オブジェクト) とすればリンクは通りますが、bar.so の中に /XXXXXX/foo.so というパスが 埋め込まれるため、foo.so を /XXXXXX に置かないと動かなくなってしまいます。 以上です。、どなたかご回答をよろしくお願いいたします。

みんなの回答

回答No.1

ld(1)のマニュアルを見る限り-l:foo.soでいけそうですが、gccがldにそのコマンドを渡してくれない場合は-Wl,-l:foo.soでやるしかないでしょうね。 参考までに http://linux.die.net/man/1/ld | -l namespec | --library=namespec (snip) | If namespec is of the form :filename, ld will search the library path | for a file called filename, otherwise it will search the library path for | a file called libnamespec.a. http://linux.die.net/man/1/gcc |-Wl,option | Pass option as an option to the linker.

tknakamuri
質問者

お礼

Linuxカテで解決しました。 こちらにも解決策を載せておきます。 ■予め foo.so に soname を付ける ld -shared -o foo.so -soname foo.so ・・・・・・・ ■リンクする ld -shared -o bar.so -L../foo -l:foo.so ・・・・・・・ これだけでした。こうすると、bar.so がロードするライブラリ名称は foo.so になります。../foo/foo.so にはなりません。

tknakamuri
質問者

補足

ありがとうございます。早速やってみて、確かにリンクはできるのですが、 埋め込まれた so の情報に ディレクトリ情報もくっついてしまいます。 つまり、 -l を用いずに、引数として so のパスを指定したのと同じ結果になりました。 ld -shared -o bar.so -L../foo -l:foo.so ・・・・・・・ [readelf で bar.so の Dynamic section のダンプ] Dynamic section at offset 0x678 contains 14 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [../foo/foo.so] これですと、実行ファイルと foo.so の位置関係が固定されてしまうようです。 ../foo/ の部分を埋め込まないようにする方法はないでしょうか?

関連するQ&A

  • libで始まらない so のリンク

    実は C/C++ カテでも質問したのですが、linuxカテの方が適切と思われるので ここであらためて質問します。Linuxは Cent OS 6.4(32bit)です。 もともとプラグイン用の so で dlopen で利用されていた so (仮に foo.so とします) が有ります。プラグインのファイル名は命名規約によって決まっており、lib~.soにはできません。 #意図的にそうしたらしいです。 この中で使われている C++ のクラスを使って(継承して)、新しいプラグインを作ることになり ld -shared -o bar.so -L ../foo -lfoo ・・・・・・ でリンクしようとすると cannot find -lfoo となってしまいます。もちろん foo.so の名称を libfoo,so に直せば問題なくリンクできるのですが、プラグインの命名規則のため できません。 ld -shared -o bar.so ../foo/foo.so ・・・・・・ とすると、リンクは可能ですが、bar.so に foo.so が[../foo/foo.so]という名称で 登録されてしまうため、実行ファイルと foo.so との位置関係が制約されてしまいます。 また、 ld -shared -o bar.so -L../foo -l:foo.so ・・・・・・ とすると、やはり、bar.so に foo.so が[../foo/foo.so]という名称で 登録されてしまうのです。 linfoo.so を -lfoo で登録すると [libfoo.so]という名称で登録され、LD_LIBRARY_PATH等に きちんと従わせることができます。これと同様に foo.so をリンクする方法を探しています。 ひょっとするとこうしたことは Linux では非常識なのでしょうか? ご存知の方がおられましたら、よろしくお願いいたします。

  • リンカへのファイルの指定順序

    リンカにオブジェクトファイル/アーカイブを指定する時に依存"される"ファイルを依存"する"ファイルより後にしなければいけないのはなぜですか? 具体的にfoo.a内のシンボルをbar.oで参照している時 ld foo.a bar.o -o abc とするとUndefined reference *** とエラーが出ます。 また、オブジェクトファイル同士の場合はコマンドラインでのファイル順序が関係ないのはなぜですか? 例えば先ほどのfoo.aには、foo.oが含まれており、 ld foo.o bar.o -o abc ではエラーは発生しません。 よろしくお願いします。

  • opensshのインストールができない

    solaris9上でOPENSSH-4.2p1をインストールしていますが、うまくいきません。下記のようなエラーが出ます。 未定義の 最初に参照している シンボル ファイル dlsym /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o) (シンボルは暗黙 の依存性 /usr/lib/libdl.so.1 に属しています) dlopen /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o) (シンボルは暗黙 の依存性 /usr/lib/libdl.so.1 に属しています) dlclose /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o) (シンボルは暗黙 の依存性 /usr/lib/libdl.so.1 に属しています) dlerror /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o) (シンボルは暗黙 の依存性 /usr/lib/libdl.so.1 に属しています) ld: 重大なエラー: シンボル参照エラー。ssh に書き込まれる出力はありません。 collect2: ld returned 1 exit status make: *** [ssh] Error 1 opensslは0.9.8、zlibは1.2.3をソースから入れました。 アドバイスお願いします。

  • Qtライブラリを静的にリンクしたい

    Qt 5.11.0 を使ってGUIアプリをつくろうとしているのですが、実行時の問題があります。 ソースは初心者用のサンプルソースコードで、Qt Creator を使って以下の「main.cpp」を作成しました。 #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } ウインドウ生成は「mainwindow.cpp」で、 #include "mainwindow.h" #include <Qtgui> #include <QtWidgets> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QLabel *label = new QLabel(tr("Hello World.")); setCentralWidget(label); } MainWindow::~MainWindow() { } となっています。 これをビルドして、Qt Creatorから実行するとウィンドウが表示されます。 しかし、単独で(ダブルクリックで)実行しようとすると 「コンピューターにQt5Cored.dllがないため、プログラムを開始できません。・・・」 というシステムエラーが表示され、実行できません。 これ以外に、mingwとmake を使って別のサンプルソースをコンパイルしても同様のエラーが出てきます。 実行ファイルと同じディレクトリにQt5Widgets.dll、Qt5Core.dll、Qt5Gui.dllの3つのDLLをコピーすると、実行できます。 しかし、いちいちDLLを要請するプログラム構成は好きでないのと、同名のライブラリlibQt5Widgets.a、libQt5Core.a、libQt5Gui.aがあることから、できれば静的にリンクしたいと思っています。 静的にリンクするために以下の4つの方法を試してみましたが、ことごとく失敗しています。 方法1 ライブラリを指定してリンク g++ -static -O0 -g -o Qt_test.exe Qt_test.obj -lmingw32 -LC:\Qt\5.11.0\mingw53_32\lib -lQt5Widgets -lQt5Core -lQt5Gui -lqtmain -LC:\utils\my_sql\my_sql\lib -LC:\utils\postgresql\pgsql\lib -lshell32 のような書式で、3つのライブラリの順番を入れかえて6パターン試しましたが、DLLエラーは変わりません。 方法2 ライブラリをld.exeでまとめたオブジェクトファイルを作ってリンク 「GNUソフトウェアプログラミング」という本の112ページにリンカ「ld」のオプションについての記述があり、オブジェクトファイルとライブラリ同士をリンクする方法が紹介されていたので試してみましたが、未解決の参照がない?のか、20バイトのファイルが出力されただけでした。 ld -static -r -o qtobj.o C:\Qt\5.11.0\mingw53_32\lib\libQt5Gui.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Widgets.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Core.a ld -static -r -o qtobj.o -LC:\Qt\5.11.0\mingw53_32\lib -lQt5Gui -lQt5Widgets -lQt5Core 方法3 arでオブジェクトファイルを作る ar rs qto2.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Gui.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Widgets.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Core.a でライブラリをまとめたファイルは作れるのですが、コンパイルするとリンク時に qto2.a: error adding symbols: Archive has no index; run ranlib to add one となり、うまくいきません。 方法4 Qt creator で静的リンク Qt Creatorで「ライブラリの追加」を行うと、「HelloWrold.pro」に以下の行が加わり、リンクできそうなのですが、実行時にやはりDLLを要求されます。 LIBS += -LC:/Qt/5.11.0/mingw53_32/lib/ -lQt5Core 結局は、Qtで静的なリンクを行う方法が知りたいのです。 ご助言をお願いいたします。 環境は、Win7、Mingw、QtはMingwパッケージオプションを付けてインストールしており、 「C:\Qt\5.11.0\mingw53_32\lib\libQt5Core.a」 「C:\Qt\5.11.0\mingw53_32\include」 「C:\Qt\5.11.0\mingw53_32\bin\Qt5Core.dll」 があり、中にDLLもライブラリもあります。 よろしくお願いします。

  • LinuxのgccのLIBパス? (類似質問)

    Linuxのgccで、LIBのパスを設定する方法が知りたいのですが、gccについて詳しい書籍やサイトがありましたら、教えてください。 例)gcc -I/usr/local/example/include test.c /tmp/ccOFpCBo.o(.text+0x26): In function `main': : undefined reference to `EXAMPLE_1' /tmp/ccOFpCBo.o(.text+0x37): In function `main': : undefined reference to `EXAMPLE_2' /tmp/ccOFpCBo.o(.text+0x48): In function `main': : undefined reference to `EXAMPLE_3' collect2: ld はステータス1で終了しました。 また、ldとはVC6++でいう LINKのことでしょうか?

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

  • エラーで出てくる「シンボリックリンクの数がMAXSYMLINKSを超えました」とは?

    cactiでのサーバーの管理の際に、pkgrmのコマンドで必要なPKGも消してしまったようで、いろいろなコマンドが使えなくなってしまいました。いくつかは復活させて現在稼働中ですが、そのなかで疑問点が。 現在、ifconfigもしくはphp /usr/local/apache2/cacti/poller.phpのコマンドを実行すると次のエラーが出ます。 ld.so.1: ifconfig: 重大なエラー: /usr/local/lib/libdlpi.so.1: パス名チェック中に見つかったシンボリックリンクの数が MAXSYMLINKS を超えました。 強制終了 上記のエラーが出てしまいます。以前は、 ld.so.1: rrdtool: 重大なエラー: libgcc_s.so.1: open に失敗しました: ファイルもディレクトリもありません。 強制終了 のようなエラーが出ていたので、サイトを参考にやってみたところ一つ目のエラーが出てしまいました。MAXSYMLINKSとは何でしょうか?調べてもなかなか出てこなくて困っています。また、これはサーバー内で設定できるものなのでしょうか? 教えてください。

  • Fedora7で libpthread.aをリンクすると、コンパイルエラーになってしまいました

    はじめまして、 Fedora7でマルチスレッドのプログラムをビルドし、 libpthread.aをリンクしたところ、コンパイルエラーになってしまいました。 Fedora4~5では、起きなかったため、 libpthread.aのバージョン変更により、問題がおきたのではないかと思っております。 libpthreadのバージョンは2.6-4で [root@localhost]# rpm -qf /usr/lib/libpthread.a glibc-devel-2.6-4 glibc-develをダウングレードしようと思いましたが、 glibc-commonの依存関係が厳しく、forceしてもうまくいきませんでした。 makeのエラーは下記の内容で、main.cppにlibpthread.aをリンクしてビルドすると、 libpthread.a内で使ってる関数がundefinedでこけてしまいます。 ネットを検索して、pthreadのについて書かれているサイトを読みましたが、あまり見つからずどうして良いやらわからない状態です。 ttp://uyota.asablo.jp/blog/2007/01/27/1142762 Fedora7でlibpthread.aをリンクし、 undefinedを回避して、うまくビルドする方法をご存知でしたら、お教えください。 ---------------- エラー内容 [root@localhost test]# make make clean make[1]: ディレクトリ `/src/test' に入ります rm Main.o removed `Main.o' make[1]: ディレクトリ `/src/test' から出ます make test make[1]: ディレクトリ `/src/test' に入ります g++ -c -o Main.o Main.cpp g++ -o test Main.o /usr/lib/libpthread.a -lpthread /usr/lib/libpthread.a(pthread_create.o): In function `pthread_create': (.text+0xca3): undefined reference to `_dl_stack_flags' /usr/lib/libpthread.a(pthread_create.o): In function `pthread_create': (.text+0x1126): undefined reference to `_dl_stack_flags' /usr/lib/libpthread.a(ptw-accept.o): In function `accept': (.text+0x23): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-accept.o): In function `accept': (.text+0x52): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-send.o): In function `__send': (.text+0x23): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-send.o): In function `__send': (.text+0x52): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-pause.o): In function `__pause_nocancel': (.text+0x18): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-pause.o):(.text+0x3b): more undefined references to `__syscall_error' follow /usr/lib/libpthread.a(init.o): In function `__pthread_initialize_minimal': (.text+0x16c): undefined reference to `__libc_setup_tls' /usr/lib/libpthread.a(init.o): In function `__pthread_initialize_minimal': (.text+0x328): undefined reference to `_dl_init_static_tls' /usr/lib/libpthread.a(init.o): In function `__pthread_initialize_minimal': (.text+0x34d): undefined reference to `_dl_wait_lookup_done' /usr/lib/libpthread.a(ptw-read.o): In function `__read_nocancel': (.text+0x26): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-read.o): In function `__read_nocancel': (.text+0x56): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-open.o): In function `__open_nocancel': (.text+0x26): undefined reference to `__syscall_error' /usr/lib/libpthread.a(ptw-open.o): In function `__open_nocancel': (.text+0x56): undefined reference to `__syscall_error' /usr/lib/libpthread.a(sigaction.o): In function `__libc_sigaction': (.text+0x60): undefined reference to `_dl_sysinfo_dso' /usr/lib/libpthread.a(sigaction.o): In function `sigaction': (.text+0x19a): undefined reference to `_dl_sysinfo_dso' collect2: ld はステータス 1 で終了しました make[1]: *** [test] エラー 1 make[1]: ディレクトリ `/src/test' から出ます make: *** [build] エラー 2 -- [root@localhost]# cat /etc/ld.so.conf /usr/lib include ld.so.conf.d/*.conf

  • Unix上C++でのdllとインポートライブラリの関係

    こんにちわ。 いつも教えてgooにお世話になっているorange_pieです。 UNIX上のC++で作成した自作ライブラリをdllにして配布したいのですが、 Unixでの基本的な考え方を教えてください。 (1)Unix上ではDLLの標準的な名称は”libxxxx.so”とするのが普通ですか?  ※この形式ならLD_LIBRARY_PATH環境変数が検索してくれる。。。 (2)通常、DLLにする場合、インポートライブラリ(.lib)と実際のライブラリ(.so)を作成して、使用する側はインポートライブラリのみをリンクするのでしょうか? (3)配布されたdllを使う側では、Link時にインポートライブラリをリンクして、関連インクルードファイルをインクルードするだけで使えるのでしょうか? (4)上記の(2)のように、インポートライブラリとライブラリの実態を作成する為のコンパイルオプションが見つかりません。(ldのmanを見たのですが、意味がわからないと言うか。。。。。) この質問は、自作ライブラリからlibxxx.soという形のオブジェクトファイルを作り、別プログラムからこのlibxxxをコンパイルオプション(-l)でリンクしてみたら正しく動作したのですが、これでは結局ライブラリの本体が一緒にリンクされている様子で、出来上がった実行形式のファイルサイズが静的ライブラリとしてリンクした時と同じ大きさになっていることに疑問を抱いてしまったものです。  この状態でも、ライブラリの方だけコンパイルしなおして実行すると ちゃんとライブラリの変更点は反映されるので問題は無いのですが、 これでもダイナミックリンク・ライブラリと呼べるのでしょうか?

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

専門家に質問してみよう