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