Компиляция / связывание mysql -connector-c ++ с CMake на MacOS Catalina - PullRequest
1 голос
/ 19 марта 2020

Введение

Я решил использовать mysql как часть проекта, чтобы научить себя C ++, поэтому позвольте мне заранее извиниться за отсутствие знаний. Концепция компоновки, динамические c и stati c библиотеки все еще очень новы для меня. С этим из пути, давайте продолжим.

Я пытаюсь запросить сервер mysql из C ++. В идеале мне бы хотелось, чтобы конечный продукт работал на любой архитектуре с минимальным количеством зависимостей от библиотек. Я не хочу, чтобы пользователь моего кода сам устанавливал какие-либо библиотеки (например, Connector / C ++). Я также хочу использовать cmake для компиляции моего проекта.

Подготовка

Для этого я использовал двоичные файлы для

  • mysql -connector-c ++ - 8.0.19-macos10.15-x86-64bit
  • mysql -8.0.19-macos10.15-x86_64 (wasn ' Я не уверен, было ли это необходимо, но в документации mysql говорится, что для подключения к серверу JDB C требуется mysql -клиент, поставляемый с mysqlserver)

Я собрал Boost из исходного кода, и я использовал brew для установки openssl, хотя библиотеки ssl и crypto dynamici c поставлялись с двоичным соединителем.

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-library в качестве ссылки для моего 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 ++ Code

#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

Question1

Если я копирую libssl и libcrypto из /usr/local/mysql-connector-c++-8.0.19/lib64 в папку сборки, тогда я смогу запустить исполняемый файл. Почему это необходимо, хотя я указал пути к библиотекам ssl и crypto, используя find_library?

Question2

Возможно связать ваше приложение с Connector / C ++ статическая библиотека. Таким образом, нет никакой зависимости во время выполнения от соединителя, и полученный двоичный файл может работать на системах, где Connector / C ++ не установлен.

Читая это, я думал, что это звучит точно как то, что я хочу. Я внес следующие изменения в мой CmakeLists.txt find_library(MYSQL_LIBS NAMES mysqlcppconn-static PATHS ${MYSQL_DIR}/lib64) Однако, пытаясь собрать библиотеку соединителей stati c, я получаю следующие ошибки об отсутствующих символах. Есть идеи, почему это происходит и как это исправить?

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

Спасибо всем за потраченное время.

...