summaryrefslogtreecommitdiffstats
path: root/CMakeModules
diff options
context:
space:
mode:
Diffstat (limited to 'CMakeModules')
-rw-r--r--CMakeModules/ABICheck.cmake66
-rw-r--r--CMakeModules/FindCMocka.cmake49
-rw-r--r--CMakeModules/FindPCRE2.cmake62
-rw-r--r--CMakeModules/FindUncrustify.cmake21
-rw-r--r--CMakeModules/GenCoverage.cmake118
-rw-r--r--CMakeModules/GenDoc.cmake28
-rw-r--r--CMakeModules/SourceFormat.cmake36
-rw-r--r--CMakeModules/UseCompat.cmake75
-rw-r--r--CMakeModules/uninstall.cmake27
9 files changed, 482 insertions, 0 deletions
diff --git a/CMakeModules/ABICheck.cmake b/CMakeModules/ABICheck.cmake
new file mode 100644
index 0000000..d5f305b
--- /dev/null
+++ b/CMakeModules/ABICheck.cmake
@@ -0,0 +1,66 @@
+# generate API/ABI report
+macro(LIB_ABI_CHECK LIB_TARGET LIB_HEADERS LIB_SOVERSION_FULL ABI_BASE_HASH)
+ # get short hash
+ string(SUBSTRING "${ABI_BASE_HASH}" 0 8 ABI_BASE_HASH_SHORT)
+
+ # find abi-dumper
+ find_program(ABI_DUMPER abi-dumper)
+ find_package_handle_standard_args(abi-dumper DEFAULT_MSG ABI_DUMPER)
+ if(NOT ABI_DUMPER)
+ message(FATAL_ERROR "Program abi-dumper not found!")
+ endif()
+
+ # find abi-checker
+ find_program(ABI_CHECKER abi-compliance-checker)
+ find_package_handle_standard_args(abi-compliance-checker DEFAULT_MSG ABI_CHECKER)
+ if(NOT ABI_CHECKER)
+ message(FATAL_ERROR "Program abi-compliance-checker not found!")
+ endif()
+
+ # abi-dump target - generating an ABI dump
+ set(PUBLIC_HEADERS ${LIB_HEADERS})
+ string(PREPEND PUBLIC_HEADERS "${CMAKE_SOURCE_DIR}/")
+ string(REPLACE ";" "\n${CMAKE_SOURCE_DIR}/" PUBLIC_HEADERS "${PUBLIC_HEADERS}")
+ file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/public_headers CONTENT "${PUBLIC_HEADERS}")
+ add_custom_target(abi-dump
+ COMMAND ${ABI_DUMPER} ./lib${LIB_TARGET}${CMAKE_SHARED_LIBRARY_SUFFIX}
+ -o lib${LIB_TARGET}.${LIB_SOVERSION_FULL}.dump
+ -lver ${LIB_SOVERSION_FULL} -public-headers ${CMAKE_BINARY_DIR}/public_headers
+ DEPENDS ${LIB_TARGET}
+ BYPRODUCTS ${CMAKE_BINARY_DIR}/lib${LIB_TARGET}.${LIB_SOVERSION_FULL}.dump
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Dumping ABI information of version ${LIB_SOVERSION_FULL} for abi-check")
+
+ # get URL for fetching origin
+ execute_process(COMMAND git remote get-url origin OUTPUT_VARIABLE ORIGIN_URL OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ # generate script for generating the base ABI dump
+ file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/abibase.sh CONTENT "#!/bin/sh
+if [ ! -d abibase ]; then mkdir abibase; fi
+cd abibase
+if [ ! -f build/lib${LIB_TARGET}.*.dump ]; then
+ if [ -d .git ] && [ \"${ABI_BASE_HASH}\" != \"`git log --pretty=oneline | cut -d' ' -f1`\" ]; then rm -rf .* 2> /dev/null; fi
+ if [ ! -d .git ]; then
+ git init --initial-branch=master
+ git remote add origin ${ORIGIN_URL}
+ git fetch origin --depth 1 ${ABI_BASE_HASH}
+ git reset --hard FETCH_HEAD
+ fi
+ if [ ! -d build ]; then mkdir build; fi
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=ABICheck ..
+ make abi-dump
+fi
+")
+
+ # abi-check target - check ABI compatibility of current version and the base hash version
+ add_custom_target(abi-check
+ COMMAND bash ./abibase.sh
+ COMMAND ${ABI_CHECKER} -l lib${LIB_TARGET}${CMAKE_SHARED_LIBRARY_SUFFIX}
+ -old abibase/build/lib${LIB_TARGET}.*.dump
+ -new ./lib${LIB_TARGET}.${LIB_SOVERSION_FULL}.dump
+ DEPENDS ${LIB_TARGET} abi-dump
+ BYPRODUCTS ${CMAKE_BINARY_DIR}/compat_reports/lib${LIB_TARGET}${CMAKE_SHARED_LIBRARY_SUFFIX}/*_to_${LIB_SOVERSION_FULL}/compat_report.html
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Checking ABI compatibility of version ${LIB_SOVERSION_FULL} and revision ${ABI_BASE_HASH_SHORT}")
+endmacro()
diff --git a/CMakeModules/FindCMocka.cmake b/CMakeModules/FindCMocka.cmake
new file mode 100644
index 0000000..2dd9fc5
--- /dev/null
+++ b/CMakeModules/FindCMocka.cmake
@@ -0,0 +1,49 @@
+# - Try to find CMocka
+# Once done this will define
+#
+# CMOCKA_ROOT_DIR - Set this variable to the root installation of CMocka
+#
+# Read-Only variables:
+# CMOCKA_FOUND - system has CMocka
+# CMOCKA_INCLUDE_DIR - the CMocka include directory
+# CMOCKA_LIBRARIES - Link these to use CMocka
+# CMOCKA_DEFINITIONS - Compiler switches required for using CMocka
+#
+#=============================================================================
+# Copyright (c) 2011-2012 Andreas Schneider <asn@cryptomilk.org>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+#
+
+find_path(CMOCKA_INCLUDE_DIR
+ NAMES
+ cmocka.h
+ PATHS
+ ${CMOCKA_ROOT_DIR}/include
+)
+
+find_library(CMOCKA_LIBRARY
+ NAMES
+ cmocka
+ PATHS
+ ${CMOCKA_ROOT_DIR}/include
+)
+
+if (CMOCKA_LIBRARY)
+ set(CMOCKA_LIBRARIES
+ ${CMOCKA_LIBRARIES}
+ ${CMOCKA_LIBRARY}
+ )
+endif (CMOCKA_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(CMocka DEFAULT_MSG CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
+
+# show the CMOCKA_INCLUDE_DIR and CMOCKA_LIBRARIES variables only in the advanced view
+mark_as_advanced(CMOCKA_INCLUDE_DIR CMOCKA_LIBRARIES)
diff --git a/CMakeModules/FindPCRE2.cmake b/CMakeModules/FindPCRE2.cmake
new file mode 100644
index 0000000..19af7b7
--- /dev/null
+++ b/CMakeModules/FindPCRE2.cmake
@@ -0,0 +1,62 @@
+# - Find pcre
+# Find the native PCRE2 headers and libraries.
+#
+# PCRE2_INCLUDE_DIRS - where to find pcre.h, etc.
+# PCRE2_LIBRARIES - List of libraries when using pcre.
+# PCRE2_FOUND - True if pcre found.
+include(FindPackageHandleStandardArgs)
+
+if(PCRE2_LIBRARIES AND PCRE2_INCLUDE_DIRS)
+ # in cache already
+ set(PCRE2_FOUND TRUE)
+else()
+ find_path(PCRE2_INCLUDE_DIR
+ NAMES
+ pcre2.h
+ PATHS
+ /usr/include
+ /usr/local/include
+ /opt/local/include
+ /sw/include
+ ${CMAKE_INCLUDE_PATH}
+ ${CMAKE_INSTALL_PREFIX}/include)
+
+ # Look for the library.
+ find_library(PCRE2_LIBRARY
+ NAMES
+ libpcre2.a
+ pcre2-8
+ PATHS
+ /usr/lib
+ /usr/lib64
+ /usr/local/lib
+ /usr/local/lib64
+ /opt/local/lib
+ /sw/lib
+ ${CMAKE_LIBRARY_PATH}
+ ${CMAKE_INSTALL_PREFIX}/lib)
+
+ if(PCRE2_INCLUDE_DIR AND PCRE2_LIBRARY)
+ # learn pcre2 version
+ file(STRINGS ${PCRE2_INCLUDE_DIR}/pcre2.h PCRE2_VERSION_MAJOR
+ REGEX "#define[ ]+PCRE2_MAJOR[ ]+[0-9]+")
+ string(REGEX MATCH " [0-9]+" PCRE2_VERSION_MAJOR ${PCRE2_VERSION_MAJOR})
+ string(STRIP "${PCRE2_VERSION_MAJOR}" PCRE2_VERSION_MAJOR)
+
+ file(STRINGS ${PCRE2_INCLUDE_DIR}/pcre2.h PCRE2_VERSION_MINOR
+ REGEX "#define[ ]+PCRE2_MINOR[ ]+[0-9]+")
+ string(REGEX MATCH " [0-9]+" PCRE2_VERSION_MINOR ${PCRE2_VERSION_MINOR})
+ string(STRIP "${PCRE2_VERSION_MINOR}" PCRE2_VERSION_MINOR)
+
+ set(PCRE2_VERSION ${PCRE2_VERSION_MAJOR}.${PCRE2_VERSION_MINOR})
+ endif()
+
+ set(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR})
+ set(PCRE2_LIBRARIES ${PCRE2_LIBRARY})
+ mark_as_advanced(PCRE2_INCLUDE_DIRS PCRE2_LIBRARIES)
+
+ # Handle the QUIETLY and REQUIRED arguments and set PCRE2_FOUND to TRUE if all listed variables are TRUE.
+ find_package_handle_standard_args(PCRE2 FOUND_VAR PCRE2_FOUND
+ REQUIRED_VARS PCRE2_LIBRARY PCRE2_INCLUDE_DIR
+ VERSION_VAR PCRE2_VERSION)
+endif()
diff --git a/CMakeModules/FindUncrustify.cmake b/CMakeModules/FindUncrustify.cmake
new file mode 100644
index 0000000..3b013e8
--- /dev/null
+++ b/CMakeModules/FindUncrustify.cmake
@@ -0,0 +1,21 @@
+# - Find uncrustify
+# Find the uncrustify binary.
+#
+# UNCRUSTIFY - path ot the binary
+# UNCRUSTIFY_VERSION - found version
+# UNCRUSTIFY_FOUND - True if uncrustify found.
+include(FindPackageHandleStandardArgs)
+
+find_program(UNCRUSTIFY uncrustify)
+if(UNCRUSTIFY)
+ execute_process(COMMAND ${UNCRUSTIFY} --version OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE VERSION)
+ string(FIND ${VERSION} "-" START_IDX)
+ math(EXPR START_IDX "${START_IDX} + 1")
+ string(SUBSTRING "${VERSION}" ${START_IDX} -1 VERSION)
+
+ string(FIND ${VERSION} "-" LEN)
+ string(SUBSTRING "${VERSION}" 0 ${LEN} UNCRUSTIFY_VERSION)
+endif()
+
+# Handle the QUIETLY and REQUIRED arguments and set UNCRUSTIFY_FOUND to TRUE if all listed variables are TRUE.
+find_package_handle_standard_args(Uncrustify REQUIRED_VARS UNCRUSTIFY VERSION_VAR UNCRUSTIFY_VERSION)
diff --git a/CMakeModules/GenCoverage.cmake b/CMakeModules/GenCoverage.cmake
new file mode 100644
index 0000000..fe26d9e
--- /dev/null
+++ b/CMakeModules/GenCoverage.cmake
@@ -0,0 +1,118 @@
+# generate test code coverage report
+
+# check that coverage tools are available - always use before GEN_COVERAGE
+macro(GEN_COVERAGE_ENABLE ENABLE_TESTS)
+ # make into normal variable
+ set(TESTS_ENABLED ${ENABLE_TESTS})
+
+ set(GEN_COVERAGE_ENABLED ON)
+ if(NOT TESTS_ENABLED)
+ message(WARNING "You cannot generate coverage when tests are disabled. Enable test by additing parameter -DENABLE_TESTS=ON or run cmake with Debug build target.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_GCOV NAMES gcov)
+ if(NOT PATH_GCOV)
+ message(WARNING "gcov executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_LCOV NAMES lcov)
+ if(NOT PATH_LCOV)
+ message(WARNING "lcov executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_GENHTML NAMES genhtml)
+ if(NOT PATH_GENHTML)
+ message(WARNING "genhtml executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ if(NOT CMAKE_COMPILER_IS_GNUCC)
+ message(WARNING "Compiler is not gcc! Coverage may break the tests!")
+ endif()
+
+ execute_process(
+ COMMAND bash "-c" "${CMAKE_C_COMPILER} --version | head -n1 | sed \"s/.* (.*) \\([0-9]\\+.[0-9]\\+.[0-9]\\+ .*\\)/\\1/\""
+ OUTPUT_VARIABLE GCC_VERSION_FULL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ execute_process(
+ COMMAND bash "-c" "${PATH_GCOV} --version | head -n1 | sed \"s/.* (.*) \\([0-9]\\+.[0-9]\\+.[0-9]\\+ .*\\)/\\1/\""
+ OUTPUT_VARIABLE GCOV_VERSION_FULL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT GCC_VERSION_FULL STREQUAL GCOV_VERSION_FULL)
+ message(WARNING "gcc and gcov versions do not match! Generating coverage may fail with errors.")
+ endif()
+
+ # add specific required compile flags
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
+ endif()
+endmacro()
+
+# tests are always expected to be in ${CMAKE_SOURCE_DIR}/tests
+function(GEN_COVERAGE MATCH_TEST_REGEX EXCLUDE_TEST_REGEX)
+ if(NOT GEN_COVERAGE_ENABLED)
+ return()
+ endif()
+
+ # destination
+ set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/code_coverage/")
+ set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/coverage_raw.info")
+ set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/coverage_clean.info")
+
+ # test match/exclude
+ if(MATCH_TEST_REGEX)
+ set(MATCH_TEST_ARGS -R \"${MATCH_TEST_REGEX}\")
+ endif()
+ if(EXCLUDE_TEST_REGEX)
+ set(EXCLUDE_TEST_ARGS -E \"${EXCLUDE_TEST_REGEX}\")
+ endif()
+
+ # coverage target
+ add_custom_target(coverage
+ COMMENT "Generating code coverage..."
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ # Cleanup code counters
+ COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
+
+ # Run tests
+ COMMAND "${CMAKE_CTEST_COMMAND}" --quiet ${MATCH_TEST_ARGS} ${EXCLUDE_TEST_ARGS}
+
+ # Capture the counters
+ COMMAND "${PATH_LCOV}"
+ --directory .
+ --rc lcov_branch_coverage=1
+ --rc 'lcov_excl_line=assert'
+ --capture --quiet
+ --output-file "${COVERAGE_FILE_RAW}"
+ # Remove coverage of tests, system headers, etc.
+ COMMAND "${PATH_LCOV}"
+ --remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
+ --rc lcov_branch_coverage=1
+ --quiet --output-file "${COVERAGE_FILE_CLEAN}"
+ # Generate HTML report
+ COMMAND "${PATH_GENHTML}"
+ --branch-coverage --function-coverage --quiet --title "${PROJECT_NAME}"
+ --legend --show-details --output-directory "${COVERAGE_DIR}"
+ "${COVERAGE_FILE_CLEAN}"
+ # Delete the counters
+ COMMAND "${CMAKE_COMMAND}" -E remove
+ ${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
+ )
+
+ add_custom_command(TARGET coverage POST_BUILD
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
+ COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
+ COMMAND ;
+ )
+endfunction()
diff --git a/CMakeModules/GenDoc.cmake b/CMakeModules/GenDoc.cmake
new file mode 100644
index 0000000..ee879d0
--- /dev/null
+++ b/CMakeModules/GenDoc.cmake
@@ -0,0 +1,28 @@
+# Prepare building doxygen documentation
+macro(GEN_DOC INPUT_FILES PROJECT_VERSION PROJECT_DESCRIPTION DOC_LOGO)
+ find_package(Doxygen)
+ if(DOXYGEN_FOUND)
+ find_program(DOT_PATH dot PATH_SUFFIXES graphviz2.38/bin graphviz/bin)
+ if(DOT_PATH)
+ set(HAVE_DOT "YES")
+ else()
+ set(HAVE_DOT "NO")
+ message(AUTHOR_WARNING "Doxygen: to generate UML diagrams please install graphviz")
+ endif()
+
+ # target doc
+ add_custom_target(doc
+ COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+
+ # generate list with spaces as separators
+ string(REPLACE ";" " " DOXY_INPUT "${INPUT_FILES}")
+
+ # make other arguments into variables
+ set(PROJECT_VERSION ${PROJECT_VERSION})
+ set(PROJECT_DESCRIPTION ${PROJECT_DESCRIPTION})
+ set(DOC_LOGO ${DOC_LOGO})
+
+ configure_file(Doxyfile.in Doxyfile)
+ endif()
+endmacro()
diff --git a/CMakeModules/SourceFormat.cmake b/CMakeModules/SourceFormat.cmake
new file mode 100644
index 0000000..fd1e63b
--- /dev/null
+++ b/CMakeModules/SourceFormat.cmake
@@ -0,0 +1,36 @@
+# format source files with uncrustify
+
+# check that format checking is available - always use before SOURCE_FORMAT
+macro(SOURCE_FORMAT_ENABLE)
+ if(NOT ${ARGC} EQUAL 1)
+ message(FATAL_ERROR "source_format_enable() needs the required Uncrustify version!")
+ endif()
+
+ find_package(Uncrustify ${ARGV0})
+ if(UNCRUSTIFY_FOUND)
+ set(SOURCE_FORMAT_ENABLED TRUE)
+ else()
+ set(SOURCE_FORMAT_ENABLED FALSE)
+ endif()
+endmacro()
+
+# files are expected to be a list and relative paths are resolved wtih respect to CMAKE_SOURCE DIR
+macro(SOURCE_FORMAT)
+ if(NOT ${ARGC})
+ message(FATAL_ERROR "source_format() needs a list of files to format!")
+ endif()
+
+ if(SOURCE_FORMAT_ENABLED)
+ add_custom_target(format
+ COMMAND ${UNCRUSTIFY} -c ${CMAKE_SOURCE_DIR}/uncrustify.cfg --no-backup --replace ${ARGN}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ COMMENT "Formating sources with ${UNCRUSTIFY} ...")
+
+ add_custom_target(format-check
+ COMMAND ${UNCRUSTIFY} -c ${CMAKE_SOURCE_DIR}/uncrustify.cfg --check ${ARGN}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ COMMENT "Checking format of the sources with ${UNCRUSTIFY} ...")
+
+ set(SOURCE_FORMAT_ENABLED TRUE)
+ endif()
+endmacro()
diff --git a/CMakeModules/UseCompat.cmake b/CMakeModules/UseCompat.cmake
new file mode 100644
index 0000000..c1befd7
--- /dev/null
+++ b/CMakeModules/UseCompat.cmake
@@ -0,0 +1,75 @@
+# - Use compat library providing various functions and macros that may be missing on some systems
+# Once done this will define
+#
+# compatsrc - sources to add to compilation
+#
+# Additionally, "compat.h" include directory is added and can be included.
+#
+# Author Michal Vasko <mvasko@cesnet.cz>
+# Copyright (c) 2021 CESNET, z.s.p.o.
+#
+# This source code is licensed under BSD 3-Clause License (the "License").
+# You may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://opensource.org/licenses/BSD-3-Clause
+#
+include(CheckSymbolExists)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(TestBigEndian)
+if(POLICY CMP0075)
+ cmake_policy(SET CMP0075 NEW)
+endif()
+
+macro(USE_COMPAT)
+ # compatibility checks
+ set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200809L)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__BSD_VISIBLE=1)
+ set(CMAKE_REQUIRED_LIBRARIES pthread)
+
+ check_symbol_exists(vdprintf "stdio.h;stdarg.h" HAVE_VDPRINTF)
+ check_symbol_exists(asprintf "stdio.h" HAVE_ASPRINTF)
+ check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF)
+ check_symbol_exists(getline "stdio.h" HAVE_GETLINE)
+
+ check_symbol_exists(strndup "string.h" HAVE_STRNDUP)
+ check_symbol_exists(strnstr "string.h" HAVE_STRNSTR)
+ check_symbol_exists(strdupa "string.h" HAVE_STRDUPA)
+ check_symbol_exists(strchrnul "string.h" HAVE_STRCHRNUL)
+
+ check_symbol_exists(get_current_dir_name "unistd.h" HAVE_GET_CURRENT_DIR_NAME)
+
+ check_function_exists(pthread_mutex_timedlock HAVE_PTHREAD_MUTEX_TIMEDLOCK)
+
+ TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
+
+ check_include_file("stdatomic.h" HAVE_STDATOMIC)
+
+ include(CheckStructHasMember)
+ check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
+ check_symbol_exists(timezone time.h HAVE_TIME_H_TIMEZONE)
+
+ check_symbol_exists(realpath "stdlib.h" HAVE_REALPATH)
+ check_symbol_exists(localtime_r "time.h" HAVE_LOCALTIME_R)
+ check_symbol_exists(gmtime_r "time.h" HAVE_GMTIME_R)
+ check_symbol_exists(strptime "time.h" HAVE_STRPTIME)
+ check_symbol_exists(mmap "sys/mman.h" HAVE_MMAP)
+ check_symbol_exists(dirname "libgen.h" HAVE_DIRNAME)
+ check_symbol_exists(setenv "stdlib.h" HAVE_SETENV)
+
+ unset(CMAKE_REQUIRED_DEFINITIONS)
+ unset(CMAKE_REQUIRED_LIBRARIES)
+
+ # header and source file (adding the source directly allows for hiding its symbols)
+ configure_file(${PROJECT_SOURCE_DIR}/compat/compat.h.in ${PROJECT_BINARY_DIR}/compat/compat.h @ONLY)
+ include_directories(${PROJECT_BINARY_DIR}/compat)
+ set(compatsrc ${PROJECT_SOURCE_DIR}/compat/compat.c)
+ if(WIN32)
+ include_directories(${PROJECT_SOURCE_DIR}/compat/posix-shims)
+ endif()
+ if(NOT HAVE_STRPTIME)
+ set(compatsrc ${compatsrc} ${PROJECT_SOURCE_DIR}/compat/strptime.c)
+ endif()
+endmacro()
diff --git a/CMakeModules/uninstall.cmake b/CMakeModules/uninstall.cmake
new file mode 100644
index 0000000..b9618a2
--- /dev/null
+++ b/CMakeModules/uninstall.cmake
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.0.2)
+
+set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt")
+
+if(NOT EXISTS ${MANIFEST})
+ message(FATAL_ERROR "Cannot find install manifest: ${MANIFEST}")
+endif()
+
+file(STRINGS ${MANIFEST} files)
+foreach(file ${files})
+ if(EXISTS ${file} OR IS_SYMLINK ${file})
+ message(STATUS "Removing: ${file}")
+
+ execute_process(COMMAND rm -f ${file}
+ RESULT_VARIABLE result
+ OUTPUT_QUIET
+ ERROR_VARIABLE stderr
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+
+ if(NOT ${result} EQUAL 0)
+ message(FATAL_ERROR "${stderr}")
+ endif()
+ else()
+ message(STATUS "Does-not-exist: ${file}")
+ endif()
+endforeach(file)