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
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
32 # some systems have broken threading in python
33 if os
.environ
.get('WAF_NOTHREADS') == '1':
38 os
.putenv('PYTHONUNBUFFERED', '1')
41 if Constants
.HEXVERSION
< 0x105019:
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
47 Alternatively, please use ./autogen-waf.sh, and then
48 run ./configure and make as usual. That will call the right version of waf.
54 def SAMBA_BUILD_ENV(conf
):
55 '''create the samba build environment'''
56 conf
.env
.BUILD_DIRECTORY
= conf
.blddir
57 mkdir_p(os
.path
.join(conf
.blddir
, LIB_PATH
))
58 mkdir_p(os
.path
.join(conf
.blddir
, "modules"))
59 mkdir_p(os
.path
.join(conf
.blddir
, '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
.blddir
, 'default'))
63 for p
in ['python','shared', 'modules']:
64 link_target
= os
.path
.join(conf
.blddir
, 'default/' + p
)
65 if not os
.path
.lexists(link_target
):
66 os
.symlink('../' + p
, link_target
)
68 # get perl to put the blib files in the build directory
69 blib_bld
= os
.path
.join(conf
.blddir
, 'default/pidl/blib')
70 blib_src
= os
.path
.join(conf
.srcdir
, 'pidl/blib')
71 mkdir_p(blib_bld
+ '/man1')
72 mkdir_p(blib_bld
+ '/man3')
73 if os
.path
.islink(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:
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
:
87 cache
[subsystem
].append( { 'TARGET':target
, 'INIT_FUNCTION':init_function
} )
88 Build
.BuildContext
.ADD_INIT_FUNCTION
= ADD_INIT_FUNCTION
92 #################################################################
93 def SAMBA_LIBRARY(bld
, libname
, source
,
103 external_library
=False,
114 target_type
='LIBRARY',
115 bundled_extension
=True,
121 private_library
=False,
122 grouping_library
=False,
124 '''define a Samba library'''
127 SET_TARGET_TYPE(bld
, libname
, 'DISABLED')
130 source
= bld
.EXPAND_VARIABLES(source
, vars=vars)
132 # remember empty libraries, so we can strip the dependencies
133 if ((source
== '') or (source
== [])) and deps
== '' and public_deps
== '':
134 SET_TARGET_TYPE(bld
, libname
, 'EMPTY')
137 if BUILTIN_LIBRARY(bld
, libname
):
140 obj_target
= libname
+ '.objlist'
142 if group
== 'libraries':
143 subsystem_group
= 'main'
145 subsystem_group
= group
147 # first create a target for building the object files for this library
148 # by separating in this way, we avoid recompiling the C files
149 # separately for the install library and the build library
150 bld
.SAMBA_SUBSYSTEM(obj_target
,
153 public_deps
= public_deps
,
155 public_headers
= public_headers
,
156 header_path
= header_path
,
158 group
= subsystem_group
,
159 autoproto
= autoproto
,
160 depends_on
= depends_on
,
161 hide_symbols
= hide_symbols
,
162 pyext
= pyext
or (target_type
== "PYTHON"),
163 local_include
= local_include
)
165 if BUILTIN_LIBRARY(bld
, libname
):
168 if not SET_TARGET_TYPE(bld
, libname
, target_type
):
171 # the library itself will depend on that object target
172 deps
+= ' ' + public_deps
174 deps
.append(obj_target
)
176 realname
= bld
.map_shlib_extension(realname
, python
=(target_type
=='PYTHON'))
177 link_name
= bld
.map_shlib_extension(link_name
, python
=(target_type
=='PYTHON'))
179 # we don't want any public libraries without version numbers
180 if not private_library
and vnum
is None and soname
is None and target_type
!= 'PYTHON' and not realname
:
181 raise Utils
.WafError("public library '%s' must have a vnum" % libname
)
183 if target_type
== 'PYTHON' or realname
or not private_library
:
184 bundled_name
= libname
.replace('_', '-')
186 bundled_name
= PRIVATE_NAME(bld
, libname
, bundled_extension
, private_library
)
190 Logs
.error("vnum is invalid for private libraries")
192 vnum
= Utils
.g_module
.VERSION
194 features
= 'cc cshlib symlink_lib install_lib'
195 if target_type
== 'PYTHON':
198 # this is quite strange. we should add pyext feature for pyext
199 # but that breaks the build. This may be a bug in the waf python tool
200 features
+= ' pyembed'
202 features
+= ' abi_check'
205 abi_file
= os
.path
.join(bld
.curdir
, abi_file
)
207 bld
.SET_BUILD_GROUP(group
)
211 target
= bundled_name
,
212 depends_on
= depends_on
,
214 samba_includes
= includes
,
215 local_include
= local_include
,
219 samba_inst_path
= install_path
,
221 samba_realname
= realname
,
222 samba_install
= install
,
224 abi_match
= abi_match
,
225 private_library
= private_library
,
226 grouping_library
=grouping_library
229 if realname
and not link_name
:
230 link_name
= 'shared/%s' % realname
233 t
.link_name
= link_name
235 if pc_files
is not None:
236 bld
.PKG_CONFIG_FILES(pc_files
, vnum
=vnum
)
238 if manpages
is not None and 'XSLTPROC_MANPAGES' in bld
.env
and bld
.env
['XSLTPROC_MANPAGES']:
239 bld
.MANPAGES(manpages
)
242 Build
.BuildContext
.SAMBA_LIBRARY
= SAMBA_LIBRARY
245 #################################################################
246 def SAMBA_BINARY(bld
, binname
, source
,
256 use_global_deps
=True,
267 '''define a Samba binary'''
270 SET_TARGET_TYPE(bld
, binname
, 'DISABLED')
273 if not SET_TARGET_TYPE(bld
, binname
, 'BINARY'):
276 features
= 'cc cprogram symlink_bin install_bin'
278 features
+= ' pyembed'
280 obj_target
= binname
+ '.objlist'
282 source
= bld
.EXPAND_VARIABLES(source
, vars=vars)
283 source
= unique_list(TO_LIST(source
))
285 if group
== 'binaries':
286 subsystem_group
= 'main'
288 subsystem_group
= group
290 # first create a target for building the object files for this binary
291 # by separating in this way, we avoid recompiling the C files
292 # separately for the install binary and the build binary
293 bld
.SAMBA_SUBSYSTEM(obj_target
,
298 group
= subsystem_group
,
299 autoproto
= autoproto
,
300 subsystem_name
= subsystem_name
,
301 local_include
= local_include
,
302 use_hostcc
= use_hostcc
,
304 use_global_deps
= use_global_deps
)
306 bld
.SET_BUILD_GROUP(group
)
308 # the binary itself will depend on that object target
310 deps
.append(obj_target
)
317 samba_includes
= includes
,
318 local_include
= local_include
,
319 samba_modules
= modules
,
321 samba_subsystem
= subsystem_name
,
323 samba_inst_path
= install_path
,
324 samba_install
= install
327 if manpages
is not None and 'XSLTPROC_MANPAGES' in bld
.env
and bld
.env
['XSLTPROC_MANPAGES']:
328 bld
.MANPAGES(manpages
)
330 Build
.BuildContext
.SAMBA_BINARY
= SAMBA_BINARY
333 #################################################################
334 def SAMBA_MODULE(bld
, modname
, source
,
340 autoproto_extra_source
='',
343 internal_module
=True,
349 '''define a Samba module.'''
351 source
= bld
.EXPAND_VARIABLES(source
, vars=vars)
353 if internal_module
or BUILTIN_LIBRARY(bld
, modname
):
354 bld
.SAMBA_SUBSYSTEM(modname
, source
,
358 autoproto_extra_source
=autoproto_extra_source
,
360 local_include
=local_include
,
363 bld
.ADD_INIT_FUNCTION(subsystem
, modname
, init_function
)
367 SET_TARGET_TYPE(bld
, modname
, 'DISABLED')
370 if aliases
is not None:
371 # if we have aliases, then create a private base library, and a set
372 # of modules on top of that library
374 cflags
+= " -D%s=samba_init_module" % init_function
376 basename
= modname
+ '-base'
377 bld
.SAMBA_LIBRARY(basename
,
381 autoproto
= autoproto
,
382 local_include
=local_include
,
388 aliases
= TO_LIST(aliases
)
389 aliases
.append(modname
)
391 for alias
in aliases
:
392 bld
.SAMBA_MODULE(alias
,
394 internal_module
=False,
396 init_function
=init_function
,
401 obj_target
= modname
+ '.objlist'
404 if subsystem
is not None:
405 deps
+= ' ' + subsystem
406 while realname
.startswith("lib"+subsystem
+"_"):
407 realname
= realname
[len("lib"+subsystem
+"_"):]
408 while realname
.startswith(subsystem
+"_"):
409 realname
= realname
[len(subsystem
+"_"):]
411 realname
= bld
.make_libname(realname
)
412 while realname
.startswith("lib"):
413 realname
= realname
[len("lib"):]
415 build_link_name
= "modules/%s/%s" % (subsystem
, realname
)
418 cflags
+= " -D%s=samba_init_module" % init_function
420 bld
.SAMBA_LIBRARY(modname
,
425 autoproto
= autoproto
,
426 local_include
=local_include
,
428 link_name
=build_link_name
,
429 install_path
="${MODULESDIR}/%s" % subsystem
,
434 Build
.BuildContext
.SAMBA_MODULE
= SAMBA_MODULE
437 #################################################################
438 def SAMBA_SUBSYSTEM(bld
, modname
, source
,
447 init_function_sentinal
=None,
449 autoproto_extra_source
='',
452 local_include_first
=True,
456 use_global_deps
=True,
460 '''define a Samba subsystem'''
463 SET_TARGET_TYPE(bld
, modname
, 'DISABLED')
466 # remember empty subsystems, so we can strip the dependencies
467 if ((source
== '') or (source
== [])) and deps
== '' and public_deps
== '':
468 SET_TARGET_TYPE(bld
, modname
, 'EMPTY')
471 if not SET_TARGET_TYPE(bld
, modname
, 'SUBSYSTEM'):
474 source
= bld
.EXPAND_VARIABLES(source
, vars=vars)
475 source
= unique_list(TO_LIST(source
))
477 deps
+= ' ' + public_deps
479 bld
.SET_BUILD_GROUP(group
)
489 samba_cflags
= CURRENT_CFLAGS(bld
, modname
, cflags
, hide_symbols
=hide_symbols
),
490 depends_on
= depends_on
,
491 samba_deps
= TO_LIST(deps
),
492 samba_includes
= includes
,
493 local_include
= local_include
,
494 local_include_first
= local_include_first
,
495 samba_subsystem
= subsystem_name
,
496 samba_use_hostcc
= use_hostcc
,
497 samba_use_global_deps
= use_global_deps
500 if cflags_end
is not None:
501 t
.samba_cflags
.extend(TO_LIST(cflags_end
))
503 if autoproto
is not None:
504 bld
.SAMBA_AUTOPROTO(autoproto
, source
+ TO_LIST(autoproto_extra_source
))
505 if public_headers
is not None:
506 bld
.PUBLIC_HEADERS(public_headers
, header_path
=header_path
)
510 Build
.BuildContext
.SAMBA_SUBSYSTEM
= SAMBA_SUBSYSTEM
513 def SAMBA_GENERATOR(bld
, name
, rule
, source
='', target
='',
514 group
='generators', enabled
=True,
519 '''A generic source generator target'''
521 if not SET_TARGET_TYPE(bld
, name
, 'GENERATOR'):
527 bld
.SET_BUILD_GROUP(group
)
530 source
=bld
.EXPAND_VARIABLES(source
, vars=vars),
532 shell
=isinstance(rule
, str),
541 if public_headers
is not None:
542 bld
.PUBLIC_HEADERS(public_headers
, header_path
=header_path
)
544 Build
.BuildContext
.SAMBA_GENERATOR
= SAMBA_GENERATOR
549 def SETUP_BUILD_GROUPS(bld
):
550 '''setup build groups used to ensure that the different build
551 phases happen consecutively'''
552 bld
.p_ln
= bld
.srcnode
# we do want to see all targets!
553 bld
.env
['USING_BUILD_GROUPS'] = True
554 bld
.add_group('setup')
555 bld
.add_group('build_compiler_source')
556 bld
.add_group('base_libraries')
557 bld
.add_group('generators')
558 bld
.add_group('compiler_prototypes')
559 bld
.add_group('compiler_libraries')
560 bld
.add_group('build_compilers')
561 bld
.add_group('build_source')
562 bld
.add_group('prototypes')
563 bld
.add_group('main')
564 bld
.add_group('symbolcheck')
565 bld
.add_group('libraries')
566 bld
.add_group('binaries')
567 bld
.add_group('syslibcheck')
568 bld
.add_group('final')
569 Build
.BuildContext
.SETUP_BUILD_GROUPS
= SETUP_BUILD_GROUPS
572 def SET_BUILD_GROUP(bld
, group
):
573 '''set the current build group'''
574 if not 'USING_BUILD_GROUPS' in bld
.env
:
577 Build
.BuildContext
.SET_BUILD_GROUP
= SET_BUILD_GROUP
582 def ENABLE_TIMESTAMP_DEPENDENCIES(conf
):
583 """use timestamps instead of file contents for deps
584 this currently doesn't work"""
585 def h_file(filename
):
587 st
= os
.stat(filename
)
588 if stat
.S_ISDIR(st
[stat
.ST_MODE
]): raise IOError('not a file')
590 m
.update(str(st
.st_mtime
))
591 m
.update(str(st
.st_size
))
594 Utils
.h_file
= h_file
598 t
= Task
.simple_task_type('copy_script', 'rm -f ${LINK_TARGET} && ln -s ${SRC[0].abspath(env)} ${LINK_TARGET}',
599 shell
=True, color
='PINK', ext_in
='.bin')
602 @feature('copy_script')
603 @before('apply_link')
604 def copy_script(self
):
605 tsk
= self
.create_task('copy_script', self
.allnodes
[0])
606 tsk
.env
.TARGET
= self
.target
608 def SAMBA_SCRIPT(bld
, name
, pattern
, installdir
, installname
=None):
609 '''used to copy scripts from the source tree into the build directory
610 for use by selftest'''
612 source
= bld
.path
.ant_glob(pattern
)
614 bld
.SET_BUILD_GROUP('build_source')
615 for s
in TO_LIST(source
):
617 if installname
!= None:
619 target
= os
.path
.join(installdir
, iname
)
620 tgtdir
= os
.path
.dirname(os
.path
.join(bld
.srcnode
.abspath(bld
.env
), '..', target
))
622 t
= bld(features
='copy_script',
627 t
.env
.LINK_TARGET
= target
629 Build
.BuildContext
.SAMBA_SCRIPT
= SAMBA_SCRIPT
632 def install_file(bld
, destdir
, file, chmod
=MODE_644
, flat
=False,
633 python_fixup
=False, destname
=None, base_name
=None):
635 destdir
= bld
.EXPAND_VARIABLES(destdir
)
639 destname
= os
.path
.basename(destname
)
640 dest
= os
.path
.join(destdir
, destname
)
642 # fixup the python path it will use to find Samba modules
643 inst_file
= file + '.inst'
644 if bld
.env
["PYTHONDIR"] not in sys
.path
:
645 regex
= "s|\(sys.path.insert.*\)bin/python\(.*\)$|\\1${PYTHONDIR}\\2|g"
647 # Eliminate updating sys.path if the target python dir is already
649 regex
= "s|sys.path.insert.*bin/python.*$||g"
650 bld
.SAMBA_GENERATOR('python_%s' % destname
,
651 rule
="sed '%s' < ${SRC} > ${TGT}" % regex
,
656 file = os
.path
.join(base_name
, file)
657 bld
.install_as(dest
, file, chmod
=chmod
)
660 def INSTALL_FILES(bld
, destdir
, files
, chmod
=MODE_644
, flat
=False,
661 python_fixup
=False, destname
=None, base_name
=None):
662 '''install a set of files'''
663 for f
in TO_LIST(files
):
664 install_file(bld
, destdir
, f
, chmod
=chmod
, flat
=flat
,
665 python_fixup
=python_fixup
, destname
=destname
,
667 Build
.BuildContext
.INSTALL_FILES
= INSTALL_FILES
670 def INSTALL_WILDCARD(bld
, destdir
, pattern
, chmod
=MODE_644
, flat
=False,
671 python_fixup
=False, exclude
=None, trim_path
=None):
672 '''install a set of files matching a wildcard pattern'''
673 files
=TO_LIST(bld
.path
.ant_glob(pattern
))
677 files2
.append(os_path_relpath(f
, trim_path
))
682 if fnmatch
.fnmatch(f
, exclude
):
684 INSTALL_FILES(bld
, destdir
, files
, chmod
=chmod
, flat
=flat
,
685 python_fixup
=python_fixup
, base_name
=trim_path
)
686 Build
.BuildContext
.INSTALL_WILDCARD
= INSTALL_WILDCARD
689 def INSTALL_DIRS(bld
, destdir
, dirs
):
690 '''install a set of directories'''
691 destdir
= bld
.EXPAND_VARIABLES(destdir
)
692 dirs
= bld
.EXPAND_VARIABLES(dirs
)
693 for d
in TO_LIST(dirs
):
694 bld
.install_dir(os
.path
.join(destdir
, d
))
695 Build
.BuildContext
.INSTALL_DIRS
= INSTALL_DIRS
698 re_header
= re
.compile('#include[ \t]*"([^"]+)"', re
.I | re
.M
)
699 class header_task(Task
.Task
):
701 The public headers (the one installed on the system) have both
702 different paths and contents, so the rename is not enough.
704 Intermediate .inst.h files are created because path manipulation
705 may be slow. The substitution is thus performed only once.
710 vars = ['INCLUDEDIR', 'HEADER_DEPS']
713 txt
= self
.inputs
[0].read(self
.env
)
715 # hard-coded string, but only present in samba4 (I promise, you won't feel a thing)
716 txt
= txt
.replace('#if _SAMBA_BUILD_ == 4', '#if 1\n')
718 # use a regexp to substitute the #include lines in the files
719 map = self
.generator
.bld
.hnodemap
720 dirnodes
= self
.generator
.bld
.hnodedirs
725 # pokemon headers: gotta catch'em all!
727 if s
.startswith('bin/default'):
728 node
= self
.generator
.bld
.srcnode
.find_resource(s
.replace('bin/default/', ''))
730 Logs
.warn('could not find the public header for %r' % s
)
734 Logs
.warn('could not find the public header replacement for build header %r' % s
)
736 # this part is more difficult since the path may be relative to anything
737 for dirnode
in dirnodes
:
738 node
= dirnode
.find_resource(s
)
744 Logs
.warn('could not find the public header replacement for source header %r %r' % (s
, node
))
746 Logs
.warn('-> could not find the public header for %r' % s
)
748 return "#include <%s>" % fin
751 txt
= re_header
.sub(repl
, txt
)
753 # and write the output file
756 f
= open(self
.outputs
[0].abspath(self
.env
), 'w')
762 @TaskGen.feature('pubh')
763 def make_public_headers(self
):
765 collect the public headers to process and to install, then
766 create the substitutions (name and contents)
769 if not self
.bld
.is_install
:
770 # install time only (lazy)
774 # hnodedirs: list of folders for searching the headers
775 # hnodemap: node ids and replacement string (node objects are unique)
777 self
.bld
.hnodedirs
.append(self
.path
)
778 except AttributeError:
779 self
.bld
.hnodemap
= {}
780 self
.bld
.hnodedirs
= [self
.bld
.srcnode
, self
.path
]
782 for k
in 'source4 source4/include lib/talloc lib/tevent/ source4/lib/ldb/include/'.split():
783 node
= self
.bld
.srcnode
.find_dir(k
)
785 self
.bld
.hnodedirs
.append(node
)
787 header_path
= getattr(self
, 'header_path', None) or ''
789 for x
in self
.to_list(self
.headers
):
791 # too complicated, but what was the original idea?
792 if isinstance(header_path
, list):
794 for (p1
, dir) in header_path
:
795 lst
= self
.to_list(p1
)
797 if fnmatch
.fnmatch(x
, p2
):
805 inst_path
= header_path
809 if x
.find(':') != -1:
814 inn
= self
.path
.find_resource(name
)
817 raise ValueError("could not find the public header %r in %r" % (name
, self
.path
))
818 out
= inn
.change_ext('.inst.h')
819 self
.create_task('header', inn
, out
)
825 inst_path
= inst_path
+ '/'
826 inst_path
= inst_path
+ dest
828 self
.bld
.install_as('${INCLUDEDIR}/%s' % inst_path
, out
, self
.env
)
830 self
.bld
.hnodemap
[inn
.id] = inst_path
832 # create a hash (not md5) to make sure the headers are re-created if something changes
834 lst
= list(self
.bld
.hnodemap
.keys())
837 val
= hash((val
, k
, self
.bld
.hnodemap
[k
]))
838 self
.bld
.env
.HEADER_DEPS
= val
840 def PUBLIC_HEADERS(bld
, public_headers
, header_path
=None):
841 '''install some headers
843 header_path may either be a string that is added to the INCLUDEDIR,
844 or it can be a dictionary of wildcard patterns which map to destination
845 directories relative to INCLUDEDIR
847 bld
.SET_BUILD_GROUP('final')
848 ret
= bld(features
=['pubh'], headers
=public_headers
, header_path
=header_path
)
850 Build
.BuildContext
.PUBLIC_HEADERS
= PUBLIC_HEADERS
853 def subst_at_vars(task
):
854 '''substiture @VAR@ style variables in a file'''
855 src
= task
.inputs
[0].srcpath(task
.env
)
856 tgt
= task
.outputs
[0].bldpath(task
.env
)
862 a
= re
.split('(@\w+@)', s
)
865 back_sub
= [ ('PREFIX', '${prefix}'), ('EXEC_PREFIX', '${exec_prefix}')]
867 if re
.match('@\w+@', v
):
869 if not vname
in task
.env
and vname
.upper() in task
.env
:
870 vname
= vname
.upper()
871 if not vname
in task
.env
:
872 Logs
.error("Unknown substitution %s in %s" % (v
, task
.name
))
874 v
= SUBST_VARS_RECURSIVE(task
.env
[vname
], task
.env
)
875 # now we back substitute the allowed pc vars
876 for (b
, m
) in back_sub
:
879 if not b
in done_var
:
880 # we don't want to substitute the first usage
886 contents
= ''.join(out
)
888 s
= f
.write(contents
)
893 def PKG_CONFIG_FILES(bld
, pc_files
, vnum
=None):
894 '''install some pkg_config pc files'''
895 dest
= '${PKGCONFIGDIR}'
896 dest
= bld
.EXPAND_VARIABLES(dest
)
897 for f
in TO_LIST(pc_files
):
898 base
=os
.path
.basename(f
)
899 t
= bld
.SAMBA_GENERATOR('PKGCONFIG_%s' % base
,
904 t
.env
.PACKAGE_VERSION
= vnum
905 INSTALL_FILES(bld
, dest
, f
, flat
=True, destname
=base
)
906 Build
.BuildContext
.PKG_CONFIG_FILES
= PKG_CONFIG_FILES
909 def MANPAGES(bld
, manpages
):
910 '''build and install manual pages'''
911 bld
.env
.MAN_XSL
= 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
912 for m
in manpages
.split():
914 bld
.SAMBA_GENERATOR(m
,
918 rule
='${XSLTPROC} -o ${TGT} --nonet ${MAN_XSL} ${SRC}'
920 bld
.INSTALL_FILES('${MANDIR}/man%s' % m
[-1], m
, flat
=True)
921 Build
.BuildContext
.MANPAGES
= MANPAGES
924 #############################################################
925 # give a nicer display when building different types of files
926 def progress_display(self
, msg
, fname
):
927 col1
= Logs
.colors(self
.color
)
928 col2
= Logs
.colors
.NORMAL
929 total
= self
.position
[1]
931 fs
= '[%%%dd/%%%dd] %s %%s%%s%%s\n' % (n
, n
, msg
)
932 return fs
% (self
.position
[0], self
.position
[1], col1
, fname
, col2
)
934 def link_display(self
):
935 if Options
.options
.progress_bar
!= 0:
936 return Task
.Task
.old_display(self
)
937 fname
= self
.outputs
[0].bldpath(self
.env
)
938 return progress_display(self
, 'Linking', fname
)
939 Task
.TaskBase
.classes
['cc_link'].display
= link_display
941 def samba_display(self
):
942 if Options
.options
.progress_bar
!= 0:
943 return Task
.Task
.old_display(self
)
945 targets
= LOCAL_CACHE(self
, 'TARGET_TYPE')
946 if self
.name
in targets
:
947 target_type
= targets
[self
.name
]
948 type_map
= { 'GENERATOR' : 'Generating',
949 'PROTOTYPE' : 'Generating'
951 if target_type
in type_map
:
952 return progress_display(self
, type_map
[target_type
], self
.name
)
954 if len(self
.inputs
) == 0:
955 return Task
.Task
.old_display(self
)
957 fname
= self
.inputs
[0].bldpath(self
.env
)
958 if fname
[0:3] == '../':
960 ext_loc
= fname
.rfind('.')
962 return Task
.Task
.old_display(self
)
963 ext
= fname
[ext_loc
:]
965 ext_map
= { '.idl' : 'Compiling IDL',
966 '.et' : 'Compiling ERRTABLE',
967 '.asn1': 'Compiling ASN1',
970 return progress_display(self
, ext_map
[ext
], fname
)
971 return Task
.Task
.old_display(self
)
973 Task
.TaskBase
.classes
['Task'].old_display
= Task
.TaskBase
.classes
['Task'].display
974 Task
.TaskBase
.classes
['Task'].display
= samba_display
979 def apply_bundle_remove_dynamiclib_patch(self
):
980 if self
.env
['MACBUNDLE'] or getattr(self
,'mac_bundle',False):
981 if not getattr(self
,'vnum',None):
983 self
.env
['LINKFLAGS'].remove('-dynamiclib')
984 self
.env
['LINKFLAGS'].remove('-single_module')