1# Copyright (c) 2009, 2021, Oracle and/or its affiliates.
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License, version 2.0,
5# as published by the Free Software Foundation.
6#
7# This program is also distributed with certain software (including
8# but not limited to OpenSSL) that is licensed under separate terms,
9# as designated in a particular file or component or in included license
10# documentation.  The authors of MySQL hereby grant you an additional
11# permission to link the program and your derivative works with the
12# separately licensed software that they have included with MySQL.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License, version 2.0, for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22#
23
24INCLUDE (CheckCSourceCompiles)
25INCLUDE (CheckCXXSourceCompiles)
26INCLUDE (CheckStructHasMember)
27INCLUDE (CheckLibraryExists)
28INCLUDE (CheckFunctionExists)
29INCLUDE (CheckCCompilerFlag)
30INCLUDE (CheckCSourceRuns)
31INCLUDE (CheckCXXSourceRuns)
32INCLUDE (CheckSymbolExists)
33
34
35# WITH_PIC options.Not of much use, PIC is taken care of on platforms
36# where it makes sense anyway.
37IF(UNIX)
38  IF(APPLE)
39    # OSX  executable are always PIC
40    SET(WITH_PIC ON)
41  ELSE()
42    OPTION(WITH_PIC "Generate PIC objects" OFF)
43    IF(WITH_PIC)
44      SET(CMAKE_C_FLAGS
45        "${CMAKE_C_FLAGS} ${CMAKE_SHARED_LIBRARY_C_FLAGS}")
46      SET(CMAKE_CXX_FLAGS
47        "${CMAKE_CXX_FLAGS} ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}")
48    ENDIF()
49  ENDIF()
50ENDIF()
51
52
53IF(CMAKE_SYSTEM_NAME MATCHES "DragonFly")
54  SET(CMAKE_SHARED_LIBRARY_C_FLAGS
55    "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS} -L/usr/local/lib")
56ENDIF()
57
58
59IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCXX)
60  ## We will be using gcc to generate .so files
61  ## Add C flags (e.g. -m64) to CMAKE_SHARED_LIBRARY_C_FLAGS
62  ## The client library contains C++ code, so add dependency on libstdc++
63  ## See cmake --help-policy CMP0018
64  SET(CMAKE_SHARED_LIBRARY_C_FLAGS
65    "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS} -lstdc++")
66ENDIF()
67
68
69# System type affects version_compile_os variable
70IF(NOT SYSTEM_TYPE)
71  IF(PLATFORM)
72    SET(SYSTEM_TYPE ${PLATFORM})
73  ELSE()
74    SET(SYSTEM_TYPE ${CMAKE_SYSTEM_NAME})
75  ENDIF()
76ENDIF()
77
78# Probobuf 2.6.1 on Sparc. Both gcc and Solaris Studio need this.
79IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND
80    SIZEOF_VOIDP EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "sparc")
81  ADD_DEFINITIONS(-DSOLARIS_64BIT_ENABLED)
82ENDIF()
83
84# Check to see if we are using LLVM's libc++ rather than e.g. libstd++
85# Can then check HAVE_LLBM_LIBCPP later without including e.g. ciso646.
86CHECK_CXX_SOURCE_RUNS("
87#include <ciso646>
88int main()
89{
90#ifdef _LIBCPP_VERSION
91  return 0;
92#else
93  return 1;
94#endif
95}" HAVE_LLVM_LIBCPP)
96
97
98IF(CMAKE_COMPILER_IS_GNUCXX)
99  IF (CMAKE_EXE_LINKER_FLAGS MATCHES " -static "
100     OR CMAKE_EXE_LINKER_FLAGS MATCHES " -static$")
101     SET(HAVE_DLOPEN FALSE CACHE "Disable dlopen due to -static flag" FORCE)
102     SET(WITHOUT_DYNAMIC_PLUGINS TRUE)
103  ENDIF()
104ENDIF()
105
106IF(WITHOUT_DYNAMIC_PLUGINS)
107  MESSAGE("Dynamic plugins are disabled.")
108ENDIF(WITHOUT_DYNAMIC_PLUGINS)
109
110# Large files, common flag
111SET(_LARGEFILE_SOURCE  1)
112
113# Same for structs, setting HAVE_STRUCT_<name> instead
114FUNCTION(MY_CHECK_STRUCT_SIZE type defbase)
115  CHECK_TYPE_SIZE("struct ${type}" SIZEOF_${defbase})
116  IF(SIZEOF_${defbase})
117    SET(HAVE_STRUCT_${defbase} 1 PARENT_SCOPE)
118  ENDIF()
119ENDFUNCTION()
120
121# Searches function in libraries
122# if function is found, sets output parameter result to the name of the library
123# if function is found in libc, result will be empty
124FUNCTION(MY_SEARCH_LIBS func libs result)
125  IF(${${result}})
126    # Library is already found or was predefined
127    RETURN()
128  ENDIF()
129  CHECK_FUNCTION_EXISTS(${func} HAVE_${func}_IN_LIBC)
130  IF(HAVE_${func}_IN_LIBC)
131    SET(${result} "" PARENT_SCOPE)
132    RETURN()
133  ENDIF()
134  FOREACH(lib  ${libs})
135    CHECK_LIBRARY_EXISTS(${lib} ${func} "" HAVE_${func}_IN_${lib})
136    IF(HAVE_${func}_IN_${lib})
137      SET(${result} ${lib} PARENT_SCOPE)
138      SET(HAVE_${result} 1 PARENT_SCOPE)
139      RETURN()
140    ENDIF()
141  ENDFOREACH()
142ENDFUNCTION()
143
144# Find out which libraries to use.
145
146# Figure out threading library
147# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
148FIND_PACKAGE (Threads)
149
150IF(UNIX)
151  IF(NOT LIBM)
152    MY_SEARCH_LIBS(floor m LIBM)
153  ENDIF()
154  IF(NOT LIBM)
155    MY_SEARCH_LIBS(__infinity m LIBM)
156  ENDIF()
157  MY_SEARCH_LIBS(gethostbyname_r  "nsl_r;nsl" LIBNSL)
158  MY_SEARCH_LIBS(bind "bind;socket" LIBBIND)
159  # Feature test broken with -fsanitize=address, look for lib first.
160  IF(CMAKE_C_FLAGS MATCHES "-fsanitize=")
161    CHECK_LIBRARY_EXISTS(crypt crypt "" HAVE_crypt_IN_crypt)
162    # If found, do not look in libc.
163    IF(HAVE_crypt_IN_crypt)
164      SET(LIBCRYPT crypt)
165      SET(${LIBCRYPT} 1)
166    ENDIF()
167  ENDIF()
168  MY_SEARCH_LIBS(crypt crypt LIBCRYPT)
169  MY_SEARCH_LIBS(setsockopt socket LIBSOCKET)
170  MY_SEARCH_LIBS(dlopen dl LIBDL)
171  # HAVE_dlopen_IN_LIBC
172  IF(NOT LIBDL)
173    MY_SEARCH_LIBS(dlsym dl LIBDL)
174  ENDIF()
175  MY_SEARCH_LIBS(sched_yield rt LIBRT)
176  IF(NOT LIBRT)
177    MY_SEARCH_LIBS(clock_gettime rt LIBRT)
178  ENDIF()
179  MY_SEARCH_LIBS(timer_create rt LIBRT)
180  MY_SEARCH_LIBS(atomic_thread_fence atomic LIBATOMIC)
181  MY_SEARCH_LIBS(backtrace execinfo LIBEXECINFO)
182
183  SET(CMAKE_REQUIRED_LIBRARIES
184    ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL}
185    ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBATOMIC} ${LIBEXECINFO}
186  )
187  # Need explicit pthread for gcc -fsanitize=address
188  IF(CMAKE_C_FLAGS MATCHES "-fsanitize=")
189    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} pthread)
190  ENDIF()
191
192  LIST(LENGTH CMAKE_REQUIRED_LIBRARIES required_libs_length)
193  IF(${required_libs_length} GREATER 0)
194    LIST(REMOVE_DUPLICATES CMAKE_REQUIRED_LIBRARIES)
195  ENDIF()
196  LINK_LIBRARIES(${CMAKE_THREAD_LIBS_INIT})
197
198  OPTION(WITH_LIBWRAP "Compile with tcp wrappers support" OFF)
199  IF(WITH_LIBWRAP)
200    SET(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
201    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} wrap)
202    CHECK_C_SOURCE_COMPILES(
203    "
204    #include <tcpd.h>
205    int allow_severity = 0;
206    int deny_severity  = 0;
207    int main()
208    {
209      hosts_access(0);
210    }"
211    HAVE_LIBWRAP)
212
213    IF(HAVE_LIBWRAP)
214      CHECK_CXX_SOURCE_COMPILES(
215      "
216      #include <tcpd.h>
217      int main()
218      {
219        struct request_info req;
220        if (req.sink)
221          (req.sink)(req.fd);
222      }"
223      HAVE_LIBWRAP_PROTOTYPES)
224    ENDIF()
225
226    SET(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
227    IF(HAVE_LIBWRAP)
228      SET(LIBWRAP "wrap")
229    ELSE()
230      MESSAGE(FATAL_ERROR
231      "WITH_LIBWRAP is defined, but can not find a working libwrap. "
232      "Make sure both the header files (tcpd.h) "
233      "and the library (libwrap) are installed.")
234    ENDIF()
235  ENDIF()
236ENDIF()
237
238#
239# Tests for header files
240#
241INCLUDE (CheckIncludeFiles)
242
243CHECK_INCLUDE_FILES (alloca.h HAVE_ALLOCA_H)
244CHECK_INCLUDE_FILES (arpa/inet.h HAVE_ARPA_INET_H)
245CHECK_INCLUDE_FILES (crypt.h HAVE_CRYPT_H)
246CHECK_INCLUDE_FILES (dlfcn.h HAVE_DLFCN_H)
247CHECK_INCLUDE_FILES (execinfo.h HAVE_EXECINFO_H)
248CHECK_INCLUDE_FILES (fpu_control.h HAVE_FPU_CONTROL_H)
249CHECK_INCLUDE_FILES (grp.h HAVE_GRP_H)
250CHECK_INCLUDE_FILES (ieeefp.h HAVE_IEEEFP_H)
251CHECK_INCLUDE_FILES (langinfo.h HAVE_LANGINFO_H)
252CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)
253CHECK_INCLUDE_FILES (netinet/in.h HAVE_NETINET_IN_H)
254CHECK_INCLUDE_FILES (poll.h HAVE_POLL_H)
255CHECK_INCLUDE_FILES (pwd.h HAVE_PWD_H)
256CHECK_INCLUDE_FILES (strings.h HAVE_STRINGS_H) # Used by NDB
257CHECK_INCLUDE_FILES (sys/ioctl.h HAVE_SYS_IOCTL_H)
258CHECK_INCLUDE_FILES (sys/mman.h HAVE_SYS_MMAN_H)
259CHECK_INCLUDE_FILES (sys/resource.h HAVE_SYS_RESOURCE_H)
260CHECK_INCLUDE_FILES (sys/select.h HAVE_SYS_SELECT_H)
261CHECK_INCLUDE_FILES (sys/socket.h HAVE_SYS_SOCKET_H)
262CHECK_INCLUDE_FILES ("curses.h;term.h" HAVE_TERM_H)
263CHECK_INCLUDE_FILES (termios.h HAVE_TERMIOS_H)
264CHECK_INCLUDE_FILES (termio.h HAVE_TERMIO_H)
265CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_H)
266CHECK_INCLUDE_FILES (sys/wait.h HAVE_SYS_WAIT_H)
267CHECK_INCLUDE_FILES (sys/param.h HAVE_SYS_PARAM_H) # Used by NDB/libevent
268CHECK_INCLUDE_FILES (fnmatch.h HAVE_FNMATCH_H)
269CHECK_INCLUDE_FILES (sys/un.h HAVE_SYS_UN_H)
270
271# For libevent
272CHECK_INCLUDE_FILES(sys/devpoll.h HAVE_DEVPOLL)
273IF(HAVE_DEVPOLL)
274  # Duplicate symbols, but keep it to avoid changing libevent code.
275  SET(HAVE_SYS_DEVPOLL_H 1)
276ENDIF()
277CHECK_INCLUDE_FILES(sys/epoll.h HAVE_SYS_EPOLL_H)
278CHECK_SYMBOL_EXISTS (TAILQ_FOREACH "sys/queue.h" HAVE_TAILQFOREACH)
279
280#
281# Tests for functions
282#
283CHECK_FUNCTION_EXISTS (_aligned_malloc HAVE_ALIGNED_MALLOC)
284CHECK_FUNCTION_EXISTS (backtrace HAVE_BACKTRACE)
285CHECK_FUNCTION_EXISTS (printstack HAVE_PRINTSTACK)
286CHECK_FUNCTION_EXISTS (index HAVE_INDEX)
287CHECK_FUNCTION_EXISTS (clock_gettime HAVE_CLOCK_GETTIME)
288CHECK_FUNCTION_EXISTS (cuserid HAVE_CUSERID)
289CHECK_FUNCTION_EXISTS (directio HAVE_DIRECTIO)
290CHECK_FUNCTION_EXISTS (ftruncate HAVE_FTRUNCATE)
291CHECK_FUNCTION_EXISTS (compress HAVE_COMPRESS)
292CHECK_FUNCTION_EXISTS (crypt HAVE_CRYPT)
293CHECK_FUNCTION_EXISTS (dlopen HAVE_DLOPEN)
294CHECK_FUNCTION_EXISTS (fchmod HAVE_FCHMOD)
295CHECK_FUNCTION_EXISTS (fcntl HAVE_FCNTL)
296CHECK_FUNCTION_EXISTS (fdatasync HAVE_FDATASYNC)
297CHECK_SYMBOL_EXISTS(fdatasync "unistd.h" HAVE_DECL_FDATASYNC)
298CHECK_FUNCTION_EXISTS (fedisableexcept HAVE_FEDISABLEEXCEPT)
299CHECK_FUNCTION_EXISTS (fseeko HAVE_FSEEKO)
300CHECK_FUNCTION_EXISTS (fsync HAVE_FSYNC)
301CHECK_FUNCTION_EXISTS (gethostbyaddr_r HAVE_GETHOSTBYADDR_R)
302CHECK_FUNCTION_EXISTS (gethrtime HAVE_GETHRTIME)
303CHECK_FUNCTION_EXISTS (getnameinfo HAVE_GETNAMEINFO)
304CHECK_FUNCTION_EXISTS (getpass HAVE_GETPASS)
305CHECK_FUNCTION_EXISTS (getpassphrase HAVE_GETPASSPHRASE)
306CHECK_FUNCTION_EXISTS (getpwnam HAVE_GETPWNAM)
307CHECK_FUNCTION_EXISTS (getpwuid HAVE_GETPWUID)
308CHECK_FUNCTION_EXISTS (getrlimit HAVE_GETRLIMIT)
309CHECK_FUNCTION_EXISTS (getrusage HAVE_GETRUSAGE)
310CHECK_FUNCTION_EXISTS (initgroups HAVE_INITGROUPS)
311CHECK_FUNCTION_EXISTS (issetugid HAVE_ISSETUGID)
312CHECK_FUNCTION_EXISTS (getuid HAVE_GETUID)
313CHECK_FUNCTION_EXISTS (geteuid HAVE_GETEUID)
314CHECK_FUNCTION_EXISTS (getgid HAVE_GETGID)
315CHECK_FUNCTION_EXISTS (getegid HAVE_GETEGID)
316CHECK_FUNCTION_EXISTS (lstat HAVE_LSTAT)
317CHECK_FUNCTION_EXISTS (madvise HAVE_MADVISE)
318CHECK_FUNCTION_EXISTS (malloc_info HAVE_MALLOC_INFO)
319CHECK_FUNCTION_EXISTS (memrchr HAVE_MEMRCHR)
320CHECK_FUNCTION_EXISTS (mlock HAVE_MLOCK)
321CHECK_FUNCTION_EXISTS (mlockall HAVE_MLOCKALL)
322CHECK_FUNCTION_EXISTS (mmap64 HAVE_MMAP64)
323CHECK_FUNCTION_EXISTS (poll HAVE_POLL)
324CHECK_FUNCTION_EXISTS (posix_fallocate HAVE_POSIX_FALLOCATE)
325CHECK_FUNCTION_EXISTS (posix_memalign HAVE_POSIX_MEMALIGN)
326CHECK_FUNCTION_EXISTS (pread HAVE_PREAD) # Used by NDB
327CHECK_FUNCTION_EXISTS (pthread_condattr_setclock HAVE_PTHREAD_CONDATTR_SETCLOCK)
328CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK)
329CHECK_FUNCTION_EXISTS (readlink HAVE_READLINK)
330CHECK_FUNCTION_EXISTS (realpath HAVE_REALPATH)
331CHECK_FUNCTION_EXISTS (setfd HAVE_SETFD)
332CHECK_FUNCTION_EXISTS (sigaction HAVE_SIGACTION)
333CHECK_FUNCTION_EXISTS (sleep HAVE_SLEEP)
334CHECK_FUNCTION_EXISTS (stpcpy HAVE_STPCPY)
335CHECK_FUNCTION_EXISTS (stpncpy HAVE_STPNCPY)
336CHECK_FUNCTION_EXISTS (strlcpy HAVE_STRLCPY)
337CHECK_FUNCTION_EXISTS (strndup HAVE_STRNDUP) # Used by libbinlogevents
338CHECK_FUNCTION_EXISTS (strnlen HAVE_STRNLEN)
339CHECK_FUNCTION_EXISTS (strlcat HAVE_STRLCAT)
340CHECK_FUNCTION_EXISTS (strsignal HAVE_STRSIGNAL)
341CHECK_FUNCTION_EXISTS (fgetln HAVE_FGETLN)
342CHECK_FUNCTION_EXISTS (strsep HAVE_STRSEP)
343CHECK_FUNCTION_EXISTS (tell HAVE_TELL)
344CHECK_FUNCTION_EXISTS (vasprintf HAVE_VASPRINTF)
345CHECK_FUNCTION_EXISTS (memalign HAVE_MEMALIGN)
346CHECK_FUNCTION_EXISTS (nl_langinfo HAVE_NL_LANGINFO)
347CHECK_FUNCTION_EXISTS (ntohll HAVE_HTONLL)
348CHECK_FUNCTION_EXISTS (memset_s HAVE_MEMSET_S)
349
350CHECK_FUNCTION_EXISTS (clock_gettime DNS_USE_CPU_CLOCK_FOR_ID)
351CHECK_FUNCTION_EXISTS (epoll_create HAVE_EPOLL)
352# Temperarily  Quote event port out as we encounter error in port_getn
353# on solaris x86
354# CHECK_FUNCTION_EXISTS (port_create HAVE_EVENT_PORTS)
355CHECK_FUNCTION_EXISTS (inet_ntop HAVE_INET_NTOP)
356CHECK_FUNCTION_EXISTS (kqueue HAVE_WORKING_KQUEUE)
357CHECK_SYMBOL_EXISTS (timeradd "sys/time.h" HAVE_TIMERADD)
358CHECK_SYMBOL_EXISTS (timerclear "sys/time.h" HAVE_TIMERCLEAR)
359CHECK_SYMBOL_EXISTS (timercmp "sys/time.h" HAVE_TIMERCMP)
360CHECK_SYMBOL_EXISTS (timerisset "sys/time.h" HAVE_TIMERISSET)
361
362#--------------------------------------------------------------------
363# Support for WL#2373 (Use cycle counter for timing)
364#--------------------------------------------------------------------
365
366CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H)
367CHECK_INCLUDE_FILES(sys/times.h HAVE_SYS_TIMES_H)
368
369CHECK_FUNCTION_EXISTS(times HAVE_TIMES)
370CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
371
372
373#
374# Tests for symbols
375#
376
377CHECK_SYMBOL_EXISTS(lrand48 "stdlib.h" HAVE_LRAND48)
378CHECK_SYMBOL_EXISTS(TIOCGWINSZ "sys/ioctl.h" GWINSZ_IN_SYS_IOCTL)
379CHECK_SYMBOL_EXISTS(FIONREAD "sys/ioctl.h" FIONREAD_IN_SYS_IOCTL)
380CHECK_SYMBOL_EXISTS(FIONREAD "sys/filio.h" FIONREAD_IN_SYS_FILIO)
381CHECK_SYMBOL_EXISTS(SIGEV_THREAD_ID "signal.h;time.h" HAVE_SIGEV_THREAD_ID)
382CHECK_SYMBOL_EXISTS(SIGEV_PORT "signal.h;time.h;sys/siginfo.h" HAVE_SIGEV_PORT)
383
384CHECK_SYMBOL_EXISTS(log2  math.h HAVE_LOG2)
385CHECK_SYMBOL_EXISTS(MADV_DONTDUMP "sys/mman.h" HAVE_MADV_DONTDUMP)
386
387# On Solaris, it is only visible in C99 mode
388CHECK_SYMBOL_EXISTS(isinf "math.h" HAVE_C_ISINF)
389
390# isinf() prototype not found on Solaris
391CHECK_CXX_SOURCE_COMPILES(
392"#include  <math.h>
393int main() {
394  isinf(0.0);
395  return 0;
396}" HAVE_CXX_ISINF)
397
398IF (HAVE_C_ISINF AND HAVE_CXX_ISINF)
399  SET(HAVE_ISINF 1 CACHE INTERNAL "isinf visible in C and C++" FORCE)
400ELSE()
401  SET(HAVE_ISINF 0 CACHE INTERNAL "isinf visible in C and C++" FORCE)
402ENDIF()
403
404
405# The results of these four checks are only needed here, not in code.
406CHECK_FUNCTION_EXISTS (timer_create HAVE_TIMER_CREATE)
407CHECK_FUNCTION_EXISTS (timer_settime HAVE_TIMER_SETTIME)
408CHECK_FUNCTION_EXISTS (kqueue HAVE_KQUEUE)
409CHECK_SYMBOL_EXISTS(EVFILT_TIMER "sys/types.h;sys/event.h;sys/time.h" HAVE_EVFILT_TIMER)
410IF(HAVE_KQUEUE AND HAVE_EVFILT_TIMER)
411  SET(HAVE_KQUEUE_TIMERS 1 CACHE INTERNAL "Have kqueue timer-related filter")
412ELSEIF(HAVE_TIMER_CREATE AND HAVE_TIMER_SETTIME)
413  IF(HAVE_SIGEV_THREAD_ID OR HAVE_SIGEV_PORT)
414    SET(HAVE_POSIX_TIMERS 1 CACHE INTERNAL "Have POSIX timer-related functions")
415  ENDIF()
416ENDIF()
417
418IF(NOT HAVE_POSIX_TIMERS AND NOT HAVE_KQUEUE_TIMERS AND NOT WIN32)
419  MESSAGE(FATAL_ERROR "No mysys timer support detected!")
420ENDIF()
421
422#
423# Test for endianess
424#
425INCLUDE(TestBigEndian)
426TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
427
428#
429# Tests for type sizes (and presence)
430#
431INCLUDE (CheckTypeSize)
432
433LIST(APPEND CMAKE_REQUIRED_DEFINITIONS
434  -D_LARGEFILE_SOURCE -D_LARGE_FILES -D_FILE_OFFSET_BITS=64
435  -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS
436  )
437
438IF(SOLARIS)
439  LIST(APPEND CMAKE_REQUIRED_DEFINITIONS
440    -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -D_PTHREADS
441    )
442ENDIF()
443
444SET(CMAKE_EXTRA_INCLUDE_FILES stdint.h stdio.h sys/types.h time.h)
445
446CHECK_TYPE_SIZE("void *"    SIZEOF_VOIDP)
447CHECK_TYPE_SIZE("char *"    SIZEOF_CHARP)
448CHECK_TYPE_SIZE("long"      SIZEOF_LONG)
449CHECK_TYPE_SIZE("short"     SIZEOF_SHORT)
450CHECK_TYPE_SIZE("int"       SIZEOF_INT)
451CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
452CHECK_TYPE_SIZE("off_t"     SIZEOF_OFF_T)
453CHECK_TYPE_SIZE("time_t"    SIZEOF_TIME_T)
454CHECK_TYPE_SIZE("struct timespec" STRUCT_TIMESPEC)
455
456# If finds the size of a type, set SIZEOF_<type> and HAVE_<type>
457FUNCTION(MY_CHECK_TYPE_SIZE type defbase)
458  CHECK_TYPE_SIZE("${type}" SIZEOF_${defbase})
459  IF(SIZEOF_${defbase})
460    SET(HAVE_${defbase} 1 PARENT_SCOPE)
461  ENDIF()
462ENDFUNCTION()
463
464# We are only interested in presence for these
465MY_CHECK_TYPE_SIZE(uint UINT)
466MY_CHECK_TYPE_SIZE(ulong ULONG)
467MY_CHECK_TYPE_SIZE(u_int32_t U_INT32_T)
468
469IF(HAVE_IEEEFP_H)
470  SET(CMAKE_EXTRA_INCLUDE_FILES ieeefp.h)
471  MY_CHECK_TYPE_SIZE(fp_except FP_EXCEPT)
472ENDIF()
473
474SET(CMAKE_EXTRA_INCLUDE_FILES)
475
476# Support for tagging symbols with __attribute__((visibility("hidden")))
477MY_CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" HAVE_VISIBILITY_HIDDEN)
478
479#
480# Code tests
481#
482
483IF(NOT STACK_DIRECTION)
484  IF(CMAKE_CROSSCOMPILING)
485   MESSAGE(FATAL_ERROR
486   "STACK_DIRECTION is not defined.  Please specify -DSTACK_DIRECTION=1 "
487   "or -DSTACK_DIRECTION=-1 when calling cmake.")
488  ELSE()
489    TRY_RUN(STACKDIR_RUN_RESULT STACKDIR_COMPILE_RESULT
490     ${CMAKE_BINARY_DIR}
491     ${CMAKE_SOURCE_DIR}/cmake/stack_direction.c
492     )
493     # Test program returns 0 (down) or 1 (up).
494     # Convert to -1 or 1
495     IF(STACKDIR_RUN_RESULT EQUAL 0)
496       SET(STACK_DIRECTION -1 CACHE INTERNAL "Stack grows direction")
497     ELSE()
498       SET(STACK_DIRECTION 1 CACHE INTERNAL "Stack grows direction")
499     ENDIF()
500     MESSAGE(STATUS "Checking stack direction : ${STACK_DIRECTION}")
501   ENDIF()
502ENDIF()
503
504CHECK_INCLUDE_FILES("time.h;sys/time.h" TIME_WITH_SYS_TIME)
505CHECK_SYMBOL_EXISTS(O_NONBLOCK "unistd.h;fcntl.h" HAVE_FCNTL_NONBLOCK)
506IF(NOT HAVE_FCNTL_NONBLOCK)
507 SET(NO_FCNTL_NONBLOCK 1)
508ENDIF()
509
510IF(NOT CMAKE_CROSSCOMPILING AND NOT MSVC)
511  STRING(TOLOWER ${CMAKE_SYSTEM_PROCESSOR}  processor)
512  IF(processor MATCHES "86" OR processor MATCHES "amd64" OR processor MATCHES "x64")
513    IF(NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
514      # The loader in some Solaris versions has a bug due to which it refuses to
515      # start a binary that has been compiled by GCC and uses __asm__("pause")
516      # with the error:
517      # $ ./mysqld
518      # ld.so.1: mysqld: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
519      # Killed
520      # $
521      # Even though the CPU does have support for the instruction.
522      # Binaries that have been compiled by GCC and use __asm__("pause")
523      # on a non-buggy Solaris get flagged with a "uses pause" flag and
524      # thus they are unusable if copied on buggy Solaris version. To
525      # circumvent this we explicitly disable __asm__("pause") when
526      # compiling on Solaris. Subsequently the tests here will enable
527      # HAVE_FAKE_PAUSE_INSTRUCTION which will use __asm__("rep; nop")
528      # which currently generates the same code as __asm__("pause") - 0xf3 0x90
529      # but without flagging the binary as "uses pause".
530      CHECK_C_SOURCE_RUNS("
531      int main()
532      {
533        __asm__ __volatile__ (\"pause\");
534        return 0;
535      }"  HAVE_PAUSE_INSTRUCTION)
536    ENDIF()
537  ENDIF()
538  IF (NOT HAVE_PAUSE_INSTRUCTION)
539    CHECK_C_SOURCE_COMPILES("
540    int main()
541    {
542     __asm__ __volatile__ (\"rep; nop\");
543     return 0;
544    }
545   " HAVE_FAKE_PAUSE_INSTRUCTION)
546  ENDIF()
547  IF (NOT HAVE_PAUSE_INSTRUCTION)
548    CHECK_C_SOURCE_COMPILES("
549    int main()
550    {
551     __asm__ __volatile__ (\"or 1,1,1\");
552     __asm__ __volatile__ (\"or 2,2,2\");
553     return 0;
554    }
555    " HAVE_HMT_PRIORITY_INSTRUCTION)
556  ENDIF()
557ENDIF()
558
559IF(CMAKE_COMPILER_IS_GNUCXX AND HAVE_CXXABI_H)
560CHECK_CXX_SOURCE_COMPILES("
561 #include <cxxabi.h>
562 int main(int argc, char **argv)
563  {
564    char *foo= 0; int bar= 0;
565    foo= abi::__cxa_demangle(foo, foo, 0, &bar);
566    return 0;
567  }"
568  HAVE_ABI_CXA_DEMANGLE)
569ENDIF()
570
571CHECK_C_SOURCE_COMPILES("
572int main()
573{
574  __builtin_unreachable();
575  return 0;
576}" HAVE_BUILTIN_UNREACHABLE)
577
578CHECK_C_SOURCE_COMPILES("
579int main()
580{
581  long l= 0;
582  __builtin_expect(l, 0);
583  return 0;
584}" HAVE_BUILTIN_EXPECT)
585
586# GCC has __builtin_stpcpy but still calls stpcpy
587IF(NOT CMAKE_SYSTEM_NAME MATCHES "SunOS" OR NOT CMAKE_COMPILER_IS_GNUCC)
588CHECK_C_SOURCE_COMPILES("
589int main()
590{
591  char foo1[1];
592  char foo2[1];
593  __builtin_stpcpy(foo1, foo2);
594  return 0;
595}" HAVE_BUILTIN_STPCPY)
596ENDIF()
597
598CHECK_CXX_SOURCE_COMPILES("
599  int main()
600  {
601    int foo= -10; int bar= 10;
602    long long int foo64= -10; long long int bar64= 10;
603    if (!__atomic_fetch_add(&foo, bar, __ATOMIC_SEQ_CST) || foo)
604      return -1;
605    bar= __atomic_exchange_n(&foo, bar, __ATOMIC_SEQ_CST);
606    if (bar || foo != 10)
607      return -1;
608    bar= __atomic_compare_exchange_n(&bar, &foo, 15, 0,
609                                     __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
610    if (bar)
611      return -1;
612    if (!__atomic_fetch_add(&foo64, bar64, __ATOMIC_SEQ_CST) || foo64)
613      return -1;
614    bar64= __atomic_exchange_n(&foo64, bar64, __ATOMIC_SEQ_CST);
615    if (bar64 || foo64 != 10)
616      return -1;
617    bar64= __atomic_compare_exchange_n(&bar64, &foo64, 15, 0,
618                                       __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
619    if (bar64)
620      return -1;
621    return 0;
622  }"
623  HAVE_GCC_ATOMIC_BUILTINS)
624
625CHECK_CXX_SOURCE_COMPILES("
626  int main()
627  {
628    int foo= -10; int bar= 10;
629    long long int foo64= -10; long long int bar64= 10;
630    if (!__sync_fetch_and_add(&foo, bar) || foo)
631      return -1;
632    bar= __sync_lock_test_and_set(&foo, bar);
633    if (bar || foo != 10)
634      return -1;
635    bar= __sync_val_compare_and_swap(&bar, foo, 15);
636    if (bar)
637      return -1;
638    if (!__sync_fetch_and_add(&foo64, bar64) || foo64)
639      return -1;
640    bar64= __sync_lock_test_and_set(&foo64, bar64);
641    if (bar64 || foo64 != 10)
642      return -1;
643    bar64= __sync_val_compare_and_swap(&bar64, foo, 15);
644    if (bar64)
645      return -1;
646    return 0;
647  }"
648  HAVE_GCC_SYNC_BUILTINS)
649
650IF(WITH_VALGRIND)
651  SET(VALGRIND_HEADERS "valgrind/memcheck.h;valgrind/valgrind.h")
652  CHECK_INCLUDE_FILES("${VALGRIND_HEADERS}" HAVE_VALGRIND_HEADERS)
653  IF(HAVE_VALGRIND_HEADERS)
654    SET(HAVE_VALGRIND 1)
655  ELSE()
656    MESSAGE(FATAL_ERROR "Unable to find Valgrind header files ${VALGRIND_HEADERS}. Make sure you have them in your include path.")
657  ENDIF()
658ENDIF()
659
660#--------------------------------------------------------------------
661# Check for IPv6 support
662#--------------------------------------------------------------------
663CHECK_INCLUDE_FILE(netinet/in6.h HAVE_NETINET_IN6_H) # Used by libevent
664
665IF(UNIX)
666  SET(CMAKE_EXTRA_INCLUDE_FILES sys/types.h netinet/in.h sys/socket.h)
667  IF(HAVE_NETINET_IN6_H)
668    SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} netinet/in6.h)
669  ENDIF()
670ELSEIF(WIN32)
671  SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} winsock2.h ws2ipdef.h)
672ENDIF()
673
674MY_CHECK_STRUCT_SIZE("sockaddr_in6" SOCKADDR_IN6)
675MY_CHECK_STRUCT_SIZE("in6_addr" IN6_ADDR)
676
677IF(HAVE_STRUCT_SOCKADDR_IN6 OR HAVE_STRUCT_IN6_ADDR)
678  SET(HAVE_IPV6 TRUE CACHE INTERNAL "")
679ENDIF()
680
681
682# Check for sockaddr_storage.ss_family
683
684CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage"
685 ss_family "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_STORAGE_SS_FAMILY)
686IF(NOT HAVE_SOCKADDR_STORAGE_SS_FAMILY)
687  CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage"
688  __ss_family "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_STORAGE___SS_FAMILY)
689  IF(HAVE_SOCKADDR_STORAGE___SS_FAMILY)
690    SET(ss_family __ss_family)
691  ENDIF()
692ENDIF()
693
694#
695# Check if struct sockaddr_in::sin_len is available.
696#
697
698CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in" sin_len
699  "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN_SIN_LEN)
700
701#
702# Check if struct sockaddr_in6::sin6_len is available.
703#
704
705CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_len
706  "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN6_SIN6_LEN)
707
708# Check for pthread_threadid_np()
709CHECK_C_SOURCE_COMPILES("
710#include <pthread.h>
711int main(int ac, char **av)
712{
713  unsigned long long tid64;
714  pthread_threadid_np(NULL, &tid64);
715  return (tid64 != 0 ? 0 : 1);
716}"
717HAVE_PTHREAD_THREADID_NP)
718
719CHECK_CXX_SOURCE_COMPILES(
720  "
721  #include <vector>
722  template<typename T>
723  class ct2
724  {
725  public:
726    typedef T type;
727    void func();
728  };
729
730  template<typename T>
731  void ct2<T>::func()
732  {
733    std::vector<T> vec;
734    std::vector<T>::iterator itr = vec.begin();
735  }
736
737  int main(int argc, char **argv)
738  {
739    ct2<double> o2;
740    o2.func();
741    return 0;
742  }
743  " HAVE_IMPLICIT_DEPENDENT_NAME_TYPING)
744
745SET(CMAKE_EXTRA_INCLUDE_FILES)
746
747CHECK_FUNCTION_EXISTS(chown HAVE_CHOWN)
748
749CHECK_INCLUDE_FILES(numa.h HAVE_NUMA_H)
750CHECK_INCLUDE_FILES(numaif.h HAVE_NUMAIF_H)
751
752IF(HAVE_NUMA_H AND HAVE_NUMAIF_H)
753    SET(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
754    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} numa)
755    CHECK_C_SOURCE_COMPILES(
756    "
757    #include <numa.h>
758    #include <numaif.h>
759    int main()
760    {
761       struct bitmask *all_nodes= numa_all_nodes_ptr;
762       set_mempolicy(MPOL_DEFAULT, 0, 0);
763       return all_nodes != NULL;
764    }"
765    HAVE_LIBNUMA)
766    SET(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
767ELSE()
768    SET(HAVE_LIBNUMA 0)
769ENDIF()
770
771IF(NOT HAVE_LIBNUMA)
772   MESSAGE(STATUS "NUMA library missing or required version not available")
773ENDIF()
774
775IF(HAVE_LIBNUMA AND HAVE_NUMA_H AND HAVE_NUMAIF_H)
776  OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" ON)
777ELSE()
778  OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" OFF)
779ENDIF()
780
781IF(WITH_NUMA AND NOT HAVE_LIBNUMA)
782  # Forget it in cache, abort the build.
783  UNSET(WITH_NUMA CACHE)
784  MESSAGE(FATAL_ERROR "NUMA library missing or required version not available")
785ENDIF()
786
787IF(HAVE_LIBNUMA AND NOT WITH_NUMA)
788   SET(HAVE_LIBNUMA 0)
789   MESSAGE(STATUS "Disabling NUMA on user's request")
790ENDIF()
791
792# needed for libevent
793CHECK_TYPE_SIZE("socklen_t" SIZEOF_SOCKLEN_T)
794IF(SIZEOF_SOCKLEN_T)
795  SET(HAVE_SOCKLEN_T 1)
796ENDIF()
797