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, Logs, sys, Configure, Options
5 from Configure import conf
9 ######################################################
10 # this is used as a decorator to make functions only
11 # run once. Based on the idea from
12 # http://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values
14 def runonce(function):
16 if args in runonce_ret:
17 return runonce_ret[args]
20 runonce_ret[args] = ret
25 ####################################################
26 # some autoconf like helpers, to make the transition
27 # to waf a bit easier for those used to autoconf
31 def DEFUN(conf, d, v):
32 conf.define(d, v, quote=False)
33 conf.env.append_value('CCDEFINES', d + '=' + str(v))
36 def CHECK_HEADER(conf, h):
37 if conf.check(header_name=h):
38 conf.env.hlist.append(h)
41 def CHECK_HEADERS(conf, list):
42 for hdr in list.split():
43 CHECK_HEADER(conf, hdr)
46 def CHECK_TYPES(conf, list):
47 for t in list.split():
48 conf.check(type_name=t, header_name=conf.env.hlist)
51 def CHECK_TYPE_IN(conf, t, hdr):
52 if conf.check(header_name=hdr):
53 conf.check(type_name=t, header_name=hdr)
56 def CHECK_TYPE(conf, t, alternate):
57 if not conf.check(type_name=t, header_name=conf.env.hlist):
58 conf.DEFUN(t, alternate)
61 def CHECK_FUNC(conf, f):
62 conf.check(function_name=f, header_name=conf.env.hlist)
66 def CHECK_FUNCS(conf, list):
67 for f in list.split():
71 def CHECK_FUNCS_IN(conf, list, library):
72 if conf.check(lib=library, uselib_store=library):
73 for f in list.split():
74 conf.check(function_name=f, lib=library, header_name=conf.env.hlist)
75 conf.env['LIB_' + library.upper()] = library
78 #################################################
79 # write out config.h in the right directory
81 def SAMBA_CONFIG_H(conf, path=None):
82 if os.path.normpath(conf.curdir) != os.path.normpath(os.environ.get('PWD')):
85 conf.write_config_header('config.h', top=True)
87 conf.write_config_header(path)
90 ##############################################################
91 # setup a configurable path
93 def CONFIG_PATH(conf, name, default):
94 if not name in conf.env:
95 conf.env[name] = conf.env['PREFIX'] + default
96 conf.define(name, conf.env[name], quote=True)
98 ##############################################################
99 # add some CFLAGS to the command line
101 def ADD_CFLAGS(conf, flags):
102 conf.env.append_value('CCFLAGS', flags.split())
105 ################################################################
106 # magic rpath handling
108 # we want a different rpath when installing and when building
109 # Note that this should really check if rpath is available on this platform
110 # and it should also honor an --enable-rpath option
112 if Options.is_install:
113 if bld.env['RPATH_ON_INSTALL']:
114 bld.env['RPATH'] = ['-Wl,-rpath=%s/lib' % bld.env.PREFIX]
116 bld.env['RPATH'] = []
118 rpath = os.path.normpath('%s/bin/%s' % (bld.curdir, LIB_PATH))
119 bld.env.append_value('RPATH', '-Wl,-rpath=%s' % rpath)
120 Build.BuildContext.set_rpath = set_rpath
122 #############################################################
123 # a build assert call
124 def ASSERT(ctx, expression, msg):
126 sys.stderr.write("ERROR: %s\n" % msg)
128 Build.BuildContext.ASSERT = ASSERT
130 ################################################################
131 # create a list of files by pre-pending each with a subdir name
132 def SUBDIR(bld, subdir, list):
134 for l in list.split():
135 ret = ret + subdir + '/' + l + ' '
137 Build.BuildContext.SUBDIR = SUBDIR
139 #################################################################
140 # create the samba build environment
142 def SAMBA_BUILD_ENV(conf):
143 libpath="%s/%s" % (conf.blddir, LIB_PATH)
144 if not os.path.exists(libpath):
147 ##############################################
148 # remove .. elements from a path list
149 def NORMPATH(bld, ilist):
150 return " ".join([os.path.normpath(p) for p in ilist.split(" ")])
151 Build.BuildContext.NORMPATH = NORMPATH
153 ################################################################
154 # this will contain the set of includes needed per Samba library
155 Build.BuildContext.SAMBA_LIBRARY_INCLUDES = {}
157 ################################################################
158 # init function list for a subsystem
159 Build.BuildContext.SAMBA_INIT_FUNCTIONS = {}
161 ################################################################
162 # add an init_function to the list for a subsystem
163 def ADD_INIT_FUNCTION(bld, subsystem, init_function):
164 if init_function is None:
166 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
167 if not subsystem in bld.SAMBA_INIT_FUNCTIONS:
168 bld.SAMBA_INIT_FUNCTIONS[subsystem] = ''
169 bld.SAMBA_INIT_FUNCTIONS[subsystem] += '%s,' % init_function
170 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
173 #################################################################
174 # return a include list for a set of library dependencies
175 def SAMBA_LIBRARY_INCLUDE_LIST(bld, deps):
176 ret = bld.curdir + ' '
177 for l in deps.split():
178 if l in bld.SAMBA_LIBRARY_INCLUDES:
179 ret = ret + bld.SAMBA_LIBRARY_INCLUDES[l] + ' '
181 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
183 #################################################################
184 # define a Samba library
185 def SAMBA_LIBRARY(bld, libname, source_list,
193 # print "Declaring SAMBA_LIBRARY %s" % libname
194 ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
195 ilist = bld.NORMPATH(ilist)
197 features = 'cc cshlib',
198 source = source_list,
201 includes='. ' + os.environ.get('PWD') + '/bin/default ' + ilist,
204 # put a link to the library in bin/shared
207 soext = '.' + vnum.split('.')[0]
209 source = 'lib%s.so' % libname,
210 target = '%s.lnk' % libname,
211 rule = 'ln -sf ../${SRC}%s %s/lib%s.so%s && touch ${TGT}' %
212 (soext, LIB_PATH, libname, soext),
215 bld.SAMBA_LIBRARY_INCLUDES[libname] = ilist
216 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
219 #################################################################
220 # define a Samba binary
221 def SAMBA_BINARY(bld, binname, source_list,
232 ilist = '. ' + os.environ.get('PWD') + '/bin/default ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + ' ' + include_list
233 ilist = bld.NORMPATH(ilist)
236 if modules is not None:
237 for m in modules.split():
238 bld.ASSERT(m in bld.SAMBA_INIT_FUNCTIONS,
239 "No init_function defined for module '%s' in binary '%s'" % (m, binname))
240 modlist = bld.SAMBA_INIT_FUNCTIONS[m]
241 ccflags += ' -DSTATIC_%s_MODULES="%s"' % (m, modlist)
244 features = 'cc cprogram',
245 source = source_list,
252 # put a link to the binary in bin/
255 rule = 'ln -sf ${SRC} .',
257 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
260 #################################################################
261 # define a Samba python module
262 def SAMBA_PYTHON(bld, name, source_list,
266 Logs.debug('runner: PYTHON_SAMBA not implemented')
268 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
271 ################################################################
272 # build a C prototype file automatically
273 def AUTOPROTO(bld, header, source_list):
274 if header is not None:
276 source = source_list,
278 rule = '../script/mkproto.pl --srcdir=.. --builddir=. --public=/dev/null --private=${TGT} ${SRC}'
280 Build.BuildContext.AUTOPROTO = AUTOPROTO
283 #################################################################
284 # define a Samba module.
285 def SAMBA_MODULE(bld, modname, source_list,
294 bld.ADD_INIT_FUNCTION(subsystem, init_function)
295 bld.AUTOPROTO(autoproto, source_list)
296 bld.SAMBA_LIBRARY(modname, source_list,
297 deps=deps, include_list=include_list)
298 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
300 #################################################################
301 # define a Samba subsystem
302 def SAMBA_SUBSYSTEM(bld, modname, source_list,
309 init_function_sentinal=None):
310 bld.SAMBA_LIBRARY(modname, source_list,
311 deps=deps, include_list=include_list)
312 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
315 ###############################################################
316 # add a new set of build rules from a subdirectory
317 def BUILD_SUBDIR(bld, dir):
319 cache = bld.cache_build_subdirs
320 except AttributeError:
321 bld.cache_build_subdirs = cache = {}
322 abs_dir=os.path.normpath(bld.curdir + '/' + dir)
325 cache[abs_dir] = True
327 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
330 ############################################################
331 # this overrides the 'waf -v' debug output to be in a nice
332 # unix like format instead of a python list.
333 # Thanks to ita on #waf for this
334 def exec_command(self, cmd, **kw):
337 if isinstance(cmd, list):
339 Logs.debug('runner: %s' % _cmd)
341 self.log.write('%s\n' % cmd)
344 if not kw.get('cwd', None):
346 except AttributeError:
347 self.cwd = kw['cwd'] = self.bldnode.abspath()
348 return Utils.exec_command(cmd, **kw)
349 Build.BuildContext.exec_command = exec_command