From f272cb0624d15b110e4f4a3617d133e3f0d174e2 Mon Sep 17 00:00:00 2001 From: Joakim Soderberg Date: Wed, 13 Feb 2013 09:29:26 +0800 Subject: [PATCH] Fixed DLL compilation on Windows for CMake. - Define LWS_DLL and LWS_INTERNAL when websockets_shared is compiled. - The websocket_shared target compiles to websocket.lib / websocket.dll (websocket.lib contains the exported functions for websocket.dll, and is the file that is linked to when a program wants to use the dll) - The websocket target compiles to websocket_static.lib on windows. - Replaced any "extern" with "LWS_EXTERN" on libwebsockets.h for proper DLL function exports. - Created a LIB_LIST with all the libwebsocket dependencies, instead of multiple calls to target_link_libraries, only one call is made for both the static and shared library version. This makes it easy to add other variants if wanted in the future. - Added ZLIB as a dependency for the libs, so that the build order will be correct at all times. - Added a dependency for the websockets lib to the test apps, so it is built before them. - Fixed the test-server-extpoll app to include the emulated_poll, and link to winsock on Windows. - Removed the global export of libwebsocket_internal_extensions, and added a function libwebsocket_get_internal_extensions() that returns it instead. Using the global would not work with the DLL export on Windows. --- CMakeLists.txt | 64 ++++++++++++++++++++++++++++++--------------- lib/extension.c | 5 ++++ lib/libwebsockets.h | 12 ++++----- lib/private-libwebsockets.h | 56 +++++++++++++++++++-------------------- test-server/test-client.c | 2 +- test-server/test-fraggle.c | 2 +- test-server/test-ping.c | 2 +- test-server/test-server.c | 18 +++++++++++-- 8 files changed, 101 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20d7609..0d1d3a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,13 +274,21 @@ add_library(websockets_shared SHARED ${HDR_PUBLIC} ${SOURCES}) -# On Windows libs have the same file ending -# for both static and shared libraries, so we -# need a unique name for the STATIC one. if (WIN32) + # On Windows libs have the same file ending (.lib) + # for both static and shared libraries, so we + # need a unique name for the static one. set_target_properties(websockets - PROPERTIES + PROPERTIES OUTPUT_NAME websockets_static) + + # Compile as DLL (export function declarations) + set_property( + TARGET websockets_shared + PROPERTY COMPILE_DEFINITIONS + LWS_DLL + LWS_INTERNAL + ) endif() # We want the shared lib to be named "libwebsockets" @@ -292,13 +300,11 @@ set_target_properties(websockets_shared # Set the so version of the lib. # Equivalent to LDFLAGS=-version-info 3:0:0 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) - set_target_properties(websockets - PROPERTIES - SOVERSION ${SOVERSION}) - - set_target_properties(websockets_shared - PROPERTIES - SOVERSION ${SOVERSION}) + foreach(lib websockets websockets_shared) + set_target_properties(${lib} + PROPERTIES + SOVERSION ${SOVERSION}) + endforeach() endif() set(LIB_LIST) @@ -345,6 +351,11 @@ else() find_package(ZLIB REQUIRED) endif() +# Make sure ZLib is compiled before the libs. +foreach (lib websockets websockets_shared) + add_dependencies(${lib} ZLIB) +endforeach() + message("ZLib include dirs: ${ZLIB_INCLUDE_DIRS}") message("ZLib libraries: ${ZLIB_LIBRARIES}") include_directories(${ZLIB_INCLUDE_DIRS}) @@ -393,8 +404,10 @@ if (UNIX) list(APPEND LIB_LIST m) endif() -target_link_libraries(websockets ${LIB_LIST}) -target_link_libraries(websockets_shared ${LIB_LIST}) +# Setup the linking for all libs. +foreach (lib websockets websockets_shared) + target_link_libraries(${lib} ${LIB_LIST}) +endforeach() # # Test applications @@ -425,10 +438,11 @@ if (NOT WITHOUT_TESTAPPS) source_group("Sources" FILES ${TEST_SRCS}) add_executable(${TEST_NAME} ${TEST_SRCS} ${TEST_HDR}) target_link_libraries(${TEST_NAME} websockets) - + add_dependencies(${TEST_NAME} websockets) set_property( TARGET ${TEST_NAME} - PROPERTY COMPILE_DEFINITIONS INSTALL_DATADIR="${SSL_CERT_DIR}" + PROPERTY COMPILE_DEFINITIONS + INSTALL_DATADIR="${SSL_CERT_DIR}" ) endfunction() @@ -458,14 +472,21 @@ if (NOT WITHOUT_TESTAPPS) if (NOT WITHOUT_SERVER AND NOT WITHOUT_SERVER_EXTPOLL) create_test_app(test-server-extpoll "test-server/test-server.c" - "" + "win32port/win32helpers/websock-w32.c" "${WIN32_HELPERS_PATH}/netdb.h;${WIN32_HELPERS_PATH}/strings.h;${WIN32_HELPERS_PATH}/unistd.h;${WIN32_HELPERS_PATH}/websock-w32.h") - # Set defines for this executable only. - set_property( - TARGET test-server-extpoll - PROPERTY COMPILE_DEFINITIONS EXTERNAL_POLL INSTALL_DATADIR="${SSL_CERT_DIR}" - ) + # Set defines for this executable only. + set_property( + TARGET test-server-extpoll + PROPERTY COMPILE_DEFINITIONS + EXTERNAL_POLL + INSTALL_DATADIR="${SSL_CERT_DIR}" + ) + + # We need to link against winsock code. + if (WIN32) + target_link_libraries(test-server-extpoll ws2_32.lib) + endif() endif() # @@ -505,6 +526,7 @@ if (NOT WITHOUT_TESTAPPS) foreach(TARGET_BIN test-client test-server + test-server-extpoll test-fraggle test-echo test-ping diff --git a/lib/extension.c b/lib/extension.c index 4fa241d..3d255b3 100644 --- a/lib/extension.c +++ b/lib/extension.c @@ -26,3 +26,8 @@ struct libwebsocket_extension libwebsocket_internal_extensions[] = { NULL, NULL, 0 } }; + +struct libwebsocket_extension *libwebsocket_get_internal_extensions() +{ + return libwebsocket_internal_extensions; +} diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 9a59032..d038a44 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -52,7 +52,7 @@ typedef int ssize_t; #endif #endif -#else +#else // NOT WIN32 #include #include #endif @@ -81,7 +81,7 @@ enum lws_log_levels { LLL_COUNT = 10 /* set to count of valid flags */ }; -extern void _lws_log(int filter, const char *format, ...); +LWS_EXTERN void _lws_log(int filter, const char *format, ...); /* notice, warn and log are always compiled in */ #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) @@ -101,7 +101,7 @@ extern void _lws_log(int filter, const char *format, ...); #define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) #define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) #define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) -extern void lwsl_hexdump(void *buf, size_t len); +LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); #else /* no debug */ @@ -944,10 +944,10 @@ lws_get_library_version(void); /* access to headers... only valid while headers valid */ -extern int +LWS_EXTERN int lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h); -extern int +LWS_EXTERN int lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, enum lws_token_indexes h); @@ -962,7 +962,7 @@ libwebsocket_read(struct libwebsocket_context *context, unsigned char *buf, size_t len); #ifndef LWS_NO_EXTENSIONS -LWS_EXTERN struct libwebsocket_extension libwebsocket_internal_extensions[]; +LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions(); #endif #ifdef __cplusplus diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index f98d3fd..3b3785b 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -401,7 +401,7 @@ struct libwebsocket { #endif }; -extern void +LWS_EXTERN void libwebsocket_close_and_free_session(struct libwebsocket_context *context, struct libwebsocket *wsi, enum lws_close_status); @@ -419,105 +419,105 @@ lws_latency(struct libwebsocket_context *context, int ret, int completion); #endif -extern int +LWS_EXTERN int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c); -extern int +LWS_EXTERN int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c); -extern int +LWS_EXTERN int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, unsigned char *buf, size_t len); -extern int +LWS_EXTERN int lws_b64_selftest(void); -extern struct libwebsocket * +LWS_EXTERN struct libwebsocket * wsi_from_fd(struct libwebsocket_context *context, int fd); -extern int +LWS_EXTERN int insert_wsi_socket_into_fds(struct libwebsocket_context *context, struct libwebsocket *wsi); -extern void +LWS_EXTERN void libwebsocket_set_timeout(struct libwebsocket *wsi, enum pending_timeout reason, int secs); -extern int +LWS_EXTERN int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len); -extern void +LWS_EXTERN void libwebsocket_service_timeout_check(struct libwebsocket_context *context, struct libwebsocket *wsi, unsigned int sec); -extern struct libwebsocket * +LWS_EXTERN struct libwebsocket * __libwebsocket_client_connect_2(struct libwebsocket_context *context, struct libwebsocket *wsi); -extern struct libwebsocket * +LWS_EXTERN struct libwebsocket * libwebsocket_create_new_server_wsi(struct libwebsocket_context *context); -extern char * +LWS_EXTERN char * libwebsockets_generate_client_handshake(struct libwebsocket_context *context, struct libwebsocket *wsi, char *pkt); -extern int +LWS_EXTERN int lws_handle_POLLOUT_event(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd); #ifndef LWS_NO_EXTENSIONS -extern int +LWS_EXTERN int lws_any_extension_handled(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_extension_callback_reasons r, void *v, size_t len); -extern void * +LWS_EXTERN void * lws_get_extension_user_matching_ext(struct libwebsocket *wsi, struct libwebsocket_extension *ext); #endif -extern int +LWS_EXTERN int lws_client_interpret_server_handshake(struct libwebsocket_context *context, struct libwebsocket *wsi); -extern int +LWS_EXTERN int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c); -extern int +LWS_EXTERN int lws_issue_raw_ext_access(struct libwebsocket *wsi, unsigned char *buf, size_t len); -extern int +LWS_EXTERN int _libwebsocket_rx_flow_control(struct libwebsocket *wsi); -extern int +LWS_EXTERN int user_callback_handle_rxflow(callback_function, struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len); -extern int +LWS_EXTERN int lws_set_socket_options(struct libwebsocket_context *context, int fd); -extern int +LWS_EXTERN int lws_allocate_header_table(struct libwebsocket *wsi); -extern char * +LWS_EXTERN char * lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h); -extern int +LWS_EXTERN int lws_hdr_simple_create(struct libwebsocket *wsi, enum lws_token_indexes h, const char *s); #ifndef LWS_NO_SERVER -extern int handshake_0405(struct libwebsocket_context *context, +LWS_EXTERN int handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi); #endif #ifndef LWS_NO_DAEMONIZE -extern int get_daemonize_pid(); +LWS_EXTERN int get_daemonize_pid(); #endif extern int interface_to_sa(const char *ifname, @@ -530,6 +530,6 @@ SHA1(const unsigned char *d, size_t n, unsigned char *md); #else -extern int openssl_websocket_private_data_index; +LWS_EXTERN int openssl_websocket_private_data_index; #endif diff --git a/test-server/test-client.c b/test-server/test-client.c index 4e8097b..872d2d3 100644 --- a/test-server/test-client.c +++ b/test-server/test-client.c @@ -273,7 +273,7 @@ int main(int argc, char **argv) info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_internal_extensions; + info.extensions = libwebsocket_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; diff --git a/test-server/test-fraggle.c b/test-server/test-fraggle.c index 5137711..61f868a 100644 --- a/test-server/test-fraggle.c +++ b/test-server/test-fraggle.c @@ -301,7 +301,7 @@ int main(int argc, char **argv) info.iface = iface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_internal_extensions; + info.extensions = libwebsocket_get_internal_extensions(); #endif if (use_ssl) { info.ssl_cert_filepath = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; diff --git a/test-server/test-ping.c b/test-server/test-ping.c index b195280..54b2f67 100644 --- a/test-server/test-ping.c +++ b/test-server/test-ping.c @@ -418,7 +418,7 @@ int main(int argc, char **argv) info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_internal_extensions; + info.extensions = libwebsocket_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; diff --git a/test-server/test-server.c b/test-server/test-server.c index 1ccffc4..ecf1dd1 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -29,9 +29,23 @@ #include #include #include -#ifndef WIN32 +#ifdef WIN32 + +#ifdef EXTERNAL_POLL + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include + #include + #include + + #include "websock-w32.h" +#endif + +#else // NOT WIN32 #include #endif + #include #include "../lib/libwebsockets.h" @@ -600,7 +614,7 @@ int main(int argc, char **argv) info.iface = iface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_internal_extensions; + info.extensions = libwebsocket_get_internal_extensions(); #endif if (!use_ssl) { info.ssl_cert_filepath = NULL; -- 2.7.4