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,
118 target_type='LIBRARY',
119 bundled_extension=True,
125 private_library=False,
126 grouping_library=False,
127 allow_undefined_symbols=False,
129 '''define a Samba library'''
132 SET_TARGET_TYPE(bld, libname, 'DISABLED')
135 source = bld.EXPAND_VARIABLES(source, vars=vars)
137 source = bld.SUBDIR(subdir, source)
139 # remember empty libraries, so we can strip the dependencies
140 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
141 SET_TARGET_TYPE(bld, libname, 'EMPTY')
144 if BUILTIN_LIBRARY(bld, libname):
147 obj_target = libname + '.objlist'
149 if group == 'libraries':
150 subsystem_group = 'main'
152 subsystem_group = group
154 # first create a target for building the object files for this library
155 # by separating in this way, we avoid recompiling the C files
156 # separately for the install library and the build library
157 bld.SAMBA_SUBSYSTEM(obj_target,
160 public_deps = public_deps,
162 public_headers = public_headers,
163 header_path = header_path,
165 group = subsystem_group,
166 autoproto = autoproto,
167 depends_on = depends_on,
168 hide_symbols = hide_symbols,
169 pyext = pyext or (target_type == "PYTHON"),
170 local_include = local_include)
172 if BUILTIN_LIBRARY(bld, libname):
175 if not SET_TARGET_TYPE(bld, libname, target_type):
178 # the library itself will depend on that object target
179 deps += ' ' + public_deps
181 deps.append(obj_target)
183 realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON'))
184 link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON'))
186 # we don't want any public libraries without version numbers
187 if not private_library and vnum is None and soname is None and target_type != 'PYTHON' and not realname:
188 raise Utils.WafError("public library '%s' must have a vnum" % libname)
190 if target_type == 'PYTHON' or realname or not private_library:
191 bundled_name = libname.replace('_', '-')
193 bundled_name = PRIVATE_NAME(bld, libname, bundled_extension, private_library)
195 ldflags = TO_LIST(ldflags)
197 features = 'cc cshlib symlink_lib install_lib'
198 if target_type == 'PYTHON':
201 # this is quite strange. we should add pyext feature for pyext
202 # but that breaks the build. This may be a bug in the waf python tool
203 features += ' pyembed'
206 features += ' abi_check'
209 if bld.env.HAVE_LD_VERSION_SCRIPT:
211 version = "%s_%s" % (Utils.g_module.APPNAME, Utils.g_module.VERSION)
213 version = "%s_%s" % (libname, vnum)
217 vscript = "%s.vscript" % libname
218 bld.ABI_VSCRIPT(libname, abi_directory, version, vscript,
220 fullname = apply_pattern(bundled_name, bld.env.shlib_PATTERN)
221 fullpath = bld.path.find_or_declare(fullname)
222 vscriptpath = bld.path.find_or_declare(vscript)
224 raise Utils.WafError("unable to find fullpath for %s" % fullname)
226 raise Utils.WafError("unable to find vscript path for %s" % vscript)
227 bld.add_manual_dependency(fullpath, vscriptpath)
228 if Options.is_install:
229 # also make the .inst file depend on the vscript
230 instname = apply_pattern(bundled_name + '.inst', bld.env.shlib_PATTERN)
231 bld.add_manual_dependency(bld.path.find_or_declare(instname), bld.path.find_or_declare(vscript))
232 vscript = os.path.join(bld.path.abspath(bld.env), vscript)
234 bld.SET_BUILD_GROUP(group)
238 target = bundled_name,
239 depends_on = depends_on,
240 samba_ldflags = ldflags,
242 samba_includes = includes,
243 version_script = vscript,
244 local_include = local_include,
248 samba_inst_path = install_path,
250 samba_realname = realname,
251 samba_install = install,
252 abi_directory = "%s/%s" % (bld.path.abspath(), abi_directory),
253 abi_match = abi_match,
254 private_library = private_library,
255 grouping_library=grouping_library,
256 allow_undefined_symbols=allow_undefined_symbols
259 if realname and not link_name:
260 link_name = 'shared/%s' % realname
263 t.link_name = link_name
265 if pc_files is not None:
266 bld.PKG_CONFIG_FILES(pc_files, vnum=vnum)
268 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
269 bld.MANPAGES(manpages)
272 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
275 #################################################################
276 def SAMBA_BINARY(bld, binname, source,
286 use_global_deps=True,
298 '''define a Samba binary'''
301 SET_TARGET_TYPE(bld, binname, 'DISABLED')
304 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
307 features = 'cc cprogram symlink_bin install_bin'
309 features += ' pyembed'
311 obj_target = binname + '.objlist'
313 source = bld.EXPAND_VARIABLES(source, vars=vars)
315 source = bld.SUBDIR(subdir, source)
316 source = unique_list(TO_LIST(source))
318 if group == 'binaries':
319 subsystem_group = 'main'
321 subsystem_group = group
323 # first create a target for building the object files for this binary
324 # by separating in this way, we avoid recompiling the C files
325 # separately for the install binary and the build binary
326 bld.SAMBA_SUBSYSTEM(obj_target,
331 group = subsystem_group,
332 autoproto = autoproto,
333 subsystem_name = subsystem_name,
334 local_include = local_include,
335 use_hostcc = use_hostcc,
337 use_global_deps= use_global_deps)
339 bld.SET_BUILD_GROUP(group)
341 # the binary itself will depend on that object target
343 deps.append(obj_target)
350 samba_includes = includes,
351 local_include = local_include,
352 samba_modules = modules,
354 samba_subsystem= subsystem_name,
356 samba_inst_path= install_path,
357 samba_install = install,
358 samba_ldflags = TO_LIST(ldflags)
361 if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
362 bld.MANPAGES(manpages)
364 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
367 #################################################################
368 def SAMBA_MODULE(bld, modname, source,
373 module_init_name='samba_init_module',
375 autoproto_extra_source='',
377 internal_module=True,
383 allow_undefined_symbols=False
385 '''define a Samba module.'''
387 source = bld.EXPAND_VARIABLES(source, vars=vars)
389 source = bld.SUBDIR(subdir, source)
391 if internal_module or BUILTIN_LIBRARY(bld, modname):
392 bld.SAMBA_SUBSYSTEM(modname, source,
396 autoproto_extra_source=autoproto_extra_source,
398 local_include=local_include,
401 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
405 SET_TARGET_TYPE(bld, modname, 'DISABLED')
408 obj_target = modname + '.objlist'
411 if subsystem is not None:
412 deps += ' ' + subsystem
413 while realname.startswith("lib"+subsystem+"_"):
414 realname = realname[len("lib"+subsystem+"_"):]
415 while realname.startswith(subsystem+"_"):
416 realname = realname[len(subsystem+"_"):]
418 realname = bld.make_libname(realname)
419 while realname.startswith("lib"):
420 realname = realname[len("lib"):]
422 build_link_name = "modules/%s/%s" % (subsystem, realname)
425 cflags += " -D%s=%s" % (init_function, module_init_name)
427 bld.SAMBA_LIBRARY(modname,
433 autoproto = autoproto,
434 local_include=local_include,
436 link_name=build_link_name,
437 install_path="${MODULESDIR}/%s" % subsystem,
439 allow_undefined_symbols=allow_undefined_symbols
443 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
446 #################################################################
447 def SAMBA_SUBSYSTEM(bld, modname, source,
456 init_function_sentinal=None,
458 autoproto_extra_source='',
461 local_include_first=True,
465 use_global_deps=True,
470 '''define a Samba subsystem'''
473 SET_TARGET_TYPE(bld, modname, 'DISABLED')
476 # remember empty subsystems, so we can strip the dependencies
477 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
478 SET_TARGET_TYPE(bld, modname, 'EMPTY')
481 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
484 source = bld.EXPAND_VARIABLES(source, vars=vars)
486 source = bld.SUBDIR(subdir, source)
487 source = unique_list(TO_LIST(source))
489 deps += ' ' + public_deps
491 bld.SET_BUILD_GROUP(group)
501 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, hide_symbols=hide_symbols),
502 depends_on = depends_on,
503 samba_deps = TO_LIST(deps),
504 samba_includes = includes,
505 local_include = local_include,
506 local_include_first = local_include_first,
507 samba_subsystem= subsystem_name,
508 samba_use_hostcc = use_hostcc,
509 samba_use_global_deps = use_global_deps
512 if cflags_end is not None:
513 t.samba_cflags.extend(TO_LIST(cflags_end))
515 if autoproto is not None:
516 bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source))
517 if public_headers is not None:
518 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
522 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
525 def SAMBA_GENERATOR(bld, name, rule, source='', target='',
526 group='generators', enabled=True,
531 '''A generic source generator target'''
533 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
539 bld.SET_BUILD_GROUP(group)
542 source=bld.EXPAND_VARIABLES(source, vars=vars),
544 shell=isinstance(rule, str),
548 samba_type='GENERATOR',
549 dep_vars = [rule] + (vars or []),
555 if public_headers is not None:
556 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
558 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
563 def SETUP_BUILD_GROUPS(bld):
564 '''setup build groups used to ensure that the different build
565 phases happen consecutively'''
566 bld.p_ln = bld.srcnode # we do want to see all targets!
567 bld.env['USING_BUILD_GROUPS'] = True
568 bld.add_group('setup')
569 bld.add_group('build_compiler_source')
570 bld.add_group('vscripts')
571 bld.add_group('base_libraries')
572 bld.add_group('generators')
573 bld.add_group('compiler_prototypes')
574 bld.add_group('compiler_libraries')
575 bld.add_group('build_compilers')
576 bld.add_group('build_source')
577 bld.add_group('prototypes')
578 bld.add_group('main')
579 bld.add_group('symbolcheck')
580 bld.add_group('libraries')
581 bld.add_group('binaries')
582 bld.add_group('syslibcheck')
583 bld.add_group('final')
584 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
587 def SET_BUILD_GROUP(bld, group):
588 '''set the current build group'''
589 if not 'USING_BUILD_GROUPS' in bld.env:
592 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
597 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
598 """use timestamps instead of file contents for deps
599 this currently doesn't work"""
600 def h_file(filename):
602 st = os.stat(filename)
603 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
605 m.update(str(st.st_mtime))
606 m.update(str(st.st_size))
609 Utils.h_file = h_file
613 t = Task.simple_task_type('copy_script', 'rm -f "${LINK_TARGET}" && ln -s "${SRC[0].abspath(env)}" ${LINK_TARGET}',
614 shell=True, color='PINK', ext_in='.bin')
617 @feature('copy_script')
618 @before('apply_link')
619 def copy_script(self):
620 tsk = self.create_task('copy_script', self.allnodes[0])
621 tsk.env.TARGET = self.target
623 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
624 '''used to copy scripts from the source tree into the build directory
625 for use by selftest'''
627 source = bld.path.ant_glob(pattern)
629 bld.SET_BUILD_GROUP('build_source')
630 for s in TO_LIST(source):
632 if installname != None:
634 target = os.path.join(installdir, iname)
635 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
637 t = bld(features='copy_script',
642 t.env.LINK_TARGET = target
644 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT
646 def copy_and_fix_python_path(task):
647 pattern='sys.path.insert(0, "bin/python")'
648 if task.env["PYTHONARCHDIR"] in sys.path and task.env["PYTHONDIR"] in sys.path:
650 elif task.env["PYTHONARCHDIR"] == task.env["PYTHONDIR"]:
651 replacement="""sys.path.insert(0, "%s")""" % task.env["PYTHONDIR"]
653 replacement="""sys.path.insert(0, "%s")
654 sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"])
656 installed_location=task.outputs[0].bldpath(task.env)
657 source_file = open(task.inputs[0].srcpath(task.env))
658 installed_file = open(installed_location, 'w')
659 for line in source_file:
662 newline = line.replace(pattern, replacement)
663 installed_file.write(newline)
664 installed_file.close()
665 os.chmod(installed_location, 0755)
669 def install_file(bld, destdir, file, chmod=MODE_644, flat=False,
670 python_fixup=False, destname=None, base_name=None):
672 destdir = bld.EXPAND_VARIABLES(destdir)
676 destname = os.path.basename(destname)
677 dest = os.path.join(destdir, destname)
679 # fixup the python path it will use to find Samba modules
680 inst_file = file + '.inst'
681 bld.SAMBA_GENERATOR('python_%s' % destname,
682 rule=copy_and_fix_python_path,
687 file = os.path.join(base_name, file)
688 bld.install_as(dest, file, chmod=chmod)
691 def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False,
692 python_fixup=False, destname=None, base_name=None):
693 '''install a set of files'''
694 for f in TO_LIST(files):
695 install_file(bld, destdir, f, chmod=chmod, flat=flat,
696 python_fixup=python_fixup, destname=destname,
698 Build.BuildContext.INSTALL_FILES = INSTALL_FILES
701 def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False,
702 python_fixup=False, exclude=None, trim_path=None):
703 '''install a set of files matching a wildcard pattern'''
704 files=TO_LIST(bld.path.ant_glob(pattern))
708 files2.append(os_path_relpath(f, trim_path))
713 if fnmatch.fnmatch(f, exclude):
715 INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat,
716 python_fixup=python_fixup, base_name=trim_path)
717 Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
720 def INSTALL_DIRS(bld, destdir, dirs):
721 '''install a set of directories'''
722 destdir = bld.EXPAND_VARIABLES(destdir)
723 dirs = bld.EXPAND_VARIABLES(dirs)
724 for d in TO_LIST(dirs):
725 bld.install_dir(os.path.join(destdir, d))
726 Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS
729 def header_install_path(header, header_path):
730 '''find the installation path for a header, given a header_path option'''
733 if not isinstance(header_path, list):
735 for (p1, dir) in header_path:
736 for p2 in TO_LIST(p1):
737 if fnmatch.fnmatch(header, p2):
739 # default to current path
743 re_header = re.compile('#include[ \t]*"([^"]+)"', re.I | re.M)
744 class header_task(Task.Task):
746 The public headers (the one installed on the system) have both
747 different paths and contents, so the rename is not enough.
749 Intermediate .inst.h files are created because path manipulation
750 may be slow. The substitution is thus performed only once.
755 vars = ['INCLUDEDIR', 'HEADER_DEPS']
758 txt = self.inputs[0].read(self.env)
760 # hard-coded string, but only present in samba4 (I promise, you won't feel a thing)
761 txt = txt.replace('#if _SAMBA_BUILD_ == 4', '#if 1\n')
763 # use a regexp to substitute the #include lines in the files
764 map = self.generator.bld.hnodemap
765 dirnodes = self.generator.bld.hnodedirs
770 # pokemon headers: gotta catch'em all!
772 if s.startswith('bin/default'):
773 node = self.generator.bld.srcnode.find_resource(s.replace('bin/default/', ''))
775 Logs.warn('could not find the public header for %r' % s)
779 Logs.warn('could not find the public header replacement for build header %r' % s)
781 # this part is more difficult since the path may be relative to anything
782 for dirnode in dirnodes:
783 node = dirnode.find_resource(s)
789 Logs.warn('could not find the public header replacement for source header %r %r' % (s, node))
791 Logs.warn('-> could not find the public header for %r' % s)
793 return "#include <%s>" % fin
796 txt = re_header.sub(repl, txt)
798 # and write the output file
801 f = open(self.outputs[0].abspath(self.env), 'w')
807 @TaskGen.feature('pubh')
808 def make_public_headers(self):
810 collect the public headers to process and to install, then
811 create the substitutions (name and contents)
814 if not self.bld.is_install:
815 # install time only (lazy)
819 # hnodedirs: list of folders for searching the headers
820 # hnodemap: node ids and replacement string (node objects are unique)
822 self.bld.hnodedirs.append(self.path)
823 except AttributeError:
824 self.bld.hnodemap = {}
825 self.bld.hnodedirs = [self.bld.srcnode, self.path]
827 for k in 'source4 source4/include lib/talloc lib/tevent/ source4/lib/ldb/include/'.split():
828 node = self.bld.srcnode.find_dir(k)
830 self.bld.hnodedirs.append(node)
832 header_path = getattr(self, 'header_path', None) or ''
834 for x in self.to_list(self.headers):
836 inst_path = header_install_path(x, header_path)
840 if x.find(':') != -1:
845 inn = self.path.find_resource(name)
848 raise ValueError("could not find the public header %r in %r" % (name, self.path))
849 out = inn.change_ext('.inst.h')
850 self.create_task('header', inn, out)
856 inst_path = inst_path + '/'
857 inst_path = inst_path + dest
859 self.bld.install_as('${INCLUDEDIR}/%s' % inst_path, out, self.env)
861 self.bld.hnodemap[inn.id] = inst_path
863 # create a hash (not md5) to make sure the headers are re-created if something changes
865 lst = list(self.bld.hnodemap.keys())
868 val = hash((val, k, self.bld.hnodemap[k]))
869 self.bld.env.HEADER_DEPS = val
873 def symlink_header(task):
874 '''symlink a header in the build tree'''
875 src = task.inputs[0].abspath(task.env)
876 tgt = task.outputs[0].bldpath(task.env)
878 if os.path.lexists(tgt):
879 if os.path.islink(tgt) and os.readlink(tgt) == src:
885 def PUBLIC_HEADERS(bld, public_headers, header_path=None):
886 '''install some headers
888 header_path may either be a string that is added to the INCLUDEDIR,
889 or it can be a dictionary of wildcard patterns which map to destination
890 directories relative to INCLUDEDIR
892 bld.SET_BUILD_GROUP('final')
893 ret = bld(features=['pubh'], headers=public_headers, header_path=header_path)
895 if bld.env.build_public_headers:
896 # when build_public_headers is set, symlink the headers into the include/public
898 for h in TO_LIST(public_headers):
899 inst_path = header_install_path(h, header_path)
900 if h.find(':') != -1:
906 inst_name = os.path.basename(h)
907 relpath1 = os_path_relpath(bld.srcnode.abspath(), bld.curdir)
908 relpath2 = os_path_relpath(bld.curdir, bld.srcnode.abspath())
909 targetdir = os.path.normpath(os.path.join(relpath1, bld.env.build_public_headers, inst_path))
910 if not os.path.exists(os.path.join(bld.curdir, targetdir)):
911 raise Utils.WafError("missing source directory %s for public header %s" % (targetdir, inst_name))
912 target = os.path.join(targetdir, inst_name)
913 bld.SAMBA_GENERATOR('HEADER_%s/%s' % (relpath2, inst_name),
920 Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS
923 def MANPAGES(bld, manpages):
924 '''build and install manual pages'''
925 bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
926 for m in manpages.split():
928 bld.SAMBA_GENERATOR(m,
932 rule='${XSLTPROC} -o ${TGT} --nonet ${MAN_XSL} ${SRC}'
934 bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True)
935 Build.BuildContext.MANPAGES = MANPAGES
938 #############################################################
939 # give a nicer display when building different types of files
940 def progress_display(self, msg, fname):
941 col1 = Logs.colors(self.color)
942 col2 = Logs.colors.NORMAL
943 total = self.position[1]
945 fs = '[%%%dd/%%%dd] %s %%s%%s%%s\n' % (n, n, msg)
946 return fs % (self.position[0], self.position[1], col1, fname, col2)
948 def link_display(self):
949 if Options.options.progress_bar != 0:
950 return Task.Task.old_display(self)
951 fname = self.outputs[0].bldpath(self.env)
952 return progress_display(self, 'Linking', fname)
953 Task.TaskBase.classes['cc_link'].display = link_display
955 def samba_display(self):
956 if Options.options.progress_bar != 0:
957 return Task.Task.old_display(self)
959 targets = LOCAL_CACHE(self, 'TARGET_TYPE')
960 if self.name in targets:
961 target_type = targets[self.name]
962 type_map = { 'GENERATOR' : 'Generating',
963 'PROTOTYPE' : 'Generating'
965 if target_type in type_map:
966 return progress_display(self, type_map[target_type], self.name)
968 if len(self.inputs) == 0:
969 return Task.Task.old_display(self)
971 fname = self.inputs[0].bldpath(self.env)
972 if fname[0:3] == '../':
974 ext_loc = fname.rfind('.')
976 return Task.Task.old_display(self)
977 ext = fname[ext_loc:]
979 ext_map = { '.idl' : 'Compiling IDL',
980 '.et' : 'Compiling ERRTABLE',
981 '.asn1': 'Compiling ASN1',
984 return progress_display(self, ext_map[ext], fname)
985 return Task.Task.old_display(self)
987 Task.TaskBase.classes['Task'].old_display = Task.TaskBase.classes['Task'].display
988 Task.TaskBase.classes['Task'].display = samba_display
993 def apply_bundle_remove_dynamiclib_patch(self):
994 if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False):
995 if not getattr(self,'vnum',None):
997 self.env['LINKFLAGS'].remove('-dynamiclib')
998 self.env['LINKFLAGS'].remove('-single_module')