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
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 *
25 #################################################################
26 # create the samba build environment
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:
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
:
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
,
63 external_library
=False,
74 SET_TARGET_TYPE(bld
, libname
, 'DISABLED')
77 # remember empty libraries, so we can strip the dependencies
78 if (source
== '') or (source
== []):
79 SET_TARGET_TYPE(bld
, libname
, 'EMPTY')
82 if bld
.env
.DISABLE_SHARED
:
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
,
93 public_deps
= public_deps
,
95 public_headers
= public_headers
,
98 autoproto
= autoproto
,
99 depends_on
= depends_on
,
100 local_include
= local_include
)
102 if bld
.env
.DISABLE_SHARED
:
105 if not SET_TARGET_TYPE(bld
, libname
, 'LIBRARY'):
108 # the library itself will depend on that object target
109 deps
+= ' ' + public_deps
111 deps
.append(obj_target
)
113 bld
.SET_BUILD_GROUP(group
)
115 features
= 'cc cshlib symlink_lib',
118 samba_cflags
= CURRENT_CFLAGS(bld
, libname
, cflags
),
119 depends_on
= depends_on
,
121 samba_includes
= includes
,
122 local_include
= local_include
,
127 if install_path
is None:
128 install_path
= '${LIBDIR}'
129 install_path
= SUBST_VARS_RECURSIVE(install_path
, bld
.env
)
132 # create a separate install library, which may have
133 # different rpath settings
134 SET_TARGET_TYPE(bld
, libname
+ '.inst', 'LIBRARY')
136 features
= 'cc cshlib',
138 target
= libname
+ '.inst',
139 samba_cflags
= CURRENT_CFLAGS(bld
, libname
, cflags
),
140 depends_on
= depends_on
,
142 samba_includes
= includes
,
143 local_include
= local_include
,
145 install_as
= libname
,
148 t
.env
['RPATH'] = install_rpath(bld
)
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
)
155 install_name
= 'lib%s.so' % libname
158 bld
.install_as(os
.path
.join(install_path
, install_name
),
159 'lib%s.inst.so' % libname
)
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
,
191 if not SET_TARGET_TYPE(bld
, binname
, 'BINARY'):
194 features
= 'cc cprogram'
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
,
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
218 deps
.append(obj_target
)
221 features
= features
+ ' symlink_bin',
224 samba_cflags
= CURRENT_CFLAGS(bld
, binname
, cflags
),
226 samba_includes
= includes
,
227 local_include
= local_include
,
228 samba_modules
= modules
,
230 samba_subsystem
= subsystem_name
,
234 if install_path
is None:
235 install_path
= '${BINDIR}'
236 install_path
= SUBST_VARS_RECURSIVE(install_path
, bld
.env
)
239 # we create a separate 'install' binary, which
240 # will have different rpath settings
241 SET_TARGET_TYPE(bld
, binname
+ '.inst', 'BINARY')
245 target
= binname
+ '.inst',
246 samba_cflags
= CURRENT_CFLAGS(bld
, binname
, cflags
),
248 samba_includes
= includes
,
249 local_include
= local_include
,
250 samba_modules
= modules
,
252 samba_subsystem
= subsystem_name
,
255 t
.env
['RPATH'] = install_rpath(bld
)
257 bld
.install_as(os
.path
.join(install_path
, binname
),
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
,
280 autoproto_extra_source
='',
283 internal_module
=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
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
,
298 autoproto_extra_source
=autoproto_extra_source
,
300 local_include
=local_include
,
305 SET_TARGET_TYPE(bld
, modname
, 'DISABLED')
308 # remember empty modules, so we can strip the dependencies
309 if (source
== '') or (source
== []):
310 SET_TARGET_TYPE(bld
, modname
, 'EMPTY')
313 if not SET_TARGET_TYPE(bld
, modname
, 'MODULE'):
316 if subsystem
is not None:
317 deps
+= ' ' + subsystem
319 bld
.SET_BUILD_GROUP('main')
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
,
346 init_function_sentinal
=None,
347 heimdal_autoproto
=None,
348 heimdal_autoproto_options
=None,
349 heimdal_autoproto_private
=None,
351 autoproto_extra_source
='',
354 local_include_first
=True,
360 SET_TARGET_TYPE(bld
, modname
, 'DISABLED')
363 # remember empty subsystems, so we can strip the dependencies
364 if (source
== '') or (source
== []):
365 SET_TARGET_TYPE(bld
, modname
, 'EMPTY')
368 if not SET_TARGET_TYPE(bld
, modname
, 'SUBSYSTEM'):
371 deps
+= ' ' + public_deps
373 bld
.SET_BUILD_GROUP(group
)
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
)
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'):
416 bld
.SET_BUILD_GROUP(group
)
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
437 debug("build: Processing subdirectory %s" % 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
448 Options
.Handler
.ADD_COMMAND
= ADD_COMMAND
450 ###########################################################
451 # setup build groups used to ensure that the different build
452 # phases happen consecutively
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
:
474 Build
.BuildContext
.SET_BUILD_GROUP
= SET_BUILD_GROUP
477 def h_file(filename
):
479 st
= os
.stat(filename
)
480 if stat
.S_ISDIR(st
[stat
.ST_MODE
]): raise IOError('not a file')
482 m
.update(str(st
.st_mtime
))
483 m
.update(str(st
.st_size
))
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')
500 @feature('symlink_lib')
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
507 vnum
= getattr(self
, 'vnum', 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')
529 @feature('symlink_bin')
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
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)
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
):
565 if installname
!= None:
567 target
= os
.path
.join(installdir
, iname
)
568 tgtdir
= os
.path
.dirname(os
.path
.join(bld
.srcnode
.abspath(bld
.env
), '..', target
))
570 t
= bld(features
='copy_script',
575 t
.env
.LINK_TARGET
= target
577 Build
.BuildContext
.SAMBA_SCRIPT
= SAMBA_SCRIPT