feat(Deps/libsidecar): Libsidecar (clustering) ABI versions check and portable shared-library loading (#26890)

This commit is contained in:
Anton Popovichenko
2026-08-22 16:52:46 +02:00
committed by GitHub
parent c1793976c8
commit 23baad639b
12 changed files with 243 additions and 10 deletions
+3 -3
View File
@@ -86,6 +86,6 @@ fkYAML (A C++ header-only YAML library)
https://github.com/fktn-k/fkYAML
Version: 721edb3e1a817e527fd9e1e18a3bea300822522e
libsidecar (enables interaction with other components when the worldserver is running in cluster mode. It requires building a shared library first and putting it in the corresponding folder.)
https://github.com/walkline/ToCloud9/tree/master/game-server/libsidecar
Version: master
libsidecar (enables interaction with other components when the worldserver is running in cluster mode. Place the shared library from the release assets in deps/libsidecar for builds. UNIX: BUILD_RPATH finds deps/libsidecar; install copies to ${prefix}/lib; runtime also searches next to worldserver and ../lib. Windows: no rpath - build copies the DLL next to worldserver; install places it next to worldserver. Headers under deps/libsidecar/include - including tc9_version.h - must come from the same libsidecar build/release as the linked binary. worldserver checks ABI early when Cluster.Enabled.)
https://github.com/walkline/ToCloud9/releases/tag/libsidecar-v1.0.0
Version: 1.0.0 (TC9_VERSION in deps/libsidecar/include/tc9_version.h)
+31 -7
View File
@@ -37,30 +37,54 @@ else()
set(LIBSIDECAR_EXTENSION "so")
endif()
# Visible to worldserver CMake (rpath on UNIX; POST_BUILD copy on Windows).
set(LIBSIDECAR_SHARED_FILE
"${CMAKE_CURRENT_SOURCE_DIR}/libsidecar.${LIBSIDECAR_EXTENSION}"
CACHE INTERNAL "Path to the real libsidecar shared library file")
if (NOT EXISTS "${LIBSIDECAR_SHARED_FILE}")
message(WARNING
"USE_REAL_LIBSIDECAR is ON but ${LIBSIDECAR_SHARED_FILE} was not found. "
"Place the matching shared library (and headers) from the same libsidecar "
"build/release before linking or installing.")
endif()
if(WIN32)
set_target_properties(libsidecar
PROPERTIES
IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/libsidecar.${LIBSIDECAR_EXTENSION}
${LIBSIDECAR_SHARED_FILE}
IMPORTED_IMPLIB
${CMAKE_CURRENT_SOURCE_DIR}/${LIBSIDECAR_IMPORT_LIB}
INTERFACE_INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR}/include)
# worldserver installs to CMAKE_INSTALL_PREFIX root; DLL must sit next to it.
# Build-tree runs: apps/CMakeLists.txt copies this DLL next to worldserver
# (Windows has no rpath; the loader only searches the exe directory / PATH).
install(FILES "${LIBSIDECAR_SHARED_FILE}"
DESTINATION "${CMAKE_INSTALL_PREFIX}")
else()
set_target_properties(libsidecar
PROPERTIES
IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/libsidecar.${LIBSIDECAR_EXTENSION}
${LIBSIDECAR_SHARED_FILE}
INTERFACE_INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR}/include
IMPORTED_NO_SONAME
true)
set_target_properties(libsidecar PROPERTIES
IMPORTED_LOCATION_NOCONFIG
"${CMAKE_INSTALL_RPATH}/libsidecar.${LIBSIDECAR_EXTENSION}"
IMPORTED_SONAME_NOCONFIG
"libsidecar.${LIBSIDECAR_EXTENSION}")
# Source-tree dir for BUILD_RPATH only (dev runs from the build tree).
# Do not put this path on INSTALL_RPATH — that would bake the build
# machine's source tree into installed binaries.
# Do not use INTERFACE_LINK_OPTIONS -rpath: game, scripts, and
# worldserver all link libsidecar and would get duplicate -rpath warnings.
set(LIBSIDECAR_RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL
"Directory containing the real libsidecar shared library (build tree)")
# Install next to the rest of the prefix libraries (worldserver → bin/,
# so runtime rpath uses $ORIGIN/../lib and CMAKE_INSTALL_RPATH = prefix/lib).
install(FILES "${LIBSIDECAR_SHARED_FILE}" DESTINATION lib)
endif()
endif()
+10
View File
@@ -19,6 +19,9 @@
#endif
#endif
/* Compile-time version macros (must match the libsidecar you link) */
#include "tc9_version.h"
/* Include all API headers */
#include "battleground-api.h"
#include "events-group.h"
@@ -33,6 +36,13 @@
extern "C" {
#endif
/* ABI / package version of the *linked* library (not the caller's headers).
* Pass TC9_VERSION_MAJOR / TC9_VERSION_MINOR from the headers you compiled
* against into TC9CheckAbiCompatible. Returns 0 if compatible. */
TC9_API void TC9GetVersion(int* major, int* minor, int* patch);
TC9_API const char* TC9GetVersionString(void);
TC9_API int TC9CheckAbiCompatible(int required_major, int required_minor);
/* Main library functions */
TC9_API void TC9InitLib(uint16_t port, uint32_t realmID, uint8_t isCrossRealm, char* availableMaps, uint32_t** assignedMaps, int* assignedMapsSize);
TC9_API void TC9GracefulShutdown();
+20
View File
@@ -0,0 +1,20 @@
#ifndef TC9_VERSION_H
#define TC9_VERSION_H
/* Vendored snapshot of libsidecar-cpp generated version header.
* Keep in sync with the libsidecar binary in this deps folder.
* Upstream source of truth: project(libsidecar VERSION ...) in
* game-server/libsidecar-cpp/CMakeLists.txt (generates this file).
*/
#define TC9_VERSION_MAJOR 1
#define TC9_VERSION_MINOR 0
#define TC9_VERSION_PATCH 0
#define TC9_VERSION_STRING "1.0.0"
/* major*10000 + minor*100 + patch */
#define TC9_VERSION_NUMBER \
(TC9_VERSION_MAJOR * 10000 + TC9_VERSION_MINOR * 100 + TC9_VERSION_PATCH)
#endif /* TC9_VERSION_H */
+26
View File
@@ -7,6 +7,32 @@ void panicWithTC9Unavailable(const char* message) {
exit(EXIT_FAILURE);
}
// Version APIs work without a real libsidecar so callers can always query
// the header version this tree was built against.
void TC9GetVersion(int* major, int* minor, int* patch)
{
if (major)
*major = TC9_VERSION_MAJOR;
if (minor)
*minor = TC9_VERSION_MINOR;
if (patch)
*patch = TC9_VERSION_PATCH;
}
const char* TC9GetVersionString(void)
{
return TC9_VERSION_STRING;
}
int TC9CheckAbiCompatible(int required_major, int required_minor)
{
if (TC9_VERSION_MAJOR != required_major)
return 1;
if (TC9_VERSION_MINOR < required_minor)
return 2;
return 0;
}
// TC9SetBattlegroundStartHandler sets handler for starting battleground.
//
extern void TC9SetBattlegroundStartHandler(BattlegroundStartHandler h) { panicWithTC9Unavailable("TC9SetBattlegroundStartHandler"); }
+8
View File
@@ -4,6 +4,9 @@
#include <stdint.h>
#include <stdbool.h>
/* Compile-time version macros (vendored with real headers under include/) */
#include "tc9_version.h"
/* Include all API headers */
#include "battleground-api.h"
#include "events-group.h"
@@ -18,6 +21,11 @@
extern "C" {
#endif
/* Version APIs (implemented by stub without panic; real lib reports its build) */
void TC9GetVersion(int* major, int* minor, int* patch);
const char* TC9GetVersionString(void);
int TC9CheckAbiCompatible(int required_major, int required_minor);
/* Main library functions */
void TC9InitLib(uint16_t port, uint32_t realmID, uint8_t isCrossRealm, char* availableMaps, uint32_t** assignedMaps, int* assignedMapsSize);
void TC9GracefulShutdown();
+21
View File
@@ -0,0 +1,21 @@
#ifndef TC9_VERSION_H
#define TC9_VERSION_H
/* Vendored snapshot of libsidecar-cpp generated version header.
* Keep in sync with include/tc9_version.h and the linked libsidecar binary.
* Built only when USE_REAL_LIBSIDECAR is OFF (static stub, not the real .so/.dll).
*/
#define TC9_LIBSIDECAR_IS_STUB 1
#define TC9_VERSION_MAJOR 1
#define TC9_VERSION_MINOR 0
#define TC9_VERSION_PATCH 0
#define TC9_VERSION_STRING "1.0.0"
/* major*10000 + minor*100 + patch */
#define TC9_VERSION_NUMBER \
(TC9_VERSION_MAJOR * 10000 + TC9_VERSION_MINOR * 100 + TC9_VERSION_PATCH)
#endif /* TC9_VERSION_H */