blob: 70acb696ca3d306df838aa0b8e1b517b001aa5d1 [file] [log] [blame]
Haibo Huangb2279672019-05-31 16:12:39 -07001#
2# Libevent CMake project
3#
4# Based on initial work by:
5# Alexey Ozeritsky
6#
7# Additional changes:
8# Brodie Thiesfield
9# Joakim Soderberg
10# Trond Norbye
11# Sergei Nikulov
12#
13# Build example:
14#
15# cd libevent
16# md build
17# cd build
18# cmake -G "Visual Studio 10" ..
19# start libevent.sln
20#
21
22cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
23
24if (POLICY CMP0054)
25 cmake_policy(SET CMP0054 NEW)
26endif()
27if (POLICY CMP0074)
28 cmake_policy(SET CMP0074 NEW)
29endif()
30if (POLICY CMP0075)
31 cmake_policy(SET CMP0075 NEW)
32endif()
33
34if(NOT CMAKE_BUILD_TYPE)
35 set(CMAKE_BUILD_TYPE Release
36 CACHE STRING "Set build type to Debug o Release (default Release)" FORCE)
37endif()
38string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
39
40# get rid of the extra default configurations
41# what? why would you get id of other useful build types? - Ellzey
42set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Limited configurations" FORCE)
43
44set(EVENT__LIBRARY_TYPE DEFAULT CACHE STRING
45 "Set library type to SHARED/STATIC/BOTH (default SHARED for MSVC, otherwise BOTH)")
46
47project(libevent C)
48
49set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
50string(REGEX MATCH "SunOS" SOLARIS "${CMAKE_SYSTEM_NAME}")
51
52
53include(CheckTypeSize)
54include(CheckFunctionExistsEx)
55include(CheckFileOffsetBits)
56include(CheckFunctionExists)
57include(CheckIncludeFile)
58include(CheckIncludeFiles)
59include(CheckVariableExists)
60include(CheckSymbolExists)
61include(CheckStructHasMember)
62include(CheckCSourceCompiles)
63include(CheckPrototypeDefinition)
64include(CheckFunctionKeywords)
65include(CheckConstExists)
66include(AddCompilerFlags)
67include(VersionViaGit)
68
69event_fuzzy_version_from_git()
70
71set(EVENT_VERSION_MAJOR ${EVENT_GIT___VERSION_MAJOR})
72set(EVENT_VERSION_MINOR ${EVENT_GIT___VERSION_MINOR})
73set(EVENT_VERSION_PATCH ${EVENT_GIT___VERSION_PATCH})
74set(EVENT_VERSION_STAGE ${EVENT_GIT___VERSION_STAGE})
75
76
77set(EVENT_ABI_MAJOR ${EVENT_VERSION_MAJOR})
78set(EVENT_ABI_MINOR ${EVENT_VERSION_MINOR})
79set(EVENT_ABI_PATCH ${EVENT_VERSION_PATCH})
80
81set(EVENT_ABI_LIBVERSION
82 "${EVENT_ABI_MAJOR}.${EVENT_ABI_MINOR}.${EVENT_ABI_PATCH}")
83
84set(EVENT_PACKAGE_VERSION
85 "${EVENT_VERSION_MAJOR}.${EVENT_VERSION_MINOR}.${EVENT_VERSION_PATCH}")
86
Haibo Huang45729092019-08-01 16:15:45 -070087set(EVENT_NUMERIC_VERSION 0x02010b00)
88# equals to VERSION_INFO in Makefile.am
89set(EVENT_ABI_LIBVERSION_CURRENT 7)
90set(EVENT_ABI_LIBVERSION_REVISION 0)
91set(EVENT_ABI_LIBVERSION_AGE 0)
92
93# equals to RELEASE in Makefile.am
94set(EVENT_PACKAGE_RELEASE 2.1)
Haibo Huangb2279672019-05-31 16:12:39 -070095
96# only a subset of names can be used, defaults to "beta"
97set(EVENT_STAGE_NAME ${EVENT_VERSION_STAGE})
98
99# a list that defines what can set for EVENT_STAGE_VERSION
100set(EVENT__ALLOWED_STAGE_NAMES
101 rc
102 beta
103 alpha
104 alpha-dev
105 release
106 stable
107)
108list(
109 FIND EVENT__ALLOWED_STAGE_NAMES
110 "${EVENT_STAGE_NAME}"
111 EVENT__STAGE_RET
112)
113if (EVENT__STAGE_RET EQUAL -1)
114 message(WARNING
115 "stage ${EVENT_STAGE_NAME} is not allowed, reset to beta")
116 set(EVENT_STAGE_NAME beta)
117endif()
118
119set(EVENT_VERSION
120 "${EVENT_VERSION_MAJOR}.${EVENT_VERSION_MINOR}.${EVENT_VERSION_PATCH}-${EVENT_STAGE_NAME}")
121
122option(EVENT__DISABLE_DEBUG_MODE
123 "Define if libevent should build without support for a debug mode" OFF)
124
125option(EVENT__ENABLE_VERBOSE_DEBUG
126 "Enables verbose debugging" OFF)
127
128option(EVENT__DISABLE_MM_REPLACEMENT
129 "Define if libevent should not allow replacing the mm functions" OFF)
130
131option(EVENT__DISABLE_THREAD_SUPPORT
132 "Define if libevent should not be compiled with thread support" OFF)
133
134option(EVENT__DISABLE_OPENSSL
135 "Define if libevent should build without support for OpenSSL encryption" OFF)
136
137option(EVENT__DISABLE_BENCHMARK
138 "Defines if libevent should build without the benchmark executables" OFF)
139
140option(EVENT__DISABLE_TESTS
141 "If tests should be compiled or not" OFF)
142
143option(EVENT__DISABLE_REGRESS
144 "Disable the regress tests" OFF)
145
146option(EVENT__DISABLE_SAMPLES
147 "Disable sample files" OFF)
148
149option(EVENT__DISABLE_CLOCK_GETTIME
150 "Do not use clock_gettime even if it is available" OFF)
151
152option(EVENT__FORCE_KQUEUE_CHECK
153 "When crosscompiling forces running a test program that verifies that Kqueue works with pipes. Note that this requires you to manually run the test program on the cross compilation target to verify that it works. See cmake documentation for try_run for more details" OFF)
154
155# TODO: Add --disable-largefile omit support for large files
156option(EVENT__COVERAGE
157"Enable running gcov to get a test coverage report (only works with GCC/CLang). Make sure to enable -DCMAKE_BUILD_TYPE=Debug as well." OFF)
158
159# Put the libaries and binaries that get built into directories at the
160# top of the build tree rather than in hard-to-find leaf directories.
161set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
162set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
163set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
164
165if (EVENT__ENABLE_VERBOSE_DEBUG)
166 add_definitions(-DUSE_DEBUG=1)
167endif()
168
169# make it colorful under ninja-build
170if ("${CMAKE_GENERATOR}" STREQUAL "Ninja")
171 add_compiler_flags(-fdiagnostics-color=always)
172endif()
173
174# Setup compiler flags for coverage.
175if (EVENT__COVERAGE)
176 if (NOT "${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "debug")
177 message(FATAL_ERROR "Coverage requires -DCMAKE_BUILD_TYPE=Debug")
178 endif()
179
180 message(STATUS "Setting coverage compiler flags")
181
182 set(CMAKE_REQUIRED_LIBRARIES "--coverage")
183 add_compiler_flags(-g -O0 --coverage)
184 set(CMAKE_REQUIRED_LIBRARIES "")
185endif()
186
187set(GNUC 0)
188set(CLANG 0)
189set(MSVC 0)
190if (("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR
191 ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang"))
192 set(CLANG 1)
193endif()
194if (("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR (${CLANG}))
195 set(GNUC 1)
196endif()
197if (("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") OR (${CLANG}))
198 set(MSVC 1)
199endif()
200
201# Detect library type
202set(EVENT_LIBRARY_TYPE)
203if ("${EVENT__LIBRARY_TYPE}" STREQUAL "DEFAULT")
204 if (${MSVC})
205 set(EVENT_LIBRARY_TYPE SHARED)
206 else()
207 set(EVENT_LIBRARY_TYPE BOTH)
208 endif()
209else()
210 string(TOUPPER "${EVENT__LIBRARY_TYPE}" EVENT_LIBRARY_TYPE)
211endif()
212if ((${MSVC}) AND ("${EVENT_LIBRARY_TYPE}" STREQUAL "BOTH"))
213 message(WARNING
214 "Building SHARED and STATIC is not supported for MSVC "
215 "(due to conflicts in library name"
216 " between STATIC library and IMPORTED library for SHARED libraries)")
217endif()
218set(EVENT_LIBRARY_STATIC OFF)
219set(EVENT_LIBRARY_SHARED OFF)
220if ("${EVENT_LIBRARY_TYPE}" STREQUAL "BOTH")
221 set(EVENT_LIBRARY_STATIC ON)
222 set(EVENT_LIBRARY_SHARED ON)
223elseif ("${EVENT_LIBRARY_TYPE}" STREQUAL "STATIC")
224 set(EVENT_LIBRARY_STATIC ON)
225elseif ("${EVENT_LIBRARY_TYPE}" STREQUAL "SHARED")
226 set(EVENT_LIBRARY_SHARED ON)
227else()
228 message(FATAL_ERROR "${EVENT_LIBRARY_TYPE} is not supported")
229endif()
230
231if (${MSVC})
232 set(msvc_static_runtime OFF)
233 if ("${EVENT_LIBRARY_TYPE}" STREQUAL "STATIC")
234 set(msvc_static_runtime ON)
235 endif()
236
237 # For more info:
238 # - https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=vs-2017
239 # - https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-can-i-build-my-msvc-application-with-a-static-runtime
240 option(EVENT__MSVC_STATIC_RUNTIME
241 "Link static runtime libraries"
242 ${msvc_static_runtime})
243
244 if (EVENT__MSVC_STATIC_RUNTIME)
245 foreach (flag_var
246 CMAKE_C_FLAGS
247 CMAKE_C_FLAGS_DEBUG
248 CMAKE_C_FLAGS_RELEASE
249 CMAKE_C_FLAGS_MINSIZEREL
250 CMAKE_C_FLAGS_RELWITHDEBINFO
251 )
252 if (${flag_var} MATCHES "/MD")
253 string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
254 endif()
255 endforeach()
256 endif()
257endif()
258
259# GNUC specific options.
260if (${GNUC})
261 option(EVENT__DISABLE_GCC_WARNINGS "Disable verbose warnings with GCC" OFF)
262 option(EVENT__ENABLE_GCC_HARDENING "Enable compiler security checks" OFF)
263 option(EVENT__ENABLE_GCC_FUNCTION_SECTIONS "Enable gcc function sections" OFF)
264 option(EVENT__ENABLE_GCC_WARNINGS "Make all GCC warnings into errors" OFF)
265
266 set(GCC_V ${CMAKE_C_COMPILER_VERSION})
267
268 list(APPEND __FLAGS
269 -Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing -Wstrict-prototypes
270
271 -fno-strict-aliasing # gcc 2.9.5+
272 -Wmissing-prototypes
273
274 # gcc 4
275 -Winit-self
276 -Wmissing-field-initializers
277 -Wdeclaration-after-statement
278
279 # gcc 4.2
280 -Waddress
281 -Wnormalized=id
282 -Woverride-init
283
284 # gcc 4.5
285 -Wlogical-op
286
287 -Wwrite-strings
288 )
289
290 if (${CLANG})
291 list(APPEND __FLAGS -Wno-unused-function)
292 endif()
293
294 if (EVENT__DISABLE_GCC_WARNINGS)
295 list(APPEND __FLAGS -w)
296 endif()
297
298 if (EVENT__ENABLE_GCC_HARDENING)
299 list(APPEND __FLAGS
300 -fstack-protector-all
301 -fwrapv
302 -fPIE
303 -Wstack-protector
304 "--param ssp-buffer-size=1")
305
306 add_definitions(-D_FORTIFY_SOURCE=2)
307 endif()
308
309 if (EVENT__ENABLE_GCC_FUNCTION_SECTIONS)
310 list(APPEND __FLAGS -ffunction-sections)
311 # TODO: Add --gc-sections support. We need some checks for NetBSD to ensure this works.
312 endif()
313
314 if (EVENT__ENABLE_GCC_WARNINGS)
315 list(APPEND __FLAGS -Werror)
316 endif()
317
318 add_compiler_flags(${__FLAGS})
319endif()
320
321if (APPLE)
322 # Get rid of deprecated warnings for OpenSSL on OSX 10.7 and greater.
323 add_compiler_flags(
324 -Wno-error=deprecated-declarations
325 -Qunused-arguments
326 )
327endif()
328
329# Winsock.
330if(WIN32)
331 set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h ws2tcpip.h)
Haibo Huang45729092019-08-01 16:15:45 -0700332 set(CMAKE_REQUIRED_LIBRARIES ws2_32.lib shell32.lib advapi32.lib)
Haibo Huangb2279672019-05-31 16:12:39 -0700333 set(CMAKE_REQUIRED_DEFINITIONS -FIwinsock2.h -FIws2tcpip.h)
334endif()
335if (SOLARIS)
336 set(CMAKE_REQUIRED_LIBRARIES socket nsl)
337endif()
338
339# Check if _GNU_SOURCE is available.
340if (NOT DEFINED _GNU_SOURCE)
341 CHECK_SYMBOL_EXISTS(__GNU_LIBRARY__ "features.h" _GNU_SOURCE)
342
343 if (NOT _GNU_SOURCE)
344 unset(_GNU_SOURCE CACHE)
345 CHECK_SYMBOL_EXISTS(_GNU_SOURCE "features.h" _GNU_SOURCE)
346 endif()
Haibo Huang45729092019-08-01 16:15:45 -0700347
348 if (ANDROID)
349 set(_GNU_SOURCE TRUE)
350 endif()
Haibo Huangb2279672019-05-31 16:12:39 -0700351endif()
352
353if (_GNU_SOURCE)
354 add_definitions(-D_GNU_SOURCE=1)
355endif()
356
357CHECK_INCLUDE_FILE(sys/types.h EVENT__HAVE_SYS_TYPES_H)
358if(EVENT__HAVE_SYS_TYPES_H)
359 list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/types.h)
360endif()
361
362CHECK_INCLUDE_FILE(sys/socket.h EVENT__HAVE_SYS_SOCKET_H)
363if(EVENT__HAVE_SYS_SOCKET_H)
364 list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
365endif()
366
367CHECK_INCLUDE_FILE(netinet/in.h EVENT__HAVE_NETINET_IN_H)
368if(EVENT__HAVE_NETINET_IN_H)
369 list(APPEND CMAKE_EXTRA_INCLUDE_FILES netinet/in.h)
370endif()
371
372CHECK_INCLUDE_FILE(sys/un.h EVENT__HAVE_SYS_UN_H)
373if(EVENT__HAVE_SYS_UN_H)
374 list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/un.h)
375endif()
376
377if(WIN32)
378 CHECK_INCLUDE_FILE(afunix.h EVENT__HAVE_AFUNIX_H)
379 if(EVENT__HAVE_AFUNIX_H)
380 list(APPEND CMAKE_EXTRA_INCLUDE_FILES afunix.h)
381 endif()
382endif()
383CHECK_TYPE_SIZE("struct sockaddr_un" EVENT__HAVE_STRUCT_SOCKADDR_UN)
384
385CHECK_INCLUDE_FILE(netinet/in6.h EVENT__HAVE_NETINET_IN6_H)
386if(EVENT__HAVE_NETINET_IN6_H)
387 list(APPEND CMAKE_EXTRA_INCLUDE_FILES netinet/in6.h)
388endif()
389
390CHECK_INCLUDE_FILE(unistd.h EVENT__HAVE_UNISTD_H)
391CHECK_INCLUDE_FILE(netdb.h EVENT__HAVE_NETDB_H)
392CHECK_INCLUDE_FILE(dlfcn.h EVENT__HAVE_DLFCN_H)
393CHECK_INCLUDE_FILE(arpa/inet.h EVENT__HAVE_ARPA_INET_H)
394CHECK_INCLUDE_FILE(fcntl.h EVENT__HAVE_FCNTL_H)
395if(EVENT__HAVE_FCNTL_H)
396 list(APPEND CMAKE_EXTRA_INCLUDE_FILES fcntl.h)
397endif()
398CHECK_INCLUDE_FILE(inttypes.h EVENT__HAVE_INTTYPES_H)
399CHECK_INCLUDE_FILE(memory.h EVENT__HAVE_MEMORY_H)
400CHECK_INCLUDE_FILE(poll.h EVENT__HAVE_POLL_H)
401CHECK_INCLUDE_FILE(port.h EVENT__HAVE_PORT_H)
402if(EVENT__HAVE_PORT_H)
403 list(APPEND CMAKE_EXTRA_INCLUDE_FILES port.h)
404endif()
405CHECK_INCLUDE_FILE(signal.h EVENT__HAVE_SIGNAL_H)
406CHECK_INCLUDE_FILE(stdarg.h EVENT__HAVE_STDARG_H)
407CHECK_INCLUDE_FILE(stddef.h EVENT__HAVE_STDDEF_H)
408CHECK_INCLUDE_FILE(stdint.h EVENT__HAVE_STDINT_H)
409CHECK_INCLUDE_FILE(stdlib.h EVENT__HAVE_STDLIB_H)
410CHECK_INCLUDE_FILE(strings.h EVENT__HAVE_STRINGS_H)
411CHECK_INCLUDE_FILE(string.h EVENT__HAVE_STRING_H)
412CHECK_INCLUDE_FILE(sys/devpoll.h EVENT__HAVE_DEVPOLL)
413CHECK_INCLUDE_FILE(sys/epoll.h EVENT__HAVE_SYS_EPOLL_H)
414CHECK_INCLUDE_FILE(sys/eventfd.h EVENT__HAVE_SYS_EVENTFD_H)
415CHECK_INCLUDE_FILE(sys/event.h EVENT__HAVE_SYS_EVENT_H)
416CHECK_INCLUDE_FILE(sys/ioctl.h EVENT__HAVE_SYS_IOCTL_H)
417CHECK_INCLUDE_FILE(sys/mman.h EVENT__HAVE_SYS_MMAN_H)
418CHECK_INCLUDE_FILE(sys/param.h EVENT__HAVE_SYS_PARAM_H)
419CHECK_INCLUDE_FILE(sys/queue.h EVENT__HAVE_SYS_QUEUE_H)
420CHECK_INCLUDE_FILE(sys/select.h EVENT__HAVE_SYS_SELECT_H)
421CHECK_INCLUDE_FILE(sys/sendfile.h EVENT__HAVE_SYS_SENDFILE_H)
422CHECK_INCLUDE_FILE(sys/stat.h EVENT__HAVE_SYS_STAT_H)
423CHECK_INCLUDE_FILE(sys/time.h EVENT__HAVE_SYS_TIME_H)
424if(EVENT__HAVE_SYS_TIME_H)
425 list(APPEND CMAKE_EXTRA_INCLUDE_FILES sys/time.h)
426endif()
427CHECK_INCLUDE_FILE(sys/uio.h EVENT__HAVE_SYS_UIO_H)
428CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" EVENT__HAVE_IFADDRS_H)
429CHECK_INCLUDE_FILE(mach/mach_time.h EVENT__HAVE_MACH_MACH_TIME_H)
430CHECK_INCLUDE_FILE(netinet/tcp.h EVENT__HAVE_NETINET_TCP_H)
431CHECK_INCLUDE_FILE(sys/wait.h EVENT__HAVE_SYS_WAIT_H)
432CHECK_INCLUDE_FILE(sys/resource.h EVENT__HAVE_SYS_RESOURCE_H)
433CHECK_INCLUDE_FILE(sys/sysctl.h EVENT__HAVE_SYS_SYSCTL_H)
434CHECK_INCLUDE_FILE(sys/timerfd.h EVENT__HAVE_SYS_TIMERFD_H)
435CHECK_INCLUDE_FILE(errno.h EVENT__HAVE_ERRNO_H)
436
437
438CHECK_FUNCTION_EXISTS_EX(epoll_create EVENT__HAVE_EPOLL)
439CHECK_FUNCTION_EXISTS_EX(epoll_ctl EVENT__HAVE_EPOLL_CTL)
440CHECK_FUNCTION_EXISTS_EX(eventfd EVENT__HAVE_EVENTFD)
441if(NOT EVENT__DISABLE_CLOCK_GETTIME)
442 CHECK_FUNCTION_EXISTS_EX(clock_gettime EVENT__HAVE_CLOCK_GETTIME)
443endif()
444CHECK_FUNCTION_EXISTS_EX(fcntl EVENT__HAVE_FCNTL)
445CHECK_FUNCTION_EXISTS_EX(getaddrinfo EVENT__HAVE_GETADDRINFO)
446CHECK_FUNCTION_EXISTS_EX(getnameinfo EVENT__HAVE_GETNAMEINFO)
447CHECK_FUNCTION_EXISTS_EX(gettimeofday EVENT__HAVE_GETTIMEOFDAY)
448CHECK_FUNCTION_EXISTS_EX(getprotobynumber EVENT__HAVE_GETPROTOBYNUMBER)
449CHECK_FUNCTION_EXISTS_EX(getservbyname EVENT__HAVE_GETSERVBYNAME)
450CHECK_FUNCTION_EXISTS_EX(inet_ntop EVENT__HAVE_INET_NTOP)
451CHECK_FUNCTION_EXISTS_EX(inet_pton EVENT__HAVE_INET_PTON)
452CHECK_FUNCTION_EXISTS_EX(kqueue EVENT__HAVE_KQUEUE)
453CHECK_FUNCTION_EXISTS_EX(mmap EVENT__HAVE_MMAP)
454CHECK_FUNCTION_EXISTS_EX(pipe EVENT__HAVE_PIPE)
455CHECK_FUNCTION_EXISTS_EX(pipe2 EVENT__HAVE_PIPE2)
456CHECK_FUNCTION_EXISTS_EX(poll EVENT__HAVE_POLL)
457CHECK_FUNCTION_EXISTS_EX(port_create EVENT__HAVE_PORT_CREATE)
458CHECK_FUNCTION_EXISTS_EX(sendfile EVENT__HAVE_SENDFILE)
459CHECK_FUNCTION_EXISTS_EX(sigaction EVENT__HAVE_SIGACTION)
460CHECK_FUNCTION_EXISTS_EX(signal EVENT__HAVE_SIGNAL)
461CHECK_FUNCTION_EXISTS_EX(splice EVENT__HAVE_SPLICE)
462CHECK_FUNCTION_EXISTS_EX(strlcpy EVENT__HAVE_STRLCPY)
463CHECK_FUNCTION_EXISTS_EX(strsep EVENT__HAVE_STRSEP)
464CHECK_FUNCTION_EXISTS_EX(strtok_r EVENT__HAVE_STRTOK_R)
465CHECK_FUNCTION_EXISTS_EX(strtoll EVENT__HAVE_STRTOLL)
466CHECK_FUNCTION_EXISTS_EX(vasprintf EVENT__HAVE_VASPRINTF)
467CHECK_FUNCTION_EXISTS_EX(sysctl EVENT__HAVE_SYSCTL)
468CHECK_FUNCTION_EXISTS_EX(accept4 EVENT__HAVE_ACCEPT4)
469CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM)
470CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF)
471CHECK_FUNCTION_EXISTS_EX(arc4random_addrandom EVENT__HAVE_ARC4RANDOM_ADDRANDOM)
472CHECK_FUNCTION_EXISTS_EX(epoll_create1 EVENT__HAVE_EPOLL_CREATE1)
473CHECK_FUNCTION_EXISTS_EX(getegid EVENT__HAVE_GETEGID)
474CHECK_FUNCTION_EXISTS_EX(geteuid EVENT__HAVE_GETEUID)
475CHECK_FUNCTION_EXISTS_EX(getifaddrs EVENT__HAVE_GETIFADDRS)
476CHECK_FUNCTION_EXISTS_EX(issetugid EVENT__HAVE_ISSETUGID)
477CHECK_FUNCTION_EXISTS_EX(mach_absolute_time EVENT__HAVE_MACH_ABSOLUTE_TIME)
478CHECK_FUNCTION_EXISTS_EX(nanosleep EVENT__HAVE_NANOSLEEP)
479CHECK_FUNCTION_EXISTS_EX(usleep EVENT__HAVE_USLEEP)
480CHECK_FUNCTION_EXISTS_EX(timeradd EVENT__HAVE_TIMERADD)
481CHECK_FUNCTION_EXISTS_EX(timerclear EVENT__HAVE_TIMERCLEAR)
482CHECK_FUNCTION_EXISTS_EX(timercmp EVENT__HAVE_TIMERCMP)
483CHECK_FUNCTION_EXISTS_EX(timerfd_create EVENT__HAVE_TIMERFD_CREATE)
484CHECK_FUNCTION_EXISTS_EX(timerisset EVENT__HAVE_TIMERISSET)
485CHECK_FUNCTION_EXISTS_EX(putenv EVENT__HAVE_PUTENV)
486CHECK_FUNCTION_EXISTS_EX(setenv EVENT__HAVE_SETENV)
487CHECK_FUNCTION_EXISTS_EX(setrlimit EVENT__HAVE_SETRLIMIT)
488CHECK_FUNCTION_EXISTS_EX(umask EVENT__HAVE_UMASK)
489CHECK_FUNCTION_EXISTS_EX(unsetenv EVENT__HAVE_UNSETENV)
490
491# Get the gethostbyname_r prototype.
492CHECK_FUNCTION_EXISTS_EX(gethostbyname_r EVENT__HAVE_GETHOSTBYNAME_R)
493
494if(EVENT__HAVE_GETHOSTBYNAME_R)
495 CHECK_PROTOTYPE_DEFINITION(gethostbyname_r
496 "int gethostbyname_r(const char *name, struct hostent *hp, struct hostent_data *hdata)"
497 "0"
498 "netdb.h"
499 EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
500
501 CHECK_PROTOTYPE_DEFINITION(gethostbyname_r
502 "struct hostent *gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen, int *herr)"
503 "NULL"
504 "netdb.h"
505 EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
506
507 CHECK_PROTOTYPE_DEFINITION(gethostbyname_r
508 "int gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen, struct hostent **result, int *herr)"
509 "0"
510 "netdb.h"
511 EVENT__HAVE_GETHOSTBYNAME_R_6_ARG)
512endif()
513
514if(HAVE_PORT_H AND HAVE_PORT_CREATE)
515 set(EVENT__HAVE_EVENT_PORTS 1)
516endif()
517
518if(NOT WIN32)
519 CHECK_FUNCTION_EXISTS_EX(select EVENT__HAVE_SELECT)
520endif()
521
522CHECK_TYPE_SIZE("uint8_t" EVENT__HAVE_UINT8_T)
523CHECK_TYPE_SIZE("uint16_t" EVENT__HAVE_UINT16_T)
524CHECK_TYPE_SIZE("uint32_t" EVENT__HAVE_UINT32_T)
525CHECK_TYPE_SIZE("uint64_t" EVENT__HAVE_UINT64_T)
526CHECK_TYPE_SIZE("short" EVENT__SIZEOF_SHORT BUILTIN_TYPES_ONLY)
527CHECK_TYPE_SIZE("int" EVENT__SIZEOF_INT BUILTIN_TYPES_ONLY)
528CHECK_TYPE_SIZE("unsigned" EVENT__SIZEOF_UNSIGNED BUILTIN_TYPES_ONLY)
529CHECK_TYPE_SIZE("unsigned int" EVENT__SIZEOF_UNSIGNED_INT BUILTIN_TYPES_ONLY)
530CHECK_TYPE_SIZE("long" EVENT__SIZEOF_LONG BUILTIN_TYPES_ONLY)
531CHECK_TYPE_SIZE("long long" EVENT__SIZEOF_LONG_LONG BUILTIN_TYPES_ONLY)
532
533if(WIN32)
534 # These aren't available until Windows Vista.
535 # But you can still link them. They just won't be found when running the exe.
536 set(EVENT__HAVE_INET_NTOP 0)
537 set(EVENT__HAVE_INET_PTON 0)
538endif()
539
540# Check for different inline keyword versions.
541check_function_keywords("inline" "__inline" "__inline__")
542
543if (HAVE_INLINE)
544 set(EVENT__inline inline)
545elseif (HAVE___INLINE)
546 set(EVENT__inline __inline)
547elseif(HAVE___INLINE__)
548 set(EVENT__inline __inline__)
549else()
550 set(EVENT__inline)
551endif()
552
553# __func__/__FUNCTION__ is not a macros in general
554CHECK_SYMBOL_EXISTS("__func__" "" EVENT__HAVE___func__)
555CHECK_SYMBOL_EXISTS("__FUNCTION__" "" EVENT__HAVE___FUNCTION__)
556
557CHECK_SYMBOL_EXISTS(TAILQ_FOREACH sys/queue.h EVENT__HAVE_TAILQFOREACH)
558CHECK_CONST_EXISTS(CTL_KERN sys/sysctl.h EVENT__HAVE_DECL_CTL_KERN)
559CHECK_CONST_EXISTS(KERN_ARND sys/sysctl.h EVENT__HAVE_DECL_KERN_ARND)
560CHECK_CONST_EXISTS(KERN_RANDOM sys/sysctl.h EVENT__HAVE_DECL_KERN_RANDOM)
561CHECK_CONST_EXISTS(RANDOM_UUID sys/sysctl.h EVENT__HAVE_DECL_RANDOM_UUID)
562CHECK_SYMBOL_EXISTS(F_SETFD fcntl.h EVENT__HAVE_SETFD)
563
564CHECK_TYPE_SIZE(fd_mask EVENT__HAVE_FD_MASK)
565
566CHECK_TYPE_SIZE(size_t EVENT__SIZEOF_SIZE_T)
567if(NOT EVENT__SIZEOF_SIZE_T)
568 set(EVENT__size_t "unsigned")
569 set(EVENT__SIZEOF_SIZE_T ${EVENT__SIZEOF_UNSIGNED})
570else()
571 set(EVENT__size_t size_t)
572endif()
573
574CHECK_TYPE_SIZE("off_t" EVENT__SIZEOF_OFF_T LANGUAGE C)
575
576
577# XXX we should functionalize these size and type sets. --elley
578
579# Winssck.
580if (_MSC_VER)
581 list(APPEND CMAKE_EXTRA_INCLUDE_FILES BaseTsd.h)
582endif()
583CHECK_TYPE_SIZE("ssize_t" EVENT__SIZEOF_SSIZE_T_LOWER LANGUAGE C)
584CHECK_TYPE_SIZE("SSIZE_T" EVENT__SIZEOF_SSIZE_T_UPPER LANGUAGE C)
585
586if (EVENT__SIZEOF_SSIZE_T_LOWER)
587 set(EVENT__ssize_t "ssize_t")
588 set(EVENT__SIZEOF_SSIZE_T ${EVENT__SIZEOF_SSIZE_T_LOWER})
589elseif (EVENT__SIZEOF_SSIZE_T_UPPER)
590 set(EVENT__ssize_t "SSIZE_T")
591 set(EVENT__SIZEOF_SSIZE_T ${EVENT__SIZEOF_SSIZE_T_UPPER})
592else()
593 set(EVENT__ssize_t "int")
594 set(EVENT__SIZEOF_SSIZE_T ${EVENT__SIZEOF_INT})
595endif()
596
597CHECK_TYPE_SIZE(socklen_t EVENT__SIZEOF_SOCKLEN_T)
598if(NOT EVENT__SIZEOF_SOCKLEN_T)
599 set(EVENT__socklen_t "unsigned int")
600 set(EVENT__SIZEOF_SOCKLEN_T ${EVENT__SIZEOF_UNSIGNED_INT})
601else()
602 set(EVENT__socklen_t "socklen_t")
603endif()
604
605CHECK_TYPE_SIZE(pid_t EVENT__SIZEOF_PID_T)
606if(NOT EVENT__SIZEOF_PID_T)
607 set(EVENT__SIZEOF_PID_T ${EVENT__SIZEOF_INT})
608else()
609 set(EVENT__SIZEOF_PID_T EVENT__SIZEOF_PID_T)
610endif()
611
612if (NOT EVENT__DISABLE_THREAD_SUPPORT)
613 if (NOT WIN32)
614 list(APPEND CMAKE_EXTRA_INCLUDE_FILES pthread.h)
615 endif()
616 CHECK_TYPE_SIZE(pthread_t EVENT__SIZEOF_PTHREAD_T)
617endif()
618
619if(EVENT__HAVE_CLOCK_GETTIME)
620 set(EVENT__DNS_USE_CPU_CLOCK_FOR_ID 1)
621endif()
622
623# we're just getting lazy now.
624CHECK_TYPE_SIZE("uintptr_t" EVENT__HAVE_UINTPTR_T)
625CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P)
626CHECK_TYPE_SIZE("time_t" EVENT__SIZEOF_TIME_T)
627
628# Tests file offset bits.
629# TODO: Add AIX test for if -D_LARGE_FILES is needed.
630
631# XXX: Why is this here? we don't even use it. Well, we don't even use it
632# on top of that, why is it set in the config.h?! IT_MAKES_NO_SENSE
633# I'm commenting it out for now.
634# - ellzey
635
636#CHECK_FILE_OFFSET_BITS()
637
638# Verify kqueue works with pipes.
639if (EVENT__HAVE_KQUEUE)
Haibo Huang45729092019-08-01 16:15:45 -0700640 if ((CMAKE_CROSSCOMPILING OR APPLE) AND NOT EVENT__FORCE_KQUEUE_CHECK)
Haibo Huangb2279672019-05-31 16:12:39 -0700641 message(WARNING "Cannot check if kqueue works with pipes when crosscompiling, use EVENT__FORCE_KQUEUE_CHECK to be sure (this requires manually running a test program on the cross compilation target)")
642 set(EVENT__HAVE_WORKING_KQUEUE 1)
643 else()
644 message(STATUS "Checking if kqueue works with pipes...")
645 include(CheckWorkingKqueue)
646 endif()
647endif()
648
649if(EVENT__HAVE_NETDB_H)
650 list(APPEND CMAKE_EXTRA_INCLUDE_FILES netdb.h)
651 CHECK_TYPE_SIZE("struct addrinfo" EVENT__HAVE_STRUCT_ADDRINFO)
652elseif(WIN32)
653 list(APPEND CMAKE_EXTRA_INCLUDE_FILES ws2tcpip.h)
654 CHECK_TYPE_SIZE("struct addrinfo" EVENT__HAVE_STRUCT_ADDRINFO)
655endif()
656
657# Check for sockaddr structure sizes.
658set(SOCKADDR_HEADERS)
659if (WIN32)
660 set(CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN")
661 if (_MSC_VER LESS 1300)
662 set(SOCKADDR_HEADERS winsock.h)
663 else()
664 set(SOCKADDR_HEADERS winsock2.h ws2tcpip.h)
665 endif()
666else()
667 if (EVENT__HAVE_NETINET_IN_H)
668 set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} netinet/in.h)
669 endif()
670
671 if (EVENT__HAVE_NETINET_IN6_H)
672 set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} netinet/in6.h)
673 endif()
674
675 if (EVENT__HAVE_SYS_SOCKET_H)
676 set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} sys/socket.h)
677 endif()
678
679 if (EVENT__HAVE_NETDB_H)
680 set(SOCKADDR_HEADERS ${SOCKADDR_HEADERS} netdb.h)
681 endif()
682endif()
683
684CHECK_TYPE_SIZE("struct in6_addr" EVENT__HAVE_STRUCT_IN6_ADDR)
685if(EVENT__HAVE_STRUCT_IN6_ADDR)
686 CHECK_STRUCT_HAS_MEMBER("struct in6_addr"
687 s6_addr16 "${SOCKADDR_HEADERS}"
688 EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16)
689
690 CHECK_STRUCT_HAS_MEMBER("struct in6_addr"
691 s6_addr32 "${SOCKADDR_HEADERS}"
692 EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32)
693endif()
694
695CHECK_TYPE_SIZE("sa_family_t" EVENT__HAVE_SA_FAMILY_T)
696CHECK_TYPE_SIZE("struct sockaddr_in6" EVENT__HAVE_STRUCT_SOCKADDR_IN6)
697
698if(EVENT__HAVE_STRUCT_SOCKADDR_IN6)
699 CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6"
700 sin6_len "${SOCKADDR_HEADERS}"
701 EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN)
702
703 CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6"
704 sin_len "${SOCKADDR_HEADERS}"
705 EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN)
706endif()
707
708CHECK_TYPE_SIZE("struct sockaddr_storage" EVENT__HAVE_STRUCT_SOCKADDR_STORAGE)
709if(EVENT__HAVE_STRUCT_SOCKADDR_STORAGE)
710 CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage"
711 ss_family "${SOCKADDR_HEADERS}"
712 EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)
713
714 CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage"
715 __ss_family "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY)
716endif()
717
718CHECK_TYPE_SIZE("struct linger" EVENT__HAVE_STRUCT_LINGER)
719
720# Group the source files.
721set(HDR_PRIVATE
722 bufferevent-internal.h
723 changelist-internal.h
724 defer-internal.h
725 epolltable-internal.h
726 evbuffer-internal.h
727 event-internal.h
728 evmap-internal.h
729 evrpc-internal.h
730 evsignal-internal.h
731 evthread-internal.h
732 ht-internal.h
733 http-internal.h
734 iocp-internal.h
735 ipv6-internal.h
736 log-internal.h
737 minheap-internal.h
738 mm-internal.h
739 ratelim-internal.h
740 strlcpy-internal.h
741 util-internal.h
742 evconfig-private.h
743 compat/sys/queue.h)
744
745set(HDR_COMPAT
746 include/evdns.h
747 include/evrpc.h
748 include/event.h
749 include/evhttp.h
750 include/evutil.h)
751
752set(HDR_PUBLIC
753 include/event2/buffer.h
754 include/event2/bufferevent.h
755 include/event2/bufferevent_compat.h
756 include/event2/bufferevent_struct.h
757 include/event2/buffer_compat.h
758 include/event2/dns.h
759 include/event2/dns_compat.h
760 include/event2/dns_struct.h
761 include/event2/event.h
762 include/event2/event_compat.h
763 include/event2/event_struct.h
764 include/event2/http.h
765 include/event2/http_compat.h
766 include/event2/http_struct.h
767 include/event2/keyvalq_struct.h
768 include/event2/listener.h
769 include/event2/rpc.h
770 include/event2/rpc_compat.h
771 include/event2/rpc_struct.h
772 include/event2/tag.h
773 include/event2/tag_compat.h
774 include/event2/thread.h
775 include/event2/util.h
776 include/event2/visibility.h
777 ${PROJECT_BINARY_DIR}/include/event2/event-config.h)
778
779set(SRC_CORE
780 buffer.c
781 bufferevent.c
782 bufferevent_filter.c
783 bufferevent_pair.c
784 bufferevent_ratelim.c
785 bufferevent_sock.c
786 event.c
787 evmap.c
788 evthread.c
789 evutil.c
790 evutil_rand.c
791 evutil_time.c
792 listener.c
793 log.c
794 signal.c
795 strlcpy.c)
796
797if(EVENT__HAVE_SELECT)
798 list(APPEND SRC_CORE select.c)
799endif()
800
801if(EVENT__HAVE_POLL)
802 list(APPEND SRC_CORE poll.c)
803endif()
804
805if(EVENT__HAVE_KQUEUE)
806 list(APPEND SRC_CORE kqueue.c)
807endif()
808
809if(EVENT__HAVE_DEVPOLL)
810 list(APPEND SRC_CORE devpoll.c)
811endif()
812
813if(EVENT__HAVE_EPOLL)
814 list(APPEND SRC_CORE epoll.c)
815endif()
816
817if(EVENT__HAVE_EVENT_PORTS)
818 list(APPEND SRC_CORE evport.c)
819endif()
820
821if (NOT EVENT__DISABLE_OPENSSL)
822 find_package(OpenSSL REQUIRED)
823
824 set(EVENT__HAVE_OPENSSL 1)
825
826 message(STATUS "OpenSSL include: ${OPENSSL_INCLUDE_DIR}")
827 message(STATUS "OpenSSL lib: ${OPENSSL_LIBRARIES}")
828
829 include_directories(${OPENSSL_INCLUDE_DIR})
830
831 list(APPEND SRC_OPENSSL bufferevent_openssl.c)
832 list(APPEND HDR_PUBLIC include/event2/bufferevent_ssl.h)
833 list(APPEND LIB_APPS ${OPENSSL_LIBRARIES})
834endif()
835
836if (NOT EVENT__DISABLE_THREAD_SUPPORT)
837 if (WIN32)
838 list(APPEND SRC_CORE evthread_win32.c)
839 else()
840 find_package(Threads REQUIRED)
841 if (NOT CMAKE_USE_PTHREADS_INIT)
842 message(FATAL_ERROR
843 "Failed to find Pthreads, set EVENT__DISABLE_THREAD_SUPPORT to disable")
844 endif()
845
846 set(EVENT__HAVE_PTHREADS 1)
847 list(APPEND LIB_APPS ${CMAKE_THREAD_LIBS_INIT})
848 endif()
849endif()
850
851if (NOT EVENT__DISABLE_TESTS)
852 # Zlib is only used for testing.
853 find_package(ZLIB)
854
855 if (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
856 include_directories(${ZLIB_INCLUDE_DIRS})
857
858 set(EVENT__HAVE_LIBZ 1)
859 list(APPEND LIB_APPS ${ZLIB_LIBRARIES})
860 endif()
861endif()
862
863set(SRC_EXTRA
864 event_tagging.c
865 http.c
866 evdns.c
867 evrpc.c)
868
869add_definitions(-DHAVE_CONFIG_H)
870
871# We use BEFORE here so we don't accidentally look in system directories
872# first for some previous versions of the headers that are installed.
873include_directories(BEFORE ${PROJECT_SOURCE_DIR}
874 ${PROJECT_SOURCE_DIR}/compat
875 ${PROJECT_SOURCE_DIR}/include)
876
877if(WIN32)
878 list(APPEND SRC_CORE
879 buffer_iocp.c
880 bufferevent_async.c
881 event_iocp.c
882 win32select.c)
883
884 list(APPEND HDR_PRIVATE WIN32-Code/getopt.h)
885
886 set(EVENT__DNS_USE_FTIME_FOR_ID 1)
Haibo Huang45729092019-08-01 16:15:45 -0700887 set(LIB_PLATFORM ws2_32 shell32 advapi32)
Haibo Huangb2279672019-05-31 16:12:39 -0700888 add_definitions(
889 -D_CRT_SECURE_NO_WARNINGS
890 -D_CRT_NONSTDC_NO_DEPRECATE)
891
892 include_directories(./WIN32-Code)
893endif()
894
895if (SOLARIS)
896 list(APPEND LIB_PLATFORM socket nsl)
897endif()
898
899source_group("Headers Private" FILES ${HDR_PRIVATE})
900source_group("Header Compat" FILES ${HDR_COMPAT})
901source_group("Headers Public" FILES ${HDR_PUBLIC})
902source_group("Source Core" FILES ${SRC_CORE})
903source_group("Source Extra" FILES ${SRC_EXTRA})
904
905# Generate the configure headers.
906# (Place them in the build dir so we don't polute the source tree with generated files).
907include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include)
908
909if (${GNUC})
910 set(EVENT_SHARED_FLAGS -fvisibility=hidden)
911elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "SunPro")
912 set(EVENT_SHARED_FLAGS -xldscope=hidden)
913endif()
914
915configure_file(
916 ${CMAKE_CURRENT_SOURCE_DIR}/event-config.h.cmake
917 ${CMAKE_CURRENT_BINARY_DIR}/include/event2/event-config.h
918 NEWLINE_STYLE UNIX)
919
920configure_file(
921 ${CMAKE_CURRENT_SOURCE_DIR}/evconfig-private.h.cmake
922 ${CMAKE_CURRENT_BINARY_DIR}/include/evconfig-private.h)
923
924#
925# Create the libraries.
926#
927include(AddEventLibrary)
928add_event_library(event_core SOURCES ${SRC_CORE})
929add_event_library(event_extra
930 LIBRARIES event_core_shared
931 SOURCES ${SRC_EXTRA})
932
933if (NOT EVENT__DISABLE_OPENSSL)
934 add_event_library(event_openssl
935 LIBRARIES event_core_shared ${OPENSSL_LIBRARIES}
936 SOURCES ${SRC_OPENSSL})
937endif()
938
939if (CMAKE_USE_PTHREADS_INIT)
940 set(SRC_PTHREADS evthread_pthread.c)
941 add_event_library(event_pthreads
942 LIBRARIES event_core_shared
943 SOURCES ${SRC_PTHREADS})
944endif()
945
946# library exists for historical reasons; it contains the contents of
947# both libevent_core and libevent_extra. You shouldn’t use it; it may
948# go away in a future version of Libevent.
949add_event_library(event SOURCES ${SRC_CORE} ${SRC_EXTRA})
950
951set(WIN32_GETOPT)
952if (WIN32)
953 list(APPEND WIN32_GETOPT
954 WIN32-Code/getopt.c
955 WIN32-Code/getopt_long.c)
956endif()
957
958#
959# Samples.
960#
961macro(add_sample_prog ssl name)
962 add_executable(${name} ${ARGN})
963
964 target_link_libraries(${name}
965 event_extra
966 event_core
967 ${LIB_APPS}
968 ${LIB_PLATFORM})
969
970 if (${ssl})
971 target_link_libraries(${name} event_openssl)
972 endif()
973endmacro()
974if (NOT EVENT__DISABLE_SAMPLES)
975 set(SAMPLES
976 event-read-fifo
977 hello-world
978 signal-test
979 http-connect
980 time-test)
981
982 foreach(SAMPLE ${SAMPLES})
983 add_sample_prog(OFF ${SAMPLE} sample/${SAMPLE}.c)
984 endforeach()
985
986 if (NOT EVENT__DISABLE_OPENSSL)
987 add_sample_prog(ON https-client
988 sample/https-client.c
989 sample/openssl_hostname_validation.c
990 sample/hostcheck.c)
991 add_sample_prog(ON le-proxy
992 sample/le-proxy.c)
993 endif()
994
995 set(SAMPLES_WOPT
996 dns-example
997 http-server
998 )
999 foreach (SAMPLE ${SAMPLES_WOPT})
1000 add_sample_prog(OFF ${SAMPLE} sample/${SAMPLE}.c ${WIN32_GETOPT})
1001 endforeach()
1002endif()
1003
1004#
1005# Benchmarks
1006#
1007macro(add_bench_prog prog)
1008 add_executable(${prog} ${ARGN})
1009 target_link_libraries(${prog}
1010 event_extra
1011 event_core
1012 ${LIB_APPS}
1013 ${LIB_PLATFORM})
1014endmacro()
1015if (NOT EVENT__DISABLE_BENCHMARK)
1016 foreach (BENCHMARK bench_http bench_httpclient)
1017 add_bench_prog(${BENCHMARK} test/${BENCHMARK}.c)
1018 endforeach()
1019
1020 add_bench_prog(bench test/bench.c ${WIN32_GETOPT})
1021 add_bench_prog(bench_cascade test/bench_cascade.c ${WIN32_GETOPT})
1022endif()
1023
1024#
1025# Tests
1026#
1027macro(add_test_prog prog)
1028 add_executable(${prog} test/${prog}.c)
1029 target_link_libraries(${prog}
1030 ${LIB_APPS}
1031 ${LIB_PLATFORM}
1032 event_core
1033 event_extra
1034 ${ARGN})
1035endmacro()
1036if (NOT EVENT__DISABLE_TESTS)
1037 #
1038 # Generate Regress tests.
1039 #
1040 if (NOT EVENT__DISABLE_REGRESS)
1041 # (We require python to generate the regress tests)
1042 find_package(PythonInterp 3)
1043
1044 if (PYTHONINTERP_FOUND)
1045 set(__FOUND_USABLE_PYTHON 1)
1046 else()
1047 find_package(PythonInterp 2)
1048 if (PYTHONINTERP_FOUND)
1049 set(__FOUND_USABLE_PYTHON 1)
1050 else()
1051 message(ERROR "No suitable Python version found, bailing...")
1052 endif()
1053 endif()
1054
1055 if (__FOUND_USABLE_PYTHON)
1056 message(STATUS "Generating regress tests...")
1057
1058 add_definitions(-DTINYTEST_LOCAL)
1059
1060 add_custom_command(
1061 OUTPUT
1062 ${CMAKE_CURRENT_SOURCE_DIR}/test/regress.gen.c
1063 ${CMAKE_CURRENT_SOURCE_DIR}/test/regress.gen.h
1064 DEPENDS
1065 event_rpcgen.py
1066 test/regress.rpc
1067 COMMAND ${PYTHON_EXECUTABLE} ../event_rpcgen.py regress.rpc
1068 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test)
1069
1070 list(APPEND SRC_REGRESS
1071 test/regress.c
1072 test/regress.gen.c
1073 test/regress.gen.h
1074 test/regress_buffer.c
1075 test/regress_bufferevent.c
1076 test/regress_dns.c
1077 test/regress_et.c
1078 test/regress_finalize.c
1079 test/regress_http.c
1080 test/regress_listener.c
1081 test/regress_main.c
1082 test/regress_minheap.c
1083 test/regress_rpc.c
1084 test/regress_testutils.c
1085 test/regress_testutils.h
1086 test/regress_util.c
1087 test/tinytest.c)
1088
1089 if (WIN32)
1090 list(APPEND SRC_REGRESS test/regress_iocp.c)
1091 if (NOT EVENT__DISABLE_THREAD_SUPPORT)
1092 list(APPEND SRC_REGRESS test/regress_thread.c)
1093 endif()
1094 elseif (CMAKE_USE_PTHREADS_INIT)
1095 list(APPEND SRC_REGRESS test/regress_thread.c)
1096 endif()
1097
1098 if (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
1099 list(APPEND SRC_REGRESS test/regress_zlib.c)
1100 endif()
1101
1102 if (NOT EVENT__DISABLE_OPENSSL)
1103 list(APPEND SRC_REGRESS test/regress_ssl.c)
1104 endif()
1105
1106 add_executable(regress ${SRC_REGRESS})
1107
1108 target_link_libraries(regress
1109 ${LIB_APPS}
1110 ${LIB_PLATFORM}
1111 event_core
1112 event_extra)
1113 if (NOT EVENT__DISABLE_OPENSSL)
1114 target_link_libraries(regress event_openssl)
1115 endif()
1116 if (CMAKE_USE_PTHREADS_INIT)
1117 target_link_libraries(regress event_pthreads)
1118 endif()
1119 else()
1120 message(WARNING "No suitable Python interpreter found, cannot generate regress tests!")
1121 endif()
1122 endif()
1123
1124 #
1125 # Test programs.
1126 #
1127 # all of these, including the cmakelists.txt should be moved
1128 # into the dirctory 'tests' first.
1129 #
1130 # doing this, we can remove all the DISABLE_TESTS stuff, and simply
1131 # do something like:
1132 #
1133 # add_custom_targets(tests)
1134 # add_executable(... EXCLUDE_FROM_ALL ...c)
1135 # add_dependencis(tests testa testb testc)
1136 # add_test(....)
1137 #
1138 # then you can just run 'make tests' instead of them all
1139 # auto-compile|running
1140 # - ellzey
1141 set(TESTPROGS test-changelist
1142 test-eof
1143 test-fdleak
1144 test-init
1145 test-time
1146 test-weof)
1147
1148 foreach (TESTPROG ${TESTPROGS} test-dumpevents)
1149 add_test_prog(${TESTPROG})
1150 endforeach()
1151 if (UNIX)
1152 add_test_prog(test-ratelim m)
1153 else()
1154 add_test_prog(test-ratelim)
1155 endif()
1156
1157 set(ALL_TESTPROGS
1158 ${TESTPROGS}
1159 test-dumpevents
1160 test-ratelim
1161 )
1162
1163 #
1164 # We run all tests with the different backends turned on one at a time.
1165 #
1166
1167 # Add event backends based on system introspection result.
1168 set(BACKENDS "")
1169
1170 if (EVENT__HAVE_EPOLL)
1171 list(APPEND BACKENDS EPOLL)
1172 endif()
1173
1174 if (EVENT__HAVE_SELECT)
1175 list(APPEND BACKENDS SELECT)
1176 endif()
1177
1178 if (EVENT__HAVE_POLL)
1179 list(APPEND BACKENDS POLL)
1180 endif()
1181
1182 if (EVENT__HAVE_KQUEUE)
1183 list(APPEND BACKENDS KQUEUE)
1184 endif()
1185
1186 if (EVENT__HAVE_EVENT_PORTS)
1187 list(APPEND BACKENDS EVPORT)
1188 endif()
1189
1190 if (EVENT__HAVE_DEVPOLL)
1191 list(APPEND BACKENDS DEVPOLL)
1192 endif()
1193
1194 if (WIN32)
1195 list(APPEND BACKENDS WIN32)
1196 endif()
1197
1198
1199 # Default environment variables turns off all event systems,
1200 # then we enable each one, one at a time when creating the tests.
1201 set(DEFAULT_TEST_ENV_VARS "EVENT_SHOW_METHOD=1;")
1202 foreach(BACKEND ${BACKENDS})
1203 set(BACKEND_ENV_VAR "EVENT_NO${BACKEND}=1")
1204 list(APPEND DEFAULT_TEST_ENV_VARS "${BACKEND_ENV_VAR}")
1205 endforeach()
1206
1207 # Macro that creates the ctest test for a backend.
1208 macro(add_backend_test BACKEND_TEST_NAME ENV_VARS)
1209 set(TEST_NAMES "")
1210
1211 foreach (TESTPROG ${TESTPROGS})
1212 set(TEST_NAME ${TESTPROG}__${BACKEND_TEST_NAME})
1213
1214 add_test(${TEST_NAME}
1215 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTPROG})
1216
1217 list(APPEND TEST_NAMES ${TEST_NAME})
1218
1219 set_tests_properties(${TEST_NAME}
1220 PROPERTIES ENVIRONMENT "${ENV_VARS}")
1221 endforeach()
1222
1223 # Dump events test.
1224 if (__FOUND_USABLE_PYTHON)
1225 set(TEST_NAME test-dumpevents__${BACKEND_TEST_NAME})
1226
1227 add_test(${TEST_NAME}
1228 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents |
1229 ${PYTHON_EXECUTABLE}
1230 ${CMAKE_CURRENT_SOURCE_DIR}/test/check-dumpevents.py)
1231
1232 set_tests_properties(${TEST_NAME}
1233 PROPERTIES ENVIRONMENT "${ENV_VARS}")
1234 else()
1235 message(WARNING "test-dumpevents will be run without output check since python was not found!")
1236 set(TEST_NAME test-dumpevents__${BACKEND_TEST_NAME}_no_check)
1237
1238 add_test(${TEST_NAME}
1239 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents)
1240
1241 set_tests_properties(${TEST_NAME}
1242 PROPERTIES ENVIRONMENT "${ENV_VARS}")
1243 endif()
1244
1245 # Regress tests.
1246 if (NOT EVENT__DISABLE_REGRESS AND __FOUND_USABLE_PYTHON)
1247 set(TEST_NAME regress__${BACKEND_TEST_NAME})
1248
1249 add_test(${TEST_NAME}
1250 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress)
1251
1252 set_tests_properties(${TEST_NAME}
1253 PROPERTIES ENVIRONMENT "${ENV_VARS}")
1254
1255 add_test(${TEST_NAME}_debug
1256 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress)
1257
1258 set_tests_properties(${TEST_NAME}_debug
1259 PROPERTIES ENVIRONMENT "${ENV_VARS};EVENT_DEBUG_MODE=1")
1260 endif()
1261 endmacro()
1262
1263 # Add the tests for each backend.
1264 foreach(BACKEND ${BACKENDS})
1265 # Enable this backend only.
1266 set(BACKEND_ENV_VARS ${DEFAULT_TEST_ENV_VARS})
1267 list(REMOVE_ITEM BACKEND_ENV_VARS EVENT_NO${BACKEND}=1)
1268
1269 # Epoll has some extra settings.
1270 if (${BACKEND} STREQUAL "EPOLL")
1271 add_backend_test(timerfd_${BACKEND}
1272 "${BACKEND_ENV_VARS};EVENT_PRECISE_TIMER=1")
1273
1274 add_backend_test(changelist_${BACKEND}
1275 "${BACKEND_ENV_VARS};EVENT_EPOLL_USE_CHANGELIST=yes")
1276
1277 add_backend_test(timerfd_changelist_${BACKEND}
1278 "${BACKEND_ENV_VARS};EVENT_EPOLL_USE_CHANGELIST=yes;EVENT_PRECISE_TIMER=1")
1279 else()
1280 add_backend_test(${BACKEND} "${BACKEND_ENV_VARS}")
1281 endif()
1282 endforeach()
1283
1284 #
1285 # Rate limiter tests.
1286 #
1287
1288 # Group limits, no connection limit.
1289 set(RL_BIN ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim)
1290
1291 add_test(test-ratelim__group_lim
1292 ${RL_BIN}
1293 -g 30000
1294 -n 30
1295 -t 100
1296 --check-grouplimit 1000
1297 --check-stddev 100)
1298
1299 # Connection limit, no group limit.
1300 add_test(test-ratelim__con_lim
1301 ${RL_BIN}
1302 -c 1000
1303 -n 30
1304 -t 100
1305 --check-connlimit 50
1306 --check-stddev 50)
1307
1308 # Connection limit and group limit.
1309 add_test(test-ratelim__group_con_lim
1310 ${RL_BIN}
1311 -c 1000
1312 -g 30000
1313 -n 30
1314 -t 100
1315 --check-grouplimit 1000
1316 --check-connlimit 50
1317 --check-stddev 50)
1318
1319 # Connection limit and group limit with independent drain.
1320 add_test(test-ratelim__group_con_lim_drain
1321 ${RL_BIN}
1322 -c 1000
1323 -g 35000
1324 -n 30
1325 -t 100
1326 -G 500
1327 --check-grouplimit 1000
1328 --check-connlimit 50
1329 --check-stddev 50)
1330
1331 # Add a "make verify" target, same as for autoconf.
1332 # (Important! This will unset all EVENT_NO* environment variables.
1333 # If they are set in the shell the tests are running using simply "ctest" or "make test" will fail)
1334 if (WIN32)
1335 # Windows doesn't have "unset". But you can use "set VAR=" instead.
1336 # We need to guard against the possibility taht EVENT_NOWIN32 is set, and all test failing
1337 # since no event backend being available.
1338 file(TO_NATIVE_PATH ${CMAKE_CTEST_COMMAND} WINDOWS_CTEST_COMMAND)
1339
1340 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/verify_tests.bat
1341 "
1342 set EVENT_NOWIN32=
1343 \"${WINDOWS_CTEST_COMMAND}\"
1344 ")
1345
1346 message(STATUS "${WINDOWS_CTEST_COMMAND}")
1347
1348 file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/verify_tests.bat
1349 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
1350 FILE_PERMISSIONS
1351 OWNER_READ
1352 OWNER_WRITE
1353 OWNER_EXECUTE
1354 GROUP_READ
1355 GROUP_EXECUTE
1356 WORLD_READ WORLD_EXECUTE)
1357
1358 file(TO_NATIVE_PATH
1359 "${CMAKE_CURRENT_BINARY_DIR}/verify_tests.bat" VERIFY_PATH)
1360
1361 add_custom_target(verify COMMAND "${VERIFY_PATH}"
1362 DEPENDS event ${ALL_TESTPROGS})
1363 else()
1364 # On some platforms doing exec(unset) as CMake does won't work, so make sure
1365 # we run the unset command in a shell instead.
1366 # First we write the script contents.
1367 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/verify_tests.sh
1368 "
1369 #!/bin/bash
1370 unset EVENT_NOEPOLL; unset EVENT_NOPOLL; unset EVENT_NOSELECT; unset EVENT_NOWIN32; unset EVENT_NOEVPORT; unset EVENT_NOKQUEUE; unset EVENT_NODEVPOLL
1371 ${CMAKE_CTEST_COMMAND}
1372 ")
1373
1374 # Then we copy the file (this allows us to set execute permission on it)
1375 file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/verify_tests.sh
1376 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
1377 FILE_PERMISSIONS
1378 OWNER_READ
1379 OWNER_WRITE
1380 OWNER_EXECUTE
1381 GROUP_READ
1382 GROUP_EXECUTE
1383 WORLD_READ
1384 WORLD_EXECUTE)
1385
1386 # Create the target that runs the script.
1387 add_custom_target(verify
1388 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/verify_tests.sh
1389 DEPENDS event ${ALL_TESTPROGS})
1390 endif()
1391
1392 if (NOT EVENT__DISABLE_REGRESS AND __FOUND_USABLE_PYTHON)
1393 add_dependencies(verify regress)
1394 endif()
1395
1396 if (EVENT__COVERAGE)
1397 include(CodeCoverage)
1398
1399 setup_target_for_coverage(
1400 verify_coverage # Coverage target name "make verify_coverage"
1401 make # Test runner.
1402 coverage # Output directory.
1403 verify) # Arguments passed to test runner. "make verify"
1404 endif()
1405
1406 enable_testing()
1407
1408 include(CTest)
1409endif()
1410
1411#
1412# Installation preparation.
1413#
1414
1415if(WIN32 AND NOT CYGWIN)
1416 set(DEF_INSTALL_CMAKE_DIR cmake)
1417else()
1418 set(DEF_INSTALL_CMAKE_DIR lib/cmake/libevent)
1419endif()
1420
1421set(EVENT_INSTALL_CMAKE_DIR
1422 "${CMAKE_INSTALL_PREFIX}/${DEF_INSTALL_CMAKE_DIR}"
1423 CACHE PATH "Installation directory for CMake files")
1424
1425export(PACKAGE libevent)
1426
1427# Generate the config file for the build-tree.
1428set(EVENT__INCLUDE_DIRS
1429 "${PROJECT_SOURCE_DIR}/include"
1430 "${PROJECT_BINARY_DIR}/include")
1431
1432set(LIBEVENT_INCLUDE_DIRS
1433 ${EVENT__INCLUDE_DIRS}
1434 CACHE PATH "Libevent include directories")
1435
1436configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfigBuildTree.cmake.in
1437 ${PROJECT_BINARY_DIR}/LibeventConfig.cmake
1438 @ONLY)
1439
1440# Generate the config file for the installation tree.
1441# Calculate the relative directory from the Cmake dir.
1442file(RELATIVE_PATH
1443 REL_INCLUDE_DIR
1444 "${EVENT_INSTALL_CMAKE_DIR}"
1445 "${CMAKE_INSTALL_PREFIX}/include")
1446
1447# Note the LIBEVENT_CMAKE_DIR is defined in LibeventConfig.cmake.in,
1448# we escape it here so it's evaluated when it is included instead
1449# so that the include dirs are given relative to where the
1450# config file is located.
1451set(EVENT_INSTALL_INCLUDE_DIR "\${LIBEVENT_CMAKE_DIR}/${REL_INCLUDE_DIR}")
1452
1453configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfig.cmake.in
1454 ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake
1455 @ONLY)
1456
1457# Generate version info for both build-tree and install-tree.
1458configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfigVersion.cmake.in
1459 ${PROJECT_BINARY_DIR}/LibeventConfigVersion.cmake
1460 @ONLY)
1461
1462# Install compat headers
1463install(FILES ${HDR_COMPAT}
1464 DESTINATION "include"
1465 COMPONENT dev)
1466
1467# Install the configs.
1468install(FILES
1469 ${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake
1470 ${PROJECT_BINARY_DIR}/LibeventConfigVersion.cmake
1471 DESTINATION "${EVENT_INSTALL_CMAKE_DIR}"
1472 COMPONENT dev)
1473
1474# Install exports for the install-tree.
1475install(EXPORT LibeventTargets
1476 DESTINATION "${DEF_INSTALL_CMAKE_DIR}"
1477 COMPONENT dev)
1478
Haibo Huang45729092019-08-01 16:15:45 -07001479# Install the scripts.
1480install(PROGRAMS
1481 ${CMAKE_CURRENT_SOURCE_DIR}/event_rpcgen.py
1482 DESTINATION "bin"
1483 COMPONENT runtime)
1484
1485# Create documents with doxygen.
1486find_program(DOXYGEN doxygen)
1487if (DOXYGEN)
1488 add_custom_target(doxygen
1489 COMMAND ${DOXYGEN} Doxyfile
1490 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
1491else()
1492 message(WARNING "The doxygen target will not support since doxygen command was not found!")
1493endif()
1494
1495
1496# Create the uninstall target.
1497# https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake
1498configure_file(${PROJECT_SOURCE_DIR}/cmake/Uninstall.cmake.in
1499 ${PROJECT_BINARY_DIR}/Uninstall.cmake
1500 @ONLY)
1501
1502add_custom_target(uninstall
1503 COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/Uninstall.cmake)
1504
1505
Haibo Huangb2279672019-05-31 16:12:39 -07001506message(STATUS "")
1507message(STATUS " ---( Libevent " ${EVENT_VERSION} " )---")
1508message(STATUS "")
1509message(STATUS "Available event backends: ${BACKENDS}")
1510message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
1511message(STATUS "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}")
1512message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
1513message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
1514message(STATUS "PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
1515message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
1516message(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
1517message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
1518message(STATUS "CMAKE_ROOT: ${CMAKE_ROOT}")
1519message(STATUS "CMAKE_SYSTEM: ${CMAKE_SYSTEM}")
1520message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
1521message(STATUS "CMAKE_SYSTEM_VERSION: ${CMAKE_SYSTEM_VERSION}")
1522message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
1523message(STATUS "CMAKE_SKIP_RPATH: ${CMAKE_SKIP_RPATH}")
1524message(STATUS "CMAKE_VERBOSE_MAKEFILE: ${CMAKE_VERBOSE_MAKEFILE}")
1525message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
1526message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
1527message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER} (id ${CMAKE_C_COMPILER_ID}, clang ${CLANG}, GNUC ${GNUC})")
1528message(STATUS "CMAKE_AR: ${CMAKE_AR}")
1529message(STATUS "CMAKE_RANLIB: ${CMAKE_RANLIB}")
1530message(STATUS "")
1531