cmake: Put defines in config.h
[nss_wrapper.git] / ConfigureChecks.cmake
1 include(CheckIncludeFile)
2 include(CheckSymbolExists)
3 include(CheckFunctionExists)
4 include(CheckLibraryExists)
5 include(CheckTypeSize)
6 include(CheckStructHasMember)
7 include(CheckPrototypeDefinition)
8 include(TestBigEndian)
9 include(CheckCSourceRuns)
10
11 set(PACKAGE ${PROJECT_NAME})
12 set(VERSION ${PROJECT_VERSION})
13 set(DATADIR ${DATA_INSTALL_DIR})
14 set(LIBDIR ${LIB_INSTALL_DIR})
15 set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
16 set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
17
18 set(BINARYDIR ${CMAKE_BINARY_DIR})
19 set(SOURCEDIR ${CMAKE_SOURCE_DIR})
20
21 function(COMPILER_DUMPVERSION _OUTPUT_VERSION)
22     # Remove whitespaces from the argument.
23     # This is needed for CC="ccache gcc" cmake ..
24     string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}")
25
26     execute_process(
27         COMMAND
28             ${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion
29         OUTPUT_VARIABLE _COMPILER_VERSION
30     )
31
32     string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
33            _COMPILER_VERSION "${_COMPILER_VERSION}")
34
35     set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
36 endfunction()
37
38 if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
39     compiler_dumpversion(GNUCC_VERSION)
40     if (NOT GNUCC_VERSION EQUAL 34)
41         set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden")
42         check_c_source_compiles(
43 "void __attribute__((visibility(\"default\"))) test() {}
44 int main(void){ return 0; }
45 " WITH_VISIBILITY_HIDDEN)
46         set(CMAKE_REQUIRED_FLAGS "")
47     endif (NOT GNUCC_VERSION EQUAL 34)
48 endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
49
50 # HEADERS
51 check_include_file(sys/types.h HAVE_SYS_TYPES_H)
52 check_include_file(pwd.h HAVE_PWD_H)
53 check_include_file(shadow.h HAVE_SHADOW_H)
54 check_include_file(grp.h HAVE_GRP_H)
55 check_include_file(nss.h HAVE_NSS_H)
56 check_include_file(nss_common.h HAVE_NSS_COMMON_H)
57
58 # FUNCTIONS
59 check_function_exists(strncpy HAVE_STRNCPY)
60 check_function_exists(vsnprintf HAVE_VSNPRINTF)
61 check_function_exists(snprintf HAVE_SNPRINTF)
62
63 check_function_exists(getpwnam_r HAVE_GETPWNAM_R)
64 check_function_exists(getpwuid_r HAVE_GETPWUID_R)
65 check_function_exists(getpwent_r HAVE_GETPWENT_R)
66
67 check_function_exists(setspent HAVE_SETSPENT)
68 check_function_exists(getspnam HAVE_GETSPNAM)
69
70 check_function_exists(getgrnam_r HAVE_GETGRNAM_R)
71 check_function_exists(getgrgid_r HAVE_GETGRGID_R)
72 check_function_exists(getgrent_r HAVE_GETGRENT_R)
73
74 check_function_exists(getgrouplist HAVE_GETGROUPLIST)
75
76 check_function_exists(gethostbyaddr_r HAVE_GETHOSTBYADDR_R)
77 check_function_exists(gethostbyname_r HAVE_GETHOSTBYNAME_R)
78
79 check_function_exists(gethostbyname2 HAVE_GETHOSTBYNAME2)
80
81 if (WIN32)
82     check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
83     check_function_exists(_vsnprintf HAVE__VSNPRINTF)
84     check_function_exists(_snprintf HAVE__SNPRINTF)
85     check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
86 endif (WIN32)
87
88 if (UNIX)
89     if (NOT LINUX)
90         # libsocket (Solaris)
91         check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET)
92         if (HAVE_LIBSOCKET)
93             list(APPEND _REQUIRED_LIBRARIES socket)
94         endif (HAVE_LIBSOCKET)
95
96         # libnsl/inet_pton (Solaris)
97         check_library_exists(nsl inet_pton "" HAVE_LIBNSL)
98         if (HAVE_LIBNSL)
99             list(APPEND _REQUIRED_LIBRARIES nsl)
100         endif (HAVE_LIBNSL)
101     endif (NOT LINUX)
102
103     check_function_exists(getaddrinfo HAVE_GETADDRINFO)
104 endif (UNIX)
105
106 if (SOLARIS)
107     check_function_exists(__posix_getpwnam_r HAVE___POSIX_GETPWNAM_R)
108     check_function_exists(__posix_getpwuid_r HAVE___POSIX_GETPWUID_R)
109
110     check_function_exists(__posix_getgrgid_r HAVE___POSIX_GETGRGID_R)
111     check_function_exists(__posix_getgrnam_r HAVE___POSIX_GETGRNAM_R)
112 endif (SOLARIS)
113
114 check_function_exists(asprintf HAVE_ASPRINTF)
115 if (UNIX AND HAVE_ASPRINTF)
116     add_definitions(-D_GNU_SOURCE)
117 endif (UNIX AND HAVE_ASPRINTF)
118
119 set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_PTHREAD_SEMANTICS)
120 check_prototype_definition(getpwent_r
121     "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
122     "NULL"
123     "unistd.h;pwd.h"
124     HAVE_SOLARIS_GETPWENT_R)
125
126 check_prototype_definition(getpwnam_r
127     "int getpwnam_r(const char *name, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)"
128     "-1"
129     "unistd.h;pwd.h"
130     HAVE_SOLARIS_GETPWNAM_R)
131
132 check_prototype_definition(getpwuid_r
133     "int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)"
134     "-1"
135     "unistd.h;pwd.h"
136     HAVE_SOLARIS_GETPWUID_R)
137
138 check_prototype_definition(getgrent_r
139     "struct group *getgrent_r(struct group *src, char *buf, int buflen)"
140     "NULL"
141     "unistd.h;grp.h"
142     HAVE_SOLARIS_GETGRENT_R)
143
144 check_prototype_definition(getgrnam_r
145     "int getgrnam_r(const char *name, struct group *grp, char *buf, int buflen, struct group **pgrp)"
146     "-1"
147     "unistd.h;grp.h"
148     HAVE_SOLARIS_GETGRNAM_R)
149
150 check_prototype_definition(getgrgid_r
151     "int getgrgid_r(gid_t gid, struct group *grp, char *buf, int buflen, struct group **pgrp)"
152     "-1"
153     "unistd.h;grp.h"
154     HAVE_SOLARIS_GETGRGID_R)
155
156 check_prototype_definition(sethostent
157     "int sethostent(int stayopen)"
158     "-1"
159     "unistd.h;netdb.h"
160     HAVE_SOLARIS_SETHOSTENT)
161
162 check_prototype_definition(endhostent
163     "int endhostent(void)"
164     "-1"
165     "unistd.h;netdb.h"
166     HAVE_SOLARIS_ENDHOSTENT)
167
168 check_prototype_definition(gethostname
169     "int gethostname(char *name, int len)"
170     "-1"
171     "unistd.h;netdb.h"
172     HAVE_SOLARIS_GETHOSTNAME)
173 set(CMAKE_REQUIRED_DEFINITIONS)
174
175 check_prototype_definition(setgrent
176     "int setgrent(void)"
177     "-1"
178     "unistd.h;grp.h"
179     HAVE_BSD_SETGRENT)
180
181 check_prototype_definition(getnameinfo
182     "int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, int flags)"
183     "-1"
184     "unistd.h;netdb.h"
185     HAVE_LINUX_GETNAMEINFO)
186
187 check_prototype_definition(getnameinfo
188     "int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, unsigned int flags)"
189     "-1"
190     "unistd.h;netdb.h"
191     HAVE_LINUX_GETNAMEINFO_UNSIGNED)
192
193 # STRUCT MEMBERS
194 check_struct_has_member("struct sockaddr" sa_len "sys/socket.h netinet/in.h" HAVE_STRUCT_SOCKADDR_SA_LEN)
195 check_struct_has_member("struct passwd" pw_class "pwd.h" HAVE_STRUCT_PASSWD_PW_CLASS)
196 check_struct_has_member("struct passwd" pw_change "pwd.h" HAVE_STRUCT_PASSWD_PW_CHANGE)
197 check_struct_has_member("struct passwd" pw_expire "pwd.h" HAVE_STRUCT_PASSWD_PW_EXPIRE)
198
199 # IPV6
200 check_c_source_compiles("
201     #include <stdlib.h>
202     #include <sys/socket.h>
203     #include <netdb.h>
204     #include <netinet/in.h>
205     #include <net/if.h>
206
207 int main(void) {
208     struct sockaddr_storage sa_store;
209     struct addrinfo *ai = NULL;
210     struct in6_addr in6addr;
211     int idx = if_nametoindex(\"iface1\");
212     int s = socket(AF_INET6, SOCK_STREAM, 0);
213     int ret = getaddrinfo(NULL, NULL, NULL, &ai);
214     if (ret != 0) {
215         const char *es = gai_strerror(ret);
216     }
217
218     freeaddrinfo(ai);
219     {
220         int val = 1;
221 #ifdef HAVE_LINUX_IPV6_V6ONLY_26
222 #define IPV6_V6ONLY 26
223 #endif
224         ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
225                          (const void *)&val, sizeof(val));
226     }
227
228     return 0;
229 }" HAVE_IPV6)
230
231 check_c_source_compiles("
232 void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
233
234 int main(void) {
235     return 0;
236 }" HAVE_ATTRIBUTE_PRINTF_FORMAT)
237
238 check_c_source_compiles("
239 void test_constructor_attribute(void) __attribute__ ((constructor));
240
241 void test_constructor_attribute(void)
242 {
243      return;
244 }
245
246 int main(void) {
247      return 0;
248 }" HAVE_CONSTRUCTOR_ATTRIBUTE)
249
250 check_c_source_compiles("
251 void test_destructor_attribute(void) __attribute__ ((destructor));
252
253 void test_destructor_attribute(void)
254 {
255     return;
256 }
257
258 int main(void) {
259     return 0;
260 }" HAVE_DESTRUCTOR_ATTRIBUTE)
261
262 find_library(DLFCN_LIBRARY dl)
263 if (DLFCN_LIBRARY)
264     list(APPEND _REQUIRED_LIBRARIES ${DLFCN_LIBRARY})
265 else()
266     check_function_exists(dlopen HAVE_DLOPEN)
267     if (NOT HAVE_DLOPEN)
268         message(FATAL_ERROR "FATAL: No dlopen() function detected")
269     endif()
270 endif()
271
272 # ENDIAN
273 if (NOT WIN32)
274     test_big_endian(WORDS_BIGENDIAN)
275 endif (NOT WIN32)
276
277 # check whether getaddrinfo() returns "node" in "ai_canonname" for IP-addresses
278 check_c_source_runs("#include <stddef.h>
279 #include <string.h>
280 #include <sys/types.h>
281 #include <sys/socket.h>
282 #include <netdb.h>
283 int main(void) {
284     struct addrinfo hints;
285     struct addrinfo *res = NULL;
286
287     memset(&hints, 0, sizeof(struct addrinfo));
288     hints.ai_family = AF_INET;
289     hints.ai_socktype = SOCK_STREAM;
290     hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
291
292     if (getaddrinfo(\"0.0.0.0\", \"389\", &hints, &res) != 0) {
293         return 2;
294     }
295
296     if (res == NULL) {
297         return 3;
298     }
299
300     return strncmp(res->ai_canonname, \"0.0.0.0\", sizeof(\"0.0.0.0\")) != 0;
301 }" HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES)
302
303 # check whether getaddrinfo() returns EAI_SERVICE when the requested service is not available for the requested socket type.
304 check_c_source_runs("#include <stddef.h>
305 #include <string.h>
306 #include <sys/types.h>
307 #include <sys/socket.h>
308 #include <netdb.h>
309 int main(void) {
310     struct addrinfo hints;
311     struct addrinfo *res = NULL;
312     int rc;
313
314     memset(&hints, 0, sizeof(struct addrinfo));
315     hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
316     hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
317     hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;    /* For wildcard IP address */
318     hints.ai_protocol = 0;          /* Any protocol */
319     hints.ai_canonname = NULL;
320
321     rc = getaddrinfo(NULL, \"echo\", &hints, &res);
322     return rc != EAI_SERVICE;
323 }" HAVE_GETADDRINFO_USES_EAI_SERVICE)
324
325 # check for non-NULL gethostent()
326 check_c_source_runs("#include <stddef.h>
327 #include <netdb.h>
328 int main(void) {
329     struct hostent *hostent = NULL;
330     sethostent(0);
331     hostent = gethostent();
332     endhostent();
333     return hostent == NULL;
334 }" HAVE_NONNULL_GETHOSTENT)
335
336 set(NWRAP_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} CACHE INTERNAL "nss_wrapper required system libraries")