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