cmake: Fix Windows static build

BUILD_SHARED_LIBS is a CMake variable. Due to how MSVC exports
and imports symbols from DLLs*, we still need to appropriately
define symbols so that __declspec(dllexport) and __declspec(dllimport)
are used properly, and also so that they're *not* used when building
statically, to avoid MSVC and LINK warnings LNK4217 and LNK4286,
and errors C2734, LNK2019, and LNK1120.

Do this by defining the compile-time definition ENABLE_STATIC
(not to be confused with the previous CMake variable ENABLE_STATIC)
whenever BUILD_SHARED_LIBS is set to OFF, and also defining
ENABLE_STATIC specifically for the static version of wsutil and
dumpcap / writecap that use it.

Also, eliminate some non-fatal warnings that occurred before by
defining WSUTIL_EXPORT to just be extern in the all static case.

Fixup 67bb36a181f9e643533bbfc96f52207edb47de0c

* - Data and functions are not directly exported, there's indirection
through an address table, but the appearance of direct export can be
obtained via syntactic sugar, See
https://learn.microsoft.com/en-us/cpp/build/importing-data-using-declspec-dllimport
https://learn.microsoft.com/en-us/cpp/c-language/rules-and-limitations-for-dllimport-dllexport
https://gcc.gnu.org/onlinedocs/gcc/Microsoft-Windows-Function-Attributes.html
This commit is contained in:
John Thacker 2025-06-03 09:32:29 -04:00
parent 049c1116e1
commit 56c1fab216
4 changed files with 14 additions and 6 deletions

View File

@ -541,6 +541,7 @@ set_property(DIRECTORY
$<$<OR:$<BOOL:${ENABLE_DEBUG}>,$<CONFIG:Debug>>:WS_DEBUG>
$<$<OR:$<AND:$<BOOL:${ENABLE_DEBUG}>,$<BOOL:${ENABLE_DEBUG_UTF_8}>>,$<CONFIG:Debug>>:WS_DEBUG_UTF_8>
$<$<BOOL:${ENABLE_ASSERT}>:ENABLE_ASSERT>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:ENABLE_STATIC>
)
if(WIN32)
@ -3497,7 +3498,7 @@ if(BUILD_dumpcap AND PCAP_FOUND)
#
# Instead, we just include source files for the relevant code
# to be built as part of dumpcap, so that they're built with
# BUILD_SHARED_LIBS defined, and will be able to be built with
# ENABLE_STATIC defined, and will be able to be built with
# the static version of libwsutil.
#
set(dumpcap_FILES
@ -3515,7 +3516,7 @@ if(BUILD_dumpcap AND PCAP_FOUND)
set_extra_executable_properties(dumpcap "Executables")
target_link_libraries(dumpcap ${dumpcap_LIBS})
target_include_directories(dumpcap SYSTEM PRIVATE ${NL_INCLUDE_DIRS})
target_compile_definitions(dumpcap PRIVATE BUILD_SHARED_LIBS)
target_compile_definitions(dumpcap PRIVATE ENABLE_STATIC)
executable_link_mingw_unicode(dumpcap)
install(TARGETS dumpcap
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}

View File

@ -91,7 +91,7 @@
* be necessary, e.g. if what's declared is an array whose size is
* not given in the declaration.
*/
#ifdef BUILD_SHARED_LIBS
#ifdef ENABLE_STATIC
/*
* We're building all-static, so we're not building any DLLs.
*/
@ -190,7 +190,14 @@
* (not an executable) using MSVC.
*/
#ifdef _MSC_VER
# ifdef BUILD_WSUTIL
# ifdef ENABLE_STATIC
/*
* We're building all-static, so we're not building any DLLs.
* Anything const and not initialized in the header (e.g., ws_utf8_seqlen)
* must be extern to avoid C2734.
*/
# define WSUTIL_EXPORT extern
# elif defined(BUILD_WSUTIL)
# define WSUTIL_EXPORT __declspec(dllexport) extern
# else
# define WSUTIL_EXPORT __declspec(dllimport) extern

View File

@ -37,7 +37,7 @@ set_target_properties(writecap PROPERTIES
target_compile_definitions(writecap
PRIVATE
# Necessary to avoid C4273 inconsistent DLL linkage on MSVC
BUILD_SHARED_LIBS
ENABLE_STATIC
)
target_link_libraries(writecap

View File

@ -431,7 +431,7 @@ add_library(wsutil_static STATIC
)
target_compile_definitions(wsutil_static PRIVATE
BUILD_SHARED_LIBS
ENABLE_STATIC
BUILD_WSUTIL
)