Libwebsockets is an open source library of WebSocket protocol implementation. It is written in pure C language. Its homepage is: https://libwebsockets.org/ . This serial of articles will show you how to build libwebsockets libraries with Visual Studio on Windows step by step.
Prerequisites:
1. Git client for Windows ( Link: https://git-scm.com/download/win );
2. Visual Studio; VS 2010 is used here, but VS 2015 or higher version is recommend.
3. CMake ( Link: https://cmake.org/download/ );
4. OpenSSL ( Link: https://www.openssl.org/ ) header files and library files for Windows if SSL or TLS support is required. Any SSL implementation in the set {OpenSSL, wolfSSL, BoringSSL and mbedTLS} may work together with libwebsockets, and OpenSSL is the default choice. You can build OpenSSL libraries from source codes, or download them from https://slproweb.com/products/Win32OpenSSL.html or https://wiki.openssl.org/index.php/Binaries. OpenSSL 1.1.1 is needed for the version 3.1 of libwebsockets.
Git 2.11.0, VS 2010, CMake 3.14.0 and OpenSSL 1.1.1 are used here. The platform is 64-bit Windows 7. You can use 32-bit or 64-bit version of Git. It does not matter. The 32-bit libraries of libwebsockets 3.1 will be built in this post, so CMake and OpenSSL used are both in 32-bit version. If 64-bit libwebsockets libraries is required, CMake and OpenSSL should be in 64-bit version. I compiled OpenSSL 1.1.1 from source codes, and the generated files were put into the path 'C:\Program Files (x86)\OpenSSL' by default.
The characters of '(' and ')' in the path 'C:\Program Files (x86)\OpenSSL' will cause CMake error, so all sub-folders below 'C:\Program Files (x86)\OpenSSL' should be copied to another temporary directory where non-English letters are excluded, such as 'C:\Temp\OpenSSL-1_1_1\OpenSSL'.
By the way, the library of libuv ( https://github.com/libuv/libuv ), libev ( https://github.com/enki/libev ) or libevent ( https://github.com/libevent/libevent ) can be used in building process of libwebsockets, but none is used here. When open source libraries from third-parties are used, it must be sure that those libraries are compiled with the same multithread-dll / Mtd attributes as libwebsockets itself.
Let's start! Open a command-line window, execute the following instructions:
cd /d c:\Temp
mkdir libwebsockets
cd libwebsockets
git clone https://github.com/warmcat/libwebsockets.git
cd libwebsockets
mkdir build
cd build
cmake ..\ -DLWS_OPENSSL_INCLUDE_DIRS=C:\Temp\OpenSSL-1_1_1\OpenSSL\include -DLWS_OPENSSL_LIBRARIES=C:\Temp\OpenSSL-1_1_1\OpenSSL\lib\libcrypto.lib;C:\Temp\OpenSSL-1_1_1\OpenSSL\lib\libssl.lib -DOPENSSL_EXECUTABLE=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\openssl.exe -DLIBEAY_BIN=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\libcrypto-1_1.dll -DSSLEAY_BIN=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\libssl-1_1.dll -G "Visual Studio 10"
The output is as follows:
-- The C compiler identification is MSVC 16.0.40219.1
-- Check for working C compiler: c:/Microsoft Visual Studio 10.0/VC/bin/cl.exe
-- Check for working C compiler: c:/Microsoft Visual Studio 10.0/VC/bin/cl.exe -
- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- CMAKE_TOOLCHAIN_FILE=''
-- Found Git: C:/Program Files/Git/cmd/git.exe
Git commit hash: v3.1.0-105-g1f23d403
-- Performing Test LWS_HAVE_inline
-- Performing Test LWS_HAVE_inline - Failed
-- Performing Test LWS_HAVE___inline__
-- Performing Test LWS_HAVE___inline__ - Failed
-- Performing Test LWS_HAVE___inline
-- Performing Test LWS_HAVE___inline - Success
-- Performing Test LWS_HAVE_BZERO
-- Performing Test LWS_HAVE_BZERO - Failed
-- Performing Test LWS_HAVE_MALLOC_TRIM
-- Performing Test LWS_HAVE_MALLOC_TRIM - Failed
-- Performing Test LWS_HAVE_MALLOC_USABLE_SIZE
-- Performing Test LWS_HAVE_MALLOC_USABLE_SIZE - Failed
-- Looking for fork
-- Looking for fork - not found
-- Looking for getenv
-- Looking for getenv - found
-- Looking for malloc
-- Looking for malloc - found
-- Looking for memset
-- Looking for memset - found
-- Looking for realloc
-- Looking for realloc - found
-- Looking for socket
-- Looking for socket - not found
-- Looking for strerror
-- Looking for strerror - found
-- Looking for vfork
-- Looking for vfork - not found
-- Looking for execvpe
-- Looking for execvpe - found
-- Looking for getifaddrs
-- Looking for getifaddrs - not found
-- Looking for snprintf
-- Looking for snprintf - not found
-- Looking for _snprintf
-- Looking for _snprintf - found
-- Looking for _vsnprintf
-- Looking for _vsnprintf - found
-- Looking for getloadavg
-- Looking for getloadavg - not found
-- Looking for atoll
-- Looking for atoll - not found
-- Looking for _atoi64
-- Looking for _atoi64 - found
-- Looking for _stat32i64
-- Looking for _stat32i64 - found
-- Looking for dlfcn.h
-- Looking for dlfcn.h - not found
-- Looking for fcntl.h
-- Looking for fcntl.h - found
-- Looking for in6addr.h
-- Looking for in6addr.h - not found
-- Looking for memory.h
-- Looking for memory.h - found
-- Looking for netinet/in.h
-- Looking for netinet/in.h - not found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stdlib.h
-- Looking for stdlib.h - found
-- Looking for strings.h
-- Looking for strings.h - not found
-- Looking for string.h
-- Looking for string.h - found
-- Looking for sys/prctl.h
-- Looking for sys/prctl.h - not found
-- Looking for sys/socket.h
-- Looking for sys/socket.h - not found
-- Looking for sys/sockio.h
-- Looking for sys/sockio.h - not found
-- Looking for sys/stat.h
-- Looking for sys/stat.h - found
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for unistd.h
-- Looking for unistd.h - not found
-- Looking for vfork.h
-- Looking for vfork.h - not found
-- Looking for sys/capability.h
-- Looking for sys/capability.h - not found
-- Looking for malloc.h
-- Looking for malloc.h - found
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Looking for cap_set_flag in cap
-- Looking for cap_set_flag in cap - not found
-- Looking for 4 include files stdlib.h, ..., float.h
-- Looking for 4 include files stdlib.h, ..., float.h - found
-- Performing Test LWS_HAS_INTPTR_T
-- Performing Test LWS_HAS_INTPTR_T - Success
-- Performing Test LWS_HAS_PTHREAD_SETNAME_NP
-- Performing Test LWS_HAS_PTHREAD_SETNAME_NP - Failed
-- Performing Test LWS_HAS_GETOPT_LONG
-- Performing Test LWS_HAS_GETOPT_LONG - Failed
Compiling with SSL support
OpenSSL include dir: C:/Temp/OpenSSL-1_1_1/OpenSSL/include
OpenSSL libraries: C:/Temp/OpenSSL-1_1_1/OpenSSL/lib/libcrypto.lib;C:/Temp/OpenS
SL-1_1_1/OpenSSL/lib/libssl.lib
-- Looking for openssl/ecdh.h
-- Looking for openssl/ecdh.h - found
-- Looking for SSL_CTX_set1_param
-- Looking for SSL_CTX_set1_param - found
-- Looking for SSL_set_info_callback
-- Looking for SSL_set_info_callback - found
-- Looking for X509_VERIFY_PARAM_set1_host
-- Looking for X509_VERIFY_PARAM_set1_host - found
-- Looking for RSA_set0_key
-- Looking for RSA_set0_key - found
-- Looking for X509_get_key_usage
-- Looking for X509_get_key_usage - found
-- Looking for SSL_CTX_get0_certificate
-- Looking for SSL_CTX_get0_certificate - found
-- Looking for SSL_get0_alpn_selected
-- Looking for SSL_get0_alpn_selected - found
-- Looking for SSL_set_alpn_protos
-- Looking for SSL_set_alpn_protos - found
-- Looking for SSL_CTX_set_ciphersuites
-- Looking for SSL_CTX_set_ciphersuites - found
-- Looking for SSL_CTX_get_extra_chain_certs_only
-- Looking for SSL_CTX_get_extra_chain_certs_only - found
-- Looking for EVP_MD_CTX_free
-- Looking for EVP_MD_CTX_free - found
-- Looking for ECDSA_SIG_set0
-- Looking for ECDSA_SIG_set0 - found
-- Looking for BN_bn2binpad
-- Looking for BN_bn2binpad - found
-- Looking for EVP_aes_128_wrap
-- Looking for EVP_aes_128_wrap - found
-- Looking for TLS_client_method
-- Looking for TLS_client_method - found
-- Looking for TLSv1_2_client_method
-- Looking for TLSv1_2_client_method - found
-- Performing Test LWS_HAVE_PIPE2
-- Performing Test LWS_HAVE_PIPE2 - Failed
-- Performing Test LWS_HAVE_TCP_USER_TIMEOUT
-- Performing Test LWS_HAVE_TCP_USER_TIMEOUT - Failed
Searching for OpenSSL executable and dlls
OpenSSL executable: C:/Temp/OpenSSL-1_1_1/OpenSSL/bin/openssl.exe
GENCERTS = 1
Generating SSL Certificates for the test-server...
OPENSSL_INPUT_WIN_PATH = C:\Temp\libwebsokets\libwebsockets\build\openssl_input.
txt
cmd = "C:/Temp/OpenSSL-1_1_1/OpenSSL/bin/openssl.exe" req -new -newkey rsa:1024
-days 10000 -nodes -x509 -keyout "C:/Temp/libwebsokets/libwebsockets/build/libwe
bsockets-test-server.key.pem" -out "C:/Temp/libwebsokets/libwebsockets/build/lib
websockets-test-server.pem"
SUCCSESFULLY generated SSL certificate
OpenSSL dlls found:
Libeay: C:/Temp/OpenSSL-1_1_1/OpenSSL/bin/libcrypto-1_1.dll
SSLeay: C:/Temp/OpenSSL-1_1_1/OpenSSL/bin/libssl-1_1.dll
-- RPM tools not available on Win32 systems
---------------------------------------------------------------------
Settings: (For more help do cmake -LH <srcpath>)
---------------------------------------------------------------------
LWS_WITH_STATIC = ON
LWS_WITH_SHARED = ON
LWS_WITH_SSL = ON (SSL Support)
LWS_SSL_CLIENT_USE_OS_CA_CERTS = 1
LWS_WITH_WOLFSSL = OFF (wolfSSL/CyaSSL replacement for OpenSSL)
LWS_WITH_MBEDTLS = OFF (mbedTLS replacement for OpenSSL)
LWS_WITHOUT_BUILTIN_SHA1 = OFF
LWS_WITHOUT_BUILTIN_GETIFADDRS = OFF
LWS_WITHOUT_CLIENT = OFF
LWS_WITHOUT_SERVER = OFF
LWS_LINK_TESTAPPS_DYNAMIC = OFF
LWS_WITHOUT_TESTAPPS = OFF
LWS_WITHOUT_TEST_SERVER = OFF
LWS_WITHOUT_TEST_SERVER_EXTPOLL = OFF
LWS_WITHOUT_TEST_PING = OFF
LWS_WITHOUT_TEST_CLIENT = OFF
LWS_WITHOUT_EXTENSIONS = ON
LWS_WITH_LATENCY = OFF
LWS_WITHOUT_DAEMONIZE = ON
LWS_WITH_LIBEV = OFF
LWS_WITH_LIBUV = OFF
LWS_WITH_LIBEVENT = OFF
LWS_IPV6 = OFF
LWS_UNIX_SOCK = 0
LWS_WITH_HTTP2 = 1
LWS_SSL_SERVER_WITH_ECDH_CERT = OFF
LWS_MAX_SMP = 1
LWS_HAVE_PTHREAD_H =
LWS_WITH_CGI = OFF
LWS_HAVE_OPENSSL_ECDH_H = 1
LWS_HAVE_SSL_CTX_set1_param = 1
LWS_HAVE_RSA_SET0_KEY = 1
LWS_WITH_HTTP_PROXY = OFF
LIBHUBBUB_LIBRARIES =
PLUGINS =
LWS_WITH_ACCESS_LOG = OFF
LWS_WITH_SERVER_STATUS = OFF
LWS_WITH_LEJP = ON
LWS_WITH_LEJP_CONF = OFF
LWS_WITH_SMTP = OFF
LWS_WITH_GENERIC_SESSIONS = OFF
LWS_STATIC_PIC = OFF
LWS_WITH_RANGES = OFF
LWS_PLAT_OPTEE = OFF
LWS_WITH_ESP32 = OFF
LWS_WITH_ZIP_FOPS = OFF
LWS_AVOID_SIGPIPE_IGN = OFF
LWS_WITH_STATS = OFF
LWS_WITH_SOCKS5 = OFF
LWS_HAVE_SYS_CAPABILITY_H =
LWS_HAVE_LIBCAP =
LWS_WITH_PEER_LIMITS = OFF
LWS_HAVE_ATOLL =
LWS_HAVE__ATOI64 = 1
LWS_HAVE_STAT32I64 =
LWS_HAS_INTPTR_T = 1
LWS_WITH_EXPORT_LWSTARGETS = ON
---------------------------------------------------------------------
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Temp/libwebsokets/libwebsockets/build
Note:
1. If the building target is 64-bit libraries, -DLIB_SUFFIX=64 should be added to CMake command line. And the file names of OpenSSL dynamic libraries may be changed accordingly. That is, change -DLIBEAY_BIN=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\libcrypto-1_1.dll to -DLIBEAY_BIN=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\libcrypto-1_1-x64.dll, change -DSSLEAY_BIN=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\libssl-1_1.dll to -DSSLEAY_BIN=C:\Temp\OpenSSL-1_1_1\OpenSSL\bin\libssl-1_1-x64.dll in the cmake instruction. The names of 64-bit OpenSSL dynamic libraries are libcrypto-1_1-x64.dll and libssl-1_1-x64.dll by default.
2. If debug information is needed, -DCMAKE_BUILD_TYPE=DEBUG should be added to CMake command line.
3. If debug information isn't required, adding -DCMAKE_BUILD_TYPE=RELEASE to CMake command line is not necessary. In C:\Temp\libwebsokets\libwebsockets\CMakeLists.txt you can find the following:
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
endif()
So release version is the default building target.
4. There are lots of MACRO definitions in CMakeLists.txt. You can configure custom values to meet your needs.