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