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
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,
73 SET_TARGET_TYPE(bld
, libname
, 'DISABLED')
76 # remember empty libraries, so we can strip the dependencies
77 if (source
== '') or (source
== []):
78 SET_TARGET_TYPE(bld
, libname
, 'EMPTY')
81 if not SET_TARGET_TYPE(bld
, libname
, 'LIBRARY'):
84 obj_target
= libname
+ '.objlist'
86 # first create a target for building the object files for this library
87 # by separating in this way, we avoid recompiling the C files
88 # separately for the install library and the build library
89 bld
.SAMBA_SUBSYSTEM(obj_target
,
92 public_deps
= public_deps
,
94 public_headers
= public_headers
,
97 autoproto
= autoproto
,
98 depends_on
= depends_on
,
99 local_include
= local_include
)
101 # the library itself will depend on that object target
102 deps
+= ' ' + public_deps
104 deps
.append(obj_target
)
106 bld
.SET_BUILD_GROUP(group
)
108 features
= 'cc cshlib symlink_lib',
111 samba_cflags
= CURRENT_CFLAGS(bld
, libname
, cflags
),
112 depends_on
= depends_on
,
114 samba_includes
= includes
,
115 local_include
= local_include
,
120 if install_path
is None:
121 install_path
= '${PREFIX}/lib'
124 # create a separate install library, which may have
125 # different rpath settings
126 SET_TARGET_TYPE(bld
, libname
+ '.inst', 'LIBRARY')
128 features
= 'cc cshlib',
130 target
= libname
+ '.inst',
131 samba_cflags
= CURRENT_CFLAGS(bld
, libname
, cflags
),
132 depends_on
= depends_on
,
134 samba_includes
= includes
,
135 local_include
= local_include
,
137 install_as
= libname
,
140 t
.env
['RPATH'] = install_rpath(bld
)
143 vnum_base
= vnum
.split('.')[0]
144 install_name
= 'lib%s.so.%s' % (libname
, vnum
)
145 install_link
= 'lib%s.so.%s' % (libname
, vnum_base
)
147 install_name
= 'lib%s.so' % libname
150 bld
.install_as(os
.path
.join(install_path
, install_name
),
151 'lib%s.inst.so' % libname
)
153 bld
.symlink_as(os
.path
.join(install_path
, install_link
), install_name
)
156 if autoproto
is not None:
157 bld
.SAMBA_AUTOPROTO(autoproto
, source
)
159 Build
.BuildContext
.SAMBA_LIBRARY
= SAMBA_LIBRARY
162 #################################################################
163 # define a Samba binary
164 def SAMBA_BINARY(bld
, binname
, source
,
183 if not SET_TARGET_TYPE(bld
, binname
, 'BINARY'):
186 features
= 'cc cprogram'
188 features
+= ' pyembed'
190 bld
.SET_BUILD_GROUP(group
)
192 obj_target
= binname
+ '.objlist'
194 # first create a target for building the object files for this binary
195 # by separating in this way, we avoid recompiling the C files
196 # separately for the install binary and the build binary
197 bld
.SAMBA_SUBSYSTEM(obj_target
,
203 autoproto
= autoproto
,
204 subsystem_name
= subsystem_name
,
205 needs_python
= needs_python
,
206 local_include
= local_include
)
208 # the library itself will depend on that object target
210 deps
.append(obj_target
)
213 features
= features
+ ' symlink_bin',
216 samba_cflags
= CURRENT_CFLAGS(bld
, binname
, cflags
),
218 samba_includes
= includes
,
219 local_include
= local_include
,
220 samba_modules
= modules
,
222 samba_subsystem
= subsystem_name
,
226 if install_path
is None:
227 install_path
= '${PREFIX}/bin'
230 # we create a separate 'install' binary, which
231 # will have different rpath settings
232 SET_TARGET_TYPE(bld
, binname
+ '.inst', 'BINARY')
236 target
= binname
+ '.inst',
237 samba_cflags
= CURRENT_CFLAGS(bld
, binname
, cflags
),
239 samba_includes
= includes
,
240 local_include
= local_include
,
241 samba_modules
= modules
,
243 samba_subsystem
= subsystem_name
,
246 t
.env
['RPATH'] = install_rpath(bld
)
248 bld
.install_as(os
.path
.join(install_path
, binname
),
252 # setup the subsystem_name as an alias for the real
253 # binary name, so it can be found when expanding
254 # subsystem dependencies
255 if subsystem_name
is not None:
256 bld
.TARGET_ALIAS(subsystem_name
, binname
)
258 if autoproto
is not None:
259 bld
.SAMBA_AUTOPROTO(autoproto
, source
)
260 Build
.BuildContext
.SAMBA_BINARY
= SAMBA_BINARY
263 #################################################################
264 # define a Samba module.
265 def SAMBA_MODULE(bld
, modname
, source
,
271 autoproto_extra_source
='',
274 internal_module
=True,
279 # treat internal modules as subsystems for now
280 SAMBA_SUBSYSTEM(bld
, modname
, source
,
284 autoproto_extra_source
=autoproto_extra_source
,
286 local_include
=local_include
,
288 # even though we're treating it as a subsystem, we need to
289 # add it to the init_function list
290 # TODO: we should also create an implicit dependency
291 # between the subsystem target and this target
293 bld
.ADD_INIT_FUNCTION(subsystem
, modname
, init_function
)
297 SET_TARGET_TYPE(bld
, modname
, 'DISABLED')
300 # remember empty modules, so we can strip the dependencies
301 if (source
== '') or (source
== []):
302 SET_TARGET_TYPE(bld
, modname
, 'EMPTY')
305 if not SET_TARGET_TYPE(bld
, modname
, 'MODULE'):
309 bld
.ADD_INIT_FUNCTION(subsystem
, modname
, init_function
)
311 if subsystem
is not None:
312 deps
+= ' ' + subsystem
314 bld
.SET_BUILD_GROUP('main')
319 samba_cflags
= CURRENT_CFLAGS(bld
, modname
, cflags
),
320 samba_includes
= includes
,
321 local_include
= local_include
,
322 samba_deps
= TO_LIST(deps
)
325 if autoproto
is not None:
326 bld
.SAMBA_AUTOPROTO(autoproto
, source
+ ' ' + autoproto_extra_source
)
328 Build
.BuildContext
.SAMBA_MODULE
= SAMBA_MODULE
331 #################################################################
332 # define a Samba subsystem
333 def SAMBA_SUBSYSTEM(bld
, modname
, source
,
341 init_function_sentinal
=None,
342 heimdal_autoproto
=None,
343 heimdal_autoproto_options
=None,
344 heimdal_autoproto_private
=None,
346 autoproto_extra_source
='',
349 local_include_first
=True,
355 SET_TARGET_TYPE(bld
, modname
, 'DISABLED')
358 # remember empty subsystems, so we can strip the dependencies
359 if (source
== '') or (source
== []):
360 SET_TARGET_TYPE(bld
, modname
, 'EMPTY')
363 if not SET_TARGET_TYPE(bld
, modname
, 'SUBSYSTEM'):
366 deps
+= ' ' + public_deps
368 bld
.SET_BUILD_GROUP(group
)
378 samba_cflags
= CURRENT_CFLAGS(bld
, modname
, cflags
),
379 depends_on
= depends_on
,
380 samba_deps
= TO_LIST(deps
),
381 samba_includes
= includes
,
382 local_include
= local_include
,
383 local_include_first
= local_include_first
,
384 samba_subsystem
= subsystem_name
387 if cflags_end
is not None:
388 t
.samba_cflags
.extend(TO_LIST(cflags_end
))
390 if heimdal_autoproto
is not None:
391 bld
.HEIMDAL_AUTOPROTO(heimdal_autoproto
, source
, options
=heimdal_autoproto_options
)
392 if heimdal_autoproto_private
is not None:
393 bld
.HEIMDAL_AUTOPROTO_PRIVATE(heimdal_autoproto_private
, source
)
394 if autoproto
is not None:
395 bld
.SAMBA_AUTOPROTO(autoproto
, source
+ ' ' + autoproto_extra_source
)
398 Build
.BuildContext
.SAMBA_SUBSYSTEM
= SAMBA_SUBSYSTEM
401 def SAMBA_GENERATOR(bld
, name
, rule
, source
, target
,
402 group
='build_source'):
403 '''A generic source generator target'''
405 if not SET_TARGET_TYPE(bld
, name
, 'GENERATOR'):
408 bld
.SET_BUILD_GROUP(group
)
415 Build
.BuildContext
.SAMBA_GENERATOR
= SAMBA_GENERATOR
419 ###############################################################
420 # add a new set of build rules from a subdirectory
421 # the @runonce decorator ensures we don't end up
422 # with duplicate rules
423 def BUILD_SUBDIR(bld
, dir):
424 path
= os
.path
.normpath(bld
.curdir
+ '/' + dir)
425 cache
= LOCAL_CACHE(bld
, 'SUBDIR_LIST')
426 if path
in cache
: return
428 debug("build: Processing subdirectory %s" % dir)
431 Build
.BuildContext
.BUILD_SUBDIR
= BUILD_SUBDIR
434 ##########################################################
435 # add a new top level command to waf
436 def ADD_COMMAND(opt
, name
, function
):
437 Utils
.g_module
.__dict
__[name
] = function
439 Options
.Handler
.ADD_COMMAND
= ADD_COMMAND
441 ###########################################################
442 # setup build groups used to ensure that the different build
443 # phases happen consecutively
445 def SETUP_BUILD_GROUPS(bld
):
446 bld
.p_ln
= bld
.srcnode
# we do want to see all targets!
447 bld
.env
['USING_BUILD_GROUPS'] = True
448 bld
.add_group('setup')
449 bld
.add_group('base_libraries')
450 bld
.add_group('build_compilers')
451 bld
.add_group('build_source')
452 bld
.add_group('prototypes')
453 bld
.add_group('main')
454 bld
.add_group('binaries')
455 bld
.add_group('final')
456 Build
.BuildContext
.SETUP_BUILD_GROUPS
= SETUP_BUILD_GROUPS
459 ###########################################################
460 # set the current build group
461 def SET_BUILD_GROUP(bld
, group
):
462 if not 'USING_BUILD_GROUPS' in bld
.env
:
465 Build
.BuildContext
.SET_BUILD_GROUP
= SET_BUILD_GROUP
468 def h_file(filename
):
470 st
= os
.stat(filename
)
471 if stat
.S_ISDIR(st
[stat
.ST_MODE
]): raise IOError('not a file')
473 m
.update(str(st
.st_mtime
))
474 m
.update(str(st
.st_size
))
479 def ENABLE_TIMESTAMP_DEPENDENCIES(conf
):
480 Utils
.h_file
= h_file
483 ##############################
484 # handle the creation of links for libraries and binaries
485 # note that we use a relative symlink path to allow the whole tree
486 # to me moved/copied elsewhere without breaking the links
487 t
= Task
.simple_task_type('symlink_lib', 'ln -sf ${LINK_SOURCE} ${LINK_TARGET}',
488 color
='PINK', ext_in
='.bin')
491 @feature('symlink_lib')
493 def symlink_lib(self
):
494 tsk
= self
.create_task('symlink_lib', self
.link_task
.outputs
[0])
496 # calculat the link target and put it in the environment
498 vnum
= getattr(self
, 'vnum', None)
500 soext
= '.' + vnum
.split('.')[0]
502 link_target
= getattr(self
, 'link_name', '')
503 if link_target
== '':
504 link_target
= '%s/lib%s.so%s' % (LIB_PATH
, self
.sname
, soext
)
507 link_source
= os_path_relpath(self
.link_task
.outputs
[0].abspath(self
.env
),
508 os
.path
.join(self
.env
.BUILD_DIRECTORY
, link_target
))
510 tsk
.env
.LINK_TARGET
= link_target
511 tsk
.env
.LINK_SOURCE
= link_source
[3:]
512 debug('task_gen: LINK for %s is %s -> %s',
513 self
.name
, tsk
.env
.LINK_SOURCE
, tsk
.env
.LINK_TARGET
)
516 t
= Task
.simple_task_type('symlink_bin', 'ln -sf ${SRC} ${BIN_TARGET}',
517 color
='PINK', ext_in
='.bin')
520 @feature('symlink_bin')
522 def symlink_bin(self
):
523 if Options
.is_install
:
524 # we don't want to copy the install binary, as
525 # that has the install rpath, not the build rpath
526 # The rpath of the binaries in bin/default/foo/blah is different
527 # during the install phase, as distros insist on not using rpath in installed binaries
529 tsk
= self
.create_task('symlink_bin', self
.link_task
.outputs
[0])
531 tsk
.env
.BIN_TARGET
= self
.target
532 debug('task_gen: BIN_TARGET for %s is %s', self
.name
, tsk
.env
.BIN_TARGET
)
537 t
= Task
.simple_task_type('copy_script', 'ln -sf ${SRC[0].abspath(env)} ${LINK_TARGET}',
538 color
='PINK', ext_in
='.bin', shell
=True)
541 @feature('copy_script')
542 @before('apply_link')
543 def copy_script(self
):
544 tsk
= self
.create_task('copy_script', self
.allnodes
[0])
545 tsk
.env
.TARGET
= self
.target
547 def SAMBA_SCRIPT(bld
, name
, pattern
, installdir
, installname
=None):
548 '''used to copy scripts from the source tree into the build directory
549 for use by selftest'''
551 source
= bld
.path
.ant_glob(pattern
)
553 bld
.SET_BUILD_GROUP('build_source')
554 for s
in TO_LIST(source
):
556 if installname
!= None:
558 target
= os
.path
.join(installdir
, iname
)
559 tgtdir
= os
.path
.dirname(os
.path
.join(bld
.srcnode
.abspath(bld
.env
), '..', target
))
561 t
= bld(features
='copy_script',
566 t
.env
.LINK_TARGET
= target
568 Build
.BuildContext
.SAMBA_SCRIPT
= SAMBA_SCRIPT