s3: lib: Add new clistr_smb2_extract_snapshot_token() function.
[Samba.git] / buildtools / wafsamba / wafsamba.py
blob79f352878a8778ac6ca5dadb3fd43b1fc5126cf4
1 # a waf tool to add autoconf-like macros to the configure section
2 # and for SAMBA_ macros for building libraries, binaries etc
4 import os, sys, re, shutil, fnmatch
5 from waflib import Build, Options, Task, Utils, TaskGen, Logs, Context, Errors
6 from waflib.Configure import conf
7 from waflib.Logs import debug
8 from samba_utils import SUBST_VARS_RECURSIVE
9 TaskGen.task_gen.apply_verif = Utils.nada
11 # bring in the other samba modules
12 from samba_utils import *
13 from samba_utils import symlink
14 from samba_version import *
15 from samba_autoconf import *
16 from samba_patterns import *
17 from samba_pidl import *
18 from samba_autoproto import *
19 from samba_python import *
20 from samba_perl import *
21 from samba_deps import *
22 from samba_bundled import *
23 from samba_third_party import *
24 import samba_cross
25 import samba_install
26 import samba_conftests
27 import samba_abi
28 import samba_headers
29 import generic_cc
30 import samba_dist
31 import samba_wildcard
32 import symbols
33 import pkgconfig
34 import configure_file
35 import samba_waf18
37 LIB_PATH="shared"
39 os.environ['PYTHONUNBUFFERED'] = '1'
41 if Context.HEXVERSION not in (0x2001800,):
42 Logs.error('''
43 Please use the version of waf that comes with Samba, not
44 a system installed version. See http://wiki.samba.org/index.php/Waf
45 for details.
47 Alternatively, please run ./configure and make as usual. That will
48 call the right version of waf.''')
49 sys.exit(1)
51 @conf
52 def SAMBA_BUILD_ENV(conf):
53 '''create the samba build environment'''
54 conf.env.BUILD_DIRECTORY = conf.bldnode.abspath()
55 mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH))
56 mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH, "private"))
57 mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, "modules"))
58 mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, "plugins"))
59 mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'python/samba/dcerpc'))
60 # this allows all of the bin/shared and bin/python targets
61 # to be expressed in terms of build directory paths
62 mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'default'))
63 for (source, target) in [('shared', 'shared'), ('modules', 'modules'), ('plugins', 'plugins'), ('python', 'python')]:
64 link_target = os.path.join(conf.env.BUILD_DIRECTORY, 'default/' + target)
65 if not os.path.lexists(link_target):
66 symlink('../' + source, link_target)
68 # get perl to put the blib files in the build directory
69 blib_bld = os.path.join(conf.env.BUILD_DIRECTORY, 'default/pidl/blib')
70 blib_src = os.path.join(conf.srcnode.abspath(), 'pidl/blib')
71 mkdir_p(blib_bld + '/man1')
72 mkdir_p(blib_bld + '/man3')
73 if os.path.islink(blib_src):
74 os.unlink(blib_src)
75 elif os.path.exists(blib_src):
76 shutil.rmtree(blib_src)
79 def ADD_INIT_FUNCTION(bld, subsystem, target, init_function):
80 '''add an init_function to the list for a subsystem'''
81 if init_function is None:
82 return
83 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
84 cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
85 if not subsystem in cache:
86 cache[subsystem] = []
87 cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } )
88 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
91 def generate_empty_file(task):
92 task.outputs[0].write('')
93 return 0
95 #################################################################
96 def SAMBA_LIBRARY(bld, libname, source,
97 deps='',
98 public_deps='',
99 includes='',
100 public_headers=None,
101 public_headers_install=True,
102 private_headers=None,
103 header_path=None,
104 pc_files=None,
105 vnum=None,
106 soname=None,
107 cflags='',
108 cflags_end=None,
109 ldflags='',
110 external_library=False,
111 realname=None,
112 keep_underscore=False,
113 autoproto=None,
114 autoproto_extra_source='',
115 group='main',
116 depends_on='',
117 local_include=True,
118 global_include=True,
119 vars=None,
120 subdir=None,
121 install_path=None,
122 install=True,
123 pyembed=False,
124 pyext=False,
125 target_type='LIBRARY',
126 bundled_name=None,
127 link_name=None,
128 abi_directory=None,
129 abi_match=None,
130 orig_vscript_map=None,
131 hide_symbols=False,
132 manpages=None,
133 private_library=False,
134 grouping_library=False,
135 require_builtin_deps=False,
136 provide_builtin_linking=False,
137 builtin_cflags='',
138 allow_undefined_symbols=False,
139 allow_warnings=False,
140 enabled=True):
141 '''define a Samba library'''
143 # We support:
144 # - LIBRARY: this can be use to link via -llibname
145 # - MODULE: this is module from SAMBA_MODULE()
146 # - PLUGIN: this is plugin for external consumers to be
147 # loaded via dlopen()
148 # - PYTHON: a python C binding library
150 if target_type not in ['LIBRARY', 'MODULE', 'PLUGIN', 'PYTHON']:
151 raise Errors.WafError("target_type[%s] not supported in SAMBA_LIBRARY('%s')" %
152 (target_type, libname))
154 if require_builtin_deps:
155 # For now we only support require_builtin_deps only for libraries, plugins
156 if target_type not in ['LIBRARY', 'PLUGIN']:
157 raise Errors.WafError("target_type[%s] not supported SAMBA_LIBRARY('%s', require_builtin_deps=True)" %
158 (target_type, libname))
160 if private_library and public_headers:
161 raise Errors.WafError("private library '%s' must not have public header files" %
162 libname)
164 if orig_vscript_map and not private_library:
165 raise Errors.WafError("public library '%s' must not have orig_vscript_map" %
166 libname)
168 if orig_vscript_map and abi_directory:
169 raise Errors.WafError("private library '%s' with orig_vscript_map must not have abi_directory" %
170 libname)
171 if orig_vscript_map and abi_match:
172 raise Errors.WafError("private library '%s' with orig_vscript_map must not have abi_match" %
173 libname)
175 if LIB_MUST_BE_PRIVATE(bld, libname) and target_type not in ['PLUGIN']:
176 private_library = True
178 if not enabled:
179 SET_TARGET_TYPE(bld, libname, 'DISABLED')
180 return
182 source = bld.EXPAND_VARIABLES(source, vars=vars)
183 if subdir:
184 source = bld.SUBDIR(subdir, source)
186 # remember empty libraries, so we can strip the dependencies
187 if ((source == '') or (source == [])):
188 if deps == '' and public_deps == '':
189 SET_TARGET_TYPE(bld, libname, 'EMPTY')
190 return
191 empty_c = libname + '.empty.c'
192 bld.SAMBA_GENERATOR('%s_empty_c' % libname,
193 rule=generate_empty_file,
194 target=empty_c)
195 source=empty_c
197 samba_deps = deps + ' ' + public_deps
198 samba_deps = TO_LIST(samba_deps)
200 if BUILTIN_LIBRARY(bld, libname):
201 builtin_target = libname + '.builtin.objlist'
202 builtin_cflags_end = '-D_PUBLIC_=_PRIVATE_'
203 empty_target = libname
204 obj_target = None
205 else:
206 if provide_builtin_linking:
207 builtin_target = libname + '.builtin.objlist'
208 builtin_cflags_end = '-D_PUBLIC_=_PRIVATE_'
209 else:
210 builtin_target = None
211 empty_target = None
212 obj_target = libname + '.objlist'
213 if require_builtin_deps:
214 # hide the builtin deps from the callers
215 samba_deps = TO_LIST('')
216 dep_target = obj_target
218 if group == 'libraries':
219 subsystem_group = 'main'
220 else:
221 subsystem_group = group
223 # first create a target for building the object files for this library
224 # by separating in this way, we avoid recompiling the C files
225 # separately for the install library and the build library
226 if builtin_target:
227 __t = __SAMBA_SUBSYSTEM_BUILTIN(bld, builtin_target, source,
228 deps=deps,
229 public_deps=public_deps,
230 includes=includes,
231 header_path=header_path,
232 builtin_cflags=builtin_cflags,
233 builtin_cflags_end=builtin_cflags_end,
234 group=group,
235 depends_on=depends_on,
236 local_include=local_include,
237 global_include=global_include,
238 allow_warnings=allow_warnings)
239 builtin_subsystem = __t
240 else:
241 builtin_subsystem = None
242 if obj_target:
243 bld.SAMBA_SUBSYSTEM(obj_target,
244 source = source,
245 deps = deps,
246 public_deps = public_deps,
247 includes = includes,
248 public_headers = public_headers,
249 public_headers_install = public_headers_install,
250 private_headers= private_headers,
251 header_path = header_path,
252 cflags = cflags,
253 cflags_end = cflags_end,
254 group = subsystem_group,
255 autoproto = autoproto,
256 autoproto_extra_source=autoproto_extra_source,
257 depends_on = depends_on,
258 hide_symbols = hide_symbols,
259 allow_warnings = allow_warnings,
260 pyembed = pyembed,
261 pyext = pyext,
262 local_include = local_include,
263 __require_builtin_deps=require_builtin_deps,
264 global_include = global_include)
265 else:
266 et = bld.SAMBA_SUBSYSTEM(empty_target,
267 source=[],
268 __force_empty=True,
269 __require_builtin_deps=True)
270 et.samba_builtin_subsystem = builtin_subsystem
272 if BUILTIN_LIBRARY(bld, libname):
273 return
275 if not SET_TARGET_TYPE(bld, libname, target_type):
276 return
278 # the library itself will depend on that object target
279 samba_deps.append(dep_target)
281 realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON'))
282 link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON'))
284 # we don't want any public libraries without version numbers
285 if (not private_library and target_type != 'PYTHON' and not realname):
286 if vnum is None and soname is None:
287 raise Errors.WafError("public library '%s' must have a vnum" %
288 libname)
289 if pc_files is None:
290 raise Errors.WafError("public library '%s' must have pkg-config file" %
291 libname)
292 if public_headers is None:
293 raise Errors.WafError("public library '%s' must have header files" %
294 libname)
296 abi_vnum = vnum
298 if bundled_name is not None:
299 pass
300 elif target_type == 'PYTHON' or realname or not private_library:
301 if keep_underscore:
302 bundled_name = libname
303 else:
304 bundled_name = libname.replace('_', '-')
305 else:
306 assert (private_library == True and realname is None)
307 bundled_name = PRIVATE_NAME(bld, libname.replace('_', '-'))
308 vnum = None
310 ldflags = TO_LIST(ldflags)
311 if bld.env['ENABLE_RELRO'] is True:
312 ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now'))
314 features = 'c cshlib symlink_lib install_lib'
315 if pyext:
316 features += ' pyext'
317 if pyembed:
318 features += ' pyembed'
320 if abi_directory:
321 features += ' abi_check'
323 if pyembed and bld.env['PYTHON_SO_ABI_FLAG']:
324 # For ABI checking, we don't care about the Python version.
325 # Remove the Python ABI tag (e.g. ".cpython-35m")
326 abi_flag = bld.env['PYTHON_SO_ABI_FLAG']
327 replacement = ''
328 version_libname = libname.replace(abi_flag, replacement)
329 else:
330 version_libname = libname
332 vscript = None
333 if bld.env.HAVE_LD_VERSION_SCRIPT:
334 if private_library:
335 version = bld.env.PRIVATE_VERSION
336 elif vnum:
337 version = "%s_%s" % (libname, vnum)
338 else:
339 version = None
340 if version:
341 vscript = "%s.vscript" % libname
342 if orig_vscript_map:
343 bld.VSCRIPT_MAP_PRIVATE(version_libname, orig_vscript_map, version, vscript)
344 else:
345 bld.ABI_VSCRIPT(version_libname, abi_directory, version, vscript,
346 abi_match, private_library)
347 fullname = apply_pattern(bundled_name, bld.env.cshlib_PATTERN)
348 fullpath = bld.path.find_or_declare(fullname)
349 vscriptpath = bld.path.find_or_declare(vscript)
350 if not fullpath:
351 raise Errors.WafError("unable to find fullpath for %s" % fullname)
352 if not vscriptpath:
353 raise Errors.WafError("unable to find vscript path for %s" % vscript)
354 bld.add_manual_dependency(fullpath, vscriptpath)
355 if bld.is_install:
356 # also make the .inst file depend on the vscript
357 instname = apply_pattern(bundled_name + '.inst', bld.env.cshlib_PATTERN)
358 bld.add_manual_dependency(bld.path.find_or_declare(instname), bld.path.find_or_declare(vscript))
359 vscript = os.path.join(bld.path.abspath(bld.env), vscript)
361 bld.SET_BUILD_GROUP(group)
362 t = bld(
363 features = features,
364 source = [],
365 target = bundled_name,
366 depends_on = depends_on,
367 samba_ldflags = ldflags,
368 samba_deps = samba_deps,
369 samba_includes = includes,
370 version_script = vscript,
371 version_libname = version_libname,
372 local_include = local_include,
373 global_include = global_include,
374 vnum = vnum,
375 soname = soname,
376 install_path = None,
377 samba_inst_path = install_path,
378 name = libname,
379 samba_realname = realname,
380 samba_install = install,
381 abi_directory = "%s/%s" % (bld.path.abspath(), abi_directory),
382 abi_match = abi_match,
383 abi_vnum = abi_vnum,
384 private_library = private_library,
385 grouping_library=grouping_library,
386 allow_undefined_symbols=allow_undefined_symbols,
387 samba_require_builtin_deps=False,
388 samba_builtin_subsystem=builtin_subsystem,
391 if realname and not link_name:
392 link_name = 'shared/%s' % realname
394 if link_name:
395 if 'waflib.extras.compat15' in sys.modules:
396 link_name = 'default/' + link_name
397 t.link_name = link_name
399 if pc_files is not None and not private_library:
400 if pyembed:
401 bld.PKG_CONFIG_FILES(pc_files, vnum=vnum, extra_name=bld.env['PYTHON_SO_ABI_FLAG'])
402 else:
403 bld.PKG_CONFIG_FILES(pc_files, vnum=vnum)
405 if (manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and
406 bld.env['XSLTPROC_MANPAGES']):
407 bld.MANPAGES(manpages, install)
410 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
413 #################################################################
414 def SAMBA_BINARY(bld, binname, source,
415 deps='',
416 includes='',
417 public_headers=None,
418 private_headers=None,
419 header_path=None,
420 modules=None,
421 ldflags=None,
422 cflags='',
423 cflags_end=None,
424 autoproto=None,
425 use_hostcc=False,
426 use_global_deps=True,
427 compiler=None,
428 group='main',
429 manpages=None,
430 local_include=True,
431 global_include=True,
432 subsystem_name=None,
433 allow_warnings=False,
434 pyembed=False,
435 vars=None,
436 subdir=None,
437 install=True,
438 install_path=None,
439 enabled=True,
440 fuzzer=False,
441 for_selftest=False):
442 '''define a Samba binary'''
444 if for_selftest:
445 install=False
446 if not bld.CONFIG_GET('ENABLE_SELFTEST'):
447 enabled=False
449 if not enabled:
450 SET_TARGET_TYPE(bld, binname, 'DISABLED')
451 return
453 # Fuzzing builds do not build normal binaries
454 # however we must build asn1compile etc
456 if not use_hostcc and bld.env.enable_fuzzing != fuzzer:
457 SET_TARGET_TYPE(bld, binname, 'DISABLED')
458 return
460 if fuzzer:
461 install = False
462 if ldflags is None:
463 ldflags = bld.env['FUZZ_TARGET_LDFLAGS']
465 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
466 return
468 features = 'c cprogram symlink_bin install_bin'
469 if pyembed:
470 features += ' pyembed'
472 obj_target = binname + '.objlist'
474 source = bld.EXPAND_VARIABLES(source, vars=vars)
475 if subdir:
476 source = bld.SUBDIR(subdir, source)
477 source = unique_list(TO_LIST(source))
479 if group == 'binaries':
480 subsystem_group = 'main'
481 elif group == 'build_compilers':
482 subsystem_group = 'compiler_libraries'
483 else:
484 subsystem_group = group
486 # only specify PIE flags for binaries
487 pie_cflags = TO_LIST(cflags)
488 pie_ldflags = TO_LIST(ldflags)
489 if bld.env['ENABLE_PIE'] is True:
490 pie_cflags.extend(TO_LIST('-fPIE'))
491 pie_ldflags.extend(TO_LIST('-pie'))
492 if bld.env['ENABLE_RELRO'] is True:
493 pie_ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now'))
495 # first create a target for building the object files for this binary
496 # by separating in this way, we avoid recompiling the C files
497 # separately for the install binary and the build binary
498 bld.SAMBA_SUBSYSTEM(obj_target,
499 source = source,
500 deps = deps,
501 includes = includes,
502 cflags = pie_cflags,
503 cflags_end = cflags_end,
504 group = subsystem_group,
505 autoproto = autoproto,
506 subsystem_name = subsystem_name,
507 local_include = local_include,
508 global_include = global_include,
509 use_hostcc = use_hostcc,
510 pyext = pyembed,
511 allow_warnings = allow_warnings,
512 use_global_deps= use_global_deps)
514 bld.SET_BUILD_GROUP(group)
516 # the binary itself will depend on that object target
517 deps = TO_LIST(deps)
518 deps.append(obj_target)
520 t = bld(
521 features = features,
522 source = [],
523 target = binname,
524 samba_deps = deps,
525 samba_includes = includes,
526 local_include = local_include,
527 global_include = global_include,
528 samba_modules = modules,
529 top = True,
530 samba_subsystem= subsystem_name,
531 install_path = None,
532 samba_inst_path= install_path,
533 samba_install = install,
534 samba_ldflags = pie_ldflags
537 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
538 bld.MANPAGES(manpages, install)
540 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
543 #################################################################
544 def SAMBA_MODULE(bld, modname, source,
545 deps='',
546 includes='',
547 subsystem=None,
548 init_function=None,
549 module_init_name='samba_init_module',
550 autoproto=None,
551 autoproto_extra_source='',
552 cflags='',
553 cflags_end=None,
554 internal_module=True,
555 local_include=True,
556 global_include=True,
557 vars=None,
558 subdir=None,
559 enabled=True,
560 pyembed=False,
561 manpages=None,
562 allow_undefined_symbols=False,
563 allow_warnings=False,
564 install=True
566 '''define a Samba module.'''
568 bld.ASSERT(subsystem, "You must specify a subsystem for SAMBA_MODULE(%s)" % modname)
570 source = bld.EXPAND_VARIABLES(source, vars=vars)
571 if subdir:
572 source = bld.SUBDIR(subdir, source)
574 if internal_module or BUILTIN_LIBRARY(bld, modname):
575 # Do not create modules for disabled subsystems
576 if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED':
577 return
578 bld.SAMBA_SUBSYSTEM(modname, source,
579 deps=deps,
580 includes=includes,
581 autoproto=autoproto,
582 autoproto_extra_source=autoproto_extra_source,
583 cflags=cflags,
584 cflags_end=cflags_end,
585 local_include=local_include,
586 global_include=global_include,
587 allow_warnings=allow_warnings,
588 enabled=enabled)
590 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
591 return
593 if not enabled:
594 SET_TARGET_TYPE(bld, modname, 'DISABLED')
595 return
597 # Do not create modules for disabled subsystems
598 if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED':
599 return
601 realname = modname
602 deps += ' ' + subsystem
603 while realname.startswith("lib"+subsystem+"_"):
604 realname = realname[len("lib"+subsystem+"_"):]
605 while realname.startswith(subsystem+"_"):
606 realname = realname[len(subsystem+"_"):]
608 build_name = "%s_module_%s" % (subsystem, realname)
610 realname = bld.make_libname(realname)
611 while realname.startswith("lib"):
612 realname = realname[len("lib"):]
614 build_link_name = "modules/%s/%s" % (subsystem, realname)
616 if init_function:
617 cflags += " -D%s=%s" % (init_function, module_init_name)
619 bld.SAMBA_LIBRARY(modname,
620 source,
621 deps=deps,
622 includes=includes,
623 cflags=cflags,
624 cflags_end=cflags_end,
625 realname = realname,
626 autoproto = autoproto,
627 local_include=local_include,
628 global_include=global_include,
629 vars=vars,
630 bundled_name=build_name,
631 link_name=build_link_name,
632 install_path="${MODULESDIR}/%s" % subsystem,
633 pyembed=pyembed,
634 manpages=manpages,
635 allow_undefined_symbols=allow_undefined_symbols,
636 allow_warnings=allow_warnings,
637 private_library=True,
638 install=install
642 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
644 #################################################################
645 def SAMBA_PLUGIN(bld, pluginname, source,
646 deps='',
647 includes='',
648 vnum=None,
649 soname=None,
650 cflags='',
651 ldflags='',
652 local_include=True,
653 global_include=True,
654 vars=None,
655 subdir=None,
656 realname=None,
657 keep_underscore=False,
658 autoproto=None,
659 autoproto_extra_source='',
660 install_path=None,
661 install=True,
662 manpages=None,
663 require_builtin_deps=True,
664 allow_undefined_symbols=False,
665 enabled=True):
666 '''define an external plugin.'''
668 bld.ASSERT(realname, "You must specify a realname for SAMBA_PLUGIN(%s)" % pluginname)
670 source = bld.EXPAND_VARIABLES(source, vars=vars)
671 if subdir:
672 source = bld.SUBDIR(subdir, source)
674 build_name = "_plugin_%s" % (pluginname)
675 build_link_name = "plugins/%s" % (realname)
677 bld.SAMBA_LIBRARY(pluginname,
678 source,
679 bundled_name=build_name,
680 link_name=build_link_name,
681 target_type='PLUGIN',
682 deps=deps,
683 includes=includes,
684 vnum=vnum,
685 soname=soname,
686 cflags=cflags,
687 ldflags=ldflags,
688 realname=realname,
689 autoproto=autoproto,
690 autoproto_extra_source=autoproto_extra_source,
691 local_include=local_include,
692 global_include=global_include,
693 vars=vars,
694 group='main',
695 install_path=install_path,
696 install=install,
697 manpages=manpages,
698 require_builtin_deps=require_builtin_deps,
699 builtin_cflags=cflags,
700 hide_symbols=True,
701 public_headers=[],
702 public_headers_install=False,
703 pc_files=[],
704 allow_undefined_symbols=allow_undefined_symbols,
705 allow_warnings=False,
706 enabled=enabled)
707 Build.BuildContext.SAMBA_PLUGIN = SAMBA_PLUGIN
709 def __SAMBA_SUBSYSTEM_BUILTIN(bld, builtin_target, source,
710 deps='',
711 public_deps='',
712 includes='',
713 public_headers=None,
714 public_headers_install=True,
715 private_headers=None,
716 header_path=None,
717 builtin_cflags='',
718 builtin_cflags_end=None,
719 group='main',
720 autoproto=None,
721 autoproto_extra_source='',
722 depends_on='',
723 local_include=True,
724 global_include=True,
725 allow_warnings=False):
727 bld.ASSERT(builtin_target.endswith('.builtin.objlist'),
728 "builtin_target[%s] does not end with '.builtin.objlist'" %
729 (builtin_target))
730 return bld.SAMBA_SUBSYSTEM(builtin_target, source,
731 deps=deps,
732 public_deps=public_deps,
733 includes=includes,
734 public_headers=public_headers,
735 public_headers_install=public_headers_install,
736 private_headers=private_headers,
737 header_path=header_path,
738 cflags=builtin_cflags,
739 cflags_end=builtin_cflags_end,
740 hide_symbols=True,
741 group=group,
742 target_type='BUILTIN',
743 autoproto=autoproto,
744 autoproto_extra_source=autoproto_extra_source,
745 depends_on=depends_on,
746 local_include=local_include,
747 global_include=global_include,
748 allow_warnings=allow_warnings,
749 __require_builtin_deps=True)
751 #################################################################
752 def SAMBA_SUBSYSTEM(bld, modname, source,
753 deps='',
754 public_deps='',
755 __force_empty=False,
756 includes='',
757 public_headers=None,
758 public_headers_install=True,
759 private_headers=None,
760 header_path=None,
761 cflags='',
762 cflags_end=None,
763 group='main',
764 target_type='SUBSYSTEM',
765 init_function_sentinel=None,
766 autoproto=None,
767 autoproto_extra_source='',
768 depends_on='',
769 local_include=True,
770 local_include_first=True,
771 global_include=True,
772 subsystem_name=None,
773 enabled=True,
774 use_hostcc=False,
775 use_global_deps=True,
776 vars=None,
777 subdir=None,
778 hide_symbols=False,
779 __require_builtin_deps=False,
780 provide_builtin_linking=False,
781 builtin_cflags='',
782 allow_warnings=False,
783 pyext=False,
784 pyembed=False):
785 '''define a Samba subsystem'''
787 # We support:
788 # - SUBSYSTEM: a normal subsystem from SAMBA_SUBSYSTEM()
789 # - BUILTIN: a hidden subsystem from __SAMBA_SUBSYSTEM_BUILTIN()
790 if target_type not in ['SUBSYSTEM', 'BUILTIN']:
791 raise Errors.WafError("target_type[%s] not supported in SAMBA_SUBSYSTEM('%s')" %
792 (target_type, modname))
794 if not enabled:
795 SET_TARGET_TYPE(bld, modname, 'DISABLED')
796 return
798 # remember empty subsystems, so we can strip the dependencies
799 if ((source == '') or (source == [])):
800 if not __force_empty and deps == '' and public_deps == '':
801 SET_TARGET_TYPE(bld, modname, 'EMPTY')
802 return
803 empty_c = modname + '.empty.c'
804 bld.SAMBA_GENERATOR('%s_empty_c' % modname,
805 rule=generate_empty_file,
806 target=empty_c)
807 source=empty_c
809 if not SET_TARGET_TYPE(bld, modname, target_type):
810 return
812 source = bld.EXPAND_VARIABLES(source, vars=vars)
813 if subdir:
814 source = bld.SUBDIR(subdir, source)
815 source = unique_list(TO_LIST(source))
817 deps += ' ' + public_deps
819 bld.SET_BUILD_GROUP(group)
821 features = 'c'
822 if pyext:
823 features += ' pyext'
824 if pyembed:
825 features += ' pyembed'
827 t = bld(
828 features = features,
829 source = source,
830 target = modname,
831 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags,
832 allow_warnings=allow_warnings,
833 use_hostcc=use_hostcc,
834 hide_symbols=hide_symbols),
835 depends_on = depends_on,
836 samba_deps = TO_LIST(deps),
837 samba_includes = includes,
838 local_include = local_include,
839 local_include_first = local_include_first,
840 global_include = global_include,
841 samba_subsystem= subsystem_name,
842 samba_use_hostcc = use_hostcc,
843 samba_use_global_deps = use_global_deps,
844 samba_require_builtin_deps = __require_builtin_deps,
845 samba_builtin_subsystem = None,
848 if cflags_end is not None:
849 t.samba_cflags.extend(TO_LIST(cflags_end))
851 if autoproto is not None:
852 bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source))
853 if public_headers is not None:
854 bld.PUBLIC_HEADERS(public_headers, header_path=header_path,
855 public_headers_install=public_headers_install)
857 if provide_builtin_linking:
859 if use_hostcc:
860 raise Errors.WafError("subsystem[%s] provide_builtin_linking=True " +
861 "not allowed with use_hostcc=True" %
862 modname)
864 if pyext or pyembed:
865 raise Errors.WafError("subsystem[%s] provide_builtin_linking=True " +
866 "not allowed with pyext=True nor pyembed=True" %
867 modname)
869 if __require_builtin_deps:
870 raise Errors.WafError("subsystem[%s] provide_builtin_linking=True " +
871 "not allowed with __require_builtin_deps=True" %
872 modname)
874 builtin_target = modname + '.builtin.objlist'
875 tbuiltin = __SAMBA_SUBSYSTEM_BUILTIN(bld, builtin_target, source,
876 deps=deps,
877 public_deps=public_deps,
878 includes=includes,
879 header_path=header_path,
880 builtin_cflags=builtin_cflags,
881 builtin_cflags_end='-D_PUBLIC_=_PRIVATE_',
882 group=group,
883 depends_on=depends_on,
884 local_include=local_include,
885 global_include=global_include,
886 allow_warnings=allow_warnings)
887 t.samba_builtin_subsystem = tbuiltin
889 return t
892 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
895 def SAMBA_GENERATOR(bld, name, rule, source='', target='',
896 group='generators', enabled=True,
897 public_headers=None,
898 public_headers_install=True,
899 private_headers=None,
900 header_path=None,
901 vars=None,
902 dep_vars=[],
903 always=False):
904 '''A generic source generator target'''
906 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
907 return
909 if not enabled:
910 return
912 dep_vars = TO_LIST(dep_vars)
913 dep_vars.append('ruledeps')
914 dep_vars.append('SAMBA_GENERATOR_VARS')
916 shell=isinstance(rule, str)
918 # This ensures that if the command (executed in the shell) fails
919 # (returns non-zero), the build fails
920 if shell:
921 rule = "set -e; " + rule
923 bld.SET_BUILD_GROUP(group)
924 t = bld(
925 rule=rule,
926 source=bld.EXPAND_VARIABLES(source, vars=vars),
927 shell=shell,
928 target=target,
929 update_outputs=True,
930 before='c',
931 ext_out='.c',
932 samba_type='GENERATOR',
933 dep_vars = dep_vars,
934 name=name)
936 if vars is None:
937 vars = {}
938 t.env.SAMBA_GENERATOR_VARS = vars
940 if always:
941 t.always = True
943 if public_headers is not None:
944 bld.PUBLIC_HEADERS(public_headers, header_path=header_path,
945 public_headers_install=public_headers_install)
946 return t
947 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
951 @Utils.run_once
952 def SETUP_BUILD_GROUPS(bld):
953 '''setup build groups used to ensure that the different build
954 phases happen consecutively'''
955 bld.p_ln = bld.srcnode # we do want to see all targets!
956 bld.env['USING_BUILD_GROUPS'] = True
957 bld.add_group('setup')
958 bld.add_group('generators')
959 bld.add_group('hostcc_base_build_source')
960 bld.add_group('hostcc_base_build_main')
961 bld.add_group('hostcc_build_source')
962 bld.add_group('hostcc_build_main')
963 bld.add_group('vscripts')
964 bld.add_group('base_libraries')
965 bld.add_group('build_source')
966 bld.add_group('prototypes')
967 bld.add_group('headers')
968 bld.add_group('main')
969 bld.add_group('symbolcheck')
970 bld.add_group('syslibcheck')
971 bld.add_group('final')
972 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
975 def SET_BUILD_GROUP(bld, group):
976 '''set the current build group'''
977 if not 'USING_BUILD_GROUPS' in bld.env:
978 return
979 bld.set_group(group)
980 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
984 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
985 '''used to copy scripts from the source tree into the build directory
986 for use by selftest'''
988 source = bld.path.ant_glob(pattern, flat=True)
990 bld.SET_BUILD_GROUP('build_source')
991 for s in TO_LIST(source):
992 iname = s
993 if installname is not None:
994 iname = installname
995 target = os.path.join(installdir, iname)
996 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
997 mkdir_p(tgtdir)
998 link_src = os.path.normpath(os.path.join(bld.path.abspath(), s))
999 link_dst = os.path.join(tgtdir, os.path.basename(iname))
1000 if os.path.islink(link_dst) and os.readlink(link_dst) == link_src:
1001 continue
1002 if os.path.islink(link_dst):
1003 os.unlink(link_dst)
1004 Logs.info("symlink: %s -> %s/%s" % (s, installdir, iname))
1005 symlink(link_src, link_dst)
1006 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT
1009 def copy_and_fix_python_path(task):
1010 pattern='sys.path.insert(0, "bin/python")'
1011 if task.env["PYTHONARCHDIR"] in sys.path and task.env["PYTHONDIR"] in sys.path:
1012 replacement = ""
1013 elif task.env["PYTHONARCHDIR"] == task.env["PYTHONDIR"]:
1014 replacement="""sys.path.insert(0, "%s")""" % task.env["PYTHONDIR"]
1015 else:
1016 replacement="""sys.path.insert(0, "%s")
1017 sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"])
1019 if task.env["PYTHON"][0].startswith("/"):
1020 replacement_shebang = "#!%s\n" % task.env["PYTHON"][0]
1021 else:
1022 replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PYTHON"][0]
1024 installed_location=task.outputs[0].bldpath(task.env)
1025 source_file = open(task.inputs[0].srcpath(task.env))
1026 installed_file = open(installed_location, 'w')
1027 lineno = 0
1028 for line in source_file:
1029 newline = line
1030 if (lineno == 0 and
1031 line[:2] == "#!"):
1032 newline = replacement_shebang
1033 elif pattern in line:
1034 newline = line.replace(pattern, replacement)
1035 installed_file.write(newline)
1036 lineno = lineno + 1
1037 installed_file.close()
1038 os.chmod(installed_location, 0o755)
1039 return 0
1041 def copy_and_fix_perl_path(task):
1042 pattern='use lib "$RealBin/lib";'
1044 replacement = ""
1045 if not task.env["PERL_LIB_INSTALL_DIR"] in task.env["PERL_INC"]:
1046 replacement = 'use lib "%s";' % task.env["PERL_LIB_INSTALL_DIR"]
1048 if task.env["PERL"][0] == "/":
1049 replacement_shebang = "#!%s\n" % task.env["PERL"]
1050 else:
1051 replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PERL"]
1053 installed_location=task.outputs[0].bldpath(task.env)
1054 source_file = open(task.inputs[0].srcpath(task.env))
1055 installed_file = open(installed_location, 'w')
1056 lineno = 0
1057 for line in source_file:
1058 newline = line
1059 if lineno == 0 and task.env["PERL_SPECIFIED"] == True and line[:2] == "#!":
1060 newline = replacement_shebang
1061 elif pattern in line:
1062 newline = line.replace(pattern, replacement)
1063 installed_file.write(newline)
1064 lineno = lineno + 1
1065 installed_file.close()
1066 os.chmod(installed_location, 0o755)
1067 return 0
1070 def install_file(bld, destdir, file, chmod=MODE_644, flat=False,
1071 python_fixup=False, perl_fixup=False,
1072 destname=None, base_name=None):
1073 '''install a file'''
1074 if not isinstance(file, str):
1075 file = file.abspath()
1076 destdir = bld.EXPAND_VARIABLES(destdir)
1077 if not destname:
1078 destname = file
1079 if flat:
1080 destname = os.path.basename(destname)
1081 dest = os.path.join(destdir, destname)
1082 if python_fixup:
1083 # fix the path python will use to find Samba modules
1084 inst_file = file + '.inst'
1085 bld.SAMBA_GENERATOR('python_%s' % destname,
1086 rule=copy_and_fix_python_path,
1087 dep_vars=["PYTHON","PYTHON_SPECIFIED","PYTHONDIR","PYTHONARCHDIR"],
1088 source=file,
1089 target=inst_file)
1090 file = inst_file
1091 if perl_fixup:
1092 # fix the path perl will use to find Samba modules
1093 inst_file = file + '.inst'
1094 bld.SAMBA_GENERATOR('perl_%s' % destname,
1095 rule=copy_and_fix_perl_path,
1096 dep_vars=["PERL","PERL_SPECIFIED","PERL_LIB_INSTALL_DIR"],
1097 source=file,
1098 target=inst_file)
1099 file = inst_file
1100 if base_name:
1101 file = os.path.join(base_name, file)
1102 bld.install_as(dest, file, chmod=chmod)
1105 def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False,
1106 python_fixup=False, perl_fixup=False,
1107 destname=None, base_name=None):
1108 '''install a set of files'''
1109 for f in TO_LIST(files):
1110 install_file(bld, destdir, f, chmod=chmod, flat=flat,
1111 python_fixup=python_fixup, perl_fixup=perl_fixup,
1112 destname=destname, base_name=base_name)
1113 Build.BuildContext.INSTALL_FILES = INSTALL_FILES
1116 def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False,
1117 python_fixup=False, exclude=None, trim_path=None):
1118 '''install a set of files matching a wildcard pattern'''
1119 files=TO_LIST(bld.path.ant_glob(pattern, flat=True))
1120 if trim_path:
1121 files2 = []
1122 for f in files:
1123 files2.append(os.path.relpath(f, trim_path))
1124 files = files2
1126 if exclude:
1127 for f in files[:]:
1128 if fnmatch.fnmatch(f, exclude):
1129 files.remove(f)
1130 INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat,
1131 python_fixup=python_fixup, base_name=trim_path)
1132 Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
1134 def INSTALL_DIR(bld, path, chmod=0o755, env=None):
1135 """Install a directory if it doesn't exist, always set permissions."""
1137 if not path:
1138 return []
1140 destpath = bld.EXPAND_VARIABLES(path)
1141 if Options.options.destdir:
1142 destpath = os.path.join(Options.options.destdir, destpath.lstrip(os.sep))
1144 if bld.is_install > 0:
1145 if not os.path.isdir(destpath):
1146 try:
1147 Logs.info('* create %s', destpath)
1148 os.makedirs(destpath)
1149 os.chmod(destpath, chmod)
1150 except OSError as e:
1151 if not os.path.isdir(destpath):
1152 raise Errors.WafError("Cannot create the folder '%s' (error: %s)" % (path, e))
1153 Build.BuildContext.INSTALL_DIR = INSTALL_DIR
1155 def INSTALL_DIRS(bld, destdir, dirs, chmod=0o755, env=None):
1156 '''install a set of directories'''
1157 destdir = bld.EXPAND_VARIABLES(destdir)
1158 dirs = bld.EXPAND_VARIABLES(dirs)
1159 for d in TO_LIST(dirs):
1160 INSTALL_DIR(bld, os.path.join(destdir, d), chmod, env)
1161 Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS
1164 def MANPAGES(bld, manpages, install):
1165 '''build and install manual pages'''
1166 bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
1167 for m in manpages.split():
1168 source = m + '.xml'
1169 bld.SAMBA_GENERATOR(m,
1170 source=source,
1171 target=m,
1172 group='final',
1173 rule='${XSLTPROC} --xinclude -o ${TGT} --nonet ${MAN_XSL} ${SRC}'
1175 if install:
1176 bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True)
1177 Build.BuildContext.MANPAGES = MANPAGES
1179 def SAMBAMANPAGES(bld, manpages, extra_source=None):
1180 '''build and install manual pages'''
1181 bld.env.SAMBA_EXPAND_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/expand-sambadoc.xsl'
1182 bld.env.SAMBA_MAN_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/man.xsl'
1183 bld.env.SAMBA_CATALOG = bld.bldnode.abspath() + '/docs-xml/build/catalog.xml'
1184 bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.env.SAMBA_CATALOG
1186 for m in manpages.split():
1187 source = [m + '.xml']
1188 if extra_source is not None:
1189 source = [source, extra_source]
1190 # ${SRC[1]}, ${SRC[2]} and ${SRC[3]} are not referenced in the
1191 # SAMBA_GENERATOR but trigger the dependency calculation so
1192 # ensures that manpages are rebuilt when these change.
1193 source += ['build/DTD/samba.build.pathconfig', 'build/DTD/samba.entities', 'build/DTD/samba.build.version']
1194 bld.SAMBA_GENERATOR(m,
1195 source=source,
1196 target=m,
1197 group='final',
1198 dep_vars=['SAMBA_MAN_XSL', 'SAMBA_EXPAND_XSL', 'SAMBA_CATALOG'],
1199 rule='''XML_CATALOG_FILES="${SAMBA_CATALOGS}"
1200 export XML_CATALOG_FILES
1201 ${XSLTPROC} --xinclude --stringparam noreference 0 -o ${TGT}.xml --nonet ${SAMBA_EXPAND_XSL} ${SRC[0].abspath(env)}
1202 ${XSLTPROC} --nonet -o ${TGT} ${SAMBA_MAN_XSL} ${TGT}.xml'''
1204 bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True)
1205 Build.BuildContext.SAMBAMANPAGES = SAMBAMANPAGES
1207 @after('apply_link')
1208 @feature('cshlib')
1209 def apply_bundle_remove_dynamiclib_patch(self):
1210 if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False):
1211 if not getattr(self,'vnum',None):
1212 try:
1213 self.env['LINKFLAGS'].remove('-dynamiclib')
1214 self.env['LINKFLAGS'].remove('-single_module')
1215 except ValueError:
1216 pass