1

cmake 2.8.12 correctly shows:

Boost version: 1.56.0
Found the following Boost libraries:
  system
  thread
  log
  log_setup

And the generated link.txt shows full, correct path to the .so files, but every Boost call is simply "In function...undefined reference to boost..." with no cxx11 or ABI or any other hints.

CMakeFiles/proj.dir/src/proj.cc.o: In function `proj::init()':

/code/proj/src/proj.cc:31: undefined reference to `boost::log::v2s_mt_posix::core::get()'

This is running on an old box, for example using libc-2.13.so on a 32bit processor. I compiled the boost libraries on the box yesterday and am trying to compile this on the box but am getting nowhere. I compiled cmake on the box as well.

Searching dozens of questions here has gotten me nowhere. Any suggestions on what is wrong? How to investigate the issue?

set(PROJ_NAME my-proj)

set(HEADERS
    headers/proj.h
)

set(SOURCES
    src/proj.cc
)

set(MAIN_FILE src/main.cc)

if(COMMAND cmake_policy)
   cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)

add_executable (${PROJ_NAME} ${SOURCES} 
${HEADERS} ${MAIN_FILE})

target_include_directories ( ${PROJ_NAME}
   PUBLIC headers
   PRIVATE .
   PRIVATE /usr/local/lib/
)

set( Boost_LIBRARY_DIR /usr/local/lib )
find_package(Boost COMPONENTS system thread log log_setup REQUIRED)
link_directories(${Boost_LIBRARY_DIR})

target_link_libraries ( ${PROJ_NAME} -pthread ${Boost_LIBRARIES} )
user2725742
  • 398
  • 2
  • 12
  • *Finding* the Boost libraries does not automatically *link* them. You'd need to show a [mcve] including a CMakeLists.txt for us to tell you if you might be missing an instruction or two, along the lines of `target_link_libraries( MyTarget ${Boost_LIBRARIES} )`. Also, the CMake version you are using is old as dust. You might want to upgrade.... – DevSolar Mar 03 '22 at 14:07
  • Got your minimum example. I am following the structure of dozens of other cmake files in my other project so hopefully no issues. I added the policy thing because cmake suggested it, due to having to search for boost_system. But the link.txt output shows the full, correct path. – user2725742 Mar 03 '22 at 14:35
  • Please. add **exact error message** to the question post. If there are many errors, then show at least the very first of them. – Tsyvarev Mar 03 '22 at 16:38
  • Many errors, all like the one I just added. – user2725742 Mar 03 '22 at 16:55
  • 1
    "This is running on an old box" - Do you use **old tools**? What is version of CMake? Version of Boost? Version of compiler? Do you use the **same compiler** for your project and for the Boost? Run building with `make VERBOSE=1`: it will print exact command lines executed. Add to the question post the **linker's command line** (which causes the error). Setting `set( Boost_LIBRARY_DIR /usr/local/lib )` smells: Normally, `find_package` should check this directory by default. – Tsyvarev Mar 03 '22 at 17:45

2 Answers2

0

I think that

set( Boost_LIBRARY_DIR /usr/local/lib )

is wrong and interferes badly with Find_Package. If you want to provide a hint, use e.g. BOOST_ROOT as documented:

BOOST_ROOT=~/custom/boost cmake .

Here's a fixed-up / simplified self-contained example that works:

  • File CMakeLists.txt

     set(PROJ_NAME my-proj)
    
     find_package(Boost 1.65.0 COMPONENTS system thread log log_setup REQUIRED)
     set(HEADERS
         headers/proj.h
     )
    
     set(SOURCES
         src/proj.cc
     )
    
     set(MAIN_FILE src/main.cc)
    
     if(COMMAND cmake_policy)
        cmake_policy(SET CMP0003 NEW)
     endif(COMMAND cmake_policy)
    
     add_executable (${PROJ_NAME} ${SOURCES} 
     ${HEADERS} ${MAIN_FILE})
    
     target_include_directories ( ${PROJ_NAME}
        PUBLIC headers
        PRIVATE .
        PRIVATE /usr/local/lib/
     )
    
     link_directories(${Boost_LIBRARY_DIR})
    
     target_link_libraries ( ${PROJ_NAME} -pthread ${Boost_LIBRARIES} )
    
  • File headers/proj.h

  • File src/main.cc

     int main() {
     }
    
  • File src/proj.cc

     #include <boost/thread.hpp>
    
     void foo() {
         boost::thread_group tg;
         tg.create_thread([]{});
         tg.join_all();
     }
    

Proof of the pudding:

cmake .
CMake Warning (dev) in CMakeLists.txt:
  No project() command is present.  The top-level CMakeLists.txt file must
  contain a literal, direct call to the project() command.  Add a line of
  code such as

    project(ProjectName)

  near the top of the file, but after cmake_minimum_required().

  CMake is pretending there is a "project(Project)" command on the first
  line.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Found Boost: /usr/include (found suitable version "1.65.1", minimum required is "1.65.0") found components: system thread log log_setup chrono date_time atomic filesystem regex 
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.22)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/q
 sehe  /  tmp  q  make
[ 66%] Building CXX object CMakeFiles/my-proj.dir/src/proj.o
[ 66%] Building CXX object CMakeFiles/my-proj.dir/src/main.o
[100%] Linking CXX executable my-proj
[100%] Built target my-proj
 sehe  /  tmp  q  ldd my-proj 
    linux-vdso.so.1 (0x00007ffd917e4000)
    libboost_system.so.1.65.1 => /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 (0x00007f40c25bd000)
    libboost_thread.so.1.65.1 => /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 (0x00007f40c2398000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f40c2179000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f40c1d6c000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f40c1b54000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f40c1763000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f40c155b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f40c29e7000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f40c11bd000)

NOTES

Note that if you use a too-recent boost then maybe the dependencies might be incorrect:

CMake Warning at /usr/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/share/cmake-3.22/Modules/FindBoost.cmake:1492 (_Boost_COMPONENT_DEPENDENCIES)
  /usr/share/cmake-3.22/Modules/FindBoost.cmake:2102 (_Boost_MISSING_DEPENDENCIES)
  CMakeLists.txt:5 (find_package)

On my system, e.g. in order to use Boost 1.78 successfully, I have to add Boost System manually. Linker errors:

make
[ 33%] Building CXX object CMakeFiles/my-proj.dir/src/proj.o
[ 66%] Building CXX object CMakeFiles/my-proj.dir/src/main.o
[100%] Linking CXX executable my-proj
CMakeFiles/my-proj.dir/src/proj.o: In function `__static_initialization_and_destruction_0(int, int)':
proj.cc:(.text+0x6a1): undefined reference to `boost::system::generic_category()'
proj.cc:(.text+0x6ad): undefined reference to `boost::system::generic_category()'
proj.cc:(.text+0x6b9): undefined reference to `boost::system::system_category()'
CMakeFiles/my-proj.dir/src/proj.o: In function `boost::system::error_category::std_category::equivalent(int, std::error_condition const&) const':
proj.cc:(.text._ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition[_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition]+0xb8): undefined reference to `boost::system::generic_category()'
proj.cc:(.text._ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition[_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition]+0xf3): undefined reference to `boost::system::generic_category()'
CMakeFiles/my-proj.dir/src/proj.o: In function `boost::system::error_category::std_category::equivalent(std::error_code const&, int) const':
proj.cc:(.text._ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0xb8): undefined reference to `boost::system::generic_category()'
proj.cc:(.text._ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0xf3): undefined reference to `boost::system::generic_category()'
proj.cc:(.text._ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0x1d2): undefined reference to `boost::system::generic_category()'
CMakeFiles/my-proj.dir/src/proj.o:proj.cc:(.text._ZN5boost16thread_exceptionC2EiPKc[_ZN5boost16thread_exceptionC5EiPKc]+0x28): more undefined references to `boost::system::generic_category()' follow
collect2: error: ld returned 1 exit status
CMakeFiles/my-proj.dir/build.make:121: recipe for target 'my-proj' failed
make[2]: *** [my-proj] Error 1
CMakeFiles/Makefile2:82: recipe for target 'CMakeFiles/my-proj.dir/all' failed
make[1]: *** [CMakeFiles/my-proj.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2

Fix:

target_link_libraries ( ${PROJ_NAME} boost_system )

sehe
  • 374,641
  • 47
  • 450
  • 633
0

I hope that it is not too late to drop my answer here.

TLDR: When Boost is installed using package managers such as Homebrew or macports often it is compiled using clang++. But on your project side, one might be using a different compiler, leading to undefined references in the linkage stage.

In order to use the compiler that you want to use in your project, you will have to use a version of Boost compiled with the same compiler. to achieve this you can customize Boost compilation on macos as follows:

  1. In the Bootstrap stage use:

./bootstrap.sh --prefix=/usr/local/Cellar/boost_gcc --with-toolset=gcc --without-libraries=python,mpi

  1. Install the headers-only part as follows:

./b2 headers

  1. Customize the compiler to build the libraries by adding a file named user-config.jam with the following line in it:

using gcc : : /usr/local/bin/g++-11 ;

  1. Compile and install the library as follows:

./b2 -d2 -j12 --layout=tagged-1.66 --user-config=user-config.jam install threading=multi,single link=shared,static

I hope that it helps.

user3116936
  • 492
  • 3
  • 21