gpt4 book ai didi

c++ - 在 MacOS Catalina 上使用 CMake 编译/链接 mysql-connector-c++

转载 作者:行者123 更新时间:2023-12-02 10:34:52 42 4
gpt4 key购买 nike

介绍

我决定使用 mysql 作为项目的一部分来自学 C++,所以让我为缺乏知识提前道歉。链接、动态和静态库的概念对我来说还是很新的。有了这个,让我们继续吧。

我正在尝试从 C++ 查询 mysql 服务器。理想情况下,我希望最终产品能够在任何架构上运行,并且尽可能少地依赖库。我不希望我的代码的用户必须自己安装任何库(即连接器/C++)。我也想使用 cmake 来编译我的项目。

准备

为了做到这一点,我使用二进制文件

  • mysql-connector-c++-8.0.19-macos10.15-x86-64bit
  • mysql-8.0.19-macos10.15-x86_64(不确定这是否必要,但mysql文档说使用JDBC连接服务器需要mysqlserver附带的mysql-client)

  • 我从源代码构建了 Boost,并使用 brew 来安装 openssl,即使连接器二进制文件附带了 ssl 和加密动态库。

    CmakeLists.txt

    我用了 https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-apps-macos-notes.htmlhttps://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

    如果我从 /usr/local/mysql-connector-c++-8.0.19/lib64 复制 libssl 和 libcrypto到我的构建文件夹然后我是 能跑可执行文件。为什么这是必要的,即使我已经使用 find_library 指定了 ssl 和加密库的路径?

    问题2

    It is possible to link your application with the Connector/C++ static library. This way there is no runtime dependency on the connector, and the resulting binary can run on systems where Connector/C++ is not installed.



    读到这里,我觉得这听起来和我想要的完全一样。

    我对我的 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++ 连接器依赖于 MySQL 运行时“C”库。我相信这就是 OpenSSL 发挥作用的地方。因此,如果您走“重新编译所有内容”的路线,您可能需要重新编译的不仅仅是 C++ 连接器。

    关于c++ - 在 MacOS Catalina 上使用 CMake 编译/链接 mysql-connector-c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60749953/

    42 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com