【问题标题】:strange mingw linker errors with boost?带有boost的奇怪的mingw链接器错误?
【发布时间】:2011-07-12 02:45:25
【问题描述】:

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

我正在做一种提升你好世界如下:

#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 文件夹。与 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.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

现在在那里的某个地方,我可以说这些显然是我应该从 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

我还是很茫然。

【问题讨论】:

  • 指定toolset=gcc是不够的,MinGW还需要target-os=windows

标签: c++ boost linker g++ mingw


【解决方案1】:

解决了这个问题。 Boost 的标头配置为动态链接,但除非您指定,否则不会构建动态库(dll):

--build-type=complete

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

-L/BOOST_DIR/stage/lib -lname

链接时。

【讨论】:

  • 谢谢,这个解决方案有效。我多次尝试让 Boost-Thread "Hello world" 程序运行,但程序无法编译,直到我在编译 Boost-Thread 库时添加 --build-type=complete 标志。中,
【解决方案2】:

这组库文件:

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

【讨论】:

  • 谢谢,这是我得到的相同答案。此外,如果您不想静态链接,可以使用 --build-type=complete 选项继续构建 dll。
  • @user48998:我注意到你已经得出了同样的结论,但只是在我编辑了我的答案之后。顺便说一句,我通过使用link=shared runtime-link=shared 选项运行bjam 获得了DLL。我想这是--build-type=complete 所做的另一个子集。但是,现在我实际上无法编译静态库链接(即使我指定-DBOOST_THREAD_USE_LIB),这让我很吃惊。我得挖一点看看这是怎么回事。
猜你喜欢
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多