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=None):
55 if os.path.normpath(conf.curdir) != os.path.normpath(os.environ.get('PWD')):
58 conf.write_config_header('config.h', top=True)
60 conf.write_config_header(path)
63 ##############################################################
64 # setup a configurable path
66 def CONFIG_PATH(conf, name, default):
67 if not name in conf.env:
68 conf.env[name] = conf.env['PREFIX'] + default
69 conf.define(name, conf.env[name], quote=True)
71 ##############################################################
72 # add some CFLAGS to the command line
74 def ADD_CFLAGS(conf, flags):
75 conf.env.append_value('CCFLAGS', flags.split())
78 ################################################################
79 # magic rpath handling
81 # we want a different rpath when installing and when building
82 # Note that this should really check if rpath is available on this platform
83 # and it should also honor an --enable-rpath option
86 if Options.is_install:
87 if bld.env['RPATH_ON_INSTALL']:
88 bld.env['RPATH'] = ['-Wl,-rpath=%s/lib' % bld.env.PREFIX]
92 rpath = os.path.normpath('%s/bin/%s' % (bld.curdir, LIB_PATH))
93 bld.env.append_value('RPATH', '-Wl,-rpath=%s' % rpath)
94 Build.BuildContext.set_rpath = set_rpath
96 #############################################################
98 def ASSERT(ctx, expression, msg):
100 sys.stderr.write("ERROR: %s\n" % msg)
102 Build.BuildContext.ASSERT = ASSERT
104 ################################################################
105 # create a list of files by pre-pending each with a subdir name
106 def SUBDIR(bld, subdir, list):
108 for l in list.split():
109 ret = ret + subdir + '/' + l + ' '
111 Build.BuildContext.SUBDIR = SUBDIR
113 #################################################################
114 # create the samba build environment
116 def SAMBA_BUILD_ENV(conf):
117 libpath="%s/%s" % (conf.blddir, LIB_PATH)
118 if not os.path.exists(libpath):
121 ##############################################
122 # remove .. elements from a path list
123 def NORMPATH(bld, ilist):
124 return " ".join([os.path.normpath(p) for p in ilist.split(" ")])
125 Build.BuildContext.NORMPATH = NORMPATH
127 ################################################################
128 # this will contain the set of includes needed per Samba library
129 Build.BuildContext.SAMBA_LIBRARY_INCLUDES = {}
131 ################################################################
132 # init function list for a subsystem
133 Build.BuildContext.SAMBA_INIT_FUNCTIONS = {}
135 ################################################################
136 # add an init_function to the list for a subsystem
137 def ADD_INIT_FUNCTION(bld, subsystem, init_function):
138 if init_function is None:
140 bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function)
141 if not subsystem in bld.SAMBA_INIT_FUNCTIONS:
142 bld.SAMBA_INIT_FUNCTIONS[subsystem] = ''
143 bld.SAMBA_INIT_FUNCTIONS[subsystem] += '%s,' % init_function
144 Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION
147 #################################################################
148 # return a include list for a set of library dependencies
149 def SAMBA_LIBRARY_INCLUDE_LIST(bld, deps):
150 ret = bld.curdir + ' '
151 for l in deps.split():
152 if l in bld.SAMBA_LIBRARY_INCLUDES:
153 ret = ret + bld.SAMBA_LIBRARY_INCLUDES[l] + ' '
155 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
157 #################################################################
158 # define a Samba library
159 def SAMBA_LIBRARY(bld, libname, source_list,
166 ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
167 ilist = bld.NORMPATH(ilist)
169 features = 'cc cshlib',
170 source = source_list,
173 includes='. ' + os.environ.get('PWD') + '/bin/default ' + ilist,
176 # put a link to the library in bin/shared
179 soext = '.' + vnum.split('.')[0]
181 source = 'lib%s.so' % libname,
182 target = '%s.lnk' % libname,
183 rule = 'ln -sf ../${SRC}%s %s/lib%s.so%s && touch ${TGT}' %
184 (soext, LIB_PATH, libname, soext),
187 bld.SAMBA_LIBRARY_INCLUDES[libname] = ilist
188 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
191 #################################################################
192 # define a Samba binary
193 def SAMBA_BINARY(bld, binname, source_list,
203 ilist = '. ' + os.environ.get('PWD') + '/bin/default ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + ' ' + include_list
204 ilist = bld.NORMPATH(ilist)
207 if modules is not None:
208 for m in modules.split():
209 bld.ASSERT(m in bld.SAMBA_INIT_FUNCTIONS,
210 "No init_function defined for module '%s' in binary '%s'" % (m, binname))
211 modlist = bld.SAMBA_INIT_FUNCTIONS[m]
212 ccflags += ' -DSTATIC_%s_MODULES="%s"' % (m, modlist)
215 features = 'cc cprogram',
216 source = source_list,
223 # put a link to the binary in bin/
226 rule = 'ln -sf ${SRC} .',
228 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
231 #################################################################
232 # define a Samba python module
233 def SAMBA_PYTHON(bld, name, source_list,
237 Logs.debug('runner: PYTHON_SAMBA not implemented')
239 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
242 ################################################################
243 # build a C prototype file automatically
244 def AUTOPROTO(bld, header, source_list):
245 if header is not None:
247 source = source_list,
249 rule = '../script/mkproto.pl --srcdir=.. --builddir=. --public=/dev/null --private=${TGT} ${SRC}'
251 Build.BuildContext.AUTOPROTO = AUTOPROTO
254 #################################################################
255 # define a Samba module.
256 def SAMBA_MODULE(bld, modname, source_list,
265 bld.ADD_INIT_FUNCTION(subsystem, init_function)
266 bld.AUTOPROTO(autoproto, source_list)
267 bld.SAMBA_LIBRARY(modname, source_list,
268 deps=deps, include_list=include_list)
269 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
271 #################################################################
272 # define a Samba subsystem
273 def SAMBA_SUBSYSTEM(bld, modname, source_list,
279 init_function_sentinal=None):
280 bld.SAMBA_LIBRARY(modname, source_list,
281 deps=deps, include_list=include_list)
282 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
285 ############################################################
286 # this overrides the 'waf -v' debug output to be in a nice
287 # unix like format instead of a python list.
288 # Thanks to ita on #waf for this
289 def exec_command(self, cmd, **kw):
292 if isinstance(cmd, list):
294 Logs.debug('runner: %s' % _cmd)
296 self.log.write('%s\n' % cmd)
299 if not kw.get('cwd', None):
301 except AttributeError:
302 self.cwd = kw['cwd'] = self.bldnode.abspath()
303 return Utils.exec_command(cmd, **kw)
304 Build.BuildContext.exec_command = exec_command
307 ######################################################
308 # this is used as a decorator to make functions only
309 # run once. Based on the idea from
310 # http://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values
312 def runonce(function):
314 if args in runonce_ret:
315 return runonce_ret[args]
317 ret = function(*args)
318 runonce_ret[args] = ret