• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1CMAKE_MINIMUM_REQUIRED (VERSION 3.1.0)
2
3INCLUDE (CheckIncludeFiles)
4INCLUDE (CheckTypeSize)
5INCLUDE (CheckFunctionExists)
6INCLUDE (CheckSymbolExists)
7INCLUDE (CheckCSourceCompiles)
8INCLUDE (CheckStructHasMember)
9INCLUDE (CheckLibraryExists)
10
11PROJECT (c-ares LANGUAGES C VERSION "1.16.1" )
12
13# Set this version before release
14SET (CARES_VERSION "1.16.1")
15
16INCLUDE (GNUInstallDirs) # include this *AFTER* PROJECT(), otherwise paths are wrong.
17
18# This is for libtool compatibility, and specified in a form that is easily
19# translatable from libtool (even if the actual form doesn't make sense).
20# For instance, in an autotools project, in Makefile.am there is a line that
21# contains something like:
22#     -version-info 4:0:2
23# This breaks down into sections of current:revision:age
24# This then generates a version of  "(current-age).age.revision"  with an
25# interface version of "(current-age)"
26# For example, a version of 4:0:2 would generate output such as:
27#    libname.so   -> libname.so.2
28#    libname.so.2 -> libname.so.2.2.0
29SET (CARES_LIB_VERSIONINFO "6:1:4")
30
31
32OPTION (CARES_STATIC     "Build as a static library"                                             OFF)
33OPTION (CARES_SHARED     "Build as a shared library"                                             ON)
34OPTION (CARES_INSTALL    "Create installation targets (chain builders may want to disable this)" ON)
35OPTION (CARES_STATIC_PIC "Build the static library as PIC (position independent)"                OFF)
36OPTION (CARES_BUILD_TESTS "Build and run tests"                                                  OFF)
37OPTION (CARES_BUILD_CONTAINER_TESTS "Build and run container tests (implies CARES_BUILD_TESTS, Linux only)" OFF)
38OPTION (CARES_BUILD_TOOLS "Build tools"                                                          ON)
39
40# Tests require static to be enabled
41IF (CARES_BUILD_TESTS)
42	SET (CARES_STATIC ON)
43	SET (CARES_STATIC_PIC ON)
44ENDIF ()
45
46# allow linking against the static runtime library in msvc
47IF (MSVC)
48	OPTION (CARES_MSVC_STATIC_RUNTIME "Link against the static runtime library" OFF)
49	IF (CARES_MSVC_STATIC_RUNTIME)
50		# CMAKE_CONFIGURATION_TYPES is empty on non-IDE generators (Ninja, NMake)
51		# and that's why we also use CMAKE_BUILD_TYPE to cover for those generators.
52		# For IDE generators, CMAKE_BUILD_TYPE is usually empty
53		FOREACH (config_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE})
54			STRING (TOUPPER ${config_type} upper_config_type)
55			SET (flag_var "CMAKE_C_FLAGS_${upper_config_type}")
56			IF (${flag_var} MATCHES "/MD")
57				STRING (REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
58			ENDIF ()
59		ENDFOREACH ()
60
61		# clean up
62		SET (upper_config_type)
63		SET (config_type)
64		SET (flag_var)
65	ENDIF ()
66ENDIF ()
67
68# Keep build organized.
69SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
70SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
71SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
72SET (PACKAGE_DIRECTORY ${PROJECT_BINARY_DIR}/package)
73
74# Destinations for installing different kinds of targets (pass to install command).
75SET (TARGETS_INST_DEST
76	RUNTIME DESTINATION  ${CMAKE_INSTALL_BINDIR}
77	LIBRARY DESTINATION  ${CMAKE_INSTALL_LIBDIR}
78	ARCHIVE DESTINATION  ${CMAKE_INSTALL_LIBDIR}
79)
80
81# Function in Library
82# CHECK_LIBRARY_EXISTS can't be used as it will return true if the function
83# is found in a different dependent library.
84MACRO (CARES_FUNCTION_IN_LIBRARY func lib var)
85	CHECK_FUNCTION_EXISTS ("${func}" "_CARES_FUNC_IN_LIB_GLOBAL_${func}")
86	IF ("${_CARES_FUNC_IN_LIB_GLOBAL_${func}}")
87		SET (${var} FALSE)
88	ELSE ()
89		CHECK_LIBRARY_EXISTS ("${lib}" "${func}" "" ${var})
90	ENDIF ()
91ENDMACRO ()
92
93# Look for dependent/required libraries
94CARES_FUNCTION_IN_LIBRARY (res_servicename resolv HAVE_RES_SERVICENAME_IN_LIBRESOLV)
95IF (HAVE_RES_SERVICENAME_IN_LIBRESOLV)
96	SET (HAVE_LIBRESOLV 1)
97ENDIF ()
98
99IF (APPLE)
100	CHECK_C_SOURCE_COMPILES ("
101	#include <stdio.h>
102	#include <TargetConditionals.h>
103	int main() {
104#if TARGET_OS_IPHONE == 0
105#error Not an iPhone target
106#endif
107return 0;
108	}
109	"
110	IOS)
111
112	CHECK_C_SOURCE_COMPILES ("
113#include <stdio.h>
114#include <TargetConditionals.h>
115	int main() {
116#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
117#  error Not iOS v10
118#endif
119return 0;
120	}
121	"
122	IOS_V10)
123
124	CHECK_C_SOURCE_COMPILES ("
125#include <stdio.h>
126#include <AvailabilityMacros.h>
127#ifndef MAC_OS_X_VERSION_10_12
128#  define MAC_OS_X_VERSION_10_12 101200
129#endif
130	int main() {
131#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
132#  error Not MacOSX 10.12 or higher
133#endif
134return 0;
135	}
136	"
137	MACOS_V1012)
138ENDIF ()
139
140IF ((IOS OR APPLE) AND HAVE_LIBRESOLV)
141	SET (CARES_USE_LIBRESOLV 1)
142ENDIF()
143
144
145CARES_FUNCTION_IN_LIBRARY (gethostbyname nsl HAVE_LIBNSL)
146CARES_FUNCTION_IN_LIBRARY (gethostbyname socket HAVE_GHBN_LIBSOCKET)
147CARES_FUNCTION_IN_LIBRARY (socket socket HAVE_SOCKET_LIBSOCKET)
148IF (HAVE_GHBN_LIBSOCKET OR HAVE_SOCKET_LIBSOCKET)
149	SET(HAVE_LIBSOCKET TRUE)
150ENDIF ()
151CARES_FUNCTION_IN_LIBRARY (clock_gettime rt HAVE_LIBRT)
152
153
154# Look for necessary includes
155CHECK_INCLUDE_FILES (sys/types.h           HAVE_SYS_TYPES_H)
156CHECK_INCLUDE_FILES (sys/socket.h          HAVE_SYS_SOCKET_H)
157CHECK_INCLUDE_FILES (arpa/inet.h           HAVE_ARPA_INET_H)
158CHECK_INCLUDE_FILES (arpa/nameser_compat.h HAVE_ARPA_NAMESER_COMPAT_H)
159CHECK_INCLUDE_FILES (arpa/nameser.h        HAVE_ARPA_NAMESER_H)
160CHECK_INCLUDE_FILES (assert.h              HAVE_ASSERT_H)
161CHECK_INCLUDE_FILES (errno.h               HAVE_ERRNO_H)
162CHECK_INCLUDE_FILES (fcntl.h               HAVE_FCNTL_H)
163CHECK_INCLUDE_FILES (inttypes.h            HAVE_INTTYPES_H)
164CHECK_INCLUDE_FILES (limits.h              HAVE_LIMITS_H)
165CHECK_INCLUDE_FILES (malloc.h              HAVE_MALLOC_H)
166CHECK_INCLUDE_FILES (memory.h              HAVE_MEMORY_H)
167CHECK_INCLUDE_FILES (netdb.h               HAVE_NETDB_H)
168CHECK_INCLUDE_FILES (netinet/in.h          HAVE_NETINET_IN_H)
169CHECK_INCLUDE_FILES (netinet/tcp.h         HAVE_NETINET_TCP_H)
170CHECK_INCLUDE_FILES (net/if.h              HAVE_NET_IF_H)
171CHECK_INCLUDE_FILES (signal.h              HAVE_SIGNAL_H)
172CHECK_INCLUDE_FILES (socket.h              HAVE_SOCKET_H)
173CHECK_INCLUDE_FILES (stdbool.h             HAVE_STDBOOL_H)
174CHECK_INCLUDE_FILES (stdint.h              HAVE_STDINT_H)
175CHECK_INCLUDE_FILES (stdlib.h              HAVE_STDLIB_H)
176CHECK_INCLUDE_FILES (strings.h             HAVE_STRINGS_H)
177CHECK_INCLUDE_FILES (string.h              HAVE_STRING_H)
178CHECK_INCLUDE_FILES (stropts.h             HAVE_STROPTS_H)
179CHECK_INCLUDE_FILES (sys/ioctl.h           HAVE_SYS_IOCTL_H)
180CHECK_INCLUDE_FILES (sys/param.h           HAVE_SYS_PARAM_H)
181CHECK_INCLUDE_FILES (sys/select.h          HAVE_SYS_SELECT_H)
182CHECK_INCLUDE_FILES (sys/socket.h          HAVE_SYS_SOCKET_H)
183CHECK_INCLUDE_FILES (sys/stat.h            HAVE_SYS_STAT_H)
184CHECK_INCLUDE_FILES (sys/time.h            HAVE_SYS_TIME_H)
185CHECK_INCLUDE_FILES (sys/types.h           HAVE_SYS_TYPES_H)
186CHECK_INCLUDE_FILES (sys/uio.h             HAVE_SYS_UIO_H)
187CHECK_INCLUDE_FILES (time.h                HAVE_TIME_H)
188CHECK_INCLUDE_FILES (dlfcn.h               HAVE_DLFCN_H)
189CHECK_INCLUDE_FILES (unistd.h              HAVE_UNISTD_H)
190
191# Include order matters for these windows files.
192CHECK_INCLUDE_FILES ("winsock2.h;windows.h"            HAVE_WINSOCK2_H)
193CHECK_INCLUDE_FILES ("winsock2.h;ws2tcpip.h;windows.h" HAVE_WS2TCPIP_H)
194CHECK_INCLUDE_FILES ("winsock.h;windows.h"             HAVE_WINSOCK_H)
195CHECK_INCLUDE_FILES (windows.h                         HAVE_WINDOWS_H)
196
197
198# Set system-specific compiler flags
199IF (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
200	LIST (APPEND SYSFLAGS -D_DARWIN_C_SOURCE)
201ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Linux")
202	LIST (APPEND SYSFLAGS -D_GNU_SOURCE -D_POSIX_C_SOURCE=199309L -D_XOPEN_SOURCE=600)
203ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
204	LIST (APPEND SYSFLAGS -D__EXTENSIONS__ -D_REENTRANT -D_XOPEN_SOURCE=600)
205ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX")
206	LIST (APPEND SYSFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=600 -D_USE_IRS)
207ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
208	# Don't define _XOPEN_SOURCE on FreeBSD, it actually reduces visibility instead of increasing it
209ELSEIF (WIN32)
210	LIST (APPEND SYSFLAGS -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WIN32_WINNT=0x0600)
211ENDIF ()
212ADD_DEFINITIONS(${SYSFLAGS})
213
214
215
216# Tell C-Ares about libraries to depend on
217IF (HAVE_LIBRESOLV)
218	LIST (APPEND CARES_DEPENDENT_LIBS resolv)
219ENDIF ()
220IF (HAVE_LIBNSL)
221	LIST (APPEND CARES_DEPENDENT_LIBS nsl)
222ENDIF ()
223IF (HAVE_LIBSOCKET)
224	LIST (APPEND CARES_DEPENDENT_LIBS socket)
225ENDIF ()
226IF (HAVE_LIBRT)
227	LIST (APPEND CARES_DEPENDENT_LIBS rt)
228ENDIF ()
229IF (WIN32)
230	LIST (APPEND CARES_DEPENDENT_LIBS ws2_32 Advapi32)
231ENDIF ()
232
233
234# When checking for symbols, we need to make sure we set the proper
235# headers, libraries, and definitions for the detection to work properly
236# CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES, and
237# CMAKE_EXTRA_INCLUDE_FILES.  When we're done with the detection, we'll
238# unset them.
239
240SET (CMAKE_REQUIRED_DEFINITIONS ${SYSFLAGS})
241LIST (APPEND CMAKE_REQUIRED_LIBRARIES ${CARES_DEPENDENT_LIBS})
242
243MACRO (CARES_EXTRAINCLUDE_IFSET var include)
244	IF (${var})
245		LIST (APPEND CMAKE_EXTRA_INCLUDE_FILES ${include})
246	ENDIF ()
247ENDMACRO ()
248
249CARES_EXTRAINCLUDE_IFSET (HAVE_STDBOOL_H      stdbool.h)
250CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_TYPES_H    sys/types.h)
251CARES_EXTRAINCLUDE_IFSET (HAVE_ARPA_INET_H    arpa/inet.h)
252CARES_EXTRAINCLUDE_IFSET (HAVE_ARPA_NAMESER_H arpa/nameser.h)
253CARES_EXTRAINCLUDE_IFSET (HAVE_NETDB_H        netdb.h)
254CARES_EXTRAINCLUDE_IFSET (HAVE_NET_IF_H       net/if.h)
255CARES_EXTRAINCLUDE_IFSET (HAVE_NETINET_IN_H   netinet/in.h)
256CARES_EXTRAINCLUDE_IFSET (HAVE_NETINET_TCP_H  netinet/tcp.h)
257CARES_EXTRAINCLUDE_IFSET (HAVE_SIGNAL_H       signal.h)
258CARES_EXTRAINCLUDE_IFSET (HAVE_STDLIB_H       stdlib.h)
259CARES_EXTRAINCLUDE_IFSET (HAVE_STRING_H       string.h)
260CARES_EXTRAINCLUDE_IFSET (HAVE_STRINGS_H      strings.h)
261CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_IOCTL_H    sys/ioctl.h)
262CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SELECT_H   sys/select.h)
263CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SOCKET_H   sys/socket.h)
264CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_TIME_H     sys/time.h)
265CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_UIO_H      sys/uio.h)
266CARES_EXTRAINCLUDE_IFSET (HAVE_TIME_H         time.h)
267CARES_EXTRAINCLUDE_IFSET (HAVE_FCNTL_H        fcntl.h)
268CARES_EXTRAINCLUDE_IFSET (HAVE_UNISTD_H       unistd.h)
269CARES_EXTRAINCLUDE_IFSET (HAVE_WINSOCK2_H     winsock2.h)
270CARES_EXTRAINCLUDE_IFSET (HAVE_WS2TCPIP_H     ws2tcpip.h)
271CARES_EXTRAINCLUDE_IFSET (HAVE_WINDOWS_H      windows.h)
272
273# Check Types
274# CHECK_TYPE_SIZE can't be used to see if a type exists because on Apple when
275# building multi-arch, it will throw an error.  So we need to wrap
276# CHECK_C_SOURCE_COMPILES for our tests.
277MACRO (CARES_TYPE_EXISTS type var)
278	SET(_CARES_C_SOURCE "
279		#include <stdio.h>
280		#include <stdlib.h>
281	")
282	FOREACH(_C_HEADER ${CMAKE_EXTRA_INCLUDE_FILES})
283		SET(_CARES_C_SOURCE "${_CARES_C_SOURCE}
284		#include <${_C_HEADER}>")
285	ENDFOREACH(_C_HEADER)
286
287	SET(_CARES_C_SOURCE "${_CARES_C_SOURCE}
288		int main() {
289			${type} var_exists;
290			(void)var_exists;
291			return 0;
292		}
293	")
294	CHECK_C_SOURCE_COMPILES ("${_CARES_C_SOURCE}" ${var})
295ENDMACRO ()
296
297CARES_TYPE_EXISTS (socklen_t                 HAVE_SOCKLEN_T)
298CARES_TYPE_EXISTS (SOCKET                    HAVE_TYPE_SOCKET)
299CARES_TYPE_EXISTS (bool                      HAVE_BOOL_T)
300CARES_TYPE_EXISTS (ssize_t                   HAVE_SSIZE_T)
301CARES_TYPE_EXISTS ("long long"               HAVE_LONGLONG)
302CARES_TYPE_EXISTS (sig_atomic_t              HAVE_SIG_ATOMIC_T)
303CARES_TYPE_EXISTS ("struct addrinfo"         HAVE_STRUCT_ADDRINFO)
304CARES_TYPE_EXISTS ("struct in6_addr"         HAVE_STRUCT_IN6_ADDR)
305CARES_TYPE_EXISTS ("struct sockaddr_in6"     HAVE_STRUCT_SOCKADDR_IN6)
306CARES_TYPE_EXISTS ("struct sockaddr_storage" HAVE_STRUCT_SOCKADDR_STORAGE)
307CARES_TYPE_EXISTS ("struct timeval"          HAVE_STRUCT_TIMEVAL)
308
309
310# Check for preprocessor defines
311CHECK_SYMBOL_EXISTS (AF_INET6        "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_AF_INET6)
312CHECK_SYMBOL_EXISTS (O_NONBLOCK      "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_O_NONBLOCK)
313CHECK_SYMBOL_EXISTS (FIONBIO         "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FIONBIO)
314CHECK_SYMBOL_EXISTS (SIOCGIFADDR     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTL_SIOCGIFADDR)
315CHECK_SYMBOL_EXISTS (MSG_NOSIGNAL    "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_MSG_NOSIGNAL)
316CHECK_SYMBOL_EXISTS (PF_INET6        "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_PF_INET6)
317CHECK_SYMBOL_EXISTS (SO_NONBLOCK     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SO_NONBLOCK)
318
319# XCode v8 bug: iOS when targeting less than v10, or MacOS when targeting less than v10.12 will
320# say clock_gettime exists, it is a weak symbol that only exists in iOS10/MacOS10.12 and will
321# cause a crash at runtime when running on older versions.  Skip finding CLOCK_MONOTONIC on older
322# OS's.
323IF ((NOT APPLE) OR IOS_V10 OR MACOS_V1012)
324	CHECK_SYMBOL_EXISTS (CLOCK_MONOTONIC "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOCK_GETTIME_MONOTONIC)
325ENDIF ()
326
327CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_scope_id "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID LANGUAGE C)
328
329# Check for "LL" numeric suffix support
330CHECK_C_SOURCE_COMPILES ("int main() { int n=1234LL; return 0; }" HAVE_LL)
331
332
333CHECK_SYMBOL_EXISTS (bitncmp         "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_BITNCMP)
334CHECK_SYMBOL_EXISTS (closesocket     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET)
335CHECK_SYMBOL_EXISTS (CloseSocket     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET_CAMEL)
336CHECK_SYMBOL_EXISTS (connect         "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONNECT)
337CHECK_SYMBOL_EXISTS (fcntl           "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FCNTL)
338CHECK_SYMBOL_EXISTS (freeaddrinfo    "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FREEADDRINFO)
339CHECK_SYMBOL_EXISTS (getaddrinfo     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETADDRINFO)
340CHECK_SYMBOL_EXISTS (getenv          "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETENV)
341CHECK_SYMBOL_EXISTS (gethostbyaddr   "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYADDR)
342CHECK_SYMBOL_EXISTS (gethostbyname   "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYNAME)
343CHECK_SYMBOL_EXISTS (gethostname     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTNAME)
344CHECK_SYMBOL_EXISTS (getnameinfo     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETNAMEINFO)
345CHECK_SYMBOL_EXISTS (getservbyport_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYPORT_R)
346CHECK_SYMBOL_EXISTS (getservbyname_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYNAME_R)
347CHECK_SYMBOL_EXISTS (gettimeofday    "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETTIMEOFDAY)
348CHECK_SYMBOL_EXISTS (if_indextoname  "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_INDEXTONAME)
349CHECK_SYMBOL_EXISTS (inet_net_pton   "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NET_PTON)
350IF (NOT WIN32)
351	# Disabled on Windows, because these functions are only really supported on Windows
352	# Vista or newer (_WIN32_WINNT >= 0x0600). Older versions of Windows may provide
353	# them as experimental non-working features, so we have to disable them manually.
354	CHECK_SYMBOL_EXISTS (inet_ntop       "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NTOP)
355	CHECK_SYMBOL_EXISTS (inet_pton       "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_PTON)
356ENDIF ()
357CHECK_SYMBOL_EXISTS (ioctl           "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTL)
358CHECK_SYMBOL_EXISTS (ioctlsocket     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTLSOCKET)
359CHECK_SYMBOL_EXISTS (IoctlSocket     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTLSOCKET_CAMEL)
360CHECK_SYMBOL_EXISTS (recv            "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_RECV)
361CHECK_SYMBOL_EXISTS (recvfrom        "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_RECVFROM)
362CHECK_SYMBOL_EXISTS (send            "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SEND)
363CHECK_SYMBOL_EXISTS (setsockopt      "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SETSOCKOPT)
364CHECK_SYMBOL_EXISTS (socket          "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKET)
365CHECK_SYMBOL_EXISTS (strcasecmp      "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRCASECMP)
366CHECK_SYMBOL_EXISTS (strcmpi         "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRCMPI)
367CHECK_SYMBOL_EXISTS (strdup          "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRDUP)
368CHECK_SYMBOL_EXISTS (stricmp         "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRICMP)
369CHECK_SYMBOL_EXISTS (strncasecmp     "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCASECMP)
370CHECK_SYMBOL_EXISTS (strncmpi        "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCMPI)
371CHECK_SYMBOL_EXISTS (strnicmp        "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNICMP)
372CHECK_SYMBOL_EXISTS (writev          "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_WRITEV)
373
374# On Android, the system headers may define __system_property_get(), but excluded
375# from libc.  We need to perform a link test instead of a header/symbol test.
376CHECK_FUNCTION_EXISTS (__system_property_get HAVE___SYSTEM_PROPERTY_GET)
377
378# Unset temporary data
379SET (CMAKE_EXTRA_INCLUDE_FILES)
380SET (CMAKE_REQUIRED_DEFINITIONS)
381SET (CMAKE_REQUIRED_LIBRARIES)
382
383
384################################################################################
385# recv, recvfrom, send, getnameinfo, gethostname
386# ARGUMENTS AND RETURN VALUES
387#
388# The AutoTools build tries to be really thorough here.  So much so that it
389# takes forever.  We really don't want to do that.  Lets make some educated
390# guesses based on datatypes we have available, and for others, use some 'sane'
391# defaults.  This should be much quicker and nearly as accurate ... and even
392# if not, it probably won't matter in the least.
393
394IF (HAVE_SSIZE_T AND HAVE_SOCKLEN_T)
395	# If we have ssize_t and socklen_t, the API is usually sane and uses ssize_t and size_t for lengths
396	SET (RECVFROM_TYPE_RETV ssize_t)
397	SET (RECVFROM_TYPE_ARG3 size_t)
398ELSE ()
399	SET (RECVFROM_TYPE_RETV int)
400	SET (RECVFROM_TYPE_ARG3 int)
401ENDIF ()
402
403IF (HAVE_TYPE_SOCKET)
404	# If the SOCKET type is defined, it uses socket ... should be windows only
405	SET (RECVFROM_TYPE_ARG1 SOCKET)
406ELSE ()
407	SET (RECVFROM_TYPE_ARG1 int)
408ENDIF()
409
410IF (HAVE_SOCKLEN_T)
411	# If we have socklen_t the APIs pretty much always actually use it
412	SET (RECVFROM_TYPE_ARG6 "socklen_t *")
413	SET (GETNAMEINFO_TYPE_ARG2 socklen_t)
414	SET (GETNAMEINFO_TYPE_ARG46 socklen_t)
415ELSE ()
416	SET (RECVFROM_TYPE_ARG6 "int *")
417	SET (GETNAMEINFO_TYPE_ARG2 int)
418	SET (GETNAMEINFO_TYPE_ARG46 int)
419ENDIF ()
420
421IF (WIN32)
422	SET (RECV_TYPE_ARG2 "char *")
423ELSE ()
424	SET (RECV_TYPE_ARG2 "void *")
425ENDIF ()
426
427# Functions are typically consistent so the equivalent fields map ... equivalently
428SET (RECV_TYPE_RETV ${RECVFROM_TYPE_RETV})
429SET (SEND_TYPE_RETV ${RECVFROM_TYPE_RETV})
430SET (RECV_TYPE_ARG1 ${RECVFROM_TYPE_ARG1})
431SET (RECVFROM_TYPE_ARG2 ${RECV_TYPE_ARG2})
432SET (SEND_TYPE_ARG1 ${RECVFROM_TYPE_ARG1})
433SET (RECV_TYPE_ARG3 ${RECVFROM_TYPE_ARG3})
434SET (SEND_TYPE_ARG3 ${RECVFROM_TYPE_ARG3})
435SET (GETHOSTNAME_TYPE_ARG2 ${RECVFROM_TYPE_ARG3})
436
437# These should always be "sane" values to use always
438SET (RECVFROM_QUAL_ARG5 )
439SET (RECVFROM_TYPE_ARG4 int)
440SET (RECVFROM_TYPE_ARG5 "struct sockaddr *")
441SET (RECV_TYPE_ARG4 int)
442SET (GETNAMEINFO_TYPE_ARG1 "struct sockaddr *")
443SET (GETNAMEINFO_TYPE_ARG7 int)
444SET (SEND_TYPE_ARG2 "void *")
445SET (SEND_TYPE_ARG4 int)
446################################################################################
447
448
449# HAVE_CXX11  ??
450# HAVE_SIG_ATOMIC_T_VOLATILE  ??
451
452
453# Set a few variables by hand that C-Ares wants, logically, based on detection
454# data.
455
456IF (HAVE_SOCKLEN_T)
457	Set (CARES_TYPEOF_ARES_SOCKLEN_T "socklen_t")
458ELSE ()
459	Set (CARES_TYPEOF_ARES_SOCKLEN_T "int")
460ENDIF ()
461
462IF (HAVE_SSIZE_T)
463	Set (CARES_TYPEOF_ARES_SSIZE_T "ssize_t")
464ELSE ()
465	IF (WIN32)
466		IF ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
467			Set (CARES_TYPEOF_ARES_SSIZE_T "__int64")
468		ELSE ()
469			Set (CARES_TYPEOF_ARES_SSIZE_T "int")
470		ENDIF ()
471	ELSE ()
472		Set (CARES_TYPEOF_ARES_SSIZE_T "long")
473	ENDIF ()
474ENDIF ()
475
476IF (HAVE_FCNTL AND HAVE_O_NONBLOCK)
477	SET (HAVE_FCNTL_O_NONBLOCK 1)
478ENDIF ()
479
480IF (HAVE_IOCTL AND HAVE_FIONBIO)
481	SET (HAVE_IOCTL_FIONBIO 1)
482ENDIF ()
483
484IF (HAVE_IOCTLSOCKET AND HAVE_FIONBIO)
485	SET (HAVE_IOCTLSOCKET_FIONBIO 1)
486ENDIF ()
487
488IF (HAVE_IOCTLSOCKET_CAMEL AND HAVE_FIONBIO)
489	SET (HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1)
490ENDIF ()
491
492IF (HAVE_GETADDRINFO)
493	IF (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
494		CMAKE_SYSTEM_NAME STREQUAL "HPUX" OR
495		CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
496		CMAKE_SYSTEM_NAME STREQUAL "SunOS" OR
497		CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
498		CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
499		WIN32)
500			SET (HAVE_GETADDRINFO_THREADSAFE 1)
501	ENDIF ()
502ENDIF ()
503
504IF (HAVE_TIME_H AND HAVE_SYS_TIME_H)
505	SET (TIME_WITH_SYS_TIME 1)
506ENDIF ()
507
508IF (HAVE_GETSERVBYPORT_R)
509	# TODO : Should probably autodetect
510	IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
511		SET (GETSERVBYPORT_R_ARGS 5)
512	ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
513		CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
514		SET (GETSERVBYPORT_R_ARGS 4)
515	ELSE ()
516		# Probably linux
517		SET (GETSERVBYPORT_R_ARGS 6)
518	ENDIF ()
519ENDIF ()
520
521IF (HAVE_GETSERVBYNAME_R)
522	# TODO : Should probably autodetect
523	IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
524		SET (GETSERVBYNAME_R_ARGS 5)
525	ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
526		CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
527		SET (GETSERVBYNAME_R_ARGS 4)
528	ELSE ()
529		# Probably linux
530		SET (GETSERVBYNAME_R_ARGS 6)
531	ENDIF ()
532ENDIF ()
533
534# Set some aliases used for ares_build.h
535IF (HAVE_SYS_TYPES_H)
536	SET (CARES_HAVE_SYS_TYPES_H 1)
537ENDIF ()
538IF (HAVE_SYS_SOCKET_H)
539	SET (CARES_HAVE_SYS_SOCKET_H 1)
540ENDIF()
541IF (HAVE_WS2TCPIP_H)
542	SET (CARES_HAVE_WS2TCPIP_H 1)
543ENDIF()
544IF (HAVE_WINSOCK2_H)
545	SET (CARES_HAVE_WINSOCK2_H 1)
546ENDIF()
547IF (HAVE_WINDOWS_H)
548	SET (CARES_HAVE_WINDOWS_H 1)
549ENDIF()
550
551# Write ares_build.h configuration file.  This is an installed file.
552CONFIGURE_FILE (ares_build.h.cmake ${PROJECT_BINARY_DIR}/ares_build.h)
553
554# Write ares_config.h configuration file.  This is used only for the build.
555CONFIGURE_FILE (ares_config.h.cmake ${PROJECT_BINARY_DIR}/ares_config.h)
556
557
558# TRANSFORM_MAKEFILE_INC
559#
560# This function consumes the "Makefile.inc" autotools file, and converts it into
561#  "Makefile.inc.cmake", a cmake include file; transforming this:
562#
563# CSOURCES = ares__close_sockets.c	\
564#   ares__get_hostent.c			\
565#   ares__read_line.c			\
566#   ...
567#
568#   into this:
569#
570# SET (CSOURCES
571# 	ares__close_sockets.c
572# 	ares__get_hostent.c
573# 	ares__read_line.c
574#	...
575function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
576	file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
577	string(REPLACE "$(top_srcdir)"   "\${PROJECT_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
578	string(REPLACE "$(top_builddir)" "\${PROJECT_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
579
580	string(REGEX REPLACE "\\\\\n" "ß!ß" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
581	string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
582	string(REPLACE "ß!ß" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
583
584	string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace $() with ${}
585	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.
586	file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
587endfunction()
588
589# run the function...
590transform_makefile_inc("Makefile.inc" "${PROJECT_BINARY_DIR}/Makefile.inc.cmake")
591include(${PROJECT_BINARY_DIR}/Makefile.inc.cmake)
592
593
594# Build the dynamic/shared library
595IF (CARES_SHARED)
596	ADD_LIBRARY (${PROJECT_NAME} SHARED ${CSOURCES})
597
598	# Convert CARES_LIB_VERSIONINFO libtool version format into VERSION and SOVERSION
599	# Convert from ":" separated into CMake list format using ";"
600	STRING (REPLACE ":" ";" CARES_LIB_VERSIONINFO ${CARES_LIB_VERSIONINFO})
601	LIST (GET CARES_LIB_VERSIONINFO 0 CARES_LIB_VERSION_CURRENT)
602	LIST (GET CARES_LIB_VERSIONINFO 1 CARES_LIB_VERSION_REVISION)
603	LIST (GET CARES_LIB_VERSIONINFO 2 CARES_LIB_VERSION_AGE)
604	MATH (EXPR CARES_LIB_VERSION_MAJOR "${CARES_LIB_VERSION_CURRENT} - ${CARES_LIB_VERSION_AGE}")
605	SET  (CARES_LIB_VERSION_MINOR "${CARES_LIB_VERSION_AGE}")
606	SET  (CARES_LIB_VERSION_RELEASE "${CARES_LIB_VERSION_REVISION}")
607
608	SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES
609		EXPORT_NAME                  cares
610		OUTPUT_NAME                  cares
611		COMPILE_PDB_NAME             cares
612		COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
613		SOVERSION                    ${CARES_LIB_VERSION_MAJOR}
614		VERSION                      "${CARES_LIB_VERSION_MAJOR}.${CARES_LIB_VERSION_MINOR}.${CARES_LIB_VERSION_RELEASE}"
615	)
616
617	TARGET_INCLUDE_DIRECTORIES (${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>")
618	TARGET_INCLUDE_DIRECTORIES (${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>")
619	TARGET_INCLUDE_DIRECTORIES (${PROJECT_NAME} PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
620
621	TARGET_COMPILE_DEFINITIONS (${PROJECT_NAME} PRIVATE HAVE_CONFIG_H=1 CARES_BUILDING_LIBRARY)
622
623	TARGET_LINK_LIBRARIES (${PROJECT_NAME} PUBLIC ${CARES_DEPENDENT_LIBS})
624
625	IF (CARES_INSTALL)
626		INSTALL (TARGETS ${PROJECT_NAME}
627			EXPORT ${PROJECT_NAME}-targets
628			COMPONENT Library
629			${TARGETS_INST_DEST}
630		)
631		INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cares.pdb
632			DESTINATION ${CMAKE_INSTALL_BINDIR}
633			COMPONENT Library
634			OPTIONAL
635		)
636	ENDIF ()
637	SET (STATIC_SUFFIX "_static")
638
639	# For chain building: add alias targets that look like import libs that would be returned by find_package(c-ares).
640	ADD_LIBRARY (${PROJECT_NAME}::cares_shared ALIAS ${PROJECT_NAME})
641	ADD_LIBRARY (${PROJECT_NAME}::cares        ALIAS ${PROJECT_NAME})
642ENDIF ()
643
644# Build the static library
645IF (CARES_STATIC)
646	SET (LIBNAME ${PROJECT_NAME}${STATIC_SUFFIX})
647
648	ADD_LIBRARY (${LIBNAME} STATIC ${CSOURCES})
649
650	SET_TARGET_PROPERTIES (${LIBNAME} PROPERTIES
651		EXPORT_NAME                  cares${STATIC_SUFFIX}
652		OUTPUT_NAME                  cares${STATIC_SUFFIX}
653		COMPILE_PDB_NAME             cares${STATIC_SUFFIX}
654		COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
655	)
656
657	IF (CARES_STATIC_PIC)
658		SET_TARGET_PROPERTIES (${LIBNAME} PROPERTIES POSITION_INDEPENDENT_CODE True)
659	ENDIF ()
660
661	TARGET_INCLUDE_DIRECTORIES (${LIBNAME} PUBLIC "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>")
662	TARGET_INCLUDE_DIRECTORIES (${LIBNAME} PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>")
663	TARGET_INCLUDE_DIRECTORIES (${LIBNAME} PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
664
665	TARGET_COMPILE_DEFINITIONS (${LIBNAME}
666		PUBLIC  CARES_STATICLIB
667		PRIVATE HAVE_CONFIG_H=1
668	)
669
670	TARGET_LINK_LIBRARIES (${LIBNAME} PUBLIC ${CARES_DEPENDENT_LIBS})
671	IF (CARES_INSTALL)
672		INSTALL (TARGETS ${LIBNAME} EXPORT ${PROJECT_NAME}-targets COMPONENT Devel
673			${TARGETS_INST_DEST}
674		)
675		INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cares${STATIC_SUFFIX}.pdb
676			DESTINATION ${CMAKE_INSTALL_BINDIR}
677			COMPONENT Library
678			OPTIONAL
679		)
680	ENDIF ()
681
682	# For chain building: add alias targets that look like import libs that would be returned by find_package(c-ares).
683	ADD_LIBRARY (${PROJECT_NAME}::cares_static ALIAS ${LIBNAME})
684	IF (NOT TARGET ${PROJECT_NAME}::cares)
685		# Only use static for the generic alias if shared lib wasn't built.
686		ADD_LIBRARY (${PROJECT_NAME}::cares ALIAS ${LIBNAME})
687	ENDIF ()
688ENDIF ()
689
690IF (CARES_BUILD_TESTS OR CARES_BUILD_CONTAINER_TESTS)
691	ENABLE_TESTING ()
692	ADD_SUBDIRECTORY (test)
693ENDIF ()
694
695# Headers and Man Pages installation target
696IF (CARES_INSTALL)
697	SET (CARES_HEADERS ares.h ares_version.h ares_dns.h "${PROJECT_BINARY_DIR}/ares_build.h" ares_rules.h)
698	INSTALL (FILES ${CARES_HEADERS} COMPONENT Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
699
700	# ManPages
701	FILE (GLOB DevelManPages "." "*.3")
702	INSTALL (FILES ${DevelManPages}
703		DESTINATION ${CMAKE_INSTALL_MANDIR}/man3
704		COMPONENT Devel
705	)
706ENDIF ()
707
708# Export targets
709IF (CARES_INSTALL)
710	SET (CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
711	INCLUDE (CMakePackageConfigHelpers)
712	CONFIGURE_PACKAGE_CONFIG_FILE (${PROJECT_NAME}-config.cmake.in ${PROJECT_NAME}-config.cmake
713		INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
714		PATH_VARS CMAKE_INSTALL_INCLUDEDIR
715		NO_CHECK_REQUIRED_COMPONENTS_MACRO
716	)
717
718	WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_NAME}-config-version.cmake VERSION "${CARES_VERSION}" COMPATIBILITY SameMajorVersion)
719	INSTALL (EXPORT ${PROJECT_NAME}-targets COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR} NAMESPACE ${PROJECT_NAME}::)
720	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})
721
722	# pkgconfig support
723	IF (NOT CARES_SHARED)
724		SET (CPPFLAG_CARES_STATICLIB "-DCARES_STATICLIB")
725		FOREACH (LIB ${CARES_DEPENDENT_LIBS})
726			SET (CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}")
727		ENDFOREACH ()
728	ENDIF ()
729	CONFIGURE_FILE("libcares.pc.cmake" "libcares.pc" @ONLY)
730	INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcares.pc" COMPONENT Devel DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
731ENDIF ()
732
733# Legacy chain-building variables (provided for compatibility with old code).
734# Don't use these, external code should be updated to refer to the aliases directly (e.g., Cares::cares).
735SET (CARES_FOUND 1 CACHE INTERNAL "CARES LIBRARY FOUND")
736SET (CARES_LIBRARIES ${PROJECT_NAME}::cares CACHE INTERNAL "CARES LIBRARIES")
737
738IF (CARES_BUILD_TOOLS)
739	# Build ahost
740	ADD_EXECUTABLE (ahost ahost.c ${SAMPLESOURCES})
741	TARGET_COMPILE_DEFINITIONS (ahost PRIVATE HAVE_CONFIG_H=1)
742	TARGET_LINK_LIBRARIES (ahost PRIVATE ${PROJECT_NAME})
743	IF (CARES_INSTALL)
744		INSTALL (TARGETS ahost COMPONENT Tools ${TARGETS_INST_DEST})
745	ENDIF ()
746
747
748	# Build adig
749	ADD_EXECUTABLE (adig adig.c ${SAMPLESOURCES})
750	TARGET_COMPILE_DEFINITIONS (adig PRIVATE HAVE_CONFIG_H=1)
751	TARGET_LINK_LIBRARIES (adig PRIVATE ${PROJECT_NAME})
752	IF (CARES_INSTALL)
753		INSTALL (TARGETS adig COMPONENT Tools ${TARGETS_INST_DEST})
754	ENDIF ()
755
756
757	# Build acountry
758	ADD_EXECUTABLE (acountry acountry.c ${SAMPLESOURCES})
759	TARGET_COMPILE_DEFINITIONS (acountry PRIVATE HAVE_CONFIG_H=1)
760	TARGET_LINK_LIBRARIES (acountry PRIVATE ${PROJECT_NAME})
761	IF (CARES_INSTALL)
762		INSTALL (TARGETS acountry COMPONENT Tools ${TARGETS_INST_DEST})
763	ENDIF ()
764
765	# Install Man Pages
766	IF (CARES_INSTALL)
767		FILE (GLOB ToolManPages "." "*.1")
768		INSTALL (FILES ${ToolManPages}
769			DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
770			COMPONENT Tools
771		)
772	ENDIF ()
773ENDIF ()
774
775
776IF (CARES_INSTALL)
777
778    # Package creation
779
780    set( CPACK_PACKAGE_NAME ${PROJECT_NAME} )
781    set( CPACK_PACKAGE_VENDOR "Daniel Stenberg" ) # Github project owner
782    set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "A C library for asynchronous DNS requests" )
783    set( CPACK_PACKAGE_HOMEPAGE_URL "https://c-ares.haxx.se/" )
784    set( CPACK_PACKAGE_CONTACT      "https://c-ares.haxx.se/" )
785    set( CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} )
786    set( CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR} )
787    set( CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH} )
788    set( CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH} )
789    set( CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME} )
790    set( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md" )
791    set( CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md" )
792
793    set( CPACK_COMPONENT_Library_DISPLAY_NAME "c-ares Library" )
794    set( CPACK_COMPONENT_Library_DESCRIPTION "The c-ares binary library." )
795    set( CPACK_COMPONENT_Library_REQUIRED 1 )
796    set( CPACK_COMPONENT_Devel_DISPLAY_NAME "c-ares Development Files" )
797    set( CPACK_COMPONENT_Devel_DESCRIPTION "Development files for compiling against c-ares." )
798    set( CPACK_COMPONENT_Devel_REQUIRED 0 )
799    IF (CARES_BUILD_TOOLS)
800        set( CPACK_COMPONENT_Tools_DISPLAY_NAME "c-ares Tools" )
801        set( CPACK_COMPONENT_Tools_DESCRIPTION "Tools for using c-ares." )
802        set( CPACK_COMPONENT_Tools_REQUIRED 0 )
803    ENDIF ()
804
805    if( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
806
807        if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" )
808            # Note: the architecture should default to the local architecture, but it
809            # in fact comes up empty.  We call `uname -m` to ask the kernel instead.
810            EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE )
811        endif()
812
813        set( CPACK_INCLUDE_TOPLEVEL_DIRECTORY 1 )
814        set( CPACK_PACKAGE_RELEASE 1 )
815
816
817        # RPM - https://cmake.org/cmake/help/latest/cpack_gen/rpm.html
818        set( CPACK_RPM_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} )
819        set( CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_PACKAGE_ARCHITECTURE} )
820        set( CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} )
821        set( CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_HOMEPAGE_URL} )
822        set( CPACK_RPM_PACKAGE_LICENSE "MIT" )
823        set( CPACK_RPM_COMPONENT_INSTALL 1 )
824        set( CPACK_RPM_COMPRESSION_TYPE "xz" )
825        set( CPACK_RPM_PACKAGE_AUTOPROV 1 )
826
827        set( CPACK_RPM_Library_PACKAGE_SUMMARY ${CPACK_COMPONENT_Library_DESCRIPTION} )
828        set( CPACK_RPM_Library_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} )
829        set( CPACK_RPM_Library_PACKAGE_NAME "libcares${CARES_LIB_VERSION_MAJOR}" )
830        set( CPACK_RPM_Library_FILE_NAME "RPM-DEFAULT" )
831
832        set( CPACK_RPM_Devel_PACKAGE_REQUIRES "cmake >= ${CMAKE_MINIMUM_REQUIRED_VERSION}, ${CPACK_RPM_Library_PACKAGE_NAME} >= ${CPACK_PACKAGE_VERSION}" )
833        set( CPACK_RPM_Devel_PACKAGE_SUMMARY ${CPACK_COMPONENT_Devel_DESCRIPTION} )
834        set( CPACK_RPM_Devel_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} )
835        set( CPACK_RPM_Devel_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-devel" )
836        set( CPACK_RPM_Devel_FILE_NAME "RPM-DEFAULT" )
837
838        IF (CARES_BUILD_TOOLS)
839            set( CPACK_RPM_Tools_PACKAGE_REQUIRES "${CPACK_RPM_Library_PACKAGE_NAME} >= ${CPACK_PACKAGE_VERSION}" )
840            set( CPACK_RPM_Tools_PACKAGE_SUMMARY ${CPACK_COMPONENT_Tools_DESCRIPTION} )
841            set( CPACK_RPM_Tools_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} )
842            set( CPACK_RPM_Tools_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-tools" )
843            set( CPACK_RPM_Tools_FILE_NAME "RPM-DEFAULT" )
844        ENDIF ()
845
846
847        # DEB - https://cmake.org/cmake/help/latest/cpack_gen/deb.html
848        set( CPACK_DEBIAN_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} )
849        set( CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL} )
850        set( CPACK_DEB_COMPONENT_INSTALL 1 )
851        set( CPACK_DEBIAN_COMPRESSION_TYPE "xz")
852        set( CPACK_DEBIAN_PACKAGE_SHLIBDEPS 1 )
853
854        if ( ${CPACK_PACKAGE_ARCHITECTURE} STREQUAL "x86_64" )
855            set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64" )  # DEB doesn't always use the kernel's arch name
856        else()
857            set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${CPACK_PACKAGE_ARCHITECTURE} )
858        endif()
859
860        set( CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT" ) # Use default naming scheme
861
862        set( CPACK_DEBIAN_LIBRARY_PACKAGE_NAME ${CPACK_RPM_Library_PACKAGE_NAME} )
863
864        set( CPACK_DEBIAN_DEVEL_PACKAGE_DEPENDS "cmake (>= ${CMAKE_MINIMUM_REQUIRED_VERSION}), ${CPACK_DEBIAN_LIBRARY_PACKAGE_NAME} (>= ${CPACK_PACKAGE_VERSION})" )
865        set( CPACK_DEBIAN_DEVEL_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev" )
866
867        IF (CARES_BUILD_TOOLS)
868            set( CPACK_DEBIAN_TOOLS_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-tools" )
869            set( CPACK_DEBIAN_TOOLS_PACKAGE_SHLIBDEPS OFF ) # dpkg-shlibdeps can't find the libs we built
870            set( CPACK_DEBIAN_TOOLS_PACKAGE_DEPENDS "${CPACK_DEBIAN_LIBRARY_PACKAGE_NAME} (>= ${CPACK_PACKAGE_VERSION})" )
871        ENDIF ()
872
873    elseif( ${CMAKE_HOST_WIN32} )
874        set( CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON )
875        set( CPACK_NSIS_DISPLAY_NAME ${PROJECT_NAME} )
876        set( CPACK_NSIS_PACKAGE_NAME ${PROJECT_NAME} )
877        set( CPACK_NSIS_URL_INFO_ABOUT ${CPACK_PACKAGE_HOMEPAGE_URL} )
878    endif()
879
880
881    # This must always be last!
882    include( CPack )
883ENDIF ()
884