# # 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.8.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" OFF) option(EVENT__ENABLE_VERBOSE_DEBUG "Enables verbose debugging" OFF) option(EVENT__DISABLE_MM_REPLACEMENT "Define if libevent should not allow replacing the mm functions" OFF) option(EVENT__DISABLE_THREAD_SUPPORT "Define if libevent should not be compiled with thread support" OFF) option(EVENT__DISABLE_OPENSSL "Define if libevent should build without support for OpenSSL encrpytion" OFF) option(EVENT__DISABLE_BENCHMARK "Defines if libevent should build without the benchmark exectuables" OFF) option(EVENT__DISABLE_TESTS "If tests should be compiled or not" OFF) option(EVENT__DISABLE_REGRESS "Disable the regress tests" OFF) # TODO: Add --enable-verbose-debug, verbose debug logging # TODO: Add --disable-largefile omit support for large files # 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 if (CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") option(EVENT__DISABLE_GCC_WARNINGS "Disable verbose warnings with GCC" OFF) if (EVENT__DISABLE_GCC_WARNINGS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") endif() option(EVENT__ENABLE_GCC_HARDENING "Enable compiler security checks" OFF) if (EVENT__ENABLE_GCC_HARDENING) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2 -fstack-protector-all -fwrapv -fPIE -Wstack-protector --param ssp-buffer-size=1") endif() option(EVENT__ENABLE_GCC_FUNCTION_SECTIONS "Enable gcc function sections" OFF) if (EVENT__ENABLE_GCC_FUNCTION_SECTIONS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections") # TODO: Add --gc-sections support. We need some checks for NetBSD to ensure this works. endif() # We need to test for at least gcc 2.95 here, because older versions don't # have -fno-strict-aliasing execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 2.95) message(STATUS "GCC Version >= 2.95 enabling no-strict-aliasing") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") endif() endif() if (APPLE) # Get rid of deprecated warnings for OpenSSL on OSX 10.7 and greater. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=deprecated-declarations") endif() # 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 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 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_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) set(EVENT__HAVE_OPENSSL 1) message("OpenSSL include: ${OPENSSL_INCLUDE_DIR}") message("OpenSSL lib: ${OPENSSL_LIBRARIES}") include_directories(${OPENSSL_INCLUDE_DIR}) list(APPEND SRC_CORE bufferevent_openssl.c) list(APPEND HDR_PUBLIC include/event2/bufferevent_ssl.h) list(APPEND LIB_APPS ${OPENSSL_LIBRARIES}) endif() if (NOT EVENT__DISABLE_THREAD_SUPPORT) if (WIN32) list(APPEND SRC_CORE evthread_win32.c) else() find_package(Threads REQUIRED) if (NOT CMAKE_USE_PTHREADS_INIT) message(FATAL_ERROR "Failed to find Pthreads, set EVENT__DISABLE_THREAD_SUPPORT to turn off thread support") endif() set(EVENT__HAVE_PTHREADS 1) list(APPEND SRC_CORE evthread_pthread.c) list(APPEND LIB_APPS ${CMAKE_THREAD_LIBS_INIT}) endif() endif() if (ZLIB_LIBRARY) set(EVENT__HAVE_ZLIB 1) set(EVENT__HAVE_ZLIB_H) include_directories(${ZLIB_INCLUDE_DIRS}) list(APPEND LIB_APPS ${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 ) list(APPEND HDR_PRIVATE WIN32-Code/getopt.h) 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() if (UNIX) list(APPEND LIB_PLATFORM m) 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}) # Generate the configure headers. # (Place them in the build dir so we don't polute the source tree with generated files). include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/event-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/include/event2/event-config.h) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/evconfig-private.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/include/evconfig-private.h) # TODO: Add dynamic versions of the libraries as well. 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} ) if (NOT EVENT__DISABLE_SAMPLES) set(SAMPLES dns-example event-read-fifo hello-world le-proxy signal-test http-server time-test) if (OPENSSL_LIBRARIES) # Special sample with more than one file. add_executable(https-client sample/https-client.c sample/openssl_hostname_validation.c sample/hostcheck.c) target_link_libraries(https-client event ${LIB_APPS} ${LIB_PLATFORM}) add_dependencies(https-client event) endif() foreach(SAMPLE ${SAMPLES}) add_executable(${SAMPLE} sample/${SAMPLE}.c) target_link_libraries(${SAMPLE} event ${LIB_APPS} ${LIB_PLATFORM}) add_dependencies(${SAMPLE} event) endforeach() endif() if (NOT EVENT__DISABLE_BENCHMARK) foreach (BENCHMARK bench bench_cascade bench_http bench_httpclient) set(BENCH_SRC test/${BENCHMARK}.c) if (WIN32) list(APPEND BENCH_SRC WIN32-Code/getopt.c WIN32-Code/getopt_long.c) endif() add_executable(${BENCHMARK} ${BENCH_SRC}) target_link_libraries(${BENCHMARK} event ${LIB_PLATFORM}) add_dependencies(${BENCHMARK} event) endforeach() endif() if (NOT EVENT__DISABLE_TESTS) # (We require python to generate the regress tests) find_package(PythonInterp 2) # TODO: Require 2.4+ here... # # Generate Regress tests. # if (NOT EVENT__DISABLE_REGRESS AND 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.gen.c test/regress.gen.h test/regress_buffer.c test/regress_bufferevent.c test/regress_dns.c test/regress_et.c test/regress_finalize.c test/regress_http.c test/regress_listener.c test/regress_main.c test/regress_minheap.c test/regress_rpc.c test/regress_testutils.c test/regress_testutils.h test/regress_util.c test/tinytest.c ) if (WIN32) list(APPEND SRC_REGRESS test/regress_iocp.c) list(APPEND SRC_REGRESS test/regress_thread.c) endif() if (CMAKE_USE_PTHREADS_INIT) list(APPEND SRC_REGRESS test/regress_thread.c) endif() if (ZLIB_LIBRARY) list(APPEND SRC_REGRESS test/regress_zlib.c) endif() if (OPENSSL_LIBRARIES) list(APPEND SRC_REGRESS test/regress_ssl.c) endif() add_executable(regress ${SRC_REGRESS}) target_link_libraries(regress event ${LIB_APPS} ${LIB_PLATFORM}) add_dependencies(regress event) else() message(WARNING "Python not found, cannot generate regress tests!") endif() # # Test programs. # set(TESTPROGS test-changelist test-eof test-fdleak test-init test-time test-weof) set(ALL_TESTPROGS ${TESTPROGS} test-dumpevents test-ratelim) # Create test program executables. foreach (TESTPROG ${ALL_TESTPROGS}) add_executable(${TESTPROG} test/${TESTPROG}.c) target_link_libraries(${TESTPROG} event ${LIB_PLATFORM}) add_dependencies(${TESTPROG} event) endforeach() # # We run all tests with the different backends turned on one at a time. # # Add event backends based on system introspection result. set(BACKENDS "") if (EVENT__HAVE_EPOLL) list(APPEND BACKENDS EPOLL) endif() if (EVENT__HAVE_SELECT) list(APPEND BACKENDS SELECT) endif() if (EVENT__HAVE_POLL) list(APPEND BACKENDS POLL) endif() if (EVENT__HAVE_KQUEUE) list(APPEND BACKENDS KQUEUE) endif() if (EVENT__HAVE_EVENT_PORTS) list(APPEND BACKENDS EVPORT) endif() if (EVENT__HAVE_DEVPOLL) list(APPEND BACKENDS DEVPOLL) endif() if (WIN32) list(APPEND BACKENDS WIN32) endif() message("Available event backends: ${BACKENDS}") # Default environment variables turns off all event systems, # then we enable each one, one at a time when creating the tests. set(DEFAULT_TEST_ENV_VARS "EVENT_SHOW_METHOD=1;") foreach(BACKEND ${BACKENDS}) set(BACKEND_ENV_VAR "EVENT_NO${BACKEND}=1") list(APPEND DEFAULT_TEST_ENV_VARS "${BACKEND_ENV_VAR}") endforeach() # Macro that creates the ctest test for a backend. macro(add_backend_test BACKEND_TEST_NAME ENV_VARS) set(TEST_NAMES "") foreach (TESTPROG ${TESTPROGS}) set(TEST_NAME ${TESTPROG}__${BACKEND_TEST_NAME}) add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTPROG}) list(APPEND TEST_NAMES ${TEST_NAME}) set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARS}") endforeach() # Dump events test. if (PYTHONINTERP_FOUND) set(TEST_NAME test-dumpevents__${BACKEND_TEST_NAME}) add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents | ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/check-dumpevents.py) set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARS}") else() message(WARNING "test-dumpevents will be run without output check since python was not found!") set(TEST_NAME test-dumpevents__${BACKEND_TEST_NAME}_no_check) add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents) set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARS}") endif() # Regress tests. if (NOT EVENT__DISABLE_REGRESS AND PYTHONINTERP_FOUND) set(TEST_NAME regress__${BACKEND_TEST_NAME}) add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress) set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARS}") endif() endmacro() # Add the tests for each backend. foreach(BACKEND ${BACKENDS}) # Enable this backend only. set(BACKEND_ENV_VARS ${DEFAULT_TEST_ENV_VARS}) list(REMOVE_ITEM BACKEND_ENV_VARS EVENT_NO${BACKEND}=1) # Epoll has some extra settings. if (${BACKEND} STREQUAL "EPOLL") add_backend_test(timerfd_${BACKEND} "${BACKEND_ENV_VARS};EVENT_PRECISE_TIMER=1") add_backend_test(changelist_${BACKEND} "${BACKEND_ENV_VARS};EVENT_EPOLL_USE_CHANGELIST=yes") add_backend_test(timerfd_changelist_${BACKEND} "${BACKEND_ENV_VARS};EVENT_EPOLL_USE_CHANGELIST=yes;EVENT_PRECISE_TIMER=1") else() add_backend_test(${BACKEND} "${BACKEND_ENV_VARS}") endif() endforeach() # # Rate limiter tests. # # Group limits, no connection limit. add_test(test-ratelim__group_lim ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim -g 30000 -n 30 -t 100 --check-grouplimit 1000 --check-stddev 100) # Connection limit, no group limit. add_test(test-ratelim__con_lim ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim -c 1000 -n 30 -t 100 --check-connlimit 50 --check-stddev 50) # Connection limit and group limit. add_test(test-ratelim__group_con_lim ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim -c 1000 -g 30000 -n 30 -t 100 --check-grouplimit 1000 --check-connlimit 50 --check-stddev 50) # Connection limit and group limit with independent drain. add_test(test-ratelim__group_con_lim_drain ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim -c 1000 -g 35000 -n 30 -t 100 -G 500 --check-grouplimit 1000 --check-connlimit 50 --check-stddev 50) # Add a "make verify" target, same as for autoconf. # (Important! This will unset all EVENT_NO* environment variables. # If they are set in the shell the tests are running using simply "ctest" or "make test" will fail) if (WIN32) # Windows doesn't have "unset", and the above does not happen anyway. add_custom_target(verify COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS event ${ALL_TESTPROGS}) else() add_custom_target(verify COMMAND unset EVENT_NOEPOLL && unset EVENT_NOPOLL && unset EVENT_NOSELECT && unset EVENT_NOWIN32 && unset EVENT_NOEVPORT && unset EVENT_NOKQUEUE && unset EVENT_NODEVPOLL && ${CMAKE_CTEST_COMMAND} DEPENDS event ${ALL_TESTPROGS}) endif() if (NOT EVENT__DISABLE_REGRESS) add_dependencies(verify regress) endif() enable_testing() include(CTest) endif()