From 2f6cabb839cdabf8e2c16dab09f143f350244de7 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 23 May 2024 16:35:16 +0800 Subject: [PATCH] Library: prepare for static linking --- src/common/library.c | 4 + src/common/library.h | 44 ++++++ src/common/settings.c | 178 ++++++++++++------------ src/detection/displayserver/linux/drm.c | 2 +- 4 files changed, 137 insertions(+), 91 deletions(-) diff --git a/src/common/library.c b/src/common/library.c index e776516b5..0aa5e2419 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -1,6 +1,8 @@ #include "fastfetch.h" #include "common/library.h" +#ifndef FF_LIBRARY_STATIC_BUILD + #include //Clang doesn't define __SANITIZE_ADDRESS__ but defines __has_feature(address_sanitizer) @@ -77,3 +79,5 @@ void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...) return result; } + +#endif diff --git a/src/common/library.h b/src/common/library.h index 5a283bc2e..d06b31105 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -3,6 +3,8 @@ #include "fastfetch.h" #include "util/FFcheckmacros.h" +#ifndef FF_LIBRARY_STATIC_BUILD + #if defined(_WIN32) #include #define FF_DLOPEN_FLAGS 0 @@ -71,3 +73,45 @@ static inline void ffLibraryUnload(void** handle) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue); void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...); + +#else + +#define FF_LIBRARY_EXTENSION "" + +#define FF_LIBRARY_SYMBOL(symbolName) \ + __typeof__(&symbolName) ff ## symbolName; + +#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \ + FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder + +#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \ + symbolMapping = (__typeof__(&symbolName)) &symbolName + +#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \ + symbolMapping = (__typeof__(&symbolName)) &symbolName + +#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \ + FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue); + +#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \ + FF_MAYBE_UNUSED __typeof__(&symbolName) ff ## symbolName = (__typeof__(&symbolName)) &symbolName; + +#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \ + FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); + +#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \ + FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); + +#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \ + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue); + +#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \ + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); + +#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \ + FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); + +#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \ + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue); + +#endif diff --git a/src/common/settings.c b/src/common/settings.c index a01d4e706..8d6e6e47f 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -6,45 +6,6 @@ #include -typedef enum FFInitState -{ - FF_INITSTATE_UNINITIALIZED = 0, - FF_INITSTATE_SUCCESSFUL = 1, - FF_INITSTATE_FAILED = 2 -} FFInitState; - -#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \ - static dataObject data; \ - static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \ - if(initState != FF_INITSTATE_UNINITIALIZED) {\ - return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \ - } \ - initState = FF_INITSTATE_SUCCESSFUL; \ - void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \ - if(libraryHandle == NULL) { \ - initState = FF_INITSTATE_FAILED; \ - return NULL; \ - } \ - -#define FF_LIBRARY_DATA_LOAD_SYMBOL(symbolName) \ - data.ff ## symbolName = dlsym(libraryHandle, #symbolName); \ - if(data.ff ## symbolName == NULL) { \ - dlclose(libraryHandle); \ - initState = FF_INITSTATE_FAILED; \ - return NULL; \ - } - -#define FF_LIBRARY_DATA_LOAD_RETURN \ - initState = FF_INITSTATE_SUCCESSFUL; \ - return &data; - -#define FF_LIBRARY_DATA_LOAD_ERROR \ - { \ - dlclose(libraryHandle); \ - initState = FF_INITSTATE_FAILED; \ - return NULL; \ - } - #ifdef FF_HAVE_GIO #include @@ -88,32 +49,39 @@ typedef struct GSettingsData FF_LIBRARY_SYMBOL(g_settings_schema_source_get_default) GSettingsSchemaSource* schemaSource; GVariantGetters variantGetters; + + bool inited; } GSettingsData; static const GSettingsData* getGSettingsData(void) { - FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.library.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1); + static GSettingsData data; - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_new_full) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_value) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_user_value) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_default_value) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_get_default) + if (!data.inited) + { + data.inited = true; + FF_LIBRARY_LOAD(libgsettings, &instance.config.library.libGIO, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_has_key, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_new_full, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_value, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_user_value, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_default_value, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_get_default, NULL) - #define data data.variantGetters - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref); - #undef data + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_dup_string, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_boolean, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_int32, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_unref, NULL); - data.schemaSource = data.ffg_settings_schema_source_get_default(); - if(data.schemaSource == NULL) - FF_LIBRARY_DATA_LOAD_ERROR + data.schemaSource = data.ffg_settings_schema_source_get_default(); + if (data.schemaSource) + libgsettings = NULL; + } + if(!data.schemaSource) + return NULL; - FF_LIBRARY_DATA_LOAD_RETURN + return &data; } FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type) @@ -161,27 +129,34 @@ typedef struct DConfData FF_LIBRARY_SYMBOL(dconf_client_new) GVariantGetters variantGetters; DConfClient* client; + + bool inited; } DConfData; static const DConfData* getDConfData(void) { - FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.library.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2); + static DConfData data; - FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full) - FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new) + if (!data.inited) + { + data.inited = true; - #define data data.variantGetters - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32) - FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref) - #undef data + FF_LIBRARY_LOAD(libdconf, &instance.config.library.libDConf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2); + FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_read_full, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_new, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_dup_string, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_boolean, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_int32, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_unref, NULL) - data.client = data.ffdconf_client_new(); - if(data.client == NULL) - FF_LIBRARY_DATA_LOAD_ERROR + data.client = data.ffdconf_client_new(); + if (data.client) + libdconf = NULL; + } + if(!data.client) + return NULL; - FF_LIBRARY_DATA_LOAD_RETURN + return &data; } FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) @@ -232,23 +207,35 @@ typedef struct XFConfData FF_LIBRARY_SYMBOL(xfconf_channel_get_bool) FF_LIBRARY_SYMBOL(xfconf_channel_get_int) FF_LIBRARY_SYMBOL(xfconf_init) + + bool inited; } XFConfData; static const XFConfData* getXFConfData(void) { - FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.library.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4); + static XFConfData data; - FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get) - FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property) - FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_string) - FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_bool) - FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_int) - FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_init) + if (!data.inited) + { + data.inited = true; + FF_LIBRARY_LOAD(libxfconf, &instance.config.library.libXFConf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4); - if(data.ffxfconf_init(NULL) == false) - FF_LIBRARY_DATA_LOAD_ERROR + FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_has_property, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_string, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_bool, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_int, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_init, NULL) + if(!data.ffxfconf_init(NULL)) + data.ffxfconf_init = NULL; + else + libxfconf = NULL; + } - FF_LIBRARY_DATA_LOAD_RETURN + if(!data.ffxfconf_init) + return NULL; + + return &data; } FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type) @@ -294,22 +281,33 @@ typedef struct SQLiteData FF_LIBRARY_SYMBOL(sqlite3_column_text) FF_LIBRARY_SYMBOL(sqlite3_finalize) FF_LIBRARY_SYMBOL(sqlite3_close) + + bool inited; } SQLiteData; static const SQLiteData* getSQLiteData(void) { - FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.library.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1); + static SQLiteData data; - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_step) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_data_count) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_int) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_text) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_finalize) - FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_close) + if (!data.inited) + { + data.inited = true; + FF_LIBRARY_LOAD(libsqlite, &instance.config.library.libSQLite3, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_prepare_v2, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_step, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_data_count, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_int, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_text, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_finalize, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_close, NULL) + libsqlite = NULL; + } - FF_LIBRARY_DATA_LOAD_RETURN + if (!data.ffsqlite3_close) + return NULL; + + return &data; } int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c index 3710f1db2..3a2ed89e0 100644 --- a/src/detection/displayserver/linux/drm.c +++ b/src/detection/displayserver/linux/drm.c @@ -194,7 +194,7 @@ static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name) static const char* drmConnectLibdrm(FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen libdrm" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmGetDevices) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetResources) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetConnectorCurrent)