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, sys, Options, Task, Utils, cc, TaskGen, fnmatch, re, shutil, Logs, Constants
5 from Configure import conf
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 *
22 import samba_conftests
34 # some systems have broken threading in python
35 if os.environ.get('WAF_NOTHREADS') == '1':
40 os.environ['PYTHONUNBUFFERED'] = '1'
43 if Constants.HEXVERSION < 0x105019:
45 Please use the version of waf that comes with Samba, not
46 a system installed version. See http://wiki.samba.org/index.php/Waf
49 Alternatively, please run ./configure and make as usual. That will
50 call the right version of waf.''')
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):
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:
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:
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,
106 external_library=False,
119 target_type='LIBRARY',
120 bundled_extension=True,
126 private_library=False,
127 grouping_library=False,
128 allow_undefined_symbols=False,
130 '''define a Samba library'''
133 SET_TARGET_TYPE(bld, libname, 'DISABLED')
136 source = bld.EXPAND_VARIABLES(source, vars=vars)
138 source = bld.SUBDIR(subdir, source)
140 # remember empty libraries, so we can strip the dependencies
141 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
142 SET_TARGET_TYPE(bld, libname, 'EMPTY')
145 if BUILTIN_LIBRARY(bld, libname):
148 obj_target = libname + '.objlist'
150 if group == 'libraries':
151 subsystem_group = 'main'
153 subsystem_group = group
155 # first create a target for building the object files for this library
156 # by separating in this way, we avoid recompiling the C files
157 # separately for the install library and the build library
158 bld.SAMBA_SUBSYSTEM(obj_target,
161 public_deps = public_deps,
163 public_headers = public_headers,
164 header_path = header_path,
166 group = subsystem_group,
167 autoproto = autoproto,
168 depends_on = depends_on,
169 hide_symbols = hide_symbols,
170 pyext = pyext or (target_type == "PYTHON"),
171 local_include = local_include,
172 global_include = global_include)
174 if BUILTIN_LIBRARY(bld, libname):
177 if not SET_TARGET_TYPE(bld, libname, target_type):
180 # the library itself will depend on that object target
181 deps += ' ' + public_deps
183 deps.append(obj_target)
185 realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON'))
186 link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON'))
188 # we don't want any public libraries without version numbers
189 if not private_library and vnum is None and soname is None and target_type != 'PYTHON' and not realname:
190 raise Utils.WafError("public library '%s' must have a vnum" % libname)
192 if target_type == 'PYTHON' or realname or not private_library:
193 bundled_name = libname.replace('_', '-')
195 bundled_name = PRIVATE_NAME(bld, libname, bundled_extension, private_library)
197 ldflags = TO_LIST(ldflags)
199 features = 'cc cshlib symlink_lib install_lib'
200 if target_type == 'PYTHON':
203 # this is quite strange. we should add pyext feature for pyext
204 # but that breaks the build. This may be a bug in the waf python tool
205 features += ' pyembed'
208 features += ' abi_check'
211 if bld.env.HAVE_LD_VERSION_SCRIPT:
213 version = "%s_%s" % (Utils.g_module.APPNAME, Utils.g_module.VERSION)
215 version = "%s_%s" % (libname, vnum)
219 vscript = "%s.vscript" % libname
220 bld.ABI_VSCRIPT(libname, abi_directory, version, vscript,
222 fullname = apply_pattern(bundled_name, bld.env.shlib_PATTERN)
223 fullpath = bld.path.find_or_declare(fullname)
224 vscriptpath = bld.path.find_or_declare(vscript)
226 raise Utils.WafError("unable to find fullpath for %s" % fullname)
228 raise Utils.WafError("unable to find vscript path for %s" % vscript)
229 bld.add_manual_dependency(fullpath, vscriptpath)
230 if Options.is_install:
231 # also make the .inst file depend on the vscript
232 instname = apply_pattern(bundled_name + '.inst', bld.env.shlib_PATTERN)
233 bld.add_manual_dependency(bld.path.find_or_declare(instname), bld.path.find_or_declare(vscript))
234 vscript = os.path.join(bld.path.abspath(bld.env), vscript)
236 bld.SET_BUILD_GROUP(group)
240 target = bundled_name,
241 depends_on = depends_on,
242 samba_ldflags = ldflags,
244 samba_includes = includes,
245 version_script = vscript,
246 local_include = local_include,
247 global_include = global_include,
251 samba_inst_path = install_path,
253 samba_realname = realname,
254 samba_install = install,
255 abi_directory = "%s/%s" % (bld.path.abspath(), abi_directory),
256 abi_match = abi_match,
257 private_library = private_library,
258 grouping_library=grouping_library,
259 allow_undefined_symbols=allow_undefined_symbols
262 if realname and not link_name:
263 link_name = 'shared/%s' % realname
266 t.link_name = link_name
268 if pc_files is not None:
269 bld.PKG_CONFIG_FILES(pc_files, vnum=vnum)
271 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
272 bld.MANPAGES(manpages)
275 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
278 #################################################################
279 def SAMBA_BINARY(bld, binname, source,
289 use_global_deps=True,
302 '''define a Samba binary'''
305 SET_TARGET_TYPE(bld, binname, 'DISABLED')
308 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
311 features = 'cc cprogram symlink_bin install_bin'
313 features += ' pyembed'
315 obj_target = binname + '.objlist'
317 source = bld.EXPAND_VARIABLES(source, vars=vars)
319 source = bld.SUBDIR(subdir, source)
320 source = unique_list(TO_LIST(source))
322 if group == 'binaries':
323 subsystem_group = 'main'
325 subsystem_group = group
327 # first create a target for building the object files for this binary
328 # by separating in this way, we avoid recompiling the C files
329 # separately for the install binary and the build binary
330 bld.SAMBA_SUBSYSTEM(obj_target,
335 group = subsystem_group,
336 autoproto = autoproto,
337 subsystem_name = subsystem_name,
338 local_include = local_include,
339 global_include = global_include,
340 use_hostcc = use_hostcc,
342 use_global_deps= use_global_deps)
344 bld.SET_BUILD_GROUP(group)
346 # the binary itself will depend on that object target
348 deps.append(obj_target)
355 samba_includes = includes,
356 local_include = local_include,
357 global_include = global_include,
358 samba_modules = modules,
360 samba_subsystem= subsystem_name,
362 samba_inst_path= install_path,
363 samba_install = install,
364 samba_ldflags = TO_LIST(ldflags)
367 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
368 bld.MANPAGES(manpages)
370 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
373 #################################################################
374 def SAMBA_MODULE(bld, modname, source,
379 module_init_name='samba_init_module',
381 autoproto_extra_source='',
383 internal_module=True,
390 allow_undefined_symbols=False
392 '''define a Samba module.'''
394 source = bld.EXPAND_VARIABLES(source, vars=vars)
396 source = bld.SUBDIR(subdir, source)
398 if internal_module or BUILTIN_LIBRARY(bld, modname):
399 bld.SAMBA_SUBSYSTEM(modname, source,
403 autoproto_extra_source=autoproto_extra_source,
405 local_include=local_include,
406 global_include=global_include,
409 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
413 SET_TARGET_TYPE(bld, modname, 'DISABLED')
416 obj_target = modname + '.objlist'
419 if subsystem is not None:
420 deps += ' ' + subsystem
421 while realname.startswith("lib"+subsystem+"_"):
422 realname = realname[len("lib"+subsystem+"_"):]
423 while realname.startswith(subsystem+"_"):
424 realname = realname[len(subsystem+"_"):]
426 realname = bld.make_libname(realname)
427 while realname.startswith("lib"):
428 realname = realname[len("lib"):]
430 build_link_name = "modules/%s/%s" % (subsystem, realname)
433 cflags += " -D%s=%s" % (init_function, module_init_name)
435 bld.SAMBA_LIBRARY(modname,
441 autoproto = autoproto,
442 local_include=local_include,
443 global_include=global_include,
445 link_name=build_link_name,
446 install_path="${MODULESDIR}/%s" % subsystem,
448 allow_undefined_symbols=allow_undefined_symbols
452 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
455 #################################################################
456 def SAMBA_SUBSYSTEM(bld, modname, source,
465 init_function_sentinal=None,
467 autoproto_extra_source='',
470 local_include_first=True,
475 use_global_deps=True,
480 '''define a Samba subsystem'''
483 SET_TARGET_TYPE(bld, modname, 'DISABLED')
486 # remember empty subsystems, so we can strip the dependencies
487 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
488 SET_TARGET_TYPE(bld, modname, 'EMPTY')
491 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
494 source = bld.EXPAND_VARIABLES(source, vars=vars)
496 source = bld.SUBDIR(subdir, source)
497 source = unique_list(TO_LIST(source))
499 deps += ' ' + public_deps
501 bld.SET_BUILD_GROUP(group)
511 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, hide_symbols=hide_symbols),
512 depends_on = depends_on,
513 samba_deps = TO_LIST(deps),
514 samba_includes = includes,
515 local_include = local_include,
516 local_include_first = local_include_first,
517 global_include = global_include,
518 samba_subsystem= subsystem_name,
519 samba_use_hostcc = use_hostcc,
520 samba_use_global_deps = use_global_deps
523 if cflags_end is not None:
524 t.samba_cflags.extend(TO_LIST(cflags_end))
526 if autoproto is not None:
527 bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source))
528 if public_headers is not None:
529 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
533 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
536 def SAMBA_GENERATOR(bld, name, rule, source='', target='',
537 group='generators', enabled=True,
542 '''A generic source generator target'''
544 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
550 bld.SET_BUILD_GROUP(group)
553 source=bld.EXPAND_VARIABLES(source, vars=vars),
555 shell=isinstance(rule, str),
559 samba_type='GENERATOR',
560 dep_vars = [rule] + (vars or []),
566 if public_headers is not None:
567 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
569 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
574 def SETUP_BUILD_GROUPS(bld):
575 '''setup build groups used to ensure that the different build
576 phases happen consecutively'''
577 bld.p_ln = bld.srcnode # we do want to see all targets!
578 bld.env['USING_BUILD_GROUPS'] = True
579 bld.add_group('setup')
580 bld.add_group('build_compiler_source')
581 bld.add_group('vscripts')
582 bld.add_group('base_libraries')
583 bld.add_group('generators')
584 bld.add_group('compiler_prototypes')
585 bld.add_group('compiler_libraries')
586 bld.add_group('build_compilers')
587 bld.add_group('build_source')
588 bld.add_group('prototypes')
589 bld.add_group('main')
590 bld.add_group('symbolcheck')
591 bld.add_group('libraries')
592 bld.add_group('binaries')
593 bld.add_group('syslibcheck')
594 bld.add_group('final')
595 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
598 def SET_BUILD_GROUP(bld, group):
599 '''set the current build group'''
600 if not 'USING_BUILD_GROUPS' in bld.env:
603 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
608 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
609 """use timestamps instead of file contents for deps
610 this currently doesn't work"""
611 def h_file(filename):
613 st = os.stat(filename)
614 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
616 m.update(str(st.st_mtime))
617 m.update(str(st.st_size))
620 Utils.h_file = h_file
624 t = Task.simple_task_type('copy_script', 'rm -f "${LINK_TARGET}" && ln -s "${SRC[0].abspath(env)}" ${LINK_TARGET}',
625 shell=True, color='PINK', ext_in='.bin')
628 @feature('copy_script')
629 @before('apply_link')
630 def copy_script(self):
631 tsk = self.create_task('copy_script', self.allnodes[0])
632 tsk.env.TARGET = self.target
634 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
635 '''used to copy scripts from the source tree into the build directory
636 for use by selftest'''
638 source = bld.path.ant_glob(pattern)
640 bld.SET_BUILD_GROUP('build_source')
641 for s in TO_LIST(source):
643 if installname != None:
645 target = os.path.join(installdir, iname)
646 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
648 t = bld(features='copy_script',
653 t.env.LINK_TARGET = target
655 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT
657 def copy_and_fix_python_path(task):
658 pattern='sys.path.insert(0, "bin/python")'
659 if task.env["PYTHONARCHDIR"] in sys.path and task.env["PYTHONDIR"] in sys.path:
661 elif task.env["PYTHONARCHDIR"] == task.env["PYTHONDIR"]:
662 replacement="""sys.path.insert(0, "%s")""" % task.env["PYTHONDIR"]
664 replacement="""sys.path.insert(0, "%s")
665 sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"])
667 installed_location=task.outputs[0].bldpath(task.env)
668 source_file = open(task.inputs[0].srcpath(task.env))
669 installed_file = open(installed_location, 'w')
670 for line in source_file:
673 newline = line.replace(pattern, replacement)
674 installed_file.write(newline)
675 installed_file.close()
676 os.chmod(installed_location, 0755)
680 def install_file(bld, destdir, file, chmod=MODE_644, flat=False,
681 python_fixup=False, destname=None, base_name=None):
683 destdir = bld.EXPAND_VARIABLES(destdir)
687 destname = os.path.basename(destname)
688 dest = os.path.join(destdir, destname)
690 # fixup the python path it will use to find Samba modules
691 inst_file = file + '.inst'
692 bld.SAMBA_GENERATOR('python_%s' % destname,
693 rule=copy_and_fix_python_path,
698 file = os.path.join(base_name, file)
699 bld.install_as(dest, file, chmod=chmod)
702 def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False,
703 python_fixup=False, destname=None, base_name=None):
704 '''install a set of files'''
705 for f in TO_LIST(files):
706 install_file(bld, destdir, f, chmod=chmod, flat=flat,
707 python_fixup=python_fixup, destname=destname,
709 Build.BuildContext.INSTALL_FILES = INSTALL_FILES
712 def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False,
713 python_fixup=False, exclude=None, trim_path=None):
714 '''install a set of files matching a wildcard pattern'''
715 files=TO_LIST(bld.path.ant_glob(pattern))
719 files2.append(os_path_relpath(f, trim_path))
724 if fnmatch.fnmatch(f, exclude):
726 INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat,
727 python_fixup=python_fixup, base_name=trim_path)
728 Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
731 def INSTALL_DIRS(bld, destdir, dirs):
732 '''install a set of directories'''
733 destdir = bld.EXPAND_VARIABLES(destdir)
734 dirs = bld.EXPAND_VARIABLES(dirs)
735 for d in TO_LIST(dirs):
736 bld.install_dir(os.path.join(destdir, d))
737 Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS
740 def header_install_path(header, header_path):
741 '''find the installation path for a header, given a header_path option'''
744 if not isinstance(header_path, list):
746 for (p1, dir) in header_path:
747 for p2 in TO_LIST(p1):
748 if fnmatch.fnmatch(header, p2):
750 # default to current path
754 re_header = re.compile('#include[ \t]*"([^"]+)"', re.I | re.M)
755 class header_task(Task.Task):
757 The public headers (the one installed on the system) have both
758 different paths and contents, so the rename is not enough.
760 Intermediate .inst.h files are created because path manipulation
761 may be slow. The substitution is thus performed only once.
766 vars = ['INCLUDEDIR', 'HEADER_DEPS']
769 txt = self.inputs[0].read(self.env)
771 # hard-coded string, but only present in samba4 (I promise, you won't feel a thing)
772 txt = txt.replace('#if _SAMBA_BUILD_ == 4', '#if 1\n')
774 # use a regexp to substitute the #include lines in the files
775 map = self.generator.bld.hnodemap
776 dirnodes = self.generator.bld.hnodedirs
781 # pokemon headers: gotta catch'em all!
783 if s.startswith('bin/default'):
784 node = self.generator.bld.srcnode.find_resource(s.replace('bin/default/', ''))
786 Logs.warn('could not find the public header for %r' % s)
790 Logs.warn('could not find the public header replacement for build header %r' % s)
792 # this part is more difficult since the path may be relative to anything
793 for dirnode in dirnodes:
794 node = dirnode.find_resource(s)
800 Logs.warn('could not find the public header replacement for source header %r %r' % (s, node))
802 Logs.warn('-> could not find the public header for %r' % s)
804 return "#include <%s>" % fin
807 txt = re_header.sub(repl, txt)
809 # and write the output file
812 f = open(self.outputs[0].abspath(self.env), 'w')
818 @TaskGen.feature('pubh')
819 def make_public_headers(self):
821 collect the public headers to process and to install, then
822 create the substitutions (name and contents)
825 if not self.bld.is_install:
826 # install time only (lazy)
830 # hnodedirs: list of folders for searching the headers
831 # hnodemap: node ids and replacement string (node objects are unique)
833 self.bld.hnodedirs.append(self.path)
834 except AttributeError:
835 self.bld.hnodemap = {}
836 self.bld.hnodedirs = [self.bld.srcnode, self.path]
838 for k in 'source4 source4/include lib/talloc lib/tevent/ source4/lib/ldb/include/'.split():
839 node = self.bld.srcnode.find_dir(k)
841 self.bld.hnodedirs.append(node)
843 header_path = getattr(self, 'header_path', None) or ''
845 for x in self.to_list(self.headers):
847 inst_path = header_install_path(x, header_path)
851 if x.find(':') != -1:
856 inn = self.path.find_resource(name)
859 raise ValueError("could not find the public header %r in %r" % (name, self.path))
860 out = inn.change_ext('.inst.h')
861 self.create_task('header', inn, out)
867 inst_path = inst_path + '/'
868 inst_path = inst_path + dest
870 self.bld.install_as('${INCLUDEDIR}/%s' % inst_path, out, self.env)
872 self.bld.hnodemap[inn.id] = inst_path
874 # create a hash (not md5) to make sure the headers are re-created if something changes
876 lst = list(self.bld.hnodemap.keys())
879 val = hash((val, k, self.bld.hnodemap[k]))
880 self.bld.env.HEADER_DEPS = val
884 def symlink_header(task):
885 '''symlink a header in the build tree'''
886 src = task.inputs[0].abspath(task.env)
887 tgt = task.outputs[0].bldpath(task.env)
889 if os.path.lexists(tgt):
890 if os.path.islink(tgt) and os.readlink(tgt) == src:
896 def PUBLIC_HEADERS(bld, public_headers, header_path=None):
897 '''install some headers
899 header_path may either be a string that is added to the INCLUDEDIR,
900 or it can be a dictionary of wildcard patterns which map to destination
901 directories relative to INCLUDEDIR
903 bld.SET_BUILD_GROUP('final')
904 ret = bld(features=['pubh'], headers=public_headers, header_path=header_path)
906 if bld.env.build_public_headers:
907 # when build_public_headers is set, symlink the headers into the include/public
909 for h in TO_LIST(public_headers):
910 inst_path = header_install_path(h, header_path)
911 if h.find(':') != -1:
917 inst_name = os.path.basename(h)
918 relpath1 = os_path_relpath(bld.srcnode.abspath(), bld.curdir)
919 relpath2 = os_path_relpath(bld.curdir, bld.srcnode.abspath())
920 targetdir = os.path.normpath(os.path.join(relpath1, bld.env.build_public_headers, inst_path))
921 if not os.path.exists(os.path.join(bld.curdir, targetdir)):
922 raise Utils.WafError("missing source directory %s for public header %s" % (targetdir, inst_name))
923 target = os.path.join(targetdir, inst_name)
924 bld.SAMBA_GENERATOR('HEADER_%s/%s' % (relpath2, inst_name),
931 Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS
934 def MANPAGES(bld, manpages):
935 '''build and install manual pages'''
936 bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
937 for m in manpages.split():
939 bld.SAMBA_GENERATOR(m,
943 rule='${XSLTPROC} -o ${TGT} --nonet ${MAN_XSL} ${SRC}'
945 bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True)
946 Build.BuildContext.MANPAGES = MANPAGES
949 #############################################################
950 # give a nicer display when building different types of files
951 def progress_display(self, msg, fname):
952 col1 = Logs.colors(self.color)
953 col2 = Logs.colors.NORMAL
954 total = self.position[1]
956 fs = '[%%%dd/%%%dd] %s %%s%%s%%s\n' % (n, n, msg)
957 return fs % (self.position[0], self.position[1], col1, fname, col2)
959 def link_display(self):
960 if Options.options.progress_bar != 0:
961 return Task.Task.old_display(self)
962 fname = self.outputs[0].bldpath(self.env)
963 return progress_display(self, 'Linking', fname)
964 Task.TaskBase.classes['cc_link'].display = link_display
966 def samba_display(self):
967 if Options.options.progress_bar != 0:
968 return Task.Task.old_display(self)
970 targets = LOCAL_CACHE(self, 'TARGET_TYPE')
971 if self.name in targets:
972 target_type = targets[self.name]
973 type_map = { 'GENERATOR' : 'Generating',
974 'PROTOTYPE' : 'Generating'
976 if target_type in type_map:
977 return progress_display(self, type_map[target_type], self.name)
979 if len(self.inputs) == 0:
980 return Task.Task.old_display(self)
982 fname = self.inputs[0].bldpath(self.env)
983 if fname[0:3] == '../':
985 ext_loc = fname.rfind('.')
987 return Task.Task.old_display(self)
988 ext = fname[ext_loc:]
990 ext_map = { '.idl' : 'Compiling IDL',
991 '.et' : 'Compiling ERRTABLE',
992 '.asn1': 'Compiling ASN1',
995 return progress_display(self, ext_map[ext], fname)
996 return Task.Task.old_display(self)
998 Task.TaskBase.classes['Task'].old_display = Task.TaskBase.classes['Task'].display
999 Task.TaskBase.classes['Task'].display = samba_display
1002 @after('apply_link')
1004 def apply_bundle_remove_dynamiclib_patch(self):
1005 if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False):
1006 if not getattr(self,'vnum',None):
1008 self.env['LINKFLAGS'].remove('-dynamiclib')
1009 self.env['LINKFLAGS'].remove('-single_module')