5

How to run boost asio with cmake? Havint this simple project layout:

c1
├── c1
│   └── main.cpp
└── CMakeLists.txt

CMakeLists.txt:

cmake_minimum_required(VERSION 3.20.0)
project(c1)

add_executable(c1 c1/main.cpp)
include_directories(.)

set(BOOST_ROOT /usr/local/boost_1_78_0)
find_package(Boost 1.78.0 REQUIRED COMPONENTS system)
target_include_directories(c1 PUBLIC ${Boost_INCLUDE_DIR})
target_link_libraries(c1 LINK_PUBLIC ${Boost_LIBRARIES})

and main.cpp:

#include <iostream>
#include <boost/asio.hpp>

int main(){
    boost::asio::io_context io;
    boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
    t.wait();
    std::cout << "Hello world!" << std::endl;
}

I am getting this cmake error:

CMake Error at /usr/local/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find Boost (missing: system) (found suitable version "1.78.0",
  minimum required is "1.78.0")
Call Stack (most recent call first):
  /usr/local/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:2360 (find_package_handle_standard_args)
  CMakeLists.txt:8 (find_package)

I am not sure if I understand it correclty, but it is trying to find suitable version 1.78.0, but it found 1.78.0, so what is the problem?

Also before that, there was a warning:

CMake Warning at /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:1369 (message):
  New Boost version may have incorrect or missing dependencies and imported
  targets
Call Stack (most recent call first):
  /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:1492 (_Boost_COMPONENT_DEPENDENCIES)
  /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:2102 (_Boost_MISSING_DEPENDENCIES)
  CMakeLists.txt:8 (find_package)

So what should I do?

EDIT: the system library is at:

/usr/local/boost_1_78_0/boost/system

and the debug output of where is cmake looking:

-- [ /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:2053 ] _boost_LIBRARY_SEARCH_DIRS_RELEASE = "/usr/local/boost_1_78_0/lib;/usr/local/boost_1_78_0/stage/lib;/usr/local/boost_1_78_0/lib;/usr/local/boost_1_78_0/../lib;/usr/local/boost_1_78_0/stage/lib;PATHS;C:/boost/lib;C:/boost;/sw/local/lib"
-- [ /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:2054 ] _boost_LIBRARY_SEARCH_DIRS_DEBUG = "/usr/local/boost_1_78_0/lib;/usr/local/boost_1_78_0/stage/lib;/usr/local/boost_1_78_0/lib;/usr/local/boost_1_78_0/../lib;/usr/local/boost_1_78_0/stage/lib;PATHS;C:/boost/lib;C:/boost;/sw/local/lib"

-- [ /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:2239 ] Searching for SYSTEM_LIBRARY_RELEASE: boost_system-gcc10-mt-1_78;boost_system-gcc10-mt;boost_system-gcc10-mt;boost_system-mt-1_78;boost_system-mt;boost_system-mt;boost_system-mt;boost_system
-- [ /usr/local/share/cmake-3.22/Modules/FindBoost.cmake:2294 ] Searching for SYSTEM_LIBRARY_DEBUG: boost_system-gcc10-mt-d-1_78;boost_system-gcc10-mt-d;boost_system-gcc10-mt-d;boost_system-mt-d-1_78;boost_system-mt-d;boost_system-mt-d;boost_system-mt;boost_system

Yet I cannot understand, why the cmake cannot find that library.

milanHrabos
  • 2,010
  • 3
  • 11
  • 45
  • 4
    The problem is `missing: system`, which means that CMake cannot find the library corresponding to the "system" component. Run CMake with additional `-DBoost_DEBUG=ON`, that way CMake will print which exact libraries it searches and where. Compare that output with files which you actually has. – Tsyvarev Mar 24 '22 at 23:21
  • @Tsyvarev see the edits. The system library do exist of course. And even with the debug enabled and with the output, I have no idea why cannot cmake find it – milanHrabos Mar 25 '22 at 08:34
  • 1
    The directory `/usr/local/boost_1_78_0/boost/system` contains a **headers**. But a **library** is a `.so` file, not *headers*. Debug output "Searching for SYSTEM_LIBRARY_RELEASE" lists possible names of the file corresponding to the Boost system library, and "_boost_LIBRARY_SEARCH_DIRS_RELEASE" lists directories where this file is searched. Do you have the library file in one of this directories? – Tsyvarev Mar 25 '22 at 09:22
  • the system library is in `/usr/local/boost_1_78_0/libs/system`, and from the output, I see the cmake is looking for the system in `_boost_LIBRARY_SEARCH_DIRS_RELEASE = "/usr/local/boost_1_78_0/lib`... So there is lib**s** directory, but the cmake is looking after only "lib" (without **s** at the end), is this the reason? If so, is not that bug for boost or cmake? Why is there naming inconsistency? – milanHrabos Mar 25 '22 at 09:38
  • Subdirectory `libs` looks like a weird place for Boost libraries. But what about the library itself, which **exact path** it has? E.g. on Ubuntu the library path is `/usr/lib/x86_64-linux-gnu/libboost_system.so`. – Tsyvarev Mar 25 '22 at 09:52
  • So here is how I downloaded the boost. First here https://www.boost.org/users/download/ get the latest boost version boost_1_78_0.tar.bz2, `mv`ed to `/usr/local`, `tar -xf ` and that's how the directory was created. Then simple in my project, modified the `BOOST_ROOT` in the cmake (as you can see from the cmakelist dump above) to point to that path. And yes, triggered `sudo ./bootstrap.sh` from the boots dir. So there is no dpkg involved, the boost is manually installed. But that should not be problem or? – milanHrabos Mar 25 '22 at 10:20
  • 3
    Downloaded Boost provides only **header-only** libraries (the libraries which has no library files, only headers), these libraries shouldn't be specified in COMPONENTS. `system` is a header-only library since Boost 1.69, but it can have a library file too. You either need to remove COMPONENTS from `find_package` call, so downloaded Boost will work. Or you need to **install** Boost (`./bootstrap.sh` and `./b2 install`), and tell CMake to use installed variant. By default, Boost is installed into `/usr/local`, which is searched by CMake automatically (no needs to set BOOST_ROOT variable). – Tsyvarev Mar 25 '22 at 11:05

2 Answers2

6

Looks like you forgot to build the Boost libraries.

Many Boost libraries are, or can be, header-only, but many aren't.

I think the CMake FindBoost components only bother with the libraries that require building. So, if you name system as a required component, you're telling CMake that you need to link it, and it looks for the built libraries.

The built libraries are typically under stage/lib/ e.g.

/home/sehe/custom/boost/stage/lib/libboost_system.a
/home/sehe/custom/boost/stage/lib/libboost_system.so
/home/sehe/custom/boost/stage/lib/libboost_system.so.1.78.0

However, if you didn't build the library, it will be missing.

See https://www.boost.org/doc/libs/1_78_0/more/getting_started/unix-variants.html

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
sehe
  • 374,641
  • 47
  • 450
  • 633
  • So now after building the libraries with `./bootstrap.sh install`, and having specified system as component in `find_package(Boost 1.78.0 REQUIRED COMPONENTS system)`, I am getting undefined references for `pthread_condattr_setclock`, `pthread_detach`, `pthread_join`, `pthread_create` and other posix pthread functions. Should I include another `find_pakcage` for pthread support or should that be job of bootstrap? Why am I getting link errors now? – milanHrabos Mar 25 '22 at 14:20
  • So I have to `find_package` for thread support : https://stackoverflow.com/questions/1620918/cmake-and-libpthread. But why is that not included with the boost libraries automatically? As it is dependency for `boost asio` to work, it should take care of its dependencies or? – milanHrabos Mar 25 '22 at 14:23
  • That is not normal. `pthread` is obviously normally present and detected by the default toolsets. – sehe Mar 25 '22 at 15:02
3

Don't waste your time trying to compile Boost, this is not the problem here.

Like Tsyvarev said, since version 1.69 if you are using only system or any other header-only component (not requiring build) you must remove keyword COMPONENT

find_package(Boost 1.80.0 REQUIRED)

# ...Nothing more
56ka
  • 1,463
  • 1
  • 21
  • 37
  • This just results in the target not finding `Boost::filesystem` for me. – Newbyte Nov 15 '22 at 08:36
  • 1
    @Newbyte `Boost::filesystem` must be compiled so my answer does not work for you. See the list of components requiring compilation here under **Header-Only Libraries** https://www.boost.org/doc/libs/1_80_0/more/getting_started/windows.html#id30 – 56ka Nov 24 '22 at 09:31