链接 cxx 可执行文件时出现 Cmake 错误未定义引用

Posted

技术标签:

【中文标题】链接 cxx 可执行文件时出现 Cmake 错误未定义引用【英文标题】:Cmake Error undefined reference when linking cxx executable 【发布时间】:2021-10-29 09:31:54 【问题描述】:

在我的 C++ Cmake 项目中,我最近不得不包含 mariadb c++ 连接器。 (我是 cmake 初学者)。

想法是根据这个 mariadb 连接器创建和安装我自己的库(例如:libnt)并将它们用于另一个程序。

所以我在根目录下创建了一个 ma​​in.cpp 来测试它。

项目结构如下:

--Libnt (root)
    |
     --- build
    |
     --- nt
    |     |
    |     --- include
    |     |      |
    |     |       --- nt
    |     |            |---log.h
    |     |            |---dcs.h
    |     |            |---db.h
    |     | 
    |     --- src
    |     |    |---log.cpp
    |     |    |---dcs.cpp
    |     |    |---db.cpp
    |     |
    |     --- thirdparty
    |     |       |-- restc-cpp
    |     |
    |     --- CMakeLists.txt
    |
    |--- CmakeLists.txt 
    |--- main.cpp

    

我按照documentation做了mariadb安装

cmake.. && make 时,我确实有以下错误,我真的不知道如何处理它。

[100%] Linking CXX executable trylib
/usr/bin/ld : avertissement : libmariadb.so.3, requis par /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so, non trouvé (essayez avec -rpath ou -rpath-link)
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_fetch_field_direct@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_num_rows@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_reset_connection@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_fetch_lengths@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_close@libmysqlclient_18 »

有人可以帮我吗?

问候,


CMakeLists.txt(根)

cmake_minimum_required(VERSION 3.0.0)

project(Calculator_Project VERSION 1.0.0)

set (CMAKE_CXX_STANDARD 14)
set(CMAKE_MODULE_PATH $CMAKE_MODULE_PATH "$CMAKE_CURRENT_SOURCE_DIR/cmake")

add_subdirectory(my_math)
add_subdirectory(my_print)
add_subdirectory(nt)
add_executable(trylib main.cpp)
target_link_libraries(trylib PRIVATE my_math  my_print nt)

message("CMAKE_INSTALL_PREFIX = $CMAKE_INSTALL_PREFIX")

CMakeLists.txt

set (CMAKE_CXX_STANDARD 14)
set(CMAKE_MODULE_PATH $CMAKE_MODULE_PATH "$CMAKE_CURRENT_SOURCE_DIR/cmake")

find_package(GTest REQUIRED)
include_directories($GTEST_INCLUDE_DIRS)

message($CMAKE_CURRENT_LIST_DIR/thirdparty/restc-cpp/include)
include_directories($CMAKE_CURRENT_LIST_DIR/thirdparty/restc-cpp/include)

set(Boost_USE_STATIC_LIBS        ON)  # only find static libs
set(Boost_USE_DEBUG_LIBS         OFF) # ignore debug libs and 
set(Boost_USE_RELEASE_LIBS       ON)  # only find release libs 
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF) 
find_package(Boost 1.71.0 COMPONENTS system iostreams asio program_options filesystem date_time context coroutine coroutines chrono log)
if(Boost_FOUND)   
    include_directories($Boost_INCLUDE_DIRS)   
endif()

find_package(Threads REQUIRED)

find_library(restc-cpp_location NAMES libnamespacetest.a librestc-cpp.a)
message(STATUS $restc-cpp_location0)

add_library(restc-cpp STATIC IMPORTED)
set_target_properties(restc-cpp PROPERTIES IMPORTED_LOCATION $restc-cpp_location)

#[[
    LIBNT
]]#

add_library(nt src/log.cpp src/dcs.cpp src/db.cpp)

target_link_libraries(nt PRIVATE Threads::Threads restc-cpp mariadbcpp ssl crypto z boost_iostreams boost_log $Boost_LIBRARIES)

target_include_directories( nt PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:$CMAKE_CURRENT_SOURCE_DIR/include>
)

install(FILES   $CMAKE_CURRENT_SOURCE_DIR/include/nt/log.h 
                $CMAKE_CURRENT_SOURCE_DIR/include/nt/dcs.h 
                $CMAKE_CURRENT_SOURCE_DIR/include/nt/db.h 
        DESTINATION $CMAKE_INSTALL_PREFIX/include/nt)

install(TARGETS nt EXPORT my_export DESTINATION $CMAKE_INSTALL_PREFIX/lib/nt)
install(EXPORT my_export FILE nt-config.cmake DESTINATION $CMAKE_INSTALL_PREFIX/lib/nt)

这是完整的跟踪:

-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.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
-- Found GTest: /usr/lib/x86_64-linux-gnu/libgtest.a  
/home/pierre/Documents/Git/Libnt/nt/thirdparty/restc-cpp/include
-- Could NOT find Boost: missing: asio coroutines (found /usr/local/lib/cmake/Boost-1.77.0/BoostConfig.cmake (found suitable version "1.77.0", minimum required is "1.71.0"))
-- Found Threads: TRUE  
-- 
CMAKE_INSTALL_PREFIX = /usr/local
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pierre/Documents/Git/Libnt/build
[  9%] Building CXX object nt/CMakeFiles/nt.dir/src/log.cpp.o
[ 18%] Building CXX object nt/CMakeFiles/nt.dir/src/dcs.cpp.o
[ 27%] Building CXX object nt/CMakeFiles/nt.dir/src/db.cpp.o
[ 36%] Linking CXX static library libnt.a
[ 36%] Built target nt
[ 45%] Building CXX object my_print/CMakeFiles/my_print.dir/src/print_result.cpp.o
[ 54%] Linking CXX static library libmy_print.a
[ 54%] Built target my_print
[ 63%] Building CXX object my_math/CMakeFiles/my_math.dir/src/addition.cpp.o
[ 72%] Building CXX object my_math/CMakeFiles/my_math.dir/src/division.cpp.o
[ 81%] Linking CXX static library libmy_math.a
[ 81%] Built target my_math
[ 90%] Building CXX object CMakeFiles/trylib.dir/main.cpp.o
/home/pierre/Documents/Git/Libnt/main.cpp:10:6: warning: ISO C++ forbids declaration of ‘main’ with no type [-Wreturn-type]
   10 | main()
      |      ^
[100%] Linking CXX executable trylib
/usr/bin/ld : avertissement : libmariadb.so.3, requis par /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so, non trouvé (essayez avec -rpath ou -rpath-link)
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_fetch_field_direct@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_num_rows@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_reset_connection@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_fetch_lengths@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_close@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_field_count@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_error@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_send_long_data@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_store_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_select_db@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_error@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_next_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mariadb_get_infov@libmariadb_3 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_sqlstate@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_real_connect@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_get_server_info@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_insert_id@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_fetch_row@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_init@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_next_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_fetch_field@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_data_seek@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_thread_id@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mariadb_get_charset_by_nr@libmariadb_3 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_execute@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_session_track_get_first@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_init@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_warning_count@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_param_count@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_insert_id@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_ping@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_errno@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_data_seek@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_optionsv@libmariadb_3 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_close@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_get_socket@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_use_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_free_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_field_count@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_store_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_errno@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_bind_result@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_warning_count@libmariadb_3 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_bind_param@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_sqlstate@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_attr_set@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_real_query@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_prepare@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mariadb_reconnect@libmariadb_3 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_affected_rows@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_result_metadata@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_fetch@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_num_rows@libmysqlclient_18 »
/usr/bin/ld : /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so : référence indéfinie vers « mysql_stmt_affected_rows@libmysqlclient_18 »
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/trylib.dir/build.make:113 : trylib] Erreur 1
make[1]: *** [CMakeFiles/Makefile2:138 : CMakeFiles/trylib.dir/all] Erreur 2
make: *** [Makefile:136 : all] Erreur 2

【问题讨论】:

日志中的第一个错误/usr/bin/ld : avertissement : libmariadb.so.3, requis par /usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libmariadbcpp.so, non trouvé (essayez avec -rpath ou -rpath-link)。据我所知,该错误意味着找不到libmariadb.so.3 你也需要链接libmysqlclient。使用命令“ldd libmariadb.so”,您可以查看 libmariadb.so 需要哪些库并将它们包含在 cmake 中。 【参考方案1】:

谢谢nayab 和Tsyvarev。现在一切正常! 对不起,我缺乏经验。

ldd libmariadbcpp.so 之后,我有

linux-vdso.so.1 (0x00007ffe609ca000)
    libmariadb.so.3 => not found
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f866ec91000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f866ec76000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f866ea84000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f866e935000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f866f02e000)

我不得不做一个sudo apt install libmariadb-dev,ldd 命令变成了

~/Documents/Git/Libnt/nt/thirdparty/mariadb-connector-cpp-1.0.1-ubuntu-focal-amd64/lib64/mariadb$ ldd libmariadbcpp.so 
    linux-vdso.so.1 (0x00007ffda61d1000)
    libmariadb.so.3 => /lib/x86_64-linux-gnu/libmariadb.so.3 (0x00007f326f47d000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f326f29b000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f326f280000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f326f08e000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f326f088000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f326f065000)
    libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007f326ee8d000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f326ee71000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f326ed22000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f326f68f000)
    libp11-kit.so.0 => /lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007f326ebec000)
    libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007f326ebcb000)
    libunistring.so.2 => /lib/x86_64-linux-gnu/libunistring.so.2 (0x00007f326ea49000)
    libtasn1.so.6 => /lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007f326ea31000)
    libnettle.so.7 => /lib/x86_64-linux-gnu/libnettle.so.7 (0x00007f326e9f7000)
    libhogweed.so.5 => /lib/x86_64-linux-gnu/libhogweed.so.5 (0x00007f326e9c0000)
    libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f326e93c000)
    libffi.so.7 => /lib/x86_64-linux-gnu/libffi.so.7 (0x00007f326e930000)

【讨论】:

以上是关于链接 cxx 可执行文件时出现 Cmake 错误未定义引用的主要内容,如果未能解决你的问题,请参考以下文章

在运行时动态加载库时出现“未解析的外部符号”错误

在 gcloud 上部署烧瓶应用程序时出现“找不到 CMAKE_CXX_COMPILER”错误

CMake 未启用异常

在 CMake 中添加多个可执行文件

使用 Cmake 文件在 Visual Studio 中构建 Qt 项目时出现链接错误

将 16 位实模式代码链接到符合 Multiboot 的 ELF 可执行文件时出现 LD 错误