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
5 from Configure import conf
8 # bring in the other samba modules
9 from samba_includes import *
10 from samba_utils import *
11 from samba_autoconf import *
12 from samba_patterns import *
13 from samba_pidl import *
14 from samba_errtable import *
15 from samba_asn1 import *
16 from samba_autoproto import *
17 from samba_python import *
18 from samba_deps import *
24 #################################################################
25 # create the samba build environment
27 def SAMBA_BUILD_ENV(conf):
28 conf.env['BUILD_DIRECTORY'] = conf.blddir
29 mkdir_p(os.path.join(conf.blddir, LIB_PATH))
30 mkdir_p(os.path.join(conf.blddir, 'python/samba/dcerpc'))
31 # this allows all of the bin/shared and bin/python targets
32 # to be expressed in terms of build directory paths
33 for p in ['python','shared']:
34 link_target = os.path.join(conf.blddir, 'default/' + p)
35 if not os.path.lexists(link_target):
36 os.symlink('../' + p, link_target)
40 ################################################################
41 # add an init_function to the list for a subsystem
42 def ADD_INIT_FUNCTION(bld, subsystem, target, init_function):
43 if init_function is None:
45 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
46 cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
47 if not subsystem in cache:
49 cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } )
50 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
53 #################################################################
54 # define a Samba library
55 def SAMBA_LIBRARY(bld, libname, source,
62 external_library=False,
69 # remember empty libraries, so we can strip the dependencies
70 if (source == '') or (source == []):
71 SET_TARGET_TYPE(bld, libname, 'EMPTY')
74 if not SET_TARGET_TYPE(bld, libname, 'LIBRARY'):
77 deps += ' ' + public_deps
79 # this print below should show that we're runnig this code
80 bld.SET_BUILD_GROUP(group)
82 features = 'cc cshlib symlink_lib',
85 samba_cflags = CURRENT_CFLAGS(bld, libname, cflags),
86 depends_on = depends_on,
87 samba_deps = TO_LIST(deps),
88 samba_includes = includes,
89 local_include = local_include,
92 if autoproto is not None:
93 bld.SAMBA_AUTOPROTO(autoproto, source)
95 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
97 #################################################################
98 # define a Samba binary
99 def SAMBA_BINARY(bld, binname, source,
116 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
119 features = 'cc cprogram copy_bin'
121 features += ' pyembed'
123 bld.SET_BUILD_GROUP(group)
128 samba_cflags = CURRENT_CFLAGS(bld, binname, cflags),
129 samba_deps = TO_LIST(deps),
130 samba_includes = includes,
131 local_include = local_include,
132 samba_modules = modules,
134 samba_subsystem= subsystem_name
137 # setup the subsystem_name as an alias for the real
138 # binary name, so it can be found when expanding
139 # subsystem dependencies
140 if subsystem_name is not None:
141 bld.TARGET_ALIAS(subsystem_name, binname)
143 if autoproto is not None:
144 bld.SAMBA_AUTOPROTO(autoproto, source)
145 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
148 #################################################################
149 # define a Samba module.
150 def SAMBA_MODULE(bld, modname, source,
156 autoproto_extra_source='',
159 internal_module=True,
164 # treat internal modules as subsystems for now
165 SAMBA_SUBSYSTEM(bld, modname, source,
169 autoproto_extra_source=autoproto_extra_source,
171 local_include=local_include,
173 # even though we're treating it as a subsystem, we need to
174 # add it to the init_function list
175 # TODO: we should also create an implicit dependency
176 # between the subsystem target and this target
178 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
182 SET_TARGET_TYPE(bld, modname, 'DISABLED')
185 # remember empty modules, so we can strip the dependencies
186 if (source == '') or (source == []):
187 SET_TARGET_TYPE(bld, modname, 'EMPTY')
190 if not SET_TARGET_TYPE(bld, modname, 'MODULE'):
194 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
196 if subsystem is not None:
197 deps += ' ' + subsystem
199 bld.SET_BUILD_GROUP('main')
204 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags),
205 samba_includes = includes,
206 local_include = local_include,
207 samba_deps = TO_LIST(deps)
210 if autoproto is not None:
211 bld.SAMBA_AUTOPROTO(autoproto, source + ' ' + autoproto_extra_source)
213 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
216 #################################################################
217 # define a Samba subsystem
218 def SAMBA_SUBSYSTEM(bld, modname, source,
226 init_function_sentinal=None,
227 heimdal_autoproto=None,
228 heimdal_autoproto_options=None,
229 heimdal_autoproto_private=None,
231 autoproto_extra_source='',
234 local_include_first=True,
240 SET_TARGET_TYPE(bld, modname, 'DISABLED')
243 # remember empty subsystems, so we can strip the dependencies
244 if (source == '') or (source == []):
245 SET_TARGET_TYPE(bld, modname, 'EMPTY')
248 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
251 deps += ' ' + public_deps
253 bld.SET_BUILD_GROUP(group)
263 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags),
264 depends_on = depends_on,
265 samba_deps = TO_LIST(deps),
266 samba_includes = includes,
267 local_include = local_include,
268 local_include_first = local_include_first,
269 samba_subsystem= subsystem_name
272 if heimdal_autoproto is not None:
273 bld.HEIMDAL_AUTOPROTO(heimdal_autoproto, source, options=heimdal_autoproto_options)
274 if heimdal_autoproto_private is not None:
275 bld.HEIMDAL_AUTOPROTO_PRIVATE(heimdal_autoproto_private, source)
276 if autoproto is not None:
277 bld.SAMBA_AUTOPROTO(autoproto, source + ' ' + autoproto_extra_source)
280 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
283 def SAMBA_GENERATOR(bld, name, rule, source, target,
284 group='build_source'):
285 '''A generic source generator target'''
287 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
290 bld.SET_BUILD_GROUP(group)
297 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
301 ###############################################################
302 # add a new set of build rules from a subdirectory
303 # the @runonce decorator ensures we don't end up
304 # with duplicate rules
305 def BUILD_SUBDIR(bld, dir):
306 path = os.path.normpath(bld.curdir + '/' + dir)
307 cache = LOCAL_CACHE(bld, 'SUBDIR_LIST')
308 if path in cache: return
310 debug("build: Processing subdirectory %s" % dir)
313 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
316 ##########################################################
317 # add a new top level command to waf
318 def ADD_COMMAND(opt, name, function):
319 Utils.g_module.__dict__[name] = function
321 Options.Handler.ADD_COMMAND = ADD_COMMAND
323 ###########################################################
324 # setup build groups used to ensure that the different build
325 # phases happen consecutively
327 def SETUP_BUILD_GROUPS(bld):
328 bld.p_ln = bld.srcnode # we do want to see all targets!
329 bld.env['USING_BUILD_GROUPS'] = True
330 bld.add_group('setup')
331 bld.add_group('base_libraries')
332 bld.add_group('build_compilers')
333 bld.add_group('build_source')
334 bld.add_group('prototypes')
335 bld.add_group('main')
336 bld.add_group('binaries')
337 bld.add_group('final')
338 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
341 ###########################################################
342 # set the current build group
343 def SET_BUILD_GROUP(bld, group):
344 if not 'USING_BUILD_GROUPS' in bld.env:
347 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
350 def h_file(filename):
352 st = os.stat(filename)
353 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
355 m.update(str(st.st_mtime))
356 m.update(str(st.st_size))
361 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
362 Utils.h_file = h_file
365 ##############################
366 # handle the creation of links for libraries and binaries
367 # note that we use a relative symlink path to allow the whole tree
368 # to me moved/copied elsewhere without breaking the links
369 t = Task.simple_task_type('symlink_lib', 'ln -sf ${LINK_SOURCE} ${LINK_TARGET}',
370 color='PINK', ext_in='.bin')
373 @feature('symlink_lib')
375 def symlink_lib(self):
376 tsk = self.create_task('symlink_lib', self.link_task.outputs[0])
378 # calculat the link target and put it in the environment
380 vnum = getattr(self, 'vnum', None)
382 soext = '.' + vnum.split('.')[0]
384 link_target = getattr(self, 'link_name', '')
385 if link_target == '':
386 link_target = '%s/lib%s.so%s' % (LIB_PATH, self.sname, soext)
389 link_source = os_path_relpath(self.link_task.outputs[0].abspath(self.env),
390 os.path.join(self.env.BUILD_DIRECTORY, link_target))
392 tsk.env.LINK_TARGET = link_target
393 tsk.env.LINK_SOURCE = link_source[3:]
394 debug('task_gen: LINK for %s is %s -> %s',
395 self.name, tsk.env.LINK_SOURCE, tsk.env.LINK_TARGET)
397 # for binaries we need to copy the executable to avoid the rpath changing
398 # in the local bin/ directory on install
399 t = Task.simple_task_type('copy_bin', 'rm -f ${BIN_TARGET} && cp ${SRC} ${BIN_TARGET}', color='PINK',
400 ext_in='.bin', shell=True)
406 if Options.is_install:
407 # we don't want to copy the install binary, as
408 # that has the install rpath, not the build rpath
409 # The rpath of the binaries in bin/default/foo/blah is different
410 # during the install phase, as distros insist on not using rpath in installed binaries
412 tsk = self.create_task('copy_bin', self.link_task.outputs[0])
414 tsk.env.BIN_TARGET = self.target
415 debug('task_gen: BIN_TARGET for %s is %s', self.name, tsk.env.BIN_TARGET)
420 t = Task.simple_task_type('copy_script', 'ln -sf ${SRC[0].abspath(env)} ${LINK_TARGET}',
421 color='PINK', ext_in='.bin', shell=True)
424 @feature('copy_script')
425 @before('apply_link')
426 def copy_script(self):
427 tsk = self.create_task('copy_script', self.allnodes[0])
428 tsk.env.TARGET = self.target
430 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
431 '''used to copy scripts from the source tree into the build directory
432 for use by selftest'''
434 source = bld.path.ant_glob(pattern)
436 bld.SET_BUILD_GROUP('build_source')
437 for s in TO_LIST(source):
439 if installname != None:
441 target = os.path.join(installdir, iname)
442 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
444 t = bld(features='copy_script',
448 t.env.LINK_TARGET = target
450 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT