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 "FreeBSD")
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)
348
349CHECK_FUNCTION_EXISTS (clock_gettime DNS_USE_CPU_CLOCK_FOR_ID)
350CHECK_FUNCTION_EXISTS (epoll_create HAVE_EPOLL)
351# Temperarily  Quote event port out as we encounter error in port_getn
352# on solaris x86
353# CHECK_FUNCTION_EXISTS (port_create HAVE_EVENT_PORTS)
354CHECK_FUNCTION_EXISTS (inet_ntop HAVE_INET_NTOP)
355CHECK_FUNCTION_EXISTS (kqueue HAVE_WORKING_KQUEUE)
356CHECK_SYMBOL_EXISTS (timeradd "sys/time.h" HAVE_TIMERADD)
357CHECK_SYMBOL_EXISTS (timerclear "sys/time.h" HAVE_TIMERCLEAR)
358CHECK_SYMBOL_EXISTS (timercmp "sys/time.h" HAVE_TIMERCMP)
359CHECK_SYMBOL_EXISTS (timerisset "sys/time.h" HAVE_TIMERISSET)
360
361#--------------------------------------------------------------------
362# Support for WL#2373 (Use cycle counter for timing)
363#--------------------------------------------------------------------
364
365CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H)
366CHECK_INCLUDE_FILES(sys/times.h HAVE_SYS_TIMES_H)
367
368CHECK_FUNCTION_EXISTS(times HAVE_TIMES)
369CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
370
371
372#
373# Tests for symbols
374#
375
376CHECK_SYMBOL_EXISTS(lrand48 "stdlib.h" HAVE_LRAND48)
377CHECK_SYMBOL_EXISTS(TIOCGWINSZ "sys/ioctl.h" GWINSZ_IN_SYS_IOCTL)
378CHECK_SYMBOL_EXISTS(FIONREAD "sys/ioctl.h" FIONREAD_IN_SYS_IOCTL)
379CHECK_SYMBOL_EXISTS(FIONREAD "sys/filio.h" FIONREAD_IN_SYS_FILIO)
380CHECK_SYMBOL_EXISTS(SIGEV_THREAD_ID "signal.h;time.h" HAVE_SIGEV_THREAD_ID)
381CHECK_SYMBOL_EXISTS(SIGEV_PORT "signal.h;time.h;sys/siginfo.h" HAVE_SIGEV_PORT)
382
383CHECK_SYMBOL_EXISTS(log2  math.h HAVE_LOG2)
384
385# On Solaris, it is only visible in C99 mode
386CHECK_SYMBOL_EXISTS(isinf "math.h" HAVE_C_ISINF)
387
388# isinf() prototype not found on Solaris
389CHECK_CXX_SOURCE_COMPILES(
390"#include  <math.h>
391int main() {
392  isinf(0.0);
393  return 0;
394}" HAVE_CXX_ISINF)
395
396IF (HAVE_C_ISINF AND HAVE_CXX_ISINF)
397  SET(HAVE_ISINF 1 CACHE INTERNAL "isinf visible in C and C++" FORCE)
398ELSE()
399  SET(HAVE_ISINF 0 CACHE INTERNAL "isinf visible in C and C++" FORCE)
400ENDIF()
401
402
403# The results of these four checks are only needed here, not in code.
404CHECK_FUNCTION_EXISTS (timer_create HAVE_TIMER_CREATE)
405CHECK_FUNCTION_EXISTS (timer_settime HAVE_TIMER_SETTIME)
406CHECK_FUNCTION_EXISTS (kqueue HAVE_KQUEUE)
407CHECK_SYMBOL_EXISTS(EVFILT_TIMER "sys/types.h;sys/event.h;sys/time.h" HAVE_EVFILT_TIMER)
408IF(HAVE_KQUEUE AND HAVE_EVFILT_TIMER)
409  SET(HAVE_KQUEUE_TIMERS 1 CACHE INTERNAL "Have kqueue timer-related filter")
410ELSEIF(HAVE_TIMER_CREATE AND HAVE_TIMER_SETTIME)
411  IF(HAVE_SIGEV_THREAD_ID OR HAVE_SIGEV_PORT)
412    SET(HAVE_POSIX_TIMERS 1 CACHE INTERNAL "Have POSIX timer-related functions")
413  ENDIF()
414ENDIF()
415
416IF(NOT HAVE_POSIX_TIMERS AND NOT HAVE_KQUEUE_TIMERS AND NOT WIN32)
417  MESSAGE(FATAL_ERROR "No mysys timer support detected!")
418ENDIF()
419
420#
421# Test for endianess
422#
423INCLUDE(TestBigEndian)
424TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
425
426#
427# Tests for type sizes (and presence)
428#
429INCLUDE (CheckTypeSize)
430
431LIST(APPEND CMAKE_REQUIRED_DEFINITIONS
432  -D_LARGEFILE_SOURCE -D_LARGE_FILES -D_FILE_OFFSET_BITS=64
433  -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS
434  )
435
436IF(SOLARIS)
437  LIST(APPEND CMAKE_REQUIRED_DEFINITIONS
438    -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -D_PTHREADS
439    )
440ENDIF()
441
442SET(CMAKE_EXTRA_INCLUDE_FILES stdint.h stdio.h sys/types.h time.h)
443
444CHECK_TYPE_SIZE("void *"    SIZEOF_VOIDP)
445CHECK_TYPE_SIZE("char *"    SIZEOF_CHARP)
446CHECK_TYPE_SIZE("long"      SIZEOF_LONG)
447CHECK_TYPE_SIZE("short"     SIZEOF_SHORT)
448CHECK_TYPE_SIZE("int"       SIZEOF_INT)
449CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
450CHECK_TYPE_SIZE("off_t"     SIZEOF_OFF_T)
451CHECK_TYPE_SIZE("time_t"    SIZEOF_TIME_T)
452CHECK_TYPE_SIZE("struct timespec" STRUCT_TIMESPEC)
453
454# If finds the size of a type, set SIZEOF_<type> and HAVE_<type>
455FUNCTION(MY_CHECK_TYPE_SIZE type defbase)
456  CHECK_TYPE_SIZE("${type}" SIZEOF_${defbase})
457  IF(SIZEOF_${defbase})
458    SET(HAVE_${defbase} 1 PARENT_SCOPE)
459  ENDIF()
460ENDFUNCTION()
461
462# We are only interested in presence for these
463MY_CHECK_TYPE_SIZE(uint UINT)
464MY_CHECK_TYPE_SIZE(ulong ULONG)
465MY_CHECK_TYPE_SIZE(u_int32_t U_INT32_T)
466
467IF(HAVE_IEEEFP_H)
468  SET(CMAKE_EXTRA_INCLUDE_FILES ieeefp.h)
469  MY_CHECK_TYPE_SIZE(fp_except FP_EXCEPT)
470ENDIF()
471
472SET(CMAKE_EXTRA_INCLUDE_FILES)
473
474# Support for tagging symbols with __attribute__((visibility("hidden")))
475MY_CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" HAVE_VISIBILITY_HIDDEN)
476
477#
478# Code tests
479#
480
481IF(NOT STACK_DIRECTION)
482  IF(CMAKE_CROSSCOMPILING)
483   MESSAGE(FATAL_ERROR
484   "STACK_DIRECTION is not defined.  Please specify -DSTACK_DIRECTION=1 "
485   "or -DSTACK_DIRECTION=-1 when calling cmake.")
486  ELSE()
487    TRY_RUN(STACKDIR_RUN_RESULT STACKDIR_COMPILE_RESULT
488     ${CMAKE_BINARY_DIR}
489     ${CMAKE_SOURCE_DIR}/cmake/stack_direction.c
490     )
491     # Test program returns 0 (down) or 1 (up).
492     # Convert to -1 or 1
493     IF(STACKDIR_RUN_RESULT EQUAL 0)
494       SET(STACK_DIRECTION -1 CACHE INTERNAL "Stack grows direction")
495     ELSE()
496       SET(STACK_DIRECTION 1 CACHE INTERNAL "Stack grows direction")
497     ENDIF()
498     MESSAGE(STATUS "Checking stack direction : ${STACK_DIRECTION}")
499   ENDIF()
500ENDIF()
501
502CHECK_INCLUDE_FILES("time.h;sys/time.h" TIME_WITH_SYS_TIME)
503CHECK_SYMBOL_EXISTS(O_NONBLOCK "unistd.h;fcntl.h" HAVE_FCNTL_NONBLOCK)
504IF(NOT HAVE_FCNTL_NONBLOCK)
505 SET(NO_FCNTL_NONBLOCK 1)
506ENDIF()
507
508IF(NOT CMAKE_CROSSCOMPILING AND NOT MSVC)
509  STRING(TOLOWER ${CMAKE_SYSTEM_PROCESSOR}  processor)
510  IF(processor MATCHES "86" OR processor MATCHES "amd64" OR processor MATCHES "x64")
511    IF(NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
512      # The loader in some Solaris versions has a bug due to which it refuses to
513      # start a binary that has been compiled by GCC and uses __asm__("pause")
514      # with the error:
515      # $ ./mysqld
516      # ld.so.1: mysqld: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
517      # Killed
518      # $
519      # Even though the CPU does have support for the instruction.
520      # Binaries that have been compiled by GCC and use __asm__("pause")
521      # on a non-buggy Solaris get flagged with a "uses pause" flag and
522      # thus they are unusable if copied on buggy Solaris version. To
523      # circumvent this we explicitly disable __asm__("pause") when
524      # compiling on Solaris. Subsequently the tests here will enable
525      # HAVE_FAKE_PAUSE_INSTRUCTION which will use __asm__("rep; nop")
526      # which currently generates the same code as __asm__("pause") - 0xf3 0x90
527      # but without flagging the binary as "uses pause".
528      CHECK_C_SOURCE_RUNS("
529      int main()
530      {
531        __asm__ __volatile__ (\"pause\");
532        return 0;
533      }"  HAVE_PAUSE_INSTRUCTION)
534    ENDIF()
535  ENDIF()
536  IF (NOT HAVE_PAUSE_INSTRUCTION)
537    CHECK_C_SOURCE_COMPILES("
538    int main()
539    {
540     __asm__ __volatile__ (\"rep; nop\");
541     return 0;
542    }
543   " HAVE_FAKE_PAUSE_INSTRUCTION)
544  ENDIF()
545  IF (NOT HAVE_PAUSE_INSTRUCTION)
546    CHECK_C_SOURCE_COMPILES("
547    int main()
548    {
549     __asm__ __volatile__ (\"or 1,1,1\");
550     __asm__ __volatile__ (\"or 2,2,2\");
551     return 0;
552    }
553    " HAVE_HMT_PRIORITY_INSTRUCTION)
554  ENDIF()
555ENDIF()
556
557IF(CMAKE_COMPILER_IS_GNUCXX AND HAVE_CXXABI_H)
558CHECK_CXX_SOURCE_COMPILES("
559 #include <cxxabi.h>
560 int main(int argc, char **argv)
561  {
562    char *foo= 0; int bar= 0;
563    foo= abi::__cxa_demangle(foo, foo, 0, &bar);
564    return 0;
565  }"
566  HAVE_ABI_CXA_DEMANGLE)
567ENDIF()
568
569CHECK_C_SOURCE_COMPILES("
570int main()
571{
572  __builtin_unreachable();
573  return 0;
574}" HAVE_BUILTIN_UNREACHABLE)
575
576CHECK_C_SOURCE_COMPILES("
577int main()
578{
579  long l= 0;
580  __builtin_expect(l, 0);
581  return 0;
582}" HAVE_BUILTIN_EXPECT)
583
584# GCC has __builtin_stpcpy but still calls stpcpy
585IF(NOT CMAKE_SYSTEM_NAME MATCHES "SunOS" OR NOT CMAKE_COMPILER_IS_GNUCC)
586CHECK_C_SOURCE_COMPILES("
587int main()
588{
589  char foo1[1];
590  char foo2[1];
591  __builtin_stpcpy(foo1, foo2);
592  return 0;
593}" HAVE_BUILTIN_STPCPY)
594ENDIF()
595
596CHECK_CXX_SOURCE_COMPILES("
597  int main()
598  {
599    int foo= -10; int bar= 10;
600    long long int foo64= -10; long long int bar64= 10;
601    if (!__atomic_fetch_add(&foo, bar, __ATOMIC_SEQ_CST) || foo)
602      return -1;
603    bar= __atomic_exchange_n(&foo, bar, __ATOMIC_SEQ_CST);
604    if (bar || foo != 10)
605      return -1;
606    bar= __atomic_compare_exchange_n(&bar, &foo, 15, 0,
607                                     __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
608    if (bar)
609      return -1;
610    if (!__atomic_fetch_add(&foo64, bar64, __ATOMIC_SEQ_CST) || foo64)
611      return -1;
612    bar64= __atomic_exchange_n(&foo64, bar64, __ATOMIC_SEQ_CST);
613    if (bar64 || foo64 != 10)
614      return -1;
615    bar64= __atomic_compare_exchange_n(&bar64, &foo64, 15, 0,
616                                       __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
617    if (bar64)
618      return -1;
619    return 0;
620  }"
621  HAVE_GCC_ATOMIC_BUILTINS)
622
623CHECK_CXX_SOURCE_COMPILES("
624  int main()
625  {
626    int foo= -10; int bar= 10;
627    long long int foo64= -10; long long int bar64= 10;
628    if (!__sync_fetch_and_add(&foo, bar) || foo)
629      return -1;
630    bar= __sync_lock_test_and_set(&foo, bar);
631    if (bar || foo != 10)
632      return -1;
633    bar= __sync_val_compare_and_swap(&bar, foo, 15);
634    if (bar)
635      return -1;
636    if (!__sync_fetch_and_add(&foo64, bar64) || foo64)
637      return -1;
638    bar64= __sync_lock_test_and_set(&foo64, bar64);
639    if (bar64 || foo64 != 10)
640      return -1;
641    bar64= __sync_val_compare_and_swap(&bar64, foo, 15);
642    if (bar64)
643      return -1;
644    return 0;
645  }"
646  HAVE_GCC_SYNC_BUILTINS)
647
648IF(WITH_VALGRIND)
649  SET(VALGRIND_HEADERS "valgrind/memcheck.h;valgrind/valgrind.h")
650  CHECK_INCLUDE_FILES("${VALGRIND_HEADERS}" HAVE_VALGRIND_HEADERS)
651  IF(HAVE_VALGRIND_HEADERS)
652    SET(HAVE_VALGRIND 1)
653  ELSE()
654    MESSAGE(FATAL_ERROR "Unable to find Valgrind header files ${VALGRIND_HEADERS}. Make sure you have them in your include path.")
655  ENDIF()
656ENDIF()
657
658#--------------------------------------------------------------------
659# Check for IPv6 support
660#--------------------------------------------------------------------
661CHECK_INCLUDE_FILE(netinet/in6.h HAVE_NETINET_IN6_H) # Used by libevent
662
663IF(UNIX)
664  SET(CMAKE_EXTRA_INCLUDE_FILES sys/types.h netinet/in.h sys/socket.h)
665  IF(HAVE_NETINET_IN6_H)
666    SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} netinet/in6.h)
667  ENDIF()
668ELSEIF(WIN32)
669  SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} winsock2.h ws2ipdef.h)
670ENDIF()
671
672MY_CHECK_STRUCT_SIZE("sockaddr_in6" SOCKADDR_IN6)
673MY_CHECK_STRUCT_SIZE("in6_addr" IN6_ADDR)
674
675IF(HAVE_STRUCT_SOCKADDR_IN6 OR HAVE_STRUCT_IN6_ADDR)
676  SET(HAVE_IPV6 TRUE CACHE INTERNAL "")
677ENDIF()
678
679
680# Check for sockaddr_storage.ss_family
681
682CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage"
683 ss_family "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_STORAGE_SS_FAMILY)
684IF(NOT HAVE_SOCKADDR_STORAGE_SS_FAMILY)
685  CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage"
686  __ss_family "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_STORAGE___SS_FAMILY)
687  IF(HAVE_SOCKADDR_STORAGE___SS_FAMILY)
688    SET(ss_family __ss_family)
689  ENDIF()
690ENDIF()
691
692#
693# Check if struct sockaddr_in::sin_len is available.
694#
695
696CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in" sin_len
697  "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN_SIN_LEN)
698
699#
700# Check if struct sockaddr_in6::sin6_len is available.
701#
702
703CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_len
704  "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN6_SIN6_LEN)
705
706# Check for pthread_threadid_np()
707CHECK_C_SOURCE_COMPILES("
708#include <pthread.h>
709int main(int ac, char **av)
710{
711  unsigned long long tid64;
712  pthread_threadid_np(NULL, &tid64);
713  return (tid64 != 0 ? 0 : 1);
714}"
715HAVE_PTHREAD_THREADID_NP)
716
717CHECK_CXX_SOURCE_COMPILES(
718  "
719  #include <vector>
720  template<typename T>
721  class ct2
722  {
723  public:
724    typedef T type;
725    void func();
726  };
727
728  template<typename T>
729  void ct2<T>::func()
730  {
731    std::vector<T> vec;
732    std::vector<T>::iterator itr = vec.begin();
733  }
734
735  int main(int argc, char **argv)
736  {
737    ct2<double> o2;
738    o2.func();
739    return 0;
740  }
741  " HAVE_IMPLICIT_DEPENDENT_NAME_TYPING)
742
743SET(CMAKE_EXTRA_INCLUDE_FILES)
744
745CHECK_FUNCTION_EXISTS(chown HAVE_CHOWN)
746
747CHECK_INCLUDE_FILES(numa.h HAVE_NUMA_H)
748CHECK_INCLUDE_FILES(numaif.h HAVE_NUMAIF_H)
749
750IF(HAVE_NUMA_H AND HAVE_NUMAIF_H)
751    SET(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
752    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} numa)
753    CHECK_C_SOURCE_COMPILES(
754    "
755    #include <numa.h>
756    #include <numaif.h>
757    int main()
758    {
759       struct bitmask *all_nodes= numa_all_nodes_ptr;
760       set_mempolicy(MPOL_DEFAULT, 0, 0);
761       return all_nodes != NULL;
762    }"
763    HAVE_LIBNUMA)
764    SET(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
765ELSE()
766    SET(HAVE_LIBNUMA 0)
767ENDIF()
768
769IF(NOT HAVE_LIBNUMA)
770   MESSAGE(STATUS "NUMA library missing or required version not available")
771ENDIF()
772
773IF(HAVE_LIBNUMA AND HAVE_NUMA_H AND HAVE_NUMAIF_H)
774  OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" ON)
775ELSE()
776  OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" OFF)
777ENDIF()
778
779IF(WITH_NUMA AND NOT HAVE_LIBNUMA)
780  # Forget it in cache, abort the build.
781  UNSET(WITH_NUMA CACHE)
782  MESSAGE(FATAL_ERROR "NUMA library missing or required version not available")
783ENDIF()
784
785IF(HAVE_LIBNUMA AND NOT WITH_NUMA)
786   SET(HAVE_LIBNUMA 0)
787   MESSAGE(STATUS "Disabling NUMA on user's request")
788ENDIF()
789
790# needed for libevent
791CHECK_TYPE_SIZE("socklen_t" SIZEOF_SOCKLEN_T)
792IF(SIZEOF_SOCKLEN_T)
793  SET(HAVE_SOCKLEN_T 1)
794ENDIF()
795