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, Logs, sys, Configure, Options, string, Task, Utils, optparse
5 from Configure import conf
7 from TaskGen import extension
9 # bring in the other samba modules
10 from samba_utils import *
11 # should be enabled from the above?
12 from samba_autoconf import *
13 from samba_patterns import *
14 from samba_pidl import *
15 from samba_asn1 import *
16 from samba_autoproto import *
21 #################################################################
22 # create the samba build environment
24 def SAMBA_BUILD_ENV(conf):
25 libpath="%s/%s" % (conf.blddir, LIB_PATH)
26 conf.env['BUILD_DIRECTORY'] = conf.blddir
27 if not os.path.exists(libpath):
30 ##############################################
31 # remove .. elements from a path list
32 def NORMPATH(bld, ilist):
33 return " ".join([os.path.normpath(p) for p in ilist.split(" ")])
34 Build.BuildContext.NORMPATH = NORMPATH
36 ################################################################
37 # add an init_function to the list for a subsystem
38 def ADD_INIT_FUNCTION(bld, subsystem, init_function):
39 if init_function is None:
41 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
42 cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
43 if not subsystem in cache:
45 cache[subsystem] += '%s,' % init_function
46 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
48 ################################################################
49 # recursively build the dependency list for a target
50 def FULL_DEPENDENCIES(bld, cache, target, chain, path):
51 if not target in cache:
53 deps = cache[target].copy()
54 for t in cache[target]:
55 bld.ASSERT(t not in chain, "Circular dependency for %s: %s->%s" % (t, path, t));
58 dict_concat(deps, FULL_DEPENDENCIES(bld, cache, t, c2, "%s->%s" % (path, t)))
61 ############################################################
62 # check our build dependencies for circular dependencies
63 def CHECK_TARGET_DEPENDENCY(bld, target):
64 cache = LOCAL_CACHE(bld, 'LIB_DEPS')
65 return FULL_DEPENDENCIES(bld, cache, target, { target:True }, target)
67 ############################################################
68 # check that all dependencies have been declared
69 def CHECK_DEPENDENCIES(bld):
70 cache = LOCAL_CACHE(bld, 'LIB_DEPS')
71 target_cache = LOCAL_CACHE(bld, 'TARGET_TYPE')
72 debug('deps: Checking dependencies')
74 deps = CHECK_TARGET_DEPENDENCY(bld, t)
76 if not d in target_cache:
77 print "WARNING: Dependency '%s' of target '%s' not declared" % (d, t)
78 #ASSERT(bld, d in target_cache,
79 # "Dependency '%s' of target '%s' not declared" % (d, t))
80 debug("deps: Dependencies checked for %u targets" % len(target_cache))
81 Build.BuildContext.CHECK_DEPENDENCIES = CHECK_DEPENDENCIES
84 ############################################################
85 # pre-declare a target as being of a particular type
86 def PREDECLARE(bld, target, type):
87 cache = LOCAL_CACHE(bld, 'PREDECLARED_TARGET')
88 target_cache = LOCAL_CACHE(bld, 'TARGET_TYPE')
89 ASSERT(bld, not target in target_cache, "Target '%s' is already declared" % target)
90 ASSERT(bld, not target in cache, "Target '%s' already predeclared" % target)
92 Build.BuildContext.PREDECLARE = PREDECLARE
96 ################################################################
97 # add to the dependency list. Return a new dependency list with
98 # any circular dependencies removed
99 # returns a tuple containing (systemdeps, localdeps, add_objects)
100 def ADD_DEPENDENCIES(bld, name, deps):
101 debug('deps: Calculating dependencies for %s' % name)
102 lib_deps = LOCAL_CACHE(bld, 'LIB_DEPS')
103 if not name in lib_deps:
108 lib_deps[name][d] = True;
110 CHECK_TARGET_DEPENDENCY(bld, name)
112 except AssertionError:
113 sys.stderr.write("Removing dependency %s from target %s\n" % (d, name))
114 del(lib_deps[name][d])
116 target_cache = LOCAL_CACHE(bld, 'TARGET_TYPE')
118 # extract out the system dependencies
122 cache = LOCAL_CACHE(bld, 'EMPTY_TARGETS')
123 predeclare = LOCAL_CACHE(bld, 'PREDECLARED_TARGET')
126 # strip out any dependencies on empty libraries
128 debug("deps: Removing empty dependency '%s' from '%s'" % (d, name))
132 if d in target_cache:
133 type = target_cache[d]
134 elif d in predeclare:
138 LOCAL_CACHE_SET(bld, 'ASSUMED_TARGET', d, type)
142 elif type == 'LIBRARY':
144 elif type == 'SUBSYSTEM':
145 add_objects.append(d)
147 elif type == 'MODULE':
148 add_objects.append(d)
150 elif type == 'PYTHON':
154 elif type == 'BINARY':
157 ASSERT(bld, False, "Unknown target type '%s' for dependency %s" % (
160 # for some types we have to build the list recursively
161 if recurse and (d in lib_deps):
162 rec_deps = ' '.join(lib_deps[d].keys())
163 (rec_sysdeps, rec_localdeps, rec_add_objects) = ADD_DEPENDENCIES(bld, d, rec_deps)
164 sysdeps.extend(rec_sysdeps.split())
165 localdeps.extend(rec_localdeps.split())
166 add_objects.extend(rec_add_objects.split())
168 debug('deps: Dependencies for %s: sysdeps: %u localdeps: %u add_objects=%u' % (
169 name, len(sysdeps), len(localdeps), len(add_objects)))
170 return (' '.join(sysdeps), ' '.join(localdeps), ' '.join(add_objects))
173 #################################################################
174 # return a include list for a set of library dependencies
175 def SAMBA_LIBRARY_INCLUDE_LIST(bld, deps):
176 ret = bld.curdir + ' '
177 cache = LOCAL_CACHE(bld, 'INCLUDE_LIST')
178 for l in deps.split():
180 ret = ret + cache[l] + ' '
181 if 'EXTRA_INCLUDES' in bld.env:
182 ret += ' ' + ' '.join(bld.env['EXTRA_INCLUDES'])
184 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
186 #################################################################
187 # define a Samba library
188 def SAMBA_LIBRARY(bld, libname, source,
200 if not SET_TARGET_TYPE(bld, libname, 'LIBRARY'):
203 # remember empty libraries, so we can strip the dependencies
204 if (source == '') or (source == []):
205 LOCAL_CACHE_SET(bld, 'EMPTY_TARGETS', libname, True)
208 (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, libname, deps)
210 ilist = bld.SUBDIR(bld.curdir, includes) + ' ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps)
211 ilist = bld.NORMPATH(ilist)
213 # this print below should show that we're runnig this code
214 print "Setting build group for library %s to %s" % (libname, group), bld.path
215 bld.SET_BUILD_GROUP(group) # <- here
217 features = 'cc cshlib',
220 uselib_local = localdeps,
222 add_objects = add_objects,
223 ccflags = CURRENT_CFLAGS(bld, cflags),
224 includes=ilist + ' . #',
225 depends_on=depends_on,
228 # I have to set it each time? I expect it to be still
229 # set from the few lines above
231 # put a link to the library in bin/shared
234 soext = '.' + vnum.split('.')[0]
237 source = 'lib%s.so' % libname,
238 rule = 'ln -sf ../${SRC}%s %s/lib%s.so%s' % (soext, LIB_PATH, libname, soext),
239 # rule = 'ln -sf ../%s.so%s %s/lib%s.so%s' % (libname, soext, LIB_PATH, libname, soext),
243 name = 'fff' + libname,
246 LOCAL_CACHE_SET(bld, 'INCLUDE_LIST', libname, ilist)
248 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
250 #################################################################
251 # define a Samba binary
252 def SAMBA_BINARY(bld, binname, source,
265 ilist = includes + ' ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps)
266 ilist = bld.NORMPATH(ilist)
268 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
271 (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, binname, deps)
273 cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
274 if modules is not None:
275 for m in modules.split():
276 bld.ASSERT(m in cache,
277 "No init_function defined for module '%s' in binary '%s'" % (m, binname))
278 cflags += ' -DSTATIC_%s_MODULES="%s"' % (m, cache[m])
280 bld.SET_BUILD_GROUP(group)
282 features = 'cc cprogram',
285 uselib_local = localdeps,
287 includes = ilist + ' . #',
288 ccflags = CURRENT_CFLAGS(bld, cflags),
289 add_objects = add_objects,
292 if not Options.is_install:
295 rule = 'rm -f %s && cp ${SRC} .' % (binname),
300 name = binname + ".copy",
303 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
306 #################################################################
307 # define a Samba python module
308 def SAMBA_PYTHON(bld, name, source,
313 if not SET_TARGET_TYPE(bld, name, 'PYTHON'):
316 (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, name, deps)
319 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
321 #################################################################
322 # define a Samba ET target
323 def SAMBA_ERRTABLE(bld, name, source,
326 # print "Skipping ERRTABLE rule for %s with source=%s" % (name, source)
328 if not SET_TARGET_TYPE(bld, name, 'ET'):
330 bld.SET_BUILD_GROUP('build_source')
336 Build.BuildContext.SAMBA_ERRTABLE = SAMBA_ERRTABLE
341 ################################################################
342 # build a C prototype file automatically
343 def AUTOPROTO(bld, header, source):
344 if header is not None:
345 bld.SET_BUILD_GROUP('prototypes')
349 rule = '../script/mkproto.pl --srcdir=.. --builddir=. --public=/dev/null --private=${TGT} ${SRC}'
351 Build.BuildContext.AUTOPROTO = AUTOPROTO
354 #################################################################
355 # define a Samba module.
356 def SAMBA_MODULE(bld, modname, source,
366 if not SET_TARGET_TYPE(bld, modname, 'MODULE'):
369 # remember empty modules, so we can strip the dependencies
370 if (source == '') or (source == []):
371 LOCAL_CACHE_SET(bld, 'EMPTY_TARGETS', modname, True)
374 (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, modname, deps)
376 ilist = bld.SUBDIR(bld.curdir, includes) + ' ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps)
377 ilist = bld.NORMPATH(ilist)
378 bld.SET_BUILD_GROUP('main')
383 ccflags = CURRENT_CFLAGS(bld, cflags),
384 includes=ilist + ' . #')
385 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
388 #################################################################
389 # define a Samba subsystem
390 def SAMBA_SUBSYSTEM(bld, modname, source,
398 init_function_sentinal=None,
399 heimdal_autoproto=None,
400 heimdal_autoproto_private=None,
404 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
407 # if the caller specifies a config_option, then we create a blank
408 # subsystem if that configuration option was found at configure time
409 if (config_option is not None) and bld.CONFIG_SET(config_option):
412 # remember empty subsystems, so we can strip the dependencies
413 if (source == '') or (source == []):
414 LOCAL_CACHE_SET(bld, 'EMPTY_TARGETS', modname, True)
417 (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, modname, deps)
419 ilist = bld.SUBDIR(bld.curdir, includes) + ' ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps)
420 ilist = bld.NORMPATH(ilist)
421 bld.SET_BUILD_GROUP(group)
426 ccflags = CURRENT_CFLAGS(bld, cflags),
427 includes=ilist + ' . #',
428 depends_on=depends_on)
429 LOCAL_CACHE_SET(bld, 'INCLUDE_LIST', modname, ilist)
431 if heimdal_autoproto is not None:
432 bld.HEIMDAL_AUTOPROTO(heimdal_autoproto, source)
433 if heimdal_autoproto_private is not None:
434 bld.HEIMDAL_AUTOPROTO_PRIVATE(heimdal_autoproto_private, source)
435 if autoproto is not None:
436 bld.SAMBA_AUTOPROTO(autoproto, source)
439 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
442 ###############################################################
443 # add a new set of build rules from a subdirectory
444 # the @runonce decorator ensures we don't end up
445 # with duplicate rules
446 def BUILD_SUBDIR(bld, dir):
447 path = os.path.normpath(bld.curdir + '/' + dir)
448 cache = LOCAL_CACHE(bld, 'SUBDIR_LIST')
449 if path in cache: return
451 debug("build: Processing subdirectory %s" % dir)
454 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
457 ##########################################################
458 # add a new top level command to waf
459 def ADD_COMMAND(opt, name, function):
460 Utils.g_module.__dict__[name] = function
462 Options.Handler.ADD_COMMAND = ADD_COMMAND
464 ###########################################################
465 # setup build groups used to ensure that the different build
466 # phases happen consecutively
468 def SETUP_BUILD_GROUPS(bld):
469 bld.p_ln = bld.srcnode # we do want to see all targets!
470 bld.env['USING_BUILD_GROUPS'] = True
471 bld.add_group('setup')
472 bld.add_group('base_libraries')
473 bld.add_group('build_compilers')
474 bld.add_group('build_source')
475 bld.add_group('prototypes')
476 bld.add_group('main')
477 bld.add_group('final')
478 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
481 ###########################################################
482 # set the current build group
483 def SET_BUILD_GROUP(bld, group):
484 if not 'USING_BUILD_GROUPS' in bld.env:
487 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP