介绍
我决定将mysql作为一个自学C++的项目的一部分,因此由于缺乏知识,让我提前道歉。对我来说,链接,动态和静态库的概念仍然很新。顺便说一句,让我们继续。
我正在尝试从C++查询mysql服务器。理想情况下,我希望最终产品可以在任何架构上运行,并且对库的依赖关系尽可能少。我不希望我的代码的用户必须自己安装任何库(即Connector / C++)。我也想使用cmake来编译我的项目。
制备
为此,我将二进制文件用于
我从源代码构建了Boost,即使连接器二进制文件附带了ssl和crypto动态库,我还是使用brew来安装openssl。
CmakeLists.txt
我使用https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-apps-macos-notes.html和https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-apps-general-considerations.html#connector-cpp-apps-link-libraries作为我的CmakeLists.txt的参考
cmake_minimum_required(VERSION 3.1)
project(SQL VERSION 0.1.0)
# enable c++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(MYSQL_DIR "/usr/local/mysql-connector-c++-8.0.19")
find_package(Threads REQUIRED)
find_package(Boost REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(
${PROJECT_NAME}
PUBLIC
${MYSQL_DIR}/include
${Boost_INCLUDE_DIRS}
)
find_library(SSL_LIB NAMES ssl PATHS ${MYSQL_DIR}/lib64 NO_DEFAULT_PATH)
find_library(CRYPTO_LIB NAMES crypto PATHS ${MYSQL_DIR}/lib64 NO_DEFAULT_PATH)
find_library(MYSQL_LIBS NAMES mysqlcppconn PATHS ${MYSQL_DIR}/lib64)
target_link_libraries(${PROJECT_NAME} ${MYSQL_LIBS} ${SSL_LIB} ${CRYPTO_LIB} Threads::Threads)
C++代码
#define STATIC_CONCPP
#include <mysql/jdbc.h>
#include <iostream>
#include <vector>
#include <stdexcept>
int main(){
std::cout << "Connector/C++ standalone program example..." << '\n';
sql::Connection *con;
sql::Statement *stmt;
sql::mysql::MySQL_Driver * driver = sql::mysql::get_driver_instance();
con = driver->connect(URI, USER, PASS);
con->setSchema(EXAMPLE_DB);
stmt = con->createStatement();
sql::ResultSet *res = stmt->executeQuery("SELECT * FROM TICKERS");
std::cout << "\t... running " << "SELECT * FROM TICKERS" << "..." <<'\n';
sql::ResultSetMetaData *mtd = res->getMetaData();
while (res->next()){
std::cout << res->getString(1) <<'\t' <<res->getString(2) << '\n';
}
}
结果与问题
我使用
cmake ..; cmake --build .
构建我的项目。使用上面的内容,首先我得到了
Scanning dependencies of target SQL
[ 50%] Building CXX object CMakeFiles/SQL.dir/main.cpp.o
[100%] Linking CXX executable SQL
[100%] Built target SQL
但是,为什么我尝试运行可执行文件却得到了
dyld: Library not loaded: libssl.1.1.dylib
Referenced from: /Users/paperino/dev/cpp/learn/mysql/build/./SQL
Reason: image not found
Abort trap: 6
问题1
如果将libssl和libcrypto从
/usr/local/mysql-connector-c++-8.0.19/lib64
复制到构建文件夹,则能够运行可执行文件。即使我已经使用find_library
指定了ssl和crypto库的路径,为什么仍需要这样做呢?问题2
读这篇文章,我认为这听起来完全像我想要的。
我对CmakeLists.txt进行了以下更改
find_library(MYSQL_LIBS NAMES mysqlcppconn-static PATHS ${MYSQL_DIR}/lib64)
但是,尝试使用静态连接器库进行构建时,遇到有关丢失符号的以下错误。有什么想法为什么会发生以及如何解决?
Scanning dependencies of target SQL
[ 50%] Building CXX object CMakeFiles/SQL.dir/main.cpp.o
[100%] Linking CXX executable SQL
Undefined symbols for architecture x86_64:
"_res_9_dn_expand", referenced from:
sql::mysql::srv_list(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short&) in libmysqlcppconn-static.a(mysql_connection.cpp.o)
"_res_9_nclose", referenced from:
sql::mysql::srv_list(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short&) in libmysqlcppconn-static.a(mysql_connection.cpp.o)
"_res_9_ninit", referenced from:
sql::mysql::srv_list(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short&) in libmysqlcppconn-static.a(mysql_connection.cpp.o)
"_res_9_ns_initparse", referenced from:
sql::mysql::srv_list(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short&) in libmysqlcppconn-static.a(mysql_connection.cpp.o)
"_res_9_ns_parserr", referenced from:
sql::mysql::srv_list(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short&) in libmysqlcppconn-static.a(mysql_connection.cpp.o)
"_res_9_nsearch", referenced from:
sql::mysql::srv_list(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short&) in libmysqlcppconn-static.a(mysql_connection.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [SQL] Error 1
make[1]: *** [CMakeFiles/SQL.dir/all] Error 2
make: *** [all] Error 2
谢谢您的时间。
最佳答案
至于_res_9_dn_expand和相关的错误,您还需要链接“resolv”库。在链接器命令行中添加“-lresolv”。在阅读其余内容之前,请先尝试一下。
正确地说,如果要构建应用程序以使不需要其他文件,则必须链接到MySQL的静态库以及MySQL所需的所有静态库。为了正确链接,您将需要使用与构建MySQL库相同的OpenSSL库。
有两条路可走。要么获得与MySQL用于构建其现成库的OpenSSL静态库相同的版本,要么使用您拥有的OpenSSL版本再次编译MySQL库。
只是为了增加混乱,我上次执行此操作时,MySQL C++ Connector取决于MySQL运行时“C”库。我相信这就是OpenSSL发挥作用的地方。因此,如果您采用“重新编译所有内容”的方法,则可能不仅需要C++连接器,还需要重新编译。
关于c++ - 在MacOS Catalina上使用CMake编译/链接mysql-connector-c++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60749953/