From ecebb0d9afd6e14914f4bbcda989950ad9dbe1d1 Mon Sep 17 00:00:00 2001 From: ashbob999 Date: Sat, 26 Oct 2024 22:43:38 +0100 Subject: [PATCH] Make: Fixed the stringzillite still having dependencies dlls on windows --- CMakeLists.txt | 10 ---------- c/lib.c | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50c9312..780a893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,16 +361,6 @@ if(${STRINGZILLA_BUILD_SHARED}) "SZ_USE_ARM_NEON=1" "SZ_USE_ARM_SVE=$,0,1>") endif() - - if (MSVC) - # Add dependencies for necessary runtime libraries in case of static linking - # This ensures that basic runtime functions are available: - # msvcrt.lib: Microsoft Visual C Runtime, required for basic C runtime functions on Windows. - # vcruntime.lib: Microsoft Visual C++ Runtime library for basic runtime functions. - # ucrt.lib: Universal C Runtime, necessary for linking basic C functions like I/O. - target_link_libraries(${target} PRIVATE msvcrt.lib vcruntime.lib ucrt.lib) - endif() - endfunction() define_shared(stringzilla_shared) diff --git a/c/lib.c b/c/lib.c index c6b403e..2b45896 100644 --- a/c/lib.c +++ b/c/lib.c @@ -144,7 +144,7 @@ __attribute__((aligned(64))) static sz_implementations_t sz_dispatch_table; * @brief Initializes a global static "virtual table" of supported backends * Run it just once to avoiding unnecessary `if`-s. */ -static void sz_dispatch_table_init(void) { +SZ_DYNAMIC void sz_dispatch_table_init(void) { sz_implementations_t *impl = &sz_dispatch_table; sz_capability_t caps = sz_capabilities(); sz_unused(caps); //< Unused when compiling on pre-SIMD machines. @@ -232,9 +232,20 @@ static void sz_dispatch_table_init(void) { } #if defined(_MSC_VER) -#pragma section(".CRT$XCU", read) -__declspec(allocate(".CRT$XCU")) void (*_sz_dispatch_table_init)() = sz_dispatch_table_init; +/* + * Makes sure the sz_dispatch_table_init function is called at startup, from either an executable or when loading a DLL. + * The section name must be no more than 8 characters long, and must be between .CRT$XCA and .CRT$XCZ alphabetically + * (exclusive). + * The Mircrosft C++ compiler puts C++ initialisation code in .CRT$XCU, so avoid that section. + * + * Reference: https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170 + */ +#pragma comment(linker, "/INCLUDE:_sz_dispatch_table_init") +#pragma section(".CRT$XCS", read) +__declspec(allocate(".CRT$XCS")) void (*_sz_dispatch_table_init)() = sz_dispatch_table_init; + +// Called either from CRT code or out own _DLLMainCRTStartup, when a DLL is loaded. BOOL WINAPI DllMain(HINSTANCE hints, DWORD forward_reason, LPVOID lp) { switch (forward_reason) { case DLL_PROCESS_ATTACH: @@ -247,6 +258,14 @@ BOOL WINAPI DllMain(HINSTANCE hints, DWORD forward_reason, LPVOID lp) { return TRUE; } +#if SZ_AVOID_LIBC +// Called when the DLL is loaded, and ther is no CRT code. +BOOL WINAPI _DllMainCRTStartup(HINSTANCE hints, DWORD forward_reason, LPVOID lp) { + DllMain(hints, forward_reason, lp); + return TRUE; +} +#endif + #else __attribute__((constructor)) static void sz_dispatch_table_init_on_gcc_or_clang(void) { sz_dispatch_table_init(); } #endif