【问题标题】:GCC C++ linking boost when creating a library创建库时的 GCC C++ 链接提升
【发布时间】:2013-03-09 23:28:28
【问题描述】:

我想我的问题是,当 Boost 刚刚编译并存储在我的主目录中而不是系统中时,创建存档时静态链接到 Boost 的正确方法是什么?将我的程序创建为库背后的想法是,我将能够重新分发库文件以供其他人在他们的程序中链接。

我想制作一个可以在 Linux 上链接的 C++ 库文件。我真的不在乎它是静态的还是动态的,但静态可能会让我更轻松。

我遇到的问题是我找到的示例没有告诉您如何链接库中的其他库。我的库使用 Boost,并且我已经构建了 Boost,但我无权将其移出我的用户区域。

我尝试过制作这样的静态存档:

编译 cpp 文件:

g++ -O3 -ffast-math -Wall -Wextra -g -I./ -I../../boost/ -c BuddyManager.cpp -o build/BuddyManager.o

创建静态存档:

ar rcs build/libppmi.a ../../boost/lib/libboost_system.a build/Application.o build/DataBlock.o (后面列出了我的所有目标文件等)

但是当我稍后链接到我创建的 .a 文件时,它会给出未定义的引用错误。

我设法通过在 Mac 上构建共享库 SO 文件来创建我的库,但在该系统上,Boost 安装在标准系统位置。当我在 Linux 上构建共享库时,我收到错误“/usr/lib/crtbegin.o 中的隐藏符号 `__dso_handle' 被 DSO 引用”并且我经常遇到无法找到 Boost .SO 文件的问题。因此我决定改为静态链接。

系统在 Scientific Linux SL 版本 5.3 (Boron) 上运行,我使用的是 gcc-4.6.2。但是,我希望它可以移植到几乎所有版本的 GCC。

谢谢。如果有任何不清楚的地方或者您想了解更多详情,请询问。

一些缺失的参考资料是:

对`boost::thread::interrupt()'的未定义引用

boost/boost/thread/pthread/thread_data.hpp:247:未定义对 `boost::this_thread::hiden::sleep_until(timespec const&)' 的引用

boost/boost/archive/detail/iserializer.hpp:158:未定义对 `boost::archive::detail::basic_iserializer::~basic_iserializer()' 的引用

他们似乎都在 Boost 中。它找不到应该在 Boost 档案中的参考资料。

有关更多信息,这是我正在编译的内容:

ar rcs build/libppmi.a ../../boost/lib/libboost_system.a ../../boost/lib/libboost_iostreams.a ../../boost/lib/libboost_serialization.a 。 ./../boost/lib/libboost_thread.a build/Application.o build/DataBlock.o build/Iteration.o build/Launcher.o build/Message.o build/Network.o build/Processes.o build/DataBlockManager .o build/Communicator.o build/NetworkServer.o build/NetworkClientSession.o build/NetworkMessage.o build/NetworkConnection.o build/Threadable.o build/BuddyManager.o

这工作正常。当我使用它的存档时,它会中断。我也尝试从 boost 库中提取 .o 文件,但这会导致其他有关 pthread 库的链接器错误。

【问题讨论】:

  • 缺少哪些符号?来自您的代码、来自 boost 或看似无关的符号?你能给出几个符号名称吗?您很可能只是在存档中丢失了一些文件。
  • 感谢您的回复。我已经更新了问题以显示一些符号。需要明确的是,在创建存档和系统时,我还会链接到 Boost 线程和序列化。
  • 好吧,那么您至少缺少libboost_thread.a 以及其他一些。您为什么不直接构建您的项目,然后使用ldd 检查它使用了哪些库?然后,您可以将它们一起打包到您的存档中(确保遵守相关的许可条款)。
  • 所以我的存档的实际编译行是:ar rcs build/libppmi.a ../../boost/lib/libboost_system.a ../../boost/lib/libboost_iostreams。 a ../../boost/lib/libboost_serialization.a ../../boost/lib/libboost_thread.a build/Application.o build/DataBlock.o build/Iteration.o build/Launcher.o build/Message .o build/Network.o build/Processes.o build/DataBlockManager.o build/Communicator.o build/NetworkServer.o build/NetworkClientSession.o build/NetworkMessage.o build/NetworkConnection.o build/Threadable.o build/BuddyManager .o 这很好用,但是当我使用我的存档时,会出现参考错误。
  • @rpamely 使用此信息编辑您的问题,以便未来的读者不必扫描 cmets

标签: c++ gcc boost static


【解决方案1】:

您正在创建档案档案,但是当链接器在档案中查找时,它需要目标文件。链接器将查看libppmi.a 并跳过所有非目标文件,包括libboost_system.a,因为它不知道如何处理它们,因此找不到任何Boost 符号。您可以通过与-t 链接来确认这一点(如果您使用gccg++ 进行链接,则使用-Wl,-t-t 传递给链接器)在链接器处理时打印每个文件的名称它,你会看到它不处理嵌套档案。

如果您想在存档中包含所有 Boost 代码,则需要列出各个对象(通过在构建 Boost 的地方直接引用它们或从 Boost 存档中提取它们然后将它们添加到新存档中。 )

这工作正常。当我使用存档时它会中断。

当然,它会创建一个包含您列出的文件的存档。创建存档只需将大量单独的文件放入一个大文件中,您可以将任何文件类型放入其中。它不会真的出错,但这并不意味着结果是正确的或可用的。

我也尝试从 boost 库中提取 .o 文件,但这会导致其他有关 pthread 库的链接器错误。

这是正确的方法,但您遇到了不同的问题,因此请解决该问题,而不是放弃该方法。如果你使用的是 Boost.Thread 那么你需要编译和链接-pthread

【讨论】:

  • 感谢您的回答。有趣的是,最好的方法是将 boost 档案提取到 .o 文件中,然后重新链接这些文件。遗憾的是,这是最好的方法,因为现在我必须将所有库 boost 链接显式添加到我的存档链接命令中。然而,这似乎是正确的方法,所以我会接受你的回答。不幸的是,当我尝试链接档案时,GCC 无法使其成为一个更友好的程序并自动执行此操作。谢谢。
  • 如果你想创建一个静态存档,这是唯一的方法,因为这就是存档的工作方式以及链接器(而不是 GCC)的工作方式。如果您创建一个动态库,则可以将其链接到现有存档,而无需从中提取对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
相关资源
最近更新 更多