質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

Q&A

解決済

1回答

4304閲覧

MinGW : boostをリンクした静的ライブラリをリンクすると一部のboost関数がundefined

Chironian

総合スコア23272

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

1グッド

0クリップ

投稿2016/03/09 13:53

編集2016/03/09 14:10

boostをリンクした静的リンクライブラリ(仮にlib.aとします)を作り、そのライブラリをexe(仮にfoo.exeとします)にリンクするのですが、一部のboost関数がundefinedになってしまい困ってます。
この現象に関して、何か情報をお持ちの方がいらっしゃいましたら、ご教授頂けないでしょうか?

MinGWでboostをビルドし、その同じMinGWでlib.aをビルドしています。このlib.aにはboostの下記静的リンクライブラリをリンクしています。

C:/Boost/lib/libboost_locale-mgw52-mt-1_59.a
C:/Boost/lib/libboost_filesystem-mgw52-mt-1_59.a
C:/Boost/lib/libboost_system-mgw52-mt-1_59.a

このlib.aをfoo.exeへリンクするとboostの一部の関数がundefinedとなります。
lib.aをnmコマンドで見てみると、確かにそれらの関数が未定義(U)になっています。
ですが、元のlibboost*.aをnmコマンドで見ると、それらの関数はちゃんと定義済(T)になっているのです。
非常に不可解です。また、この現象はmsvc 2015では発生していません。

未定義エラーは全部で36個ですが、全て書くのもなんですので、一部を書きます。

- nmコマンドの表示 - libboost*.a lib.a boost::system::generic_category 00001a70 T U boost::system::system_category 00001ac0 T U boost::filesystem::detail::status 000027f0 T U boost::filesystem::path::filename 000016e0 T U boost::locale::generator::generate 00000dd0 T U

全てを確認できたわけではないのですが、libboost*.a内で既にリンクされてアドレスが0でないシンボルに限って未定義になっている印象です。
このような現象について、解決のヒントになるような情報に心当たりがありましたら、是非教えて下さい。

boostライブラリのリンク・トラブルで調べると、「boostはほとんどヘッダだけで良いが、filesystem等いくつかはリンクが必要だ、ライブラリをリンクしなさい」って回答が多くて、それに隠れて欲しい情報がなかなか見つからないのです。

環境
OS : Windows 7 pro 64bit
コンパイラ : MinGW 5.2.0 32bits版
boost : 1.59.0

maisumakun👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

こんにちは。

結局、この問題、悲しいかな「boostをリンクした静的リンクライブラリを作っていた」つもりが、これができていませんでした。foo.exeへリンクできている関数はinline関数(ヘッダ定義)で、リンクできていないものがboostライブラリ内の関数でした。orz

CMakeでビルドシステムを作っているのですが、CMakeのtarget_link_librariesの働きを私が理解できていないことが原因でした。
このコマンドはターゲットがexeの時はexeへリンクするライブラリを指定するものです。
なので、ターゲットに静的リンクライブラリを指定すれば、そのライブラリへリンクしてくれるものと思っていたのですが、そうではなく、「ターゲットのライブラリがリンクされるexe」へリンクするライブラリを指定するものでした。
CMakeでビルドしていると、CMakeが良きに計らってリンクしてくれるので気が付きませんでした。

MSVCの場合は、ビルド・システムの概念が異なるせいか、上記の複雑な仕組みが働かずCMakeが良きに計らってくれないため、ビルド後イベントでlib.exeを起動してリンクするようにCMakeに指示してました。なので意図通りにリンクできていたので問題がでなかったと言うことになります。


target_link_librariesの使い方の問題であることが分かったので、それで検索してここが見つかりました。
ar xで一度aファイルをバラして再度arすることでほとんどリンクできるようになったのですが、boost::locale::impl_std空間の関数が何故かar xで抽出したnumeric.oファイルに含まれず、解説には至っていません。

結局、静的リンクライブラリに静的リンクライブラリをリンクするという行為自体、あまり行われない方法のようですので、他の方法(たぶん、IMPORTED)を探ることにします。

どうもお騒がせ致しました。


【追記】

boost::locale::impl_std空間の関数が何故かar xで抽出したnumeric.oファイルに含まれない

その後、この原因が分かりました。
boost::localeは、collate.o converter.o numeric.oの3つのファイルが、同じ名前でimpl_stdとimpl_winに2つずつありました。そのため、ar xで抽出すると前のものが上書きされて消えるということでした。
ar x numeric.oと指定すると前にある方を抽出できたので、2回コマンドを叩くことで全て抽出でき、undefinedを無くせました。これで解決。

なお、IMPORTEDはtarget_link_livrariesと同じことをもう少し細かく指定できるもので、今回の目的には使えませんでした。

投稿2016/03/10 09:15

編集2016/03/11 09:18
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問