CMAKE_MINIMUM_REQUIRED ( VERSION 3.1.0 )
INCLUDE ( CheckIncludeFiles )
INCLUDE ( CheckTypeSize )
INCLUDE ( CheckFunctionExists )
INCLUDE ( CheckSymbolExists )
INCLUDE ( CheckCSourceCompiles )
INCLUDE ( CheckStructHasMember )
INCLUDE ( CheckLibraryExists )
PROJECT ( c-ares LANGUAGES C VERSION "1.17.0" )
# Set this version before release
SET ( CARES_VERSION "${PROJECT_VERSION}" )
INCLUDE ( GNUInstallDirs ) # include this *AFTER* PROJECT(), otherwise paths are wrong.
# This is for libtool compatibility, and specified in a form that is easily
# translatable from libtool (even if the actual form doesn't make sense).
# For instance, in an autotools project, in Makefile.am there is a line that
# contains something like:
# -version-info 4:0:2
# This breaks down into sections of current:revision:age
# This then generates a version of "(current-age).age.revision" with an
# interface version of "(current-age)"
# For example, a version of 4:0:2 would generate output such as:
# libname.so -> libname.so.2
# libname.so.2 -> libname.so.2.2.0
SET ( CARES_LIB_VERSIONINFO "6:2:4" )
OPTION ( CARES_STATIC "Build as a static library" OFF )
OPTION ( CARES_SHARED "Build as a shared library" ON )
OPTION ( CARES_INSTALL "Create installation targets (chain builders may want to disable this)" ON )
OPTION ( CARES_STATIC_PIC "Build the static library as PIC (position independent)" OFF )
OPTION ( CARES_BUILD_TESTS "Build and run tests" OFF )
OPTION ( CARES_BUILD_CONTAINER_TESTS "Build and run container tests (implies CARES_BUILD_TESTS, Linux only)" OFF )
OPTION ( CARES_BUILD_TOOLS "Build tools" ON )
# Tests require static to be enabled
IF ( CARES_BUILD_TESTS )
SET ( CARES_STATIC ON )
SET ( CARES_STATIC_PIC ON )
ENDIF ( )
# allow linking against the static runtime library in msvc
IF ( MSVC )
OPTION ( CARES_MSVC_STATIC_RUNTIME "Link against the static runtime library" OFF )
IF ( CARES_MSVC_STATIC_RUNTIME )
# CMAKE_CONFIGURATION_TYPES is empty on non-IDE generators (Ninja, NMake)
# and that's why we also use CMAKE_BUILD_TYPE to cover for those generators.
# For IDE generators, CMAKE_BUILD_TYPE is usually empty
FOREACH ( config_type ${ CMAKE_CONFIGURATION_TYPES } ${ CMAKE_BUILD_TYPE } )
STRING ( TOUPPER ${ config_type } upper_config_type )
SET ( flag_var "CMAKE_C_FLAGS_${upper_config_type}" )
IF ( ${ flag_var } MATCHES "/MD" )
STRING ( REGEX REPLACE "/MD" "/MT" ${ flag_var } "${${flag_var}}" )
ENDIF ( )
ENDFOREACH ( )
# clean up
SET ( upper_config_type )
SET ( config_type )
SET ( flag_var )
ENDIF ( )
ENDIF ( )
# Keep build organized.
SET ( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}" )
SET ( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" )
SET ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" )
SET ( PACKAGE_DIRECTORY ${ PROJECT_BINARY_DIR } /package )
# Destinations for installing different kinds of targets (pass to install command).
SET ( TARGETS_INST_DEST
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
L I B R A R Y D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R }
A R C H I V E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R }
)
# Function in Library
# CHECK_LIBRARY_EXISTS can't be used as it will return true if the function
# is found in a different dependent library.
MACRO ( CARES_FUNCTION_IN_LIBRARY func lib var )
CHECK_FUNCTION_EXISTS ( "${func}" "_CARES_FUNC_IN_LIB_GLOBAL_${func}" )
IF ( "${_CARES_FUNC_IN_LIB_GLOBAL_${func}}" )
SET ( ${ var } FALSE )
ELSE ( )
CHECK_LIBRARY_EXISTS ( "${lib}" "${func}" "" ${ var } )
ENDIF ( )
ENDMACRO ( )
# Look for dependent/required libraries
CARES_FUNCTION_IN_LIBRARY ( res_servicename resolv HAVE_RES_SERVICENAME_IN_LIBRESOLV )
IF ( HAVE_RES_SERVICENAME_IN_LIBRESOLV )
SET ( HAVE_LIBRESOLV 1 )
ENDIF ( )
IF ( APPLE )
CHECK_C_SOURCE_COMPILES ( "
#include <stdio.h>
#include <TargetConditionals.h>
i n t main ( ) {
#if TARGET_OS_IPHONE == 0
#error Not an iPhone target
#endif
r e t u r n 0 ;
}
"
I O S )
CHECK_C_SOURCE_COMPILES ( "
#include <stdio.h>
#include <TargetConditionals.h>
i n t main ( ) {
#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
# error Not iOS v10
#endif
r e t u r n 0 ;
}
"
I O S _ V 1 0 )
CHECK_C_SOURCE_COMPILES ( "
#include <stdio.h>
#include <AvailabilityMacros.h>
#ifndef MAC_OS_X_VERSION_10_12
# define MAC_OS_X_VERSION_10_12 101200
#endif
i n t main ( ) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
# error Not MacOSX 10.12 or higher
#endif
r e t u r n 0 ;
}
"
M A C O S _ V 1 0 1 2 )
ENDIF ( )
IF ( ( IOS OR APPLE ) AND HAVE_LIBRESOLV )
SET ( CARES_USE_LIBRESOLV 1 )
ENDIF ( )
CARES_FUNCTION_IN_LIBRARY ( gethostbyname nsl HAVE_LIBNSL )
CARES_FUNCTION_IN_LIBRARY ( gethostbyname socket HAVE_GHBN_LIBSOCKET )
CARES_FUNCTION_IN_LIBRARY ( socket socket HAVE_SOCKET_LIBSOCKET )
IF ( HAVE_GHBN_LIBSOCKET OR HAVE_SOCKET_LIBSOCKET )
SET ( HAVE_LIBSOCKET TRUE )
ENDIF ( )
CARES_FUNCTION_IN_LIBRARY ( clock_gettime rt HAVE_LIBRT )
# Look for necessary includes
CHECK_INCLUDE_FILES ( sys/types.h HAVE_SYS_TYPES_H )
CHECK_INCLUDE_FILES ( sys/socket.h HAVE_SYS_SOCKET_H )
CHECK_INCLUDE_FILES ( arpa/inet.h HAVE_ARPA_INET_H )
CHECK_INCLUDE_FILES ( arpa/nameser_compat.h HAVE_ARPA_NAMESER_COMPAT_H )
CHECK_INCLUDE_FILES ( arpa/nameser.h HAVE_ARPA_NAMESER_H )
CHECK_INCLUDE_FILES ( assert.h HAVE_ASSERT_H )
CHECK_INCLUDE_FILES ( errno.h HAVE_ERRNO_H )
CHECK_INCLUDE_FILES ( fcntl.h HAVE_FCNTL_H )
CHECK_INCLUDE_FILES ( inttypes.h HAVE_INTTYPES_H )
CHECK_INCLUDE_FILES ( limits.h HAVE_LIMITS_H )
CHECK_INCLUDE_FILES ( malloc.h HAVE_MALLOC_H )
CHECK_INCLUDE_FILES ( memory.h HAVE_MEMORY_H )
CHECK_INCLUDE_FILES ( netdb.h HAVE_NETDB_H )
CHECK_INCLUDE_FILES ( netinet/in.h HAVE_NETINET_IN_H )
CHECK_INCLUDE_FILES ( netinet/tcp.h HAVE_NETINET_TCP_H )
CHECK_INCLUDE_FILES ( net/if.h HAVE_NET_IF_H )
CHECK_INCLUDE_FILES ( signal.h HAVE_SIGNAL_H )
CHECK_INCLUDE_FILES ( socket.h HAVE_SOCKET_H )
CHECK_INCLUDE_FILES ( stdbool.h HAVE_STDBOOL_H )
CHECK_INCLUDE_FILES ( stdint.h HAVE_STDINT_H )
CHECK_INCLUDE_FILES ( stdlib.h HAVE_STDLIB_H )
CHECK_INCLUDE_FILES ( strings.h HAVE_STRINGS_H )
CHECK_INCLUDE_FILES ( string.h HAVE_STRING_H )
CHECK_INCLUDE_FILES ( stropts.h HAVE_STROPTS_H )
CHECK_INCLUDE_FILES ( sys/ioctl.h HAVE_SYS_IOCTL_H )
CHECK_INCLUDE_FILES ( sys/param.h HAVE_SYS_PARAM_H )
CHECK_INCLUDE_FILES ( sys/select.h HAVE_SYS_SELECT_H )
CHECK_INCLUDE_FILES ( sys/socket.h HAVE_SYS_SOCKET_H )
CHECK_INCLUDE_FILES ( sys/stat.h HAVE_SYS_STAT_H )
CHECK_INCLUDE_FILES ( sys/time.h HAVE_SYS_TIME_H )
CHECK_INCLUDE_FILES ( sys/types.h HAVE_SYS_TYPES_H )
CHECK_INCLUDE_FILES ( sys/uio.h HAVE_SYS_UIO_H )
CHECK_INCLUDE_FILES ( time.h HAVE_TIME_H )
CHECK_INCLUDE_FILES ( dlfcn.h HAVE_DLFCN_H )
CHECK_INCLUDE_FILES ( unistd.h HAVE_UNISTD_H )
# Include order matters for these windows files.
CHECK_INCLUDE_FILES ( "winsock2.h;windows.h" HAVE_WINSOCK2_H )
CHECK_INCLUDE_FILES ( "winsock2.h;ws2tcpip.h;windows.h" HAVE_WS2TCPIP_H )
CHECK_INCLUDE_FILES ( "winsock.h;windows.h" HAVE_WINSOCK_H )
CHECK_INCLUDE_FILES ( windows.h HAVE_WINDOWS_H )
# Set system-specific compiler flags
IF ( CMAKE_SYSTEM_NAME STREQUAL "Darwin" )
LIST ( APPEND SYSFLAGS -D_DARWIN_C_SOURCE )
ELSEIF ( CMAKE_SYSTEM_NAME STREQUAL "Linux" )
LIST ( APPEND SYSFLAGS -D_GNU_SOURCE -D_POSIX_C_SOURCE=199309L -D_XOPEN_SOURCE=600 )
ELSEIF ( CMAKE_SYSTEM_NAME STREQUAL "SunOS" )
LIST ( APPEND SYSFLAGS -D__EXTENSIONS__ -D_REENTRANT -D_XOPEN_SOURCE=600 )
ELSEIF ( CMAKE_SYSTEM_NAME STREQUAL "AIX" )
LIST ( APPEND SYSFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=600 -D_USE_IRS )
ELSEIF ( CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" )
# Don't define _XOPEN_SOURCE on FreeBSD, it actually reduces visibility instead of increasing it
ELSEIF ( WIN32 )
LIST ( APPEND SYSFLAGS -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WIN32_WINNT=0x0600 )
ENDIF ( )
ADD_DEFINITIONS ( ${ SYSFLAGS } )
# Tell C-Ares about libraries to depend on
IF ( HAVE_LIBRESOLV )
LIST ( APPEND CARES_DEPENDENT_LIBS resolv )
ENDIF ( )
IF ( HAVE_LIBNSL )
LIST ( APPEND CARES_DEPENDENT_LIBS nsl )
ENDIF ( )
IF ( HAVE_LIBSOCKET )
LIST ( APPEND CARES_DEPENDENT_LIBS socket )
ENDIF ( )
IF ( HAVE_LIBRT )
LIST ( APPEND CARES_DEPENDENT_LIBS rt )
ENDIF ( )
IF ( WIN32 )
LIST ( APPEND CARES_DEPENDENT_LIBS ws2_32 Advapi32 )
ENDIF ( )
# When checking for symbols, we need to make sure we set the proper
# headers, libraries, and definitions for the detection to work properly
# CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES, and
# CMAKE_EXTRA_INCLUDE_FILES. When we're done with the detection, we'll
# unset them.
SET ( CMAKE_REQUIRED_DEFINITIONS ${ SYSFLAGS } )
LIST ( APPEND CMAKE_REQUIRED_LIBRARIES ${ CARES_DEPENDENT_LIBS } )
MACRO ( CARES_EXTRAINCLUDE_IFSET var include )
IF ( ${ var } )
LIST ( APPEND CMAKE_EXTRA_INCLUDE_FILES ${ include } )
ENDIF ( )
ENDMACRO ( )
CARES_EXTRAINCLUDE_IFSET ( HAVE_STDBOOL_H stdbool.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SYS_TYPES_H sys/types.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_ARPA_INET_H arpa/inet.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_ARPA_NAMESER_H arpa/nameser.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_NETDB_H netdb.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_NET_IF_H net/if.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_NETINET_IN_H netinet/in.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_NETINET_TCP_H netinet/tcp.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SIGNAL_H signal.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_STDLIB_H stdlib.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_STRING_H string.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_STRINGS_H strings.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SYS_IOCTL_H sys/ioctl.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SYS_SELECT_H sys/select.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SYS_SOCKET_H sys/socket.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SYS_TIME_H sys/time.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_SYS_UIO_H sys/uio.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_TIME_H time.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_FCNTL_H fcntl.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_UNISTD_H unistd.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_WINSOCK2_H winsock2.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_WS2TCPIP_H ws2tcpip.h )
CARES_EXTRAINCLUDE_IFSET ( HAVE_WINDOWS_H windows.h )
# Check Types
# CHECK_TYPE_SIZE can't be used to see if a type exists because on Apple when
# building multi-arch, it will throw an error. So we need to wrap
# CHECK_C_SOURCE_COMPILES for our tests.
MACRO ( CARES_TYPE_EXISTS type var )
SET ( _CARES_C_SOURCE "
#include <stdio.h>
#include <stdlib.h>
" )
FOREACH ( _C_HEADER ${ CMAKE_EXTRA_INCLUDE_FILES } )
SET ( _CARES_C_SOURCE " ${ _CARES_C_SOURCE }
#include <${_C_HEADER}>")
ENDFOREACH ( _C_HEADER )
SET ( _CARES_C_SOURCE " ${ _CARES_C_SOURCE }
i n t main ( ) {
$ { t y p e } v a r _ e x i s t s ;
( v o i d ) v a r _ e x i s t s ;
r e t u r n 0 ;
}
" )
CHECK_C_SOURCE_COMPILES ( "${_CARES_C_SOURCE}" ${ var } )
ENDMACRO ( )
CARES_TYPE_EXISTS ( socklen_t HAVE_SOCKLEN_T )
CARES_TYPE_EXISTS ( SOCKET HAVE_TYPE_SOCKET )
CARES_TYPE_EXISTS ( bool HAVE_BOOL_T )
CARES_TYPE_EXISTS ( ssize_t HAVE_SSIZE_T )
CARES_TYPE_EXISTS ( "long long" HAVE_LONGLONG )
CARES_TYPE_EXISTS ( sig_atomic_t HAVE_SIG_ATOMIC_T )
CARES_TYPE_EXISTS ( "struct addrinfo" HAVE_STRUCT_ADDRINFO )
CARES_TYPE_EXISTS ( "struct in6_addr" HAVE_STRUCT_IN6_ADDR )
CARES_TYPE_EXISTS ( "struct sockaddr_in6" HAVE_STRUCT_SOCKADDR_IN6 )
CARES_TYPE_EXISTS ( "struct sockaddr_storage" HAVE_STRUCT_SOCKADDR_STORAGE )
CARES_TYPE_EXISTS ( "struct timeval" HAVE_STRUCT_TIMEVAL )
# Check for preprocessor defines
CHECK_SYMBOL_EXISTS ( AF_INET6 "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_AF_INET6 )
CHECK_SYMBOL_EXISTS ( O_NONBLOCK "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_O_NONBLOCK )
CHECK_SYMBOL_EXISTS ( FIONBIO "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FIONBIO )
CHECK_SYMBOL_EXISTS ( SIOCGIFADDR "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTL_SIOCGIFADDR )
CHECK_SYMBOL_EXISTS ( MSG_NOSIGNAL "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_MSG_NOSIGNAL )
CHECK_SYMBOL_EXISTS ( PF_INET6 "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_PF_INET6 )
CHECK_SYMBOL_EXISTS ( SO_NONBLOCK "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SO_NONBLOCK )
# XCode v8 bug: iOS when targeting less than v10, or MacOS when targeting less than v10.12 will
# say clock_gettime exists, it is a weak symbol that only exists in iOS10/MacOS10.12 and will
# cause a crash at runtime when running on older versions. Skip finding CLOCK_MONOTONIC on older
# OS's.
IF ( ( NOT APPLE ) OR IOS_V10 OR MACOS_V1012 )
CHECK_SYMBOL_EXISTS ( CLOCK_MONOTONIC "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOCK_GETTIME_MONOTONIC )
ENDIF ( )
CHECK_STRUCT_HAS_MEMBER ( "struct sockaddr_in6" sin6_scope_id "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID LANGUAGE C )
# Check for "LL" numeric suffix support
CHECK_C_SOURCE_COMPILES ( "int main() { int n=1234LL; return 0; }" HAVE_LL )
CHECK_SYMBOL_EXISTS ( bitncmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_BITNCMP )
CHECK_SYMBOL_EXISTS ( closesocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET )
CHECK_SYMBOL_EXISTS ( CloseSocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET_CAMEL )
CHECK_SYMBOL_EXISTS ( connect "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONNECT )
CHECK_SYMBOL_EXISTS ( fcntl "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FCNTL )
CHECK_SYMBOL_EXISTS ( freeaddrinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FREEADDRINFO )
CHECK_SYMBOL_EXISTS ( getaddrinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETADDRINFO )
CHECK_SYMBOL_EXISTS ( getenv "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETENV )
CHECK_SYMBOL_EXISTS ( gethostbyaddr "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYADDR )
CHECK_SYMBOL_EXISTS ( gethostbyname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYNAME )
CHECK_SYMBOL_EXISTS ( gethostname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTNAME )
CHECK_SYMBOL_EXISTS ( getnameinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETNAMEINFO )
CHECK_SYMBOL_EXISTS ( getservbyport_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYPORT_R )
CHECK_SYMBOL_EXISTS ( getservbyname_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYNAME_R )
CHECK_SYMBOL_EXISTS ( gettimeofday "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETTIMEOFDAY )
CHECK_SYMBOL_EXISTS ( if_indextoname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_INDEXTONAME )
CHECK_SYMBOL_EXISTS ( inet_net_pton "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NET_PTON )
IF ( NOT WIN32 )
# Disabled on Windows, because these functions are only really supported on Windows
# Vista or newer (_WIN32_WINNT >= 0x0600). Older versions of Windows may provide
# them as experimental non-working features, so we have to disable them manually.
CHECK_SYMBOL_EXISTS ( inet_ntop "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NTOP )
CHECK_SYMBOL_EXISTS ( inet_pton "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_PTON )
ENDIF ( )
CHECK_SYMBOL_EXISTS ( ioctl "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTL )
CHECK_SYMBOL_EXISTS ( ioctlsocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTLSOCKET )
CHECK_SYMBOL_EXISTS ( IoctlSocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTLSOCKET_CAMEL )
CHECK_SYMBOL_EXISTS ( recv "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_RECV )
CHECK_SYMBOL_EXISTS ( recvfrom "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_RECVFROM )
CHECK_SYMBOL_EXISTS ( send "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SEND )
CHECK_SYMBOL_EXISTS ( setsockopt "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SETSOCKOPT )
CHECK_SYMBOL_EXISTS ( socket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKET )
CHECK_SYMBOL_EXISTS ( strcasecmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRCASECMP )
CHECK_SYMBOL_EXISTS ( strcmpi "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRCMPI )
CHECK_SYMBOL_EXISTS ( strdup "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRDUP )
CHECK_SYMBOL_EXISTS ( stricmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRICMP )
CHECK_SYMBOL_EXISTS ( strncasecmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCASECMP )
CHECK_SYMBOL_EXISTS ( strncmpi "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCMPI )
CHECK_SYMBOL_EXISTS ( strnicmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNICMP )
CHECK_SYMBOL_EXISTS ( writev "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_WRITEV )
# On Android, the system headers may define __system_property_get(), but excluded
# from libc. We need to perform a link test instead of a header/symbol test.
CHECK_FUNCTION_EXISTS ( __system_property_get HAVE___SYSTEM_PROPERTY_GET )
# Unset temporary data
SET ( CMAKE_EXTRA_INCLUDE_FILES )
SET ( CMAKE_REQUIRED_DEFINITIONS )
SET ( CMAKE_REQUIRED_LIBRARIES )
################################################################################
# recv, recvfrom, send, getnameinfo, gethostname
# ARGUMENTS AND RETURN VALUES
#
# The AutoTools build tries to be really thorough here. So much so that it
# takes forever. We really don't want to do that. Lets make some educated
# guesses based on datatypes we have available, and for others, use some 'sane'
# defaults. This should be much quicker and nearly as accurate ... and even
# if not, it probably won't matter in the least.
IF ( HAVE_SSIZE_T AND HAVE_SOCKLEN_T )
# If we have ssize_t and socklen_t, the API is usually sane and uses ssize_t and size_t for lengths
SET ( RECVFROM_TYPE_RETV ssize_t )
SET ( RECVFROM_TYPE_ARG3 size_t )
ELSE ( )
SET ( RECVFROM_TYPE_RETV int )
SET ( RECVFROM_TYPE_ARG3 int )
ENDIF ( )
IF ( HAVE_TYPE_SOCKET )
# If the SOCKET type is defined, it uses socket ... should be windows only
SET ( RECVFROM_TYPE_ARG1 SOCKET )
ELSE ( )
SET ( RECVFROM_TYPE_ARG1 int )
ENDIF ( )
IF ( HAVE_SOCKLEN_T )
# If we have socklen_t the APIs pretty much always actually use it
SET ( RECVFROM_TYPE_ARG6 "socklen_t *" )
SET ( GETNAMEINFO_TYPE_ARG2 socklen_t )
SET ( GETNAMEINFO_TYPE_ARG46 socklen_t )
ELSE ( )
SET ( RECVFROM_TYPE_ARG6 "int *" )
SET ( GETNAMEINFO_TYPE_ARG2 int )
SET ( GETNAMEINFO_TYPE_ARG46 int )
ENDIF ( )
IF ( WIN32 )
SET ( RECV_TYPE_ARG2 "char *" )
ELSE ( )
SET ( RECV_TYPE_ARG2 "void *" )
ENDIF ( )
# Functions are typically consistent so the equivalent fields map ... equivalently
SET ( RECV_TYPE_RETV ${ RECVFROM_TYPE_RETV } )
SET ( SEND_TYPE_RETV ${ RECVFROM_TYPE_RETV } )
SET ( RECV_TYPE_ARG1 ${ RECVFROM_TYPE_ARG1 } )
SET ( RECVFROM_TYPE_ARG2 ${ RECV_TYPE_ARG2 } )
SET ( SEND_TYPE_ARG1 ${ RECVFROM_TYPE_ARG1 } )
SET ( RECV_TYPE_ARG3 ${ RECVFROM_TYPE_ARG3 } )
SET ( SEND_TYPE_ARG3 ${ RECVFROM_TYPE_ARG3 } )
SET ( GETHOSTNAME_TYPE_ARG2 ${ RECVFROM_TYPE_ARG3 } )
# These should always be "sane" values to use always
SET ( RECVFROM_QUAL_ARG5 )
SET ( RECVFROM_TYPE_ARG4 int )
SET ( RECVFROM_TYPE_ARG5 "struct sockaddr *" )
SET ( RECV_TYPE_ARG4 int )
SET ( GETNAMEINFO_TYPE_ARG1 "struct sockaddr *" )
SET ( GETNAMEINFO_TYPE_ARG7 int )
SET ( SEND_TYPE_ARG2 "void *" )
SET ( SEND_TYPE_ARG4 int )
################################################################################
# HAVE_CXX11 ??
# HAVE_SIG_ATOMIC_T_VOLATILE ??
# Set a few variables by hand that C-Ares wants, logically, based on detection
# data.
IF ( HAVE_SOCKLEN_T )
Set ( CARES_TYPEOF_ARES_SOCKLEN_T "socklen_t" )
ELSE ( )
Set ( CARES_TYPEOF_ARES_SOCKLEN_T "int" )
ENDIF ( )
IF ( HAVE_SSIZE_T )
Set ( CARES_TYPEOF_ARES_SSIZE_T "ssize_t" )
ELSE ( )
IF ( WIN32 )
IF ( "${CMAKE_SIZEOF_VOID_P}" EQUAL "8" )
Set ( CARES_TYPEOF_ARES_SSIZE_T "__int64" )
ELSE ( )
Set ( CARES_TYPEOF_ARES_SSIZE_T "int" )
ENDIF ( )
ELSE ( )
Set ( CARES_TYPEOF_ARES_SSIZE_T "long" )
ENDIF ( )
ENDIF ( )
IF ( HAVE_FCNTL AND HAVE_O_NONBLOCK )
SET ( HAVE_FCNTL_O_NONBLOCK 1 )
ENDIF ( )
IF ( HAVE_IOCTL AND HAVE_FIONBIO )
SET ( HAVE_IOCTL_FIONBIO 1 )
ENDIF ( )
IF ( HAVE_IOCTLSOCKET AND HAVE_FIONBIO )
SET ( HAVE_IOCTLSOCKET_FIONBIO 1 )
ENDIF ( )
IF ( HAVE_IOCTLSOCKET_CAMEL AND HAVE_FIONBIO )
SET ( HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 )
ENDIF ( )
IF ( HAVE_GETADDRINFO )
IF ( CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " H P U X " O R
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " N e t B S D " O R
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " S u n O S " O R
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " F r e e B S D " O R
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " A I X " O R
WIN32 )
SET ( HAVE_GETADDRINFO_THREADSAFE 1 )
ENDIF ( )
ENDIF ( )
IF ( HAVE_TIME_H AND HAVE_SYS_TIME_H )
SET ( TIME_WITH_SYS_TIME 1 )
ENDIF ( )
IF ( HAVE_GETSERVBYPORT_R )
# TODO : Should probably autodetect
IF ( CMAKE_SYSTEM_NAME STREQUAL "SunOS" )
SET ( GETSERVBYPORT_R_ARGS 5 )
ELSEIF ( CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " O p e n B S D " )
SET ( GETSERVBYPORT_R_ARGS 4 )
ELSE ( )
# Probably linux
SET ( GETSERVBYPORT_R_ARGS 6 )
ENDIF ( )
ENDIF ( )
IF ( HAVE_GETSERVBYNAME_R )
# TODO : Should probably autodetect
IF ( CMAKE_SYSTEM_NAME STREQUAL "SunOS" )
SET ( GETSERVBYNAME_R_ARGS 5 )
ELSEIF ( CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
C M A K E _ S Y S T E M _ N A M E S T R E Q U A L " O p e n B S D " )
SET ( GETSERVBYNAME_R_ARGS 4 )
ELSE ( )
# Probably linux
SET ( GETSERVBYNAME_R_ARGS 6 )
ENDIF ( )
ENDIF ( )
# Set some aliases used for ares_build.h
IF ( HAVE_SYS_TYPES_H )
SET ( CARES_HAVE_SYS_TYPES_H 1 )
ENDIF ( )
IF ( HAVE_SYS_SOCKET_H )
SET ( CARES_HAVE_SYS_SOCKET_H 1 )
ENDIF ( )
IF ( HAVE_WS2TCPIP_H )
SET ( CARES_HAVE_WS2TCPIP_H 1 )
ENDIF ( )
IF ( HAVE_WINSOCK2_H )
SET ( CARES_HAVE_WINSOCK2_H 1 )
ENDIF ( )
IF ( HAVE_WINDOWS_H )
SET ( CARES_HAVE_WINDOWS_H 1 )
ENDIF ( )
# Record toplevel CMakeLists.txt path
set ( CARES_TOPLEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}" )
# TRANSFORM_MAKEFILE_INC
#
# This function consumes the "Makefile.inc" autotools file, and converts it into
# "Makefile.inc.cmake", a cmake include file; transforming this:
#
# CSOURCES = ares__close_sockets.c \
# ares__get_hostent.c \
# ares__read_line.c \
# ...
#
# into this:
#
# SET (CSOURCES
# ares__close_sockets.c
# ares__get_hostent.c
# ares__read_line.c
# ...
function ( TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE )
file ( READ ${ INPUT_FILE } MAKEFILE_INC_TEXT )
string ( REPLACE "$(top_srcdir)" "\${PROJECT_SOURCE_DIR}" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } )
string ( REPLACE "$(top_builddir)" "\${PROJECT_BINARY_DIR}" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } )
string ( REGEX REPLACE "\\\\\n" "ß!ß" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } )
string ( REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } )
string ( REPLACE "ß!ß" "\n" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } )
string ( REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } ) # Replace $() with ${}
string ( REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${ MAKEFILE_INC_TEXT } ) # Replace @@ with ${}, even if that may not be read by CMake scripts.
file ( WRITE ${ OUTPUT_FILE } ${ MAKEFILE_INC_TEXT } )
endfunction ( )
# Directory for includes
ADD_SUBDIRECTORY ( include )
# Directory for lib and tools
ADD_SUBDIRECTORY ( src )
# Docs
ADD_SUBDIRECTORY ( docs )
# Tests
IF ( CARES_BUILD_TESTS OR CARES_BUILD_CONTAINER_TESTS )
ENABLE_TESTING ( )
ADD_SUBDIRECTORY ( test )
ENDIF ( )
# Export targets
IF ( CARES_INSTALL )
SET ( CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" )
INCLUDE ( CMakePackageConfigHelpers )
CONFIGURE_PACKAGE_CONFIG_FILE ( ${ PROJECT_NAME } -config.cmake.in ${ PROJECT_NAME } -config.cmake
I N S T A L L _ D E S T I N A T I O N $ { C M A K E C O N F I G _ I N S T A L L _ D I R }
P A T H _ V A R S C M A K E _ I N S T A L L _ I N C L U D E D I R
N O _ C H E C K _ R E Q U I R E D _ C O M P O N E N T S _ M A C R O
)
WRITE_BASIC_PACKAGE_VERSION_FILE ( ${ PROJECT_NAME } -config-version.cmake VERSION "${CARES_VERSION}" COMPATIBILITY SameMajorVersion )
INSTALL ( EXPORT ${ PROJECT_NAME } -targets COMPONENT Devel DESTINATION ${ CMAKECONFIG_INSTALL_DIR } NAMESPACE ${ PROJECT_NAME } :: )
INSTALL ( FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" COMPONENT Devel DESTINATION ${ CMAKECONFIG_INSTALL_DIR } )
# pkgconfig support
IF ( NOT CARES_SHARED )
SET ( CPPFLAG_CARES_STATICLIB "-DCARES_STATICLIB" )
FOREACH ( LIB ${ CARES_DEPENDENT_LIBS } )
SET ( CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}" )
ENDFOREACH ( )
ENDIF ( )
CONFIGURE_FILE ( "libcares.pc.cmake" "libcares.pc" @ONLY )
INSTALL ( FILES "${CMAKE_CURRENT_BINARY_DIR}/libcares.pc" COMPONENT Devel DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" )
ENDIF ( )
# Legacy chain-building variables (provided for compatibility with old code).
# Don't use these, external code should be updated to refer to the aliases directly (e.g., Cares::cares).
SET ( CARES_FOUND 1 CACHE INTERNAL "CARES LIBRARY FOUND" )
SET ( CARES_LIBRARIES ${ PROJECT_NAME } ::cares CACHE INTERNAL "CARES LIBRARIES" )
IF ( CARES_INSTALL )
# Package creation
set ( CPACK_PACKAGE_NAME ${ PROJECT_NAME } )
set ( CPACK_PACKAGE_VENDOR "Daniel Stenberg" ) # Github project owner
set ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "A C library for asynchronous DNS requests" )
set ( CPACK_PACKAGE_HOMEPAGE_URL "https://c-ares.haxx.se/" )
set ( CPACK_PACKAGE_CONTACT "https://c-ares.haxx.se/" )
set ( CPACK_PACKAGE_VERSION_MAJOR ${ PROJECT_VERSION_MAJOR } )
set ( CPACK_PACKAGE_VERSION_MINOR ${ PROJECT_VERSION_MINOR } )
set ( CPACK_PACKAGE_VERSION_PATCH ${ PROJECT_VERSION_PATCH } )
set ( CPACK_PACKAGE_VERSION ${ CPACK_PACKAGE_VERSION_MAJOR } . ${ CPACK_PACKAGE_VERSION_MINOR } . ${ CPACK_PACKAGE_VERSION_PATCH } )
set ( CPACK_PACKAGE_INSTALL_DIRECTORY ${ PROJECT_NAME } )
set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md" )
set ( CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md" )
set ( CPACK_COMPONENT_Library_DISPLAY_NAME "c-ares Library" )
set ( CPACK_COMPONENT_Library_DESCRIPTION "The c-ares binary library." )
set ( CPACK_COMPONENT_Library_REQUIRED 1 )
set ( CPACK_COMPONENT_Devel_DISPLAY_NAME "c-ares Development Files" )
set ( CPACK_COMPONENT_Devel_DESCRIPTION "Development files for compiling against c-ares." )
set ( CPACK_COMPONENT_Devel_REQUIRED 0 )
IF ( CARES_BUILD_TOOLS )
set ( CPACK_COMPONENT_Tools_DISPLAY_NAME "c-ares Tools" )
set ( CPACK_COMPONENT_Tools_DESCRIPTION "Tools for using c-ares." )
set ( CPACK_COMPONENT_Tools_REQUIRED 0 )
ENDIF ( )
if ( ${ CMAKE_SYSTEM_NAME } STREQUAL "Linux" )
if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" )
# Note: the architecture should default to the local architecture, but it
# in fact comes up empty. We call `uname -m` to ask the kernel instead.
EXECUTE_PROCESS ( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE )
endif ( )
set ( CPACK_INCLUDE_TOPLEVEL_DIRECTORY 1 )
set ( CPACK_PACKAGE_RELEASE 1 )
# RPM - https://cmake.org/cmake/help/latest/cpack_gen/rpm.html
set ( CPACK_RPM_PACKAGE_RELEASE ${ CPACK_PACKAGE_RELEASE } )
set ( CPACK_RPM_PACKAGE_ARCHITECTURE ${ CPACK_PACKAGE_ARCHITECTURE } )
set ( CPACK_RPM_PACKAGE_DESCRIPTION ${ CPACK_PACKAGE_DESCRIPTION_SUMMARY } )
set ( CPACK_RPM_PACKAGE_URL ${ CPACK_PACKAGE_HOMEPAGE_URL } )
set ( CPACK_RPM_PACKAGE_LICENSE "MIT" )
set ( CPACK_RPM_COMPONENT_INSTALL 1 )
set ( CPACK_RPM_COMPRESSION_TYPE "xz" )
set ( CPACK_RPM_PACKAGE_AUTOPROV 1 )
set ( CPACK_RPM_Library_PACKAGE_SUMMARY ${ CPACK_COMPONENT_Library_DESCRIPTION } )
set ( CPACK_RPM_Library_PACKAGE_ARCHITECTURE ${ CPACK_RPM_PACKAGE_ARCHITECTURE } )
set ( CPACK_RPM_Library_PACKAGE_NAME "libcares${CARES_LIB_VERSION_MAJOR}" )
set ( CPACK_RPM_Library_FILE_NAME "RPM-DEFAULT" )
set ( CPACK_RPM_Devel_PACKAGE_REQUIRES "cmake >= ${CMAKE_MINIMUM_REQUIRED_VERSION}, ${CPACK_RPM_Library_PACKAGE_NAME} >= ${CPACK_PACKAGE_VERSION}" )
set ( CPACK_RPM_Devel_PACKAGE_SUMMARY ${ CPACK_COMPONENT_Devel_DESCRIPTION } )
set ( CPACK_RPM_Devel_PACKAGE_ARCHITECTURE ${ CPACK_RPM_PACKAGE_ARCHITECTURE } )
set ( CPACK_RPM_Devel_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-devel" )
set ( CPACK_RPM_Devel_FILE_NAME "RPM-DEFAULT" )
IF ( CARES_BUILD_TOOLS )
set ( CPACK_RPM_Tools_PACKAGE_REQUIRES "${CPACK_RPM_Library_PACKAGE_NAME} >= ${CPACK_PACKAGE_VERSION}" )
set ( CPACK_RPM_Tools_PACKAGE_SUMMARY ${ CPACK_COMPONENT_Tools_DESCRIPTION } )
set ( CPACK_RPM_Tools_PACKAGE_ARCHITECTURE ${ CPACK_RPM_PACKAGE_ARCHITECTURE } )
set ( CPACK_RPM_Tools_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-tools" )
set ( CPACK_RPM_Tools_FILE_NAME "RPM-DEFAULT" )
ENDIF ( )
# DEB - https://cmake.org/cmake/help/latest/cpack_gen/deb.html
set ( CPACK_DEBIAN_PACKAGE_RELEASE ${ CPACK_PACKAGE_RELEASE } )
set ( CPACK_DEBIAN_PACKAGE_HOMEPAGE ${ CPACK_PACKAGE_HOMEPAGE_URL } )
set ( CPACK_DEB_COMPONENT_INSTALL 1 )
set ( CPACK_DEBIAN_COMPRESSION_TYPE "xz" )
set ( CPACK_DEBIAN_PACKAGE_SHLIBDEPS 1 )
if ( ${ CPACK_PACKAGE_ARCHITECTURE } STREQUAL "x86_64" )
set ( CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64" ) # DEB doesn't always use the kernel's arch name
else ( )
set ( CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${ CPACK_PACKAGE_ARCHITECTURE } )
endif ( )
set ( CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT" ) # Use default naming scheme
set ( CPACK_DEBIAN_LIBRARY_PACKAGE_NAME ${ CPACK_RPM_Library_PACKAGE_NAME } )
set ( CPACK_DEBIAN_DEVEL_PACKAGE_DEPENDS "cmake (>= ${CMAKE_MINIMUM_REQUIRED_VERSION}), ${CPACK_DEBIAN_LIBRARY_PACKAGE_NAME} (>= ${CPACK_PACKAGE_VERSION})" )
set ( CPACK_DEBIAN_DEVEL_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev" )
IF ( CARES_BUILD_TOOLS )
set ( CPACK_DEBIAN_TOOLS_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-tools" )
set ( CPACK_DEBIAN_TOOLS_PACKAGE_SHLIBDEPS OFF ) # dpkg-shlibdeps can't find the libs we built
set ( CPACK_DEBIAN_TOOLS_PACKAGE_DEPENDS "${CPACK_DEBIAN_LIBRARY_PACKAGE_NAME} (>= ${CPACK_PACKAGE_VERSION})" )
ENDIF ( )
elseif ( ${ CMAKE_HOST_WIN32 } )
set ( CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON )
set ( CPACK_NSIS_DISPLAY_NAME ${ PROJECT_NAME } )
set ( CPACK_NSIS_PACKAGE_NAME ${ PROJECT_NAME } )
set ( CPACK_NSIS_URL_INFO_ABOUT ${ CPACK_PACKAGE_HOMEPAGE_URL } )
endif ( )
# This must always be last!
include ( CPack )
ENDIF ( )