291d8acb4b271f767590c48695466dba7f08e5f5
[nivanova/samba-autobuild/.git] / buildtools / wafsamba / wafsamba.py
1 # a waf tool to add autoconf-like macros to the configure section
2 # and for SAMBA_ macros for building libraries, binaries etc
3
4 import Build, os, Options, Task, Utils, cc, TaskGen, fnmatch, re, shutil
5 from Configure import conf
6 from Logs import debug
7 from samba_utils import SUBST_VARS_RECURSIVE
8
9 # bring in the other samba modules
10 from samba_optimisation import *
11 from samba_utils import *
12 from samba_autoconf import *
13 from samba_patterns import *
14 from samba_pidl import *
15 from samba_errtable import *
16 from samba_asn1 import *
17 from samba_autoproto import *
18 from samba_python import *
19 from samba_deps import *
20 from samba_bundled import *
21 import samba_conftests
22
23 LIB_PATH="shared"
24
25 os.putenv('PYTHONUNBUFFERED', '1')
26
27 @conf
28 def SAMBA_BUILD_ENV(conf):
29     '''create the samba build environment'''
30     conf.env['BUILD_DIRECTORY'] = conf.blddir
31     mkdir_p(os.path.join(conf.blddir, LIB_PATH))
32     mkdir_p(os.path.join(conf.blddir, 'python/samba/dcerpc'))
33     # this allows all of the bin/shared and bin/python targets
34     # to be expressed in terms of build directory paths
35     for p in ['python','shared']:
36         link_target = os.path.join(conf.blddir, 'default/' + p)
37         if not os.path.lexists(link_target):
38             os.symlink('../' + p, link_target)
39
40     # get perl to put the blib files in the build directory
41     blib_bld = os.path.join(conf.blddir, 'default/pidl/blib')
42     blib_src = os.path.join(conf.srcdir, 'pidl/blib')
43     mkdir_p(blib_bld + '/man1')
44     mkdir_p(blib_bld + '/man3')
45     if os.path.islink(blib_src):
46         os.unlink(blib_src)
47     else:
48         shutil.rmtree(blib_src)
49     os.symlink(blib_bld, blib_src)
50
51
52
53 def ADD_INIT_FUNCTION(bld, subsystem, target, init_function):
54     '''add an init_function to the list for a subsystem'''
55     if init_function is None:
56         return
57     bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
58     cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
59     if not subsystem in cache:
60         cache[subsystem] = []
61     cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } )
62 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
63
64
65
66 #################################################################
67 def SAMBA_LIBRARY(bld, libname, source,
68                   deps='',
69                   public_deps='',
70                   includes='',
71                   public_headers=None,
72                   header_path=None,
73                   pc_files=None,
74                   vnum=None,
75                   cflags='',
76                   external_library=False,
77                   realname=None,
78                   autoproto=None,
79                   group='main',
80                   depends_on='',
81                   local_include=True,
82                   vars=None,
83                   install_path=None,
84                   install=True,
85                   needs_python=False,
86                   target_type='LIBRARY',
87                   bundled_extension=True,
88                   link_name=None,
89                   enabled=True):
90     '''define a Samba library'''
91
92     if not enabled:
93         SET_TARGET_TYPE(bld, libname, 'DISABLED')
94         return
95
96     source = bld.EXPAND_VARIABLES(source, vars=vars)
97
98     # remember empty libraries, so we can strip the dependencies
99     if (source == '') or (source == []):
100         SET_TARGET_TYPE(bld, libname, 'EMPTY')
101         return
102
103     if BUILTIN_LIBRARY(bld, libname):
104         obj_target = libname
105     else:
106         obj_target = libname + '.objlist'
107
108     # first create a target for building the object files for this library
109     # by separating in this way, we avoid recompiling the C files
110     # separately for the install library and the build library
111     bld.SAMBA_SUBSYSTEM(obj_target,
112                         source         = source,
113                         deps           = deps,
114                         public_deps    = public_deps,
115                         includes       = includes,
116                         public_headers = public_headers,
117                         header_path    = header_path,
118                         cflags         = cflags,
119                         group          = group,
120                         autoproto      = autoproto,
121                         depends_on     = depends_on,
122                         needs_python   = needs_python,
123                         local_include  = local_include)
124
125     if BUILTIN_LIBRARY(bld, libname):
126         return
127
128     if not SET_TARGET_TYPE(bld, libname, target_type):
129         return
130
131     # the library itself will depend on that object target
132     deps += ' ' + public_deps
133     deps = TO_LIST(deps)
134     deps.append(obj_target)
135
136     if needs_python:
137         bundled_name = libname
138     else:
139         bundled_name = BUNDLED_NAME(bld, libname, bundled_extension)
140
141     features = 'cc cshlib'
142     if needs_python:
143         features += ' pyext'
144
145     bld.SET_BUILD_GROUP(group)
146     t = bld(
147         features        = features + ' symlink_lib',
148         source          = [],
149         target          = bundled_name,
150         samba_cflags    = CURRENT_CFLAGS(bld, libname, cflags),
151         depends_on      = depends_on,
152         samba_deps      = deps,
153         samba_includes  = includes,
154         local_include   = local_include,
155         vnum            = vnum,
156         install_path    = None,
157         ldflags         = build_rpath(bld),
158         name            = libname
159         )
160
161     if link_name:
162         t.link_name = link_name
163
164     if install_path is None:
165         install_path = '${LIBDIR}'
166     install_path = SUBST_VARS_RECURSIVE(install_path, bld.env)
167
168     # we don't need the double libraries if rpath is off
169     if (bld.env.RPATH_ON_INSTALL == False and
170         bld.env.RPATH_ON_BUILD == False):
171         install_target = bundled_name
172     else:
173         install_target = bundled_name + '.inst'
174
175     if install and install_target != bundled_name:
176         # create a separate install library, which may have
177         # different rpath settings
178         SET_TARGET_TYPE(bld, install_target, target_type)
179         t = bld(
180             features        = features,
181             source          = [],
182             target          = install_target,
183             samba_cflags    = CURRENT_CFLAGS(bld, libname, cflags),
184             depends_on      = depends_on,
185             samba_deps      = deps,
186             samba_includes  = includes,
187             local_include   = local_include,
188             vnum            = vnum,
189             install_as      = bundled_name,
190             install_path    = None,
191             ldflags         = install_rpath(bld)
192             )
193
194     if install:
195         if realname:
196             install_name = realname
197             install_link = None
198             inst_name    = libname + '.inst.so'
199         elif vnum:
200             vnum_base = vnum.split('.')[0]
201             install_name = 'lib%s.so.%s' % (bundled_name, vnum)
202             install_link = 'lib%s.so.%s' % (bundled_name, vnum_base)
203             inst_name    = 'lib%s.inst.so' % bundled_name
204         else:
205             install_name = 'lib%s.so' % bundled_name
206             install_link = None
207             inst_name    = 'lib%s.inst.so' % bundled_name
208
209         bld.install_as(os.path.join(install_path, install_name), inst_name)
210         if install_link:
211             bld.symlink_as(os.path.join(install_path, install_link), install_name)
212
213     if autoproto is not None:
214         bld.SAMBA_AUTOPROTO(autoproto, source)
215
216     if public_headers is not None:
217         bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
218
219     if pc_files is not None:
220         bld.PKG_CONFIG_FILES(pc_files)
221
222 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
223
224
225 #################################################################
226 def SAMBA_BINARY(bld, binname, source,
227                  deps='',
228                  includes='',
229                  public_headers=None,
230                  header_path=None,
231                  modules=None,
232                  installdir=None,
233                  ldflags=None,
234                  cflags='',
235                  autoproto=None,
236                  use_hostcc=None,
237                  compiler=None,
238                  group='binaries',
239                  manpages=None,
240                  local_include=True,
241                  subsystem_name=None,
242                  needs_python=False,
243                  vars=None,
244                  install=True,
245                  install_path=None):
246     '''define a Samba binary'''
247
248     if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
249         return
250
251     features = 'cc cprogram'
252     if needs_python:
253         features += ' pyembed'
254
255     bld.SET_BUILD_GROUP(group)
256
257     obj_target = binname + '.objlist'
258
259     source = bld.EXPAND_VARIABLES(source, vars=vars)
260
261     # first create a target for building the object files for this binary
262     # by separating in this way, we avoid recompiling the C files
263     # separately for the install binary and the build binary
264     bld.SAMBA_SUBSYSTEM(obj_target,
265                         source         = source,
266                         deps           = deps,
267                         includes       = includes,
268                         cflags         = cflags,
269                         group          = group,
270                         autoproto      = autoproto,
271                         subsystem_name = subsystem_name,
272                         needs_python   = needs_python,
273                         local_include  = local_include)
274
275     # the library itself will depend on that object target
276     deps = TO_LIST(deps)
277     deps.append(obj_target)
278
279     bld(
280         features       = features + ' symlink_bin',
281         source         = [],
282         target         = binname,
283         samba_cflags   = CURRENT_CFLAGS(bld, binname, cflags),
284         samba_deps     = deps,
285         samba_includes = includes,
286         local_include  = local_include,
287         samba_modules  = modules,
288         top            = True,
289         samba_subsystem= subsystem_name,
290         install_path   = None,
291         ldflags        = build_rpath(bld)
292         )
293
294     if install_path is None:
295         install_path = '${BINDIR}'
296     install_path = SUBST_VARS_RECURSIVE(install_path, bld.env)
297
298     # we don't need the double binaries if rpath is off
299     if (bld.env.RPATH_ON_INSTALL == False and
300         bld.env.RPATH_ON_BUILD == False):
301         install_target = binname
302     else:
303         install_target = binname + '.inst'
304
305     if install and install_target != binname:
306         # we create a separate 'install' binary, which
307         # will have different rpath settings
308         SET_TARGET_TYPE(bld, install_target, 'BINARY')
309         t = bld(
310             features       = features,
311             source         = [],
312             target         = install_target,
313             samba_cflags   = CURRENT_CFLAGS(bld, binname, cflags),
314             samba_deps     = deps,
315             samba_includes = includes,
316             local_include  = local_include,
317             samba_modules  = modules,
318             top            = True,
319             samba_subsystem= subsystem_name,
320             install_path   = None,
321             ldflags        = install_rpath(bld)
322             )
323
324     if install:
325         bld.install_as(os.path.join(install_path, binname),
326                        install_target,
327                        chmod=0755)
328
329     # setup the subsystem_name as an alias for the real
330     # binary name, so it can be found when expanding
331     # subsystem dependencies
332     if subsystem_name is not None:
333         bld.TARGET_ALIAS(subsystem_name, binname)
334
335     if autoproto is not None:
336         bld.SAMBA_AUTOPROTO(autoproto, source)
337     if public_headers is not None:
338         bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
339 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
340
341
342 #################################################################
343 def SAMBA_MODULE(bld, modname, source,
344                  deps='',
345                  includes='',
346                  subsystem=None,
347                  init_function=None,
348                  autoproto=None,
349                  autoproto_extra_source='',
350                  aliases=None,
351                  cflags='',
352                  internal_module=True,
353                  local_include=True,
354                  vars=None,
355                  enabled=True):
356     '''define a Samba module.'''
357
358     # we add the init function regardless of whether the module
359     # is enabled or not, as we need to generate a null list if
360     # all disabled
361     bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
362
363     if internal_module or BUILTIN_LIBRARY(bld, modname):
364         # treat internal modules as subsystems for now
365         SAMBA_SUBSYSTEM(bld, modname, source,
366                         deps=deps,
367                         includes=includes,
368                         autoproto=autoproto,
369                         autoproto_extra_source=autoproto_extra_source,
370                         cflags=cflags,
371                         local_include=local_include,
372                         enabled=enabled)
373         return
374
375     if not enabled:
376         SET_TARGET_TYPE(bld, modname, 'DISABLED')
377         return
378
379     source = bld.EXPAND_VARIABLES(source, vars=vars)
380
381     # remember empty modules, so we can strip the dependencies
382     if (source == '') or (source == []):
383         SET_TARGET_TYPE(bld, modname, 'EMPTY')
384         return
385
386     if not SET_TARGET_TYPE(bld, modname, 'MODULE'):
387         return
388
389     if subsystem is not None:
390         deps += ' ' + subsystem
391
392     bld.SET_BUILD_GROUP('main')
393     bld(
394         features       = 'cc',
395         source         = source,
396         target         = modname,
397         samba_cflags   = CURRENT_CFLAGS(bld, modname, cflags),
398         samba_includes = includes,
399         local_include  = local_include,
400         samba_deps     = TO_LIST(deps)
401         )
402
403     if autoproto is not None:
404         bld.SAMBA_AUTOPROTO(autoproto, source + ' ' + autoproto_extra_source)
405
406 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
407
408
409 #################################################################
410 def SAMBA_SUBSYSTEM(bld, modname, source,
411                     deps='',
412                     public_deps='',
413                     includes='',
414                     public_headers=None,
415                     header_path=None,
416                     cflags='',
417                     cflags_end=None,
418                     group='main',
419                     init_function_sentinal=None,
420                     heimdal_autoproto=None,
421                     heimdal_autoproto_options=None,
422                     heimdal_autoproto_private=None,
423                     autoproto=None,
424                     autoproto_extra_source='',
425                     depends_on='',
426                     local_include=True,
427                     local_include_first=True,
428                     subsystem_name=None,
429                     enabled=True,
430                     vars=None,
431                     needs_python=False):
432     '''define a Samba subsystem'''
433
434     if not enabled:
435         SET_TARGET_TYPE(bld, modname, 'DISABLED')
436         return
437
438     # remember empty subsystems, so we can strip the dependencies
439     if (source == '') or (source == []):
440         SET_TARGET_TYPE(bld, modname, 'EMPTY')
441         return
442
443     if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
444         return
445
446     source = bld.EXPAND_VARIABLES(source, vars=vars)
447
448     deps += ' ' + public_deps
449
450     bld.SET_BUILD_GROUP(group)
451
452     features = 'cc'
453     if needs_python:
454         features += ' pyext'
455
456     t = bld(
457         features       = features,
458         source         = source,
459         target         = modname,
460         samba_cflags   = CURRENT_CFLAGS(bld, modname, cflags),
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         )
468
469     if cflags_end is not None:
470         t.samba_cflags.extend(TO_LIST(cflags_end))
471
472     if heimdal_autoproto is not None:
473         bld.HEIMDAL_AUTOPROTO(heimdal_autoproto, source, options=heimdal_autoproto_options)
474     if heimdal_autoproto_private is not None:
475         bld.HEIMDAL_AUTOPROTO_PRIVATE(heimdal_autoproto_private, source)
476     if autoproto is not None:
477         bld.SAMBA_AUTOPROTO(autoproto, source + ' ' + autoproto_extra_source)
478     if public_headers is not None:
479         bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
480     return t
481
482
483 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
484
485
486 def SAMBA_GENERATOR(bld, name, rule, source, target,
487                     group='build_source', enabled=True,
488                     public_headers=None,
489                     header_path=None,
490                     vars=None):
491     '''A generic source generator target'''
492
493     if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
494         return
495
496     if not enabled:
497         return
498
499     bld.SET_BUILD_GROUP(group)
500     t = bld(
501         rule=rule,
502         source=bld.EXPAND_VARIABLES(source, vars=vars),
503         target=target,
504         shell=isinstance(rule, str),
505         on_results=True,
506         before='cc',
507         ext_out='.c',
508         name=name)
509
510     if public_headers is not None:
511         bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
512     return t
513 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
514
515
516
517 def BUILD_SUBDIR(bld, dir):
518     '''add a new set of build rules from a subdirectory'''
519     path = os.path.normpath(bld.curdir + '/' + dir)
520     cache = LOCAL_CACHE(bld, 'SUBDIR_LIST')
521     if path in cache: return
522     cache[path] = True
523     debug("build: Processing subdirectory %s" % dir)
524     bld.add_subdirs(dir)
525 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
526
527
528
529 @runonce
530 def SETUP_BUILD_GROUPS(bld):
531     '''setup build groups used to ensure that the different build
532     phases happen consecutively'''
533     bld.p_ln = bld.srcnode # we do want to see all targets!
534     bld.env['USING_BUILD_GROUPS'] = True
535     bld.add_group('setup')
536     bld.add_group('build_compiler_source')
537     bld.add_group('base_libraries')
538     bld.add_group('build_compilers')
539     bld.add_group('build_source')
540     bld.add_group('prototypes')
541     bld.add_group('main')
542     bld.add_group('binaries')
543     bld.add_group('final')
544 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
545
546
547 def SET_BUILD_GROUP(bld, group):
548     '''set the current build group'''
549     if not 'USING_BUILD_GROUPS' in bld.env:
550         return
551     bld.set_group(group)
552 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
553
554
555
556 @conf
557 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
558     """use timestamps instead of file contents for deps
559     this currently doesn't work"""
560     def h_file(filename):
561         import stat
562         st = os.stat(filename)
563         if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
564         m = Utils.md5()
565         m.update(str(st.st_mtime))
566         m.update(str(st.st_size))
567         m.update(filename)
568         return m.digest()
569     Utils.h_file = h_file
570
571
572
573 ##############################
574 # handle the creation of links for libraries and binaries
575 # note that we use a relative symlink path to allow the whole tree
576 # to me moved/copied elsewhere without breaking the links
577 t = Task.simple_task_type('symlink_lib', 'rm -f ${LINK_TARGET} && ln -s ${LINK_SOURCE} ${LINK_TARGET}',
578                           shell=True, color='PINK', ext_in='.bin')
579 t.quiet = True
580
581 @feature('symlink_lib')
582 @after('apply_link')
583 def symlink_lib(self):
584     '''symlink a shared lib'''
585     tsk = self.create_task('symlink_lib', self.link_task.outputs[0])
586
587     # calculat the link target and put it in the environment
588     soext=""
589     vnum = getattr(self, 'vnum', None)
590     if vnum is not None:
591         soext = '.' + vnum.split('.')[0]
592
593     link_target = getattr(self, 'link_name', '')
594     if link_target == '':
595         link_target = '%s/lib%s.so%s' % (LIB_PATH, self.target, soext)
596
597
598     link_source = os_path_relpath(self.link_task.outputs[0].abspath(self.env),
599                                   os.path.join(self.env.BUILD_DIRECTORY, link_target))
600
601     tsk.env.LINK_TARGET = link_target
602     tsk.env.LINK_SOURCE = link_source[3:]
603     debug('task_gen: LINK for %s is %s -> %s',
604           self.name, tsk.env.LINK_SOURCE, tsk.env.LINK_TARGET)
605
606
607 t = Task.simple_task_type('symlink_bin', 'rm -f ${BIN_TARGET} && ln -s ${SRC} ${BIN_TARGET}',
608                           shell=True, color='PINK', ext_in='.bin')
609 t.quiet = True
610
611 @feature('symlink_bin')
612 @after('apply_link')
613 def symlink_bin(self):
614     '''symlink a binary'''
615     if Options.is_install:
616         # we don't want to copy the install binary, as
617         # that has the install rpath, not the build rpath
618         # The rpath of the binaries in bin/default/foo/blah is different
619         # during the install phase, as distros insist on not using rpath in installed binaries
620         return
621     tsk = self.create_task('symlink_bin', self.link_task.outputs[0])
622
623     tsk.env.BIN_TARGET = self.target
624     debug('task_gen: BIN_TARGET for %s is %s', self.name, tsk.env.BIN_TARGET)
625
626
627
628
629 t = Task.simple_task_type('copy_script', 'rm -f ${LINK_TARGET} && ln -s ${SRC[0].abspath(env)} ${LINK_TARGET}',
630                           shell=True, color='PINK', ext_in='.bin')
631 t.quiet = True
632
633 @feature('copy_script')
634 @before('apply_link')
635 def copy_script(self):
636     tsk = self.create_task('copy_script', self.allnodes[0])
637     tsk.env.TARGET = self.target
638
639 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
640     '''used to copy scripts from the source tree into the build directory
641        for use by selftest'''
642
643     source = bld.path.ant_glob(pattern)
644
645     bld.SET_BUILD_GROUP('build_source')
646     for s in TO_LIST(source):
647         iname = s
648         if installname != None:
649             iname = installname
650         target = os.path.join(installdir, iname)
651         tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
652         mkdir_p(tgtdir)
653         t = bld(features='copy_script',
654                 source       = s,
655                 target       = target,
656                 always       = True,
657                 install_path = None)
658         t.env.LINK_TARGET = target
659
660 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT
661
662
663 def install_file(bld, destdir, file, chmod=0644, flat=False,
664                  python_fixup=False, destname=None):
665     '''install a file'''
666     destdir = bld.EXPAND_VARIABLES(destdir)
667     if not destname:
668         destname = file
669         if flat:
670             destname = os.path.basename(destname)
671     dest = os.path.join(destdir, destname)
672     if python_fixup:
673         # fixup the python path it will use to find Samba modules
674         inst_file = file + '.inst'
675         bld.SAMBA_GENERATOR('python_%s' % destname,
676                             rule="sed 's|\(sys.path.insert.*\)bin/python\(.*\)$|\\1${PYTHONDIR}\\2|g' < ${SRC} > ${TGT}",
677                             source=file,
678                             target=inst_file)
679         file = inst_file
680     bld.install_as(dest, file, chmod=chmod)
681
682
683 def INSTALL_FILES(bld, destdir, files, chmod=0644, flat=False,
684                   python_fixup=False, destname=None):
685     '''install a set of files'''
686     for f in TO_LIST(files):
687         install_file(bld, destdir, f, chmod=chmod, flat=flat,
688                      python_fixup=python_fixup, destname=destname)
689 Build.BuildContext.INSTALL_FILES = INSTALL_FILES
690
691
692 def INSTALL_WILDCARD(bld, destdir, pattern, chmod=0644, flat=False,
693                      python_fixup=False, exclude=None):
694     '''install a set of files matching a wildcard pattern'''
695     files=TO_LIST(bld.path.ant_glob(pattern))
696     if exclude:
697         for f in files[:]:
698             if fnmatch.fnmatch(f, exclude):
699                 files.remove(f)
700     INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat, python_fixup=python_fixup)
701 Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
702
703
704 def PUBLIC_HEADERS(bld, public_headers, header_path=None):
705     '''install some headers
706
707     header_path may either be a string that is added to the INCLUDEDIR,
708     or it can be a dictionary of wildcard patterns which map to destination
709     directories relative to INCLUDEDIR
710     '''
711     dest = '${INCLUDEDIR}'
712     if isinstance(header_path, str):
713         dest += '/' + header_path
714     for h in TO_LIST(public_headers):
715         hdest = dest
716         if isinstance(header_path, list):
717             for (p1, dir) in header_path:
718                 found_match=False
719                 lst = TO_LIST(p1)
720                 for p2 in lst:
721                     if fnmatch.fnmatch(h, p2):
722                         if dir:
723                             hdest = os.path.join(hdest, dir)
724                         found_match=True
725                         break
726                 if found_match: break
727         if h.find(':') != -1:
728             hs=h.split(':')
729             INSTALL_FILES(bld, hdest, hs[0], flat=True, destname=hs[1])
730         else:
731             INSTALL_FILES(bld, hdest, h, flat=True)
732 Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS
733
734
735 def subst_at_vars(task):
736     '''substiture @VAR@ style variables in a file'''
737     src = task.inputs[0].srcpath(task.env)
738     tgt = task.outputs[0].bldpath(task.env)
739
740     f = open(src, 'r')
741     s = f.read()
742     f.close()
743     # split on the vars
744     a = re.split('(@\w+@)', s)
745     out = []
746     for v in a:
747         if re.match('@\w+@', v):
748             vname = v[1:-1]
749             if not vname in task.env and vname.upper() in task.env:
750                 vname = vname.upper()
751             if not vname in task.env:
752                 print "Unknown substitution %s in %s" % (v, task.name)
753                 raise
754             v = task.env[vname]
755         out.append(v)
756     contents = ''.join(out)
757     f = open(tgt, 'w')
758     s = f.write(contents)
759     f.close()
760     return 0
761
762
763
764 def PKG_CONFIG_FILES(bld, pc_files):
765     '''install some pkg_config pc files'''
766     dest = '${PKGCONFIGDIR}'
767     dest = bld.EXPAND_VARIABLES(dest)
768     for f in TO_LIST(pc_files):
769         base=os.path.basename(f)
770         bld.SAMBA_GENERATOR('PKGCONFIG_%s' % base,
771                             rule=subst_at_vars,
772                             source=f+'.in',
773                             target=f)
774         INSTALL_FILES(bld, dest, f, flat=True, destname=base)
775 Build.BuildContext.PKG_CONFIG_FILES = PKG_CONFIG_FILES
776
777
778 # override the display of the compilation and linking messages
779 def build_progress(self):
780     return "[%d/%d]" % (self.position[0], self.position[1])
781
782 def cc_display(self):
783     if Options.options.progress_bar != 0:
784         return Task.Task.display(self)
785     fname = self.inputs[0].bldpath(self.env)
786     if fname[0:3] == '../':
787         fname = fname[3:]
788     return "%s Compiling %s\n" % (build_progress(self), fname)
789 Task.TaskBase.classes['cc'].display = cc_display
790
791 def link_display(self):
792     if Options.options.progress_bar != 0:
793         return Task.Task.display(self)
794     fname = self.outputs[0].bldpath(self.env)
795     return "%s Linking %s\n" % (build_progress(self), fname)
796 Task.TaskBase.classes['cc_link'].display = link_display