build: added autoproto stub
[nivanova/samba-autobuild/.git] / lib / replace / wafsamba.py
1 # a waf tool to add autoconf-like macros to the configure section
2 # and for SAMBA_ macros for building libraries, binaries etc
3
4 import Build, os, Logs, sys
5 from Configure import conf
6
7 LIB_PATH="shared"
8
9 ####################################################
10 # some autoconf like helpers, to make the transition
11 # to waf a bit easier for those used to autoconf
12 # m4 files
13 @conf
14 def DEFUN(conf, d, v):
15     conf.define(d, v, quote=False)
16     conf.env.append_value('CCDEFINES', d + '=' + str(v))
17
18 @conf
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)
23
24 @conf
25 def CHECK_TYPES(conf, list):
26     for t in list.split():
27         conf.check(type_name=t, header_name=conf.env.hlist)
28
29 @conf
30 def CHECK_TYPE_IN(conf, t, hdr):
31     if conf.check(header_name=hdr):
32         conf.check(type_name=t, header_name=hdr)
33
34 @conf
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)
38
39 @conf
40 def CHECK_FUNCS(conf, list):
41     for f in list.split():
42         conf.check(function_name=f, header_name=conf.env.hlist)
43
44 @conf
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
50
51 #################################################
52 # write out config.h in the right directory
53 @conf
54 def SAMBA_CONFIG_H(conf, path=None):
55     if os.path.normpath(conf.curdir) != os.path.normpath(os.environ.get('PWD')):
56         return
57     if path is None:
58         conf.write_config_header('config.h', top=True)
59     else:
60         conf.write_config_header(path)
61
62
63 ##############################################################
64 # setup a configurable path
65 @conf
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)
70
71 ##############################################################
72 # add some CFLAGS to the command line
73 @conf
74 def ADD_CFLAGS(conf, flags):
75     conf.env.append_value('CCFLAGS', flags.split())
76
77
78 ################################################################
79 # magic rpath handling
80 #
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
84 def set_rpath(bld):
85     import Options
86     if Options.is_install:
87         if bld.env['RPATH_ON_INSTALL']:
88             bld.env['RPATH'] = ['-Wl,-rpath=%s/lib' % bld.env.PREFIX]
89         else:
90             bld.env['RPATH'] = []
91     else:
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
95
96 #############################################################
97 # a build assert call
98 def ASSERT(ctx, expression, msg):
99     if not expression:
100         sys.stderr.write("ERROR: %s\n" % msg)
101         raise AssertionError
102 Build.BuildContext.ASSERT = ASSERT
103
104 ################################################################
105 # create a list of files by pre-pending each with a subdir name
106 def SUBDIR(bld, subdir, list):
107     ret = ''
108     for l in list.split():
109         ret = ret + subdir + '/' + l + ' '
110     return ret
111 Build.BuildContext.SUBDIR = SUBDIR
112
113 #################################################################
114 # create the samba build environment
115 @conf
116 def SAMBA_BUILD_ENV(conf):
117     libpath="%s/%s" % (conf.blddir, LIB_PATH)
118     if not os.path.exists(libpath):
119         os.mkdir(libpath)
120
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
126
127 ################################################################
128 # this will contain the set of includes needed per Samba library
129 Build.BuildContext.SAMBA_LIBRARY_INCLUDES = {}
130
131 ################################################################
132 # init function list for a subsystem
133 Build.BuildContext.SAMBA_INIT_FUNCTIONS = {}
134
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:
139         return
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
145
146
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] + ' '
154     return ret
155 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
156
157 #################################################################
158 # define a Samba library
159 def SAMBA_LIBRARY(bld, libname, source_list,
160                   deps='',
161                   public_deps='',
162                   include_list='.',
163                   vnum=None,
164                   cflags=None,
165                   autoproto=None):
166     ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + bld.SUBDIR(bld.curdir, include_list)
167     ilist = bld.NORMPATH(ilist)
168     bld(
169         features = 'cc cshlib',
170         source = source_list,
171         target=libname,
172         uselib_local = deps,
173         includes='. ' + os.environ.get('PWD') + '/bin/default ' + ilist,
174         vnum=vnum)
175
176     # put a link to the library in bin/shared
177     soext=""
178     if vnum is not None:
179         soext = '.' + vnum.split('.')[0]
180     bld(
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),
185         shell = True
186         )
187     bld.SAMBA_LIBRARY_INCLUDES[libname] = ilist
188 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
189
190
191 #################################################################
192 # define a Samba binary
193 def SAMBA_BINARY(bld, binname, source_list,
194                  deps='',
195                  syslibs='',
196                  include_list='',
197                  modules=None,
198                  installdir=None,
199                  ldflags=None,
200                  cflags=None,
201                  autoproto=None):
202     ilist = '. ' + os.environ.get('PWD') + '/bin/default ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(deps) + ' ' + include_list
203     ilist = bld.NORMPATH(ilist)
204     ccflags = ''
205
206     if modules is not None:
207         for m in modules.split():
208             bld.ASSERT(m in bld.SAMBA_INIT_FUNCTIONS,
209                        "No init_function defined for module '%s' in binary '%s'" % (m, binname))
210             modlist = bld.SAMBA_INIT_FUNCTIONS[m]
211             ccflags += ' -DSTATIC_%s_MODULES="%s"' % (m, modlist)
212
213     bld(
214         features = 'cc cprogram',
215         source = source_list,
216         target = binname,
217         uselib_local = deps,
218         uselib = syslibs,
219         includes = ilist,
220         ccflags = ccflags,
221         top=True)
222     # put a link to the binary in bin/
223     bld(
224         source = binname,
225         rule = 'ln -sf ${SRC} .',
226         )
227 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
228
229
230 #################################################################
231 # define a Samba python module
232 def SAMBA_PYTHON(bld, name, source_list,
233                  deps='',
234                  public_deps='',
235                  realname=''):
236     Logs.debug('runner: PYTHON_SAMBA not implemented')
237     return
238 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
239
240
241 ################################################################
242 # build a C prototype file automatically
243 def AUTOPROTO(bld, header, source_list):
244     if header is not None:
245         bld(
246             source = source_list,
247             target = header,
248             rule = '../script/mkproto.pl --srcdir=.. --builddir=. --public=/dev/null --private=${TGT} ${SRC}'
249             )
250 Build.BuildContext.AUTOPROTO = AUTOPROTO
251
252
253 #################################################################
254 # define a Samba module.
255 def SAMBA_MODULE(bld, modname, source_list,
256                  deps='',
257                  include_list='.',
258                  subsystem=None,
259                  init_function=None,
260                  autoproto=None,
261                  aliases=None,
262                  cflags=None,
263                  output_type=None):
264     bld.ADD_INIT_FUNCTION(subsystem, init_function)
265     bld.AUTOPROTO(autoproto, source_list)
266     bld.SAMBA_LIBRARY(modname, source_list,
267                       deps=deps, include_list=include_list)
268 Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE
269
270 #################################################################
271 # define a Samba subsystem
272 def SAMBA_SUBSYSTEM(bld, modname, source_list,
273                     deps='',
274                     public_deps='',
275                     include_list='.',
276                     autoproto=None,
277                     cflags=None,
278                     init_function_sentinal=None):
279     bld.SAMBA_LIBRARY(modname, source_list,
280                       deps=deps, include_list=include_list)
281 Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM
282
283
284 ############################################################
285 # this overrides the 'waf -v' debug output to be in a nice
286 # unix like format instead of a python list.
287 # Thanks to ita on #waf for this
288 def exec_command(self, cmd, **kw):
289     import Utils, Logs
290     _cmd = cmd
291     if isinstance(cmd, list):
292         _cmd = ' '.join(cmd)
293     Logs.debug('runner: %s' % _cmd)
294     if self.log:
295         self.log.write('%s\n' % cmd)
296         kw['log'] = self.log
297     try:
298         if not kw.get('cwd', None):
299             kw['cwd'] = self.cwd
300     except AttributeError:
301         self.cwd = kw['cwd'] = self.bldnode.abspath()
302     return Utils.exec_command(cmd, **kw)
303 Build.BuildContext.exec_command = exec_command
304
305
306 ######################################################
307 # this is used as a decorator to make functions only
308 # run once. Based on the idea from
309 # http://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values
310 runonce_ret = {}
311 def runonce(function):
312     def wrapper(*args):
313         if args in runonce_ret:
314             return runonce_ret[args]
315         else:
316             ret = function(*args)
317             runonce_ret[args] = ret
318             return ret
319     return wrapper