【问题标题】:boost.asio linking and librariesboost.asio 链接和库
【发布时间】:2014-09-29 17:34:14
【问题描述】:

我是 boost.asio 编程的新手,我在链接 boost 库时遇到了困难。

我的问题是,当我包含 asio 标头时,如何找出应该链接到我的项目的库。

例如,我使用了 #include <boost/date_time/posix_time/posix_time.hpp>#include <boost/asio.hpp 指令。

这是我的编译命令:

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 怎么样? boost.org/boost-build2
  • 这很好,但我正在尝试直接学习使用 g++ 编译器
  • 您使用的是什么操作系统?如果你用的是windows,你用的是Cygwin还是MinGW?
  • 我使用的是 Ubuntu 12.04
  • 太好了!到时候我会发布答案。

标签: c++ linker g++ boost-asio


【解决方案1】:

需要链接的库将根据所使用的 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): 未定义的引用
    `boost::system::generic_category()'
...
/tmp/cc9ow7fd.o:在函数`boost::asio::error::get_system_category()'中:
    example.cpp:(.text._ZN5boost4asio5error19get_system_categoryEv[
    _ZN5boost4asio5error19get_system_categoryEv]+0x5): 未定义引用
     到`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 提升
    U boost::协程::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::线程::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
    用于 boost::detail::thread_data_base 的 U vtable

此输出比链接器错误更易于管理。再一次,符号命名空间(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

另外,请注意linking order matters

【讨论】:

    【解决方案2】:

    正如您在 cmets 中所说的,您使用的是 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 之后要做什么。
    猜你喜欢
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多