Cmake 带有“未定义的引用”尽管找到了增强库

发布于 2025-01-11 07:20:53 字数 1183 浏览 0 评论 0原文

cmake 2.8.12 正确显示:

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

生成的 link.txt 显示 .so 文件的完整、正确路径,但每个 Boost 调用只是“在函数中...未定义对 boost 的引用...”,没有 cxx11 或 ABI 或任何其他提示。

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()'

它在旧机器上运行,例如在 32 位处理器上使用 libc-2.13.so。我昨天在盒子上编译了 boost 库,并尝试在盒子上编译它,但一无所获。我也在盒子上编译了cmake。

在这里搜索几十个问题却一无所获。关于哪里出了问题有什么建议吗?如何调查问题?

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} )

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} )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酒与心事 2025-01-18 07:20:53

我认为这

set( Boost_LIBRARY_DIR /usr/local/lib )

是错误的,并且会严重干扰 Find_Package。如果您想提供提示,请使用例如 BOOST_ROOT 如文档所述

BOOST_ROOT=~/custom/boost cmake .

这是一个有效的固定/简化的独立示例:

  • File CMakeLists.txt

     设置(PROJ_NAME my-proj)
    
     find_package(需要 Boost 1.65.0 COMPONENTS 系统线程日志 log_setup)
     设置(标题
         标题/proj.h
     )
    
     设置(来源
         src/proj.cc
     )
    
     设置(MAIN_FILE src/main.cc)
    
     if(命令 cmake_policy)
        cmake_policy(设置 CMP0003 新)
     endif(命令 cmake_policy)
    
     add_executable(${PROJ_NAME} ${SOURCES}) 
     ${HEADERS} ${MAIN_FILE})
    
     target_include_directories (${PROJ_NAME})
        公共标头
        私人的 。
        私有/usr/local/lib/
     )
    
     link_directories(${Boost_LIBRARY_DIR})
    
     target_link_libraries ( ${PROJ_NAME} -pthread ${Boost_LIBRARIES} )
    
  • 文件headers/proj.h

  • 文件src/main.cc

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

     #include ;
    
     无效 foo() {
         boost::thread_group tg;
         tg.create_thread([]{});
         tg.join_all();
     }
    

布丁的证明:

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)

注释

请注意,如果您使用太新的Boost,那么依赖关系可能不正确:

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)

在我的系统上,例如为了成功使用Boost 1.78,我必须手动添加Boost System。链接器错误:

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

修复:

target_link_libraries ( ${PROJ_NAME} boost_system )

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 )

多孤肩上扛 2025-01-18 07:20:53

我希望在这里放弃我的答案还为时不晚。

TLDR:当使用 Homebrew 或 macports 等包管理器安装 Boost 时,通常会使用 clang++ 进行编译。但在您的项目方面,可能会使用不同的编译器,从而导致链接阶段出现未定义的引用。

为了在项目中使用您想要使用的编译器,您必须使用使用相同编译器编译的 Boost 版本。要实现此目的,您可以在 Macos 上自定义 Boost 编译,如下所示:

  1. 在 Bootstrap 阶段使用:

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

  1. 安装仅包含头文件的部分,如下所示:

./b2 headers

  1. 通过添加名为的文件来自定义编译器来构建库user-config.jam 其中包含以下行:

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

  1. 按如下方式编译并安装库:

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

我希望它有帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文