使用CMake构建C++数据库程序时遇mariadb-connector-c链接错误求助
链接Mariadb Connector C时的CMake链接错误排查与解决
问题背景
学习C++和CMake时,构建连接数据库的程序执行cmake --build .出现链接错误,提示mysql_init等函数未定义。
错误信息
$cmake ../src ... $cmake --build . Scanning dependencies of target MYSQL_CPP [ 50%] Building CXX object CMakeFiles/MYSQL_CPP.dir/main.cxx.o [100%] Linking CXX executable MYSQL_CPP CMakeFiles/MYSQL_CPP.dir/main.cxx.o: In function `main': main.cxx:(.text+0x7b): undefined reference to `mysql_init' main.cxx:(.text+0x8f): undefined reference to `mysql_error' main.cxx:(.text+0x104): undefined reference to `mysql_real_connect' collect2: ld returned 1 exit status gmake[2]: *** [MYSQL_CPP] Error 1 gmake[1]: *** [CMakeFiles/MYSQL_CPP.dir/all] Error 2 gmake: *** [all] Error 2
文件结构
. |-- bin `-- src |-- CMakeLists.txt |-- lib | `-- gcc-4.1.2 | `-- mariadb-connector-c-3.0.9 | |-- bin | | `-- mariadb_config | |-- include | | `-- mariadb | | |-- errmsg.h | | |-- ma_list.h | | |-- ma_pvio.h | | |-- ma_tls.h | | |-- mariadb | | | `-- ma_io.h | | |-- mariadb_com.h | | |-- mariadb_ctype.h | | |-- mariadb_dyncol.h | | |-- mariadb_stmt.h | | |-- mariadb_version.h | | |-- mysql | | | |-- client_plugin.h | | | |-- plugin_auth.h | | | `-- plugin_auth_common.h | | |-- mysql.h | | `-- mysqld_error.h | `-- lib | |-- mariadb | | |-- libmariadb.so -> libmariadb.so.3 | | |-- libmariadb.so.3 | | |-- libmariadbclient.a | | |-- libmariadbclient_static.a | | `-- plugin | | |-- auth_gssapi_client.so | | |-- caching_sha2_password.so | | |-- dialog.so | | |-- mysql_clear_password.so | | |-- remote_io.so | | `-- sha256_password.so | `-- pkgconfig | `-- libmariadb.pc `-- main.cxx
当前CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2) # set the project name project(CRUD_CPP) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib/gcc-4.1.2/mariadb-connector-c-3.0.9/include/) LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib/gcc-4.1.2/mariadb-connector-c-3.0.9/lib/mariadb/) add_executable(CRUD_CPP main.cxx)
main.cxx代码
#include<iostream> #include<mariadb/mysql.h> #include<mariadb/errmsg.h> const char *host = "XXX"; const char *user = "XXX"; const char *pwd = "XXX"; const char *db = "XX"; const int port = XX; int main(){ MYSQL *mysql = mysql_init(NULL); if(mysql==NULL){ std::cout << "Eror:" << mysql_error(mysql) << std::endl; return 1; } mysql = mysql_real_connect(mysql, host, user, pwd, db, port, NULL, 0); //connect if(mysql){ std::cout << "Success!" << std::endl; } else std::cout << "Failed!" << std::endl; return 0; }
解决方案
链接错误的核心原因是只指定了库的搜索路径,但没有明确告诉CMake需要链接哪个Mariadb库。修改CMakeLists.txt,添加链接库的指令即可解决:
修改后的CMakeLists.txt(推荐写法)
cmake_minimum_required(VERSION 3.0.2) project(CRUD_CPP) # 指定头文件目录 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib/gcc-4.1.2/mariadb-connector-c-3.0.9/include/) # 指定库文件搜索目录 LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib/gcc-4.1.2/mariadb-connector-c-3.0.9/lib/mariadb/) add_executable(CRUD_CPP main.cxx) # 链接Mariadb库,CMake自动匹配对应动态/静态库文件 target_link_libraries(CRUD_CPP mariadb)
额外注意事项
- 如果需要使用静态库
libmariadbclient_static.a,需确保链接所有依赖系统库。可通过执行以下命令获取完整链接参数:
输出类似./src/lib/gcc-4.1.2/mariadb-connector-c-3.0.9/bin/mariadb_config --libs-L/path/to/lib -lmariadb -lpthread -ldl -lm -lssl -lcrypto,将这些参数转换为CMake的target_link_libraries指令即可。 - 确保编译器架构与Mariadb Connector的架构一致(均为32位或64位),否则会出现链接错误。
内容的提问来源于stack exchange,提问作者James Maxwell
相关产品推荐
相关产品推荐

