Boost.Log with CMake causing undefined reference error
Asked Answered
V

3

25

I am trying to use the new Boost.Log library in a project I am working on. The project is built with CMake. I am receiving link errors claiming that the linker has come across undefined references to Boost.Log

Linking CXX executable main
CMakeFiles/main.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x30): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'

I have a simple hello world test that fails with these errors. If I am linking against the Boost.Log libraries what would cause it to generate an undefined reference error?

main.cpp:

#include <boost/log/trivial.hpp>
int main(int argc, char* const argv[]) {
  BOOST_LOG_TRIVIAL(info) << "Hello World";
}

CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE(Boost 1.54 COMPONENTS log REQUIRED)
FIND_PACKAGE(Threads)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_EXECUTABLE(main main.cpp)
TARGET_LINK_LIBRARIES(main ${Boost_LOG_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})

Edit: verbose output from cmake and make

cmake:

-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:476 ] _boost_TEST_VERSIONS = 1.56.0;1.56;1.55.0;1.55;1.54.0;1.54
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:478 ] Boost_USE_MULTITHREADED = TRUE
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:480 ] Boost_USE_STATIC_LIBS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:482 ] Boost_USE_STATIC_RUNTIME = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:484 ] Boost_ADDITIONAL_VERSIONS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:486 ] Boost_NO_SYSTEM_PATHS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:538 ] Declared as CMake or Environmental Variables:
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:540 ]   BOOST_ROOT = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:542 ]   BOOST_INCLUDEDIR = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:544 ]   BOOST_LIBRARYDIR = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:546 ] _boost_TEST_VERSIONS = 1.56.0;1.56;1.55.0;1.55;1.54.0;1.54
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:639 ] location of version.hpp: /usr/include/boost/version.hpp
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:663 ] version.hpp reveals boost 1.54.0
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:739 ] guessed _boost_COMPILER = -gcc48
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:749 ] _boost_MULTITHREADED = -mt
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:792 ] _boost_RELEASE_ABI_TAG = -
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:794 ] _boost_DEBUG_ABI_TAG = -d
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:842 ] _boost_LIBRARY_SEARCH_DIRS = /usr/lib64;NO_DEFAULT_PATH
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:930 ] Searching for LOG_LIBRARY_RELEASE: boost_log-gcc48-mt-1_54;boost_log-gcc48-mt;boost_log-mt-1_54;boost_log-mt;boost_log
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:966 ] Searching for LOG_LIBRARY_DEBUG: boost_log-gcc48-mt-d-1_54;boost_log-gcc48-mt-d;boost_log-mt-d-1_54;boost_log-mt-d;boost_log-mt;boost_log
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:1017 ] Boost_FOUND = 1
-- Boost version: 1.54.0
-- Found the following Boost libraries:
--   log
-- Configuring done
-- Generating done
-- Build files have been written to: /home/durrw/boost-log-test/build

make:

/usr/bin/cmake -H/home/durrw/boost-log-test -B/home/durrw/boost-log-test/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/durrw/boost-log-test/build/CMakeFiles /home/durrw/boost-log-test/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/durrw/boost-log-test/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/depend
make[2]: Entering directory `/home/durrw/boost-log-test/build'
cd /home/durrw/boost-log-test/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/durrw/boost-log-test /home/durrw/boost-log-test /home/durrw/boost-log-test/build /home/durrw/boost-log-test/build /home/durrw/boost-log-test/build/CMakeFiles/main.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/durrw/boost-log-test/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/build
make[2]: Entering directory `/home/durrw/boost-log-test/build'
Linking CXX executable main
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/usr/bin/c++       CMakeFiles/main.dir/main.cpp.o  -o main -rdynamic -lboost_log -lpthread 
CMakeFiles/main.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x39): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
Vorlage answered 24/7, 2013 at 20:20 Comment(2)
If you run cmake . -DBoost_DEBUG=1 and also make VERBOSE=1 you'll get a lot more info about what CMake is doing and what the actual linker command is. Feel free to add the output of these to your question to get more help.Bluebell
The debug output was useful, but still doesn't seem to help as it is linking against boost_logVorlage
B
36

It looks like it boils down to linking to the shared version of Boost.Log.

There is a bit of detail on the issue in the docs for Boost.Log Your error message mentions the namespace boost::log::v2s_mt_posix and from the docs, this implies the linker is expecting to link to a static version of Boost.Log.

If you want to link to the shared version, it seems you need to define BOOST_LOG_DYN_LINK or BOOST_ALL_DYN_LINK, i.e. in your CMakeLists.txt add:

ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)

If you want to link to the static version of Boost.Log, instead you need to add a CMake variable before calling FIND_PACKAGE(Boost ...):

SET(Boost_USE_STATIC_LIBS ON)
FIND_PACKAGE(Boost 1.54 COMPONENTS log REQUIRED)

For further variables which affect how CMake finds Boost, see the docs for FindBoost.

Bluebell answered 25/7, 2013 at 21:19 Comment(1)
Needed to add ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) to my CMakeLists.txt files. Also I am new to CMake and didn't realize that things are not carried over to CMakeLists.txt files in subfolders. Thought I could add it to the CMakeLists.txt file in the root folder and have it applied to all subfolders. However, I discovered this is not how CMake works.Vorlage
B
1

For CMake 3.15 (and some earlier versions) the following appears to be sufficient to build Boost.Log with CMake without the original linker error:

cmake_minimum_required(VERSION 3.15)
project(boost_log_tutorial)

SET(Boost_USE_STATIC_LIBS ON)           # link statically
#ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)  # or, link dynamically

find_package(Boost 1.69.0 COMPONENTS log REQUIRED)

add_executable(boost_log_tutorial main.cpp)
target_link_libraries(boost_log_tutorial Boost::log_setup Boost::log)

The key things seem to be linking against Boost:log_setup and Boost::log, and specifying either static or dynamic linking with SET(Boost_USE_STATIC_LIBS ON) or ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK).

Also, make sure that the build type (Debug, or Release) for Conan matches the build type for CMake. For example:

$ conan install -s build_type=Debug ..
$ cmake -DCMAKE_BUILD_TYPE=Debug ..

If they mismatch then the link will fail with the same error.

Bowen answered 1/10, 2019 at 21:35 Comment(0)
J
0

It is Boost_INCLUDE_DIRS not Boost_INCLUDE_DIR.

You could try enable Boost_USE_STATIC_LIBS

Jaquith answered 24/7, 2013 at 20:52 Comment(3)
According to the docs for FindBoost, it looks like either variable is now valid. Also, if that was wrong, wouldn't it result in a compiler error rather than a linker one?Bluebell
Boost_INCLUDE_DIR support was added in CMake 2.8.11, and really can't be used unless you enforce a CMake version check.Jaquith
Ah - OK. Still, there'd be a compiler problem with the C++ #include call if that was wrong wouldn't there?Bluebell

© 2022 - 2024 — McMap. All rights reserved.