boost.asio linking and libraries

2019-04-02 05:05发布

I'm new to boost.asio programming and i have difficulties linking boost libraries.

My question is that how to find out which libraries I should link to my project when I include asio headers.

For example I used #include <boost/date_time/posix_time/posix_time.hpp> and #include <boost/asio.hpp directives.

so this is my command to compile it:

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

consider my boost library is installed on /usr/local/boost_1_55_0 and binaries are on /usr/local/lib.

my problem is actually what I need to write after -l

Thanks for your answers.

2条回答
萌系小妹纸
2楼-- · 2019-04-02 05:47

The libraries needing to be linked against will be determined based on the Boost.Asio features used and other Boost header files. In general, one can determine which library to link against with some guess work on the undefined reference's namespaces, and inspecting the symbols in the Boost libraries if that doesn't work.


In all of the examples below, I am using gcc 4.8.1. The exact error messages are not important, as the content in them should be fairly similar between compilers.

Take a basic program that include Boost.Asio:

#include <boost/asio.hpp>

int main() {}

When compiling this:

$ 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()'

Note the undefined references are symbols contained within the boost::system namespace. If one was to look at the list of installed Boost libraries, libboost_system.so may come to mind as a good candidate for linking. If there is not an obvious candidate, then one can use tools like nm or readelf to examine candidate libraries and look for a symbol:

$ 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()
...

In this case, the boost::system::generic_category() symbol is defined in the text section of libboost_system.so. Thus, the basic program needs to link against boost_system:

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

Here is an example that is a bit more complex. The program asynchronously waits on a monotonic timer in a coroutine that is executed by an additional thread.

#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();
}

While the same approach as before can be used, the linker error results in 40+ lines of mangled template symbols, which can be quite daunting. As an alternative, one can compile the example, but not link it by using the -c option. Then, the resulting object file can be examined for undefined symbols:

$ 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

This output is much more manageable than the linker error. Once again, the symbol namespaces (boost::coroutine, boost::chrono, boost::thread, and boost::system) provide a good hint as to what library may define the symbol. The above program can be compiled and linked with:

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

Also, be aware that the linking order matters.

查看更多
Rolldiameter
3楼-- · 2019-04-02 05:48

As you told in the comments that you are on Ubuntu, I'll answer how to do it on an Ubuntu system.

First, make sure you have the library installed. It will be most convenient to use apt, since it saves you the effort of having to manually putting the library in /usr/local/lib.

sudo apt-get install libboost-all-dev

Then you can compile your file using:

g++ my_file.cpp -lboost_system

EDIT:

The only apparent mistake I can see in your command is that you use spaces after the flag indicators. Try this:

g++ -I/usr/local/boost_1_55_0 ASIO.cpp -o HELLO -L/usr/local/lib/ -lboost_system
查看更多
登录 后发表回答