mirror of
https://github.com/znc/znc.git
synced 2026-07-06 18:01:21 +02:00
Refactor the way how modules are loaded.
Make version checks more strict. This finishes attempt to preserve ABI between patch versions. That didn't work well, and the people who could make it work, left the project already. Close #1255 Close #1274 Close #172
This commit is contained in:
+48
-22
@@ -60,25 +60,53 @@ class CModInfo;
|
||||
#define ZNC_EXPORT_LIB_EXPORT
|
||||
#endif
|
||||
|
||||
#define MODCOMMONDEFS(CLASS, DESCRIPTION, TYPE) \
|
||||
extern "C" { \
|
||||
ZNC_EXPORT_LIB_EXPORT bool ZNCModInfo(double dCoreVersion, \
|
||||
CModInfo& Info); \
|
||||
ZNC_EXPORT_LIB_EXPORT bool ZNCModInfo(double dCoreVersion, \
|
||||
CModInfo& Info) { \
|
||||
if (dCoreVersion != VERSION) return false; \
|
||||
auto t_s = [&](const CString& sEnglish, \
|
||||
const CString& sContext = "") { \
|
||||
return sEnglish.empty() ? "" : Info.t_s(sEnglish, sContext); \
|
||||
}; \
|
||||
t_s(CString()); /* Don't warn about unused t_s */ \
|
||||
Info.SetDescription(DESCRIPTION); \
|
||||
Info.SetDefaultType(TYPE); \
|
||||
Info.AddType(TYPE); \
|
||||
Info.SetLoader(TModLoad<CLASS>); \
|
||||
TModInfo<CLASS>(Info); \
|
||||
return true; \
|
||||
} \
|
||||
/** C-style entry point to the module.
|
||||
*
|
||||
* First, core compares C strings with version and compilation options of core
|
||||
* and module. If they match, assume that C++ classes have the same layout and
|
||||
* proceed to filling CModInfo.
|
||||
*
|
||||
* Most parts of version-extra is explicitly not compared, otherwise all
|
||||
* modules need to be rebuilt for every commit, which is more cumbersome for
|
||||
* ZNC developers. However, the part set by user (e.g. +deb1), is compared.
|
||||
*
|
||||
* If this struct ever changes, the first field (pcVersion) must stay the same.
|
||||
* Otherwise, name of ZNCModuleEntry function must also change. Other fields
|
||||
* can change at will.
|
||||
*
|
||||
* Modules shouldn't care about this struct, it's all managed by ...MODULEDEFS
|
||||
* macro.
|
||||
*/
|
||||
struct CModuleEntry {
|
||||
const char* pcVersion;
|
||||
const char* pcVersionExtra;
|
||||
const char* pcCompileOptions;
|
||||
void (*fpFillModInfo)(CModInfo&);
|
||||
};
|
||||
|
||||
#define MODCOMMONDEFS(CLASS, DESCRIPTION, TYPE) \
|
||||
static void FillModInfo(CModInfo& Info) { \
|
||||
auto t_s = [&](const CString& sEnglish, \
|
||||
const CString& sContext = "") { \
|
||||
return sEnglish.empty() ? "" : Info.t_s(sEnglish, sContext); \
|
||||
}; \
|
||||
t_s(CString()); /* Don't warn about unused t_s */ \
|
||||
Info.SetDescription(DESCRIPTION); \
|
||||
Info.SetDefaultType(TYPE); \
|
||||
Info.AddType(TYPE); \
|
||||
Info.SetLoader(TModLoad<CLASS>); \
|
||||
TModInfo<CLASS>(Info); \
|
||||
} \
|
||||
extern "C" { \
|
||||
/* A global variable leads to ODR violation when several modules are \
|
||||
* loaded. But a static variable inside a function works. */ \
|
||||
ZNC_EXPORT_LIB_EXPORT const CModuleEntry* ZNCModuleEntry(); \
|
||||
ZNC_EXPORT_LIB_EXPORT const CModuleEntry* ZNCModuleEntry() { \
|
||||
static const CModuleEntry ThisModule = {VERSION_STR, VERSION_EXTRA, \
|
||||
ZNC_COMPILE_OPTIONS_STRING, \
|
||||
FillModInfo}; \
|
||||
return &ThisModule; \
|
||||
} \
|
||||
}
|
||||
|
||||
/** Instead of writing a constructor, you should call this macro. It accepts all
|
||||
@@ -1016,7 +1044,6 @@ class CModule {
|
||||
virtual EModRet OnSendToIRC(CString& sLine);
|
||||
|
||||
ModHandle GetDLL() { return m_pDLL; }
|
||||
static double GetCoreVersion() { return VERSION; }
|
||||
|
||||
/** This function sends a given raw IRC line to the IRC server, if we
|
||||
* are connected to one. Else this line is discarded.
|
||||
@@ -1552,8 +1579,7 @@ class CModules : public std::vector<CModule*> {
|
||||
|
||||
private:
|
||||
static ModHandle OpenModule(const CString& sModule, const CString& sModPath,
|
||||
bool& bVersionMismatch, CModInfo& Info,
|
||||
CString& sRetMsg);
|
||||
CModInfo& Info, CString& sRetMsg);
|
||||
|
||||
protected:
|
||||
CUser* m_pUser;
|
||||
|
||||
+39
-2
@@ -6,11 +6,11 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 7
|
||||
#define VERSION_PATCH -1
|
||||
// This one is for display purpose
|
||||
// This one is for display purpose and to check ABI compatibility of modules
|
||||
#define VERSION_STR "1.7.x"
|
||||
#endif
|
||||
|
||||
// This one is for ZNCModInfo
|
||||
// Don't use this one
|
||||
#define VERSION (VERSION_MAJOR + VERSION_MINOR / 10.0)
|
||||
|
||||
// You can add -DVERSION_EXTRA="stuff" to your CXXFLAGS!
|
||||
@@ -19,4 +19,41 @@
|
||||
#endif
|
||||
extern const char* ZNC_VERSION_EXTRA;
|
||||
|
||||
// Compilation options which affect ABI
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
#define ZNC_VERSION_TEXT_IPV6 "yes"
|
||||
#else
|
||||
#define ZNC_VERSION_TEXT_IPV6 "no"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
#define ZNC_VERSION_TEXT_SSL "yes"
|
||||
#else
|
||||
#define ZNC_VERSION_TEXT_SSL "no"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_THREADED_DNS
|
||||
#define ZNC_VERSION_TEXT_DNS "threads"
|
||||
#else
|
||||
#define ZNC_VERSION_TEXT_DNS "blocking"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ICU
|
||||
#define ZNC_VERSION_TEXT_ICU "yes"
|
||||
#else
|
||||
#define ZNC_VERSION_TEXT_ICU "no"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_I18N
|
||||
#define ZNC_VERSION_TEXT_I18N "yes"
|
||||
#else
|
||||
#define ZNC_VERSION_TEXT_I18N "no"
|
||||
#endif
|
||||
|
||||
#define ZNC_COMPILE_OPTIONS_STRING \
|
||||
"IPv6: " ZNC_VERSION_TEXT_IPV6 ", SSL: " ZNC_VERSION_TEXT_SSL \
|
||||
", DNS: " ZNC_VERSION_TEXT_DNS ", charset: " ZNC_VERSION_TEXT_ICU \
|
||||
", i18n: " ZNC_VERSION_TEXT_I18N
|
||||
|
||||
#endif // !ZNC_VERSION_H
|
||||
|
||||
Reference in New Issue
Block a user