- 締切済み
静的ライブラリから静的ライブラリを生成する方法
初めて質問させていただきます。 複数の静的リンクライブラリをまとめて、 一つの静的リンクライブラリを作成できずに困っています。 以下の様な構造のディレクトリがあります。 MAINDIR ├SUBDIR_A ├SUBDIR_B └SUBDIR_C まず、それぞれのサブディレクトリ(SUBDIR_A, SUBDIR_B, SUBDIR_C) で、個別に静的ライブラリ(SUB_A.a, SUB_B.a, SUB_C.a)を 作成しました。コマンドはgccでコンパイル後に"ar rv" です。 最後にMAINDIRで、各サブディレクトリで作った静的ライブラリ (SUB_A.a, SUB_B.a, SUB_C.a)から一つの静的ライブラリ(MAINLIB.a) を以下のコマンドで作りました。 ar rv MAINLIB.a SUB_A.a, SUB_B.a, SUB_C.a しかし、作成したMAINLIB.aから実行ファイルを作ろうとすると、 "ould not read symbols: Archive has no index; run ranlib to add" というエラーメッセージが出て失敗しました。 複数の静的ライブラリをまとめた一つの共有ライブラリを作れたので、 複数静的ライブラリ→1つの静的ライブラリも作れると思ったのですが。。。 御存知の方がいらっしゃいましたら、お助けください。お願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- entree
- ベストアンサー率55% (405/735)
これでどうでしょうか? % cd MAINDIR % ( cd SUBDIR_A; ar cr libSUB_A.a *.o; ranlib libSUB_A.a ) % ( cd SUBDIR_B; ar cr libSUB_B.a *.o; ranlib libSUB_B.a ) % ( cd SUBDIR_B; ar cr libSUB_C.a *.o; ranlib libSUB_C.a ) で、これらを1つにまとめるためには、libSUB_A.a、libSUB_B.a、libSUB_C.a をいったん展開しないとだめです。 % mkdir work % cd work % ar x ../SUBDIR_A/libSUB_A.a % ar x ../SUBDIR_B/libSUB_B.a % ar x ../SUBDIR_C/libSUB_C.a % ar c ../libMAIN.a *.o; ranlib ../libMAIN.a % cd .. % rm -rf work ただ、複数の静的ライブラリをまとめるようなことはあまりしないと思いますが・・・。 > しかし、作成したMAINLIB.aから実行ファイルを作ろうとすると、 > "ould not read symbols: Archive has no index; run ranlib to add" > というエラーメッセージが出て失敗しました。 メッセージのとおり ranlib を実行すれば解決するでしょう。 > これは、私のケアレスミスでした。実行ファイル作成時のライブラリのリンク順の問題でした。 > #なぜ、ar実施版だけリックエラーが??という疑問がありますが。。。 共有ライブラリの場合はリンク時に指定する順番を問いませんが、静的ライブラリの場合は順番が重要になります。例えば、libintl は libiconv に依存しますが、どちらも静的ライブラリしかない場合、 ○ gcc test.c -lintl -liconv × gcc test.c -liconv -lintl となります。(共有ライブラリの場合はどちらでもOK) > #ld -r -o MAINLIB.o --whole-archive libSUB_A.a libSUB_B.a... --no-whole-archive > #ar rv libMAINLIB.a MAINLIB.o > で libMAINLIB.aを作成してみましたが、これだと > 実行ファイル生成時に、libMAINLIB.a内の関数について"undefined reference"のリンクエラーがでました。 file コマンドや nm コマンドも活用してみてください。 ld -r で作成されたファイルがオブジェクト・ファイルなのか、静的ライブラリなのかは file コマンドで確認できるでしょう。 シンボルが解決できているかは nm コマンドで確認できるでしょう。
- Tacosan
- ベストアンサー率23% (3656/15482)
え~と.... すみません, 期待にそえるとは全く思っていないのですが, とりあえずお約束の質問を 1つ: 環境 (OS, ar, ld などのバージョン) は? いや, ld でスタティックライブラリを作れる環境がちょっと想像できないので....
お礼
回答ありがとうございます。 返事がおそくなり申し訳ありません。 すいません。職場の環境ですので、 月曜日にまた追記させていただきます。 ちなみにOSはLinuxです。 ディストリビューションはFedora Core 6です。
補足
バージョンを確認しましたので、追記させていただきます。 ar: 2.13.90.0.18 20030206 ld: 2.13.90.0.18 20030206 OS: Linux(Fedora Core 6) でした。
- noocyte
- ベストアンサー率58% (171/291)
> arの中では結局ld が走るという事は知りませんでした。 いえ,ar の中で ld が走るんじゃなくて,リンク時に ld が 使用する静的ライブラリが ar 形式なので,ar の中身は ld が 読める *.o ファイルでなければならないということです. > MAINLIB.a SUB_A.a, SUB_B.a, SUB_C.a それから,静的ライブラリ XXX の名前は libXXX.a にするのが 慣例です.この形式の名前にしておくと,例えばコンパイル・ オプション -lXXX でライブラリ指定が可能です. (ライブラリ・ディレクトリの指定が別途必要.) 例:gcc src.c -lXXX …
お礼
ご指摘感謝します。 理解が間違っておりました。 ちょっと実験してみたのですが、以下の様にすると 複数の静的ライブラリから1つのライブラリを作れるようです。 #ld -r -o MAINLIB.a --whole-archive SUB_A.a SUB_B.a... --no-whole-archive #ライブラリ名の付け方のご指摘を反映させると #ld -r -o libMAINLIB.a --whole-archive libSUB_A.a libSUB_B.a... --no-whole-archive ですね。 "-r"引数は「ldの入力として指定できる形式で出力する。」 "--whole-archive"引数は「以降に指定する書庫内の*.oをリンクする」 "--no-whole-archive"引数は「以降"--whole-archive"を無効にする」 です。 上記の様に生成したlibMAINLIB.aで実行ファイルが動く事は確認できました。 ただ、1つ気になる点が、 上記で作成したlibMAINLIB.aは静的ライブラリっぽい名前をつけた オブジェクトの塊だけど、書庫ファイルとは別物では?と思い。 #ld -r -o MAINLIB.o --whole-archive libSUB_A.a libSUB_B.a... --no-whole-archive #ar rv libMAINLIB.a MAINLIB.o で libMAINLIB.aを作成してみましたが、これだと 実行ファイル生成時に、libMAINLIB.a内の関数について"undefined reference"のリンクエラーがでました。 ご意見をいただければ、助かります。
補足
下の「ANo.2 回答のお礼」で間違いがありましたので訂正します。 > 実行ファイル生成時に、libMAINLIB.a内の関数について"undefined reference"のリンクエラーがでました。 これは、私のケアレスミスでした。実行ファイル作成時のライブラリのリンク順の問題でした。 #なぜ、ar実施版だけリックエラーが??という疑問がありますが。。。 双方とも、実行ファイルは作成できて動作するようです。 ファイルサイズは違うので前者と後者版のlibMAINLIB.aは、別物なのでしょうが。。。
- noocyte
- ベストアンサー率58% (171/291)
ar は汎用のアーカイバじゃないのでどんなファイルでも入れられる わけではありません.いや,入れるだけならできますが,結局 その中身は ld が使うわけだから,その入力となりうるファイル (事実上 *.o) じゃないと意味がありません. /usr/lib あたりにたくさん *.a ファイルがあるので,ar tv libXXX.a で 覗いてみればわかると思いますが,*.o ファイルしか入っていないはずです. > 各サブディレクトリで作った静的ライブラリ > (SUB_A.a, SUB_B.a, SUB_C.a)から一つの静的ライブラリ(MAINLIB.a) > を以下のコマンドで作りました。 > ar rv MAINLIB.a SUB_A.a, SUB_B.a, SUB_C.a SUB_[ABC].a からすべての *.o を取り出して MAINLIB.a に入れなきゃ. ar xv SUB_A.a ar xv SUB_B.a ar xv SUB_C.a ar rv MAINLIB.a *.o ranlib MAINLIB.a # 不要かもしれない. ar のマニュアル http://www.linux.or.jp/JM/html/GNU_binutils/man1/ar.1.html ranlib のマニュアル http://www.linux.or.jp/JM/html/GNU_binutils/man1/ranlib.1.html ld のマニュアル http://www.linux.or.jp/JM/html/GNU_binutils/man1/ld.1.html
お礼
ご教授ありがとうございます。 arの中では結局ld が走るという事は知りませんでした。 この情報を知ることができてよかったです。 確かに*.o以外じゃldの入力になりませんね。納得です。 この観点でもう少し、ar, ldを勉強してみたいと思います。 助かりました。ありがとうございました。
お礼
ご丁寧な回答に感謝します。 お返事遅くなり申し訳ありません。 > これらを1つにまとめるためには、libSUB_A.a、libSUB_B.a、 > libSUB_C.a をいったん展開しないとだめです。 やはり、いったい展開しないとだめなんですね。。。。 > メッセージのとおり ranlib を実行すれば解決するでしょう。 実は、ranlibを行ってもerrorがでてしまうのです。 MAINLIB.aの中身が*.oではなく*.aなので読めないみたいです。 nmコマンドでも、シンボルを読めません。。。 > file コマンドや nm コマンドも活用してみてください。 > ld -r で作成されたファイルがオブジェクト・ファイルなのか、静的> ライブラリなのかは file コマンドで確認できるでしょう。 > シンボルが解決できているかは nm コマンドで確認できるでしょう。 fileコマンドですか!なるほど、ちょっとしらべてみます。ありがとうございます。