build: improve autoconf macros
[abartlet/samba.git/.git] / buildtools / wafsamba / samba_autoconf.py
1 # a waf tool to add autoconf-like macros to the configure section
2
3 import Build, os, Logs, sys, Configure, Options
4 import string, Task, Utils, optparse
5 from Configure import conf
6 from Logs import debug
7 from TaskGen import extension
8 from samba_utils import *
9
10 ####################################################
11 # some autoconf like helpers, to make the transition
12 # to waf a bit easier for those used to autoconf
13 # m4 files
14 @runonce
15 @conf
16 def DEFINE(conf, d, v):
17     conf.define(d, v, quote=False)
18     conf.env.append_value('CCDEFINES', d + '=' + str(v))
19
20 @runonce
21 def CHECK_HEADER(conf, h, add_headers=True):
22     if conf.check(header_name=h) and add_headers:
23         conf.env.hlist.append(h)
24         return True
25     return False
26
27 @conf
28 def CHECK_HEADERS(conf, list, add_headers=True):
29     ret = True
30     for hdr in list.split():
31         if not CHECK_HEADER(conf, hdr, add_headers):
32             ret = False
33     return ret
34
35 @conf
36 def CHECK_TYPES(conf, list):
37     ret = True
38     for t in list.split():
39         if not conf.check(type_name=t, header_name=conf.env.hlist):
40             ret = False
41     return ret
42
43 @conf
44 def CHECK_TYPE_IN(conf, t, hdr):
45     if conf.check(header_name=hdr):
46         conf.check(type_name=t, header_name=hdr)
47         return True
48     return False
49
50 @conf
51 def CHECK_TYPE(conf, t, alternate):
52     if not conf.check(type_name=t, header_name=conf.env.hlist):
53         conf.DEFINE(t, alternate)
54         return True
55     return False
56
57 @conf
58 def CHECK_VARIABLE(conf, v, define=None, always=False, headers=None):
59     hdrs=''
60     if headers is not None:
61         hlist = headers.split()
62     else:
63         hlist = conf.env.hlist
64     for h in hlist:
65         hdrs += '#include <%s>\n' % h
66     if define is None:
67         define = 'HAVE_%s' % v.upper()
68     if conf.check(fragment=
69                   '''
70                   %s
71                   int main(void) {
72                     #ifndef %s
73                     void *_x; _x=(void *)&%s;
74                     #endif
75                     return 0;
76                   }\n
77                   ''' % (hdrs, v, v),
78                   execute=0,
79                   msg="Checking for variable %s" % v):
80         conf.DEFINE(define, 1)
81         return True
82     elif always:
83         conf.DEFINE(define, 0)
84         return False
85
86 @conf
87 def CHECK_DECLS(conf, vars, reverse=False, headers=None):
88     '''check a list of variable declarations, using the HAVE_DECL_xxx form
89        of define
90
91        When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
92        '''
93     ret = True
94     for v in vars.split():
95         if not reverse:
96             define='HAVE_DECL_%s' % v.upper()
97         else:
98             define='HAVE_%s_DECL' % v.upper()
99         if not CHECK_VARIABLE(conf, v, define=define, headers=headers):
100             ret = False
101     return ret
102
103
104 @runonce
105 def CHECK_FUNC(conf, f):
106     return conf.check(function_name=f, header_name=conf.env.hlist)
107
108
109 @conf
110 def CHECK_FUNCS(conf, list):
111     ret = True
112     for f in list.split():
113         if not CHECK_FUNC(conf, f):
114             ret = False
115     return ret
116
117
118 #################################################
119 # return True if a configuration option was found
120 @conf
121 def CONFIG_SET(conf, option):
122     return (option in conf.env) and (conf.env[option] != ())
123 Build.BuildContext.CONFIG_SET = CONFIG_SET
124
125
126 ###########################################################
127 # check that the functions in 'list' are available in 'library'
128 # if they are, then make that library available as a dependency
129 #
130 # if the library is not available and mandatory==True, then
131 # raise an error.
132 #
133 # If the library is not available and mandatory==False, then
134 # add the library to the list of dependencies to remove from
135 # build rules
136 #
137 # optionally check for the functions first in libc
138 @conf
139 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False):
140     # first see if the functions are in libc
141     if checklibc:
142         remaining = []
143         for f in list.split():
144             if not CHECK_FUNC(conf, f):
145                 remaining.append(f)
146     else:
147         remaining = list.split()
148
149     if remaining == []:
150         LOCAL_CACHE_SET(conf, 'EMPTY_TARGETS', library.upper(), True)
151         return True
152
153     if not conf.check(lib=library, uselib_store=library):
154         conf.ASSERT(not mandatory,
155                     "Mandatory library '%s' not found for functions '%s'" % (library, list))
156         # if it isn't a mandatory library, then remove it from dependency lists
157         LOCAL_CACHE_SET(conf, 'EMPTY_TARGETS', library.upper(), True)
158         return False
159
160     ret = True
161     for f in remaining:
162         if not conf.check(function_name=f, lib=library, header_name=conf.env.hlist):
163             ret = False
164     conf.env['LIB_' + library.upper()] = library
165     LOCAL_CACHE_SET(conf, 'TARGET_TYPE', library, 'SYSLIB')
166     return ret
167
168
169 #################################################
170 # write out config.h in the right directory
171 @conf
172 def SAMBA_CONFIG_H(conf, path=None):
173     if os.path.normpath(conf.curdir) != os.path.normpath(os.environ.get('PWD')):
174         return
175     if path is None:
176         conf.write_config_header('config.h', top=True)
177     else:
178         conf.write_config_header(path)
179
180
181 ##############################################################
182 # setup a configurable path
183 @conf
184 def CONFIG_PATH(conf, name, default):
185     if not name in conf.env:
186         conf.env[name] = conf.env['PREFIX'] + default
187     conf.define(name, conf.env[name], quote=True)
188
189 ##############################################################
190 # add some CFLAGS to the command line
191 @conf
192 def ADD_CFLAGS(conf, flags):
193     if not 'EXTRA_CFLAGS' in conf.env:
194         conf.env['EXTRA_CFLAGS'] = []
195     conf.env['EXTRA_CFLAGS'].extend(flags.split())
196
197 ##############################################################
198 # add some extra include directories to all builds
199 @conf
200 def ADD_EXTRA_INCLUDES(conf, includes):
201     if not 'EXTRA_INCLUDES' in conf.env:
202         conf.env['EXTRA_INCLUDES'] = []
203     conf.env['EXTRA_INCLUDES'].extend(includes.split())
204
205
206 ##############################################################
207 # work out the current flags. local flags are added first
208 def CURRENT_CFLAGS(bld, cflags):
209     if not 'EXTRA_CFLAGS' in bld.env:
210         list = []
211     else:
212         list = bld.env['EXTRA_CFLAGS'];
213     ret = cflags.split()
214     ret.extend(list)
215     return ret