奇怪的mingw链接错误与boost

strange mingw linker errors with boost?

本文关键字:错误 boost 链接 mingw      更新时间:2023-10-16

我已经为此工作了一段时间,但似乎无法理解这种情况-部分原因是我不完全理解发生了什么(这就是我来这里的原因)。

我正在做一种增强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,现在有一个stage/lib文件夹,其中包含所有.lib文件。与boost/thread库相关的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。0。然后:

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

现在在那里的某个地方,我可以告诉这些显然是我应该从boost/thread获得的函数,显然它确实找到了lib文件,那么为什么它不能正确链接呢?

非常感谢您的帮助!

编辑:

我已经使用bjam"stage"选项重建了boost

bjam toolset=gcc stage

现在,在构建完成后,我留下了一个带有.a文件的stage/lib文件夹,这是意料之中的。下面是boost/thread相关的库:

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

我还是不知道。

问题解决了。Boost的头文件被配置为动态链接,但是动态库(dll)不会被构建,除非你指定:

--build-type=complete

调用bjam时。之后,将适当的dll复制到您的应用程序目录中,但仍然使用

-L/BOOST_DIR/stage/lib -lname
当链接

这组库文件:

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构建默认是针对DLL库构建的,除非使用MSVC或Intel编译器。

我甚至不确定如何构建DLL库-我必须查找它。同时,您可以使用下面的命令来构建示例,这样它就可以链接到静态库。BOOST_THREAD_USE_LIB宏构建.cpp文件,这样它将期望链接到静态库:

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