Confusion about using libbson in cmake

According to the online example, I write a demo. Test under Ubuntu 20.04 and Debian 10.

// main.cpp
#include <bson/bson.h>

int main()
{
    return 0;
}
cmake_minimum_required(VERSION 3.5)

project(test)

find_package(bson-1.0 1.7 REQUIRED)
message(STATUS "find BSON_INCLUDE_DIRS = ${BSON_INCLUDE_DIRS}")
add_executable(main main.cpp)
target_include_directories(main PRIVATE
    ${BSON_INCLUDE_DIRS}
)

CMake seems to find the bson-1.0, but the BSON_INCLUDE_DIRS not set, gcc cant find the bson.h header.

~/Documents/code/test_cmake$ cmake .
-- find BSON_INCLUDE_DIRS = 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xzc/Documents/code/test_cmake
~/Documents/code/test_cmake$ make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
Documents/code/test_cmake/main.cpp:1:10: fatal error: bson/bson.h: No such file or directory
    1 | #include <bson/bson.h>
      |          ^~~~~~~~~~~~~
compilation terminated.

using find_package(libbson-1.0 1.7 REQUIRED) works, except it warn about deprecated

~/Documents/code/test_cmake$ cmake .
CMake Warning at /usr/local/lib/cmake/libbson-1.0/libbson-1.0-config.cmake:15 (message):
  This CMake target is deprecated.  Use 'mongo::bson_shared' instead.
  Consult the example projects for further details.
Call Stack (most recent call first):
  CMakeLists.txt:5 (find_package)


-- find BSON_INCLUDE_DIRS = /usr/local/include/libbson-1.0
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xzc/Documents/code/test_cmake
~/Documents/code/test_cmake$ make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main

I don’t understand the warning. mongo::bson_shared is a library, like target_link_libraries (hello_bson PRIVATE mongo::bson_shared) but in my case I dont even link with libbson, only include it. How can I avoid this warning.

Also, is the online example outdate? find_package (bson-1.0 1.7 REQUIRED) does not work.

@x_changnet, there are several things going on here. The libbson-1.0 package is an older package the required the consuming project to manually set each of the properties based on variables set by the package. This was not very CMake-like and so the new bson-1.0 package uses a proper CMake target. The libbson-1.0 package is deprecated and will be discontinued in a future release. So, you are better off to use the bson-1.0 package, which is planned to be supported long term.

That said, to use the bson-1.0 package in the way that you want, that is only for headers and without linking to the library itself, you need to extract the appropriate property from the imported CMake target. You can do that by adding after find_package():

 get_target_property(BSON_INCLUDE_DIRS mongo::bson_shared INTERFACE_INCLUDE_DIRECTORIES)

When I did that, I get this output from CMake:

-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- find BSON_INCLUDE_DIRS = /usr/local/include/libbson-1.0
-- Configuring done
-- Generating done
-- Build files have been written to: /home/roberto/cmake_test/build

Please give that a try and follow-up if you are still unable to get it working.

2 Likes

Thank you for the reply, it really help.

I look into INTERFACE_INCLUDE_DIRECTORIES it turns out when target_link_libraries (hello_bson PRIVATE mongo::bson_shared) CMake will read include directories from mongo::bson_shared. target_include_directories() is’t needed at all.

In my case, I trying to build a library base on bson, it only need the bson header, not link with it, so target_link_libraries (hello_bson PRIVATE mongo::bson_shared) is missing, leading to gcc complaints bson.h header file missing.

Now I use find_package (bson-1.0 1.7 REQUIRED) and extract include directories get_target_property(BSON_INCLUDE_DIRS mongo::bson_shared INTERFACE_INCLUDE_DIRECTORIES), the deprecated warning is gone, and everything works find.