~ubuntu-branches/ubuntu/wily/samba/wily

« back to all changes in this revision

Viewing changes to buildtools/wafadmin/Tools/config_c.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-05-15 17:00:56 UTC
  • mfrom: (178.1.1 precise-security) (0.39.27 sid)
  • Revision ID: package-import@ubuntu.com-20120515170056-gludtas4257eb61q
Tags: 2:3.6.5-2ubuntu1
* Merge from Debian unstable, remaining changes: 
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Other changes now in Debian packaging.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.install: install profile.
    - debian/control: have samba suggest ufw.
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba-common-bin.install: install hook.
  + Switch to upstart:
    - Added debian/samba.{nmbd,smbd}.upstart.
    - debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
      Make upstart compatible.
* d/samba.install, d/samba-common-bin.install: Restore apport hook and ufw
  profile (LP: #999764).
* Dropped:
  + debian/patches/CVE-2012-1182-*.patch: fixed in upstream release 3.6.4.
  + debian/patches/CVE-2012-2111.patch: fixed in upstream release 3.6.5.
  + debian/patches/fix-debuglevel-name-conflict.patch: fixed upstream -
    debug_level is no longer used as a global variable name.
  + debian/patches/error-trans.fix-276472: fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# encoding: utf-8
 
3
# Thomas Nagy, 2005-2008 (ita)
 
4
 
 
5
"""
 
6
c/c++ configuration routines
 
7
"""
 
8
 
 
9
import os, imp, sys, shlex, shutil
 
10
from Utils import md5
 
11
import Build, Utils, Configure, Task, Options, Logs, TaskGen
 
12
from Constants import *
 
13
from Configure import conf, conftest
 
14
 
 
15
cfg_ver = {
 
16
        'atleast-version': '>=',
 
17
        'exact-version': '==',
 
18
        'max-version': '<=',
 
19
}
 
20
 
 
21
SNIP1 = '''
 
22
        int main() {
 
23
        void *p;
 
24
        p=(void*)(%s);
 
25
        return 0;
 
26
}
 
27
'''
 
28
 
 
29
SNIP2 = '''
 
30
int main() {
 
31
        if ((%(type_name)s *) 0) return 0;
 
32
        if (sizeof (%(type_name)s)) return 0;
 
33
}
 
34
'''
 
35
 
 
36
SNIP3 = '''
 
37
int main() {
 
38
        return 0;
 
39
}
 
40
'''
 
41
 
 
42
def parse_flags(line, uselib, env):
 
43
        """pkg-config still has bugs on some platforms, and there are many -config programs, parsing flags is necessary :-/"""
 
44
 
 
45
        lst = shlex.split(line)
 
46
        while lst:
 
47
                x = lst.pop(0)
 
48
                st = x[:2]
 
49
                ot = x[2:]
 
50
                app = env.append_value
 
51
                if st == '-I' or st == '/I':
 
52
                        if not ot: ot = lst.pop(0)
 
53
                        app('CPPPATH_' + uselib, ot)
 
54
                elif st == '-D':
 
55
                        if not ot: ot = lst.pop(0)
 
56
                        app('CXXDEFINES_' + uselib, ot)
 
57
                        app('CCDEFINES_' + uselib, ot)
 
58
                elif st == '-l':
 
59
                        if not ot: ot = lst.pop(0)
 
60
                        app('LIB_' + uselib, ot)
 
61
                elif st == '-L':
 
62
                        if not ot: ot = lst.pop(0)
 
63
                        app('LIBPATH_' + uselib, ot)
 
64
                elif x == '-pthread' or x.startswith('+'):
 
65
                        app('CCFLAGS_' + uselib, x)
 
66
                        app('CXXFLAGS_' + uselib, x)
 
67
                        app('LINKFLAGS_' + uselib, x)
 
68
                elif x == '-framework':
 
69
                        app('FRAMEWORK_' + uselib, lst.pop(0))
 
70
                elif x.startswith('-F'):
 
71
                        app('FRAMEWORKPATH_' + uselib, x[2:])
 
72
                elif x.startswith('-std'):
 
73
                        app('CCFLAGS_' + uselib, x)
 
74
                        app('CXXFLAGS_' + uselib, x)
 
75
                        app('LINKFLAGS_' + uselib, x)
 
76
                elif x.startswith('-Wl'):
 
77
                        app('LINKFLAGS_' + uselib, x)
 
78
                elif x.startswith('-m') or x.startswith('-f'):
 
79
                        app('CCFLAGS_' + uselib, x)
 
80
                        app('CXXFLAGS_' + uselib, x)
 
81
 
 
82
@conf
 
83
def ret_msg(self, f, kw):
 
84
        """execute a function, when provided"""
 
85
        if isinstance(f, str):
 
86
                return f
 
87
        return f(kw)
 
88
 
 
89
@conf
 
90
def validate_cfg(self, kw):
 
91
        if not 'path' in kw:
 
92
                kw['path'] = 'pkg-config --errors-to-stdout --print-errors'
 
93
 
 
94
        # pkg-config version
 
95
        if 'atleast_pkgconfig_version' in kw:
 
96
                if not 'msg' in kw:
 
97
                        kw['msg'] = 'Checking for pkg-config version >= %s' % kw['atleast_pkgconfig_version']
 
98
                return
 
99
 
 
100
        # pkg-config --modversion
 
101
        if 'modversion' in kw:
 
102
                return
 
103
 
 
104
        if 'variables' in kw:
 
105
                if not 'msg' in kw:
 
106
                        kw['msg'] = 'Checking for %s variables' % kw['package']
 
107
                return
 
108
 
 
109
        # checking for the version of a module, for the moment, one thing at a time
 
110
        for x in cfg_ver.keys():
 
111
                y = x.replace('-', '_')
 
112
                if y in kw:
 
113
                        if not 'package' in kw:
 
114
                                raise ValueError('%s requires a package' % x)
 
115
 
 
116
                        if not 'msg' in kw:
 
117
                                kw['msg'] = 'Checking for %s %s %s' % (kw['package'], cfg_ver[x], kw[y])
 
118
                        return
 
119
 
 
120
        if not 'msg' in kw:
 
121
                kw['msg'] = 'Checking for %s' % (kw['package'] or kw['path'])
 
122
        if not 'okmsg' in kw:
 
123
                kw['okmsg'] = 'yes'
 
124
        if not 'errmsg' in kw:
 
125
                kw['errmsg'] = 'not found'
 
126
 
 
127
@conf
 
128
def cmd_and_log(self, cmd, kw):
 
129
        Logs.debug('runner: %s\n' % cmd)
 
130
        if self.log:
 
131
                self.log.write('%s\n' % cmd)
 
132
 
 
133
        try:
 
134
                p = Utils.pproc.Popen(cmd, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE, shell=True)
 
135
                (out, err) = p.communicate()
 
136
        except OSError, e:
 
137
                self.log.write('error %r' % e)
 
138
                self.fatal(str(e))
 
139
 
 
140
        # placeholder, don't touch
 
141
        out = str(out)
 
142
        err = str(err)
 
143
 
 
144
        if self.log:
 
145
                self.log.write(out)
 
146
                self.log.write(err)
 
147
 
 
148
        if p.returncode:
 
149
                if not kw.get('errmsg', ''):
 
150
                        if kw.get('mandatory', False):
 
151
                                kw['errmsg'] = out.strip()
 
152
                        else:
 
153
                                kw['errmsg'] = 'no'
 
154
                self.fatal('fail')
 
155
        return out
 
156
 
 
157
@conf
 
158
def exec_cfg(self, kw):
 
159
 
 
160
        # pkg-config version
 
161
        if 'atleast_pkgconfig_version' in kw:
 
162
                cmd = '%s --atleast-pkgconfig-version=%s' % (kw['path'], kw['atleast_pkgconfig_version'])
 
163
                self.cmd_and_log(cmd, kw)
 
164
                if not 'okmsg' in kw:
 
165
                        kw['okmsg'] = 'yes'
 
166
                return
 
167
 
 
168
        # checking for the version of a module
 
169
        for x in cfg_ver:
 
170
                y = x.replace('-', '_')
 
171
                if y in kw:
 
172
                        self.cmd_and_log('%s --%s=%s %s' % (kw['path'], x, kw[y], kw['package']), kw)
 
173
                        if not 'okmsg' in kw:
 
174
                                kw['okmsg'] = 'yes'
 
175
                        self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0)
 
176
                        break
 
177
 
 
178
        # retrieving the version of a module
 
179
        if 'modversion' in kw:
 
180
                version = self.cmd_and_log('%s --modversion %s' % (kw['path'], kw['modversion']), kw).strip()
 
181
                self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version)
 
182
                return version
 
183
 
 
184
        # retrieving variables of a module
 
185
        if 'variables' in kw:
 
186
                env = kw.get('env', self.env)
 
187
                uselib = kw.get('uselib_store', kw['package'].upper())
 
188
                vars = Utils.to_list(kw['variables'])
 
189
                for v in vars:
 
190
                        val = self.cmd_and_log('%s --variable=%s %s' % (kw['path'], v, kw['package']), kw).strip()
 
191
                        var = '%s_%s' % (uselib, v)
 
192
                        env[var] = val
 
193
                if not 'okmsg' in kw:
 
194
                        kw['okmsg'] = 'yes'
 
195
                return
 
196
 
 
197
        lst = [kw['path']]
 
198
 
 
199
 
 
200
        defi = kw.get('define_variable', None)
 
201
        if not defi:
 
202
                defi = self.env.PKG_CONFIG_DEFINES or {}
 
203
        for key, val in defi.iteritems():
 
204
                lst.append('--define-variable=%s=%s' % (key, val))
 
205
 
 
206
        lst.append(kw.get('args', ''))
 
207
        lst.append(kw['package'])
 
208
 
 
209
        # so we assume the command-line will output flags to be parsed afterwards
 
210
        cmd = ' '.join(lst)
 
211
        ret = self.cmd_and_log(cmd, kw)
 
212
        if not 'okmsg' in kw:
 
213
                kw['okmsg'] = 'yes'
 
214
 
 
215
        self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0)
 
216
        parse_flags(ret, kw.get('uselib_store', kw['package'].upper()), kw.get('env', self.env))
 
217
        return ret
 
218
 
 
219
@conf
 
220
def check_cfg(self, *k, **kw):
 
221
        """
 
222
        for pkg-config mostly, but also all the -config tools
 
223
        conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI')
 
224
        conf.check_cfg(package='dbus-1', variables='system_bus_default_address session_bus_services_dir')
 
225
        """
 
226
 
 
227
        self.validate_cfg(kw)
 
228
        if 'msg' in kw:
 
229
                self.check_message_1(kw['msg'])
 
230
        ret = None
 
231
        try:
 
232
                ret = self.exec_cfg(kw)
 
233
        except Configure.ConfigurationError, e:
 
234
                if 'errmsg' in kw:
 
235
                        self.check_message_2(kw['errmsg'], 'YELLOW')
 
236
                if 'mandatory' in kw and kw['mandatory']:
 
237
                        if Logs.verbose > 1:
 
238
                                raise
 
239
                        else:
 
240
                                self.fatal('the configuration failed (see %r)' % self.log.name)
 
241
        else:
 
242
                kw['success'] = ret
 
243
                if 'okmsg' in kw:
 
244
                        self.check_message_2(self.ret_msg(kw['okmsg'], kw))
 
245
 
 
246
        return ret
 
247
 
 
248
# the idea is the following: now that we are certain
 
249
# that all the code here is only for c or c++, it is
 
250
# easy to put all the logic in one function
 
251
#
 
252
# this should prevent code duplication (ita)
 
253
 
 
254
# env: an optional environment (modified -> provide a copy)
 
255
# compiler: cc or cxx - it tries to guess what is best
 
256
# type: cprogram, cshlib, cstaticlib
 
257
# code: a c code to execute
 
258
# uselib_store: where to add the variables
 
259
# uselib: parameters to use for building
 
260
# define: define to set, like FOO in #define FOO, if not set, add /* #undef FOO */
 
261
# execute: True or False - will return the result of the execution
 
262
 
 
263
@conf
 
264
def validate_c(self, kw):
 
265
        """validate the parameters for the test method"""
 
266
 
 
267
        if not 'env' in kw:
 
268
                kw['env'] = self.env.copy()
 
269
 
 
270
        env = kw['env']
 
271
        if not 'compiler' in kw:
 
272
                kw['compiler'] = 'cc'
 
273
                if env['CXX_NAME'] and Task.TaskBase.classes.get('cxx', None):
 
274
                        kw['compiler'] = 'cxx'
 
275
                        if not self.env['CXX']:
 
276
                                self.fatal('a c++ compiler is required')
 
277
                else:
 
278
                        if not self.env['CC']:
 
279
                                self.fatal('a c compiler is required')
 
280
 
 
281
        if not 'type' in kw:
 
282
                kw['type'] = 'cprogram'
 
283
 
 
284
        assert not(kw['type'] != 'cprogram' and kw.get('execute', 0)), 'can only execute programs'
 
285
 
 
286
 
 
287
        #if kw['type'] != 'program' and kw.get('execute', 0):
 
288
        #       raise ValueError, 'can only execute programs'
 
289
 
 
290
        def to_header(dct):
 
291
                if 'header_name' in dct:
 
292
                        dct = Utils.to_list(dct['header_name'])
 
293
                        return ''.join(['#include <%s>\n' % x for x in dct])
 
294
                return ''
 
295
 
 
296
        # set the file name
 
297
        if not 'compile_mode' in kw:
 
298
                kw['compile_mode'] = (kw['compiler'] == 'cxx') and 'cxx' or 'cc'
 
299
 
 
300
        if not 'compile_filename' in kw:
 
301
                kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '')
 
302
 
 
303
        #OSX
 
304
        if 'framework_name' in kw:
 
305
                try: TaskGen.task_gen.create_task_macapp
 
306
                except AttributeError: self.fatal('frameworks require the osx tool')
 
307
 
 
308
                fwkname = kw['framework_name']
 
309
                if not 'uselib_store' in kw:
 
310
                        kw['uselib_store'] = fwkname.upper()
 
311
 
 
312
                if not kw.get('no_header', False):
 
313
                        if not 'header_name' in kw:
 
314
                                kw['header_name'] = []
 
315
                        fwk = '%s/%s.h' % (fwkname, fwkname)
 
316
                        if kw.get('remove_dot_h', None):
 
317
                                fwk = fwk[:-2]
 
318
                        kw['header_name'] = Utils.to_list(kw['header_name']) + [fwk]
 
319
 
 
320
                kw['msg'] = 'Checking for framework %s' % fwkname
 
321
                kw['framework'] = fwkname
 
322
                #kw['frameworkpath'] = set it yourself
 
323
 
 
324
        if 'function_name' in kw:
 
325
                fu = kw['function_name']
 
326
                if not 'msg' in kw:
 
327
                        kw['msg'] = 'Checking for function %s' % fu
 
328
                kw['code'] = to_header(kw) + SNIP1 % fu
 
329
                if not 'uselib_store' in kw:
 
330
                        kw['uselib_store'] = fu.upper()
 
331
                if not 'define_name' in kw:
 
332
                        kw['define_name'] = self.have_define(fu)
 
333
 
 
334
        elif 'type_name' in kw:
 
335
                tu = kw['type_name']
 
336
                if not 'msg' in kw:
 
337
                        kw['msg'] = 'Checking for type %s' % tu
 
338
                if not 'header_name' in kw:
 
339
                        kw['header_name'] = 'stdint.h'
 
340
                kw['code'] = to_header(kw) + SNIP2 % {'type_name' : tu}
 
341
                if not 'define_name' in kw:
 
342
                        kw['define_name'] = self.have_define(tu.upper())
 
343
 
 
344
        elif 'header_name' in kw:
 
345
                if not 'msg' in kw:
 
346
                        kw['msg'] = 'Checking for header %s' % kw['header_name']
 
347
 
 
348
                l = Utils.to_list(kw['header_name'])
 
349
                assert len(l)>0, 'list of headers in header_name is empty'
 
350
 
 
351
                kw['code'] = to_header(kw) + SNIP3
 
352
 
 
353
                if not 'uselib_store' in kw:
 
354
                        kw['uselib_store'] = l[0].upper()
 
355
 
 
356
                if not 'define_name' in kw:
 
357
                        kw['define_name'] = self.have_define(l[0])
 
358
 
 
359
        if 'lib' in kw:
 
360
                if not 'msg' in kw:
 
361
                        kw['msg'] = 'Checking for library %s' % kw['lib']
 
362
                if not 'uselib_store' in kw:
 
363
                        kw['uselib_store'] = kw['lib'].upper()
 
364
 
 
365
        if 'staticlib' in kw:
 
366
                if not 'msg' in kw:
 
367
                        kw['msg'] = 'Checking for static library %s' % kw['staticlib']
 
368
                if not 'uselib_store' in kw:
 
369
                        kw['uselib_store'] = kw['staticlib'].upper()
 
370
 
 
371
        if 'fragment' in kw:
 
372
                # an additional code fragment may be provided to replace the predefined code
 
373
                # in custom headers
 
374
                kw['code'] = kw['fragment']
 
375
                if not 'msg' in kw:
 
376
                        kw['msg'] = 'Checking for custom code'
 
377
                if not 'errmsg' in kw:
 
378
                        kw['errmsg'] = 'no'
 
379
 
 
380
        for (flagsname,flagstype) in [('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')]:
 
381
                if flagsname in kw:
 
382
                        if not 'msg' in kw:
 
383
                                kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname])
 
384
                        if not 'errmsg' in kw:
 
385
                                kw['errmsg'] = 'no'
 
386
 
 
387
        if not 'execute' in kw:
 
388
                kw['execute'] = False
 
389
 
 
390
        if not 'errmsg' in kw:
 
391
                kw['errmsg'] = 'not found'
 
392
 
 
393
        if not 'okmsg' in kw:
 
394
                kw['okmsg'] = 'yes'
 
395
 
 
396
        if not 'code' in kw:
 
397
                kw['code'] = SNIP3
 
398
 
 
399
        if not kw.get('success'): kw['success'] = None
 
400
 
 
401
        assert 'msg' in kw, 'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
 
402
 
 
403
@conf
 
404
def post_check(self, *k, **kw):
 
405
        "set the variables after a test was run successfully"
 
406
 
 
407
        is_success = False
 
408
        if kw['execute']:
 
409
                if kw['success'] is not None:
 
410
                        is_success = True
 
411
        else:
 
412
                is_success = (kw['success'] == 0)
 
413
 
 
414
        if 'define_name' in kw:
 
415
                if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw:
 
416
                        if kw['execute']:
 
417
                                key = kw['success']
 
418
                                if isinstance(key, str):
 
419
                                        if key:
 
420
                                                self.define(kw['define_name'], key, quote=kw.get('quote', 1))
 
421
                                        else:
 
422
                                                self.define_cond(kw['define_name'], True)
 
423
                                else:
 
424
                                        self.define_cond(kw['define_name'], False)
 
425
                        else:
 
426
                                self.define_cond(kw['define_name'], is_success)
 
427
 
 
428
        if is_success and 'uselib_store' in kw:
 
429
                import cc, cxx
 
430
                for k in set(cc.g_cc_flag_vars).union(cxx.g_cxx_flag_vars):
 
431
                        lk = k.lower()
 
432
                        # inconsistency: includes -> CPPPATH
 
433
                        if k == 'CPPPATH': lk = 'includes'
 
434
                        if k == 'CXXDEFINES': lk = 'defines'
 
435
                        if k == 'CCDEFINES': lk = 'defines'
 
436
                        if lk in kw:
 
437
                                val = kw[lk]
 
438
                                # remove trailing slash
 
439
                                if isinstance(val, str):
 
440
                                        val = val.rstrip(os.path.sep)
 
441
                                self.env.append_unique(k + '_' + kw['uselib_store'], val)
 
442
 
 
443
@conf
 
444
def check(self, *k, **kw):
 
445
        # so this will be the generic function
 
446
        # it will be safer to use check_cxx or check_cc
 
447
        self.validate_c(kw)
 
448
        self.check_message_1(kw['msg'])
 
449
        ret = None
 
450
        try:
 
451
                ret = self.run_c_code(*k, **kw)
 
452
        except Configure.ConfigurationError, e:
 
453
                self.check_message_2(kw['errmsg'], 'YELLOW')
 
454
                if 'mandatory' in kw and kw['mandatory']:
 
455
                        if Logs.verbose > 1:
 
456
                                raise
 
457
                        else:
 
458
                                self.fatal('the configuration failed (see %r)' % self.log.name)
 
459
        else:
 
460
                kw['success'] = ret
 
461
                self.check_message_2(self.ret_msg(kw['okmsg'], kw))
 
462
 
 
463
        self.post_check(*k, **kw)
 
464
        if not kw.get('execute', False):
 
465
                return ret == 0
 
466
        return ret
 
467
 
 
468
@conf
 
469
def run_c_code(self, *k, **kw):
 
470
        test_f_name = kw['compile_filename']
 
471
 
 
472
        k = 0
 
473
        while k < 10000:
 
474
                # make certain to use a fresh folder - necessary for win32
 
475
                dir = os.path.join(self.blddir, '.conf_check_%d' % k)
 
476
 
 
477
                # if the folder already exists, remove it
 
478
                try:
 
479
                        shutil.rmtree(dir)
 
480
                except OSError:
 
481
                        pass
 
482
 
 
483
                try:
 
484
                        os.stat(dir)
 
485
                except OSError:
 
486
                        break
 
487
 
 
488
                k += 1
 
489
 
 
490
        try:
 
491
                os.makedirs(dir)
 
492
        except:
 
493
                self.fatal('cannot create a configuration test folder %r' % dir)
 
494
 
 
495
        try:
 
496
                os.stat(dir)
 
497
        except:
 
498
                self.fatal('cannot use the configuration test folder %r' % dir)
 
499
 
 
500
        bdir = os.path.join(dir, 'testbuild')
 
501
 
 
502
        if not os.path.exists(bdir):
 
503
                os.makedirs(bdir)
 
504
 
 
505
        env = kw['env']
 
506
 
 
507
        dest = open(os.path.join(dir, test_f_name), 'w')
 
508
        dest.write(kw['code'])
 
509
        dest.close()
 
510
 
 
511
        back = os.path.abspath('.')
 
512
 
 
513
        bld = Build.BuildContext()
 
514
        bld.log = self.log
 
515
        bld.all_envs.update(self.all_envs)
 
516
        bld.all_envs['default'] = env
 
517
        bld.lst_variants = bld.all_envs.keys()
 
518
        bld.load_dirs(dir, bdir)
 
519
 
 
520
        os.chdir(dir)
 
521
 
 
522
        bld.rescan(bld.srcnode)
 
523
 
 
524
        if not 'features' in kw:
 
525
                # conf.check(features='cc cprogram pyext', ...)
 
526
                kw['features'] = [kw['compile_mode'], kw['type']] # "cprogram cc"
 
527
 
 
528
        o = bld(features=kw['features'], source=test_f_name, target='testprog')
 
529
 
 
530
        for k, v in kw.iteritems():
 
531
                setattr(o, k, v)
 
532
 
 
533
        self.log.write("==>\n%s\n<==\n" % kw['code'])
 
534
 
 
535
        # compile the program
 
536
        try:
 
537
                bld.compile()
 
538
        except Utils.WafError:
 
539
                ret = Utils.ex_stack()
 
540
        else:
 
541
                ret = 0
 
542
 
 
543
        # chdir before returning
 
544
        os.chdir(back)
 
545
 
 
546
        if ret:
 
547
                self.log.write('command returned %r' % ret)
 
548
                self.fatal(str(ret))
 
549
 
 
550
        # if we need to run the program, try to get its result
 
551
        # keep the name of the program to execute
 
552
        if kw['execute']:
 
553
                lastprog = o.link_task.outputs[0].abspath(env)
 
554
 
 
555
                args = Utils.to_list(kw.get('exec_args', []))
 
556
                proc = Utils.pproc.Popen([lastprog] + args, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE)
 
557
                (out, err) = proc.communicate()
 
558
                w = self.log.write
 
559
                w(str(out))
 
560
                w('\n')
 
561
                w(str(err))
 
562
                w('\n')
 
563
                w('returncode %r' % proc.returncode)
 
564
                w('\n')
 
565
                if proc.returncode:
 
566
                        self.fatal(Utils.ex_stack())
 
567
                ret = out
 
568
 
 
569
        return ret
 
570
 
 
571
@conf
 
572
def check_cxx(self, *k, **kw):
 
573
        kw['compiler'] = 'cxx'
 
574
        return self.check(*k, **kw)
 
575
 
 
576
@conf
 
577
def check_cc(self, *k, **kw):
 
578
        kw['compiler'] = 'cc'
 
579
        return self.check(*k, **kw)
 
580
 
 
581
@conf
 
582
def define(self, define, value, quote=1):
 
583
        """store a single define and its state into an internal list for later
 
584
           writing to a config header file.  Value can only be
 
585
           a string or int; other types not supported.  String
 
586
           values will appear properly quoted in the generated
 
587
           header file."""
 
588
        assert define and isinstance(define, str)
 
589
 
 
590
        # ordered_dict is for writing the configuration header in order
 
591
        tbl = self.env[DEFINES] or Utils.ordered_dict()
 
592
 
 
593
        # the user forgot to tell if the value is quoted or not
 
594
        if isinstance(value, str):
 
595
                if quote:
 
596
                        tbl[define] = '"%s"' % repr('"'+value)[2:-1].replace('"', '\\"')
 
597
                else:
 
598
                        tbl[define] = value
 
599
        elif isinstance(value, int):
 
600
                tbl[define] = value
 
601
        else:
 
602
                raise TypeError('define %r -> %r must be a string or an int' % (define, value))
 
603
 
 
604
        # add later to make reconfiguring faster
 
605
        self.env[DEFINES] = tbl
 
606
        self.env[define] = value # <- not certain this is necessary
 
607
 
 
608
@conf
 
609
def undefine(self, define):
 
610
        """store a single define and its state into an internal list
 
611
           for later writing to a config header file"""
 
612
        assert define and isinstance(define, str)
 
613
 
 
614
        tbl = self.env[DEFINES] or Utils.ordered_dict()
 
615
 
 
616
        value = UNDEFINED
 
617
        tbl[define] = value
 
618
 
 
619
        # add later to make reconfiguring faster
 
620
        self.env[DEFINES] = tbl
 
621
        self.env[define] = value
 
622
 
 
623
@conf
 
624
def define_cond(self, name, value):
 
625
        """Conditionally define a name.
 
626
        Formally equivalent to: if value: define(name, 1) else: undefine(name)"""
 
627
        if value:
 
628
                self.define(name, 1)
 
629
        else:
 
630
                self.undefine(name)
 
631
 
 
632
@conf
 
633
def is_defined(self, key):
 
634
        defines = self.env[DEFINES]
 
635
        if not defines:
 
636
                return False
 
637
        try:
 
638
                value = defines[key]
 
639
        except KeyError:
 
640
                return False
 
641
        else:
 
642
                return value != UNDEFINED
 
643
 
 
644
@conf
 
645
def get_define(self, define):
 
646
        "get the value of a previously stored define"
 
647
        try: return self.env[DEFINES][define]
 
648
        except KeyError: return None
 
649
 
 
650
@conf
 
651
def have_define(self, name):
 
652
        "prefix the define with 'HAVE_' and make sure it has valid characters."
 
653
        return self.__dict__.get('HAVE_PAT', 'HAVE_%s') % Utils.quote_define_name(name)
 
654
 
 
655
@conf
 
656
def write_config_header(self, configfile='', env='', guard='', top=False):
 
657
        "save the defines into a file"
 
658
        if not configfile: configfile = WAF_CONFIG_H
 
659
        waf_guard = guard or '_%s_WAF' % Utils.quote_define_name(configfile)
 
660
 
 
661
        # configfile -> absolute path
 
662
        # there is a good reason to concatenate first and to split afterwards
 
663
        if not env: env = self.env
 
664
        if top:
 
665
                diff = ''
 
666
        else:
 
667
                diff = Utils.diff_path(self.srcdir, self.curdir)
 
668
        full = os.sep.join([self.blddir, env.variant(), diff, configfile])
 
669
        full = os.path.normpath(full)
 
670
        (dir, base) = os.path.split(full)
 
671
 
 
672
        try: os.makedirs(dir)
 
673
        except: pass
 
674
 
 
675
        dest = open(full, 'w')
 
676
        dest.write('/* Configuration header created by Waf - do not edit */\n')
 
677
        dest.write('#ifndef %s\n#define %s\n\n' % (waf_guard, waf_guard))
 
678
 
 
679
        dest.write(self.get_config_header())
 
680
 
 
681
        # config files are not removed on "waf clean"
 
682
        env.append_unique(CFG_FILES, os.path.join(diff, configfile))
 
683
 
 
684
        dest.write('\n#endif /* %s */\n' % waf_guard)
 
685
        dest.close()
 
686
 
 
687
@conf
 
688
def get_config_header(self):
 
689
        """Fill-in the contents of the config header. Override when you need to write your own config header."""
 
690
        config_header = []
 
691
 
 
692
        tbl = self.env[DEFINES] or Utils.ordered_dict()
 
693
        for key in tbl.allkeys:
 
694
                value = tbl[key]
 
695
                if value is None:
 
696
                        config_header.append('#define %s' % key)
 
697
                elif value is UNDEFINED:
 
698
                        config_header.append('/* #undef %s */' % key)
 
699
                else:
 
700
                        config_header.append('#define %s %s' % (key, value))
 
701
        return "\n".join(config_header)
 
702
 
 
703
@conftest
 
704
def find_cpp(conf):
 
705
        v = conf.env
 
706
        cpp = []
 
707
        if v['CPP']: cpp = v['CPP']
 
708
        elif 'CPP' in conf.environ: cpp = conf.environ['CPP']
 
709
        if not cpp: cpp = conf.find_program('cpp', var='CPP')
 
710
        #if not cpp: cpp = v['CC']
 
711
        #if not cpp: cpp = v['CXX']
 
712
        v['CPP'] = cpp
 
713
 
 
714
@conftest
 
715
def cc_add_flags(conf):
 
716
        conf.add_os_flags('CFLAGS', 'CCFLAGS')
 
717
        conf.add_os_flags('CPPFLAGS')
 
718
 
 
719
@conftest
 
720
def cxx_add_flags(conf):
 
721
        conf.add_os_flags('CXXFLAGS')
 
722
        conf.add_os_flags('CPPFLAGS')
 
723
 
 
724
@conftest
 
725
def link_add_flags(conf):
 
726
        conf.add_os_flags('LINKFLAGS')
 
727
        conf.add_os_flags('LDFLAGS', 'LINKFLAGS')
 
728
 
 
729
@conftest
 
730
def cc_load_tools(conf):
 
731
        conf.check_tool('cc')
 
732
 
 
733
@conftest
 
734
def cxx_load_tools(conf):
 
735
        conf.check_tool('cxx')
 
736