Explorar o código

CMake build

This implements the CMake build for the project using the extra CMake
modules that have previously been added to the project.
Matt Clarkson %!s(int64=10) %!d(string=hai) anos
pai
achega
e03cf46867
Modificáronse 3 ficheiros con 803 adicións e 0 borrados
  1. 406 0
      CMakeLists.txt
  2. 277 0
      src/CMakeLists.txt
  3. 120 0
      test/CMakeLists.txt

+ 406 - 0
CMakeLists.txt

@@ -0,0 +1,406 @@
+# Determines what CMake APIs we can rely on
+cmake_minimum_required (VERSION 2.8.11)
+if (${CMAKE_VERSION} VERSION_GREATER 3.2.2)
+  cmake_policy(VERSION 3.2.2)
+endif()
+if (${CMAKE_VERSION} VERSION_GREATER 3.1 OR
+    ${CMAKE_VERSION} VERSION_EQUAL 3.1)
+  cmake_policy(SET CMP0054 NEW)
+endif()
+
+# Do not allow in source builds
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
+
+# Make sure we can import out CMake functions
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+# Load in the needed CMake modules
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+include(AddCCompilerFlag)
+include(AddCXXCompilerFlag)
+include(DetermineTargetArchitecture)
+include(CMakeDependentOption)
+
+# Set up the project
+project (civetweb)
+set(CIVETWEB_VERSION "1.7.0" CACHE STRING "The version of the civetweb library")
+string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CIVETWEB_VERSION_MATCH "${CIVETWEB_VERSION}")
+if ("${CIVETWEB_VERSION_MATCH}" STREQUAL "")
+  message(FATAL_ERROR "Must specify a semantic version: major.minor.patch")
+endif()
+set(CIVETWEB_VERSION_MAJOR "${CMAKE_MATCH_1}")
+set(CIVETWEB_VERSION_MINOR "${CMAKE_MATCH_2}")
+set(CIVETWEB_VERSION_PATCH "${CMAKE_MATCH_3}")
+determine_target_architecture(CIVETWEB_ARCHITECTURE)
+
+# Detect the platform reliably
+if(NOT MACOSX AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+   SET(DARWIN YES)
+elseif(NOT BSD AND ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+    SET(FREEBSD YES)
+elseif(NOT LINUX AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+    SET(LINUX YES)
+endif()
+
+# C++ wrappers
+option(CIVETWEB_ENABLE_THIRD_PARTY_OUTPUT "Shows the output of third party dependency processing" OFF)
+
+# Max Request Size
+set(CIVETWEB_MAX_REQUEST_SIZE 16384 CACHE STRING
+  "The largest amount of content bytes allowed in a request")
+set_property(CACHE CIVETWEB_MAX_REQUEST_SIZE PROPERTY VALUE ${CIVETWEB_MAX_REQUEST_SIZE})
+message(STATUS "Max Request Size - ${CIVETWEB_MAX_REQUEST_SIZE}")
+
+# Thread Stack Size
+set(CIVETWEB_THREAD_STACK_SIZE 102400 CACHE STRING
+  "The stack size in bytes for each thread created")
+set_property(CACHE CIVETWEB_THREAD_STACK_SIZE PROPERTY VALUE ${CIVETWEB_THREAD_STACK_SIZE})
+message(STATUS "Thread Stack Size - ${CIVETWEB_THREAD_STACK_SIZE}")
+
+# C++ wrappers
+option(CIVETWEB_ENABLE_CXX "Enables the C++ wrapper library" OFF)
+message(STATUS "C++ wrappers - ${CIVETWEB_ENABLE_CXX}")
+
+# IP Version 6
+option(CIVETWEB_ENABLE_IPV6 "Enables the IP version 6 support" OFF)
+message(STATUS "IP Version 6 - ${CIVETWEB_ENABLE_IPV6}")
+
+# Websocket support
+option(CIVETWEB_ENABLE_WEBSOCKETS "Enable websockets connections" OFF)
+message(STATUS "Websockets support - ${CIVETWEB_ENABLE_WEBSOCKETS}")
+
+# Memory debugging
+option(CIVETWEB_ENABLE_MEMORY_DEBUGGING "Enable the memory debugging features" OFF)
+message(STATUS "Memory Debugging - ${CIVETWEB_ENABLE_MEMORY_DEBUGGING}")
+
+# LUA CGI support
+option(CIVETWEB_ENABLE_LUA "Enable Lua CGIs" OFF)
+message(STATUS "Lua CGI support - ${CIVETWEB_ENABLE_LUA}")
+
+# Link to the shared LUA library
+cmake_dependent_option(
+  CIVETWEB_ENABLE_LUA_SHARED  "Link to the shared LUA system library" OFF
+ CIVETWEB_ENABLE_LUA OFF)
+if (CIVETWEB_ENABLE_LUA)
+  message(STATUS "Linking shared Lua library - ${CIVETWEB_ENABLE_LUA_SHARED}")
+endif()
+
+# Lua Third Party Settings
+if (CIVETWEB_ENABLE_LUA)
+  if (NOT CIVETWEB_ENABLE_LUA_SHARED)
+    # Lua Version
+    set(CIVETWEB_LUA_VERSION 5.3.0 CACHE STRING
+      "The version of Lua to build and include statically")
+    set_property(CACHE CIVETWEB_LUA_VERSION PROPERTY VALUE ${CIVETWEB_LUA_VERSION})
+    message(STATUS "Lua Version - ${CIVETWEB_LUA_VERSION}")
+    mark_as_advanced(CIVETWEB_LUA_VERSION)
+
+    # Lua Verification Hash
+    set(CIVETWEB_LUA_MD5_HASH a1b0a7e92d0c85bbff7a8d27bf29f8af CACHE STRING
+      "The hash of Lua archive to be downloaded")
+    set_property(CACHE CIVETWEB_LUA_MD5_HASH PROPERTY VALUE ${CIVETWEB_LUA_MD5_HASH})
+    mark_as_advanced(CIVETWEB_LUA_MD5_HASH)
+  endif()
+
+  # Lua Filesystem Version
+  set(CIVETWEB_LUA_FILESYSTEM_VERSION 1.6.3 CACHE STRING
+    "The version of Lua Filesystem to build and include statically")
+  set_property(CACHE CIVETWEB_LUA_FILESYSTEM_VERSION PROPERTY VALUE ${CIVETWEB_LUA_FILESYSTEM_VERSION})
+  message(STATUS "Lua Filesystem Version - ${CIVETWEB_LUA_FILESYSTEM_VERSION}")
+  mark_as_advanced(CIVETWEB_LUA_FILESYSTEM_VERSION)
+
+  # Lua Filesystem Verification Hash
+  set(CIVETWEB_LUA_FILESYSTEM_MD5_HASH d0552c7e5a082f5bb2865af63fb9dc95 CACHE STRING
+    "The hash of Lua Filesystem archive to be downloaded")
+  set_property(CACHE CIVETWEB_LUA_FILESYSTEM_MD5_HASH PROPERTY VALUE ${CIVETWEB_LUA_FILESYSTEM_MD5_HASH})
+  mark_as_advanced(CIVETWEB_LUA_FILESYSTEM_MD5_HASH)
+
+  # Lua SQLite Version
+  set(CIVETWEB_LUA_SQLITE_VERSION 0.9.3 CACHE STRING
+    "The version of Lua SQLite to build and include statically")
+  set_property(CACHE CIVETWEB_LUA_SQLITE_VERSION PROPERTY VALUE ${CIVETWEB_LUA_SQLITE_VERSION})
+  message(STATUS "Lua SQLite Version - ${CIVETWEB_LUA_SQLITE_VERSION}")
+  mark_as_advanced(CIVETWEB_LUA_SQLITE_VERSION)
+
+  # Lua SQLite Verification Hash
+  set(CIVETWEB_LUA_SQLITE_MD5_HASH 43234ae08197dfce6da02482ed14ec92 CACHE STRING
+    "The hash of Lua SQLite archive to be downloaded")
+  set_property(CACHE CIVETWEB_LUA_SQLITE_MD5_HASH PROPERTY VALUE ${CIVETWEB_LUA_SQLITE_MD5_HASH})
+  mark_as_advanced(CIVETWEB_LUA_SQLITE_MD5_HASH)
+
+  # Lua XML Version
+  set(CIVETWEB_LUA_XML_VERSION 1.8.0 CACHE STRING
+    "The version of Lua XML to build and include statically")
+  set_property(CACHE CIVETWEB_LUA_XML_VERSION PROPERTY VALUE ${CIVETWEB_LUA_XML_VERSION})
+  message(STATUS "Lua XML Version - ${CIVETWEB_LUA_XML_VERSION}")
+  mark_as_advanced(CIVETWEB_LUA_XML_VERSION)
+
+  # Lua XML Verification Hash
+  set(CIVETWEB_LUA_XML_MD5_HASH 25e4c276c5d8716af1de0c7853aec2b4 CACHE STRING
+    "The hash of Lua XML archive to be downloaded")
+  set_property(CACHE CIVETWEB_LUA_XML_MD5_HASH PROPERTY VALUE ${CIVETWEB_LUA_XML_MD5_HASH})
+  mark_as_advanced(CIVETWEB_LUA_XML_MD5_HASH)
+
+  # SQLite Version
+  set(CIVETWEB_SQLITE_VERSION 3.8.9 CACHE STRING
+    "The version of SQLite to build and include statically")
+  set_property(CACHE CIVETWEB_SQLITE_VERSION PROPERTY VALUE ${CIVETWEB_SQLITE_VERSION})
+  message(STATUS "SQLite Version - ${CIVETWEB_SQLITE_VERSION}")
+  mark_as_advanced(CIVETWEB_SQLITE_VERSION)
+
+  # SQLite Verification Hash
+  set(CIVETWEB_SQLITE_MD5_HASH 02e9c3a6daa8b8587cf6bef828c2e33f CACHE STRING
+    "The hash of SQLite archive to be downloaded")
+  set_property(CACHE CIVETWEB_SQLITE_MD5_HASH PROPERTY VALUE ${CIVETWEB_SQLITE_MD5_HASH})
+  mark_as_advanced(CIVETWEB_SQLITE_MD5_HASH)
+endif()
+
+# SSL support
+option(CIVETWEB_ENABLE_SSL "Enables the secure socket layer" ON)
+message(STATUS "SSL support - ${CIVETWEB_ENABLE_SSL}")
+
+# Dynamically load or link the SSL libraries
+cmake_dependent_option(
+  CIVETWEB_ENABLE_SSL_DYNAMIC_LOADING "Dynamically loads the SSL library rather than linking it" ON
+  CIVETWEB_ENABLE_SSL OFF)
+if (CIVETWEB_ENABLE_SSL)
+  message(STATUS "Dynamically load SSL libraries - ${CIVETWEB_ENABLE_SSL_DYNAMIC_LOADING}")
+endif()
+
+# Unix systems can define the dynamic library names to load
+if (CIVETWEB_ENABLE_SSL_DYNAMIC_LOADING AND NOT DARWIN AND UNIX)
+  # SSL library name
+  set(CIVETWEB_SSL_SSL_LIB "libssl.so" CACHE STRING
+    "The name of the SSL library to load")
+  set_property(CACHE CIVETWEB_SSL_SSL_LIB PROPERTY VALUE ${CIVETWEB_SSL_SSL_LIB})
+  message(STATUS "SSL Library Name - ${CIVETWEB_SSL_SSL_LIB}")
+
+  # Crytography library name
+  set(CIVETWEB_SSL_CRYPTO_LIB "libcrypto.so" CACHE STRING
+    "The name of the SSL Cryptography library to load")
+  set_property(CACHE CIVETWEB_SSL_CRYPTO_LIB PROPERTY VALUE ${CIVETWEB_SSL_CRYPTO_LIB})
+  message(STATUS "SSL Cryptography Library Name - ${CIVETWEB_SSL_CRYPTO_LIB}")
+endif()
+
+# The C and C++ standards to use
+set(CIVETWEB_C_STANDARD auto CACHE STRING
+  "The C standard to use; auto determines the latest supported by the compiler")
+set_property(CACHE CIVETWEB_C_STANDARD PROPERTY STRINGS auto c11 c99 c89)
+set(CIVETWEB_CXX_STANDARD auto CACHE STRING
+  "The C++ standard to use; auto determines the latest supported by the compiler")
+set_property(CACHE CIVETWEB_CXX_STANDARD PROPERTY STRINGS auto c++14 c++11 c++98)
+
+# Configure the linker
+if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+  find_program(GCC_AR gcc-ar)
+  if (GCC_AR)
+    set(CMAKE_AR ${GCC_AR})
+  endif()
+  find_program(GCC_RANLIB gcc-ranlib)
+  if (GCC_RANLIB)
+    set(CMAKE_RANLIB ${GCC_RANLIB})
+  endif()
+endif()
+
+# Configure the C compiler
+message(STATUS "Configuring C Compiler")
+if ("${CIVETWEB_C_STANDARD}" STREQUAL "auto")
+  add_c_compiler_flag(-std=c11)
+  if (NOT HAVE_C_FLAG_STD_C11)
+    add_c_compiler_flag(-std=c99)
+    if (NOT HAVE_C_FLAG_STD_C99)
+      add_c_compiler_flag(-std=c89)
+    endif()
+  endif()
+else()
+  add_c_compiler_flag(-std=${CIVETWEB_C_STANDARD})
+endif()
+add_c_compiler_flag(-Wall)
+add_c_compiler_flag(-Wextra)
+add_c_compiler_flag(-Wshadow)
+add_c_compiler_flag(-Wsign-conversion)
+add_c_compiler_flag(-Wmissing-prototypes)
+add_c_compiler_flag(-Weverything)
+add_c_compiler_flag(/W4)
+add_c_compiler_flag(-Wno-padded)
+add_c_compiler_flag(/Wd4820) # padding
+add_c_compiler_flag(-Wno-unused-macros)
+add_c_compiler_flag(-Wno-format-nonliteral)
+if (MINGW)
+  add_c_compiler_flag(-Wno-format)
+endif()
+add_c_compiler_flag(-Werror)
+add_c_compiler_flag(/WX)
+add_c_compiler_flag(-pedantic-errors)
+add_c_compiler_flag(-fvisibility=hidden)
+add_c_compiler_flag(-fstack-protector-strong RELEASE)
+add_c_compiler_flag(-flto RELEASE)
+add_c_compiler_flag(-fsanitize=undefined DEBUG)
+add_c_compiler_flag(-fsanitize=address DEBUG)
+if (HAVE_C_FLAG_FSANITIZE_ADDRESS)
+  add_c_compiler_flag(-static-asan DEBUG)
+endif()
+add_c_compiler_flag(-fstack-protector-all DEBUG)
+add_c_compiler_flag(-mwindows)
+
+# Coverage build type
+set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the C compiler during coverage builds."
+    FORCE)
+set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used for linking binaries during coverage builds."
+    FORCE)
+set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the shared libraries linker during coverage builds."
+    FORCE)
+mark_as_advanced(
+    CMAKE_CXX_FLAGS_COVERAGE
+    CMAKE_C_FLAGS_COVERAGE
+    CMAKE_EXE_LINKER_FLAGS_COVERAGE
+    CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
+set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
+    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage."
+    FORCE)
+add_c_compiler_flag(--coverage COVERAGE)
+
+# Configure the C++ compiler
+if (CIVETWEB_ENABLE_CXX)
+  message(STATUS "Configuring C++ Compiler")
+  if ("${CIVETWEB_CXX_STANDARD}" STREQUAL "auto")
+    add_cxx_compiler_flag(-std=c++14)
+    if (NOT HAVE_CXX_FLAG_STD_CXX14)
+      add_cxx_compiler_flag(-std=c++11)
+      if (NOT HAVE_CXX_FLAG_STD_CXX11)
+        add_cxx_compiler_flag(-std=c++98)
+      endif()
+    endif()
+  else()
+    add_cxx_compiler_flag(-std=${CIVETWEB_CXX_STANDARD})
+  endif()
+  add_cxx_compiler_flag(-Wall)
+  add_cxx_compiler_flag(-Wextra)
+  add_cxx_compiler_flag(-Wshadow)
+  add_cxx_compiler_flag(-Wsign-conversion)
+  add_cxx_compiler_flag(-Wmissing-prototypes)
+  add_cxx_compiler_flag(-Weverything)
+  add_cxx_compiler_flag(/W4)
+  add_cxx_compiler_flag(-Wno-padded)
+  add_cxx_compiler_flag(/Wd4820) # padding
+  add_cxx_compiler_flag(-Wno-unused-macros)
+  add_cxx_compiler_flag(-Wno-format-nonliteral)
+  if (MINGW)
+    add_cxx_compiler_flag(-Wno-format)
+  endif()
+  add_cxx_compiler_flag(-Werror)
+  add_cxx_compiler_flag(/WX)
+  add_cxx_compiler_flag(-pedantic-errors)
+  add_cxx_compiler_flag(-Wzero-as-null-pointer-constant)
+  add_cxx_compiler_flag(-fvisibility=hidden)
+  add_cxx_compiler_flag(-fstack-protector-strong RELEASE)
+  add_cxx_compiler_flag(-flto RELEASE)
+  add_cxx_compiler_flag(-fsanitize=undefined DEBUG)
+  add_cxx_compiler_flag(-fsanitize=address DEBUG)
+  if (HAVE_CXX_FLAG_FSANITIZE_ADDRESS)
+    add_cxx_compiler_flag(-static-asan DEBUG)
+  endif()
+  add_cxx_compiler_flag(-fstack-protector-all DEBUG)
+  add_cxx_compiler_flag(-mwindows)
+  set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
+      "Flags used by the C++ compiler during coverage builds."
+      FORCE)
+  add_cxx_compiler_flag(--coverage COVERAGE)
+endif()
+
+# Set up the definitions
+if (${CMAKE_BUILD_TYPE} MATCHES "[Dd]ebug")
+  add_definitions(-DDEBUG)
+endif()
+if (HAVE_STDINT)
+  add_definitions(-DHAVE_STDINT)
+endif()
+if (CIVETWEB_ENABLE_IPV6)
+  add_definitions(-DUSE_IPV6)
+endif()
+if (CIVETWEB_ENABLE_WEBSOCKETS)
+  add_definitions(-DUSE_WEBSOCKET)
+endif()
+if (CIVETWEB_ENABLE_LUA)
+  add_definitions(-DUSE_LUA)
+endif()
+if (CIVETWEB_ENABLE_MEMORY_DEBUGGING)
+  add_definitions(-DMEMORY_DEBUGGING)
+endif()
+if (NOT CIVETWEB_ENABLE_SSL)
+  add_definitions(-DNO_SSL)
+elseif (NOT CIVETWEB_ENABLE_SSL_DYNAMIC_LOADING)
+  add_definitions(-DNO_SSL_DL)
+else()
+  if(CIVETWEB_SSL_SSL_LIB)
+    add_definitions(-DSSL_LIB="${CIVETWEB_SSL_SSL_LIB}")
+  endif()
+  if(CIVETWEB_SSL_CRYPTO_LIB)
+    add_definitions(-DCRYPTO_LIB="${CIVETWEB_SSL_CRYPTO_LIB}")
+  endif()
+endif()
+add_definitions(-DUSE_STACK_SIZE=${CIVETWEB_THREAD_STACK_SIZE})
+add_definitions(-DMAX_REQUEST_SIZE=${CIVETWEB_MAX_REQUEST_SIZE})
+
+# Build the targets
+add_subdirectory(src)
+
+# Enable the testing of the library/executable
+include(CTest)
+if (BUILD_TESTING)
+  # Check unit testing framework Version
+  set(CIVETWEB_CHECK_VERSION 0.9.14 CACHE STRING
+    "The version of Check unit testing framework to build and include statically")
+  set_property(CACHE CIVETWEB_CHECK_VERSION PROPERTY VALUE ${CIVETWEB_CHECK_VERSION})
+  message(STATUS "Check Unit Testing Framework Version - ${CIVETWEB_CHECK_VERSION}")
+  mark_as_advanced(CIVETWEB_CHECK_VERSION)
+
+  # Check unit testing framework Verification Hash
+  set(CIVETWEB_CHECK_MD5_HASH 38263d115d784c17aa3b959ce94be8b8 CACHE STRING
+    "The hash of Check unit testing framework archive to be downloaded")
+  set_property(CACHE CIVETWEB_CHECK_MD5_HASH PROPERTY VALUE ${CIVETWEB_CHECK_MD5_HASH})
+  mark_as_advanced(CIVETWEB_CHECK_MD5_HASH)
+
+  # Build the testing
+  add_subdirectory(test)
+endif()
+
+# Set up CPack
+include(InstallRequiredSystemLibraries)
+set(CPACK_PACKAGE_VENDOR "civetweb Contributors")
+set(CPACK_PACKAGE_CONTACT "civetweb@github.com")
+set(CPACK_PACKAGE_VERSION_MAJOR "${CIVETWEB_VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${CIVETWEB_VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${CIVETWEB_VERSION_PATCH}")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A HTTP library and server")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.md")
+set(CPACK_STRIP_FILES TRUE)
+set(CPACK_PACKAGE_DEPENDS "openssl")
+if (CIVETWEB_ENABLE_LUA_SHARED)
+  set(CPACK_PACKAGE_DEPENDS "lua, ${CPACK_PACKAGE_DEPENDS}")
+endif()
+
+# RPM Packaging
+set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
+set(CPACK_RPM_PACKAGE_LICENSE "MIT")
+set(CPACK_RPM_PACKAGE_ARCHITECTURE "${CIVETWEB_ARCHITECTURE}")
+set(CPACK_RPM_PACKAGE_REQUIRES "${CPACK_PACKAGE_DEPENDS}")
+
+# Debian Packaging
+set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CIVETWEB_ARCHITECTURE}")
+set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/bel2125/civetweb")
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_PACKAGE_DEPENDS}")
+
+# WiX Packaging
+# TODO: www.cmake.org/cmake/help/v3.0/module/CPackWIX.html
+
+# Finalize CPack settings
+include(CPack)

+ 277 - 0
src/CMakeLists.txt

@@ -0,0 +1,277 @@
+# Check the headers we need
+include(CheckIncludeFiles)
+check_include_files(stdint.h HAVE_STDINT)
+
+# The C API library
+add_library(c-library civetweb.c)
+set_target_properties(c-library PROPERTIES
+  OUTPUT_NAME "civetweb"
+  VERSION ${CIVETWEB_VERSION}
+  SOVERSION ${CIVETWEB_VERSION}
+)
+if (BUILD_SHARED_LIBS)
+  target_compile_definitions(c-library PRIVATE CIVETWEB_DLL_EXPORTS)
+endif()
+target_include_directories(
+  c-library PUBLIC
+  ${PROJECT_SOURCE_DIR}/include)
+install(
+  TARGETS c-library
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin
+  COMPONENT c-library)
+install(FILES
+  ${PROJECT_SOURCE_DIR}/include/civetweb.h
+  DESTINATION include
+  COMPONENT c-library)
+
+# Need Windows sockets if available
+find_package(WinSock)
+if (WINSOCK_FOUND)
+  target_link_libraries(c-library WINSOCK::WINSOCK)
+endif()
+
+# We need threading
+find_package(Threads)
+target_link_libraries(c-library ${CMAKE_THREAD_LIBS_INIT})
+
+# Need the realtime library if we're using timers
+find_package(LibRt)
+if (CIVETWEB_ENABLE_WEBSOCKETS AND CIVETWEB_ENABLE_LUA AND LIBRT_FOUND)
+  target_link_libraries(c-library LIBRT::LIBRT)
+endif()
+
+# We need to link OpenSSL if not dynamically loading
+if (CIVETWEB_ENABLE_SLL AND NOT CIVETWEB_ENABLE_OPENSLL_DYNAMIC_LOADING)
+  find_package(OpenSSL)
+  target_link_libraries(c-library ${OPENSSL_LIBRARIES})
+else()
+  find_package(LibDl)
+  if (LIBDL_FOUND)
+    target_link_libraries(c-library LIBDL::LIBDL)
+  endif()
+endif()
+
+# If Lua support is needed we build some extra Lua libraries
+if (CIVETWEB_ENABLE_LUA)
+  include(ExternalProject)
+
+  # Determine if we should print to the output
+  if (CIVETWEB_ENABLE_THIRD_PARTY_OUTPUT)
+    set(THIRD_PARTY_LOGGING 0)
+  else()
+    set(THIRD_PARTY_LOGGING 1)
+  endif()
+
+  # If Lua is static we must build it from source
+  if (NOT CIVETWEB_ENABLE_LUA_SHARED)
+    if (LINUX)
+      set(LUA_MAKE_TARGET linux)
+    elseif(DARWIN)
+      set(LUA_MAKE_TARGET macosx)
+    elseif(FREEBSD)
+      set(LUA_MAKE_TARGET freebsd)
+    elseif(WINDOWS)
+      set(LUA_MAKE_TARGET mingw)
+    elseif(UNIX)
+      set(LUA_MAKE_TARGET posix)
+    else()
+      set(LUA_MAKE_TARGET generic)
+    endif()
+    set(LUA_BUILD_COMMAND "${CMAKE_MAKE_PROGRAM};${LUA_MAKE_TARGET}")
+    if (BUILD_SHARED_LIBS)
+      set(LUA_BUILD_COMMAND "${LUA_BUILD_COMMAND};MYCFLAGS=-fPIC")
+    endif()
+    ExternalProject_Add(lua
+      URL "http://www.lua.org/ftp/lua-${CIVETWEB_LUA_VERSION}.tar.gz"
+      URL_MD5 ${CIVETWEB_LUA_MD5_HASH}
+      PREFIX "${CMAKE_BINARY_DIR}/third_party"
+      CONFIGURE_COMMAND ""
+      BUILD_COMMAND ${LUA_BUILD_COMMAND}
+      BUILD_IN_SOURCE 1
+      INSTALL_COMMAND make install "INSTALL_TOP=<INSTALL_DIR>"
+      LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
+      LOG_UPDATE ${THIRD_PARTY_LOGGING}
+      LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
+      LOG_BUILD ${THIRD_PARTY_LOGGING}
+      LOG_TEST ${THIRD_PARTY_LOGGING}
+      LOG_INSTALL ${THIRD_PARTY_LOGGING})
+    ExternalProject_Get_Property(lua INSTALL_DIR)
+    set(LUA_INSTALL_DIR ${INSTALL_DIR})
+    unset(INSTALL_DIR)
+    link_directories("${LUA_INSTALL_DIR}/lib")
+    include_directories("${LUA_INSTALL_DIR}/include")
+    set(LUA_LIBRARIES "${LUA_INSTALL_DIR}/lib/liblua.a")
+    add_dependencies(c-library lua)
+  else()
+    find_package(Lua)
+  endif()
+
+  # Lua Filesystem Support
+  string(REPLACE "." "_" LUA_FILESYSTEM_VERSION_UNDERSCORE ${CIVETWEB_LUA_FILESYSTEM_VERSION})
+  ExternalProject_Add(luafilesystem
+    URL "https://github.com/keplerproject/luafilesystem/archive/v_${LUA_FILESYSTEM_VERSION_UNDERSCORE}.tar.gz"
+    URL_MD5 ${CIVETWEB_LUA_FILESYSTEM_MD5_HASH}
+    PREFIX "${CMAKE_BINARY_DIR}/third_party"
+    PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+      "${CMAKE_SOURCE_DIR}/cmake/luafilesystem/CMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
+    CMAKE_ARGS
+      "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
+      "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
+    LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
+    LOG_UPDATE ${THIRD_PARTY_LOGGING}
+    LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
+    LOG_BUILD ${THIRD_PARTY_LOGGING}
+    LOG_TEST ${THIRD_PARTY_LOGGING}
+    LOG_INSTALL ${THIRD_PARTY_LOGGING})
+  ExternalProject_Get_Property(luafilesystem INSTALL_DIR)
+  set(LUA_FILESYSTEM_INSTALL_DIR ${INSTALL_DIR})
+  unset(INSTALL_DIR)
+  link_directories("${LUA_FILESYSTEM_INSTALL_DIR}/lib")
+  include_directories("${LUA_FILESYSTEM_INSTALL_DIR}/include")
+  set(LUA_LIBRARIES "${LUA_LIBRARIES};${LUA_FILESYSTEM_INSTALL_DIR}/lib/libluafilesystem.a")
+  add_dependencies(c-library luafilesystem)
+
+  # Lua SQLite Support
+  if (${CIVETWEB_LUA_SQLITE_VERSION} VERSION_EQUAL "0.9.3")
+    set(LUA_SQLITE_FILENAME lsqlite3_fsl09w.zip)
+  elseif (${CIVETWEB_LUA_SQLITE_VERSION} VERSION_EQUAL "0.9.2")
+    set(LUA_SQLITE_FILENAME lsqlite3_fsl09v.zip)
+  elseif (${CIVETWEB_LUA_SQLITE_VERSION} VERSION_EQUAL "0.9.1")
+    set(LUA_SQLITE_FILENAME lsqlite3_fsl09t.zip)
+  else()
+    message(FATAL_ERROR "The Lua SQLite archive filename is unknown for version ${CIVETWEB_LUA_SQLITE_VERSION}")
+  endif()
+  ExternalProject_Add(luasqlite
+    URL "http://lua.sqlite.org/index.cgi/zip/${LUA_SQLITE_FILENAME}"
+    URL_MD5 ${CIVETWEB_LUA_SQLITE_MD5_HASH}
+    PREFIX "${CMAKE_BINARY_DIR}/third_party"
+    PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+      "${CMAKE_SOURCE_DIR}/cmake/luasqlite/CMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
+    CMAKE_ARGS
+      "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
+      "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
+    LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
+    LOG_UPDATE ${THIRD_PARTY_LOGGING}
+    LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
+    LOG_BUILD ${THIRD_PARTY_LOGGING}
+    LOG_TEST ${THIRD_PARTY_LOGGING}
+    LOG_INSTALL ${THIRD_PARTY_LOGGING})
+  ExternalProject_Get_Property(luasqlite INSTALL_DIR)
+  set(LUA_SQLITE_INSTALL_DIR ${INSTALL_DIR})
+  unset(INSTALL_DIR)
+  link_directories("${LUA_SQLITE_INSTALL_DIR}/lib")
+  set(LUA_LIBRARIES "${LUA_LIBRARIES};${LUA_SQLITE_INSTALL_DIR}/lib/libluasqlite.a")
+  add_dependencies(c-library luasqlite)
+
+  # Lua XML Support
+  if (${CIVETWEB_LUA_XML_VERSION} VERSION_EQUAL "1.8.0")
+    set(LUA_XML_FILENAME LuaXML_130610.zip)
+  elseif (${CIVETWEB_LUA_XML_VERSION} VERSION_EQUAL "1.7.4")
+    set(LUA_XML_FILENAME LuaXML_101012.zip)
+  else()
+    message(FATAL_ERROR "The Lua XML archive filename is unknown for version ${CIVETWEB_LUA_XML_VERSION}")
+  endif()
+  ExternalProject_Add(luaxml
+    URL "http://viremo.eludi.net/LuaXML/${LUA_XML_FILENAME}"
+    URL_MD5 ${CIVETWEB_LUA_XML_MD5_HASH}
+    PREFIX "${CMAKE_BINARY_DIR}/third_party"
+    PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+      "${CMAKE_SOURCE_DIR}/cmake/luaxml/CMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
+    CMAKE_ARGS
+      "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
+      "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
+    LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
+    LOG_UPDATE ${THIRD_PARTY_LOGGING}
+    LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
+    LOG_BUILD ${THIRD_PARTY_LOGGING}
+    LOG_TEST ${THIRD_PARTY_LOGGING}
+    LOG_INSTALL ${THIRD_PARTY_LOGGING})
+  ExternalProject_Get_Property(luaxml INSTALL_DIR)
+  set(LUA_XML_INSTALL_DIR ${INSTALL_DIR})
+  unset(INSTALL_DIR)
+  link_directories("${LUA_XML_INSTALL_DIR}/lib")
+  set(LUA_LIBRARIES "${LUA_LIBRARIES};${LUA_XML_INSTALL_DIR}/lib/libluaxml.a")
+  add_dependencies(c-library luaxml)
+
+  # SQLite Support
+  string (REGEX MATCHALL "[0-9]+" SQLITE_VERSION_MATCHES ${CIVETWEB_SQLITE_VERSION})
+  list(GET SQLITE_VERSION_MATCHES 0 SQLITE_VERSION_MAJOR)
+  list(GET SQLITE_VERSION_MATCHES 1 SQLITE_VERSION_MINOR)
+  list(GET SQLITE_VERSION_MATCHES 2 SQLITE_VERSION_PATCH)
+  set(SQLITE_FILE_VERSION ${SQLITE_VERSION_MAJOR}0${SQLITE_VERSION_MINOR}0${SQLITE_VERSION_PATCH}00)
+  ExternalProject_Add(sqlite
+    URL "http://www.sqlite.org/2015/sqlite-amalgamation-${SQLITE_FILE_VERSION}.zip"
+    URL_MD5 ${CIVETWEB_SQLITE_MD5_HASH}
+    PREFIX "${CMAKE_BINARY_DIR}/third_party"
+    PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+      "${CMAKE_SOURCE_DIR}/cmake/sqlite/CMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
+    CMAKE_ARGS
+      "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
+      "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
+    LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
+    LOG_UPDATE ${THIRD_PARTY_LOGGING}
+    LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
+    LOG_BUILD ${THIRD_PARTY_LOGGING}
+    LOG_TEST ${THIRD_PARTY_LOGGING}
+    LOG_INSTALL ${THIRD_PARTY_LOGGING})
+  ExternalProject_Get_Property(sqlite INSTALL_DIR)
+  set(SQLITE_INSTALL_DIR ${INSTALL_DIR})
+  unset(INSTALL_DIR)
+  link_directories("${SQLITE_INSTALL_DIR}/lib")
+  include_directories("${SQLITE_INSTALL_DIR}/include")
+  set(LUA_LIBRARIES "${LUA_LIBRARIES};${SQLITE_INSTALL_DIR}/lib/libsqlite.a")
+  add_dependencies(c-library sqlite)
+
+  # Link all the Lua libraries
+  target_link_libraries(c-library ${LUA_LIBRARIES})
+endif()
+
+# The web server executable
+add_executable(c-executable main.c)
+set_target_properties(c-executable PROPERTIES
+  OUTPUT_NAME "civetweb"
+)
+install(
+  TARGETS c-executable
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin
+  COMPONENT server)
+if (BUILD_SHARED_LIBS)
+  target_compile_definitions(c-executable PRIVATE CIVETWEB_DLL_IMPORTS)
+endif()
+target_include_directories(
+  c-executable PUBLIC
+  ${PROJECT_SOURCE_DIR}/include)
+target_link_libraries(c-executable c-library)
+if (LIBRT_FOUND)
+  target_link_libraries(c-executable LIBRT::LIBRT)
+endif()
+
+# The C++ API library
+if (CIVETWEB_ENABLE_CXX)
+  add_library(cxx-library CivetServer.cpp)
+  set_target_properties(cxx-library PROPERTIES
+    OUTPUT_NAME "cxx-library"
+    VERSION ${CIVETWEB_VERSION}
+    SOVERSION ${CIVETWEB_VERSION}
+  )
+  if (BUILD_SHARED_LIBS)
+    target_compile_definitions(cxx-library PRIVATE CIVETWEB_DLL_EXPORTS)
+  endif()
+  target_include_directories(
+    cxx-library PUBLIC
+    ${PROJECT_SOURCE_DIR}/include)
+  install(
+    TARGETS cxx-library
+    ARCHIVE DESTINATION lib
+    LIBRARY DESTINATION lib
+    RUNTIME DESTINATION bin
+    COMPONENT cxx-library)
+  install(FILES
+    ${PROJECT_SOURCE_DIR}/include/CivetServer.h
+    DESTINATION include
+    COMPONENT cxx-library)
+endif()

+ 120 - 0
test/CMakeLists.txt

@@ -0,0 +1,120 @@
+# Determine if we should print to the output
+if (CIVETWEB_ENABLE_THIRD_PARTY_OUTPUT)
+  set(THIRD_PARTY_LOGGING 0)
+else()
+  set(THIRD_PARTY_LOGGING 1)
+endif()
+
+# We use the check unit testing framework for our C unit tests
+include(ExternalProject)
+ExternalProject_Add(check
+  DEPENDS c-library
+  URL "https://downloads.sourceforge.net/project/check/check/${CIVETWEB_CHECK_VERSION}/check-${CIVETWEB_CHECK_VERSION}.tar.gz"
+  URL_MD5 ${CIVETWEB_CHECK_MD5_HASH}
+  PREFIX "${CMAKE_BINARY_DIR}/third_party"
+  BUILD_IN_SOURCE 1
+  PATCH_COMMAND ${CMAKE_COMMAND}
+    -DSOURCE_DIR=<SOURCE_DIR>
+    -DBINARY_DIR=<BINARY_DIR>
+    -DINSTALL_DIR=<INSTALL_DIR>
+    -DVERSION=${CIVETWEB_CHECK_VERSION}
+    -P ${CMAKE_SOURCE_DIR}/cmake/check/patch.cmake
+  CMAKE_ARGS
+    "-DCMAKE_BUILD_TYPE=Release"
+    "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
+    "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
+  LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
+  LOG_UPDATE ${THIRD_PARTY_LOGGING}
+  LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
+  LOG_BUILD ${THIRD_PARTY_LOGGING}
+  LOG_TEST ${THIRD_PARTY_LOGGING}
+  LOG_INSTALL ${THIRD_PARTY_LOGGING})
+ExternalProject_Get_Property(check INSTALL_DIR)
+set(CHECK_INSTALL_DIR ${INSTALL_DIR})
+unset(INSTALL_DIR)
+link_directories("${CHECK_INSTALL_DIR}/lib")
+include_directories("${CHECK_INSTALL_DIR}/include")
+if (WIN32 AND MINGW)
+  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcheck.a")
+  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcompat.a")
+elseif (WIN32)
+  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/check.lib")
+  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/compat.lib")
+else()
+  set(CHECK_LIBRARIES "${CHECK_INSTALL_DIR}/lib/libcheck.a")
+endif()
+find_package(LibM)
+if (LIBM_FOUND)
+  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBM::LIBM")
+endif()
+find_package(LibRt)
+if (LIBRT_FOUND)
+  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBRT::LIBRT")
+endif()
+
+# Build the C unit tests
+add_library(public-c-unit-tests STATIC public.c)
+if (BUILD_SHARED_LIBS)
+  target_compile_definitions(public-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS)
+endif()
+target_include_directories(
+  public-c-unit-tests PUBLIC
+  ${PROJECT_SOURCE_DIR}/include)
+target_link_libraries(public-c-unit-tests c-library ${CHECK_LIBRARIES})
+add_dependencies(public-c-unit-tests check)
+add_library(private-c-unit-tests STATIC private.c)
+target_include_directories(
+  private-c-unit-tests PUBLIC
+  ${PROJECT_SOURCE_DIR}/include)
+target_link_libraries(private-c-unit-tests ${CHECK_LIBRARIES})
+add_dependencies(private-c-unit-tests check)
+add_executable(civetweb-c-unit-test main.c)
+target_link_libraries(civetweb-c-unit-test public-c-unit-tests private-c-unit-tests ${CHECK_LIBRARIES})
+add_dependencies(civetweb-c-unit-test check)
+
+# Public API tests
+add_test(test-public-cookie civetweb-c-unit-test --suite=Public --test-case=Cookies)
+
+# Private API tests
+add_test(test-private-http-message civetweb-c-unit-test --suite=Private "--test-case=HTTP Message")
+
+# Add the coverage command(s)
+if (${CMAKE_BUILD_TYPE} MATCHES "[Cc]overage")
+  find_program(GCOV_EXECUTABLE gcov)
+  find_program(LCOV_EXECUTABLE lcov)
+  find_program(GENHTML_EXECUTABLE genhtml)
+  find_program(CTEST_EXECUTABLE ctest)
+  if (GCOV_EXECUTABLE AND LCOV_EXECUTABLE AND GENHTML_EXECUTABLE AND CTEST_EXECUTABLE AND HAVE_C_FLAG_COVERAGE)
+    add_custom_command(
+      OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html
+      COMMAND ${LCOV_EXECUTABLE} -q -z -d .
+      COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i
+      COMMAND ${CTEST_EXECUTABLE} --force-new-ctest-process
+      COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov
+      COMMAND ${LCOV_EXECUTABLE} -q -a before.lcov -a after.lcov --output-file final.lcov
+      COMMAND ${LCOV_EXECUTABLE} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov
+      COMMAND ${GENHTML_EXECUTABLE} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_SOURCE_DIR}" -t benchmark
+      DEPENDS civetweb-c-unit-test
+      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+      COMMENT "Running LCOV"
+    )
+    add_custom_target(coverage
+      DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html
+      COMMENT "LCOV report at lcov/index.html"
+    )
+    message(STATUS "Coverage command added")
+  else()
+    if (HAVE_C_FLAG_COVERAGE)
+      set(C_FLAG_COVERAGE_MESSAGE supported)
+    else()
+      set(C_FLAG_COVERAGE_MESSAGE unavailable)
+    endif()
+    message(WARNING
+      "Coverage command not available:\n"
+      "  gcov: ${GCOV_EXECUTABLE}\n"
+      "  lcov: ${LCOV_EXECUTABLE}\n"
+      "  genhtml: ${GENHTML_EXECUTABLE}\n"
+      "  ctest: ${CTEST_EXECUTABLE}\n"
+      "  --coverage flag: ${C_FLAG_COVERAGE_MESSAGE}")
+  endif()
+endif()