Edit

kc3-lang/libevent/CMakeLists.txt

Branch :

  • Show log

    Commit

  • Author : Joakim Soderberg
    Date : 2013-12-09 18:05:32
    Hash : e415196a
    Message : Initial CMake commit.

  • CMakeLists.txt
  • #
    # Libevent CMake project
    #
    # Based on initial work by: 
    #    Alexey Ozeritsky
    #
    # Additional changes:
    #   Brodie Thiesfield
    #   Joakim Soderberg 
    #
    #   Build example:
    #
    #       cd libevent
    #       md build
    #       cd build
    #       cmake -G "Visual Studio 10" ..
    #       start libevent.sln
    #
    cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
    
    # get rid of the extra default configurations
    set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Limited configurations" FORCE)
    
    project(libevent)
    
    set(EVENT_NUMERIC_VERSION 0x02010401)
    set(EVENT_VERSION "2.1.4-beta")
    set(EVENT_PACKAGE_VERSION "")
    
    option(EVENT__DISABLE_DEBUG_MODE "Define if libevent should build without support for a debug mode" 0)
    option(EVENT__DISABLE_MM_REPLACEMENT "Define if libevent should not allow replacing the mm functions" 0)
    option(EVENT__DISABLE_THREAD_SUPPORT "Define if libevent should not be compiled with thread support" 0)
    option(EVENT__DISABLE_OPENSSL "Define if libevent should build without support for OpenSSL encrpytion" 0)
    option(EVENT__DISABLE_BENCHMARK "Defines if libevent should build without the benchmark exectuables" 0)
    option(EVENT__DISABLE_TESTS "If tests should be compiled or not" 0)
    
    # Put the libaries and binaries that get built into directories at the
    # top of the build tree rather than in hard-to-find leaf directories. 
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
    
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
    include(CheckFunctionExistsEx)
    include(CheckFileOffsetBits)
    include(CheckFunctionExists)
    include(CheckIncludeFile)
    include(CheckIncludeFiles)
    include(CheckTypeSize)
    include(CheckVariableExists)
    include(CheckSymbolExists)
    include(CheckStructHasMember)
    include(CheckCSourceCompiles)
    include(CheckPrototypeDefinition)
    
    include(FindZLIB)    # -> HAVE_LIBZ
    include(FindThreads) # -> HAVE_PTHREAD
    include(FindPythonInterp)
    
    # Winsock.
    if(WIN32)
        set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h ws2tcpip.h)
        set(CMAKE_REQUIRED_LIBRARIES  ws2_32.lib)
        set(CMAKE_REQUIRED_DEFINITIONS -FIwinsock2.h -FIws2tcpip.h)
    endif()
    
    # Check if _GNU_SOURCE is available.
    CHECK_SYMBOL_EXISTS(__GNU_LIBRARY__ "features.h" _GNU_SOURCE)
    
    if (_GNU_SOURCE)
        add_definitions(-D_GNU_SOURCE)
    endif()
    
    CHECK_INCLUDE_FILE(sys/types.h EVENT__HAVE_SYS_TYPES_H)
    if(EVENT__HAVE_SYS_TYPES_H)
        list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/types.h)
    endif()
    
    CHECK_INCLUDE_FILE(sys/socket.h EVENT__HAVE_SYS_SOCKET_H)
    if(EVENT__HAVE_SYS_SOCKET_H)
        list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
    endif()
    
    CHECK_INCLUDE_FILE(netinet/in.h EVENT__HAVE_NETINET_IN_H)
    if(EVENT__HAVE_NETINET_IN_H)
        list(APPEND CMAKE_EXTRA_INCLUDE_FILES netinet/in.h)
    endif()
    
    CHECK_INCLUDE_FILE(netinet/in6.h EVENT__HAVE_NETINET_IN6_H)
    if(EVENT__HAVE_NETINET_IN6_H)
        list(APPEND CMAKE_EXTRA_INCLUDE_FILES netinet/in6.h)
    endif()
    
    CHECK_INCLUDE_FILE(unistd.h EVENT__HAVE_UNISTD_H)
    CHECK_INCLUDE_FILE(netdb.h EVENT__HAVE_NETDB_H)
    CHECK_INCLUDE_FILE(dlfcn.h EVENT__HAVE_DLFCN_H)
    CHECK_INCLUDE_FILE(arpa/inet.h EVENT__HAVE_ARPA_INET_H)
    CHECK_INCLUDE_FILE(fcntl.h EVENT__HAVE_FCNTL_H)
    if(EVENT__HAVE_FCNTL_H)
        list(APPEND CMAKE_EXTRA_INCLUDE_FILES fcntl.h)
    endif()
    CHECK_INCLUDE_FILE(inttypes.h EVENT__HAVE_INTTYPES_H)
    CHECK_INCLUDE_FILE(memory.h EVENT__HAVE_MEMORY_H)
    CHECK_INCLUDE_FILE(poll.h EVENT__HAVE_POLL_H)
    CHECK_INCLUDE_FILE(port.h EVENT__HAVE_PORT_H)
    if(EVENT__HAVE_PORT_H)
        list(APPEND CMAKE_EXTRA_INCLUDE_FILES port.h)
    endif()
    CHECK_INCLUDE_FILE(signal.h EVENT__HAVE_SIGNAL_H)
    CHECK_INCLUDE_FILE(stdarg.h EVENT__HAVE_STDARG_H)
    CHECK_INCLUDE_FILE(stddef.h EVENT__HAVE_STDDEF_H)
    CHECK_INCLUDE_FILE(stdint.h EVENT__HAVE_STDINT_H)
    CHECK_INCLUDE_FILE(stdlib.h EVENT__HAVE_STDLIB_H)
    CHECK_INCLUDE_FILE(strings.h EVENT__HAVE_STRINGS_H)
    CHECK_INCLUDE_FILE(string.h EVENT__HAVE_STRING_H)
    CHECK_INCLUDE_FILE(sys/devpoll.h EVENT__HAVE_SYS_DEVPOLL_H)
    CHECK_INCLUDE_FILE(sys/epoll.h EVENT__HAVE_SYS_EPOLL_H)
    CHECK_INCLUDE_FILE(sys/eventfd.h EVENT__HAVE_SYS_EVENTFD_H)
    CHECK_INCLUDE_FILE(sys/event.h EVENT__HAVE_SYS_EVENT_H)
    CHECK_INCLUDE_FILE(sys/ioctl.h EVENT__HAVE_SYS_IOCTL_H)
    CHECK_INCLUDE_FILE(sys/mman.h EVENT__HAVE_SYS_MMAN_H)
    CHECK_INCLUDE_FILE(sys/param.h EVENT__HAVE_SYS_PARAM_H)
    CHECK_INCLUDE_FILE(sys/queue.h EVENT__HAVE_SYS_QUEUE_H)
    CHECK_INCLUDE_FILE(sys/select.h EVENT__HAVE_SYS_SELECT_H)
    CHECK_INCLUDE_FILE(sys/sendfile.h EVENT__HAVE_SYS_SENDFILE_H)
    CHECK_INCLUDE_FILE(sys/stat.h EVENT__HAVE_SYS_STAT_H)
    CHECK_INCLUDE_FILE(sys/time.h EVENT__HAVE_SYS_TIME_H)
    if(EVENT__HAVE_SYS_TIME_H)
    	list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/time.h)
    endif()
    CHECK_INCLUDE_FILE(sys/uio.h EVENT__HAVE_SYS_UIO_H)
    CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" EVENT__HAVE_IFADDRS_H)
    CHECK_INCLUDE_FILE(mach/mach_time.h EVENT__HAVE_MACH_MACH_TIME_H)
    CHECK_INCLUDE_FILE(netdb.h EVENT__HAVE_NETDB_H)
    CHECK_INCLUDE_FILE(netinet/tcp.h EVENT__HAVE_NETINET_TCP_H)
    CHECK_INCLUDE_FILE(sys/wait.h EVENT__HAVE_SYS_WAIT_H)
    CHECK_INCLUDE_FILE(sys/resource.h EVENT__HAVE_SYS_RESOURCE_H)
    CHECK_INCLUDE_FILE(sys/sysctl.h EVENT__HAVE_SYS_SYSCTL_H)
    CHECK_INCLUDE_FILE(sys/timerfd.h EVENT__HAVE_SYS_TIMERFD_H)
    
    
    CHECK_FUNCTION_EXISTS_EX(epoll_create EVENT__HAVE_EPOLL)
    CHECK_FUNCTION_EXISTS_EX(epoll_ctl EVENT__HAVE_EPOLL_CTL)
    CHECK_FUNCTION_EXISTS_EX(eventfd EVENT__HAVE_EVENTFD)
    CHECK_FUNCTION_EXISTS_EX(clock_gettime EVENT__HAVE_CLOCK_GETTIME)
    CHECK_FUNCTION_EXISTS_EX(fcntl EVENT__HAVE_FCNTL)
    CHECK_FUNCTION_EXISTS_EX(getaddrinfo EVENT__HAVE_GETADDRINFO)
    CHECK_FUNCTION_EXISTS_EX(getnameinfo EVENT__HAVE_GETNAMEINFO)
    CHECK_FUNCTION_EXISTS_EX(gettimeofday EVENT__HAVE_GETTIMEOFDAY)
    CHECK_FUNCTION_EXISTS_EX(getprotobynumber EVENT__HAVE_GETPROTOBYNUMBER)
    CHECK_FUNCTION_EXISTS_EX(getservbyname EVENT__HAVE_GETSERVBYNAME)
    CHECK_FUNCTION_EXISTS_EX(inet_aton EVENT__HAVE_INET_ATON)
    CHECK_FUNCTION_EXISTS_EX(inet_ntop EVENT__HAVE_INET_NTOP)
    CHECK_FUNCTION_EXISTS_EX(inet_pton EVENT__HAVE_INET_PTON)
    CHECK_FUNCTION_EXISTS_EX(kqueue EVENT__HAVE_KQUEUE)
    CHECK_FUNCTION_EXISTS_EX(mmap EVENT__HAVE_MMAP)
    CHECK_FUNCTION_EXISTS_EX(pipe EVENT__HAVE_PIPE)
    CHECK_FUNCTION_EXISTS_EX(pipe2 EVENT__HAVE_PIPE2)
    CHECK_FUNCTION_EXISTS_EX(poll EVENT__HAVE_POLL)
    CHECK_FUNCTION_EXISTS_EX(port_create EVENT__HAVE_PORT_CREATE)
    CHECK_FUNCTION_EXISTS_EX(sendfile EVENT__HAVE_SENDFILE)
    CHECK_FUNCTION_EXISTS_EX(sigaction EVENT__HAVE_SIGACTION)
    CHECK_FUNCTION_EXISTS_EX(signal EVENT__HAVE_SIGNAL)
    CHECK_FUNCTION_EXISTS_EX(splice EVENT__HAVE_SPLICE)
    CHECK_FUNCTION_EXISTS_EX(strlcpy EVENT__HAVE_STRLCPY)
    CHECK_FUNCTION_EXISTS_EX(strsep EVENT__HAVE_STRSEP)
    CHECK_FUNCTION_EXISTS_EX(strtok_r EVENT__HAVE_STRTOK_R)
    CHECK_FUNCTION_EXISTS_EX(strtoll EVENT__HAVE_STRTOLL)
    CHECK_FUNCTION_EXISTS_EX(vasprintf EVENT__HAVE_VASPRINTF)
    CHECK_FUNCTION_EXISTS_EX(sysctl EVENT__HAVE_SYSCTL)
    CHECK_FUNCTION_EXISTS_EX(accept4 EVENT__HAVE_ACCEPT4)
    CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM)
    CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF)
    CHECK_FUNCTION_EXISTS_EX(epoll_create1 EVENT__HAVE_EPOLL_CREATE1)
    CHECK_FUNCTION_EXISTS_EX(getegid EVENT__HAVE_GETEGID)
    CHECK_FUNCTION_EXISTS_EX(geteuid EVENT__HAVE_GETEUID)
    CHECK_FUNCTION_EXISTS_EX(getifaddrs EVENT__HAVE_GETIFADDRS)
    CHECK_FUNCTION_EXISTS_EX(issetugid EVENT__HAVE_ISSETUGID)
    CHECK_FUNCTION_EXISTS_EX(mach_absolute_time EVENT__HAVE_MACH_ABSOLUTE_TIME)
    CHECK_FUNCTION_EXISTS_EX(nanosleep EVENT__HAVE_NANOSLEEP)
    CHECK_FUNCTION_EXISTS_EX(usleep EVENT__HAVE_USLEEP)
    CHECK_FUNCTION_EXISTS_EX(timeradd EVENT__HAVE_TIMERADD)
    CHECK_FUNCTION_EXISTS_EX(timerclear EVENT__HAVE_TIMERCLEAR)
    CHECK_FUNCTION_EXISTS_EX(timercmp EVENT__HAVE_TIMERCMP)
    CHECK_FUNCTION_EXISTS_EX(timerfd_create HAVE_TIMERFD_CREATE)
    CHECK_FUNCTION_EXISTS_EX(timerisset EVENT__HAVE_TIMERISSET)
    CHECK_FUNCTION_EXISTS_EX(putenv EVENT__HAVE_PUTENV)
    CHECK_FUNCTION_EXISTS_EX(setenv EVENT__HAVE_SETENV)
    CHECK_FUNCTION_EXISTS_EX(setrlimit EVENT__HAVE_SETRLIMIT)
    CHECK_FUNCTION_EXISTS_EX(umask EVENT__HAVE_UMASK)
    CHECK_FUNCTION_EXISTS_EX(unsetenv EVENT__HAVE_UNSETENV)
    
    # Get the gethostbyname_r prototype.
    CHECK_FUNCTION_EXISTS_EX(gethostbyname_r EVENT__HAVE_GETHOSTBYNAME_R)
    
    if(EVENT__HAVE_GETHOSTBYNAME_R)
        CHECK_PROTOTYPE_DEFINITION(gethostbyname_r 
            "int gethostbyname_r(const char *name, struct hostent *hp, struct hostent_data *hdata)"
            "0"
            "netdb.h"
            EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
    
        CHECK_PROTOTYPE_DEFINITION(gethostbyname_r 
            "struct hostent *gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen, int *herr)"
            "NULL"
            "netdb.h"
            EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
    
        CHECK_PROTOTYPE_DEFINITION(gethostbyname_r 
            "int gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen, struct hostent **result, int *herr)"
            "0"
            "netdb.h"
            EVENT__HAVE_GETHOSTBYNAME_R_6_ARG)
    endif()
    
    if(HAVE_PORT_H AND HAVE_PORT_CREATE)
        set(EVENT__HAVE_EVENT_PORTS 1)
    endif()
    
    if(NOT WIN32)
    	CHECK_FUNCTION_EXISTS_EX(select EVENT__HAVE_SELECT)
    endif()
    
    CHECK_TYPE_SIZE("uint8_t" EVENT__HAVE_UINT8_T)
    CHECK_TYPE_SIZE("uint16_t" EVENT__HAVE_UINT16_T)
    CHECK_TYPE_SIZE("uint32_t" EVENT__HAVE_UINT32_T)
    CHECK_TYPE_SIZE("uint64_t" EVENT__HAVE_UINT64_T)
    CHECK_TYPE_SIZE("short" EVENT__SIZEOF_SHORT BUILTIN_TYPES_ONLY)
    CHECK_TYPE_SIZE("int" EVENT__SIZEOF_INT BUILTIN_TYPES_ONLY)
    CHECK_TYPE_SIZE("unsigned" EVENT__SIZEOF_UNSIGNED BUILTIN_TYPES_ONLY)
    CHECK_TYPE_SIZE("unsigned int" EVENT__SIZEOF_UNSIGNED_INT BUILTIN_TYPES_ONLY)
    CHECK_TYPE_SIZE("long" EVENT__SIZEOF_LONG BUILTIN_TYPES_ONLY)
    CHECK_TYPE_SIZE("long long" EVENT__SIZEOF_LONG_LONG BUILTIN_TYPES_ONLY)
    
    if(WIN32)
    	# These aren't available until Windows Vista.
    	# But you can still link them. They just won't be found when running the exe.
    	set(EVENT__HAVE_INET_NTOP 0)
    	set(EVENT__HAVE_INET_PTON 0)
    endif()
    
    # Check for different inline keyword versions.
    foreach(KEYWORD "inline" "__inline__" "__inline")
        set(CMAKE_REQUIRED_DEFINITIONS "-DKEYWORD=${KEYWORD}")
        CHECK_C_SOURCE_COMPILES(
            "
            #include <stdio.h>
            KEYWORD void a() {}
            int main(int argc, char **argv) { a(); return 0; }
            " HAVE_${KEYWORD})
    endforeach()
    
    if (NOT HAVE_inline)
        if (HAVE___inline__)
            set(EVENT__inline __inline__)
        elseif(HAVE___inline)
            set(EVENT__inline __inline)
        endif()
    endif()
    set(CMAKE_REQUIRED_DEFINITIONS "")
    
    # Check for different function name macros.
    foreach(KEYWORD "__func__" "__FUNCTION__")
        set(CMAKE_REQUIRED_DEFINITIONS "-DKEYWORD=${KEYWORD}")
        CHECK_C_SOURCE_COMPILES(
            "
            #include <stdio.h>
            int main(int argc, char **argv) { const char *cp = KEYWORD; return 0; }
            " HAVE_${KEYWORD})
    endforeach()
    set(CMAKE_REQUIRED_DEFINITIONS "")
    
    if (NOT HAVE___func__)
        if (HAVE___FUNCTION__)
            set(EVENT____func__ __FUNCTION__)
        else()
            # Substitute for __func__
            set(EVENT____func__ __FILE__)
        endif()
    endif()
    
    CHECK_SYMBOL_EXISTS(TAILQ_FOREACH sys/queue.h EVENT__HAVE_TAILQFOREACH)
    CHECK_SYMBOL_EXISTS(CTL_KERN sys/sysctl.h EVENT__HAVE_DECL_CTL_KERN)
    CHECK_SYMBOL_EXISTS(KERN_ARND sys/sysctl.h EVENT__HAVE_DECL_KERN_ARND)
    CHECK_SYMBOL_EXISTS(KERN_RANDOM sys/sysctl.h EVENT__HAVE_DECL_KERN_RANDOM)
    CHECK_SYMBOL_EXISTS(RANDOM_UUID sys/sysctl.h EVENT__HAVE_DECL_RANDOM_UUID)
    CHECK_SYMBOL_EXISTS(F_SETFD fcntl.h EVENT__HAVE_SETFD)
    
    CHECK_TYPE_SIZE(fd_mask EVENT__HAVE_FD_MASK)
    
    CHECK_TYPE_SIZE(size_t EVENT__SIZEOF_SIZE_T)
    if(NOT EVENT__SIZEOF_SIZE_T)
      set(EVENT__size_t unsigned)
      set(EVENT__SIZEOF_SIZE_T ${EVENT__SIZEOF_UNSIGNED})
    endif()
    
    CHECK_TYPE_SIZE("off_t" EVENT__SIZEOF_OFF_T)
    
    CHECK_TYPE_SIZE(ssize_t EVENT__SIZEOF_SSIZE_T)
    CHECK_TYPE_SIZE(SSIZE_T EVENT__SIZEOF_UPPERCASE_SSIZE_T)
    if(NOT EVENT__SIZEOF_SSIZE_T)
        if(EVENT__SIZEOF_UPPERCASE_SSIZE_T)
            set(EVENT__ssize_t SSIZE_T)
            set(EVENT__SIZEOF_SSIZE_T ${EVENT__SIZEOF_UPPERCASE_SSIZE_T})
        else()
            set(EVENT__ssize_t int)
            set(EVENT__SIZEOF_SSIZE_T ${EVENT__SIZEOF_INT})
        endif()
    endif()
    
    CHECK_TYPE_SIZE(socklen_t EVENT__SIZEOF_SOCKLEN_T)
    if(NOT EVENT__SIZEOF_SOCKLEN_T)
      set(EVENT__socklen_t "unsigned int")
      set(EVENT__SIZEOF_SOCKLEN_T ${EVENT__SIZEOF_UNSIGNED_INT})
    endif()
    
    CHECK_TYPE_SIZE(pid_t EVENT__SIZEOF_PID_T)
    if(NOT EVENT__SIZEOF_PID_T)
      set(EVENT__pid_t int)
      set(EVENT__SIZEOF_PID_T ${EVENT__SIZEOF_INT})
    endif()
    
    CHECK_TYPE_SIZE(pthread_t EVENT__SIZEOF_PTHREAD_T)
    
    if(EVENT__HAVE_CLOCK_GETTIME)
      set(EVENT__DNS_USE_CPU_CLOCK_FOR_ID 1)
    endif()
    
    CHECK_TYPE_SIZE("uintptr_t" EVENT__HAVE_UINTPTR_T)
    CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P)
    
    # Tests file offset bits.
    # TODO: Add AIX test for if -D_LARGE_FILES is needed.
    CHECK_FILE_OFFSET_BITS()
    set(EVENT___FILE_OFFSET_BITS _FILE_OFFSET_BITS)
    
    # TODO: Check EVENT__HAVE_WORKING_KQUEUE (Define if kqueue works correctly with pipes)
    
    CHECK_SYMBOL_EXISTS(_MINIX "stdio.h" EVENT___MINIX)
    CHECK_SYMBOL_EXISTS(_POSIX_1_SOURCE "stdio.h" EVENT___POSIX_1_SOURCE)
    CHECK_SYMBOL_EXISTS(_POSIX_SOURCE "stdio.h" EVENT___POSIX_SOURCE)
    
    if(EVENT__HAVE_NETDB_H)
    	list(APPEND CMAKE_EXTRA_INCLUDE_FILES netdb.h)
    	CHECK_TYPE_SIZE("struct addrinfo" EVENT__HAVE_STRUCT_ADDRINFO)
    elseif(WIN32)
    	list(APPEND CMAKE_EXTRA_INCLUDE_FILES ws2tcpip.h)
    	CHECK_TYPE_SIZE("struct addrinfo" EVENT__HAVE_STRUCT_ADDRINFO)
    endif()
    
    # Check for sockaddr structure sizes.
    set(SOCKADDR_HEADERS)
    
    if (WIN32)
        set(CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN")
        if (_MSC_VER LESS 1300)
            set(SOCKADDR_HEADERS winsock.h)
        else()
            set(SOCKADDR_HEADERS winsock2.h ws2tcpip.h)
        endif()
    else()
        if (EVENT__HAVE_NETINET_IN_H)
            set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} netinet/in.h)
        endif()
    
        if (EVENT__HAVE_NETINET_IN6_H)
            set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} netinet/in6.h)
        endif()
    
        if (EVENT__HAVE_SYS_SOCKET_H)
            set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} sys/socket.h)
        endif()
    
        if (EVENT__HAVE_NETDB_H)
            set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} netdb.h)
        endif()
    endif()
    
    CHECK_TYPE_SIZE("struct in6_addr" EVENT__HAVE_STRUCT_IN6_ADDR)
    if(EVENT__HAVE_STRUCT_IN6_ADDR)
    	CHECK_STRUCT_HAS_MEMBER("struct in6_addr" s6_addr16 "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16)
    	CHECK_STRUCT_HAS_MEMBER("struct in6_addr" s6_addr32 "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32)
    endif()
    
    CHECK_TYPE_SIZE("sa_family_t" EVENT__HAVE_SA_FAMILY_T)
    CHECK_TYPE_SIZE("struct sockaddr_in6" EVENT__HAVE_STRUCT_SOCKADDR_IN6)
    if(EVENT__HAVE_STRUCT_SOCKADDR_IN6)
    	CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_len "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN)
    	CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin_len "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN)
    endif()
    
    CHECK_TYPE_SIZE("struct sockaddr_storage" EVENT__HAVE_STRUCT_SOCKADDR_STORAGE)
    if(EVENT__HAVE_STRUCT_SOCKADDR_STORAGE)
    	CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage" ss_family "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)
    	CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage" __ss_family "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY)
    endif()
    
    # Group the source files.
    set(HDR_PRIVATE
        bufferevent-internal.h
        changelist-internal.h
        defer-internal.h
        evbuffer-internal.h
        include/evdns.h
        event-internal.h
        include/event.h
        include/evhttp.h
        evmap-internal.h
        evrpc-internal.h
        include/evrpc.h
        evsignal-internal.h
        evthread-internal.h
        include/evutil.h
        ht-internal.h
        http-internal.h
        iocp-internal.h
        ipv6-internal.h
        log-internal.h
        minheap-internal.h
        mm-internal.h
        ratelim-internal.h
        strlcpy-internal.h
        util-internal.h
        evconfig-private.h
        compat/sys/queue.h
        )
        
    set(HDR_PUBLIC
        include/event2/buffer.h
        include/event2/bufferevent.h
        include/event2/bufferevent_compat.h
        include/event2/bufferevent_ssl.h
        include/event2/bufferevent_struct.h
        include/event2/buffer_compat.h
        include/event2/dns.h
        include/event2/dns_compat.h
        include/event2/dns_struct.h
        include/event2/event.h
        include/event2/event_compat.h
        include/event2/event_struct.h
        include/event2/http.h
        include/event2/http_compat.h
        include/event2/http_struct.h
        include/event2/listener.h
        include/event2/rpc.h
        include/event2/rpc_compat.h
        include/event2/rpc_struct.h
        include/event2/tag.h
        include/event2/tag_compat.h
        include/event2/thread.h
        include/event2/util.h
        )
    
    set(SRC_CORE
        buffer.c 
        bufferevent.c 
        bufferevent_filter.c 
        bufferevent_pair.c 
        bufferevent_ratelim.c 
        bufferevent_sock.c 
        event.c 
        evmap.c 
        evthread.c 
        evutil.c 
        evutil_rand.c
    	evutil_time.c
        listener.c 
        log.c 
        signal.c 
        strlcpy.c
        )
    
    if(EVENT__HAVE_SELECT)
        list(APPEND SRC_CORE select.c)
    endif()
    
    if(EVENT__HAVE_POLL)
        list(APPEND SRC_CORE poll.c)
    endif()
    
    if(EVENT__HAVE_KQUEUE)
        list(APPEND SRC_CORE kqueue.c)
    endif()
    
    if(EVENT__HAVE_DEVPOLL)
        list(APPEND SRC_CORE devpoll.c)
    endif()
    
    if(EVENT__HAVE_EPOLL)
        list(APPEND SRC_CORE epoll_sub.c epoll.c)
    endif()
    
    if(EVENT__HAVE_EVENT_PORTS)
        list(APPEND SRC_CORE evport.c)
    endif()
    
    if (NOT EVENT__DISABLE_OPENSSL)
        find_package(OpenSSL REQUIRED)
        message("OpenSSL include: ${OPENSSL_INCLUDE_DIR}")
        message("OpenSSL lib: ${OPENSSL_LIBRARIES}")
        list(APPEND LIB_REGRESS ${OPENSSL_LIBRARIES})
    endif()
    
    if(CMAKE_USE_PTHREADS_INIT)
    	set(EVENT__HAVE_PTHREADS 1)
        list(APPEND SRC_CORE evthread_pthread.c)
        list(APPEND SRC_REGRESS test/regress_thread.c)
        list(APPEND LIB_REGRESS ${CMAKE_THREAD_LIBS_INIT})
    endif()
    
    if(ZLIB_LIBRARY)
        set(EVENT__HAVE_ZLIB 1)
        set(EVENT__HAVE_ZLIB_H)
        include_directories(${ZLIB_INCLUDE_DIRS})
        list(APPEND SRC_REGRESS test/regress_zlib.c)
        list(APPEND LIB_REGRESS ${ZLIB_LIBRARIES})
    endif()
    
    set(SRC_EXTRA
        event_tagging.c 
        http.c 
        evdns.c 
        evrpc.c
        )
    
    add_definitions(-DHAVE_CONFIG_H)
    include_directories(./ ./compat ./include)
    
    if(WIN32)
        list(APPEND SRC_CORE 
            buffer_iocp.c 
            bufferevent_async.c
            event_iocp.c 
            evthread_win32.c 
            win32select.c
    		WIN32-Code/getopt.c
    		WIN32-Code/getopt_long.c
            )
        list(APPEND SRC_REGRESS test/regress_iocp.c)
    	list(APPEND SRC_REGRESS test/regress_thread.c)
        set(EVENT__DNS_USE_FTIME_FOR_ID 1)
        add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
        set(LIB_PLATFORM ws2_32)
    	include_directories(./WIN32-Code)
    endif()
    
    source_group("Headers Private"  FILES ${HDR_PRIVATE})
    source_group("Headers Public"   FILES ${HDR_PUBLIC})
    source_group("Source Core"      FILES ${SRC_CORE})
    source_group("Source Extra"     FILES ${SRC_EXTRA})
    
    configure_file(
        ${CMAKE_CURRENT_SOURCE_DIR}/event-config.h.cmake 
        ${CMAKE_CURRENT_SOURCE_DIR}/include/event2/event-config.h)
    
    add_library(event_core STATIC
        ${HDR_PRIVATE}
        ${HDR_PUBLIC}
        ${SRC_CORE}
        )
        
    add_library(event_extras STATIC
        ${SRC_EXTRA}
        )
        
    add_library(event STATIC
        ${HDR_PRIVATE}
        ${HDR_PUBLIC}
        ${SRC_CORE}
        ${SRC_EXTRA}
        )
    
    # TODO: Make these into tests instead?
    #add_executable(event-test sample/event-test.c)
    #target_link_libraries(event-test event ${LIB_PLATFORM})
    
    add_executable(time-test sample/time-test.c)
    target_link_libraries(time-test event ${LIB_PLATFORM})
    
    add_executable(signal-test sample/signal-test.c)
    target_link_libraries(signal-test event ${LIB_PLATFORM})
    
    #add_executable(test-init test/test-init.c)
    #target_link_libraries(test-init event ${LIB_PLATFORM})
    
    #add_executable(test-eof test/test-eof.c)
    #target_link_libraries(test-eof event ${LIB_PLATFORM})
    
    #add_executable(test-weof test/test-weof.c)
    #target_link_libraries(test-weof event ${LIB_PLATFORM})
    
    #add_executable(time-test test/time-test.c)
    #target_link_libraries(time-test event ${LIB_PLATFORM})
    
    if (NOT EVENT__DISABLE_BENCHMARK)
        add_executable(bench_cascade test/bench_cascade.c)
        target_link_libraries(bench_cascade event ${LIB_PLATFORM})
    
        add_executable(bench_http test/bench_http.c)
        target_link_libraries(bench_http event ${LIB_PLATFORM})
    endif()
    
    if (NOT EVENT__DISABLE_TESTS)
        if (PYTHONINTERP_FOUND)
            message("Generating regress tests...")
            add_definitions(-DTINYTEST_LOCAL)
            add_custom_command(
                OUTPUT 
                    ${CMAKE_CURRENT_SOURCE_DIR}/test/regress.gen.c 
                    ${CMAKE_CURRENT_SOURCE_DIR}/test/regress.gen.h
                DEPENDS 
                    event_rpcgen.py
                    test/regress.rpc 
                COMMAND ${PYTHON_EXECUTABLE} ../event_rpcgen.py regress.rpc 
                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
                )
    
            list(APPEND SRC_REGRESS 
                test/regress.c 
                test/regress_buffer.c 
                test/regress_http.c 
                test/regress_dns.c 
                test/regress_testutils.c 
                test/regress_testutils.h 
                test/regress_rpc.c 
                test/regress_et.c 
                test/regress_bufferevent.c 
                test/regress_listener.c 
                test/regress_util.c 
                test/tinytest.c 
                test/regress_main.c 
                test/regress_minheap.c
                test/regress.gen.c
                test/regress.gen.h
                test/regress_finalize.c
                )
     
            add_executable(regress ${SRC_REGRESS})
            target_link_libraries(regress event ${LIB_REGRESS} ${LIB_PLATFORM})
        else()
            message(WARNING "Python not found, cannot generate regress tests!")
        endif()
    
        # Tests.
        enable_testing()
    
        add_test(regress "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE_OUTPUT_PATH}/regress")
    
        include(CTest)
    endif()