smbprinting: fix wrong == in shell tests
[Samba/gebeck_regimport.git] / buildtools / wafsamba / wafsamba.py
blob5d13fa1023aad02e6b1b1eb5830fb859f147f32a
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 Build, os, Options, Task, Utils, cc, TaskGen, fnmatch, re, shutil, Logs, Constants
5 from Configure import conf
6 from Logs import debug
7 from samba_utils import SUBST_VARS_RECURSIVE
8 TaskGen.task_gen.apply_verif = Utils.nada
10 # bring in the other samba modules
11 from samba_optimisation import *
12 from samba_utils import *
13 from samba_version import *
14 from samba_autoconf import *
15 from samba_patterns import *
16 from samba_pidl import *
17 from samba_autoproto import *
18 from samba_python import *
19 from samba_deps import *
20 from samba_bundled import *
21 import samba_install
22 import samba_conftests
23 import samba_abi
24 import tru64cc
25 import irixcc
26 import generic_cc
27 import samba_dist
28 import samba_wildcard
29 import stale_files
30 import symbols
31 import pkgconfig
33 # some systems have broken threading in python
34 if os.environ.get('WAF_NOTHREADS') == '1':
35 import nothreads
37 LIB_PATH="shared"
39 os.putenv('PYTHONUNBUFFERED', '1')
42 if Constants.HEXVERSION < 0x105019:
43 Logs.error('''
44 Please use the version of waf that comes with Samba, not
45 a system installed version. See http://wiki.samba.org/index.php/Waf
46 for details.
48 Alternatively, please use ./autogen-waf.sh, and then
49 run ./configure and make as usual. That will call the right version of waf.
50 ''')
51 sys.exit(1)
54 @conf
55 def SAMBA_BUILD_ENV(conf):
56 '''create the samba build environment'''
57 conf.env.BUILD_DIRECTORY = conf.blddir
58 mkdir_p(os.path.join(conf.blddir, LIB_PATH))
59 mkdir_p(os.path.join(conf.blddir, LIB_PATH, "private"))
60 mkdir_p(os.path.join(conf.blddir, "modules"))
61 mkdir_p(os.path.join(conf.blddir, 'python/samba/dcerpc'))
62 # this allows all of the bin/shared and bin/python targets
63 # to be expressed in terms of build directory paths
64 mkdir_p(os.path.join(conf.blddir, 'default'))
65 for p in ['python','shared', 'modules']:
66 link_target = os.path.join(conf.blddir, 'default/' + p)
67 if not os.path.lexists(link_target):
68 os.symlink('../' + p, link_target)
70 # get perl to put the blib files in the build directory
71 blib_bld = os.path.join(conf.blddir, 'default/pidl/blib')
72 blib_src = os.path.join(conf.srcdir, 'pidl/blib')
73 mkdir_p(blib_bld + '/man1')
74 mkdir_p(blib_bld + '/man3')
75 if os.path.islink(blib_src):
76 os.unlink(blib_src)
77 elif os.path.exists(blib_src):
78 shutil.rmtree(blib_src)
81 def ADD_INIT_FUNCTION(bld, subsystem, target, init_function):
82 '''add an init_function to the list for a subsystem'''
83 if init_function is None:
84 return
85 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
86 cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
87 if not subsystem in cache:
88 cache[subsystem] = []
89 cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } )
90 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
94 #################################################################
95 def SAMBA_LIBRARY(bld, libname, source,
96 deps='',
97 public_deps='',
98 includes='',
99 public_headers=None,
100 header_path=None,
101 pc_files=None,
102 vnum=None,
103 soname=None,
104 cflags='',
105 external_library=False,
106 realname=None,
107 autoproto=None,
108 group='libraries',
109 depends_on='',
110 local_include=True,
111 vars=None,
112 install_path=None,
113 install=True,
114 pyembed=False,
115 pyext=False,
116 target_type='LIBRARY',
117 bundled_extension=True,
118 link_name=None,
119 abi_file=None,
120 abi_match=None,
121 hide_symbols=False,
122 manpages=None,
123 private_library=False,
124 grouping_library=False,
125 enabled=True):
126 '''define a Samba library'''
128 if not enabled:
129 SET_TARGET_TYPE(bld, libname, 'DISABLED')
130 return
132 source = bld.EXPAND_VARIABLES(source, vars=vars)
134 # remember empty libraries, so we can strip the dependencies
135 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
136 SET_TARGET_TYPE(bld, libname, 'EMPTY')
137 return
139 if BUILTIN_LIBRARY(bld, libname):
140 obj_target = libname
141 else:
142 obj_target = libname + '.objlist'
144 if group == 'libraries':
145 subsystem_group = 'main'
146 else:
147 subsystem_group = group
149 # first create a target for building the object files for this library
150 # by separating in this way, we avoid recompiling the C files
151 # separately for the install library and the build library
152 bld.SAMBA_SUBSYSTEM(obj_target,
153 source = source,
154 deps = deps,
155 public_deps = public_deps,
156 includes = includes,
157 public_headers = public_headers,
158 header_path = header_path,
159 cflags = cflags,
160 group = subsystem_group,
161 autoproto = autoproto,
162 depends_on = depends_on,
163 hide_symbols = hide_symbols,
164 pyext = pyext or (target_type == "PYTHON"),
165 local_include = local_include)
167 if BUILTIN_LIBRARY(bld, libname):
168 return
170 if not SET_TARGET_TYPE(bld, libname, target_type):
171 return
173 # the library itself will depend on that object target
174 deps += ' ' + public_deps
175 deps = TO_LIST(deps)
176 deps.append(obj_target)
178 realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON'))
179 link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON'))
181 # we don't want any public libraries without version numbers
182 if not private_library and vnum is None and soname is None and target_type != 'PYTHON' and not realname:
183 raise Utils.WafError("public library '%s' must have a vnum" % libname)
185 if target_type == 'PYTHON' or realname or not private_library:
186 bundled_name = libname.replace('_', '-')
187 else:
188 bundled_name = PRIVATE_NAME(bld, libname, bundled_extension, private_library)
190 if private_library:
191 if vnum:
192 Logs.error("vnum is invalid for private libraries")
193 sys.exit(1)
194 vnum = Utils.g_module.VERSION
196 features = 'cc cshlib symlink_lib install_lib'
197 if target_type == 'PYTHON':
198 features += ' pyext'
199 if pyext or pyembed:
200 # this is quite strange. we should add pyext feature for pyext
201 # but that breaks the build. This may be a bug in the waf python tool
202 features += ' pyembed'
203 if abi_file:
204 features += ' abi_check'
206 if abi_file:
207 abi_file = os.path.join(bld.curdir, abi_file)
209 bld.SET_BUILD_GROUP(group)
210 t = bld(
211 features = features,
212 source = [],
213 target = bundled_name,
214 depends_on = depends_on,
215 samba_deps = deps,
216 samba_includes = includes,
217 local_include = local_include,
218 vnum = vnum,
219 soname = soname,
220 install_path = None,
221 samba_inst_path = install_path,
222 name = libname,
223 samba_realname = realname,
224 samba_install = install,
225 abi_file = abi_file,
226 abi_match = abi_match,
227 private_library = private_library,
228 grouping_library=grouping_library
231 if realname and not link_name:
232 link_name = 'shared/%s' % realname
234 if link_name:
235 t.link_name = link_name
237 if pc_files is not None:
238 bld.PKG_CONFIG_FILES(pc_files, vnum=vnum)
240 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
241 bld.MANPAGES(manpages)
244 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
247 #################################################################
248 def SAMBA_BINARY(bld, binname, source,
249 deps='',
250 includes='',
251 public_headers=None,
252 header_path=None,
253 modules=None,
254 ldflags=None,
255 cflags='',
256 autoproto=None,
257 use_hostcc=False,
258 use_global_deps=True,
259 compiler=None,
260 group='binaries',
261 manpages=None,
262 local_include=True,
263 subsystem_name=None,
264 pyembed=False,
265 vars=None,
266 install=True,
267 install_path=None,
268 enabled=True):
269 '''define a Samba binary'''
271 if not enabled:
272 SET_TARGET_TYPE(bld, binname, 'DISABLED')
273 return
275 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
276 return
278 features = 'cc cprogram symlink_bin install_bin'
279 if pyembed:
280 features += ' pyembed'
282 obj_target = binname + '.objlist'
284 source = bld.EXPAND_VARIABLES(source, vars=vars)
285 source = unique_list(TO_LIST(source))
287 if group == 'binaries':
288 subsystem_group = 'main'
289 else:
290 subsystem_group = group
292 # first create a target for building the object files for this binary
293 # by separating in this way, we avoid recompiling the C files
294 # separately for the install binary and the build binary
295 bld.SAMBA_SUBSYSTEM(obj_target,
296 source = source,
297 deps = deps,
298 includes = includes,
299 cflags = cflags,
300 group = subsystem_group,
301 autoproto = autoproto,
302 subsystem_name = subsystem_name,
303 local_include = local_include,
304 use_hostcc = use_hostcc,
305 pyext = pyembed,
306 use_global_deps= use_global_deps)
308 bld.SET_BUILD_GROUP(group)
310 # the binary itself will depend on that object target
311 deps = TO_LIST(deps)
312 deps.append(obj_target)
314 t = bld(
315 features = features,
316 source = [],
317 target = binname,
318 samba_deps = deps,
319 samba_includes = includes,
320 local_include = local_include,
321 samba_modules = modules,
322 top = True,
323 samba_subsystem= subsystem_name,
324 install_path = None,
325 samba_inst_path= install_path,
326 samba_install = install
329 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
330 bld.MANPAGES(manpages)
332 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
335 #################################################################
336 def SAMBA_MODULE(bld, modname, source,
337 deps='',
338 includes='',
339 subsystem=None,
340 init_function=None,
341 module_init_name='samba_init_module',
342 autoproto=None,
343 autoproto_extra_source='',
344 cflags='',
345 internal_module=True,
346 local_include=True,
347 vars=None,
348 enabled=True,
349 pyembed=True,
351 '''define a Samba module.'''
353 source = bld.EXPAND_VARIABLES(source, vars=vars)
355 if internal_module or BUILTIN_LIBRARY(bld, modname):
356 bld.SAMBA_SUBSYSTEM(modname, source,
357 deps=deps,
358 includes=includes,
359 autoproto=autoproto,
360 autoproto_extra_source=autoproto_extra_source,
361 cflags=cflags,
362 local_include=local_include,
363 enabled=enabled)
365 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
366 return
368 if not enabled:
369 SET_TARGET_TYPE(bld, modname, 'DISABLED')
370 return
372 obj_target = modname + '.objlist'
374 realname = modname
375 if subsystem is not None:
376 deps += ' ' + subsystem
377 while realname.startswith("lib"+subsystem+"_"):
378 realname = realname[len("lib"+subsystem+"_"):]
379 while realname.startswith(subsystem+"_"):
380 realname = realname[len(subsystem+"_"):]
382 realname = bld.make_libname(realname)
383 while realname.startswith("lib"):
384 realname = realname[len("lib"):]
386 build_link_name = "modules/%s/%s" % (subsystem, realname)
388 if init_function:
389 cflags += " -D%s=%s" % (init_function, module_init_name)
391 bld.SAMBA_LIBRARY(modname,
392 source,
393 deps=deps,
394 cflags=cflags,
395 realname = realname,
396 autoproto = autoproto,
397 local_include=local_include,
398 vars=vars,
399 link_name=build_link_name,
400 install_path="${MODULESDIR}/%s" % subsystem,
401 pyembed=pyembed,
405 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
408 #################################################################
409 def SAMBA_SUBSYSTEM(bld, modname, source,
410 deps='',
411 public_deps='',
412 includes='',
413 public_headers=None,
414 header_path=None,
415 cflags='',
416 cflags_end=None,
417 group='main',
418 init_function_sentinal=None,
419 autoproto=None,
420 autoproto_extra_source='',
421 depends_on='',
422 local_include=True,
423 local_include_first=True,
424 subsystem_name=None,
425 enabled=True,
426 use_hostcc=False,
427 use_global_deps=True,
428 vars=None,
429 hide_symbols=False,
430 pyext=False):
431 '''define a Samba subsystem'''
433 if not enabled:
434 SET_TARGET_TYPE(bld, modname, 'DISABLED')
435 return
437 # remember empty subsystems, so we can strip the dependencies
438 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
439 SET_TARGET_TYPE(bld, modname, 'EMPTY')
440 return
442 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
443 return
445 source = bld.EXPAND_VARIABLES(source, vars=vars)
446 source = unique_list(TO_LIST(source))
448 deps += ' ' + public_deps
450 bld.SET_BUILD_GROUP(group)
452 features = 'cc'
453 if pyext:
454 features += ' pyext'
456 t = bld(
457 features = features,
458 source = source,
459 target = modname,
460 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, hide_symbols=hide_symbols),
461 depends_on = depends_on,
462 samba_deps = TO_LIST(deps),
463 samba_includes = includes,
464 local_include = local_include,
465 local_include_first = local_include_first,
466 samba_subsystem= subsystem_name,
467 samba_use_hostcc = use_hostcc,
468 samba_use_global_deps = use_global_deps
471 if cflags_end is not None:
472 t.samba_cflags.extend(TO_LIST(cflags_end))
474 if autoproto is not None:
475 bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source))
476 if public_headers is not None:
477 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
478 return t
481 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
484 def SAMBA_GENERATOR(bld, name, rule, source='', target='',
485 group='generators', enabled=True,
486 public_headers=None,
487 header_path=None,
488 vars=None,
489 always=False):
490 '''A generic source generator target'''
492 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
493 return
495 if not enabled:
496 return
498 bld.SET_BUILD_GROUP(group)
499 t = bld(
500 rule=rule,
501 source=bld.EXPAND_VARIABLES(source, vars=vars),
502 target=target,
503 shell=isinstance(rule, str),
504 on_results=True,
505 before='cc',
506 ext_out='.c',
507 name=name)
509 if always:
510 t.always = True
512 if public_headers is not None:
513 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
514 return t
515 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
519 @runonce
520 def SETUP_BUILD_GROUPS(bld):
521 '''setup build groups used to ensure that the different build
522 phases happen consecutively'''
523 bld.p_ln = bld.srcnode # we do want to see all targets!
524 bld.env['USING_BUILD_GROUPS'] = True
525 bld.add_group('setup')
526 bld.add_group('build_compiler_source')
527 bld.add_group('base_libraries')
528 bld.add_group('generators')
529 bld.add_group('compiler_prototypes')
530 bld.add_group('compiler_libraries')
531 bld.add_group('build_compilers')
532 bld.add_group('build_source')
533 bld.add_group('prototypes')
534 bld.add_group('main')
535 bld.add_group('symbolcheck')
536 bld.add_group('libraries')
537 bld.add_group('binaries')
538 bld.add_group('syslibcheck')
539 bld.add_group('final')
540 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
543 def SET_BUILD_GROUP(bld, group):
544 '''set the current build group'''
545 if not 'USING_BUILD_GROUPS' in bld.env:
546 return
547 bld.set_group(group)
548 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
552 @conf
553 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
554 """use timestamps instead of file contents for deps
555 this currently doesn't work"""
556 def h_file(filename):
557 import stat
558 st = os.stat(filename)
559 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
560 m = Utils.md5()
561 m.update(str(st.st_mtime))
562 m.update(str(st.st_size))
563 m.update(filename)
564 return m.digest()
565 Utils.h_file = h_file
569 t = Task.simple_task_type('copy_script', 'rm -f "${LINK_TARGET}" && ln -s "${SRC[0].abspath(env)}" ${LINK_TARGET}',
570 shell=True, color='PINK', ext_in='.bin')
571 t.quiet = True
573 @feature('copy_script')
574 @before('apply_link')
575 def copy_script(self):
576 tsk = self.create_task('copy_script', self.allnodes[0])
577 tsk.env.TARGET = self.target
579 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
580 '''used to copy scripts from the source tree into the build directory
581 for use by selftest'''
583 source = bld.path.ant_glob(pattern)
585 bld.SET_BUILD_GROUP('build_source')
586 for s in TO_LIST(source):
587 iname = s
588 if installname != None:
589 iname = installname
590 target = os.path.join(installdir, iname)
591 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
592 mkdir_p(tgtdir)
593 t = bld(features='copy_script',
594 source = s,
595 target = target,
596 always = True,
597 install_path = None)
598 t.env.LINK_TARGET = target
600 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT
603 def install_file(bld, destdir, file, chmod=MODE_644, flat=False,
604 python_fixup=False, destname=None, base_name=None):
605 '''install a file'''
606 destdir = bld.EXPAND_VARIABLES(destdir)
607 if not destname:
608 destname = file
609 if flat:
610 destname = os.path.basename(destname)
611 dest = os.path.join(destdir, destname)
612 if python_fixup:
613 # fixup the python path it will use to find Samba modules
614 inst_file = file + '.inst'
615 if bld.env["PYTHONDIR"] not in sys.path:
616 regex = "s|\(sys.path.insert.*\)bin/python\(.*\)$|\\1${PYTHONDIR}\\2|g"
617 else:
618 # Eliminate updating sys.path if the target python dir is already
619 # in python path.
620 regex = "s|sys.path.insert.*bin/python.*$||g"
621 bld.SAMBA_GENERATOR('python_%s' % destname,
622 rule="sed '%s' < ${SRC} > ${TGT}" % regex,
623 source=file,
624 target=inst_file)
625 file = inst_file
626 if base_name:
627 file = os.path.join(base_name, file)
628 bld.install_as(dest, file, chmod=chmod)
631 def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False,
632 python_fixup=False, destname=None, base_name=None):
633 '''install a set of files'''
634 for f in TO_LIST(files):
635 install_file(bld, destdir, f, chmod=chmod, flat=flat,
636 python_fixup=python_fixup, destname=destname,
637 base_name=base_name)
638 Build.BuildContext.INSTALL_FILES = INSTALL_FILES
641 def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False,
642 python_fixup=False, exclude=None, trim_path=None):
643 '''install a set of files matching a wildcard pattern'''
644 files=TO_LIST(bld.path.ant_glob(pattern))
645 if trim_path:
646 files2 = []
647 for f in files:
648 files2.append(os_path_relpath(f, trim_path))
649 files = files2
651 if exclude:
652 for f in files[:]:
653 if fnmatch.fnmatch(f, exclude):
654 files.remove(f)
655 INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat,
656 python_fixup=python_fixup, base_name=trim_path)
657 Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
660 def INSTALL_DIRS(bld, destdir, dirs):
661 '''install a set of directories'''
662 destdir = bld.EXPAND_VARIABLES(destdir)
663 dirs = bld.EXPAND_VARIABLES(dirs)
664 for d in TO_LIST(dirs):
665 bld.install_dir(os.path.join(destdir, d))
666 Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS
669 re_header = re.compile('#include[ \t]*"([^"]+)"', re.I | re.M)
670 class header_task(Task.Task):
672 The public headers (the one installed on the system) have both
673 different paths and contents, so the rename is not enough.
675 Intermediate .inst.h files are created because path manipulation
676 may be slow. The substitution is thus performed only once.
679 name = 'header'
680 color = 'PINK'
681 vars = ['INCLUDEDIR', 'HEADER_DEPS']
683 def run(self):
684 txt = self.inputs[0].read(self.env)
686 # hard-coded string, but only present in samba4 (I promise, you won't feel a thing)
687 txt = txt.replace('#if _SAMBA_BUILD_ == 4', '#if 1\n')
689 # use a regexp to substitute the #include lines in the files
690 map = self.generator.bld.hnodemap
691 dirnodes = self.generator.bld.hnodedirs
692 def repl(m):
693 if m.group(1):
694 s = m.group(1)
696 # pokemon headers: gotta catch'em all!
697 fin = s
698 if s.startswith('bin/default'):
699 node = self.generator.bld.srcnode.find_resource(s.replace('bin/default/', ''))
700 if not node:
701 Logs.warn('could not find the public header for %r' % s)
702 elif node.id in map:
703 fin = map[node.id]
704 else:
705 Logs.warn('could not find the public header replacement for build header %r' % s)
706 else:
707 # this part is more difficult since the path may be relative to anything
708 for dirnode in dirnodes:
709 node = dirnode.find_resource(s)
710 if node:
711 if node.id in map:
712 fin = map[node.id]
713 break
714 else:
715 Logs.warn('could not find the public header replacement for source header %r %r' % (s, node))
716 else:
717 Logs.warn('-> could not find the public header for %r' % s)
719 return "#include <%s>" % fin
720 return ''
722 txt = re_header.sub(repl, txt)
724 # and write the output file
725 f = None
726 try:
727 f = open(self.outputs[0].abspath(self.env), 'w')
728 f.write(txt)
729 finally:
730 if f:
731 f.close()
733 @TaskGen.feature('pubh')
734 def make_public_headers(self):
736 collect the public headers to process and to install, then
737 create the substitutions (name and contents)
740 if not self.bld.is_install:
741 # install time only (lazy)
742 return
744 # keep two variables
745 # hnodedirs: list of folders for searching the headers
746 # hnodemap: node ids and replacement string (node objects are unique)
747 try:
748 self.bld.hnodedirs.append(self.path)
749 except AttributeError:
750 self.bld.hnodemap = {}
751 self.bld.hnodedirs = [self.bld.srcnode, self.path]
753 for k in 'source4 source4/include lib/talloc lib/tevent/ source4/lib/ldb/include/'.split():
754 node = self.bld.srcnode.find_dir(k)
755 if node:
756 self.bld.hnodedirs.append(node)
758 header_path = getattr(self, 'header_path', None) or ''
760 for x in self.to_list(self.headers):
762 # too complicated, but what was the original idea?
763 if isinstance(header_path, list):
764 add_dir = ''
765 for (p1, dir) in header_path:
766 lst = self.to_list(p1)
767 for p2 in lst:
768 if fnmatch.fnmatch(x, p2):
769 add_dir = dir
770 break
771 else:
772 continue
773 break
774 inst_path = add_dir
775 else:
776 inst_path = header_path
778 dest = ''
779 name = x
780 if x.find(':') != -1:
781 s = x.split(':')
782 name = s[0]
783 dest = s[1]
785 inn = self.path.find_resource(name)
787 if not inn:
788 raise ValueError("could not find the public header %r in %r" % (name, self.path))
789 out = inn.change_ext('.inst.h')
790 self.create_task('header', inn, out)
792 if not dest:
793 dest = inn.name
795 if inst_path:
796 inst_path = inst_path + '/'
797 inst_path = inst_path + dest
799 self.bld.install_as('${INCLUDEDIR}/%s' % inst_path, out, self.env)
801 self.bld.hnodemap[inn.id] = inst_path
803 # create a hash (not md5) to make sure the headers are re-created if something changes
804 val = 0
805 lst = list(self.bld.hnodemap.keys())
806 lst.sort()
807 for k in lst:
808 val = hash((val, k, self.bld.hnodemap[k]))
809 self.bld.env.HEADER_DEPS = val
811 def PUBLIC_HEADERS(bld, public_headers, header_path=None):
812 '''install some headers
814 header_path may either be a string that is added to the INCLUDEDIR,
815 or it can be a dictionary of wildcard patterns which map to destination
816 directories relative to INCLUDEDIR
818 bld.SET_BUILD_GROUP('final')
819 ret = bld(features=['pubh'], headers=public_headers, header_path=header_path)
820 return ret
821 Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS
824 def MANPAGES(bld, manpages):
825 '''build and install manual pages'''
826 bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
827 for m in manpages.split():
828 source = m + '.xml'
829 bld.SAMBA_GENERATOR(m,
830 source=source,
831 target=m,
832 group='final',
833 rule='${XSLTPROC} -o ${TGT} --nonet ${MAN_XSL} ${SRC}'
835 bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True)
836 Build.BuildContext.MANPAGES = MANPAGES
839 #############################################################
840 # give a nicer display when building different types of files
841 def progress_display(self, msg, fname):
842 col1 = Logs.colors(self.color)
843 col2 = Logs.colors.NORMAL
844 total = self.position[1]
845 n = len(str(total))
846 fs = '[%%%dd/%%%dd] %s %%s%%s%%s\n' % (n, n, msg)
847 return fs % (self.position[0], self.position[1], col1, fname, col2)
849 def link_display(self):
850 if Options.options.progress_bar != 0:
851 return Task.Task.old_display(self)
852 fname = self.outputs[0].bldpath(self.env)
853 return progress_display(self, 'Linking', fname)
854 Task.TaskBase.classes['cc_link'].display = link_display
856 def samba_display(self):
857 if Options.options.progress_bar != 0:
858 return Task.Task.old_display(self)
860 targets = LOCAL_CACHE(self, 'TARGET_TYPE')
861 if self.name in targets:
862 target_type = targets[self.name]
863 type_map = { 'GENERATOR' : 'Generating',
864 'PROTOTYPE' : 'Generating'
866 if target_type in type_map:
867 return progress_display(self, type_map[target_type], self.name)
869 if len(self.inputs) == 0:
870 return Task.Task.old_display(self)
872 fname = self.inputs[0].bldpath(self.env)
873 if fname[0:3] == '../':
874 fname = fname[3:]
875 ext_loc = fname.rfind('.')
876 if ext_loc == -1:
877 return Task.Task.old_display(self)
878 ext = fname[ext_loc:]
880 ext_map = { '.idl' : 'Compiling IDL',
881 '.et' : 'Compiling ERRTABLE',
882 '.asn1': 'Compiling ASN1',
883 '.c' : 'Compiling' }
884 if ext in ext_map:
885 return progress_display(self, ext_map[ext], fname)
886 return Task.Task.old_display(self)
888 Task.TaskBase.classes['Task'].old_display = Task.TaskBase.classes['Task'].display
889 Task.TaskBase.classes['Task'].display = samba_display
892 @after('apply_link')
893 @feature('cshlib')
894 def apply_bundle_remove_dynamiclib_patch(self):
895 if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False):
896 if not getattr(self,'vnum',None):
897 try:
898 self.env['LINKFLAGS'].remove('-dynamiclib')
899 self.env['LINKFLAGS'].remove('-single_module')
900 except ValueError:
901 pass