2011-07-12 58 views
4

我一直在研究這一段時間,似乎無法理解這種情況 - 部分原因是我沒有完全理解發生了什麼(這就是我來到這裏的原因)。奇怪的mingw鏈接器錯誤與提升?

我在做一種升壓的hello world如下:

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


void helloworld() { 
    std::printf("HELLO FROM A BOOST THREAD!"); 
} 

int main(int argc, char **argv) { 
    boost::thread t(&helloworld); 
    t.join(); 
} 

這是在Windows上。我將Boost目錄存儲在C:\ Boost中。我運行了bootstrap和bjam,現在有一個包含所有.lib文件的stage/lib文件夾。與升壓/線程庫的lib文件是:

libboost_thread-vc100-mt.lib 
libboost_thread-vc100-mt-1_46_1.lib 
libboost_thread-vc100-mt-gd.lib 
libboost_thread-vc100-mt-gd-1_46_1.lib 

現在我編譯:

g++ -c main.cpp -I/Boost 

該行正常工作,我得到main.o.然後:

g++ -o test.exe main.o -L/Boost/stage/lib -llibboost_thread-vc100-mt 

這就是麻煩發生的地方。首先,如果我沒有像我那樣輸入-l參數,MinGW甚至找不到該文件。也就是說,如果我想:

-lboost_thread-vc100-mt 

,而不是我輸入上面(我怎麼想它應該做)的方式,LD將與沒有這樣的文件退出。無論如何,這是我現在從該行獲得的輸出:

main.o:main.cpp:(.text+0x47): undefined reference to `_imp___ZN5boost6thread4joinEv' 
main.o:main.cpp:(.text+0x55): undefined reference to `_imp___ZN5boost6threadD1Ev' 
main.o:main.cpp:(.text+0x70): undefined reference to `_imp___ZN5boost6threadD1Ev' 
main.o:main.cpp:(.text$_ZN5boost6threadC1IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type)]+0x23): undefined reference to `_imp___ZN5boost6thread12start_threadEv' 
collect2: ld returned 1 exit status 

現在在那裏的某個地方,我可以告訴大家,這顯然是我應該從升壓/線程獲得的功能,顯然它確實找到了lib文件,那麼它爲什麼不正確鏈接?

非常感謝您的幫助!

編輯:

我使用的bjam改造提升「階段」選項

bjam toolset=gcc stage 

現在,構建完成後,我只剩下一個階段/ lib文件夾與.a文件,這是可以預料的。這些是升壓/線程相關的庫:

libboost_thread-mgw45-mt-1_46_1.a 
libboost_thread-mgw45-mt-d-1_46_1.a 

但是,鏈接如下:

g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1 

輸出完全相同的錯誤。還試過:

g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1 -static 

我很茫然,還是。

+0

指定'toolset = gcc'是不夠的,你還需要'target-os = windows'用於MinGW。 – ildjarn

回答

5

解決的問題。 Boost的頭被配置爲動態鏈接,但動態庫(DLL的)不建,除非你指定:

--build-type=complete 

調用的bjam時。之後,將相應的dll複製到您的應用程序目錄中,但仍然使用鏈接時的

-L/BOOST_DIR/stage/lib -lname 

+0

謝謝,這個解決方案是有效的。我嘗試了很多次讓Boost-Thread「Hello world」程序運行,但程序無法編譯,直到編譯Boost-Thread庫時才添加'--build-type = complete'標誌。忠, – TrungTN

5

這套庫文件:

libboost_thread-vc100-mt.lib 
libboost_thread-vc100-mt-1_46_1.lib 
libboost_thread-vc100-mt-gd.lib 
libboost_thread-vc100-mt-gd-1_46_1.lib 

是爲Visual Studio 2010的編譯器。他們不會與GCC合作。如果你想使用gcc/MinGW,你需要爲該編譯器下載/構建一組boost庫。或者,您可以安裝VS 2010並使用該編譯器(如果成本有問題,免費的VC++ 2010 Express版本應該可以正常工作)。

你可以從http://nuwen.net/mingw.html(我相信只有32位目標)的軟件包中獲得Boost的MinGW發行版。


回答關於獲得錯誤使用MinGW的庫:

_imp_前綴上的符號是g++正在鏈接到一個DLL /共享庫的指示。你擁有的.lib文件是用於靜態庫的(這也是我在做一個簡單的bjam庫時所得到的結果)。如果你看看boost/thread/detail/config.hpp,你將會看到,對於Win32版本,默認情況下,除非使用MSVC或Intel編譯器,否則默認爲針對DLL庫進行構建。

我甚至不確定如何構建DLL庫 - 我必須查看它。同時,您可以使用以下命令構建您的示例,以便它將鏈接到靜態庫。該BOOST_THREAD_USE_LIB宏編譯.cpp文件,使得它會想到對靜態鏈接庫:

g++ -I/Boost -DBOOST_THREAD_USE_LIB -c main.cpp 
+0

查看我的編輯新信息。 – cemulate

+0

@ user48998:我已經用更多信息更新了答案。 –

+0

謝謝你,這是我達到的相同答案。另外,如果你不想靜態鏈接,你可以使用--build-type = complete選項繼續並構建dll。 – cemulate