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
5 from Configure import conf
9 ####################################################
10 # some autoconf like helpers, to make the transition
11 # to waf a bit easier for those used to autoconf
14 def DEFUN(conf, d, v):
15 conf.define(d, v, quote=False)
16 conf.env.append_value('CCDEFINES', d + '=' + str(v))
19 def CHECK_HEADERS(conf, list):
20 for hdr in list.split():
21 if conf.check(header_name=hdr):
22 conf.env.hlist.append(hdr)
25 def CHECK_TYPES(conf, list):
26 for t in list.split():
27 conf.check(type_name=t, header_name=conf.env.hlist)
30 def CHECK_TYPE_IN(conf, t, hdr):
31 if conf.check(header_name=hdr):
32 conf.check(type_name=t, header_name=hdr)
35 def CHECK_TYPE(conf, t, alternate):
36 if not conf.check(type_name=t, header_name=conf.env.hlist):
37 conf.DEFUN(t, alternate)
40 def CHECK_FUNCS(conf, list):
41 for f in list.split():
42 conf.check(function_name=f, header_name=conf.env.hlist)
45 def CHECK_FUNCS_IN(conf, list, library):
46 if conf.check(lib=library, uselib_store=library):
47 for f in list.split():
48 conf.check(function_name=f, lib=library, header_name=conf.env.hlist)
49 conf.env['LIB_' + library.upper()] = library
51 #################################################
52 # write out config.h in the right directory
54 def SAMBA_CONFIG_H(conf, path='config.h'):
55 if os.path.normpath(conf.curdir) == os.path.normpath(os.environ.get('PWD')):
56 conf.write_config_header(path, top=True)
59 ##############################################################
60 # setup a configurable path
62 def CONFIG_PATH(conf, name, default):
63 if not name in conf.env:
64 conf.env[name] = conf.env['PREFIX'] + default
65 conf.define(name, conf.env[name], quote=True)
67 ##############################################################
68 # add some CFLAGS to the command line
70 def ADD_CFLAGS(conf, flags):
71 conf.env.append_value('CCFLAGS', flags.split())
74 ################################################################
75 # magic rpath handling
77 # we want a different rpath when installing and when building
78 # Note that this should really check if rpath is available on this platform
79 # and it should also honor an --enable-rpath option
82 if Options.is_install:
83 if bld.env['RPATH_ON_INSTALL']:
84 bld.env['RPATH'] = ['-Wl,-rpath=%s/lib' % bld.env.PREFIX]
88 rpath = os.path.normpath('%s/bin/%s' % (bld.curdir, LIB_PATH))
89 bld.env.append_value('RPATH', '-Wl,-rpath=%s' % rpath)
90 Build.BuildContext.set_rpath = set_rpath
92 #############################################################
94 def ASSERT(ctx, expression, msg):
96 sys.stderr.write("ERROR: %s\n" % msg)
98 Build.BuildContext.ASSERT = ASSERT
100 ################################################################
101 # create a list of files by pre-pending each with a subdir name
102 def SUBDIR(bld, subdir, list):
104 for l in list.split():
105 ret = ret + subdir + '/' + l + ' '
107 Build.BuildContext.SUBDIR = SUBDIR
109 #################################################################
110 # create the samba build environment
112 def SAMBA_BUILD_ENV(conf):
113 libpath="%s/%s" % (conf.blddir, LIB_PATH)
114 if not os.path.exists(libpath):
117 ##############################################
118 # remove .. elements from a path list
119 def NORMPATH(bld, ilist):
120 return " ".join([os.path.normpath(p) for p in ilist.split(" ")])
121 Build.BuildContext.NORMPATH = NORMPATH
123 ################################################################
124 # this will contain the set of includes needed per Samba library
125 Build.BuildContext.SAMBA_LIBRARY_INCLUDES = {}
127 ################################################################
128 # init function list for a subsystem
129 Build.BuildContext.SAMBA_INIT_FUNCTIONS = {}
131 ################################################################
132 # add an init_function to the list for a subsystem
133 def ADD_INIT_FUNCTION(bld, subsystem, init_function):
134 if init_function is None:
136 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
137 if not subsystem in bld.SAMBA_INIT_FUNCTIONS:
138 bld.SAMBA_INIT_FUNCTIONS[subsystem] = ''
139 bld.SAMBA_INIT_FUNCTIONS[subsystem] += '%s,' % init_function
140 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
143 #################################################################
144 # return a include list for a set of library dependencies
145 def SAMBA_LIBRARY_INCLUDE_LIST(bld, deps):
146 ret = bld.curdir + ' '
147 for l in deps.split():
148 if l in bld.SAMBA_LIBRARY_INCLUDES:
149 ret = ret + bld.SAMBA_LIBRARY_INCLUDES[l] + ' '
151 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
153 #################################################################
154 # define a Samba library
155 def SAMBA_LIBRARY(bld, libname, source_list,
161 ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
162 ilist = bld.NORMPATH(ilist)
164 features = 'cc cshlib',
165 source = source_list,
168 includes='. ' + os.environ.get('PWD') + '/bin/default ' + ilist,
171 # put a link to the library in bin/shared
174 soext = '.' + vnum.split('.')[0]
176 source = 'lib%s.so' % libname,
177 target = '%s.lnk' % libname,
178 rule = 'ln -sf ../${SRC}%s %s/lib%s.so%s && touch ${TGT}' %
179 (soext, LIB_PATH, libname, soext),
182 bld.SAMBA_LIBRARY_INCLUDES[libname] = ilist
183 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
186 #################################################################
187 # define a Samba binary
188 def SAMBA_BINARY(bld, binname, source_list,
196 ilist = '. ' + os.environ.get('PWD') + '/bin/default ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + ' ' + include_list
197 ilist = bld.NORMPATH(ilist)
200 if modules is not None:
201 for m in modules.split():
202 bld.ASSERT(m in bld.SAMBA_INIT_FUNCTIONS,
203 "No init_function defined for module '%s' in binary '%s'" % (m, binname))
204 modlist = bld.SAMBA_INIT_FUNCTIONS[m]
205 ccflags += ' -DSTATIC_%s_MODULES="%s"' % (m, modlist)
208 features = 'cc cprogram',
209 source = source_list,
216 # put a link to the binary in bin/
219 rule = 'ln -sf ${SRC} .',
221 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
224 #################################################################
225 # define a Samba python module
226 def SAMBA_PYTHON(bld, name, source_list,
230 Logs.debug('runner: PYTHON_SAMBA not implemented')
232 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
235 ################################################################
236 # build a C prototype file automatically
237 def AUTOPROTO(bld, header, source_list):
238 if header is not None:
240 source = source_list,
242 rule = '../script/mkproto.pl --srcdir=.. --builddir=. --public=/dev/null --private=${TGT} ${SRC}'
244 Build.BuildContext.AUTOPROTO = AUTOPROTO
247 #################################################################
248 # define a Samba module.
249 def SAMBA_MODULE(bld, modname, source_list,
258 bld.ADD_INIT_FUNCTION(subsystem, init_function)
259 bld.AUTOPROTO(autoproto, source_list)
260 bld.SAMBA_LIBRARY(modname, source_list,
261 deps=deps, include_list=include_list)
262 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
264 #################################################################
265 # define a Samba subsystem
266 def SAMBA_SUBSYSTEM(bld, modname, source_list,
272 init_function_sentinal=None):
273 bld.SAMBA_LIBRARY(modname, source_list,
274 deps=deps, include_list=include_list)
275 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
278 ############################################################
279 # this overrides the 'waf -v' debug output to be in a nice
280 # unix like format instead of a python list.
281 # Thanks to ita on #waf for this
282 def exec_command(self, cmd, **kw):
285 if isinstance(cmd, list):
287 Logs.debug('runner: %s' % _cmd)
289 self.log.write('%s\n' % cmd)
292 if not kw.get('cwd', None):
294 except AttributeError:
295 self.cwd = kw['cwd'] = self.bldnode.abspath()
296 return Utils.exec_command(cmd, **kw)
297 Build.BuildContext.exec_command = exec_command
300 ######################################################
301 # this is used as a decorator to make functions only
302 # run once. Based on the idea from
303 # http://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values
305 def runonce(function):
307 if args in runonce_ret:
308 return runonce_ret[args]
310 ret = function(*args)
311 runonce_ret[args] = ret