2013/11/12

g++を実行するときファイル名とライブラリ指定などのオプションには書く順番がある?

タイトルをなんて書けばいいのかわからなかったので,わかりにくいタイトルになってしまっています.

とりあえず,g++やgccには"-l"でライブラリの指定をすることができます.
例えば,下のソースをコンパイルするときは

#include <iostream>
#include <math .h>

int main(void){
        std::cout << sin(30) << std::endl;
}

このようにコンパイルすることができます.

g++ math.cpp -lm     #ライブラリの指定がファイル名の後でも
g++ -lm math.cpp     #ファイル名の前でもいい

どちらのコマンドでもおkなので,
「別にファイル名と"-l"や"-I"などのオプションには順番は関係ないんだー」
と思っていました.

しかし,
今回Boostのthreadを使ってマルチスレッドを使用とした時に,次のソースをコンパイルしたら...

#include <iostream>
#include <boost/thread.hpp>

void thFunc(void)
{
        std::cout << "thread" << std::endl;
}

int main(void)
{
        boost::thread th(thFunc);
        std::cout << "main" << std::endl;
        th.join();
        return 0;
}

ファイル名がはじめのコマンドはおkでしたが,

g++ thread.cpp -lboost_thread     #これはおk

ファイル名が後のコマンドだとエラーになってしまいました...

g++ -lboost_thread thread.cpp     #これはエラー


#/tmp/ccXxcECw.o: In function `main':
#thread.cpp:(.text+0x65): undefined reference to `boost::thread::join()'
#thread.cpp:(.text+0x76): undefined reference to `boost::thread::~thread()'
#thread.cpp:(.text+0x8e): undefined reference to `boost::thread::~thread()'
#/tmp/ccXxcECw.o: In function `boost::detail::thread_data_base::thread_data_base()':
#thread.cpp:(.text._ZN5boost6detail16thread_data_baseC2Ev[_ZN5boost6detail16thread_data_baseC5Ev]+0x24): undefined reference to `vtable for boost::detail::thread_data_base'
#/tmp/ccXxcECw.o: In function `boost::thread::thread(void (*)(), boost::disable_if >, boost::thread::dummy*>::type)':
#thread.cpp:(.text._ZN5boost6threadC2IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[_ZN5boost6threadC5IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE]+0x30): undefined reference to `boost::thread::start_thread()'
#/tmp/ccXxcECw.o: In function `boost::detail::thread_data::~thread_data()':
#thread.cpp:(.text._ZN5boost6detail11thread_dataIPFvvEED2Ev[_ZN5boost6detail11thread_dataIPFvvEED5Ev]+0x1f): undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
#/tmp/ccXxcECw.o:(.rodata._ZTIN5boost6detail11thread_dataIPFvvEEE[typeinfo for boost::detail::thread_data]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
#collect2: ld はステータス 1 で終了しました
これで数時間はまりました. 上の例のようにどちらでもおkだと思っていたので, 確かにmakefileなどにはファイル名が先に書いて有りますね. まあ,いい勉強になりました. g++やgccではライブラリの指定などのオプションよりもファイル名を先に書きましょう.

0 件のコメント:

コメントを投稿