1

I would like to compile & link the following demo application using boost::logger but I get the following output:

d$ rm -rf *; cmake ..;make -- The C compiler identification is GNU 5.4.0 -- The CXX compiler identification is GNU 5.4.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 -- Boost version: 1.67.0 -- Boost_LIBRARIES: -- -- BOOST_INCLUDEDIR: -- /path/to/env/include -- Configuring done -- Generating done -- Build files have been written to: /path/to/src/tmp/logger/build Scanning dependencies of target logger [ 50%] Building CXX object CMakeFiles/logger.dir/logger.cpp.o [100%] Linking CXX executable logger CMakeFiles/logger.dir/logger.cpp.o: In function `init()': /path/to/src/tmp/logger/logger.cpp:21: undefined reference to `boost::log::v2_mt_posix::core::get()' /path/to/src/tmp/logger/logger.cpp:24: undefined reference to `boost::log::v2_mt_posix::core::set_filter(boost::log::v2_mt_posix::filter const&)' CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::attribute_name::attribute_name(char const*)': /path/to/env/include/boost/log/attributes/attribute_name.hpp:80: undefined reference to `boost::log::v2_mt_posix::attribute_name::get_id_from_string(char const*)' CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::light_rw_mutex()': /path/to/env/include/boost/log/detail/light_rw_mutex.hpp:103: undefined reference to `pthread_rwlock_init' CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::~light_rw_mutex()': /path/to/env/include/boost/log/detail/light_rw_mutex.hpp:107: undefined reference to `pthread_rwlock_destroy' CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::lock_shared()': /path/to/env/include/boost/log/detail/light_rw_mutex.hpp:111: undefined reference to `pthread_rwlock_rdlock' CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::unlock_shared()': /path/to/env/include/boost/log/detail/light_rw_mutex.hpp:115: undefined reference to `pthread_rwlock_unlock' CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::once_block_sentry::~once_block_sentry()': ... ... 

now my CMakeLists.txt looks like:

cmake_minimum_required(VERSION 2.6) project(LOGGER) set(BOOST_INCLUDEDIR "/path/to/env/include") set(BOOST_ROOT "/path/to/env/include") set(Boost_NO_SYSTEM_PATHS on CACHE BOOL "Do not search system for Boost") find_package(Boost REQUIRED) message(STATUS Boost_LIBRARIES:) message (STATUS ${Boost_LIBRARIES}) message(STATUS BOOST_INCLUDEDIR:) message(STATUS ${BOOST_INCLUDEDIR}) ADD_EXECUTABLE(logger logger.cpp) target_include_directories(logger PUBLIC ${BOOST_INCLUDEDIR}) set (CMAKE_CXX_FLAGS "-g -Wall -DBOOST_LOG_DYN_LINK") 

and logger.cpp:

#include <iostream> #include <boost/fusion/iterator/equal_to.hpp> #include <boost/log/core.hpp> #include <boost/log/trivial.hpp> #include <boost/log/expressions.hpp> #include <boost/log/utility/setup/file.hpp> namespace logging = boost::log; namespace src = boost::log::sources; namespace sinks = boost::log::sinks; namespace keywords = boost::log::keywords; namespace expr = boost::log::expressions; void init() { logging::add_file_log("sample.log"); logging::core::get()->set_filter ( logging::trivial::severity >= logging::trivial::info ); } int main(void) { init(); std::cout <<"Hello World!"; 

As you can see in the cmake output, ${Boost_LIBRARIES} did not return anything, I suspect this to be the culprit even though, the compiler found the boost includes at the non-standard path.

1
  • You forget to add log component when finding the Boost: find_package(Boost COMPONENTS log REQUIRED). After that, Boost_LIBRARIES should be empty no longer, and you need to link your executable with it. Also, BOOST_ROOT variable is expected to contain installation directory of the Boost, not its include directory "/path/to/env/include". Commented Sep 7, 2018 at 7:56

1 Answer 1

1

There are a number of issues with your CMakeLists.

Linking

You haven't linked your executable against Boost, so although you will have access to the declarations of Boost functions from the headers found at ${Boost_INCLUDEDIR}, you'll see undefined references to their definitions. Hence, you need to:

target_link_libraries(logger PRIVATE ${Boost_LIBRARIES}) 

This will resolve the linking issue.

Compile Definitions

Less problematically, your usage of CMAKE_CXX_FLAGS has some issues. Using set() for CMAKE_CXX_FLAGS is deprecated, but the correct usage is:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} <value>") 

Because set() overwrites. However, the more modern way to do this would be:

target_compile_options(logger PRIVATE -g -Wall) target_compile_definitions(logger PRIVATE BOOST_LOG_DYN_LINK=true) 

This will ensure that these definitions are used only for this exectuable. Note that this step will require a relatively recent version of CMake.

Include Directories

The findBoost module exports a number of variables, one of which is ${Boost_INCLUDE_DIRS}. This variable represents the directories in which boost files are stored. Boost also looks for a variable, ${BOOST_INCLUDEDIR}, which is the path to the top-level directory of the boost headers. Currently, you're using the latter to represent the former, which should be corrected.

Sign up to request clarification or add additional context in comments.

9 Comments

Ha, now it can't find the headers. I get: fatal error: boost/fusion/iterator/equal_to.hpp: No such file or directory using the "modern" way with cmake version 3.5.2
Does "/path/to/env/include" look something like /path/to/boost/? Might try just fusion/iterator/equal_to.hpp, as the "boost" part might already be prepended. I tried compiling this on my end, but have boost installation differences that make it challenging.
@DrWatson no, it is like /path/to/env/include/boost/
Yeah, that's what I meant-- it ends in boost. So if you #include <boost/a/thing>, it will search for /path/to/env/include/boost/boost/a/thing, which is one too many boosts, I think.
I don't know, now I get fatal error: fusion/iterator/equal_to.hpp: No such file or directory - saying this, I think it still needs boost cause $BOOST_INCLUDEDIR comes w/o it - hmm, anyways, that's not it....it doesn't work either way
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.