Введение
Я решил использовать 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
Спасибо всем за потраченное время.