build: added --disable-shared option
[Samba/gebeck_regimport.git] / buildtools / wafsamba / wafsamba.py
blobbfe20ce5ebda1729aa3737478ac3bb4179337bf3
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
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_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 *
21 LIB_PATH="shared"
25 #################################################################
26 # create the samba build environment
27 @conf
28 def SAMBA_BUILD_ENV(conf):
29 conf.env['BUILD_DIRECTORY'] = conf.blddir
30 mkdir_p(os.path.join(conf.blddir, LIB_PATH))
31 mkdir_p(os.path.join(conf.blddir, 'python/samba/dcerpc'))
32 # this allows all of the bin/shared and bin/python targets
33 # to be expressed in terms of build directory paths
34 for p in ['python','shared']:
35 link_target = os.path.join(conf.blddir, 'default/' + p)
36 if not os.path.lexists(link_target):
37 os.symlink('../' + p, link_target)
41 ################################################################
42 # add an init_function to the list for a subsystem
43 def ADD_INIT_FUNCTION(bld, subsystem, target, init_function):
44 if init_function is None:
45 return
46 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
47 cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
48 if not subsystem in cache:
49 cache[subsystem] = []
50 cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } )
51 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
54 #################################################################
55 # define a Samba library
56 def SAMBA_LIBRARY(bld, libname, source,
57 deps='',
58 public_deps='',
59 includes='',
60 public_headers=None,
61 vnum=None,
62 cflags='',
63 external_library=False,
64 realname=None,
65 autoproto=None,
66 group='main',
67 depends_on='',
68 local_include=True,
69 install_path=None,
70 install=True,
71 enabled=True):
73 if not enabled:
74 SET_TARGET_TYPE(bld, libname, 'DISABLED')
75 return
77 # remember empty libraries, so we can strip the dependencies
78 if (source == '') or (source == []):
79 SET_TARGET_TYPE(bld, libname, 'EMPTY')
80 return
82 if bld.env.DISABLE_SHARED:
83 obj_target = libname
84 else:
85 obj_target = libname + '.objlist'
87 # first create a target for building the object files for this library
88 # by separating in this way, we avoid recompiling the C files
89 # separately for the install library and the build library
90 bld.SAMBA_SUBSYSTEM(obj_target,
91 source = source,
92 deps = deps,
93 public_deps = public_deps,
94 includes = includes,
95 public_headers = public_headers,
96 cflags = cflags,
97 group = group,
98 autoproto = autoproto,
99 depends_on = depends_on,
100 local_include = local_include)
102 if bld.env.DISABLE_SHARED:
103 return
105 if not SET_TARGET_TYPE(bld, libname, 'LIBRARY'):
106 return
108 # the library itself will depend on that object target
109 deps += ' ' + public_deps
110 deps = TO_LIST(deps)
111 deps.append(obj_target)
113 bld.SET_BUILD_GROUP(group)
114 t = bld(
115 features = 'cc cshlib symlink_lib',
116 source = [],
117 target = libname,
118 samba_cflags = CURRENT_CFLAGS(bld, libname, cflags),
119 depends_on = depends_on,
120 samba_deps = deps,
121 samba_includes = includes,
122 local_include = local_include,
123 vnum = vnum,
124 install_path = None
127 if install_path is None:
128 install_path = '${LIBDIR}'
129 install_path = SUBST_VARS_RECURSIVE(install_path, bld.env)
131 if install:
132 # create a separate install library, which may have
133 # different rpath settings
134 SET_TARGET_TYPE(bld, libname + '.inst', 'LIBRARY')
135 t = bld(
136 features = 'cc cshlib',
137 source = [],
138 target = libname + '.inst',
139 samba_cflags = CURRENT_CFLAGS(bld, libname, cflags),
140 depends_on = depends_on,
141 samba_deps = deps,
142 samba_includes = includes,
143 local_include = local_include,
144 vnum = vnum,
145 install_as = libname,
146 install_path = None,
148 t.env['RPATH'] = install_rpath(bld)
150 if vnum:
151 vnum_base = vnum.split('.')[0]
152 install_name = 'lib%s.so.%s' % (libname, vnum)
153 install_link = 'lib%s.so.%s' % (libname, vnum_base)
154 else:
155 install_name = 'lib%s.so' % libname
156 install_link = None
158 bld.install_as(os.path.join(install_path, install_name),
159 'lib%s.inst.so' % libname)
160 if install_link:
161 bld.symlink_as(os.path.join(install_path, install_link), install_name)
164 if autoproto is not None:
165 bld.SAMBA_AUTOPROTO(autoproto, source)
167 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
170 #################################################################
171 # define a Samba binary
172 def SAMBA_BINARY(bld, binname, source,
173 deps='',
174 includes='',
175 public_headers=None,
176 modules=None,
177 installdir=None,
178 ldflags=None,
179 cflags='',
180 autoproto=None,
181 use_hostcc=None,
182 compiler=None,
183 group='binaries',
184 manpages=None,
185 local_include=True,
186 subsystem_name=None,
187 needs_python=False,
188 install=True,
189 install_path=None):
191 if not SET_TARGET_TYPE(bld, binname, 'BINARY'):
192 return
194 features = 'cc cprogram'
195 if needs_python:
196 features += ' pyembed'
198 bld.SET_BUILD_GROUP(group)
200 obj_target = binname + '.objlist'
202 # first create a target for building the object files for this binary
203 # by separating in this way, we avoid recompiling the C files
204 # separately for the install binary and the build binary
205 bld.SAMBA_SUBSYSTEM(obj_target,
206 source = source,
207 deps = deps,
208 includes = includes,
209 cflags = cflags,
210 group = group,
211 autoproto = autoproto,
212 subsystem_name = subsystem_name,
213 needs_python = needs_python,
214 local_include = local_include)
216 # the library itself will depend on that object target
217 deps = TO_LIST(deps)
218 deps.append(obj_target)
220 bld(
221 features = features + ' symlink_bin',
222 source = [],
223 target = binname,
224 samba_cflags = CURRENT_CFLAGS(bld, binname, cflags),
225 samba_deps = deps,
226 samba_includes = includes,
227 local_include = local_include,
228 samba_modules = modules,
229 top = True,
230 samba_subsystem= subsystem_name,
231 install_path = None
234 if install_path is None:
235 install_path = '${BINDIR}'
236 install_path = SUBST_VARS_RECURSIVE(install_path, bld.env)
238 if install:
239 # we create a separate 'install' binary, which
240 # will have different rpath settings
241 SET_TARGET_TYPE(bld, binname + '.inst', 'BINARY')
242 t = bld(
243 features = features,
244 source = [],
245 target = binname + '.inst',
246 samba_cflags = CURRENT_CFLAGS(bld, binname, cflags),
247 samba_deps = deps,
248 samba_includes = includes,
249 local_include = local_include,
250 samba_modules = modules,
251 top = True,
252 samba_subsystem= subsystem_name,
253 install_path = None
255 t.env['RPATH'] = install_rpath(bld)
257 bld.install_as(os.path.join(install_path, binname),
258 binname + '.inst',
259 chmod=0755)
261 # setup the subsystem_name as an alias for the real
262 # binary name, so it can be found when expanding
263 # subsystem dependencies
264 if subsystem_name is not None:
265 bld.TARGET_ALIAS(subsystem_name, binname)
267 if autoproto is not None:
268 bld.SAMBA_AUTOPROTO(autoproto, source)
269 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
272 #################################################################
273 # define a Samba module.
274 def SAMBA_MODULE(bld, modname, source,
275 deps='',
276 includes='',
277 subsystem=None,
278 init_function=None,
279 autoproto=None,
280 autoproto_extra_source='',
281 aliases=None,
282 cflags='',
283 internal_module=True,
284 local_include=True,
285 enabled=True):
287 # we add the init function regardless of whether the module
288 # is enabled or not, as we need to generate a null list if
289 # all disabled
290 bld.ADD_INIT_FUNCTION(subsystem, modname, init_function)
292 if internal_module or bld.env.DISABLE_SHARED:
293 # treat internal modules as subsystems for now
294 SAMBA_SUBSYSTEM(bld, modname, source,
295 deps=deps,
296 includes=includes,
297 autoproto=autoproto,
298 autoproto_extra_source=autoproto_extra_source,
299 cflags=cflags,
300 local_include=local_include,
301 enabled=enabled)
302 return
304 if not enabled:
305 SET_TARGET_TYPE(bld, modname, 'DISABLED')
306 return
308 # remember empty modules, so we can strip the dependencies
309 if (source == '') or (source == []):
310 SET_TARGET_TYPE(bld, modname, 'EMPTY')
311 return
313 if not SET_TARGET_TYPE(bld, modname, 'MODULE'):
314 return
316 if subsystem is not None:
317 deps += ' ' + subsystem
319 bld.SET_BUILD_GROUP('main')
320 bld(
321 features = 'cc',
322 source = source,
323 target = modname,
324 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags),
325 samba_includes = includes,
326 local_include = local_include,
327 samba_deps = TO_LIST(deps)
330 if autoproto is not None:
331 bld.SAMBA_AUTOPROTO(autoproto, source + ' ' + autoproto_extra_source)
333 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
336 #################################################################
337 # define a Samba subsystem
338 def SAMBA_SUBSYSTEM(bld, modname, source,
339 deps='',
340 public_deps='',
341 includes='',
342 public_headers=None,
343 cflags='',
344 cflags_end=None,
345 group='main',
346 init_function_sentinal=None,
347 heimdal_autoproto=None,
348 heimdal_autoproto_options=None,
349 heimdal_autoproto_private=None,
350 autoproto=None,
351 autoproto_extra_source='',
352 depends_on='',
353 local_include=True,
354 local_include_first=True,
355 subsystem_name=None,
356 enabled=True,
357 needs_python=False):
359 if not enabled:
360 SET_TARGET_TYPE(bld, modname, 'DISABLED')
361 return
363 # remember empty subsystems, so we can strip the dependencies
364 if (source == '') or (source == []):
365 SET_TARGET_TYPE(bld, modname, 'EMPTY')
366 return
368 if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'):
369 return
371 deps += ' ' + public_deps
373 bld.SET_BUILD_GROUP(group)
375 features = 'cc'
376 if needs_python:
377 features += ' pyext'
379 t = bld(
380 features = features,
381 source = source,
382 target = modname,
383 samba_cflags = CURRENT_CFLAGS(bld, modname, cflags),
384 depends_on = depends_on,
385 samba_deps = TO_LIST(deps),
386 samba_includes = includes,
387 local_include = local_include,
388 local_include_first = local_include_first,
389 samba_subsystem= subsystem_name
392 if cflags_end is not None:
393 t.samba_cflags.extend(TO_LIST(cflags_end))
395 if heimdal_autoproto is not None:
396 bld.HEIMDAL_AUTOPROTO(heimdal_autoproto, source, options=heimdal_autoproto_options)
397 if heimdal_autoproto_private is not None:
398 bld.HEIMDAL_AUTOPROTO_PRIVATE(heimdal_autoproto_private, source)
399 if autoproto is not None:
400 bld.SAMBA_AUTOPROTO(autoproto, source + ' ' + autoproto_extra_source)
401 return t
403 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
406 def SAMBA_GENERATOR(bld, name, rule, source, target,
407 group='build_source', enabled=True):
408 '''A generic source generator target'''
410 if not SET_TARGET_TYPE(bld, name, 'GENERATOR'):
411 return
413 if not enabled:
414 return False
416 bld.SET_BUILD_GROUP(group)
417 bld(
418 rule=rule,
419 source=source,
420 target=target,
421 before='cc',
422 ext_out='.c',
423 name=name)
424 Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR
428 ###############################################################
429 # add a new set of build rules from a subdirectory
430 # the @runonce decorator ensures we don't end up
431 # with duplicate rules
432 def BUILD_SUBDIR(bld, dir):
433 path = os.path.normpath(bld.curdir + '/' + dir)
434 cache = LOCAL_CACHE(bld, 'SUBDIR_LIST')
435 if path in cache: return
436 cache[path] = True
437 debug("build: Processing subdirectory %s" % dir)
438 bld.add_subdirs(dir)
440 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
443 ##########################################################
444 # add a new top level command to waf
445 def ADD_COMMAND(opt, name, function):
446 Utils.g_module.__dict__[name] = function
447 opt.name = function
448 Options.Handler.ADD_COMMAND = ADD_COMMAND
450 ###########################################################
451 # setup build groups used to ensure that the different build
452 # phases happen consecutively
453 @runonce
454 def SETUP_BUILD_GROUPS(bld):
455 bld.p_ln = bld.srcnode # we do want to see all targets!
456 bld.env['USING_BUILD_GROUPS'] = True
457 bld.add_group('setup')
458 bld.add_group('base_libraries')
459 bld.add_group('build_compilers')
460 bld.add_group('build_source')
461 bld.add_group('prototypes')
462 bld.add_group('main')
463 bld.add_group('binaries')
464 bld.add_group('final')
465 Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS
468 ###########################################################
469 # set the current build group
470 def SET_BUILD_GROUP(bld, group):
471 if not 'USING_BUILD_GROUPS' in bld.env:
472 return
473 bld.set_group(group)
474 Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP
477 def h_file(filename):
478 import stat
479 st = os.stat(filename)
480 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
481 m = Utils.md5()
482 m.update(str(st.st_mtime))
483 m.update(str(st.st_size))
484 m.update(filename)
485 return m.digest()
487 @conf
488 def ENABLE_TIMESTAMP_DEPENDENCIES(conf):
489 Utils.h_file = h_file
492 ##############################
493 # handle the creation of links for libraries and binaries
494 # note that we use a relative symlink path to allow the whole tree
495 # to me moved/copied elsewhere without breaking the links
496 t = Task.simple_task_type('symlink_lib', 'ln -sf ${LINK_SOURCE} ${LINK_TARGET}',
497 color='PINK', ext_in='.bin')
498 t.quiet = True
500 @feature('symlink_lib')
501 @after('apply_link')
502 def symlink_lib(self):
503 tsk = self.create_task('symlink_lib', self.link_task.outputs[0])
505 # calculat the link target and put it in the environment
506 soext=""
507 vnum = getattr(self, 'vnum', None)
508 if vnum is not None:
509 soext = '.' + vnum.split('.')[0]
511 link_target = getattr(self, 'link_name', '')
512 if link_target == '':
513 link_target = '%s/lib%s.so%s' % (LIB_PATH, self.sname, soext)
516 link_source = os_path_relpath(self.link_task.outputs[0].abspath(self.env),
517 os.path.join(self.env.BUILD_DIRECTORY, link_target))
519 tsk.env.LINK_TARGET = link_target
520 tsk.env.LINK_SOURCE = link_source[3:]
521 debug('task_gen: LINK for %s is %s -> %s',
522 self.name, tsk.env.LINK_SOURCE, tsk.env.LINK_TARGET)
525 t = Task.simple_task_type('symlink_bin', 'ln -sf ${SRC} ${BIN_TARGET}',
526 color='PINK', ext_in='.bin')
527 t.quiet = True
529 @feature('symlink_bin')
530 @after('apply_link')
531 def symlink_bin(self):
532 if Options.is_install:
533 # we don't want to copy the install binary, as
534 # that has the install rpath, not the build rpath
535 # The rpath of the binaries in bin/default/foo/blah is different
536 # during the install phase, as distros insist on not using rpath in installed binaries
537 return
538 tsk = self.create_task('symlink_bin', self.link_task.outputs[0])
540 tsk.env.BIN_TARGET = self.target
541 debug('task_gen: BIN_TARGET for %s is %s', self.name, tsk.env.BIN_TARGET)
546 t = Task.simple_task_type('copy_script', 'ln -sf ${SRC[0].abspath(env)} ${LINK_TARGET}',
547 color='PINK', ext_in='.bin', shell=True)
548 t.quiet = True
550 @feature('copy_script')
551 @before('apply_link')
552 def copy_script(self):
553 tsk = self.create_task('copy_script', self.allnodes[0])
554 tsk.env.TARGET = self.target
556 def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None):
557 '''used to copy scripts from the source tree into the build directory
558 for use by selftest'''
560 source = bld.path.ant_glob(pattern)
562 bld.SET_BUILD_GROUP('build_source')
563 for s in TO_LIST(source):
564 iname = s
565 if installname != None:
566 iname = installname
567 target = os.path.join(installdir, iname)
568 tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target))
569 mkdir_p(tgtdir)
570 t = bld(features='copy_script',
571 source = s,
572 target = target,
573 always = True,
574 install_path = None)
575 t.env.LINK_TARGET = target
577 Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT