b01f4ec4f8cc971f8c02b4d1330b1b0581fc004b
[samba.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
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):
55     if os.path.normpath(conf.curdir) == os.path.normpath(os.environ.get('PWD')):
56         conf.write_config_header('config.h', top=True)
57
58
59 ##############################################################
60 # setup a configurable path
61 @conf
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)
66
67
68 ################################################################
69 # magic rpath handling
70 #
71 # we want a different rpath when installing and when building
72 # Note that this should really check if rpath is available on this platform
73 # and it should also honor an --enable-rpath option
74 def set_rpath(bld):
75     import Options
76     if Options.is_install:
77         bld.env['RPATH'] = ['-Wl,-rpath=%s/%s' % (bld.env.PREFIX, LIB_PATH)]
78     else:
79         bld.env.append_value('RPATH', '-Wl,-rpath=bin/%s' % LIB_PATH)
80 Build.BuildContext.set_rpath = set_rpath
81
82
83 ################################################################
84 # create a list of files by pre-pending each with a subdir name
85 def SUBDIR(bld, subdir, list):
86     ret = ''
87     for l in list.split():
88         ret = ret + subdir + '/' + l + ' '
89     return ret
90 Build.BuildContext.SUBDIR = SUBDIR
91
92 #################################################################
93 # create the samba build environment
94 @conf
95 def SAMBA_BUILD_ENV(conf):
96     libpath="%s/%s" % (conf.blddir, LIB_PATH)
97     if not os.path.exists(libpath):
98         os.mkdir(libpath)
99
100
101 ################################################################
102 # this will contain the set of includes needed per Samba library
103 Build.BuildContext.SAMBA_LIBRARY_INCLUDES = {}
104
105 #################################################################
106 # return a include list for a set of library dependencies
107 def SAMBA_LIBRARY_INCLUDE_LIST(bld, libdeps):
108     ret = bld.curdir + ' '
109     for l in libdeps.split():
110         if l in bld.SAMBA_LIBRARY_INCLUDES:
111             ret = ret + bld.SAMBA_LIBRARY_INCLUDES[l] + ' '
112     return ret
113 Build.BuildContext.SAMBA_LIBRARY_INCLUDE_LIST = SAMBA_LIBRARY_INCLUDE_LIST
114
115 #################################################################
116 # define a Samba library
117 def SAMBA_LIBRARY(bld, libname, source_list,
118                   libdeps='', include_list='.', vnum=None):
119     ilist = bld.SAMBA_LIBRARY_INCLUDE_LIST(libdeps) + bld.SUBDIR(bld.curdir, include_list)
120     bld(
121         features = 'cc cshlib',
122         source = source_list,
123         target=libname,
124         uselib_local = libdeps,
125         includes='. ' + os.environ.get('PWD') + '/bin/default ' + ilist,
126         vnum=vnum)
127
128     # put a link to the library in bin/shared
129     soext=""
130     if vnum is not None:
131         soext = '.' + vnum.split('.')[0]
132     bld(
133         source = 'lib%s.so' % libname,
134         target = '%s.lnk' % libname,
135         rule = 'ln -sf ../${SRC}%s %s/lib%s.so%s && touch ${TGT}' %
136         (soext, LIB_PATH, libname, soext),
137         shell = True
138         )
139     bld.SAMBA_LIBRARY_INCLUDES[libname] = ilist
140 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
141
142 #################################################################
143 # define a Samba binary
144 def SAMBA_BINARY(bld, binname, source_list, libdeps='', syslibs='', include_list=''):
145     bld(
146         features = 'cc cprogram',
147         source = source_list,
148         target = binname,
149         uselib_local = libdeps,
150         uselib = syslibs,
151         includes = '. ' + os.environ.get('PWD') + '/bin/default ' + bld.SAMBA_LIBRARY_INCLUDE_LIST(libdeps) + include_list,
152         top=True)
153     # put a link to the binary in bin/
154     bld(
155         source = binname,
156         rule = 'ln -sf ${SRC} .',
157         )
158
159 Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY
160
161 ############################################################
162 # this overrides the 'waf -v' debug output to be in a nice
163 # unix like format instead of a python list.
164 # Thanks to ita on #waf for this
165 def exec_command(self, cmd, **kw):
166     import Utils, Logs
167     _cmd = cmd
168     if isinstance(cmd, list):
169         _cmd = ' '.join(cmd)
170     Logs.debug('runner: %s' % _cmd)
171     if self.log:
172         self.log.write('%s\n' % cmd)
173         kw['log'] = self.log
174     try:
175         if not kw.get('cwd', None):
176             kw['cwd'] = self.cwd
177     except AttributeError:
178         self.cwd = kw['cwd'] = self.bldnode.abspath()
179     return Utils.exec_command(cmd, **kw)
180 Build.BuildContext.exec_command = exec_command
181
182
183 ######################################################
184 # this is used as a decorator to make functions only
185 # run once. Based on the idea from
186 # http://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values
187 runonce_ret = {}
188 def runonce(function):
189     def wrapper(*args):
190         if args in runonce_ret:
191             return runonce_ret[args]
192         else:
193             ret = function(*args)
194             runonce_ret[args] = ret
195             return ret
196     return wrapper