wafsamba: Correctly detect if bld.env.XSLTPROC is not set
[Samba/gebeck_regimport.git] / buildtools / wafsamba / wafsamba.py
blob41b866d05ca1e2c6c7695d1340ee4d64a9882f64
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
6 from Logs import debug
7 from samba_utils import SUBST_VARS_RECURSIVE
9 # bring in the other samba modules
10 from samba_optimisation import *
11 from samba_utils import *
12 from samba_version import *
13 from samba_autoconf import *
14 from samba_patterns import *
15 from samba_pidl import *
16 from samba_errtable import *
17 from samba_asn1 import *
18 from samba_autoproto import *
19 from samba_python import *
20 from samba_deps import *
21 from samba_bundled import *
22 import samba_install
23 import samba_conftests
24 import samba_abi
25 import tru64cc
26 import irixcc
27 import generic_cc
28 import samba_dist
29 import samba_wildcard
31 O644 = 420
33 # some systems have broken threading in python
34 if os.environ.get('WAF_NOTHREADS') == '1':
35 import nothreads
37 LIB_PATH="shared"
39 os.putenv('PYTHONUNBUFFERED', '1')
42 if Constants.HEXVERSION < 0x105016:
43 Logs.error('''
44 Please use the version of waf that comes with Samba, not
45 a system installed version. See http://wiki.samba.org/index.php/Waf
46 for details.
48 Alternatively, please use ./autogen-waf.sh, and then
49 run ./configure and make as usual. That will call the right version of waf.
50 ''')
51 sys.exit(1)
54 @conf
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, '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']:
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):
74 os.unlink(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:
82 return
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:
86 cache[subsystem] = []
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,
94 deps='',
95 public_deps='',
96 includes='',
97 public_headers=None,
98 header_path=None,
99 pc_files=None,
100 vnum=None,
101 cflags='',
102 external_library=False,
103 realname=None,
104 autoproto=None,
105 group='main',
106 depends_on='',
107 local_include=True,
108 vars=None,
109 install_path=None,
110 install=True,
111 needs_python=False,
112 target_type='LIBRARY',
113 bundled_extension=True,
114 link_name=None,
115 abi_file=None,
116 abi_match=None,
117 hide_symbols=False,
118 is_bundled=False,
119 enabled=True):
120 '''define a Samba library'''
122 if not enabled:
123 SET_TARGET_TYPE(bld, libname, 'DISABLED')
124 return
126 source = bld.EXPAND_VARIABLES(source, vars=vars)
128 # remember empty libraries, so we can strip the dependencies
129 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
130 SET_TARGET_TYPE(bld, libname, 'EMPTY')
131 return
133 if target_type != 'PYTHON' and BUILTIN_LIBRARY(bld, libname):
134 obj_target = libname
135 else:
136 obj_target = libname + '.objlist'
138 # first create a target for building the object files for this library
139 # by separating in this way, we avoid recompiling the C files
140 # separately for the install library and the build library
141 bld.SAMBA_SUBSYSTEM(obj_target,
142 source = source,
143 deps = deps,
144 public_deps = public_deps,
145 includes = includes,
146 public_headers = public_headers,
147 header_path = header_path,
148 cflags = cflags,
149 group = group,
150 autoproto = autoproto,
151 depends_on = depends_on,
152 needs_python = needs_python,
153 hide_symbols = hide_symbols,
154 local_include = local_include)
156 if libname == obj_target:
157 return
159 if not SET_TARGET_TYPE(bld, libname, target_type):
160 return
162 # the library itself will depend on that object target
163 deps += ' ' + public_deps
164 deps = TO_LIST(deps)
165 deps.append(obj_target)
167 if target_type == 'PYTHON' or realname or not is_bundled:
168 # Sanitize the library name
169 bundled_name = libname.lower().replace('_', '-')
170 while bundled_name.startswith("lib"):
171 bundled_name = bundled_name[3:]
172 else:
173 bundled_name = BUNDLED_NAME(bld, libname, bundled_extension)
175 features = 'cc cshlib symlink_lib install_lib'
176 if target_type == 'PYTHON':
177 features += ' pyext'
178 elif needs_python:
179 features += ' pyembed'
180 if abi_file:
181 features += ' abi_check'
183 if abi_file:
184 abi_file = os.path.join(bld.curdir, abi_file)
186 bld.SET_BUILD_GROUP(group)
187 t = bld(
188 features = features,
189 source = [],
190 target = bundled_name,
191 samba_cflags = CURRENT_CFLAGS(bld, libname, cflags),
192 depends_on = depends_on,
193 samba_deps = deps,
194 samba_includes = includes,
195 local_include = local_include,
196 vnum = vnum,
197 install_path = None,
198 samba_inst_path = install_path,
199 name = libname,
200 samba_realname = realname,
201 samba_install = install,
202 abi_file = abi_file,
203 abi_match = abi_match
206 if realname and not link_name:
207 link_name = 'shared/%s' % realname
209 if link_name:
210 t.link_name = link_name
212 if pc_files is not None:
213 bld.PKG_CONFIG_FILES(pc_files, vnum=vnum)
215 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
218 #################################################################
219 def SAMBA_BINARY(bld, binname, source,
220 deps='',
221 includes='',
222 public_headers=None,
223 header_path=None,
224 modules=None,
225 ldflags=None,
226 cflags='',
227 autoproto=None,
228 use_hostcc=False,
229 use_global_deps=True,
230 compiler=None,
231 group='binaries',
232 manpages=None,
233 local_include=True,
234 subsystem_name=None,
235 needs_python=False,
236 vars=None,
237 install=True,
238 install_path=None,
239 enabled=True):
240 '''define a Samba binary'''
242 if not enabled:
243 SET_TARGET_TYPE(bld, binname, 'DISABLED')
244 return
246 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
247 return
249 features = 'cc cprogram symlink_bin install_bin'
250 if needs_python:
251 features += ' pyembed'
253 obj_target = binname + '.objlist'
255 source = bld.EXPAND_VARIABLES(source, vars=vars)
256 source = unique_list(TO_LIST(source))
258 # first create a target for building the object files for this binary
259 # by separating in this way, we avoid recompiling the C files
260 # separately for the install binary and the build binary
261 bld.SAMBA_SUBSYSTEM(obj_target,
262 source = source,
263 deps = deps,
264 includes = includes,
265 cflags = cflags,
266 group = group,
267 autoproto = autoproto,
268 subsystem_name = subsystem_name,
269 needs_python = needs_python,
270 local_include = local_include,
271 use_hostcc = use_hostcc,
272 use_global_deps= use_global_deps)
274 bld.SET_BUILD_GROUP(group)
276 # the binary itself will depend on that object target
277 deps = TO_LIST(deps)
278 deps.append(obj_target)
280 t = bld(
281 features = features,
282 source = [],
283 target = binname,
284 samba_cflags = CURRENT_CFLAGS(bld, binname, cflags),
285 samba_deps = deps,
286 samba_includes = includes,
287 local_include = local_include,
288 samba_modules = modules,
289 top = True,
290 samba_subsystem= subsystem_name,
291 install_path = None,
292 samba_inst_path= install_path,
293 samba_install = install
296 # setup the subsystem_name as an alias for the real
297 # binary name, so it can be found when expanding
298 # subsystem dependencies
299 if subsystem_name is not None:
300 bld.TARGET_ALIAS(subsystem_name, binname)
302 if manpages is not None and 'XSLTPROC' in bld.env:
303 bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
304 for m in manpages.split():
305 source = m + '.xml'
306 bld.SAMBA_GENERATOR(m,
307 source=source,
308 target=m,
309 rule='${XSLTPROC} -o ${TGT} ${MAN_XSL} ${SRC}'
311 bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True)
313 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
316 #################################################################
317 def SAMBA_MODULE(bld, modname, source,
318 deps='',
319 includes='',
320 subsystem=None,
321 init_function=None,
322 autoproto=None,
323 autoproto_extra_source='',
324 aliases=None,
325 cflags='',
326 internal_module=True,
327 local_include=True,
328 vars=None,
329 enabled=True):
330 '''define a Samba module.'''
332 # we add the init function regardless of whether the module
333 # is enabled or not, as we need to generate a null list if
334 # all disabled
335 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
337 if internal_module or BUILTIN_LIBRARY(bld, modname):
338 # treat internal modules as subsystems for now
339 SAMBA_SUBSYSTEM(bld, modname, source,
340 deps=deps,
341 includes=includes,
342 autoproto=autoproto,
343 autoproto_extra_source=autoproto_extra_source,
344 cflags=cflags,
345 local_include=local_include,
346 enabled=enabled)
347 return
349 if not enabled:
350 SET_TARGET_TYPE(bld, modname, 'DISABLED')
351 return
353 source = bld.EXPAND_VARIABLES(source, vars=vars)
354 source = unique_list(TO_LIST(source))
356 # remember empty modules, so we can strip the dependencies
357 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
358 SET_TARGET_TYPE(bld, modname, 'EMPTY')
359 return
361 if not SET_TARGET_TYPE(bld, modname, 'MODULE'):
362 return
364 if subsystem is not None:
365 deps += ' ' + subsystem
367 bld.SET_BUILD_GROUP('main')
368 bld(
369 features = 'cc',
370 source = source,
371 target = modname,
372 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags),
373 samba_includes = includes,
374 local_include = local_include,
375 samba_deps = TO_LIST(deps)
378 if autoproto is not None:
379 bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source))
381 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
384 #################################################################
385 def SAMBA_SUBSYSTEM(bld, modname, source,
386 deps='',
387 public_deps='',
388 includes='',
389 public_headers=None,
390 header_path=None,
391 cflags='',
392 cflags_end=None,
393 group='main',
394 init_function_sentinal=None,
395 heimdal_autoproto=None,
396 heimdal_autoproto_options=None,
397 heimdal_autoproto_private=None,
398 autoproto=None,
399 autoproto_extra_source='',
400 depends_on='',
401 local_include=True,
402 local_include_first=True,
403 subsystem_name=None,
404 enabled=True,
405 use_hostcc=False,
406 use_global_deps=True,
407 vars=None,
408 hide_symbols=False,
409 needs_python=False):
410 '''define a Samba subsystem'''
412 if not enabled:
413 SET_TARGET_TYPE(bld, modname, 'DISABLED')
414 return
416 # remember empty subsystems, so we can strip the dependencies
417 if ((source == '') or (source == [])) and deps == '' and public_deps == '':
418 SET_TARGET_TYPE(bld, modname, 'EMPTY')
419 return
421 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
422 return
424 source = bld.EXPAND_VARIABLES(source, vars=vars)
425 source = unique_list(TO_LIST(source))
427 deps += ' ' + public_deps
429 bld.SET_BUILD_GROUP(group)
431 features = 'cc'
432 if needs_python:
433 features += ' pyext'
435 t = bld(
436 features = features,
437 source = source,
438 target = modname,
439 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, hide_symbols=hide_symbols),
440 depends_on = depends_on,
441 samba_deps = TO_LIST(deps),
442 samba_includes = includes,
443 local_include = local_include,
444 local_include_first = local_include_first,
445 samba_subsystem= subsystem_name,
446 samba_use_hostcc = use_hostcc,
447 samba_use_global_deps = use_global_deps
450 if cflags_end is not None:
451 t.samba_cflags.extend(TO_LIST(cflags_end))
453 if heimdal_autoproto is not None:
454 bld.HEIMDAL_AUTOPROTO(heimdal_autoproto, source, options=heimdal_autoproto_options)
455 if heimdal_autoproto_private is not None:
456 bld.HEIMDAL_AUTOPROTO_PRIVATE(heimdal_autoproto_private, source)
457 if autoproto is not None:
458 bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source))
459 if public_headers is not None:
460 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
461 return t
464 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
467 def SAMBA_GENERATOR(bld, name, rule, source='', target='',
468 group='generators', enabled=True,
469 public_headers=None,
470 header_path=None,
471 vars=None):
472 '''A generic source generator target'''
474 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
475 return
477 if not enabled:
478 return
480 bld.SET_BUILD_GROUP(group)
481 t = bld(
482 rule=rule,
483 source=bld.EXPAND_VARIABLES(source, vars=vars),
484 target=target,
485 shell=isinstance(rule, str),
486 on_results=True,
487 before='cc',
488 ext_out='.c',
489 name=name)
491 if public_headers is not None:
492 bld.PUBLIC_HEADERS(public_headers, header_path=header_path)
493 return t
494 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
498 @runonce
499 def SETUP_BUILD_GROUPS(bld):
500 '''setup build groups used to ensure that the different build
501 phases happen consecutively'''
502 bld.p_ln = bld.srcnode # we do want to see all targets!
503 bld.env['USING_BUILD_GROUPS'] = True
504 bld.add_group('setup')
505 bld.add_group('build_compiler_source')
506 bld.add_group('base_libraries')
507 bld.add_group('generators')
508 bld.add_group('compiler_prototypes')
509 bld.add_group('compiler_libraries')
510 bld.add_group('build_compilers')
511 bld.add_group('build_source')
512 bld.add_group('prototypes')
513 bld.add_group('main')
514 bld.add_group('binaries')
515 bld.add_group('final')
516 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
519 def SET_BUILD_GROUP(bld, group):
520 '''set the current build group'''
521 if not 'USING_BUILD_GROUPS' in bld.env:
522 return
523 bld.set_group(group)
524 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
528 @conf
529 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
530 """use timestamps instead of file contents for deps
531 this currently doesn't work"""
532 def h_file(filename):
533 import stat
534 st = os.stat(filename)
535 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
536 m = Utils.md5()
537 m.update(str(st.st_mtime))
538 m.update(str(st.st_size))
539 m.update(filename)
540 return m.digest()
541 Utils.h_file = h_file
545 t = Task.simple_task_type('copy_script', 'rm -f ${LINK_TARGET} && ln -s ${SRC[0].abspath(env)} ${LINK_TARGET}',
546 shell=True, color='PINK', ext_in='.bin')
547 t.quiet = True
549 @feature('copy_script')
550 @before('apply_link')
551 def copy_script(self):
552 tsk = self.create_task('copy_script', self.allnodes[0])
553 tsk.env.TARGET = self.target
555 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
556 '''used to copy scripts from the source tree into the build directory
557 for use by selftest'''
559 source = bld.path.ant_glob(pattern)
561 bld.SET_BUILD_GROUP('build_source')
562 for s in TO_LIST(source):
563 iname = s
564 if installname != None:
565 iname = installname
566 target = os.path.join(installdir, iname)
567 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
568 mkdir_p(tgtdir)
569 t = bld(features='copy_script',
570 source = s,
571 target = target,
572 always = True,
573 install_path = None)
574 t.env.LINK_TARGET = target
576 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT
579 def install_file(bld, destdir, file, chmod=O644, flat=False,
580 python_fixup=False, destname=None, base_name=None):
581 '''install a file'''
582 destdir = bld.EXPAND_VARIABLES(destdir)
583 if not destname:
584 destname = file
585 if flat:
586 destname = os.path.basename(destname)
587 dest = os.path.join(destdir, destname)
588 if python_fixup:
589 # fixup the python path it will use to find Samba modules
590 inst_file = file + '.inst'
591 bld.SAMBA_GENERATOR('python_%s' % destname,
592 rule="sed 's|\(sys.path.insert.*\)bin/python\(.*\)$|\\1${PYTHONDIR}\\2|g' < ${SRC} > ${TGT}",
593 source=file,
594 target=inst_file)
595 file = inst_file
596 if base_name:
597 file = os.path.join(base_name, file)
598 bld.install_as(dest, file, chmod=chmod)
601 def INSTALL_FILES(bld, destdir, files, chmod=O644, flat=False,
602 python_fixup=False, destname=None, base_name=None):
603 '''install a set of files'''
604 for f in TO_LIST(files):
605 install_file(bld, destdir, f, chmod=chmod, flat=flat,
606 python_fixup=python_fixup, destname=destname,
607 base_name=base_name)
608 Build.BuildContext.INSTALL_FILES = INSTALL_FILES
611 def INSTALL_WILDCARD(bld, destdir, pattern, chmod=O644, flat=False,
612 python_fixup=False, exclude=None, trim_path=None):
613 '''install a set of files matching a wildcard pattern'''
614 files=TO_LIST(bld.path.ant_glob(pattern))
615 if trim_path:
616 files2 = []
617 for f in files:
618 files2.append(os_path_relpath(f, trim_path))
619 files = files2
621 if exclude:
622 for f in files[:]:
623 if fnmatch.fnmatch(f, exclude):
624 files.remove(f)
625 INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat,
626 python_fixup=python_fixup, base_name=trim_path)
627 Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
630 def INSTALL_DIRS(bld, destdir, dirs):
631 '''install a set of directories'''
632 destdir = bld.EXPAND_VARIABLES(destdir)
633 dirs = bld.EXPAND_VARIABLES(dirs)
634 for d in TO_LIST(dirs):
635 bld.install_dir(os.path.join(destdir, d))
636 Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS
639 re_header = re.compile('#include[ \t]*"([^"]+)"', re.I | re.M)
640 class header_task(Task.Task):
641 name = 'header'
642 color = 'PINK'
643 vars = ['INCLUDEDIR', 'HEADER_DEPS']
644 def run(self):
645 txt = self.inputs[0].read(self.env)
647 txt = txt.replace('#if _SAMBA_BUILD_ == 4', '#if 1\n')
649 themap = self.generator.bld.subst_table
650 def repl(m):
651 if m.group(1):
652 s = m.group(1)
653 return "#include <%s>" % themap.get(s, s)
654 return ''
656 txt = re_header.sub(repl, txt)
658 f = None
659 try:
660 f = open(self.outputs[0].abspath(self.env), 'w')
661 f.write(txt)
662 finally:
663 if f:
664 f.close()
666 def init_subst(bld):
668 initialize the header substitution table
669 for now use the file headermap.txt but in the future we will compute the paths properly
672 if getattr(bld, 'subst_table', None):
673 return bld.subst_table_h
675 node = bld.srcnode.find_resource("source4/headermap.txt")
676 if not node:
677 bld.subst_table = {}
678 bld.subst_table_h = 0
679 return {}
680 lines = node.read(None)
682 lines = [x.strip().split(': ') for x in lines.split('\n') if x.rfind(': ') > -1]
683 bld.subst_table = dict(lines)
685 # pidl file replacement (all of this is temporary, one step at a time)
686 keyz = list(bld.subst_table.keys())
687 for k in keyz:
688 bld.subst_table['bin/default/' + k] = bld.subst_table[k]
690 tp = tuple(bld.subst_table.keys())
691 bld.subst_table_h = hash(tp)
692 return bld.subst_table_h
694 @TaskGen.feature('pubh')
695 def make_public_headers(self):
696 if not self.bld.is_install:
697 # install time only (lazy)
698 return
700 self.env['HEADER_DEPS'] = init_subst(self.bld)
701 # adds a dependency and trigger a rebuild if the dict changes
703 header_path = getattr(self, 'header_path', None) or ''
705 for x in self.to_list(self.headers):
707 # too complicated, but what was the original idea?
708 if isinstance(header_path, list):
709 add_dir = ''
710 for (p1, dir) in header_path:
711 lst = self.to_list(p1)
712 for p2 in lst:
713 if fnmatch.fnmatch(x, p2):
714 add_dir = dir
715 break
716 else:
717 continue
718 break
719 inst_path = add_dir
720 else:
721 inst_path = header_path
723 dest = ''
724 name = x
725 if x.find(':') != -1:
726 s = x.split(':')
727 name = s[0]
728 dest = s[1]
730 inn = self.path.find_resource(name)
731 if not inn:
732 raise ValueError("could not find the public header %r in %r" % (name, self.path))
733 out = inn.change_ext('.inst.h')
734 self.create_task('header', inn, out)
736 if not dest:
737 dest = inn.name
739 if inst_path:
740 inst_path = inst_path + '/'
741 inst_path = inst_path + dest
743 #print("going to install the headers", inst_path, out)
744 self.bld.install_as('${INCLUDEDIR}/%s' % inst_path, out, self.env)
746 def PUBLIC_HEADERS(bld, public_headers, header_path=None):
747 '''install some headers
749 header_path may either be a string that is added to the INCLUDEDIR,
750 or it can be a dictionary of wildcard patterns which map to destination
751 directories relative to INCLUDEDIR
753 bld.SET_BUILD_GROUP('final')
754 ret = bld(features=['pubh'], headers=public_headers, header_path=header_path)
755 return ret
756 Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS
759 def subst_at_vars(task):
760 '''substiture @VAR@ style variables in a file'''
761 src = task.inputs[0].srcpath(task.env)
762 tgt = task.outputs[0].bldpath(task.env)
764 f = open(src, 'r')
765 s = f.read()
766 f.close()
767 # split on the vars
768 a = re.split('(@\w+@)', s)
769 out = []
770 done_var = {}
771 back_sub = [ ('PREFIX', '${prefix}'), ('EXEC_PREFIX', '${exec_prefix}')]
772 for v in a:
773 if re.match('@\w+@', v):
774 vname = v[1:-1]
775 if not vname in task.env and vname.upper() in task.env:
776 vname = vname.upper()
777 if not vname in task.env:
778 Logs.error("Unknown substitution %s in %s" % (v, task.name))
779 sys.exit(1)
780 v = SUBST_VARS_RECURSIVE(task.env[vname], task.env)
781 # now we back substitute the allowed pc vars
782 for (b, m) in back_sub:
783 s = task.env[b]
784 if s == v[0:len(s)]:
785 if not b in done_var:
786 # we don't want to substitute the first usage
787 done_var[b] = True
788 else:
789 v = m + v[len(s):]
790 break
791 out.append(v)
792 contents = ''.join(out)
793 f = open(tgt, 'w')
794 s = f.write(contents)
795 f.close()
796 return 0
800 def PKG_CONFIG_FILES(bld, pc_files, vnum=None):
801 '''install some pkg_config pc files'''
802 dest = '${PKGCONFIGDIR}'
803 dest = bld.EXPAND_VARIABLES(dest)
804 for f in TO_LIST(pc_files):
805 base=os.path.basename(f)
806 t = bld.SAMBA_GENERATOR('PKGCONFIG_%s' % base,
807 rule=subst_at_vars,
808 source=f+'.in',
809 target=f)
810 if vnum:
811 t.env.PACKAGE_VERSION = vnum
812 INSTALL_FILES(bld, dest, f, flat=True, destname=base)
813 Build.BuildContext.PKG_CONFIG_FILES = PKG_CONFIG_FILES
817 #############################################################
818 # give a nicer display when building different types of files
819 def progress_display(self, msg, fname):
820 col1 = Logs.colors(self.color)
821 col2 = Logs.colors.NORMAL
822 total = self.position[1]
823 n = len(str(total))
824 fs = '[%%%dd/%%%dd] %s %%s%%s%%s\n' % (n, n, msg)
825 return fs % (self.position[0], self.position[1], col1, fname, col2)
827 def link_display(self):
828 if Options.options.progress_bar != 0:
829 return Task.Task.old_display(self)
830 fname = self.outputs[0].bldpath(self.env)
831 return progress_display(self, 'Linking', fname)
832 Task.TaskBase.classes['cc_link'].display = link_display
834 def samba_display(self):
835 if Options.options.progress_bar != 0:
836 return Task.Task.old_display(self)
838 targets = LOCAL_CACHE(self, 'TARGET_TYPE')
839 if self.name in targets:
840 target_type = targets[self.name]
841 type_map = { 'GENERATOR' : 'Generating',
842 'PROTOTYPE' : 'Generating'
844 if target_type in type_map:
845 return progress_display(self, type_map[target_type], self.name)
847 fname = self.inputs[0].bldpath(self.env)
848 if fname[0:3] == '../':
849 fname = fname[3:]
850 ext_loc = fname.rfind('.')
851 if ext_loc == -1:
852 return Task.Task.old_display(self)
853 ext = fname[ext_loc:]
855 ext_map = { '.idl' : 'Compiling IDL',
856 '.et' : 'Compiling ERRTABLE',
857 '.asn1': 'Compiling ASN1',
858 '.c' : 'Compiling' }
859 if ext in ext_map:
860 return progress_display(self, ext_map[ext], fname)
861 return Task.Task.old_display(self)
863 Task.TaskBase.classes['Task'].old_display = Task.TaskBase.classes['Task'].display
864 Task.TaskBase.classes['Task'].display = samba_display