Dep/MySQL: Move required version checks to CMake, raise required version to 8.0.34 and remove strict compiled<->runtime version match requirement from non-Windows platforms

This commit is contained in:
Shauren
2025-08-30 19:25:47 +02:00
parent 4124068c47
commit b386971229
4 changed files with 112 additions and 69 deletions

View File

@@ -40,6 +40,10 @@ This module will set the following variables in your project:
MySQL library.
``MYSQL_EXECUTABLE``
Path to mysql client binary.
``MYSQL_FLAVOR``
Flavor of mysql installation (MySQL or MariaDB).
``MYSQL_VERSION``
MySQL version string.
Hints
^^^^^
@@ -47,6 +51,8 @@ Hints
Set ``MYSQL_ROOT_DIR`` to the root directory of MySQL installation.
#]=======================================================================]
include(FindPackageHandleStandardArgs)
set(MYSQL_FOUND 0)
set(_MYSQL_ROOT_HINTS
@@ -219,30 +225,16 @@ endif(WIN32)
# On Windows you typically don't need to include any extra libraries
# to build MYSQL stuff.
if(NOT WIN32)
find_library(MYSQL_EXTRA_LIBRARIES
NAMES
z zlib
PATHS
/usr/lib
/usr/local/lib
DOC
"if more libraries are necessary to link in a MySQL client (typically zlib), specify them here."
)
else(NOT WIN32)
set(MYSQL_EXTRA_LIBRARIES "")
endif(NOT WIN32)
if(UNIX)
find_program(MYSQL_EXECUTABLE mysql
PATHS
${MYSQL_CONFIG_PREFER_PATH}
/usr/local/mysql/bin/
/usr/local/bin/
/usr/bin/
DOC
"path to your mysql binary."
)
find_program(MYSQL_EXECUTABLE mysql
PATHS
${MYSQL_CONFIG_PREFER_PATH}
/usr/local/mysql/bin/
/usr/local/bin/
/usr/bin/
DOC
"path to your mysql binary."
)
endif(UNIX)
if(WIN32)
@@ -291,7 +283,6 @@ foreach(_comp IN LISTS MySQL_FIND_COMPONENTS)
endforeach()
unset(_comp)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MySQL
REQUIRED_VARS
${MYSQL_REQUIRED_VARS}
@@ -301,25 +292,37 @@ find_package_handle_standard_args(MySQL
)
unset(MYSQL_REQUIRED_VARS)
if(MYSQL_FOUND)
if(MySQL_lib_WANTED AND MySQL_lib_FOUND)
message(STATUS "Found MySQL library: ${MYSQL_LIBRARY}")
message(STATUS "Found MySQL headers: ${MYSQL_INCLUDE_DIR}")
endif()
if(MySQL_binary_WANTED AND MySQL_binary_FOUND)
message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}")
endif()
mark_as_advanced(MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE)
if(MySQL_lib_WANTED AND MySQL_lib_FOUND)
try_run(MYSQL_VERSION_DETECTED MYSQL_VERSION_COMPILED ${CMAKE_BINARY_DIR}
SOURCES "${CMAKE_CURRENT_LIST_DIR}/FindMySQLVersion.c"
CMAKE_FLAGS -DINCLUDE_DIRECTORIES=${MYSQL_INCLUDE_DIR}
LINK_LIBRARIES ${MYSQL_LIBRARY}
RUN_OUTPUT_VARIABLE MYSQL_VERSION_DETECTION_RUN_OUTPUT
)
if(NOT TARGET MySQL::MySQL AND MySQL_lib_WANTED AND MySQL_lib_FOUND)
add_library(MySQL::MySQL UNKNOWN IMPORTED)
set_target_properties(MySQL::MySQL
PROPERTIES
IMPORTED_LOCATION
"${MYSQL_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES
"${MYSQL_INCLUDE_DIR}")
string(JSON MYSQL_VERSION GET "${MYSQL_VERSION_DETECTION_RUN_OUTPUT}" "version")
string(JSON MYSQL_FLAVOR GET "${MYSQL_VERSION_DETECTION_RUN_OUTPUT}" "flavor")
if(MYSQL_MIN_VERSION_${MYSQL_FLAVOR} VERSION_GREATER MYSQL_VERSION)
message(FATAL_ERROR "Found ${MYSQL_FLAVOR} version: \"${MYSQL_VERSION}\", but required is at least \"${MYSQL_MIN_VERSION_${MYSQL_FLAVOR}}\"")
else()
message(STATUS "Found ${MYSQL_FLAVOR} version: \"${MYSQL_VERSION}\", minimum required is \"${MYSQL_MIN_VERSION_${MYSQL_FLAVOR}}\"")
endif()
else()
message(FATAL_ERROR "Could not find the MySQL libraries! Please install the development libraries and headers")
message(STATUS "Found ${MYSQL_FLAVOR} library: ${MYSQL_LIBRARY}")
message(STATUS "Found ${MYSQL_FLAVOR} headers: ${MYSQL_INCLUDE_DIR}")
endif()
if(MySQL_binary_WANTED AND MySQL_binary_FOUND)
message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}")
endif()
mark_as_advanced(MYSQL_FOUND MYSQL_LIBRARY MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE)
if(NOT TARGET MySQL::MySQL AND MySQL_lib_WANTED AND MySQL_lib_FOUND)
add_library(MySQL::MySQL UNKNOWN IMPORTED)
set_target_properties(MySQL::MySQL
PROPERTIES
IMPORTED_LOCATION
"${MYSQL_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES
"${MYSQL_INCLUDE_DIR}")
endif()

View File

@@ -0,0 +1,18 @@
#include <mysql.h>
#include <stdio.h>
int main()
{
printf("{ "
"\"version\": \"%d.%d.%d\", "
"\"flavor\": \"%s\""
" }",
MYSQL_VERSION_ID / 10000, (MYSQL_VERSION_ID / 100) % 100, MYSQL_VERSION_ID % 100,
#ifdef MARIADB_VERSION_ID
"MariaDB"
#else
"MySQL"
#endif
);
return 0;
}

View File

@@ -8,10 +8,17 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
find_package(MySQL REQUIRED COMPONENTS lib)
set(MYSQL_MIN_VERSION_MySQL 8.0.34)
set(MYSQL_MIN_VERSION_MariaDB 10.4)
find_package(MySQL COMPONENTS lib)
add_library(mysql INTERFACE)
target_compile_definitions(mysql
INTERFACE
TRINITY_MYSQL_FLAVOR="${MYSQL_FLAVOR}"
TRINITY_REQUIRED_MYSQL_VERSION="${MYSQL_MIN_VERSION_${MYSQL_FLAVOR}}")
target_link_libraries(mysql
INTERFACE
MySQL::MySQL)

View File

@@ -40,15 +40,36 @@
#include <boost/stacktrace.hpp>
#endif
#define MIN_MYSQL_SERVER_VERSION 50700u
#define MIN_MYSQL_SERVER_VERSION_STRING "5.7"
#define MIN_MYSQL_CLIENT_VERSION 50700u
#define MIN_MYSQL_CLIENT_VERSION_STRING "5.7"
static consteval uint32 ParseVersionString(std::string_view chars)
{
uint32 result = 0;
uint32 partialResult = 0;
uint32 multiplier = 10000;
for (std::size_t i = 0; i < chars.length(); ++i)
{
char c = chars[i];
if (c == '.')
{
if (multiplier < 100)
throw "Too many . characters in version string";
#define MIN_MARIADB_SERVER_VERSION 100209u
#define MIN_MARIADB_SERVER_VERSION_STRING "10.2.9"
#define MIN_MARIADB_CLIENT_VERSION 30003u
#define MIN_MARIADB_CLIENT_VERSION_STRING "3.0.3"
result += partialResult * multiplier;
multiplier /= 100;
partialResult = 0;
}
else if (c >= '0' && c <= '9')
{
partialResult *= 10;
partialResult += c - '0';
}
else
throw "Invalid input character";
}
result += partialResult * multiplier;
return result;
}
namespace
{
@@ -112,14 +133,17 @@ template <class T>
DatabaseWorkerPool<T>::DatabaseWorkerPool()
: _async_threads(0), _synch_threads(0)
{
WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
// We only need check compiled version match on Windows
// because on other platforms ABI compatibility is ensured by SOVERSION
// and Windows MySQL releases don't even have abi-version-like component in their dll file name
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
#if defined(LIBMARIADB) && MARIADB_PACKAGE_VERSION_ID >= 30200
WPFatal(mysql_get_client_version() >= MIN_MARIADB_CLIENT_VERSION, "TrinityCore does not support MariaDB versions below " MIN_MARIADB_CLIENT_VERSION_STRING " (found %s id %lu, need id >= %u), please update your MariaDB client library", mysql_get_client_info(), mysql_get_client_version(), MIN_MARIADB_CLIENT_VERSION);
WPFatal(mysql_get_client_version() == MARIADB_PACKAGE_VERSION_ID, "Used MariaDB library version (%s id %lu) does not match the version id used to compile TrinityCore (id %u). Search on forum for TCE00011.", mysql_get_client_info(), mysql_get_client_version(), MARIADB_PACKAGE_VERSION_ID);
#define TRINITY_COMPILED_CLIENT_VERSION MARIADB_PACKAGE_VERSION_ID
#else
WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below " MIN_MYSQL_CLIENT_VERSION_STRING " (found %s id %lu, need id >= %u), please update your MySQL client library", mysql_get_client_info(), mysql_get_client_version(), MIN_MYSQL_CLIENT_VERSION);
WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s id %lu) does not match the version id used to compile TrinityCore (id %u). Search on forum for TCE00011.", mysql_get_client_info(), mysql_get_client_version(), MYSQL_VERSION_ID);
#define TRINITY_COMPILED_CLIENT_VERSION MYSQL_VERSION_ID
#endif
WPFatal(mysql_get_client_version() == TRINITY_COMPILED_CLIENT_VERSION, "Used " TRINITY_MYSQL_FLAVOR " library version (%s id %lu) does not match the version id used to compile TrinityCore (id %u). Search on forum for TCE00011.", mysql_get_client_info(), mysql_get_client_version(), TRINITY_COMPILED_CLIENT_VERSION);
#undef TRINITY_COMPILED_CLIENT_VERSION
#endif
}
@@ -457,18 +481,9 @@ uint32 DatabaseWorkerPool<T>::OpenConnections(InternalIndex type, uint8 numConne
_connections[type].clear();
return error;
}
#ifndef LIBMARIADB
else if (connection->GetServerVersion() < MIN_MYSQL_SERVER_VERSION)
#else
else if (connection->GetServerVersion() < MIN_MARIADB_SERVER_VERSION)
#endif
else if (uint32 serverVersion = connection->GetServerVersion(); serverVersion < ParseVersionString(TRINITY_REQUIRED_MYSQL_VERSION))
{
#ifndef LIBMARIADB
TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below " MIN_MYSQL_SERVER_VERSION_STRING " (found id {}, need id >= {}), please update your MySQL server", connection->GetServerVersion(), MIN_MYSQL_SERVER_VERSION);
#else
TC_LOG_ERROR("sql.driver", "TrinityCore does not support MariaDB versions below " MIN_MARIADB_SERVER_VERSION_STRING " (found id {}, need id >= {}), please update your MySQL server", connection->GetServerVersion(), MIN_MARIADB_SERVER_VERSION);
#endif
TC_LOG_ERROR("sql.driver", "TrinityCore does not support " TRINITY_MYSQL_FLAVOR " versions below " TRINITY_REQUIRED_MYSQL_VERSION " (found id {}, need id >= {}), please update your " TRINITY_MYSQL_FLAVOR " server", serverVersion, ParseVersionString(TRINITY_REQUIRED_MYSQL_VERSION));
return 1;
}
else