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