build: fixed formatting
[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, Logs, sys, Configure, Options, string, Task, Utils, optparse
5 from Configure import conf
6 from Logs import debug
7 from TaskGen import extension
8
9 # bring in the other samba modules
10 from samba_utils import *
11 from samba_autoconf import *
12 from samba_patterns import *
13 from samba_pidl import *
14
15 LIB_PATH="shared"
16
17
18 #################################################################
19 # create the samba build environment
20 @conf
21 def SAMBA_BUILD_ENV(conf):
22     libpath="%s/%s" % (conf.blddir, LIB_PATH)
23     conf.env['BUILD_DIRECTORY'] = conf.blddir
24     if not os.path.exists(libpath):
25         os.mkdir(libpath)
26
27 ##############################################
28 # remove .. elements from a path list
29 def NORMPATH(bld, ilist):
30     return " ".join([os.path.normpath(p) for p in ilist.split(" ")])
31 Build.BuildContext.NORMPATH = NORMPATH
32
33 ################################################################
34 # add an init_function to the list for a subsystem
35 def ADD_INIT_FUNCTION(bld, subsystem, init_function):
36     if init_function is None:
37         return
38     bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
39     cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
40     if not subsystem in cache:
41         cache[subsystem] = ''
42     cache[subsystem] += '%s,' % init_function
43 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
44
45 ################################################################
46 # recursively build the dependency list for a target
47 def FULL_DEPENDENCIES(bld, cache, target, chain, path):
48     if not target in cache:
49         return {}
50     deps = cache[target].copy()
51     for t in cache[target]:
52         bld.ASSERT(t not in chain, "Circular dependency for %s: %s->%s" % (t, path, t));
53         c2 = chain.copy()
54         c2[t] = True
55         dict_concat(deps, FULL_DEPENDENCIES(bld, cache, t, c2, "%s->%s" % (path, t)))
56     return deps
57
58 ############################################################
59 # check our build dependencies for circular dependencies
60 def CHECK_TARGET_DEPENDENCY(bld, target):
61     cache = LOCAL_CACHE(bld, 'LIB_DEPS')
62     return FULL_DEPENDENCIES(bld, cache, target, { target:True }, target)
63
64 ############################################################
65 # check that all dependencies have been declared
66 def CHECK_DEPENDENCIES(bld):
67     cache = LOCAL_CACHE(bld, 'LIB_DEPS')
68     target_cache = LOCAL_CACHE(bld, 'TARGET_TYPE')
69     debug('deps: Checking dependencies')
70     for t in cache:
71         deps = CHECK_TARGET_DEPENDENCY(bld, t)
72         for d in deps:
73             #if not d in target_cache:
74             #    print "Dependency '%s' of target '%s' not declared" % (d, t)
75             ASSERT(bld, d in target_cache,
76                    "Dependency '%s' of target '%s' not declared" % (d, t))
77     debug("deps: Dependencies checked for %u targets" % len(target_cache))
78 Build.BuildContext.CHECK_DEPENDENCIES = CHECK_DEPENDENCIES
79
80
81 ############################################################
82 # pre-declare a target as being of a particular type
83 def PREDECLARE(bld, target, type):
84     cache = LOCAL_CACHE(bld, 'PREDECLARED_TARGET')
85     target_cache = LOCAL_CACHE(bld, 'TARGET_TYPE')
86     ASSERT(bld, not target in target_cache, "Target '%s' is already declared" % target)
87     ASSERT(bld, not target in cache, "Target '%s' already predeclared" % target)
88     cache[target] = type
89 Build.BuildContext.PREDECLARE = PREDECLARE
90
91
92
93 ################################################################
94 # add to the dependency list. Return a new dependency list with
95 # any circular dependencies removed
96 # returns a tuple containing (systemdeps, localdeps, add_objects)
97 def ADD_DEPENDENCIES(bld, name, deps):
98     debug('deps: Calculating dependencies for %s' % name)
99     lib_deps = LOCAL_CACHE(bld, 'LIB_DEPS')
100     if not name in lib_deps:
101         lib_deps[name] = {}
102     list = deps.split()
103     list2 = []
104     for d in list:
105         lib_deps[name][d] = True;
106         try:
107             CHECK_TARGET_DEPENDENCY(bld, name)
108             list2.append(d)
109         except AssertionError:
110             sys.stderr.write("Removing dependency %s from target %s\n" % (d, name))
111             del(lib_deps[name][d])
112
113     # extract out the system dependencies
114     sysdeps = []
115     localdeps = []
116     add_objects = []
117     cache = LOCAL_CACHE(bld, 'EMPTY_TARGETS')
118     target_cache = LOCAL_CACHE(bld, 'TARGET_TYPE')
119     predeclare = LOCAL_CACHE(bld, 'PREDECLARED_TARGET')
120     for d in list2:
121         recurse = False
122         # strip out any dependencies on empty libraries
123         if d in cache:
124             debug("deps: Removing empty dependency '%s' from '%s'" % (d, name))
125             continue
126         type = None
127
128         if d in target_cache:
129             type = target_cache[d]
130         elif d in predeclare:
131             type = predeclare[d]
132         else:
133             type = 'SUBSYSTEM'
134             LOCAL_CACHE_SET(bld, 'ASSUMED_TARGET', d, type)
135
136         if type == 'SYSLIB':
137             sysdeps.append(d)
138         elif type == 'LIBRARY':
139             localdeps.append(d)
140         elif type == 'SUBSYSTEM':
141             add_objects.append(d)
142             recurse = True
143         elif type == 'MODULE':
144             add_objects.append(d)
145             recurse = True
146         elif type == 'PYTHON':
147             pass
148         elif type == 'ASN1':
149             pass
150         elif type == 'BINARY':
151             pass
152         else:
153             ASSERT(bld, False, "Unknown target type '%s' for dependency %s" % (
154                     type, d))
155
156         # for some types we have to build the list recursively
157         if recurse and (d in lib_deps):
158             rec_deps = ' '.join(lib_deps[d].keys())
159             (rec_sysdeps, rec_localdeps, rec_add_objects) = ADD_DEPENDENCIES(bld, d, rec_deps)
160             sysdeps.extend(rec_sysdeps.split())
161             localdeps.extend(rec_localdeps.split())
162             add_objects.extend(rec_add_objects.split())
163
164     debug('deps: Dependencies for %s: sysdeps: %u  localdeps: %u  add_objects=%u' % (
165             name, len(sysdeps), len(localdeps), len(add_objects)))
166     return (' '.join(sysdeps), ' '.join(localdeps), ' '.join(add_objects))
167
168
169 #################################################################
170 # return a include list for a set of library dependencies
171 def SAMBA_LIBRARY_INCLUDE_LIST(bld, deps):
172     ret = bld.curdir + ' '
173     cache = LOCAL_CACHE(bld, 'INCLUDE_LIST')
174     for l in deps.split():
175         if l in cache:
176             ret = ret + cache[l] + ' '
177     return ret
178 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
179
180 #################################################################
181 # define a Samba library
182 def SAMBA_LIBRARY(bld, libname, source,
183                   deps='',
184                   public_deps='',
185                   include_list='.',
186                   public_headers=None,
187                   vnum=None,
188                   cflags='',
189                   output_type=None,
190                   realname=None,
191                   autoproto=None):
192     if not SET_TARGET_TYPE(bld, libname, 'LIBRARY'):
193         return
194
195     # remember empty libraries, so we can strip the dependencies
196     if (source == '') or (source == []):
197         LOCAL_CACHE_SET(bld, 'EMPTY_TARGETS', libname, True)
198         return
199
200     (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, libname, deps)
201
202     ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
203     ilist = bld.NORMPATH(ilist)
204     bld.SET_BUILD_GROUP('main')
205     bld(
206         features = 'cc cshlib',
207         source = source,
208         target=libname,
209         uselib_local = localdeps,
210         uselib = sysdeps,
211         add_objects = add_objects,
212         ccflags = CURRENT_CFLAGS(bld, cflags),
213         includes='. ' + bld.env['BUILD_DIRECTORY'] + '/default ' + ilist,
214         vnum=vnum)
215
216     # put a link to the library in bin/shared
217     soext=""
218     if vnum is not None:
219         soext = '.' + vnum.split('.')[0]
220     bld.SET_BUILD_GROUP('final')
221     bld(
222         source = 'lib%s.so' % libname,
223         rule = 'ln -sf ../${SRC}%s %s/lib%s.so%s' %
224         (soext, LIB_PATH, libname, soext),
225         shell = True,
226         after = 'cc_link',
227         )
228     LOCAL_CACHE_SET(bld, 'INCLUDE_LIST', libname, ilist)
229
230 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
231
232
233 #################################################################
234 # define a Samba binary
235 def SAMBA_BINARY(bld, binname, source,
236                  deps='',
237                  include_list='',
238                  public_headers=None,
239                  modules=None,
240                  installdir=None,
241                  ldflags=None,
242                  cflags='',
243                  autoproto=None,
244                  use_hostcc=None,
245                  compiler=None,
246                  group='main',
247                  manpages=None):
248     ilist = '. ' + bld.env['BUILD_DIRECTORY'] + '/default ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + ' ' + include_list
249     ilist = bld.NORMPATH(ilist)
250
251     if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
252         return
253
254     (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, binname, deps)
255
256     cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
257     if modules is not None:
258         for m in modules.split():
259             bld.ASSERT(m in cache,
260                        "No init_function defined for module '%s' in binary '%s'" % (m, binname))
261             cflags += ' -DSTATIC_%s_MODULES="%s"' % (m, cache[m])
262
263     bld.SET_BUILD_GROUP(group)
264     bld(
265         features = 'cc cprogram',
266         source = source,
267         target = binname,
268         uselib_local = localdeps,
269         uselib = sysdeps,
270         includes = ilist,
271         ccflags = CURRENT_CFLAGS(bld, cflags),
272         add_objects = add_objects,
273         top=True)
274     # put a link to the binary in bin/
275     if not Options.is_install:
276         bld(
277             source = binname,
278             rule = 'rm -f %s && cp ${SRC} .' % (binname),
279             shell = True,
280             after = 'cc_link'
281             )
282 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
283
284
285 #################################################################
286 # define a Samba python module
287 def SAMBA_PYTHON(bld, name, source,
288                  deps='',
289                  public_deps='',
290                  realname=''):
291
292     if not SET_TARGET_TYPE(bld, name, 'PYTHON'):
293         return
294
295     (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, name, deps)
296
297     return
298 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
299
300
301
302 #################################################################
303 # define a Samba ASN1 target
304 def SAMBA_ASN1(bld, name, source,
305                options='',
306                directory=''):
307     if not SET_TARGET_TYPE(bld, name, 'ASN1'):
308         return
309     bld.SET_BUILD_GROUP('build_source')
310     bld(
311         features       = 'cc',
312         source         = source,
313         target         = name,
314         asn1options    = options,
315         asn1directory  = directory
316     )
317 Build.BuildContext.SAMBA_ASN1 = SAMBA_ASN1
318
319
320
321 #################################################################
322 # define a Samba ET target
323 def SAMBA_ERRTABLE(bld, name, source,
324                options='',
325                directory=''):
326     if not SET_TARGET_TYPE(bld, name, 'ET'):
327         return
328     bld.SET_BUILD_GROUP('build_source')
329     bld(
330         features = 'cc',
331         source   = source,
332         target   = name
333     )
334 Build.BuildContext.SAMBA_ERRTABLE = SAMBA_ERRTABLE
335
336
337
338
339 #################################################################
340 # define a set of Samba PIDL targets
341 def SAMBA_PIDL_LIST(bld, directory, source, options=''):
342     for p in source.split():
343         bld.SAMBA_PIDL(directory, p, options)
344 Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST
345
346
347 ################################################################
348 # build a C prototype file automatically
349 def AUTOPROTO(bld, header, source):
350     if header is not None:
351         bld.SET_BUILD_GROUP('prototypes')
352         bld(
353             source = source,
354             target = header,
355             rule = '../script/mkproto.pl --srcdir=.. --builddir=. --public=/dev/null --private=${TGT} ${SRC}'
356             )
357 Build.BuildContext.AUTOPROTO = AUTOPROTO
358
359
360 #################################################################
361 # define a Samba module.
362 def SAMBA_MODULE(bld, modname, source,
363                  deps='',
364                  include_list='.',
365                  subsystem=None,
366                  init_function=None,
367                  autoproto=None,
368                  aliases=None,
369                  cflags='',
370                  output_type=None):
371
372     if not SET_TARGET_TYPE(bld, modname, 'MODULE'):
373         return
374
375     # remember empty modules, so we can strip the dependencies
376     if (source == '') or (source == []):
377         LOCAL_CACHE_SET(bld, 'EMPTY_TARGETS', modname, True)
378         return
379
380     (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, modname, deps)
381
382     ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
383     ilist = bld.NORMPATH(ilist)
384     bld.SET_BUILD_GROUP('main')
385     bld(
386         features = 'cc',
387         source = source,
388         target=modname,
389         ccflags = CURRENT_CFLAGS(bld, cflags),
390         includes='. ' + bld.env['BUILD_DIRECTORY'] + '/default ' + ilist)
391 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
392
393
394 #################################################################
395 # define a Samba subsystem
396 def SAMBA_SUBSYSTEM(bld, modname, source,
397                     deps='',
398                     public_deps='',
399                     include_list='.',
400                     public_headers=None,
401                     autoproto=None,
402                     cflags='',
403                     group='main',
404                     config_option=None,
405                     init_function_sentinal=None):
406
407     if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
408         return
409
410     # if the caller specifies a config_option, then we create a blank
411     # subsystem if that configuration option was found at configure time
412     if (config_option is not None) and bld.CONFIG_SET(config_option):
413             source = ''
414
415     # remember empty subsystems, so we can strip the dependencies
416     if (source == '') or (source == []):
417         LOCAL_CACHE_SET(bld, 'EMPTY_TARGETS', modname, True)
418         return
419
420     (sysdeps, localdeps, add_objects) = ADD_DEPENDENCIES(bld, modname, deps)
421
422     ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
423     ilist = bld.NORMPATH(ilist)
424     bld.SET_BUILD_GROUP(group)
425     bld(
426         features = 'cc',
427         source = source,
428         target=modname,
429         ccflags = CURRENT_CFLAGS(bld, cflags),
430         includes='. ' + bld.env['BUILD_DIRECTORY'] + '/default ' + ilist)
431 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
432
433
434 ###############################################################
435 # add a new set of build rules from a subdirectory
436 # the @runonce decorator ensures we don't end up
437 # with duplicate rules
438 def BUILD_SUBDIR(bld, dir):
439     path = os.path.normpath(bld.curdir + '/' + dir)
440     cache = LOCAL_CACHE(bld, 'SUBDIR_LIST')
441     if path in cache: return
442     cache[path] = True
443     debug("build: Processing subdirectory %s" % dir)
444     bld.add_subdirs(dir)
445
446 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
447
448
449 ##########################################################
450 # add a new top level command to waf
451 def ADD_COMMAND(opt, name, function):
452     Utils.g_module.__dict__[name] = function
453     opt.name = function
454 Options.Handler.ADD_COMMAND = ADD_COMMAND
455
456 ###########################################################
457 # setup build groups used to ensure that the different build
458 # phases happen consecutively
459 @runonce
460 def SETUP_BUILD_GROUPS(bld):
461     bld.env['USING_BUILD_GROUPS'] = True
462     bld.add_group('setup')
463     bld.add_group('build_compilers')
464     bld.add_group('build_source')
465     bld.add_group('prototypes')
466     bld.add_group('main')
467     bld.add_group('final')
468 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
469
470
471 ###########################################################
472 # set the current build group
473 def SET_BUILD_GROUP(bld, group):
474     if not 'USING_BUILD_GROUPS' in bld.env:
475         return
476     bld.set_group(group)
477 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
478