Browse Source

Merge pull request #721 from KangLin/cmake

Add to support cmake
Mészáros Mihály 4 years ago
parent
commit
31c936d51d

+ 76 - 1
.gitignore

@@ -5,4 +5,79 @@ include
 lib
 sqlite
 examples/ca/CA.pl
-.vscode
+.vscode
+
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+.directory
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+*.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+

+ 74 - 0
CMakeLists.txt

@@ -0,0 +1,74 @@
+# Author: Kang Lin ([email protected])
+
+cmake_minimum_required(VERSION 3.5)
+
+project(coturn)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
+SET(BUILD_VERSION "4.5.2")
+
+# Find Git Version Patch
+IF(EXISTS "${CMAKE_SOURCE_DIR}/.git")
+    if(NOT GIT)
+        SET(GIT $ENV{GIT})
+    endif()
+    if(NOT GIT)
+        FIND_PROGRAM(GIT NAMES git git.exe git.cmd)
+    endif()
+    IF(GIT)
+        EXECUTE_PROCESS(
+            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+            COMMAND ${GIT} describe --tags
+            OUTPUT_VARIABLE GIT_VERSION  OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+        if(NOT GIT_VERSION)
+            EXECUTE_PROCESS(
+                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+                COMMAND ${GIT} rev-parse --short HEAD
+                OUTPUT_VARIABLE GIT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE
+            )
+        endif()
+        SET(BUILD_VERSION ${GIT_VERSION})
+    ENDIF()
+ENDIF()
+message("BUILD_VERSION:${BUILD_VERSION}")
+set(VERSION ${BUILD_VERSION})
+
+if(NOT DEFINED CMAKE_BUILD_TYPE)
+        set(CMAKE_BUILD_TYPE "Release")
+endif(NOT DEFINED CMAKE_BUILD_TYPE)
+if("Debug" STREQUAL CMAKE_BUILD_TYPE)
+    add_definitions(-D_DEBUG)
+endif()
+
+IF(MSVC)
+    # This option is to enable the /MP switch for Visual Studio 2005 and above compilers
+    OPTION(WIN32_USE_MP "Set to ON to build with the /MP option (Visual Studio 2005 and above)." ON)
+    MARK_AS_ADVANCED(WIN32_USE_MP)
+    IF(WIN32_USE_MP)
+        #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
+        add_compile_options(/MP)
+    ENDIF(WIN32_USE_MP)
+    add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
+    add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
+ENDIF(MSVC)
+
+include(CMakePackageConfigHelpers)
+include(GNUInstallDirs)
+include(GenerateExportHeader)
+include(CheckIncludeFile)
+include(CheckIncludeFileCXX)
+include(CheckFunctionExists)
+
+# Create will be delete files
+CONFIGURE_FILE(
+    "${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+    "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
+    IMMEDIATE @ONLY)
+# Create unistall target
+ADD_CUSTOM_TARGET(uninstall
+    "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
+    )
+
+add_subdirectory(src)
+

+ 68 - 0
cmake/CacheLog.cmake

@@ -0,0 +1,68 @@
+# Functions for keeping track of set cache variables and clearing them.
+#
+# get_cachelog_var
+#
+# add_to_cachelog
+#
+# unset_cachelog_entries
+#
+# reset_cachelog
+#
+
+
+# Get name of variable that cachelog will be stored in for this file.
+#
+# Name the cachelog variable after the Find* file that called this function.
+# This prevents collisions if multiple find modules use these functions.
+function(get_cachelog_var _cachelog_var_outname)
+	get_filename_component(_log_var "${CMAKE_CURRENT_LIST_FILE}" NAME)
+	string(MAKE_C_IDENTIFIER "${_log_var}" _log_var)
+	set(${_cachelog_var_outname} "${_log_var}_cachelog" PARENT_SCOPE)
+endfunction()
+
+
+# Add the given cache variable name to the cache log, and mark it as advanced.
+function(add_to_cachelog _name)
+	get_cachelog_var(_log_var)
+	set(${_log_var} ${${_log_var}} ${_name} CACHE INTERNAL "" FORCE)
+	mark_as_advanced(FORCE ${_name})
+endfunction()
+
+
+# Unset all cache variables that are listed in the cache log.
+function(unset_cachelog_entries)
+	get_cachelog_var(_log_var)
+	foreach (_cachevar ${${_log_var}})
+		unset(${_cachevar} CACHE)
+	endforeach ()
+endfunction()
+
+
+# Remove all cache variable names from the cache log.
+function(reset_cachelog)
+	get_cachelog_var(_log_var)
+	set(${_log_var} "" CACHE INTERNAL "" FORCE)
+endfunction()
+
+# From https://github.com/Monetra/mstdlib/blob/master/CMakeModules
+# The MIT License (MIT)
+
+# Copyright (c) 2015-2017 Main Street Softworks, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.

+ 97 - 0
cmake/FindLibevent.cmake

@@ -0,0 +1,97 @@
+# Author: Kang Lin ([email protected])
+
+# Try to find Libevent
+# Once done, this will define
+#
+# Libevent_FOUND        - system has Libevent
+# Libevent_INCLUDE_DIRS - Libevent include directories
+# Libevent_LIBRARIES    - libraries needed to use Libevent
+#
+# and the following imported targets
+#
+# Libevent::core        - the core functons of Libevent
+# Libevent::extra       - extra functions, contains http, dns and rpc
+# Libevent::pthreads    - multiple threads for Libevent, not exists on Windows
+# Libevent::openssl     - openssl support for Libevent
+
+macro(no_component_msg _comp)
+    if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${_comp})
+        set(pthreadlib)
+        if(NOT WIN32)
+            set(pthreadlib ", pthreads")
+        endif()
+        message(FATAL_ERROR "Your libevent library does not contain a ${_comp} component!\n"
+                "The valid components are core, extra${pthreadlib} and openssl.")
+    else()
+        message_if_needed(WARNING "Your libevent library does not contain a ${_comp} component!")
+    endif()
+endmacro()
+
+set(_AVAILABLE_LIBS core extra openssl pthreads)
+set(_EVENT_COMPONENTS)
+if(${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
+    foreach(_comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS})
+        list(FIND _AVAILABLE_LIBS ${_comp} _INDEX)
+        if(_INDEX GREATER -1)
+            list(APPEND _EVENT_COMPONENTS ${_comp})
+        else()
+            no_component_msg(${_comp})
+        endif()
+    endforeach()
+else()
+    set(_EVENT_COMPONENTS core extra openssl)
+    if(NOT WIN32)
+        list(APPEND _EVENT_COMPONENTS pthreads)
+    endif()
+endif()
+
+foreach(_libevent_comp ${_EVENT_COMPONENTS})
+    list(APPEND _libevent_comps libevent_${_libevent_comp})
+endforeach()
+
+find_package(PkgConfig)
+pkg_check_modules(PC_Libevent QUIET ${_libevent_comps})
+if(PC_Libevent_FOUND)
+    set(Libevent_VERSION ${PC_Libevent_VERSION})
+else()
+    foreach(_libevent_comp ${_EVENT_COMPONENTS})
+        list(APPEND PC_Libevent_LIBRARIES event_${_libevent_comp})
+    endforeach()
+endif()
+
+find_path(Libevent_INCLUDE_DIR
+    NAMES event2/event.h
+    HINTS ${Libevent_ROOT} ${PC_Libevent_INCLUDEDIR} ${PC_Libevent_INCLUDE_DIRS} /usr
+    PATHS $ENV{Libevent_DIR} ${Libevent_DIR}
+    PATH_SUFFIXES include
+    )
+
+foreach(Libevent_var ${PC_Libevent_LIBRARIES})
+    unset(Libevent_lib CACHE)
+    find_library(
+        Libevent_lib
+        NAMES
+            ${Libevent_var}
+        HINTS ${Libevent_ROOT} ${PC_Libevent_LIBDIR} ${PC_Libevent_LIBRARY_DIRS}
+        PATHS $ENV{Libevent_DIR} ${Libevent_DIR}
+        PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib)
+    if(Libevent_lib)
+        string(REPLACE event_ "" _name ${Libevent_var})
+        add_library(Libevent::${_name} UNKNOWN IMPORTED)
+        set_target_properties(Libevent::${_name} PROPERTIES
+            IMPORTED_LOCATION "${Libevent_lib}"
+            INTERFACE_INCLUDE_DIRECTORIES "${Libevent_INCLUDE_DIR}")
+        list(APPEND Libevent_LIBRARY ${Libevent_lib})
+    endif()
+endforeach()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Libevent
+    REQUIRED_VARS Libevent_LIBRARY Libevent_INCLUDE_DIR)
+
+mark_as_advanced(Libevent_FOUND Libevent_INCLUDE_DIR Libevent_LIBRARY Libevent_lib)
+
+set(Libevent_INCLUDE_DIRS ${Libevent_INCLUDE_DIR})
+set(Libevent_LIBRARIES ${Libevent_LIBRARY})
+unset(Libevent_INCLUDE_DIR)
+unset(Libevent_LIBRARY)

+ 300 - 0
cmake/FindMySQL.cmake

@@ -0,0 +1,300 @@
+# Find MySQL.
+#
+# This module prefers the MariaDB implementation of MySQL (it works better, especially on Windows). It will
+# only look for standard MySQL if MariaDB is not found.
+#
+# Set this variable to any additional path you want the module to search:
+#  MySQL_DIR
+#
+# Imported targets defined by this module:
+#  MySQL::mysql        - shared library if available, or static if that's all there is
+#  MySQL::mysql_shared - shared library
+#  MySQL::mysql_static - static library
+#
+# Informational variables:
+#  MySQL_FOUND      - MySQL (or all requested components of MySQL) was found.
+#  MySQL_VERSION    - the version of MySQL that was found
+#  MySQL_IS_MARIADB - TRUE if the MySQL that was found is MariaDB
+#
+
+include(CacheLog)
+include(FindPackageHandleStandardArgs)
+
+# Helper function for globbing for directories.
+function(append_glob_dirs list_name glob_path)
+	file(TO_CMAKE_PATH "${glob_path}" glob_path)
+	file(GLOB dirs LIST_DIRECTORIES true "${glob_path}")
+	if (dirs)
+		list(APPEND ${list_name} "${dirs}")
+		set(${list_name} "${${list_name}}" PARENT_SCOPE)
+	endif ()
+endfunction()
+
+# If MySQL_DIR has changed since the last invocation, wipe internal cache variables so we can search for everything
+# again.
+if (NOT "${MySQL_DIR}" STREQUAL "${_internal_old_mysql_dir}")
+	unset_cachelog_entries()
+endif ()
+reset_cachelog()
+
+set(_old_suffixes "${CMAKE_FIND_LIBRARY_SUFFIXES}")
+
+# Set path guesses.
+set(_paths)
+if (CMAKE_HOST_WIN32)
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(archdir    "$ENV{ProgramFiles}")
+		set(notarchdir "$ENV{ProgramFiles\(x86\)}")
+	else ()
+		set(archdir    "$ENV{ProgramFiles\(x86\)}")
+		set(notarchdir "$ENV{ProgramFiles}")
+	endif ()
+	# MariaDB
+	append_glob_dirs(_paths "${archdir}/MariaDB*/")
+	append_glob_dirs(_paths "${notarchdir}/MariaDB*/")
+	# MySQL
+	append_glob_dirs(_paths "${archdir}/MySQL/MySQL Connector.C*/")
+	append_glob_dirs(_paths "${notarchdir}/MySQL/MySQL Connector.C*/")
+else ()
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(arch 64)
+	else ()
+		set(arch 32)
+	endif ()
+	list(APPEND _paths
+		/usr/local/mariadb${arch}
+		/usr/local/mysql${arch}
+		/usr/local/mariadb
+		/usr/local/mysql
+	)
+	if (APPLE)
+		list(APPEND _paths /usr/local/opt/mariadb-connector-c)
+		append_glob_dirs(_paths "/usr/local/Cellar/mariadb-connector-c/*/")
+		list(APPEND _paths /usr/local/opt/mysql-connector-c)
+		append_glob_dirs(_paths "/usr/local/Cellar/mysql-connector-c/*/")
+	endif ()
+endif ()
+
+# Find include directory. Try hints set by variable and stuff from _paths, first.
+set(_suffixes
+	mariadb
+	include/mariadb
+	mariadb/include
+	mysql
+	include/mysql include
+)
+find_path(MySQL_INCLUDE_DIR
+	NAMES           mysql.h
+	HINTS           ${MySQL_DIR}
+	                $ENV{MySQL_DIR}
+	                ${MYSQL_ROOT_DIR}
+	PATHS           ${_paths}
+	PATH_SUFFIXES   ${_suffixes}
+	NO_DEFAULT_PATH
+)
+if (NOT MySQL_INCLUDE_DIR)
+	# If we didn't find anything using those hints, proceed to checking system paths. We need
+	# to do this in two steps in order to prevent a MySQL installation installed in system paths
+	# from being found before a MariaDB installation in /usr/local.
+	find_path(MySQL_INCLUDE_DIR
+		NAMES         mysql.h
+		PATH_SUFFIXES ${_suffixes}
+	)
+endif ()
+add_to_cachelog(MySQL_INCLUDE_DIR)
+
+if (MySQL_INCLUDE_DIR)
+	# Figure out if these headers belong to MariaDB or not.
+	if (MySQL_INCLUDE_DIR MATCHES "[Mm][Aa][Rr][Ii][Aa][Dd][Bb]")
+		set(MySQL_IS_MARIADB TRUE)
+	else ()
+		set(MySQL_IS_MARIADB FALSE)
+	endif ()
+
+	# Calculate root directory of installation from include directory.
+	string(REGEX REPLACE "(/)*include(/)*.*$" "" _root_dir "${MySQL_INCLUDE_DIR}")
+	set(MySQL_DIR "${_root_dir}" CACHE PATH "Root directory of MySQL installation" FORCE)
+	set(_internal_old_mysql_dir "${MySQL_DIR}" CACHE INTERNAL "" FORCE)
+	mark_as_advanced(FORCE MySQL_DIR)
+	
+	# Find version by parsing the mysql_version.h or mariadb_version.h header.
+	set(ver_file "${MySQL_INCLUDE_DIR}/mysql_version.h")
+	if (NOT EXISTS "${ver_file}")
+		# Note: some (but not all) mariadb installations in the wild have mariadb_version.h instead of mysql_version.h
+		set(ver_file "${MySQL_INCLUDE_DIR}/mariadb_version.h")
+		if (EXISTS "${ver_file}")
+			set(MySQL_IS_MARIADB TRUE)
+		else ()
+			set(ver_file)
+		endif ()
+	endif ()
+	if (ver_file)
+		file(STRINGS "${ver_file}" _id_str REGEX "^[ \t]*#[ \t]*define[\t ]+MYSQL_VERSION_ID[ \t]+[0-9]+")
+		if (_id_str MATCHES "^[ \t]*#[ \t]*define[\t ]+MYSQL_VERSION_ID[ \t]+([0-9]+)")
+			math(EXPR _major "${CMAKE_MATCH_1} / 10000")
+			math(EXPR _minor "( ${CMAKE_MATCH_1} % 10000 ) / 100")
+			math(EXPR _patch "${CMAKE_MATCH_1} % 100")
+			set(MySQL_VERSION "${_major}.${_minor}.${_patch}")
+		endif ()
+		
+		# If we haven't detected mariadb yet, try scanning the version file for mentions.
+		if (NOT MySQL_IS_MARIADB)
+			file(STRINGS "${MySQL_INCLUDE_DIR}/mysql_version.h" _mariadb REGEX [Mm][Aa][Rr][Ii][Aa][Dd][Bb])
+			if (_mariadb)
+				set(MySQL_IS_MARIADB TRUE)
+			endif ()
+		endif ()
+	endif ()
+	
+	# Set library names, based on which mysql we found.
+	if (MySQL_IS_MARIADB)
+		set(_static_names mariadbclient mariadb)
+		set(_shared_names libmariadb mariadb)
+		set(_dll_names libmariadb)
+	else ()
+		set(_static_names mysqlclient)
+		set(_shared_names libmysql mysqlclient)
+		set(_dll_names libmysql)
+	endif ()
+	
+	# Find static library.
+	set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+	foreach(defpath "NO_DEFAULT_PATH" "")
+		find_library(MySQL_STATIC_LIBRARY
+			NAMES         ${_static_names}
+			NAMES_PER_DIR
+			HINTS         ${MySQL_DIR}
+			PATH_SUFFIXES lib lib/mariadb
+			${defpath}
+		)
+		if (MySQL_STATIC_LIBRARY)
+			break()
+		endif ()
+	endforeach()
+	add_to_cachelog(MySQL_STATIC_LIBRARY)
+	if (MySQL_STATIC_LIBRARY)
+		set(MySQL_mysql_static_FOUND TRUE)
+		set(MySQL_mysql_FOUND TRUE)
+	endif ()
+	
+	# Find shared library (will pick up static lib if shared not found).
+	set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
+	foreach(defpath "NO_DEFAULT_PATH" "")
+		find_library(MySQL_LIBRARY
+			NAMES         ${_shared_names}
+			NAMES_PER_DIR
+			HINTS         ${MySQL_DIR}
+			PATH_SUFFIXES lib lib/mariadb
+			${defpath}
+		)
+		if (MySQL_LIBRARY)
+			break()
+		endif ()
+	endforeach()
+	add_to_cachelog(MySQL_LIBRARY)
+	if (MySQL_LIBRARY AND NOT MySQL_LIBRARY STREQUAL MySQL_STATIC_LIBRARY)
+		set(MySQL_mysql_shared_FOUND TRUE)
+		set(MySQL_mysql_FOUND TRUE)
+	endif ()
+	
+	# Find the DLL (if any).
+	if (WIN32)
+		set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
+		foreach(defpath "NO_DEFAULT_PATH" "")
+			find_library(MySQL_DLL_LIBRARY
+				NAMES         ${_dll_names}
+				NAMES_PER_DIR
+				HINTS         ${MySQL_DIR}
+				PATH_SUFFIXES bin lib bin/mariadb lib/mariadb ""
+				${defpath}
+			)
+			if (MySQL_DLL_LIBRARY)
+				break()
+			endif ()
+		endforeach()
+		add_to_cachelog(MySQL_DLL_LIBRARY)
+	endif ()
+endif ()
+
+set(_reqs MySQL_INCLUDE_DIR)
+if (NOT MySQL_FIND_COMPONENTS) # If user didn't request any particular component explicitly:
+	if (NOT MySQL_mysql_FOUND)
+		list(APPEND _reqs MySQL_LIBRARY)
+	endif ()
+endif ()
+
+find_package_handle_standard_args(MySQL
+	REQUIRED_VARS     ${_reqs}
+	VERSION_VAR       MySQL_VERSION
+	HANDLE_COMPONENTS
+	FAIL_MESSAGE      "MySQL not found, try -DMySQL_DIR=<path>"
+)
+add_to_cachelog(FIND_PACKAGE_MESSAGE_DETAILS_MySQL)
+
+# Static library.
+if (MySQL_mysql_static_FOUND AND NOT TARGET MySQL::mysql_static)
+	add_library(MySQL::mysql_static STATIC IMPORTED)
+	set_target_properties(MySQL::mysql_static PROPERTIES
+		IMPORTED_LOCATION                 "${MySQL_STATIC_LIBRARY}"
+		IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+		INTERFACE_INCLUDE_DIRECTORIES     "${MySQL_INCLUDE_DIR}"
+	)
+	set(_mysql_any MySQL::mysql_static)
+endif ()
+
+# Shared library.
+if (MySQL_mysql_shared_FOUND AND NOT TARGET MySQL::mysql_shared)
+	add_library(MySQL::mysql_shared SHARED IMPORTED)
+	set_target_properties(MySQL::mysql_shared PROPERTIES
+			IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+			INTERFACE_INCLUDE_DIRECTORIES     "${MySQL_INCLUDE_DIR}"
+	)
+	if (WIN32)
+		set_target_properties(MySQL::mysql_shared PROPERTIES
+			IMPORTED_IMPLIB "${MySQL_LIBRARY}"
+		)
+		if (MySQL_DLL_LIBRARY)
+			set_target_properties(MySQL::mysql_shared PROPERTIES
+				IMPORTED_LOCATION "${MySQL_DLL_LIBRARY}"
+			)
+		endif ()
+	else ()
+		set_target_properties(MySQL::mysql_shared PROPERTIES
+			IMPORTED_LOCATION "${MySQL_LIBRARY}"
+		)
+	endif ()
+	set(_mysql_any MySQL::mysql_shared)
+endif ()
+
+# I-don't-care library (shared, or static if shared not available).
+if (MySQL_mysql_FOUND AND NOT TARGET MySQL::mysql)
+	add_library(MySQL::mysql INTERFACE IMPORTED)
+	set_target_properties(MySQL::mysql PROPERTIES
+		INTERFACE_LINK_LIBRARIES ${_mysql_any}
+	)
+endif ()
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
+
+# From https://github.com/Monetra/mstdlib/blob/master/CMakeModules
+# The MIT License (MIT)
+
+# Copyright (c) 2015-2017 Main Street Softworks, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.

+ 260 - 0
cmake/FindPostgreSQL.cmake

@@ -0,0 +1,260 @@
+# Find PostgreSQL.
+#
+# Specifically, this finds the C client library (libpq) that can be used to talk to PostgreSQL databases.
+#
+# Set this variable to any additional path you want the module to search:
+#  PostgreSQL_DIR
+#
+# Imported targets defined by this module:
+#  PostgreSQL::pq        - shared library if available, or static if that's all there is
+#  PostgreSQL::pq_shared - shared library
+#  PostgreSQL::pq_static - static library
+#
+# Informational variables:
+#  PostgreSQL_FOUND      - PostgreSQL (or all requested components of PostgreSQL) was found.
+#  PostgreSQL_VERSION    - the version of PostgreSQL that was found
+#
+
+include(CacheLog)
+include(FindPackageHandleStandardArgs)
+
+# Helper function for globbing for directories.
+function(append_glob_dirs list_name glob_path)
+	file(TO_CMAKE_PATH "${glob_path}" glob_path)
+	file(GLOB dirs LIST_DIRECTORIES true "${glob_path}")
+	if (dirs)
+		list(APPEND ${list_name} "${dirs}")
+		set(${list_name} "${${list_name}}" PARENT_SCOPE)
+	endif ()
+endfunction()
+
+# If PostgreSQL_DIR has changed since the last invocation, wipe internal cache variables so we can search for everything
+# again.
+if (NOT "${PostgreSQL_DIR}" STREQUAL "${_internal_old_postgresql_dir}")
+	unset_cachelog_entries()
+endif ()
+reset_cachelog()
+
+set(_old_suffixes "${CMAKE_FIND_LIBRARY_SUFFIXES}")
+
+# Set path guesses.
+set(_paths)
+if (CMAKE_HOST_WIN32)
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(archdir    "$ENV{ProgramFiles}")
+		set(notarchdir "$ENV{ProgramFiles\(x86\)}")
+		set(arch       64)
+	else ()
+		set(archdir    "$ENV{ProgramFiles\(x86\)}")
+		set(notarchdir "$ENV{ProgramFiles}")
+		set(arch       32)
+	endif ()
+	# This should find installations from either the BigSQL or EDB Postgres installers.
+	# (Note: I'd recommend BigSQL, it's built with MinGW, so it's easier to package)
+	list(APPEND _paths /PostgreSQL${arch})
+	append_glob_dirs(_paths "/PostgreSQL${arch}/pg*/")
+	list(APPEND _paths /PostgreSQL)
+	append_glob_dirs(_paths "/PostgreSQL/pg*/")
+	list(APPEND _paths "${archdir}/PostgreSQL")
+	append_glob_dirs(_paths "${archdir}/PostgreSQL/*/")
+	list(APPEND _paths "${notarchdir}/PostgreSQL")
+	append_glob_dirs(_paths "${notarchdir}/PostgreSQL/*/")
+else ()
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(arch 64)
+	else ()
+		set(arch 32)
+	endif ()
+	list(APPEND _paths
+		/usr/local/postgresql${arch}
+		/usr/local/pgsql${arch}
+		/usr/local/postgresql
+		/usr/local/pgsql
+	)
+	append_glob_dirs(_paths "/usr/pgsql-*")
+endif ()
+
+# Find include directory.
+find_path(PostgreSQL_INCLUDE_DIR
+	NAMES         libpq-fe.h
+	HINTS         ${PostgreSQL_DIR}
+	              $ENV{PostgreSQL_DIR}
+	              ${POSTGRESQL_ROOT_DIR}
+	PATHS         ${_paths}
+	PATH_SUFFIXES include include/postgresql postgresql
+)
+add_to_cachelog(PostgreSQL_INCLUDE_DIR)
+
+if (PostgreSQL_INCLUDE_DIR)
+	# Calculate root directory of installation from include directory.
+	string(REGEX REPLACE "(/)*include(/)*.*$" "" _root_dir "${PostgreSQL_INCLUDE_DIR}")
+	set(PostgreSQL_DIR "${_root_dir}" CACHE PATH "Root directory of PostgreSQL installation" FORCE)
+	set(_internal_old_postgresql_dir "${PostgreSQL_DIR}" CACHE INTERNAL "" FORCE)
+	mark_as_advanced(FORCE PostgreSQL_DIR)
+	
+	# Find version by parsing the pg_config.h header.
+	set(header "${PostgreSQL_INCLUDE_DIR}/pg_config_x86_64.h")
+	if (NOT EXISTS "${header}")
+		set(header "${PostgreSQL_INCLUDE_DIR}/pg_config_x86.h")
+		if (NOT EXISTS "${header}")
+			set(header "${PostgreSQL_INCLUDE_DIR}/pg_config.h")
+			if (NOT EXISTS "${header}")
+				set(header)
+			endif ()
+		endif ()
+	endif ()
+
+	if (header)
+		file(STRINGS "${header}" _ver_str
+			REGEX "^[ \t]*#[ \t]*define[\t ]+PG_VERSION[ \t]+\".*\"")
+		if (_ver_str MATCHES "^[ \t]*#[ \t]*define[\t ]+PG_VERSION[ \t]+\"([^\"]*)\"")
+			set(PostgreSQL_VERSION "${CMAKE_MATCH_1}")
+		endif ()
+	endif ()
+	
+	# Find static library (if not on Windows, none of the installers I could find there had a static libpq)).
+	if (WIN32)
+		set(PostgreSQL_STATIC_LIBRARY "PostgreSQL_STATIC_LIBRARY-NOTFOUND" CACHE PATH "Path to libpq static lib")
+	else ()
+		set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+		foreach(defpath "NO_DEFAULT_PATH" "")
+			find_library(PostgreSQL_STATIC_LIBRARY
+				NAMES         pq libpq
+				NAMES_PER_DIR
+				HINTS         ${PostgreSQL_DIR}
+				PATH_SUFFIXES lib
+				${defpath}
+			)
+			if (PostgreSQL_STATIC_LIBRARY)
+				break()
+			endif ()
+		endforeach()
+	endif ()
+	add_to_cachelog(PostgreSQL_STATIC_LIBRARY)
+	if (PostgreSQL_STATIC_LIBRARY)
+		set(PostgreSQL_pq_static_FOUND TRUE)
+		set(PostgreSQL_pq_FOUND TRUE)
+	endif ()
+	
+	# Find shared library (will pick up static lib if shared not found).
+	set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
+	if (WIN32)
+		list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".a") #BigSQL installer names the import lib with a .a extension
+	endif ()
+	foreach(defpath "NO_DEFAULT_PATH" "")
+		find_library(PostgreSQL_LIBRARY
+			NAMES         pq libpq
+			NAMES_PER_DIR
+			HINTS         ${PostgreSQL_DIR}
+			PATH_SUFFIXES lib
+			${defpath}
+		)
+		if (PostgreSQL_LIBRARY)
+			break()
+		endif ()
+	endforeach()
+	add_to_cachelog(PostgreSQL_LIBRARY)
+	if (PostgreSQL_LIBRARY AND NOT PostgreSQL_LIBRARY STREQUAL PostgreSQL_STATIC_LIBRARY)
+		set(PostgreSQL_pq_shared_FOUND TRUE)
+		set(PostgreSQL_pq_FOUND TRUE)
+	endif ()
+	
+	# Find the DLL (if any).
+	if (WIN32)
+		set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
+		foreach(defpath "NO_DEFAULT_PATH" "")
+			find_library(PostgreSQL_DLL_LIBRARY
+				NAMES         pq libpq
+				NAMES_PER_DIR
+				HINTS         ${PostgreSQL_DIR}
+				PATH_SUFFIXES bin lib ""
+				${defpath}
+			)
+			if (PostgreSQL_DLL_LIBRARY)
+				break()
+			endif ()
+		endforeach()
+		add_to_cachelog(PostgreSQL_DLL_LIBRARY)
+	endif ()
+endif ()
+
+set(_reqs PostgreSQL_INCLUDE_DIR)
+if (NOT PostgreSQL_FIND_COMPONENTS) # If user didn't request any particular component explicitly:
+	list(APPEND _reqs PostgreSQL_LIBRARY) # Will contain shared lib, or static lib if no shared lib present
+endif ()
+
+find_package_handle_standard_args(PostgreSQL
+	REQUIRED_VARS     ${_reqs}
+	VERSION_VAR       PostgreSQL_VERSION
+	HANDLE_COMPONENTS
+	FAIL_MESSAGE      "PostgreSQL not found, try -DPostgreSQL_DIR=<path>"
+)
+add_to_cachelog(FIND_PACKAGE_MESSAGE_DETAILS_PostgreSQL)
+
+# Static library.
+if (PostgreSQL_pq_static_FOUND AND NOT TARGET PostgreSQL::pq_static)
+	add_library(PostgreSQL::pq_static STATIC IMPORTED)
+	set_target_properties(PostgreSQL::pq_static PROPERTIES
+		IMPORTED_LOCATION                 "${PostgreSQL_STATIC_LIBRARY}"
+		IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+		INTERFACE_INCLUDE_DIRECTORIES     "${PostgreSQL_INCLUDE_DIR}"
+	)
+	set(_pq_any PostgreSQL::pq_static)
+endif ()
+
+# Shared library.
+if (PostgreSQL_pq_shared_FOUND AND NOT TARGET PostgreSQL::pq_shared)
+	add_library(PostgreSQL::pq_shared SHARED IMPORTED)
+	set_target_properties(PostgreSQL::pq_shared PROPERTIES
+			IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+			INTERFACE_INCLUDE_DIRECTORIES     "${PostgreSQL_INCLUDE_DIR}"
+	)
+	if (WIN32)
+		set_target_properties(PostgreSQL::pq_shared PROPERTIES
+			IMPORTED_IMPLIB "${PostgreSQL_LIBRARY}"
+		)
+		if (PostgreSQL_DLL_LIBRARY)
+			set_target_properties(PostgreSQL::pq_shared PROPERTIES
+				IMPORTED_LOCATION "${PostgreSQL_DLL_LIBRARY}"
+			)
+		endif ()
+	else ()
+		set_target_properties(PostgreSQL::pq_shared PROPERTIES
+			IMPORTED_LOCATION "${PostgreSQL_LIBRARY}"
+		)
+	endif ()
+	set(_pq_any PostgreSQL::pq_shared)
+endif ()
+
+# I-don't-care library (shared, or static if shared not available).
+if (PostgreSQL_pq_FOUND AND NOT TARGET PostgreSQL::pq)
+	add_library(PostgreSQL::pq INTERFACE IMPORTED)
+	set_target_properties(PostgreSQL::pq PROPERTIES
+		INTERFACE_LINK_LIBRARIES ${_pq_any}
+	)
+endif ()
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
+
+# From https://github.com/Monetra/mstdlib/blob/master/CMakeModules
+# The MIT License (MIT)
+
+# Copyright (c) 2015-2017 Main Street Softworks, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.

+ 224 - 0
cmake/FindSQLite.cmake

@@ -0,0 +1,224 @@
+# Find SQLite.
+#
+# Set this variable to any additional path you want the module to search:
+#  SQLite_DIR
+#
+# Imported targets defined by this module:
+#  SQLite::sqlite        - shared library if available, or static if that's all there is
+#  SQLite::sqlite_shared - shared library
+#  SQLite::sqlite_static - static library
+#
+# Informational variables:
+#  SQLite_FOUND          - sqlite (or all requested components of sqlite) was found.
+#  SQLite_VERSION        - the version of sqlite that was found
+#
+
+include(CacheLog)
+include(FindPackageHandleStandardArgs)
+
+# If SQLite_DIR has changed since the last invocation, wipe internal cache variables so we can search for everything
+# again.
+if (NOT "${SQLite_DIR}" STREQUAL "${_internal_old_sqlite_dir}")
+	unset_cachelog_entries()
+endif ()
+reset_cachelog()
+
+set(_old_suffixes "${CMAKE_FIND_LIBRARY_SUFFIXES}")
+
+find_package(PkgConfig QUIET)
+if (PKG_CONFIG_FOUND)
+	PKG_CHECK_MODULES(PC_SQLite QUIET sqlite)
+endif ()
+
+if (CMAKE_HOST_WIN32)
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(archdir    "$ENV{ProgramFiles}")
+		set(notarchdir "$ENV{ProgramFiles\(x86\)}")
+	else ()
+		set(archdir    "$ENV{ProgramFiles\(x86\)}")
+		set(notarchdir "$ENV{ProgramFiles}")
+	endif ()
+	set(_paths
+		"${archdir}/sqlite"
+		"${archdir}/sqlite3"
+		"${notarchdir}/sqlite"
+		"${notarchdir}/sqlite3"
+	)
+else ()
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(arch 64)
+	else ()
+		set(arch 32)
+	endif ()
+	set(_paths
+		/usr/local/sqlite${arch}
+		/usr/locla/sqlite
+		/usr/local/sqlite3
+	)
+endif ()
+
+find_path(SQLite_INCLUDE_DIR
+	NAMES         sqlite3.h
+	HINTS         ${SQLite_DIR}
+	              $ENV{SQLite_DIR}
+	              ${SQLITE_ROOT_DIR}
+	              ${PC_SQLite_INCLUDE_DIRS}
+	PATHS         ${_paths}
+	PATH_SUFFIXES include
+)
+add_to_cachelog(SQLite_INCLUDE_DIR)
+
+if (SQLite_INCLUDE_DIR)
+	# Calculate root directory of installation from include directory.
+	string(REGEX REPLACE "(/)*include(/)*$" "" _root_dir "${SQLite_INCLUDE_DIR}")
+	set(SQLite_DIR "${_root_dir}" CACHE PATH "Root directory of SQLite installation" FORCE)
+	set(_internal_old_sqlite_dir "${SQLite_DIR}" CACHE INTERNAL "" FORCE)
+	mark_as_advanced(FORCE SQLite_DIR)
+
+	# Find version by parsing SQLite header.
+	if (EXISTS "${SQLite_INCLUDE_DIR}/sqlite3.h")
+		file(STRINGS "${SQLite_INCLUDE_DIR}/sqlite3.h" sqlite_version_str
+			REGEX "^[ \t]*#[ \t]*define[\t ]+SQLITE_VERSION[ \t]+\".*\"")
+		if (sqlite_version_str MATCHES "^[ \t]*#[ \t]*define[\t ]+SQLITE_VERSION[ \t]+\"([^\"]*)\"")
+			set(SQLite_VERSION "${CMAKE_MATCH_1}")
+		endif ()
+	endif ()
+
+	# Find static library.
+	set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+	foreach(defpath "NO_DEFAULT_PATH" "")
+		find_library(SQLite_STATIC_LIBRARY
+			NAMES         sqlite_static sqlite3_static sqlitestatic sqlite3static sqlite sqlite3
+			NAMES_PER_DIR
+			HINTS         ${SQLite_DIR} ${PC_SQLite_LIBRARY_DIRS}
+			PATH_SUFFIXES lib ""
+			${defpath}
+		)
+		if (SQLite_STATIC_LIBRARY)
+			break()
+		endif ()
+	endforeach()
+	add_to_cachelog(SQLite_STATIC_LIBRARY)
+	if (SQLite_STATIC_LIBRARY)
+		set(SQLite_sqlite_static_FOUND TRUE)
+		set(SQLite_sqlite_FOUND TRUE)
+	endif ()
+
+	# Find shared library (will pick up static lib if shared not found).
+	set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
+	foreach(defpath "NO_DEFAULT_PATH" "")
+		find_library(SQLite_LIBRARY
+			NAMES         sqlite sqlite3 sqlite_satic sqlite3_static sqlitestatic sqlite3static
+			NAMES_PER_DIR
+			HINTS         ${SQLite_DIR} ${PC_SQLite_LIBRARY_DIRS}
+			PATH_SUFFIXES lib ""
+			${defpath}
+		)
+		if (SQLite_LIBRARY)
+			break()
+		endif ()
+	endforeach()
+	add_to_cachelog(SQLite_LIBRARY)
+	if (SQLite_LIBRARY AND NOT SQLite_LIBRARY STREQUAL SQLite_STATIC_LIBRARY)
+		set(SQLite_sqlite_shared_FOUND TRUE)
+		set(SQLite_sqlite_FOUND TRUE)
+	endif ()
+	
+	# Look for the DLL.
+	if (WIN32)
+		set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
+		foreach(defpath "NO_DEFAULT_PATH" "")
+			find_library(SQLite_DLL_LIBRARY
+				NAMES         sqlite sqlite3
+				NAMES_PER_DIR
+				HINTS         ${SQLite_DIR}
+				PATH_SUFFIXES bin lib ""
+				${defpath}
+			)
+			if (SQLite_DLL_LIBRARY)
+				break()
+			endif ()
+		endforeach()
+		add_to_cachelog(SQLite_DLL_LIBRARY)
+	endif ()
+endif ()
+
+set(_reqs SQLite_INCLUDE_DIR)
+if (NOT SQLite_FIND_COMPONENTS) # If user didn't request any particular component explicitly:
+	list(APPEND _reqs SQLite_LIBRARY) # Will contain shared lib, or static lib if no shared lib present
+endif ()
+
+find_package_handle_standard_args(SQLite
+	REQUIRED_VARS     ${_reqs}
+	VERSION_VAR       SQLite_VERSION
+	HANDLE_COMPONENTS
+	FAIL_MESSAGE      "SQLite not found, try -DSQLite_DIR=<path>"
+)
+
+# Static library.
+if (SQLite_sqlite_static_FOUND AND NOT TARGET SQLite::sqlite_static)
+	add_library(SQLite::sqlite_static STATIC IMPORTED)
+	set_target_properties(SQLite::sqlite_static PROPERTIES
+		IMPORTED_LOCATION                 "${SQLite_STATIC_LIBRARY}"
+		IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+		INTERFACE_INCLUDE_DIRECTORIES     "${SQLite_INCLUDE_DIR}"
+	)
+	set(_sqlite_any SQLite::sqlite_static)
+endif ()
+
+# Shared library.
+if (SQLite_sqlite_shared_FOUND AND NOT TARGET SQLite::sqlite_shared)
+	add_library(SQLite::sqlite_shared SHARED IMPORTED)
+	set_target_properties(SQLite::sqlite_shared PROPERTIES
+			IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+			INTERFACE_INCLUDE_DIRECTORIES     "${SQLite_INCLUDE_DIR}"
+	)
+	if (WIN32)
+		set_target_properties(SQLite::sqlite_shared PROPERTIES
+			IMPORTED_IMPLIB "${SQLite_LIBRARY}"
+		)
+		if (SQLite_DLL_LIBRARY)
+			set_target_properties(SQLite::sqlite_shared PROPERTIES
+				IMPORTED_LOCATION "${SQLite_DLL_LIBRARY}"
+			)
+		endif ()
+	else ()
+		set_target_properties(SQLite::sqlite_shared PROPERTIES
+			IMPORTED_LOCATION "${SQLite_LIBRARY}"
+		)
+	endif ()
+	set(_sqlite_any SQLite::sqlite_shared)
+endif ()
+
+# I-don't-care library (shared, or static if shared not available).
+if (SQLite_sqlite_FOUND AND NOT TARGET SQLite::sqlite)
+	add_library(SQLite::sqlite INTERFACE IMPORTED)
+	set_target_properties(SQLite::sqlite PROPERTIES
+		INTERFACE_LINK_LIBRARIES ${_sqlite_any}
+	)
+endif ()
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
+
+# From https://github.com/Monetra/mstdlib/blob/master/CMakeModules
+# The MIT License (MIT)
+
+# Copyright (c) 2015-2017 Main Street Softworks, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.

+ 57 - 0
cmake/cmake_uninstall.cmake.in

@@ -0,0 +1,57 @@
+# Author: Kang Lin([email protected])
+
+# Use: Please add the follow code to CMakeLists.txt
+
+# # Install runtime target
+# add_custom_target(install-runtime
+#  COMMAND
+#     "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=Runtime 
+#     -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake"
+# )
+# # Uninstall runtime target
+# add_custom_target(uninstall-runtime
+#  COMMAND
+#     "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=Runtime 
+#     -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+# )
+# # Create will be delete files
+# CONFIGURE_FILE(
+#    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+#    "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
+#    IMMEDIATE @ONLY)
+# # Create unistall target
+# ADD_CUSTOM_TARGET(uninstall
+#    "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
+#    DEPENDS uninstall-runtime)
+
+
+if(CMAKE_INSTALL_COMPONENT)
+    set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
+else()
+    set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
+endif()
+
+IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/${CMAKE_INSTALL_MANIFEST}")
+    MESSAGE(WARNING "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/${CMAKE_INSTALL_MANIFEST}\"")
+ELSE()
+
+    FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/${CMAKE_INSTALL_MANIFEST}" files)
+    STRING(REGEX REPLACE "\n" ";" files "${files}")
+    FOREACH(file ${files})
+        MESSAGE(STATUS "Uninstalling \"${file}\"")
+        IF(EXISTS "${file}")
+            EXEC_PROGRAM(
+                "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\""
+                OUTPUT_VARIABLE rm_out
+                RETURN_VALUE rm_retval
+                )
+            IF("${rm_retval}" STREQUAL 0)
+            ELSE("${rm_retval}" STREQUAL 0)
+                MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"")
+            ENDIF("${rm_retval}" STREQUAL 0)
+        ELSE(EXISTS "${file}")
+            MESSAGE(STATUS "File \"${file}\" does not exist.")
+        ENDIF(EXISTS "${file}")
+    ENDFOREACH(file)
+
+ENDIF()

+ 8 - 0
src/CMakeLists.txt

@@ -0,0 +1,8 @@
+# Author: Kang Lin ([email protected])
+
+project(coturn)
+
+add_subdirectory(client)
+add_subdirectory(server)
+add_subdirectory(apps)
+

+ 10 - 0
src/apps/CMakeLists.txt

@@ -0,0 +1,10 @@
+# Author: Kang Lin ([email protected])
+
+add_subdirectory(common)
+add_subdirectory(natdiscovery)
+add_subdirectory(oauth)
+add_subdirectory(peer)
+add_subdirectory(relay)
+add_subdirectory(rfc5769)
+add_subdirectory(stunclient)
+add_subdirectory(uclient)

+ 89 - 0
src/apps/common/CMakeLists.txt

@@ -0,0 +1,89 @@
+# Author: Kang Lin ([email protected])
+
+project(turncommon)
+
+set(SOURCE_FILES
+    apputils.c
+    ns_turn_utils.c
+    stun_buffer.c
+    )
+
+set(HEADER_FILES
+    apputils.h
+    ns_turn_openssl.h
+    ns_turn_utils.h
+    stun_buffer.h
+    )
+
+if(NOT WIN32)
+    set(COMMON_LIBS pthread)
+endif()
+set(libevent_components core extra openssl)
+if(NOT WIN32)
+    list(APPEND libevent_components pthreads)
+endif()
+find_package(Libevent COMPONENTS ${libevent_components})
+if(Libevent_FOUND)
+    foreach(_libevent_com ${libevent_components})
+        list(APPEND COMMON_LIBS Libevent::${_libevent_com})
+    endforeach()
+endif()
+
+find_package(hiredis)
+if(hiredis_FOUND)
+    list(APPEND SOURCE_FILES hiredis_libevent2.c)
+    list(APPEND HEADER_FILES hiredis_libevent2.h)
+    list(APPEND COMMON_LIBS hiredis::hiredis)
+else()
+    list(APPEND COMMON_DEFINED TURN_NO_HIREDIS)
+endif()
+message("COMMON_LIBS:${COMMON_LIBS}")
+
+add_library(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES})
+
+target_link_libraries(${PROJECT_NAME} PUBLIC ${COMMON_LIBS})
+target_compile_definitions(${PROJECT_NAME} PUBLIC ${COMMON_DEFINED})
+
+# See: http://www.it1352.com/478094.html
+target_include_directories(${PROJECT_NAME} PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/server>
+    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src>
+    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/client>
+    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/apps/common>
+    ${COMMON_INCLUDE_DIR}
+    )
+
+# Install head files
+set_target_properties(${PROJECT_NAME} PROPERTIES
+    VERSION ${VERSION}
+    )
+
+INSTALL(TARGETS ${PROJECT_NAME}
+    EXPORT ${PROJECT_NAME}Config
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    INCLUDES DESTINATION
+        ${CMAKE_INSTALL_INCLUDEDIR}
+        ${CMAKE_INSTALL_INCLUDEDIR}/turn
+        ${CMAKE_INSTALL_INCLUDEDIR}/turn/client
+    )
+
+export(TARGETS ${PROJECT_NAME}
+    APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake
+    )
+
+# Install cmake configure files
+install(EXPORT ${PROJECT_NAME}Config
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake"
+    )
+# Install cmake version configure file
+if(DEFINED VERSION)
+    write_basic_package_version_file(
+        "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+        VERSION ${VERSION}
+        COMPATIBILITY AnyNewerVersion)
+    install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake")
+endif()

+ 13 - 0
src/apps/natdiscovery/CMakeLists.txt

@@ -0,0 +1,13 @@
+# Author: Kang Lin ([email protected])
+
+project(turnutils_natdiscovery)
+
+set(SOURCE_FILES
+    natdiscovery.c
+    )
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 13 - 0
src/apps/oauth/CMakeLists.txt

@@ -0,0 +1,13 @@
+# Author: Kang Lin ([email protected])
+
+project(turnutils_oauth)
+
+set(SOURCE_FILES
+    oauth.c
+    )
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 13 - 0
src/apps/peer/CMakeLists.txt

@@ -0,0 +1,13 @@
+# Author: Kang Lin ([email protected])
+
+project(turnutils_peer)
+
+set(SOURCE_FILES
+    mainudpserver.c udpserver.c
+    )
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 99 - 0
src/apps/relay/CMakeLists.txt

@@ -0,0 +1,99 @@
+# Author: Kang Lin ([email protected])
+
+project(turnserver)
+
+set(HEAD_FILES
+    tls_listener.h
+    mainrelay.h
+    turn_admin_server.h
+    dtls_listener.h
+    libtelnet.h
+    ns_ioalib_impl.h
+    ns_sm.h
+    turn_ports.h
+    userdb.h
+    dbdrivers/dbdriver.h
+    )
+
+set(SOURCE_FILES
+    mainrelay.c
+    netengine.c
+    libtelnet.c
+    turn_admin_server.c
+    tls_listener.c
+    dtls_listener.c
+    ns_ioalib_engine_impl.c
+    turn_ports.c
+    http_server.c
+    acme.c
+    userdb.c
+    dbdrivers/dbdriver.c
+    )
+
+find_package(SQLite)
+if(SQLite_FOUND)
+    list(APPEND turnserver_LIBS SQLite::sqlite)
+    list(APPEND SOURCE_FILES dbdrivers/dbd_sqlite.c)
+    list(APPEND HEAD_FILES dbdrivers/dbd_sqlite.h)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_SQLITE)
+endif()
+
+find_package(PostgreSQL)
+if(PostgreSQL_FOUND)
+    list(APPEND turnserver_LIBS PostgreSQL::pq)
+    list(APPEND SOURCE_FILES dbdrivers/dbd_pgsql.c)
+    list(APPEND HEAD_FILES dbdrivers/dbd_pgsql.h)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_PQ)
+endif()
+
+find_package(MySQL)
+if(MySQL_FOUND)
+    list(APPEND turnserver_LIBS MySQL::mysql)
+    list(APPEND SOURCE_FILES dbdrivers/dbd_mysql.c)
+    list(APPEND HEAD_FILES dbdrivers/dbd_mysql.h)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_MYSQL)
+endif()
+
+find_package(mongo)
+if(mongo_FOUND)
+    list(APPEND turnserver_LIBS mongo)
+    list(APPEND SOURCE_FILES dbdrivers/dbd_mongo.c)
+    list(APPEND HEAD_FILES dbdrivers/dbd_mongo.h)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_MONGO)
+endif()
+
+find_package(hiredis)
+if(hiredis_FOUND)
+    list(APPEND turnserver_LIBS hiredis::hiredis)
+    list(APPEND SOURCE_FILES dbdrivers/dbd_redis.c)
+    list(APPEND HEAD_FILES dbdrivers/dbd_redis.h)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_HIREDIS)
+endif()
+
+find_package(libsystemd)
+if(libsystemd_FOUND)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_SYSTEMD)
+endif()
+
+find_package(Prometheus)
+if(Prometheus_FOUND)
+    list(APPEND SOURCE_FILES prom_server.c)
+    list(APPEND HEAD_FILES prom_server.h)
+else()
+    list(APPEND turnserver_DEFINED TURN_NO_PROMETHEUS)
+endif()
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEAD_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turn_server ${turnserver_LIBS})
+target_include_directories(${PROJECT_NAME} PRIVATE ${turnserver_include_dirs})
+target_compile_definitions(${PROJECT_NAME} PRIVATE ${turnserver_DEFINED})
+
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 13 - 0
src/apps/rfc5769/CMakeLists.txt

@@ -0,0 +1,13 @@
+# Author: Kang Lin ([email protected])
+
+project(turnutils_rfc5769check)
+
+set(SOURCE_FILES
+    rfc5769check.c
+    )
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 13 - 0
src/apps/stunclient/CMakeLists.txt

@@ -0,0 +1,13 @@
+# Author: Kang Lin ([email protected])
+
+project(turnutils_stunclient)
+
+set(SOURCE_FILES
+    stunclient.c
+    )
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 15 - 0
src/apps/uclient/CMakeLists.txt

@@ -0,0 +1,15 @@
+# Author: Kang Lin ([email protected])
+
+project(turnutils_uclient)
+
+set(SOURCE_FILES
+    uclient.c
+    startuclient.c
+    mainuclient.c
+    )
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
+INSTALL(TARGETS ${PROJECT_NAME}
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    )

+ 61 - 0
src/client/CMakeLists.txt

@@ -0,0 +1,61 @@
+# Author: Kang Lin ([email protected])
+
+project(turnclient)
+
+find_package(OpenSSL REQUIRED)
+
+set(HEADER_FILES
+    ${CMAKE_SOURCE_DIR}/src/ns_turn_defs.h
+    ${CMAKE_SOURCE_DIR}/src/client++/TurnMsgLib.h
+    ns_turn_ioaddr.h
+    ns_turn_msg.h
+    ns_turn_msg_defs.h
+    ns_turn_msg_defs_experimental.h
+    ns_turn_msg_addr.h
+    )
+
+set(SOURCE_FILES
+    ns_turn_ioaddr.c
+    ns_turn_msg_addr.c
+    ns_turn_msg.c
+    )
+
+add_library(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES})
+
+target_link_libraries(${PROJECT_NAME} PUBLIC turncommon OpenSSL::SSL OpenSSL::Crypto)
+
+# Install head files
+set_target_properties(${PROJECT_NAME} PROPERTIES
+    PUBLIC_HEADER "${HEADER_FILES}"
+    VERSION ${VERSION}
+    )
+
+INSTALL(TARGETS ${PROJECT_NAME}
+    EXPORT ${PROJECT_NAME}Config
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/turn/client
+    INCLUDES DESTINATION
+        ${CMAKE_INSTALL_INCLUDEDIR}
+        ${CMAKE_INSTALL_INCLUDEDIR}/turn
+        ${CMAKE_INSTALL_INCLUDEDIR}/turn/client
+    )
+
+export(TARGETS ${PROJECT_NAME}
+    APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake
+    )
+
+# Install cmake configure files
+install(EXPORT ${PROJECT_NAME}Config
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake"
+    )
+# Install cmake version configure file
+if(DEFINED VERSION)
+    write_basic_package_version_file(
+        "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+        VERSION ${VERSION}
+        COMPATIBILITY AnyNewerVersion)
+    install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake")
+endif()

+ 63 - 0
src/server/CMakeLists.txt

@@ -0,0 +1,63 @@
+# Author: Kang Lin ([email protected])
+
+project(turn_server)
+
+set(SOURCE_FILES
+    ns_turn_allocation.c
+    ns_turn_maps_rtcp.c
+    ns_turn_maps.c
+    ns_turn_server.c
+    )
+
+set(HEADER_FILES
+    ns_turn_allocation.h
+    ns_turn_ioalib.h
+    ns_turn_khash.h
+    ns_turn_maps_rtcp.h
+    ns_turn_maps.h
+    ns_turn_server.h
+    ns_turn_session.h
+    )
+
+add_library(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES})
+
+target_link_libraries(${PROJECT_NAME} PUBLIC turnclient)
+
+# See: http://www.it1352.com/478094.html
+target_include_directories(${PROJECT_NAME} PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+    )
+
+# Install head files
+set_target_properties(${PROJECT_NAME} PROPERTIES
+    VERSION ${VERSION}
+    )
+
+INSTALL(TARGETS ${PROJECT_NAME}
+    EXPORT ${PROJECT_NAME}Config
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    INCLUDES DESTINATION
+        ${CMAKE_INSTALL_INCLUDEDIR}
+        ${CMAKE_INSTALL_INCLUDEDIR}/turn
+        ${CMAKE_INSTALL_INCLUDEDIR}/turn/client
+    )
+
+export(TARGETS ${PROJECT_NAME}
+    APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake
+    )
+
+# Install cmake configure files
+install(EXPORT ${PROJECT_NAME}Config
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake"
+    )
+# Install cmake version configure file
+if(DEFINED VERSION)
+    write_basic_package_version_file(
+        "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+        VERSION ${VERSION}
+        COMPATIBILITY AnyNewerVersion)
+    install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake")
+endif()