waf/playground/c/wscript

161 lines
3.7 KiB
Python

#! /usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2006-2010 (ita)
VERSION='0.0.1'
APPNAME='cc_test'
top = '.'
import waflib.Configure
waflib.Configure.autoconfig = True
def options(opt):
opt.load('compiler_c')
opt.load('gnu_dirs')
def build(bld):
bld.recurse('program stlib shlib stlib2')
lst = 'debug release foo bar one two'.split()
def configure(conf):
conf.load('compiler_c')
conf.check_features()
conf.check_cc(fragment="""#include<stdio.h>\nint main(){fprintf(stderr, "mu"); printf("%d", 22);return 0;}\n""", execute=True, define_name='HAVE_MU')
conf.write_config_header('config.h')
# gotcha - the config.h must be written for each variant
for x in lst:
conf.write_config_header(x + '/config.h')
from waflib import Utils, Build
class buildall_ctx(Build.BuildContext):
cmd = fun = 'buildall'
def compile(self):
pass
def buildall(ctx):
"""call 'waf buildall' to build all the variants in parallel"""
timer = Utils.Timer()
threads = []
count = [0]
line_lock = Utils.threading.Lock()
class sub_build(Utils.threading.Thread):
def run(self):
bld = self.bld = self.cls(top_dir=ctx.top_dir, out_dir=ctx.out_dir)
bld.restore()
bld.siblings = threads
bld.count = count
bld.line_lock = line_lock
bld.timer = timer
bld.logger = ctx.logger
bld.load_envs()
bld.targets = ctx.targets
bld.recurse([bld.run_dir])
bld.compile()
for x in lst:
cls = type(Build.BuildContext)(x, (Build.BuildContext,), {'cmd': x, 'variant': x})
cls.progress_line = locked_progress_line
f = sub_build()
f.cls = cls
threads.append(f)
f.start()
for x in threads:
x.join()
def locked_progress_line(self, state, total, col1, col2):
try:
self.line_lock.acquire()
self.count[0] += 1
total = 0
for x in self.siblings:
try:
p = x.bld.producer
except AttributeError:
pass
else:
total += p.total
return Build.BuildContext.progress_line(self, self.count[0], total, col1, col2)
finally:
self.line_lock.release()
class cleanall_ctx(Build.CleanContext):
cmd = fun = 'cleanall'
def cleanall(ctx):
for x in lst:
cls = type(Build.CleanContext)(x, (Build.CleanContext,), {'cmd': x, 'variant': x})
bld = cls(top_dir=ctx.top_dir, out_dir=ctx.out_dir)
bld.restore()
bld.load_envs()
bld.recurse([bld.run_dir])
try:
bld.clean()
finally:
bld.store()
# produces dict/json compatible output
features_str = r'''
#include <stdio.h>
int is_big_endian()
{
long one = 1;
return !(*((char *)(&one)));
}
int main()
{
printf("{");
if (is_big_endian()) printf("\"bigendian\":1,");
else printf("\"bigendian\":0,");
printf("\"int_size\":%lu,", sizeof(int));
printf("\"long_int_size\":%lu,", sizeof(long int));
printf("\"long_long_int_size\":%lu,", sizeof(long long int));
printf("\"double_size\":%lu", sizeof(double));
printf("}");
return 0;
}
'''
def check_features(self):
mp = self.check(fragment=features_str, define_ret=True, execute=True)
try:
mp = mp.decode('utf-8')
except:
pass
t = eval(mp)
try:
is_big = int(t['bigendian'])
except KeyError:
raise Configure.ConfigurationError('endian test failed %s (see the config.log)' % features_str)
if is_big: strbig = 'big endian'
else: strbig = 'little endian'
self.msg('endianness', strbig)
self.msg('int size', t['int_size'])
self.msg('long int size', t['long_int_size'])
self.msg('long long int size', t['long_long_int_size'])
self.msg('double size', t['double_size'])
self.define_cond('IS_BIGENDIAN', is_big)
self.define_cond('INT_SIZE', int(t['int_size']))
self.define_cond('LONG_INT_SIZE', int(t['long_int_size']))
self.define_cond('LONG_LONG_INT_SIZE', int(t['long_long_int_size']))
self.define_cond('DOUBLE_SIZE', int(t['double_size']))
return is_big
from waflib import Configure
Configure.conf(check_features) # bind the method