Boost.Asio链接和库

4
我刚开始学习boost.asio编程,并且在链接boost库时遇到了困难。
我的问题是,当我包含asio头文件时,如何找出应该链接到我的项目中的哪些库。
例如,我使用了 #include 和 #include 指令。
所以这是我编译它的命令: g++ -I /usr/local/boost_1_55_0 ASIO.cpp -o HELLO -L /usr/local/lib/ -l boost_system
请注意,我的boost库安装在 /usr/local/boost_1_55_0 下,二进制文件位于 /usr/local/lib 下。
我的问题实际上是,在 -l 后面需要写什么。
谢谢你们的回答。

不妨看看BoostBuild?http://www.boost.org/boost-build2/ - Emanuel
这很好,但我正在尝试直接使用g++编译器进行学习。 - Mohammad Karimi
你使用的操作系统是什么?如果你在使用Windows,你使用的是Cygwin还是MinGW? - Emanuel
我正在使用Ubuntu 12.04。 - Mohammad Karimi
太好了!那我就发一篇答案。 - Emanuel
3个回答

9
需要链接的库将根据使用的Boost.Asio特性和其他Boost头文件确定。通常,可以通过对未定义引用的命名空间进行猜测,并检查Boost库中的符号来确定要链接的库。
在下面的所有示例中,我都使用了gcc 4.8.1。确切的错误消息并不重要,因为它们中的内容在编译器之间应该是相似的。
以包括Boost.Asio的基本程序为例:
#include <boost/asio.hpp>

int main() {}

编译此文件时:

$ g++ example.cpp -isystem /usr/local/boost_1_55_0
...
example.cpp:(.text+0x31): undefined reference to
    `boost::system::generic_category()'
...
/tmp/cc9ow7fd.o: In function `boost::asio::error::get_system_category()':
    example.cpp:(.text._ZN5boost4asio5error19get_system_categoryEv[
    _ZN5boost4asio5error19get_system_categoryEv]+0x5): undefined reference
     to `boost::system::system_category()'

请注意,未定义的引用是在boost::system命名空间中包含的符号。如果查看已安装的Boost库列表,libboost_system.so可能被视为一个很好的链接候选项。如果没有明显的候选项,则可以使用像nmreadelf这样的工具来检查候选库并查找符号:

$ nm --defined-only --print-file-name --demangle \
> /usr/local/lib/libboost_*.so | grep boost::system::generic_category
...
/usr/local/lib/libboost_system.so:
    00000000000015c0 T boost::system::generic_category()
...

在这种情况下,boost::system::generic_category()符号在libboost_system.so的文本部分中定义。因此,基本程序需要链接到boost_system

g++ example.cpp -isystem /usr/local/boost_1_55_0 -L/usr/local/lib/ -lboost_system

这是一个稍微复杂一些的示例。该程序在协程中异步等待一个单调定时器,在由额外线程执行的协程中执行。

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/thread/thread.hpp>

boost::asio::io_service io_service;

void handler(boost::asio::yield_context yield)
{
  boost::asio::steady_timer timer(io_service);
  timer.expires_from_now(boost::chrono::seconds(3));
  timer.async_wait(yield);
}

int main()
{
  boost::asio::spawn(io_service, &handler);
  boost::thread thread(boost::bind(
      &boost::asio::io_service::run, &io_service));
  thread.join();
}

虽然可以使用之前的相同方法,但链接器错误会导致 40 多行缠绕的模板符号,这可能会让人望而生畏。作为替代方案,可以使用 -c 选项编译示例,但不进行链接。然后,可以检查生成的目标文件中的未定义符号:
$ g++ example.cpp -isystem /usr/local/boost_1_55_0 -c
$ nm --demangle --undefined example.o | grep boost
    U boost::coroutines::stack_traits::default_size()
    U boost::coroutines::stack_traits::is_unbounded()
    U boost::coroutines::stack_traits::maximum_size()
    U boost::coroutines::stack_traits::minimum_size()
    U boost::coroutines::detail::coroutine_context::jump(
        boost::coroutines::detail::coroutine_context&, long, bool)
    U boost::coroutines::detail::coroutine_context::coroutine_context(
        void (*)(long), boost::coroutines::stack_context const&)
    U boost::coroutines::detail::coroutine_context::coroutine_context()
    U boost::chrono::steady_clock::now()
    U boost::detail::thread_data_base::~thread_data_base()
    U boost::system::system_category()
    U boost::system::generic_category()
    U boost::thread::join_noexcept()
    U boost::thread::native_handle()
    U boost::thread::start_thread_noexcept()
    U boost::thread::detach()
    U typeinfo for boost::detail::thread_data_base
    U vtable for boost::detail::thread_data_base
这个输出比链接器错误更易于管理。再次提醒,符号命名空间 (boost::coroutineboost::chronoboost::threadboost::system) 提供了关于哪个库定义符号的良好提示。上面的程序可以使用以下命令编译和链接:
g++ example.cpp -isystem /usr/local/boost_1_55_0 -L/usr/local/lib/ -lboost_coroutine -lboost_chrono -lboost_thread -lboost_system
另外,请注意 链接顺序很重要

2
作为你在评论中提到自己使用Ubuntu系统,我将回答如何在Ubuntu上实现。 首先,请确保您已安装库。最方便的方法是使用apt,因为它可以节省您手动将库放置在“/ usr / local / lib”中的工作量。
sudo apt-get install libboost-all-dev

然后您可以使用以下命令编译您的文件:
g++ my_file.cpp -lboost_system

编辑:

我能看到你命令中唯一的错误就是在标识符后面使用了空格。尝试这样写:

g++ -I/usr/local/boost_1_55_0 ASIO.cpp -o HELLO -L/usr/local/lib/ -lboost_system

你说得没错,但那不是我的问题的答案! 我强调一下,我的问题是在使用g++编译器时,在-l之后该怎么做。 - Mohammad Karimi

1

我使用的是Ubuntu 20.04.4 LTS。尝试链接pthread库。这对我有效:

g++ hello.cpp -lboost_system -lpthread


这是使其工作的最简单方法!!! - HanniBaL90

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接