s3:registry: Initialize struct security_ace ace[]
[samba4-gss.git] / source3 / wscript
blob4415b3739131d9e9b965010be1d1b9eff7fee1ee
1 #!/usr/bin/env python
3 srcdir = ".."
5 import sys, os
6 from optparse import SUPPRESS_HELP
7 sys.path.insert(0, srcdir + "/buildtools/wafsamba")
8 sys.path.insert(0, "source3")
10 from waflib import Options, Logs, Errors
11 import wafsamba
12 import build.charset
13 from wafsamba import samba_utils
14 from samba_utils import TO_LIST
15 import samba3
17 default_prefix = Options.default_prefix = '/usr/local/samba'
19 def options(opt):
21 opt.add_option('--with-static-modules',
22 help=("Comma-separated list of names of modules to statically link in. "+
23 "May include !module to disable 'module'. "+
24 "Can be '!FORCED' to disable all non-required static only modules. "+
25 "Can be '!DEFAULT' to disable all modules defaulting to a static build. "+
26 "Can be 'ALL' to build all default shared modules static. "+
27 "The most specific one wins, while the order is ignored "+
28 "and --with-static-modules is evaluated before "+
29 "--with-shared-modules"),
30 action="store", dest='static_modules', default=None)
31 opt.add_option('--with-shared-modules',
32 help=("Comma-separated list of names of modules to build shared. "+
33 "May include !module to disable 'module'. "+
34 "Can be '!FORCED' to disable all non-required shared only modules. "+
35 "Can be '!DEFAULT' to disable all modules defaulting to a shared build. "+
36 "Can be 'ALL' to build all default static modules shared. "+
37 "The most specific one wins, while the order is ignored "+
38 "and --with-static-modules is evaluated before "+
39 "--with-shared-modules"),
40 action="store", dest='shared_modules', default=None)
42 # Optional Libraries
43 # ------------------
45 # Most of the calls to opt.samba_add_onoff_option() implicitly
46 # or explicitly use default=True
48 # To assist users and distributors to build Samba with the full feature
49 # set, the build system will abort if our dependent libraries and their
50 # header files are not found on the target system. This will mean for
51 # example, that xattr, acl and ldap headers must be installed for the
52 # default build to complete. The configure system will check for these
53 # headers, and the error message will indicate the option (such as
54 # --without-acl-support) that can be specified to skip this requirement.
56 # This will assist users and in particular distributors in building fully
57 # functional packages, while allowing those on systems truly without these
58 # facilities to continue to build Samba after careful consideration.
60 # It also ensures our container image generation in bootstrap/ is correct
61 # as otherwise a missing package there would just silently work
63 opt.samba_add_onoff_option('winbind')
64 opt.samba_add_onoff_option('ads')
65 opt.samba_add_onoff_option('cups', with_name="enable", without_name="disable")
66 opt.samba_add_onoff_option('iprint', with_name="enable", without_name="disable")
67 opt.samba_add_onoff_option('pam')
68 opt.samba_add_onoff_option('quotas', default=None)
69 opt.samba_add_onoff_option('sendfile-support', default=None)
70 opt.samba_add_onoff_option('utmp')
71 opt.samba_add_onoff_option('avahi', with_name="enable", without_name="disable")
72 opt.samba_add_onoff_option('iconv')
73 opt.samba_add_onoff_option('acl-support')
74 opt.samba_add_onoff_option('syslog')
75 opt.samba_add_onoff_option('automount')
76 opt.samba_add_onoff_option('dmapi', default=None) # None means autodetection
77 opt.samba_add_onoff_option('fam', default=None) # None means autodetection
78 opt.samba_add_onoff_option('profiling-data', default=False)
79 opt.samba_add_onoff_option('libarchive', default=True)
81 opt.samba_add_onoff_option('cluster-support', default=False)
83 opt.samba_add_onoff_option('regedit', default=None)
84 opt.samba_add_onoff_option('winexe', default=None)
86 opt.samba_add_onoff_option('fake-kaserver',
87 help=("Include AFS fake-kaserver support"), default=False)
89 opt.samba_add_onoff_option('glusterfs', with_name="enable", without_name="disable", default=True)
90 opt.samba_add_onoff_option('cephfs', with_name="enable", without_name="disable", default=True)
92 opt.add_option('--enable-vxfs',
93 help=("enable support for VxFS (default=no)"),
94 action="store_true", dest='enable_vxfs', default=False)
96 # default = None means autodetection
97 opt.samba_add_onoff_option('spotlight', with_name="enable", without_name="disable", default=None)
98 opt.samba_add_onoff_option('wsp', with_name="enable", without_name="disable", default=True)
100 def configure(conf):
101 default_static_modules = []
102 default_shared_modules = []
103 required_static_modules = []
104 forced_static_modules = []
105 forced_shared_modules = []
107 if sys.platform != 'openbsd5':
108 conf.ADD_LDFLAGS("-Wl,--export-dynamic", testflags=True)
110 # We crash without vfs_default
111 # and vfs_not_implemented provides helper function
112 # for other modules
113 required_static_modules.extend(['vfs_default', 'vfs_not_implemented'])
115 conf.CHECK_HEADERS('netdb.h')
116 conf.CHECK_HEADERS('linux/falloc.h linux/ioctl.h')
117 conf.CHECK_HEADERS('linux/magic.h')
119 conf.CHECK_FUNCS('getcwd fchown chmod fchmod mknod mknodat')
120 conf.CHECK_FUNCS('strtol strchr strupr chflags fchflags')
121 conf.CHECK_FUNCS('getrlimit fsync setpgid')
122 conf.CHECK_FUNCS('setsid glob strpbrk crypt16 getauthuid')
123 conf.CHECK_FUNCS('innetgr')
124 conf.CHECK_FUNCS('initgroups select poll rdchk getgrnam getgrent pathconf')
125 conf.CHECK_FUNCS('setpriv setgidx setuidx setgroups syscall sysconf')
126 conf.CHECK_FUNCS('atexit grantpt posix_openpt fallocate')
127 conf.CHECK_FUNCS('fseeko setluid')
128 conf.CHECK_FUNCS('getpwnam', headers='sys/types.h pwd.h')
129 conf.CHECK_FUNCS('fdopendir')
130 conf.CHECK_FUNCS('getpwent_r setenv clearenv strcasecmp')
131 conf.CHECK_FUNCS('syslog vsyslog timegm setlocale')
132 conf.CHECK_FUNCS('lutimes utimensat futimens')
133 conf.CHECK_FUNCS('mlock munlock mlockall munlockall')
134 conf.CHECK_FUNCS('memalign posix_memalign hstrerror')
135 conf.CHECK_FUNCS('getdomainname')
136 conf.CHECK_FUNCS_IN('dn_expand _dn_expand __dn_expand', 'resolv')
137 conf.CHECK_FUNCS_IN('dn_expand', 'inet')
138 conf.CHECK_DECLS('readahead', reverse=True, headers='fcntl.h')
140 if conf.CHECK_CODE('''
141 #if defined(HAVE_UNISTD_H)
142 #include <unistd.h>
143 #endif
144 long ret = splice(0,0,1,0,400,SPLICE_F_MOVE);
145 ''',
146 'HAVE_LINUX_SPLICE',
147 headers='fcntl.h'):
148 conf.CHECK_DECLS('splice', reverse=True, headers='fcntl.h')
150 # Check for inotify support (Skip if we are SunOS)
151 #NOTE: illumos provides sys/inotify.h but is not an exact match for linux
152 host_os = sys.platform
153 if host_os.rfind('sunos') == -1:
154 conf.CHECK_HEADERS('sys/inotify.h')
155 if conf.env.HAVE_SYS_INOTIFY_H:
156 conf.DEFINE('HAVE_INOTIFY', 1)
158 # Check for Linux kernel oplocks
159 if conf.CHECK_DECLS('F_SETLEASE', headers='linux/fcntl.h', reverse=True):
160 conf.DEFINE('HAVE_KERNEL_OPLOCKS_LINUX', 1)
162 # check for fam libs
163 samba_fam_libs=None
164 check_for_fam=False
165 if Options.options.with_fam is None:
166 check_for_fam=True
167 elif Options.options.with_fam == True:
168 check_for_fam=True
170 if check_for_fam and conf.CHECK_HEADERS('fam.h'):
171 if conf.CHECK_FUNCS_IN('FAMOpen2', 'fam'):
172 samba_fam_libs='fam'
173 elif conf.CHECK_FUNCS_IN('FAMOpen2', 'fam C'):
174 samba_fam_libs='fam C'
175 conf.CHECK_TYPE('enum FAMCodes', headers='fam.h',
176 define='HAVE_FAM_H_FAMCODES_TYPEDEF',
177 msg='Checking whether enum FAMCodes is available')
178 conf.CHECK_FUNCS_IN('FAMNoExists', 'fam')
180 if samba_fam_libs is not None:
181 conf.DEFINE('SAMBA_FAM_LIBS', samba_fam_libs)
182 conf.DEFINE('HAVE_FAM', 1)
183 else:
184 if Options.options.with_fam == True:
185 conf.fatal('FAM support requested, but no suitable FAM library found')
186 elif check_for_fam:
187 Logs.warn('no suitable FAM library found')
189 # check for libarchive (tar command in smbclient)
190 # None means autodetect, True/False means enable/disable
191 conf.SET_TARGET_TYPE('archive', 'EMPTY')
192 if Options.options.with_libarchive is not False:
193 Logs.info("Checking for libarchive existence")
194 if conf.CHECK_HEADERS('archive.h') and conf.CHECK_LIB('archive', shlib=True):
195 conf.CHECK_FUNCS_IN('archive_read_support_filter_all archive_read_free', 'archive')
196 else:
197 conf.fatal("libarchive support not found. "
198 "Try installing libarchive-dev or libarchive-devel. "
199 "Otherwise, use --without-libarchive to "
200 "build without libarchive support. "
201 "libarchive support is required for the smbclient "
202 "tar-file mode")
203 elif conf.CONFIG_GET('ENABLE_SELFTEST'):
204 raise Errors.WafError('libarchive library required for '
205 '--enable-selftest')
208 # check for DMAPI libs
209 if Options.options.with_dmapi == False:
210 have_dmapi = False
211 else:
212 have_dmapi = True
213 Logs.info("Checking for DMAPI library existence")
214 samba_dmapi_lib = ''
215 if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'dm'):
216 samba_dmapi_lib = 'dm'
217 else:
218 if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'jfsdm'):
219 samba_dmapi_lib = 'jfsdm'
220 else:
221 if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'dmapi'):
222 samba_dmapi_lib = 'dmapi'
223 else:
224 if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'xdsm'):
225 samba_dmapi_lib = 'xdsm'
226 # only bother to test headers and compilation when a candidate
227 # library has been found
228 if samba_dmapi_lib == '':
229 have_dmapi = False
230 broken_dmapi = "no suitable DMAPI library found"
232 if have_dmapi:
233 conf.CHECK_HEADERS('sys/dmi.h xfs/dmapi.h sys/jfsdmapi.h sys/dmapi.h dmapi.h')
234 conf.CHECK_CODE('''
235 #include <time.h> /* needed by Tru64 */
236 #include <sys/types.h> /* needed by AIX */
237 #ifdef HAVE_XFS_DMAPI_H
238 #include <xfs/dmapi.h>
239 #elif defined(HAVE_SYS_DMI_H)
240 #include <sys/dmi.h>
241 #elif defined(HAVE_SYS_JFSDMAPI_H)
242 #include <sys/jfsdmapi.h>
243 #elif defined(HAVE_SYS_DMAPI_H)
244 #include <sys/dmapi.h>
245 #elif defined(HAVE_DMAPI_H)
246 #include <dmapi.h>
247 #endif
249 /* This link test is designed to fail on IRI 6.4, but should
250 * succeed on Linux, IRIX 6.5 and AIX.
252 int main(int argc, char **argv)
254 char * version;
255 dm_eventset_t events;
256 /* This doesn't take an argument on IRIX 6.4. */
257 dm_init_service(&version);
258 /* IRIX 6.4 expects events to be a pointer. */
259 DMEV_ISSET(DM_EVENT_READ, events);
261 return 0;
263 ''',
264 'USEABLE_DMAPI_LIBRARY',
265 addmain=False,
266 execute=False,
267 lib=samba_dmapi_lib,
268 msg='Checking whether DMAPI lib '+samba_dmapi_lib+' can be used')
269 if not conf.CONFIG_SET('USEABLE_DMAPI_LIBRARY'):
270 have_dmapi = False
271 broken_dmapi = "no usable DMAPI library found"
273 if have_dmapi:
274 Logs.info("Building with DMAPI support.")
275 conf.env['dmapi_lib'] = samba_dmapi_lib
276 conf.DEFINE('USE_DMAPI', 1)
277 else:
278 if Options.options.with_dmapi == False:
279 Logs.info("Building without DMAPI support (--without-dmapi).")
280 elif Options.options.with_dmapi == True:
281 Logs.error("DMAPI support not available: " + broken_dmapi)
282 conf.fatal('DMAPI support requested but not found.');
283 else:
284 Logs.warn("Building without DMAPI support: " + broken_dmapi)
285 conf.env['dmapi_lib'] = ''
287 # Check for various members of the stat structure
288 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_blocks', define='HAVE_STAT_ST_BLOCKS',
289 headers='sys/stat.h')
290 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_blksize', define='HAVE_STAT_ST_BLKSIZE',
291 headers='sys/stat.h')
292 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_flags', define='HAVE_STAT_ST_FLAGS',
293 headers='sys/types.h sys/stat.h unistd.h')
295 if conf.env.HAVE_BLKCNT_T:
296 conf.CHECK_CODE('''
297 static int test_array[1 - 2 * !(((long int)(sizeof(blkcnt_t))) <= 4)];''',
298 'SIZEOF_BLKCNT_T_4',
299 headers='replace.h sys/types.h sys/stat.h unistd.h',
300 msg="Checking whether blkcnt_t is 32 bit")
302 # If sizeof is 4 it can't be 8
303 if conf.env.HAVE_BLKCNT_T:
304 if not conf.CONFIG_SET('SIZEOF_BLKCNT_T_4'):
305 conf.CHECK_CODE('''
306 static int test_array[1 - 2 * !(((long int)(sizeof(blkcnt_t))) <= 8)];''',
307 'SIZEOF_BLKCNT_T_8',
308 headers='replace.h sys/types.h sys/stat.h unistd.h',
309 msg="Checking whether blkcnt_t is 64 bit")
311 # Check for POSIX capability support
312 conf.CHECK_FUNCS_IN('cap_get_proc', 'cap', headers='sys/capability.h')
314 if conf.env.HAVE_SYS_CAPABILITY_H:
315 conf.CHECK_CODE('''
316 cap_t cap;
317 cap_value_t vals[1];
318 if (!(cap = cap_get_proc())) exit(1);
319 vals[0] = CAP_CHOWN;
320 cap_set_flag(cap, CAP_INHERITABLE, 1, vals, CAP_CLEAR);
321 cap_set_proc(cap);''',
322 'HAVE_POSIX_CAPABILITIES', execute=True, lib="cap",
323 headers='sys/capability.h',
324 msg="Checking whether POSIX capabilities are available")
326 conf.CHECK_CODE('int i;', 'BROKEN_NISPLUS_INCLUDE_FILES',
327 headers='sys/types.h sys/acl.h rpcsvc/nis.h',
328 msg="Checking for broken nisplus include files")
330 # Check if the compiler will optimize out functions
331 conf.CHECK_CODE('''
332 #include <sys/types.h>
333 size_t __unsafe_string_function_usage_here_size_t__(void);
334 #define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
335 static size_t push_string_check_fn(void *dest, const char *src, size_t dest_len) {
336 return 0;
339 #define push_string_check(dest, src, dest_len) \
340 (CHECK_STRING_SIZE(dest, dest_len) \
341 ? __unsafe_string_function_usage_here_size_t__() \
342 : push_string_check_fn(dest, src, dest_len))
344 int main(int argc, char **argv) {
345 char outbuf[1024];
346 char *p = outbuf;
347 const char *foo = "bar";
348 p += 31 + push_string_check(p + 31, foo, sizeof(outbuf) - (p + 31 - outbuf));
349 return 0;
350 }''', 'HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS',
351 addmain=False,
352 add_headers=False,
353 msg="Checking if the compiler will optimize out functions")
355 # Check if the compiler supports the LL suffix on long long integers
356 # AIX needs this
357 conf.CHECK_CODE('long long i = 0x8000000000LL', 'COMPILER_SUPPORTS_LL',
358 headers='stdio.h',
359 msg="Checking for LL suffix on long long integers")
361 conf.CHECK_FUNCS('''
362 DNSServiceRegister
363 atexit
364 chflags
365 fchflags
366 chmod
367 crypt16
368 devnm
369 endmntent
370 execl
371 fchmod
372 fchown
373 fseeko
374 fsync
375 futimens
376 getauthuid
377 getcwd
378 getgrent
379 getgrnam
380 getgrouplist
381 getgrset
382 getmntent
383 getpagesize
384 getpwanam
385 getpwent_r
386 getrlimit
387 glob
388 grantpt
389 hstrerror
390 initgroups
391 innetgr
392 llseek
393 lutimes
394 memalign
395 mknod
396 mlock
397 mlockall
398 munlock
399 munlockall
400 pathconf poll
401 posix_memalign
402 pread
403 pwrite
404 rdchk
405 select
406 setenv
407 setgidx
408 setgroups
409 setlocale
410 setluid
411 setmntent
412 setpgid
413 setpriv
414 setsid
415 setuidx
416 statvfs
417 strcasecmp
418 strchr
419 strpbrk
420 strsignal
421 strtol
422 strupr
423 sysconf
424 sysctl
425 sysctlbyname
426 syslog
427 timegm
428 utimensat
429 vsyslog
430 ''')
432 conf.CHECK_SAMBA3_CHARSET() # see build/charset.py
434 # FIXME: these should be tests for features, but the old build system just
435 # checks for OSes.
436 host_os = sys.platform
437 Logs.info("building on %s" % host_os)
439 # Python doesn't have case switches... :/
440 # FIXME: original was *linux* | gnu* | k*bsd*-gnu | kopensolaris*-gnu | *qnx*)
441 # the search for .rfind('gnu') covers gnu* and *-gnu is that too broad?
443 conf.SET_TARGET_TYPE('sunacl', 'EMPTY')
444 if (host_os.rfind('linux') > -1) or (host_os.rfind('gnu') > -1) or (host_os.rfind('qnx') > -1):
445 if host_os.rfind('linux') > -1:
446 conf.DEFINE('LINUX', '1')
447 elif host_os.rfind('qnx') > -1:
448 conf.DEFINE('QNX', '1')
449 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
450 elif (host_os.rfind('darwin') > -1):
451 conf.DEFINE('DARWINOS', 1)
452 conf.ADD_CFLAGS('-fno-common')
453 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
454 elif (host_os.rfind('freebsd') > -1):
455 conf.DEFINE('FREEBSD', 1)
456 if conf.CHECK_HEADERS('sunacl.h'):
457 conf.DEFINE('HAVE_FREEBSD_SUNACL_H', '1')
458 conf.CHECK_FUNCS_IN(['acl'], 'sunacl')
459 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
460 elif (host_os.rfind('irix') > -1):
461 conf.DEFINE('IRIX', 1)
462 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
463 elif (host_os.rfind('aix') > -1):
464 conf.DEFINE('AIX', 1)
465 conf.DEFINE('STAT_ST_BLOCKSIZE', 'DEV_BSIZE')
466 elif (host_os.rfind('hpux') > -1):
467 conf.DEFINE('HPUX', 1)
468 conf.DEFINE('STAT_ST_BLOCKSIZE', '8192')
469 elif (host_os.rfind('osf') > -1):
470 conf.DEFINE('OSF1', 1)
471 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
473 # FIXME: Add more checks here.
474 else:
475 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
477 if Options.options.with_acl_support:
478 if (host_os.rfind('hpux') > -1):
479 Logs.info('Using HPUX ACLs')
480 conf.DEFINE('HAVE_HPUX_ACLS',1)
481 conf.DEFINE('POSIX_ACL_NEEDS_MASK',1)
482 required_static_modules.extend(['vfs_hpuxacl'])
483 elif (host_os.rfind('aix') > -1):
484 Logs.info('Using AIX ACLs')
485 conf.DEFINE('HAVE_AIX_ACLS',1)
486 required_static_modules.extend(['vfs_aixacl', 'vfs_aixacl2'])
487 elif (host_os.rfind('darwin') > -1):
488 Logs.warn('ACLs on Darwin currently not supported')
489 conf.fatal("ACL support not available on Darwin/MacOS. "
490 "Use --without-acl-support for building without "
491 "ACL support. "
492 "ACL support is required to change permissions "
493 "from Windows clients.")
494 else:
495 conf.CHECK_FUNCS_IN(['acl_get_file'], 'acl')
496 if conf.CHECK_CODE('''
497 acl_t acl;
498 int entry_id;
499 acl_entry_t *entry_p;
500 return acl_get_entry(acl, entry_id, entry_p);
501 ''',
502 'HAVE_POSIX_ACLS',
503 headers='sys/types.h sys/acl.h', link=False,
504 msg="Checking for POSIX ACL support") :
505 conf.CHECK_CODE('''
506 acl_permset_t permset_d;
507 acl_perm_t perm;
508 return acl_get_perm_np(permset_d, perm);
509 ''',
510 'HAVE_ACL_GET_PERM_NP',
511 headers='sys/types.h sys/acl.h', link=True,
512 msg="Checking whether acl_get_perm_np() is available")
513 # source3/lib/sysacls.c calls posixacl_sys_acl_get_file()
514 required_static_modules.extend(['vfs_posixacl'])
515 conf.CHECK_VARIABLE('ACL_EVERYONE', headers='sys/acl.h')
516 elif conf.CHECK_FUNCS_IN(['facl'], 'sec'):
517 Logs.info('Using solaris or UnixWare ACLs')
518 conf.DEFINE('HAVE_SOLARIS_UNIXWARE_ACLS',1)
519 required_static_modules.extend(['vfs_solarisacl'])
520 else:
521 conf.fatal("ACL support not found. Try installing libacl1-dev "
522 "or libacl-devel. "
523 "Otherwise, use --without-acl-support to build "
524 "without ACL support. "
525 "ACL support is required to change permissions from "
526 "Windows clients.")
528 if conf.CHECK_FUNCS('dirfd'):
529 conf.DEFINE('HAVE_DIRFD_DECL', 1)
531 conf.CHECK_CODE('struct statfs fsd; int r = fstatfs(AT_FDCWD, &fsd);',
532 'HAVE_FSTATFS',
533 msg='Checking for fstatfs',
534 headers='sys/statfs.h fcntl.h')
535 conf.CHECK_CODE('struct statfs fsd; fsid_t fsid = fsd.f_fsid; return statfs(".", &fsd);',
536 'HAVE_STATFS_F_FSID',
537 msg="vfs_fileid checking for statfs() and struct statfs.f_fsid",
538 headers='sys/types.h sys/statfs.h',
539 execute=True)
541 if conf.CONFIG_SET('HAVE_FALLOCATE'):
542 conf.CHECK_CODE('''
543 int ret = fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 10);''',
544 'HAVE_LINUX_FALLOCATE',
545 msg="Checking whether the Linux 'fallocate' function is available",
546 headers='unistd.h sys/types.h fcntl.h linux/falloc.h')
547 conf.CHECK_CODE('''
548 int ret = fallocate(0, FALLOC_FL_PUNCH_HOLE, 0, 10);''',
549 'HAVE_FALLOC_FL_PUNCH_HOLE',
550 msg="Checking whether Linux 'fallocate' supports hole-punching",
551 headers='unistd.h sys/types.h fcntl.h linux/falloc.h')
553 conf.CHECK_CODE('''
554 int ret = lseek(0, 0, SEEK_HOLE);
555 ret = lseek(0, 0, SEEK_DATA);''',
556 'HAVE_LSEEK_HOLE_DATA',
557 msg="Checking whether lseek supports hole/data seeking",
558 headers='unistd.h sys/types.h')
560 conf.CHECK_CODE('''
561 ssize_t err = readahead(0,0,0x80000);''',
562 'HAVE_LINUX_READAHEAD',
563 msg="Checking whether Linux readahead is available",
564 headers='unistd.h fcntl.h')
565 conf.CHECK_DECLS('readahead', headers='fcntl.h', always=True)
567 conf.CHECK_CODE('int fd = openat(AT_FDCWD, ".", O_RDONLY);',
568 'HAVE_OPENAT',
569 msg='Checking for openat',
570 headers='fcntl.h')
572 conf.CHECK_CODE('''
573 struct msghdr msg;
574 union {
575 struct cmsghdr cm;
576 char control[CMSG_SPACE(sizeof(int))];
577 } control_un;
578 msg.msg_control = control_un.control;
579 msg.msg_controllen = sizeof(control_un.control);
580 ''',
581 'HAVE_STRUCT_MSGHDR_MSG_CONTROL',
582 msg='Checking if we can use msg_control for passing file descriptors',
583 headers='sys/types.h stdlib.h stddef.h sys/socket.h sys/un.h')
584 conf.CHECK_CODE('''
585 struct msghdr msg;
586 int fd;
587 msg.msg_accrights = (caddr_t) &fd;
588 msg.msg_accrightslen = sizeof(fd);
589 ''',
590 'HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS',
591 msg='Checking if we can use msg_accrights for passing file descriptors',
592 headers='sys/types.h stdlib.h stddef.h sys/socket.h sys/un.h')
594 if Options.options.with_winbind:
595 conf.env.build_winbind = True
596 conf.DEFINE('WITH_WINBIND', '1')
598 conf.find_program('awk', var='AWK')
600 conf.CHECK_HEADERS('asm/types.h')
602 conf.CHECK_CODE('dev_t dev; int i = major(dev); return 0', "HAVE_DEVICE_MAJOR_FN",
603 headers='sys/sysmacros.h unistd.h sys/types.h',
604 msg="Checking for major macro")
606 conf.CHECK_CODE('dev_t dev; int i = minor(dev); return 0', "HAVE_DEVICE_MINOR_FN",
607 headers='sys/sysmacros.h unistd.h sys/types.h',
608 msg="Checking for minor macro")
610 conf.CHECK_STRUCTURE_MEMBER('struct dirent', 'd_off',
611 headers='unistd.h sys/types.h dirent.h',
612 define='HAVE_DIRENT_D_OFF')
614 if (conf.CONFIG_SET('HAVE_GETDOMAINNAME')):
615 conf.DEFINE('HAVE_NETGROUP', '1')
617 # Look for CUPS
618 if Options.options.with_cups:
619 conf.find_program('cups-config', var='CUPS_CONFIG')
620 if conf.env.CUPS_CONFIG:
621 # we would normally use --libs here, but cups-config incorrectly adds
622 # gssapi_krb5 and other libraries to its --libs output. That breaks the use
623 # of an in-tree heimdal kerberos
624 conf.CHECK_CFG(path=conf.env.CUPS_CONFIG, args="--cflags --ldflags",
625 package="", uselib_store="CUPS")
626 conf.CHECK_HEADERS('cups/cups.h cups/language.h', lib='cups')
627 conf.CHECK_FUNCS_IN('httpConnect httpConnect2 httpConnectEncrypt', 'cups')
628 if conf.CONFIG_SET('HAVE_CUPS_CUPS_H') and conf.CONFIG_SET('HAVE_CUPS_LANGUAGE_H'):
629 conf.DEFINE('HAVE_CUPS', '1')
630 else:
631 conf.undefine('HAVE_CUPS')
632 conf.SET_TARGET_TYPE('cups', 'EMPTY')
633 else:
634 # define an empty subsystem for cups, to allow it to be used as an empty dependency
635 conf.SET_TARGET_TYPE('cups', 'EMPTY')
637 if Options.options.with_iprint:
638 if conf.CONFIG_SET('HAVE_CUPS'):
639 conf.DEFINE('HAVE_IPRINT', '1')
640 else:
641 Logs.warn("--enable-iprint=yes but cups support not sufficient")
642 if Options.options.with_syslog:
643 conf.DEFINE('WITH_SYSLOG', '1')
644 if Options.options.with_automount:
645 conf.DEFINE('WITH_AUTOMOUNT', '1')
647 if Options.options.with_ads == False:
648 use_ads = False
649 use_ads_krb5 = False
650 use_ads_ldap = False
651 else:
652 use_ads = True
653 use_ads_krb5 = True
654 use_ads_ldap = True
655 if not conf.CONFIG_SET('HAVE_ENCTYPE_ARCFOUR_HMAC_MD5') and \
656 not conf.CONFIG_SET('HAVE_ENCTYPE_ARCFOUR_HMAC'):
657 Logs.warn("arcfour-hmac-md5 encryption type not found in -lkrb5")
658 use_ads_krb5 = False
659 if not conf.CONFIG_SET('HAVE_KRB5_MK_REQ_EXTENDED'):
660 Logs.warn("krb5_mk_req_extended not found in -lkrb5")
661 use_ads_krb5 = False
662 if not conf.CONFIG_SET('HAVE_KRB5_GET_HOST_REALM'):
663 Logs.warn("krb5_get_host_realm not found in -lkrb5")
664 use_ads_krb5 = False
665 if not conf.CONFIG_SET('HAVE_KRB5_FREE_HOST_REALM'):
666 Logs.warn("krb5_free_host_realm not found in -lkrb5")
667 use_ads_krb5 = False
668 if not conf.CONFIG_SET('HAVE_KRB5_FWD_TGT_CREDS'):
669 Logs.warn("krb5_fwd_tgt_creds found in -lkrb5")
670 use_ads_krb5 = False
671 if not conf.CONFIG_SET('HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC'):
672 Logs.warn("krb5_get_init_creds_opt_alloc not found in -lkrb5")
673 use_ads_krb5 = False
674 if not conf.CONFIG_SET('KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT'):
675 Logs.warn("krb5_get_init_creds_opt_free was not found or was too old in -lkrb5")
676 use_ads_krb5 = False
677 if not conf.CONFIG_SET('HAVE_KRB5_GET_RENEWED_CREDS'):
678 Logs.warn("krb5_get_renewed_creds not found in -lkrb5")
679 use_ads_krb5 = False
680 if not conf.CONFIG_SET('HAVE_KRB5_PRINCIPAL_COMPARE_ANY_REALM'):
681 Logs.warn("krb5_principal_compare_any_realm not found in -lkrb5")
682 use_ads_krb5 = False
683 if not conf.CONFIG_SET('HAVE_KRB5_C_STRING_TO_KEY') and \
684 not conf.CONFIG_SET('HAVE_KRB5_STRING_TO_KEY_SALT'):
685 Logs.warn("krb5_c_string_to_key not found in -lkrb5")
686 use_ads_krb5 = False
687 if not conf.CONFIG_SET('HAVE_KRB5_PRINCIPAL2SALT') and \
688 not conf.CONFIG_SET('HAVE_KRB5_GET_PW_SALT'):
689 Logs.warn("no CREATE_KEY_FUNCTIONS detected")
690 use_ads_krb5 = False
691 if not conf.CONFIG_SET('HAVE_KRB5_GET_PERMITTED_ENCTYPES') and \
692 not conf.CONFIG_SET('HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES'):
693 Logs.warn("no GET_ENCTYPES_FUNCTIONS detected")
694 use_ads_krb5 = False
695 if not conf.CONFIG_SET('HAVE_KRB5_KT_FREE_ENTRY') and \
696 not conf.CONFIG_SET('HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS'):
697 Logs.warn("no KT_FREE_FUNCTION detected")
698 use_ads_krb5 = False
699 if not conf.CONFIG_SET('HAVE_KRB5_C_VERIFY_CHECKSUM'):
700 Logs.warn("krb5_c_verify_checksum_compare not found in -lkrb5")
701 use_ads_krb5 = False
703 # We don't actually use
704 # gsskrb5_extract_authz_data_from_sec_context, but it is a
705 # clue that this Heimdal, which does the PAC processing we
706 # need on the standard gss_inquire_sec_context_by_oid
707 if not conf.CONFIG_SET('HAVE_GSS_GET_NAME_ATTRIBUTE') and \
708 not (conf.CONFIG_SET('HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT') and \
709 conf.CONFIG_SET('HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID')):
710 Logs.warn("need either gss_get_name_attribute or gsskrb5_extract_authz_data_from_sec_context and gss_inquire_sec_context_by_oid in -lgssapi for PAC support")
711 use_ads_krb5 = False
713 if not conf.CONFIG_SET('HAVE_GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT'):
714 Logs.warn("need gss_krb5_export_lucid_sec_context for SPNEGO and gss_wrap support")
715 use_ads_krb5 = False
717 if use_ads_krb5:
718 conf.DEFINE('HAVE_KRB5', '1')
719 conf.env['HAVE_KRB5'] = '1'
720 else:
721 conf.undefine('HAVE_KRB5_H')
722 conf.undefine('HAVE_GSSAPI_H')
723 conf.undefine('HAVE_GSSAPI_GSSAPI_GENERIC_H')
724 conf.undefine('HAVE_GSSAPI_GSSAPI_H')
725 use_ads = False
727 if not conf.CONFIG_SET('HAVE_LDAP_TRANSPORT_WRAPPING'):
728 Logs.warn("need ber_sockbuf_add_io() and LDAP_OPT_SOCKBUF for SASL and TLS support")
729 use_ads = False
730 use_ads_ldap = False
732 if use_ads:
733 conf.DEFINE('HAVE_ADS', '1')
734 Logs.info("Building with Active Directory support.")
735 # these have broken dependencies
736 forced_shared_modules.extend(['idmap_ad', 'idmap_rfc2307'])
737 elif Options.options.with_ads == False:
738 Logs.info("Building without Active Directory support (--without-ads).")
739 if not Options.options.without_ad_dc:
740 conf.fatal("Building --without-ads requires also "
741 "building --without-ad-dc.")
742 else:
743 if not use_ads_krb5:
744 Logs.warn("Active Directory support not available: krb5 libs don't have all required features")
745 if not use_ads_ldap:
746 Logs.warn("Active Directory support not available: LDAP support is not available.")
747 if Options.options.with_ads:
748 conf.fatal("Active Directory support not found. Use --without-ads "
749 "for building without Active Directory support. "
750 "ADS support improves communication with "
751 "Active Directory domain controllers.")
752 else:
753 # this is the auto-mode case
754 Logs.warn("Building without Active Directory support.")
757 if Options.options.with_utmp:
758 conf.env.with_utmp = True
759 if not conf.CHECK_HEADERS('utmp.h'): conf.env.with_utmp = False
760 conf.CHECK_FUNCS('pututline pututxline updwtmp updwtmpx getutmpx')
761 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_name', headers='utmp.h',
762 define='HAVE_UT_UT_NAME')
763 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_user', headers='utmp.h',
764 define='HAVE_UT_UT_USER')
765 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_id', headers='utmp.h',
766 define='HAVE_UT_UT_ID')
767 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_host', headers='utmp.h',
768 define='HAVE_UT_UT_HOST')
769 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_time', headers='utmp.h',
770 define='HAVE_UT_UT_TIME')
771 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_tv', headers='utmp.h',
772 define='HAVE_UT_UT_TV')
773 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_type', headers='utmp.h',
774 define='HAVE_UT_UT_TYPE')
775 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_pid', headers='utmp.h',
776 define='HAVE_UT_UT_PID')
777 conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_exit.e_exit', headers='utmp.h',
778 define='HAVE_UT_UT_EXIT')
779 conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_syslen', headers='utmpx.h',
780 define='HAVE_UX_UT_SYSLEN')
781 conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_host', headers='utmpx.h',
782 define='HAVE_UX_UT_HOST')
783 conf.CHECK_CODE('struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg);',
784 'PUTUTLINE_RETURNS_UTMP', headers='utmp.h',
785 msg="Checking whether pututline returns pointer")
786 conf.CHECK_SIZEOF(['((struct utmp *)NULL)->ut_line'], headers='utmp.h',
787 define='SIZEOF_UTMP_UT_LINE', critical=False)
788 if not conf.CONFIG_SET('SIZEOF_UTMP_UT_LINE'):
789 conf.env.with_utmp = False
790 elif int(conf.env.SIZEOF_UTMP_UT_LINE) < 15:
791 conf.env.with_utmp = False
792 if conf.env.with_utmp:
793 conf.DEFINE('WITH_UTMP', 1)
794 else:
795 Logs.warn("--with-utmp but utmp support not sufficient")
797 if Options.options.with_avahi:
798 conf.env.with_avahi = True
799 if not conf.CHECK_HEADERS('avahi-common/watch.h avahi-client/client.h'): conf.env.with_avahi = False
800 if not conf.CHECK_FUNCS_IN('avahi_client_new', 'avahi-client'): conf.env.with_avahi = False
801 if not conf.CHECK_FUNCS_IN('avahi_strerror', 'avahi-common'): conf.env.with_avahi = False
802 if conf.env.with_avahi:
803 conf.DEFINE('WITH_AVAHI_SUPPORT', 1)
804 else:
805 conf.SET_TARGET_TYPE('avahi-common', 'EMPTY')
806 conf.SET_TARGET_TYPE('avahi-client', 'EMPTY')
808 if Options.options.with_iconv:
809 conf.env.with_iconv = True
810 if not conf.CHECK_FUNCS_IN('iconv_open', 'iconv', headers='iconv.h'):
811 conf.env.with_iconv = False
812 if conf.env.with_iconv:
813 conf.DEFINE('HAVE_ICONV', 1)
815 if Options.options.with_pam:
816 use_pam=True
817 conf.CHECK_HEADERS('security/pam_appl.h pam/pam_appl.h')
818 if not conf.CONFIG_SET('HAVE_SECURITY_PAM_APPL_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_APPL_H'):
819 Logs.warn("--with-pam=yes but pam_appl.h not found")
820 use_pam=False
821 conf.CHECK_FUNCS_IN('pam_get_data', 'pam')
822 conf.CHECK_HEADERS('security/pam_modules.h pam/pam_modules.h')
823 if not conf.CONFIG_SET('HAVE_SECURITY_PAM_MODULES_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_MODULES_H'):
824 Logs.warn("--with-pam=yes but pam_modules.h not found")
825 use_pam=False
826 conf.CHECK_HEADERS('security/pam_ext.h security/_pam_macros.h')
827 conf.CHECK_HEADERS('pam/pam_ext.h pam/_pam_macros.h')
828 conf.CHECK_FUNCS_IN('pam_vsyslog', 'pam')
829 conf.CHECK_CODE('''
830 #if defined(HAVE_SECURITY_PAM_APPL_H)
831 #include <security/pam_appl.h>
832 #elif defined(HAVE_PAM_PAM_APPL_H)
833 #include <pam/pam_appl.h>
834 #endif
835 pam_set_item(0, PAM_RHOST, 0);
836 ''',
837 'HAVE_PAM_RHOST',
838 lib='pam',
839 msg="Checking whether PAM_RHOST is available");
840 conf.CHECK_CODE('''
841 #if defined(HAVE_SECURITY_PAM_APPL_H)
842 #include <security/pam_appl.h>
843 #elif defined(HAVE_PAM_PAM_APPL_H)
844 #include <pam/pam_appl.h>
845 #endif
846 pam_set_item(0, PAM_TTY, 0);
847 ''',
848 'HAVE_PAM_TTY',
849 lib='pam',
850 msg="Checking whether PAM_TTY is available");
851 conf.CHECK_CODE('''
852 #if (!defined(LINUX))
854 #define PAM_EXTERN extern
855 #if defined(HAVE_SECURITY_PAM_APPL_H)
856 #include <security/pam_appl.h>
857 #elif defined(HAVE_PAM_PAM_APPL_H)
858 #include <pam/pam_appl.h>
859 #endif
861 #endif
863 #if defined(HAVE_SECURITY_PAM_MODULES_H)
864 #include <security/pam_modules.h>
865 #elif defined(HAVE_PAM_PAM_MODULES_H)
866 #include <pam/pam_modules.h>
867 #endif
869 #if defined(HAVE_SECURITY__PAM_MACROS_H)
870 #include <security/_pam_macros.h>
871 #elif defined(HAVE_PAM__PAM_MACROS_H)
872 #include <pam/_pam_macros.h>
873 #endif
875 #ifdef HAVE_SECURITY_PAM_EXT_H
876 #include <security/pam_ext.h>
877 #endif
879 int i; i = PAM_RADIO_TYPE;
880 ''',
881 'HAVE_PAM_RADIO_TYPE',
882 lib='pam',
883 msg="Checking whether PAM_RADIO_TYPE is available");
884 if use_pam:
885 conf.DEFINE('WITH_PAM', 1)
886 conf.DEFINE('WITH_PAM_MODULES', 1)
887 else:
888 conf.fatal("PAM support is enabled but prerequisite libraries "
889 "or headers not found. Use --without-pam to disable "
890 "PAM support.");
892 seteuid = False
895 # Ensure we select the correct set of system calls on Linux.
897 if (host_os.rfind('linux') > -1):
898 conf.CHECK_CODE('''
899 #if defined(HAVE_UNISTD_H)
900 #include <unistd.h>
901 #endif
902 #include <stdlib.h>
903 #include <stdio.h>
904 #include <sys/types.h>
905 #include <errno.h>
907 #ifdef HAVE_SYS_PRIV_H
908 #include <sys/priv.h>
909 #endif
910 #ifdef HAVE_SYS_ID_H
911 #include <sys/id.h>
912 #endif
914 #if defined(HAVE_SYSCALL_H)
915 #include <syscall.h>
916 #endif
918 #if defined(HAVE_SYS_SYSCALL_H)
919 #include <sys/syscall.h>
920 #endif
922 syscall(SYS_setresuid32, -1, -1, -1);
923 syscall(SYS_setresgid32, -1, -1, -1);
924 syscall(SYS_setreuid32, -1, -1);
925 syscall(SYS_setregid32, -1, -1);
926 syscall(SYS_setuid32, -1);
927 syscall(SYS_setgid32, -1);
928 syscall(SYS_setgroups32, 0, NULL);
929 ''',
930 'USE_LINUX_32BIT_SYSCALLS',
931 msg="Checking whether Linux should use 32-bit credential calls");
933 if (conf.CONFIG_SET('USE_LINUX_32BIT_SYSCALLS')):
934 seteuid = conf.CHECK_CODE('''
935 #define AUTOCONF_TEST 1
936 #define HAVE_LINUX_THREAD_CREDENTIALS 1
937 #define USE_LINUX_32BIT_SYSCALLS 1
938 #include "../lib/util/setid.c"
939 #include "./lib/util_sec.c"
940 ''',
941 'HAVE_LINUX_THREAD_CREDENTIALS',
942 addmain=False,
943 execute=True,
944 msg="Checking whether we can use Linux thread-specific credentials with 32-bit system calls")
945 else:
946 seteuid = conf.CHECK_CODE('''
947 #define AUTOCONF_TEST 1
948 #define HAVE_LINUX_THREAD_CREDENTIALS 1
949 #include "../lib/util/setid.c"
950 #include "./lib/util_sec.c"
951 ''',
952 'HAVE_LINUX_THREAD_CREDENTIALS',
953 addmain=False,
954 execute=True,
955 msg="Checking whether we can use Linux thread-specific credentials")
956 if not seteuid:
957 seteuid = conf.CHECK_CODE('''
958 #define AUTOCONF_TEST 1
959 #define USE_SETREUID 1
960 #include "../lib/util/setid.c"
961 #include "./lib/util_sec.c"
962 ''',
963 'USE_SETREUID',
964 addmain=False,
965 execute=True,
966 msg="Checking whether setreuid is available")
967 if not seteuid:
968 seteuid = conf.CHECK_CODE('''
969 #define AUTOCONF_TEST 1
970 #define USE_SETRESUID 1
971 #include "../lib/util/setid.c"
972 #include "./lib/util_sec.c"
973 ''',
974 'USE_SETRESUID',
975 addmain=False,
976 execute=True,
977 msg="Checking whether setresuid is available")
978 if not seteuid:
979 seteuid = conf.CHECK_CODE('''
980 #define AUTOCONF_TEST 1
981 #define USE_SETEUID 1
982 #include "../lib/util/setid.c"
983 #include "./lib/util_sec.c"
984 ''',
985 'USE_SETEUID',
986 addmain=False,
987 execute=True,
988 msg="Checking whether seteuid is available")
989 if not seteuid:
990 seteuid = conf.CHECK_CODE('''
991 #define AUTOCONF_TEST 1
992 #define USE_SETUIDX 1
993 #include "../lib/util/setid.c"
994 #include "./lib/util_sec.c"
995 ''',
996 'USE_SETUIDX',
997 addmain=False,
998 execute=True,
999 mandatory=True,
1000 msg="Checking whether setuidx is available")
1001 # valgrind.h or valgrind/valgrind.h is checked in lib/replace/wscript
1002 if Options.options.developer:
1003 if conf.CONFIG_SET('HAVE_VALGRIND_H') or conf.CONFIG_SET('HAVE_VALGRIND_VALGRIND_H'):
1004 conf.DEFINE('VALGRIND', '1')
1006 if conf.CHECK_CODE('''
1007 #include <bits/sockaddr.h>
1008 #include <linux/netlink.h>
1009 ''',
1010 'HAVE_LINUX_NETLINK_H',
1011 msg="Checking whether Linux netlink is available"):
1013 conf.CHECK_CODE('''
1014 #include <bits/sockaddr.h>
1015 #include <linux/netlink.h>
1016 #include <linux/rtnetlink.h>
1017 ''',
1018 'HAVE_LINUX_RTNETLINK_H',
1019 msg='Checking whether Linux rtnetlink is available')
1021 conf.CHECK_CODE('''
1022 #include "../tests/fcntl_lock.c"
1023 ''',
1024 'HAVE_FCNTL_LOCK',
1025 addmain=False,
1026 execute=True,
1027 msg='Checking whether fcntl locking is available')
1029 conf.CHECK_CODE('''
1030 #include <unistd.h>
1031 #include <sys/types.h>
1032 #include <sys/stat.h>
1033 #include <fcntl.h>
1034 #include <errno.h>
1036 #define DATA "ofdtest.fcntl"
1038 int main(void) {
1039 struct flock lck = {
1040 .l_whence = SEEK_SET,
1041 .l_type = F_WRLCK,
1042 .l_start = 0,
1043 .l_len = 1,
1044 .l_pid = 0,
1046 int ret;
1047 int fd1;
1048 int fd2;
1049 char *testdir = getenv("TESTDIR");
1051 if (testdir) {
1052 if (chdir(testdir) != 0) {
1053 goto err;
1057 unlink(DATA);
1058 fd1 = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600);
1059 fd2 = open(DATA, O_RDWR);
1060 if (fd1 == -1 || fd2 == -1) {
1061 goto err;
1063 ret = fcntl(fd1,F_OFD_SETLKW,&lck);
1064 if (ret == -1) {
1065 goto err;
1067 ret = fcntl(fd2,F_OFD_SETLK,&lck);
1068 if (ret != -1) {
1069 goto err;
1071 if (errno != EAGAIN) {
1072 goto err;
1074 ret = fcntl(fd2,F_OFD_GETLK,&lck);
1075 if (ret == -1) {
1076 goto err;
1078 unlink(DATA);
1079 exit(0);
1080 err:
1081 unlink(DATA);
1082 exit(1);
1083 }''',
1084 'HAVE_OFD_LOCKS',
1085 addmain=False,
1086 execute=True,
1087 msg="Checking whether fcntl lock supports open file description locks")
1089 conf.CHECK_CODE('''
1090 #include <fcntl.h>
1091 #include <unistd.h>
1092 #include <stdlib.h>
1093 #include <sys/socket.h>
1095 int main(void)
1097 int sockfd, ret;
1098 struct f_owner_ex owner, get_owner;
1100 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1101 if (sockfd == -1) {
1102 goto err;
1105 owner.type = F_OWNER_PID;
1106 owner.pid = getpid();
1108 ret = fcntl(sockfd, F_SETOWN_EX, &owner);
1109 if (ret == -1) {
1110 goto err;
1113 ret = fcntl(sockfd, F_GETOWN_EX, &get_owner);
1114 if (ret == -1) {
1115 goto err;
1118 if (get_owner.type != F_OWNER_PID) {
1119 goto err;
1122 if (get_owner.pid != getpid()) {
1123 goto err;
1126 close(sockfd);
1127 exit(0);
1128 err:
1129 close(sockfd);
1130 exit(1);
1131 }''',
1132 'HAVE_F_OWNER_EX',
1133 addmain=False,
1134 execute=True,
1135 msg="Checking whether fcntl supports flags to send direct I/O availability signals")
1137 conf.CHECK_CODE('''
1138 #include <fcntl.h>
1139 #include <unistd.h>
1140 #include <stdlib.h>
1141 #include <stdint.h>
1143 #define DATA "hinttest.fcntl"
1145 int main(void)
1147 uint64_t hint, get_hint;
1148 int fd;
1150 fd = open(DATA, O_RDONLY | O_CREAT | O_EXCL);
1151 if (fd == -1) {
1152 goto err;
1155 hint = RWH_WRITE_LIFE_SHORT;
1156 int ret = fcntl(fd, F_SET_RW_HINT, &hint);
1157 if (ret == -1) {
1158 goto err;
1161 ret = fcntl(fd, F_GET_RW_HINT, &get_hint);
1162 if (ret == -1) {
1163 goto err;
1166 if (get_hint != RWH_WRITE_LIFE_SHORT) {
1167 goto err;
1170 hint = RWH_WRITE_LIFE_EXTREME;
1171 ret = fcntl(fd, F_SET_FILE_RW_HINT, &hint);
1172 if (ret == -1) {
1173 goto err;
1176 ret = fcntl(fd, F_GET_FILE_RW_HINT, &get_hint);
1177 if (ret == -1) {
1178 goto err;
1181 if (get_hint != RWH_WRITE_LIFE_EXTREME) {
1182 goto err;
1185 close(fd);
1186 unlink(DATA);
1187 exit(0);
1188 err:
1189 close(fd);
1190 unlink(DATA);
1191 exit(1);
1192 }''',
1193 'HAVE_RW_HINTS',
1194 addmain=False,
1195 execute=True,
1196 msg="Checking whether fcntl supports setting/getting hints")
1198 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec',
1199 define='HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') # Linux, Solaris
1200 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimensec',
1201 define='HAVE_STRUCT_STAT_ST_MTIMENSEC') # BSD, if defined _POSIX_SOURCE
1202 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimespec.tv_nsec',
1203 define='HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') # BSD, if not defined _POSIX_SOURCE
1204 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtime_n',
1205 define='HAVE_STRUCT_STAT_ST_MTIME_N') # AIX
1206 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_umtime',
1207 define='HAVE_STRUCT_STAT_ST_UMTIME') # Tru64
1208 if conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') or \
1209 conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMENSEC') or \
1210 conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') or \
1211 conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIME_N') or \
1212 conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_UMTIME'):
1213 conf.DEFINE('HAVE_STAT_HIRES_TIMESTAMPS', '1')
1215 # recent FreeBSD, NetBSD have creation timestamps called birthtime:
1216 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtime',
1217 define='HAVE_STRUCT_STAT_ST_BIRTHTIME')
1218 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimespec.tv_nsec',
1219 define='HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC')
1220 conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimensec',
1221 define='HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC')
1223 conf.CHECK_CODE('''
1224 ssize_t err = posix_fadvise(0,0,0x80000,POSIX_FADV_WILLNEED);
1225 ''',
1226 'HAVE_POSIX_FADVISE',
1227 msg='Checking whether posix_fadvise is available',
1228 headers='unistd.h fcntl.h')
1230 for v in ['_SC_NGROUPS_MAX', '_SC_NPROC_ONLN', '_SC_NPROCESSORS_ONLN', '_SC_PAGESIZE' ]:
1231 conf.CHECK_CODE('''
1232 #include <unistd.h>
1233 return sysconf(%s) == -1 ? 1 : 0;
1234 ''' % v,
1235 'SYSCONF%s' % v,
1236 msg='Checking whether sysconf(%s) is available' % v)
1238 conf.CHECK_CODE('''
1239 #include <sys/syscall.h>
1240 #include <unistd.h>
1241 syscall(SYS_initgroups, 16, NULL, NULL, 0);
1242 ''',
1243 'HAVE_DARWIN_INITGROUPS',
1244 msg='Checking whether to use the Darwin-specific initgroups system call')
1246 conf.CHECK_CODE('''struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));''',
1247 'HAVE_UTIMBUF',
1248 headers='sys/types.h utime.h',
1249 msg='Checking whether struct utimbuf is available')
1251 if conf.CHECK_CODE('''struct sigevent s;''',
1252 'HAVE_STRUCT_SIGEVENT',
1253 headers='sys/types.h stdlib.h stddef.h signal.h',
1254 msg='Checking whether we have the struct sigevent'):
1255 conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sival_ptr',
1256 define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIVAL_PTR',
1257 headers='signal.h');
1258 conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sigval_ptr',
1259 define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIGVAL_PTR',
1260 headers='signal.h');
1262 if os.path.exists('/proc/sys/kernel/core_pattern'):
1263 conf.DEFINE('HAVE_SYS_KERNEL_PROC_CORE_PATTERN', '1')
1265 if conf.CHECK_CODE('''
1266 #include <time.h>
1267 int main(void) {
1268 struct tm *tm;
1269 if (sizeof(time_t) == 8) {
1270 time_t max_time = 0x7fffffffffffffffll;
1271 tm = gmtime(&max_time);
1272 /* This should fail with 32-bit tm_year. */
1273 if (tm == NULL) {
1274 /* Max time_t that works with 32-bit int tm_year in struct tm. */
1275 max_time = 67768036191676799ll;
1276 tm = gmtime(&max_time);
1277 if (tm) {
1278 exit(0);
1282 exit(1);
1283 }''',
1284 '__TIME_T_MAX',
1285 addmain=False,
1286 execute=True,
1287 msg="Checking for the maximum value of the 'time_t' type"):
1288 conf.DEFINE('TIME_T_MAX', '67768036191676799ll')
1290 conf.CHECK_CODE('''
1291 #if defined(HAVE_UNISTD_H)
1292 #include <unistd.h>
1293 #endif
1294 #include <sys/types.h>
1295 #if defined(HAVE_SYS_SYSMACROS_H)
1296 #include <sys/sysmacros.h>
1297 #endif
1298 int main(void) { dev_t dev = makedev(1,2); return 0; }
1299 ''',
1300 'HAVE_MAKEDEV',
1301 addmain=False,
1302 msg='Checking whether the macro for makedev is available')
1304 conf.CHECK_CODE('''
1305 #include <stdio.h>
1306 #include <limits.h>
1307 #include <signal.h>
1308 #include <stdlib.h>
1310 void exit_on_core(int ignored) {
1311 exit(1);
1314 int main(void) {
1315 char *newpath;
1316 signal(SIGSEGV, exit_on_core);
1317 newpath = realpath("/tmp", NULL);
1318 exit((newpath != NULL) ? 0 : 1);
1320 ''',
1321 'REALPATH_TAKES_NULL',
1322 addmain=False,
1323 execute=True,
1324 msg='Checking whether the realpath function allows a NULL argument')
1326 conf.CHECK_CODE('''#include "../tests/ftruncate.c"''',
1327 'HAVE_FTRUNCATE_EXTEND',
1328 msg='Checking for ftruncate extend',
1329 addmain=False,
1330 execute=True)
1332 conf.CHECK_CODE('''#include "../tests/readlink.c"''',
1333 'HAVE_BROKEN_READLINK',
1334 msg='Checking for readlink breakage',
1335 addmain=False,
1336 execute=True)
1338 conf.SET_TARGET_TYPE('sendfile', 'EMPTY')
1339 conf.CHECK_LIB('sendfile')
1340 if not Options.options.with_sendfile_support == False:
1341 if (host_os.rfind('linux') > -1) or (host_os.rfind('gnu') > -1) or (host_os.rfind('k*bsd*-gnu') > -1) or (host_os.rfind('kopensolaris*-gnu') > -1):
1342 conf.CHECK_CODE('''
1343 int tofd, fromfd;
1344 off_t offset;
1345 size_t total;
1346 ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
1347 ''',
1348 '_HAVE_SENDFILE',
1349 headers='sys/sendfile.h',
1350 msg='Checking for linux sendfile support')
1352 if conf.CONFIG_SET('_HAVE_SENDFILE'):
1353 conf.DEFINE('HAVE_SENDFILE', '1')
1354 conf.DEFINE('LINUX_SENDFILE_API', '1')
1355 elif (host_os.rfind('freebsd') > -1) or (host_os.rfind('dragonfly') > -1):
1356 conf.CHECK_CODE('''
1357 #include <sys/types.h>
1358 #include <unistd.h>
1359 #include <sys/socket.h>
1360 #include <sys/uio.h>
1361 int fromfd, tofd, ret, total=0;
1362 off_t offset, nwritten;
1363 struct sf_hdtr hdr;
1364 struct iovec hdtrl;
1365 hdr.headers = &hdtrl;
1366 hdr.hdr_cnt = 1;
1367 hdr.trailers = NULL;
1368 hdr.trl_cnt = 0;
1369 hdtrl.iov_base = NULL;
1370 hdtrl.iov_len = 0;
1371 ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0)
1372 ''',
1373 '_HAVE_SENDFILE',
1374 msg='Checking for freebsd sendfile support')
1375 if conf.CONFIG_SET('_HAVE_SENDFILE'):
1376 conf.DEFINE('HAVE_SENDFILE', '1')
1377 conf.DEFINE('FREEBSD_SENDFILE_API', '1')
1378 elif (host_os.rfind('darwin') > -1):
1379 conf.CHECK_CODE('''
1380 #include <sys/types.h>
1381 #include <sys/socket.h>
1382 #include <sys/uio.h>
1383 int fromfd, tofd, ret;
1384 off_t offset, nwritten;
1385 struct sf_hdtr hdr;
1386 struct iovec hdtrl;
1387 hdr.headers = &hdtrl;
1388 hdr.hdr_cnt = 1;
1389 hdr.trailers = (void *)0;
1390 hdr.trl_cnt = 0;
1391 hdtrl.iov_base = (void *)0;
1392 hdtrl.iov_len = 0;
1393 ret = sendfile(fromfd, tofd, offset, &nwritten, &hdr, 0);
1394 ''',
1395 '_HAVE_SENDFILE',
1396 msg='Checking for darwin sendfile support')
1397 if conf.CONFIG_SET('_HAVE_SENDFILE'):
1398 conf.DEFINE('HAVE_SENDFILE', '1')
1399 conf.DEFINE('DARWIN_SENDFILE_API', '1')
1400 elif (host_os.rfind('hpux') > -1) or (host_os.rfind('osf') > -1):
1401 conf.CHECK_CODE('''
1402 #include <sys/socket.h>
1403 #include <sys/uio.h>
1404 int fromfd, tofd;
1405 size_t total=0;
1406 struct iovec hdtrl[2];
1407 ssize_t nwritten;
1408 off_t offset;
1409 hdtrl[0].iov_base = 0;
1410 hdtrl[0].iov_len = 0;
1411 nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0);
1412 ''',
1413 '_HAVE_SENDFILE',
1414 msg='Checking for osf/hpux sendfile support')
1415 if conf.CONFIG_SET('_HAVE_SENDFILE'):
1416 conf.DEFINE('HAVE_SENDFILE', '1')
1417 conf.DEFINE('HPUX_SENDFILE_API', '1')
1418 elif (host_os.rfind('sunos') > -1):
1419 conf.CHECK_FUNCS_IN('sendfilev', 'sendfile')
1420 conf.CHECK_CODE('''
1421 #include <sys/sendfile.h>,
1422 int sfvcnt;
1423 size_t xferred;
1424 struct sendfilevec vec[2];
1425 ssize_t nwritten;
1426 int tofd;
1427 sfvcnt = 2;
1428 vec[0].sfv_fd = SFV_FD_SELF;
1429 vec[0].sfv_flag = 0;
1430 vec[0].sfv_off = 0;
1431 vec[0].sfv_len = 0;
1432 vec[1].sfv_fd = 0;
1433 vec[1].sfv_flag = 0;
1434 vec[1].sfv_off = 0;
1435 vec[1].sfv_len = 0;
1436 nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
1437 ''',
1438 '_HAVE_SENDFILEV',
1439 msg='Checking for solaris sendfilev support',
1440 lib='sendfile')
1441 if conf.CONFIG_SET('_HAVE_SENDFILEV'):
1442 conf.DEFINE('HAVE_SENDFILEV', '1')
1443 conf.DEFINE('SOLARIS_SENDFILE_API', '1')
1444 elif (host_os.rfind('aix') > -1):
1445 conf.CHECK_CODE('''
1446 #include <sys/socket.h>
1447 int fromfd, tofd;
1448 size_t total=0;
1449 struct sf_parms hdtrl;
1450 ssize_t nwritten;
1451 hdtrl.header_data = 0;
1452 hdtrl.header_length = 0;
1453 hdtrl.file_descriptor = fromfd;
1454 hdtrl.file_offset = 0;
1455 hdtrl.file_bytes = 0;
1456 hdtrl.trailer_data = 0;
1457 hdtrl.trailer_length = 0;
1458 nwritten = send_file(&tofd, &hdtrl, 0);
1459 ''',
1460 '_HAVE_SENDFILE',
1461 msg='Checking for AIX send_file support')
1462 if conf.CONFIG_SET('_HAVE_SENDFILE'):
1463 conf.DEFINE('HAVE_SENDFILE', '1')
1464 conf.DEFINE('AIX_SENDFILE_API', '1')
1466 if Options.options.with_sendfile_support == True and not conf.CONFIG_SET('HAVE_SENDFILE'):
1467 conf.fatal('sendfile support not found but it was requested !')
1468 # Check for getcwd allowing a NULL arg.
1469 conf.CHECK_CODE('''
1470 #include <unistd.h>
1471 int main(void) {
1472 char *s = getcwd(NULL,0);
1473 return s != NULL ? 0 : 1;
1474 }''', 'GETCWD_TAKES_NULL', addmain=False, execute=True,
1475 msg="getcwd takes a NULL argument")
1478 # UnixWare 7.x has its getspnam in -lgen
1479 conf.CHECK_FUNCS_IN('getspnam', 'gen')
1480 conf.CHECK_FUNCS_IN('getspnam', 'security')
1481 conf.CHECK_FUNCS_IN('getspnam', 'sec')
1483 legacy_quota_libs = ''
1484 if not Options.options.with_quotas == False:
1485 # For quotas on Veritas VxFS filesystems
1486 conf.CHECK_HEADERS('sys/fs/vx_quota.h')
1487 # For sys/quota.h and linux/quota.h
1488 conf.CHECK_HEADERS('sys/quota.h')
1489 # For quotas on BSD systems
1490 conf.CHECK_HEADERS('ufs/ufs/quota.h')
1491 # For quotas on AIX systems
1492 conf.CHECK_HEADERS('jfs/quota.h')
1493 # For quotas on Linux XFS filesystems
1494 if conf.CHECK_HEADERS('xfs/xqm.h'):
1495 conf.DEFINE('HAVE_XFS_QUOTAS', '1')
1496 else:
1497 # For Irix XFS
1498 conf.CHECK_CODE('''
1499 #include "confdefs.h"
1500 #ifdef HAVE_SYS_TYPES_H
1501 #include <sys/types.h>
1502 #endif
1503 #ifdef HAVE_ASM_TYPES_H
1504 #include <asm/types.h>
1505 #endif
1506 #include <sys/quota.h>
1507 int i = Q_XGETQUOTA;''',
1508 define='HAVE_XFS_QUOTAS',
1509 msg='for XFS QUOTA in <sys/quota.h>',
1510 execute=False,
1511 local_include=False)
1513 # For IRIX like dqb_isoftlimit instead of dqb_fsoftlimit in struct dqblk
1514 conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_fsoftlimit', define='HAVE_DQB_FSOFTLIMIT',
1515 headers='sys/quota.h')
1516 #darwin style quota bytecount
1517 conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_curbytes', define='HAVE_STRUCT_DQBLK_DQB_CURBYTES',
1518 headers='sys/quota.h')
1519 conf.CHECK_HEADERS('rpc/types.h rpc/xdr.h', together=True)
1520 if conf.CHECK_HEADERS('rpcsvc/rquota.h', lib='tirpc'):
1521 # Optional structure member
1522 conf.CHECK_STRUCTURE_MEMBER('struct getquota_rslt', 'getquota_rslt_u',
1523 define='HAVE_GETQUOTA_RSLT_GETQUOTA_RSLT_U',
1524 headers='rpcsvc/rquota.h',
1525 lib='tirpc')
1527 # Required function for NFS quota support
1528 conf.CHECK_CODE('''
1529 clnt_create("", RQUOTAPROG, RQUOTAVERS, "udp");
1530 ''',
1531 headers="rpc/rpc.h rpc/types.h rpcsvc/rquota.h rpc/nettype.h rpc/xdr.h",
1532 define='HAVE_NFS_QUOTAS',
1533 msg='checking for clnt_create()',
1534 execute=True,
1535 local_include=False,
1536 lib='tirpc')
1538 if (host_os.rfind('linux') > -1):
1539 conf.DEFINE('HAVE_QUOTACTL_LINUX', '1')
1540 elif not conf.CONFIG_SET("HAVE_XFS_QUOTAS"):
1541 if not conf.CHECK_CODE('''
1542 #define HAVE_QUOTACTL_4A 1
1543 #define AUTOCONF_TEST 1
1544 #include "../tests/sysquotas.c"
1545 ''',
1546 cflags=conf.env['WERROR_CFLAGS'],
1547 define='HAVE_QUOTACTL_4A',
1548 msg='for QUOTACTL_4A: long quotactl(int cmd, char *special, qid_t id, caddr_t addr)',
1549 execute=True,
1550 addmain=False):
1552 conf.CHECK_CODE('''
1553 #define HAVE_QUOTACTL_4B 1
1554 #define AUTOCONF_TEST 1
1555 #include "../tests/sysquotas.c"
1556 ''',
1557 cflags=conf.env['WERROR_CFLAGS'],
1558 define='HAVE_QUOTACTL_4B',
1559 msg='for QUOTACTL_4B: int quotactl(const char *path, int cmd, int id, char *addr)',
1560 execute=True,
1561 addmain=False)
1563 if conf.CONFIG_SET('HAVE_QUOTACTL_LINUX') or \
1564 conf.CONFIG_SET('HAVE_QUOTACTL_4A') or \
1565 conf.CONFIG_SET('HAVE_QUOTACTL_4B') or \
1566 conf.CONFIG_SET('HAVE_XFS_QUOTAS'):
1567 conf.DEFINE('HAVE_SYS_QUOTAS', '1')
1568 conf.DEFINE('WITH_QUOTAS', '1')
1571 # check if Legacy quota code can be brought in
1572 # if standard interfaces are not supported
1574 if not conf.CONFIG_SET('WITH_QUOTAS'):
1575 if host_os.rfind('sunos5') > -1:
1576 conf.DEFINE('SUNOS5', '1')
1577 legacy_quota_libs = 'nsl'
1578 conf.CHECK_CODE('''
1579 #define WITH_QUOTAS 1
1580 #define AUTOCONF_TEST 1
1581 #include "../tests/oldquotas.c"
1582 ''',
1583 cflags=conf.env['WERROR_CFLAGS'],
1584 define='WITH_QUOTAS',
1585 lib=legacy_quota_libs,
1586 msg='Checking whether legacy quota code can be used',
1587 execute=False,
1588 addmain=False)
1589 if not conf.CONFIG_SET('WITH_QUOTAS'):
1590 legacy_quota_libs = ''
1591 conf.env['legacy_quota_libs'] = legacy_quota_libs
1593 if Options.options.with_quotas == True and not conf.CONFIG_SET('WITH_QUOTAS'):
1594 conf.fatal('quota support not found but it was requested !')
1596 conf.CHECK_CODE('(void)unshare(CLONE_FS);',
1597 headers='sched.h',
1598 define='HAVE_UNSHARE_CLONE_FS',
1599 msg='for Linux unshare(CLONE_FS)')
1602 # cluster support (CTDB)
1604 if not Options.options.with_cluster_support:
1605 Logs.info("building without cluster support (--without-cluster-support)")
1606 conf.env.with_ctdb = False
1607 else:
1608 Logs.info("building with cluster support")
1609 conf.env.with_ctdb = True
1610 conf.DEFINE('CLUSTER_SUPPORT', 1)
1612 if Options.options.with_profiling_data:
1613 conf.DEFINE('WITH_PROFILE', 1);
1614 conf.CHECK_FUNCS('getrusage', headers="sys/time.h sys/resource.h")
1616 if (conf.CHECK_HEADERS('linux/ioctl.h sys/ioctl.h linux/fs.h') and
1617 conf.CHECK_DECLS('FS_IOC_GETFLAGS FS_COMPR_FL', headers='linux/fs.h')):
1618 conf.DEFINE('HAVE_LINUX_IOCTL', '1')
1620 conf.env['CFLAGS_CEPHFS'] = "-D_FILE_OFFSET_BITS=64"
1622 if (Options.options.with_cephfs and
1623 conf.CHECK_HEADERS('cephfs/libcephfs.h', False, False, 'cephfs') and
1624 conf.CHECK_LIB('cephfs', shlib=True)):
1625 if (Options.options.with_acl_support and
1626 conf.CHECK_FUNCS_IN('ceph_statx', 'cephfs',
1627 headers='cephfs/libcephfs.h')):
1628 conf.DEFINE('HAVE_CEPH', '1')
1629 conf.CHECK_FUNCS_IN('ceph_select_filesystem', 'cephfs',
1630 headers='cephfs/libcephfs.h')
1631 conf.DEFINE('HAVE_MANDATORY_CEPH_API', '1')
1632 for api in ['ceph_mkdirat', 'ceph_openat', 'ceph_unlinkat',
1633 'ceph_symlinkat', 'ceph_readlinkat', 'ceph_statxat',
1634 'ceph_fdopendir']:
1635 if not conf.CHECK_FUNCS_IN(api, 'cephfs',
1636 headers='cephfs/libcephfs.h'):
1637 conf.undefine('HAVE_MANDATORY_CEPH_API')
1638 if not conf.env.HAVE_MANDATORY_CEPH_API:
1639 Logs.warn("Installed Ceph version support is at the verge of "
1640 "deprecation due to the absence of some mandatory "
1641 "libcephfs APIs. This warning there shall result in "
1642 "disabling the Ceph VFS module altogether with the "
1643 "next major Samba version. It is highly recommended "
1644 "to update to a more recent/active version of Ceph.")
1645 else:
1646 Logs.warn('''Ceph support disabled due to --without-acl-support
1647 or lack of ceph_statx support''')
1648 conf.undefine('HAVE_CEPH')
1650 if Options.options.with_glusterfs:
1651 conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 4" --cflags --libs',
1652 msg='Checking for glusterfs-api >= 4', uselib_store="GFAPI")
1653 conf.CHECK_HEADERS('glusterfs/api/glfs.h', lib='gfapi')
1654 conf.CHECK_LIB('gfapi', shlib=True)
1656 if conf.CONFIG_SET('HAVE_GLUSTERFS_API_GLFS_H'):
1657 if Options.options.with_acl_support:
1658 conf.DEFINE('HAVE_GLUSTERFS', '1')
1659 else:
1660 Logs.warn("GlusterFS support disabled due to --without-acl-support")
1661 conf.undefine('HAVE_GLUSTERFS')
1662 else:
1663 conf.undefine('HAVE_GLUSTERFS')
1665 conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 6" --cflags --libs',
1666 msg='Checking for glusterfs-api >= 6',
1667 uselib_store="GFAPI_VER_6")
1668 conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 7.6" --cflags --libs',
1669 msg='Checking for glusterfs-api >= 7.6',
1670 uselib_store="GFAPI_VER_7_6")
1671 conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 7.9" --cflags --libs',
1672 msg='Checking for glusterfs-api >= 7.9',
1673 uselib_store="GFAPI_VER_7_9")
1674 conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 7.11" --cflags --libs',
1675 msg='Checking for glusterfs-api >= 7.11',
1676 uselib_store="GFAPI_VER_7_11")
1678 else:
1679 conf.SET_TARGET_TYPE('gfapi', 'EMPTY')
1680 conf.undefine('HAVE_GLUSTERFS')
1682 if Options.options.enable_vxfs:
1683 conf.DEFINE('HAVE_VXFS', '1')
1685 if conf.CHECK_CFG(package='liburing', args='--cflags --libs',
1686 msg='Checking for liburing package', uselib_store="URING"):
1687 if (conf.CHECK_HEADERS('liburing.h', lib='uring')
1688 and conf.CHECK_LIB('uring', shlib=True)):
1689 conf.CHECK_FUNCS_IN('io_uring_ring_dontfork', 'uring',
1690 headers='liburing.h')
1691 # There are a few distributions, which
1692 # don't seem to have linux/openat2.h available
1693 # during the liburing build, which means liburing/compat.h
1694 # defines struct open_how directly instead of including
1695 # linux/openat2.h, while linux/openat2.h is
1696 # available on the installed system, which cause problems
1697 # when we try to include both files.
1699 # check if struct open_how is defined in liburing/compat.h
1700 # itself and not via including linux/openat2.h
1701 conf.CHECK_TYPE_IN('struct open_how', 'liburing/compat.h',
1702 cflags='-D_LINUX_OPENAT2_H',
1703 define='HAVE_STRUCT_OPEN_HOW_LIBURING_COMPAT_H')
1704 conf.DEFINE('HAVE_LIBURING', '1')
1706 conf.env.build_regedit = False
1707 if not Options.options.with_regedit == False:
1708 conf.PROCESS_SEPARATE_RULE('system_ncurses')
1709 if conf.CONFIG_SET('HAVE_NCURSES'):
1710 conf.env.build_regedit = True
1712 if conf.env.build_regedit:
1713 Logs.info("building regedit")
1714 else:
1715 if Options.options.with_regedit == False:
1716 Logs.info("not building regedit (--without-regedit)")
1717 elif Options.options.with_regedit == True:
1718 Logs.error("ncurses not available, cannot build regedit")
1719 conf.fatal("ncurses not available, but --with-regedit was specified")
1720 else:
1721 Logs.info("ncurses not available, not building regedit")
1723 if conf.CHECK_HEADERS('ftw.h') and conf.CHECK_FUNCS('nftw'):
1724 conf.env.build_mvxattr = True
1726 conf.env.build_winexe = False
1727 if not Options.options.with_winexe == False:
1728 if conf.CONFIG_SET('HAVE_WINEXE_CC_WIN32') or conf.CONFIG_SET('HAVE_WINEXE_CC_WIN64'):
1729 conf.env.build_winexe = True
1731 if conf.env.build_winexe:
1732 Logs.info("building winexe")
1733 else:
1734 if Options.options.with_winexe == False:
1735 Logs.info("not building winexe (--without-winexe)")
1736 elif Options.options.with_winexe == True:
1737 Logs.error("mingw not available, cannot build winexe")
1738 conf.fatal("mingw not available, but --with-winexe was specified")
1739 else:
1740 Logs.info("mingw not available, not building winexe")
1742 conf.CHECK_FUNCS_IN('DES_pcbc_encrypt', 'crypto')
1743 if Options.options.with_fake_kaserver == True:
1744 conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1745 conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1746 if (conf.CONFIG_SET('HAVE_AFS_PARAM_H') and conf.CONFIG_SET('HAVE_AFS_STDS_H') and conf.CONFIG_SET('HAVE_DES_PCBC_ENCRYPT')):
1747 conf.DEFINE('WITH_FAKE_KASERVER', '1')
1748 else:
1749 conf.fatal('AFS headers not available, but --with-fake-kaserver was specified')
1751 if conf.CHECK_CFG(package='glib-2.0',
1752 args='--cflags --libs',
1753 msg='Checking for glib-2.0',
1754 uselib_store="GLIB-2.0"):
1755 if (conf.CHECK_HEADERS('glib.h', lib='glib-2.0') and conf.CHECK_LIB('glib-2.0', shlib=True)):
1756 conf.DEFINE('HAVE_GLIB', 1)
1758 if conf.CONFIG_SET('HAVE_GLIB'):
1759 conf.DEFINE('WITH_TEVENT_GLIB_GLUE', '1')
1761 conf.env['libtracker']=''
1762 tracker_versions = ['2.0', '1.0', '0.16', '0.14']
1764 for version in tracker_versions:
1765 testlib = 'tracker-sparql-' + version
1766 if conf.CHECK_CFG(package=testlib,
1767 args='--cflags --libs',
1768 mandatory=False):
1769 conf.SET_TARGET_TYPE(testlib, 'SYSLIB')
1770 conf.env['libtracker'] = testlib
1771 conf.DEFINE('HAVE_TRACKER', '1')
1772 break
1774 with_spotlight_tracker_backend = (
1775 conf.CONFIG_SET('HAVE_TRACKER')
1776 and conf.CONFIG_SET('HAVE_GLIB')
1777 and conf.env['BISON']
1778 and conf.env['FLEX']
1779 and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1782 with_spotlight_es_backend = (
1783 conf.CONFIG_SET('HAVE_JSON_OBJECT')
1784 and conf.env['BISON']
1785 and conf.env['FLEX']
1786 and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1789 conf.env.with_wsp = False
1790 if conf.CONFIG_GET('ENABLE_SELFTEST'):
1791 Options.options.with_wsp = True
1792 if Options.options.with_wsp:
1793 Logs.info("building with WSP support")
1794 conf.DEFINE('WITH_WSP', '1')
1795 conf.env.with_wsp = True
1797 conf.env.with_spotlight = False
1798 if Options.options.with_spotlight is not False:
1799 backends = ['noindex']
1801 if not conf.env['BISON']:
1802 Logs.warn("Spotlight support requested but bison missing")
1803 if not conf.env['FLEX']:
1804 Logs.warn("Spotlight support requested but flex missing")
1805 if not conf.CONFIG_GET('HAVE_UTF8_NORMALISATION'):
1806 Logs.warn("Missing support for Unicode normalisation. "
1807 "Try installing icu-dev or libicu-devel.")
1808 if not conf.CONFIG_SET('HAVE_TRACKER'):
1809 Logs.warn('Missing libtracker-sparql development files for Spotlight backend "tracker"')
1810 if not conf.CONFIG_SET('HAVE_GLIB'):
1811 Logs.warn('Missing glib-2.0 development files for Spotlight backend "tracker"')
1812 if not conf.CONFIG_GET('HAVE_JSON_OBJECT'):
1813 Logs.warn('Missing libjansson development files for Spotlight backend "elasticsearch"')
1815 if with_spotlight_tracker_backend:
1816 conf.env.spotlight_backend_tracker = True
1817 backends.append('tracker')
1818 conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_TRACKER', '1')
1820 if with_spotlight_es_backend:
1821 conf.env.spotlight_backend_es = True
1822 backends.append('elasticsearch')
1823 conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_ES', '1')
1825 if (Options.options.with_spotlight is True
1826 and not conf.env.spotlight_backend_tracker
1827 and not conf.env.spotlight_backend_es):
1828 conf.fatal("Unmet dependencies for Spotlight backends")
1830 Logs.info("Building with Spotlight support, available backends: %s" % ', '.join(backends))
1831 conf.DEFINE('WITH_SPOTLIGHT', '1')
1832 conf.env.with_spotlight = True
1834 if not conf.CONFIG_SET('HAVE_RPC_XDR_H'):
1835 conf.CHECK_HEADERS('rpc/types.h rpc/xdr.h', together=True, lib='tirpc')
1837 if conf.CHECK_FUNCS_IN('nscd_flush_cache', 'nscd', headers='libnscd.h'):
1838 conf.DEFINE('HAVE_NSCD_FLUSH_CACHE', '1')
1840 forced_static_modules.extend(['auth_builtin', 'auth_sam', 'auth_winbind'])
1841 default_static_modules.extend(['pdb_smbpasswd', 'pdb_tdbsam',
1842 'auth_unix',
1843 'nss_info_template', 'idmap_tdb', 'idmap_passdb',
1844 'idmap_nss'])
1846 default_shared_modules.extend(['vfs_recycle', 'vfs_audit', 'vfs_extd_audit', 'vfs_full_audit',
1847 'vfs_fake_perms', 'vfs_default_quota', 'vfs_readonly', 'vfs_cap',
1848 'vfs_expand_msdfs', 'vfs_shadow_copy', 'vfs_shadow_copy2',
1849 'vfs_readahead', 'vfs_xattr_tdb',
1850 'vfs_streams_xattr', 'vfs_streams_depot', 'vfs_acl_xattr', 'vfs_acl_tdb',
1851 'vfs_preopen', 'vfs_catia',
1852 'vfs_media_harmony', 'vfs_unityed_media', 'vfs_fruit', 'vfs_shell_snap',
1853 'vfs_commit', 'vfs_worm', 'vfs_crossrename', 'vfs_linux_xfs_sgid',
1854 'vfs_time_audit', 'vfs_offline', 'vfs_virusfilter', 'vfs_widelinks'])
1855 if host_os.rfind('linux') > -1:
1856 default_shared_modules.extend(['vfs_snapper'])
1858 default_shared_modules.extend(['idmap_tdb2', 'idmap_script'])
1859 # these have broken dependencies
1860 forced_shared_modules.extend(['idmap_autorid', 'idmap_rid', 'idmap_hash'])
1862 if Options.options.developer:
1863 default_static_modules.extend(['charset_weird'])
1864 default_shared_modules.extend(['vfs_skel_opaque',
1865 'vfs_skel_transparent',
1866 'vfs_shadow_copy_test',
1867 'pdb_test',
1868 'vfs_fake_dfq',
1869 'gpext_security', 'gpext_registry', 'gpext_scripts'])
1871 if Options.options.enable_selftest or Options.options.developer:
1872 default_shared_modules.extend(['vfs_fake_acls', 'vfs_nfs4acl_xattr',
1873 'vfs_error_inject',
1874 'vfs_delay_inject'])
1876 if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
1877 default_static_modules.extend(['pdb_samba_dsdb', 'auth_samba4', 'vfs_dfs_samba4'])
1878 default_shared_modules.extend(['vfs_posix_eadb'])
1880 if conf.CONFIG_SET('HAVE_FREEBSD_SUNACL_H'):
1881 default_shared_modules.extend(['vfs_zfsacl'])
1883 if conf.CONFIG_SET('HAVE_DIRFD_DECL'):
1884 default_shared_modules.extend(['vfs_syncops', 'vfs_dirsort'])
1886 if conf.CONFIG_SET('HAVE_STATFS_F_FSID'):
1887 default_shared_modules.extend(['vfs_fileid'])
1889 if (conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_CONTROL') or conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS')):
1890 default_shared_modules.extend(['vfs_aio_fork'])
1892 if conf.CONFIG_SET('HAVE_LIBURING'):
1893 default_shared_modules.extend(['vfs_io_uring'])
1895 if Options.options.with_pthreadpool:
1896 default_shared_modules.extend(['vfs_aio_pthread'])
1898 if conf.CONFIG_SET('HAVE_LDAP'):
1899 default_static_modules.extend(['pdb_ldapsam', 'idmap_ldap'])
1901 if conf.CONFIG_SET('DARWINOS'):
1902 default_static_modules.extend(['charset_macosxfs'])
1904 if conf.CONFIG_SET('HAVE_GPFS') and conf.CONFIG_SET('HAVE_KERNEL_OPLOCKS_LINUX'):
1905 default_shared_modules.extend(['vfs_gpfs'])
1907 if (conf.CONFIG_SET('HAVE_LINUX_IOCTL')
1908 and conf.CONFIG_SET('HAVE_BASENAME') and conf.CONFIG_SET('HAVE_DIRNAME')):
1909 default_shared_modules.extend(['vfs_btrfs'])
1911 if conf.CONFIG_SET("HAVE_CEPH"):
1912 default_shared_modules.extend(['vfs_ceph'])
1913 # Unlike vfs_ceph, vfs_ceph_snapshots doesn't depend on libcephfs, so
1914 # can be enabled atop a kernel CephFS share (with vfs_default) in
1915 # addition to vfs_ceph. Still, only enable vfs_ceph_snapshots builds
1916 # if we're building with libcephfs for now.
1917 default_shared_modules.extend(['vfs_ceph_snapshots'])
1919 if conf.CONFIG_SET('HAVE_GLUSTERFS'):
1920 default_shared_modules.extend(['vfs_glusterfs'])
1922 if conf.CONFIG_SET('HAVE_SETMNTENT'):
1923 default_shared_modules.extend(['vfs_glusterfs_fuse'])
1925 if conf.CONFIG_SET('HAVE_VXFS'):
1926 default_shared_modules.extend(['vfs_vxfs'])
1928 explicit_shared_modules = TO_LIST(Options.options.shared_modules, delimiter=',')
1929 explicit_static_modules = TO_LIST(Options.options.static_modules, delimiter=',')
1931 def replace_list_item(lst, item, value):
1932 try:
1933 idx = lst.index(item)
1934 lst[idx] = value
1935 except:
1936 pass
1937 # PDB module file name should have the same name as module registers itself
1938 # In Autoconf build we export LDAP passdb module as ldapsam but WAF build
1939 # was always exporting pdb_ldap. In order to support existing packages
1940 # allow referring to pdb_ldapsam as pdb_ldap but use proper name internally.
1941 replace_list_item(explicit_shared_modules, 'pdb_ldap', 'pdb_ldapsam')
1942 replace_list_item(explicit_static_modules, 'pdb_ldap', 'pdb_ldapsam')
1944 final_static_modules = []
1945 final_static_modules.extend(TO_LIST(required_static_modules))
1946 final_shared_modules = []
1948 if '!FORCED' not in explicit_static_modules:
1949 final_static_modules.extend(TO_LIST(forced_static_modules))
1950 if '!FORCED' not in explicit_shared_modules:
1951 final_shared_modules.extend(TO_LIST(forced_shared_modules))
1952 if '!DEFAULT' not in explicit_static_modules:
1953 final_static_modules.extend(TO_LIST(default_static_modules))
1954 if '!DEFAULT' not in explicit_shared_modules:
1955 final_shared_modules.extend(TO_LIST(default_shared_modules))
1957 if 'ALL' in explicit_static_modules:
1958 for m in default_shared_modules:
1959 if m in final_shared_modules:
1960 final_shared_modules.remove(m)
1961 final_static_modules.append(m)
1962 if 'ALL' in explicit_shared_modules:
1963 for m in default_static_modules:
1964 if m in final_static_modules:
1965 final_static_modules.remove(m)
1966 final_shared_modules.append(m)
1968 for m in explicit_static_modules:
1969 if m in ['ALL','!DEFAULT','!FORCED']:
1970 continue
1971 if m.startswith('!'):
1972 m = m[1:]
1973 if m in required_static_modules:
1974 raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
1975 ' '.join(required_static_modules))
1976 if m in final_static_modules:
1977 final_static_modules.remove(m)
1978 continue
1979 if m in forced_shared_modules:
1980 raise Errors.WafError('These modules MUST be configured as shared modules: %s' %
1981 ' '.join(forced_shared_modules))
1982 if m in final_shared_modules:
1983 final_shared_modules.remove(m)
1984 if m not in final_static_modules:
1985 final_static_modules.append(m)
1986 for m in explicit_shared_modules:
1987 if m in ['ALL','!DEFAULT','!FORCED']:
1988 continue
1989 if m.startswith('!'):
1990 m = m[1:]
1991 if m in final_shared_modules:
1992 final_shared_modules.remove(m)
1993 continue
1994 if m in required_static_modules:
1995 raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
1996 ' '.join(required_static_modules))
1997 if m in forced_static_modules:
1998 raise Errors.WafError('These module MUST be configured as static modules: %s' %
1999 ' '.join(forced_static_modules))
2000 if m in final_static_modules:
2001 final_static_modules.remove(m)
2002 if m not in final_shared_modules:
2003 final_shared_modules.append(m)
2005 conf.env['static_modules'] = final_static_modules
2006 conf.env['shared_modules'] = final_shared_modules
2008 conf.DEFINE('STRING_STATIC_MODULES', ' '.join(final_static_modules), quote=True)
2009 conf.DEFINE('STRING_SHARED_MODULES', ' '.join(final_shared_modules), quote=True)
2011 static_list = {}
2012 shared_list = {}
2014 prefixes = ['vfs', 'pdb', 'auth', 'nss_info', 'charset', 'idmap', 'gpext']
2015 conf.env['MODULE_PREFIXES'] = prefixes
2016 for p in prefixes:
2017 for m in final_static_modules:
2018 if m.find(p) == 0:
2019 if not p in static_list:
2020 static_list[p] = []
2021 static_list[p].append(m)
2022 for m in final_shared_modules:
2023 if m.find(p) == 0:
2024 if not p in shared_list:
2025 shared_list[p] = []
2026 shared_list[p].append(m)
2028 for p in prefixes:
2029 static_env = "%s_STATIC" % p.upper()
2030 shared_env = "%s_SHARED" % p.upper()
2031 conf.env[static_env] = []
2032 conf.env[shared_env] = []
2033 if p in static_list:
2034 decl_list = " ".join("extern NTSTATUS %s_init(TALLOC_CTX *mem_ctx); " % entry for entry in static_list[p])
2035 for entry in static_list[p]:
2036 conf.env[static_env].append('%s' % entry)
2037 conf.DEFINE('static_decl_%s' % p, decl_list)
2038 conf.DEFINE('static_init_%s(mem_ctx)' % p, '{ %s_init((mem_ctx)); }' % '_init((mem_ctx)); '.join(static_list[p]))
2039 else:
2040 conf.DEFINE('static_decl_%s' % p, '')
2041 conf.DEFINE('static_init_%s(mem_ctx)' % p, '{}')
2042 if p in shared_list:
2043 for entry in shared_list[p]:
2044 conf.DEFINE('%s_init' % entry, 'samba_init_module')
2045 conf.env[shared_env].append('%s' % entry)
2046 Logs.info("%s: %s" % (static_env, ','.join(conf.env[static_env])))
2047 Logs.info("%s: %s" % (shared_env, ','.join(conf.env[shared_env])))
2049 if (('vfs_snapper' in shared_list.get('vfs', []) or 'vfs_snapper' in static_list.get('vfs', []))
2050 and not (conf.CHECK_CFG(package='dbus-1', args='--cflags --libs',
2051 msg='Checking for dbus', uselib_store="DBUS-1")
2052 and conf.CHECK_HEADERS('dbus/dbus.h', lib='dbus-1')
2053 and conf.CHECK_LIB('dbus-1', shlib=True))):
2054 conf.fatal("vfs_snapper is enabled but prerequisite dbus-1 package not "
2055 "found. Use --with-shared-modules='!vfs_snapper' to disable "
2056 "vfs_snapper support.")
2058 conf.SAMBA_CONFIG_H('include/config.h')