Search code examples
c++cmakeboost

How to auto-link boost libraries with CMake


project(learn)

cmake_minimum_required(VERSION 3.11)

set(CMAKE_CXX_STANDARD 17)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    message("Current OS is Linux")
    include_directories("/mnt/e/c++/boost_1_72_0")
    link_directories("/mnt/e/c++/boost_1_72_0/stage/lib")
    link_libraries(pthread boost_thread boost_fiber boost_context)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    message("Current OS is Windows")
    include_directories("E:/c++/boost_1_72_0")
    link_directories("E:/c++/boost_1_72_0/stage/lib")
endif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")

add_executable(learn_asio learn_asio.cpp)

learn_asio.cpp:

#include <boost/asio.hpp>
#include <boost/fiber/all.hpp>
#include <boost/thread.hpp>
#include <iostream>

using boost::asio::async_write;
using boost::asio::buffer;
using boost::asio::io_context;
using boost::asio::use_future;
using boost::asio::ip::make_address;
using boost::asio::ip::tcp;
using boost::fibers::async;
using boost::fibers::fiber;
using boost::system::error_code;

int main(){
  io_context ioc;
  tcp::socket socket(ioc);

  tcp::endpoint ep(make_address("192.168.1.20"), 80);

  auto ret_f = socket.async_connect(ep, boost::asio::use_future);

  boost::thread_group t;
  t.create_thread([&ioc]() {
    ioc.run();
    std::cout << "jfiejf" << std::endl;
  });

  ret_f.wait_for(std::chrono::seconds(3));

  t.join_all();

  return 0;
}


My library folder: boost library folder
Accroding to the code above I can successfully build my code. But I hate the code:

link_libraries(pthread boost_thread boost_fiber boost_context)

on the linux platform. Why do I not need it on windows platforms?
As I remember Linux can auto link the library too.
How can I achieve it?


Solution

  • Boost docs:

    Auto-Linking

    Most Windows compilers and linkers have so-called “auto-linking support,” which eliminates the second challenge. Special code in Boost header files detects your compiler options and uses that information to encode the name of the correct library into your object files; the linker selects the library with that name from the directories you've told it to search.

    The GCC toolchains (Cygwin and MinGW) are notable exceptions; GCC users should refer to the linking instructions for Unix variant OSes for the appropriate command-line options to use.

    Note that the auto-linking feature has been known to fail on occasion (e.g. when your Boost libraries are installed using a non-standard setting). You can define BOOST_ALL_NO_LIB to disable the feature on Windows.

    You shouldn't be hard-coding Boost paths into your CMakeLists.txt, though. Better use the platform-independent find_package:

    set( Boost_USE_STATIC_LIBS OFF )
    set( Boost_USE_MULTITHREADED ON )
    set( Boost_USE_STATIC_RUNTIME OFF )
    
    find_package( Boost 1.72.0 COMPONENTS thread fiber context )
    
    if ( Boost_FOUND )
        include_directories( ${Boost_INCLUDE_DIRS} )
        link_libraries( learn_asio ${Boost_LIBRARIES} )
    else()
        message( FATAL_ERROR "Required Boost packages not found. Perhaps add -DBOOST_ROOT?" )
    endif()