81a8eba4c7d5aa4badf6165888c20cad406d5905
[senf.git] / site_scons / site_tools / CustomTests.py
1 import SCons.Environment
2 import SCons.Util, SCons.Script
3
4 # Fix for SCons 0.97 compatibility
5 import SCons.SConf
6 try: SCons.SConf.SConfBase.Define
7 except AttributeError:
8     import string
9     def Define(self, name, value = None, comment = None):
10         lines = []
11         if comment:
12             comment_str = "/* %s */" % comment
13             lines.append(comment_str)
14         if value is not None:
15             define_str = "#define %s %s" % (name, value)
16         else:
17             define_str = "#define %s" % name
18         lines.append(define_str)
19         lines.append('')
20         self.config_h_text = self.config_h_text + string.join(lines, '\n')
21     SCons.SConf.SConfBase.Define = Define
22
23 class ConfTest(object):
24     """Configuration test decorator.
25
26 This class is used as a decorator to define SCons Configure
27 tests. There are three ways to use this facility:
28
29
30 DIRECT WITH EXTERNAL REGISTRY
31
32 In this scenario, you pass the test registry, a map, as argument to
33 the decorator. This usage is primarily interesting for tool writers:
34
35     from CustomTests import ConfTest
36
37     MY_TESTS = {}
38     
39     @ConfTest(MY_TESTS)
40     def CheckMyFoo(context):
41         pass
42
43     def generate(env):
44         env.Append(CUSTOM_TESTS = MY_TESTS)
45
46 This will place CheckMyFoo into the MY_TESTS dictionary which you can
47 later add to the CUSTOM_TESTS environment variable.
48
49
50 USING A REGISTRY ALIAS
51
52 In this scenario, you define a local alias for the decorator which
53 serves as the registry. This usage is again primarily interesting for
54 tool and extension writers:
55
56     import CustomTests
57
58     MyConfTest = CustomTests.ConfTest()
59
60     @MyConfTest
61     def CheckMyFoo(context):
62         pass
63
64     def generate(env):
65         env.Append(CUSTOM_TESTS = MyConfTest.tests)
66
67 Logically this is like the previous method.
68
69
70 USING THE ENVIRONMENT MEMBER
71
72 This usage is interesting for SConstruct and SConscript writers:
73
74     env = Environment()
75     env.Tool('CustomTests')
76     
77     @env.ConfTest()
78     def CheckMyFoo(context):
79         pass
80
81     conf = env.Configure()
82     conf.CheckMyFoo()
83     env = conf.Finish()
84
85 The new configuration test is automatically added to
86 env['CUSTOM_TESTS'] and is thus automatically available to all
87 configuration contexts created from the environment.
88 """
89     
90     def __init__(self, registry=None):
91         if registry is None:
92             self.tests = {}
93         elif isinstance(registry, SCons.Environment.SubstitutionEnvironment):
94             self.tests =registry['CUSTOM_TESTS']
95         else:
96             self.tests = registry
97
98     def __call__(self, func):
99         self.tests[func.__name__] = func
100         return func
101
102 DefaultTest = ConfTest()
103
104 def Configure(self, *args, **kw):
105     try: kw['custom_tests'].update(self['CUSTOM_TESTS'])
106     except KeyError: kw['custom_tests'] = dict(self['CUSTOM_TESTS'])
107     return self._CustomTests_orig_Configure(*args, **kw)
108
109 @DefaultTest
110 def Fail(context, msg):
111     SCons.Util.display("scons: *** %s" % msg)
112     SCons.Script.Exit(1)
113
114 def generate(env):
115     env.Append( CUSTOM_TESTS = DefaultTest.tests )
116     env._CustomTests_orig_Configure = env.Configure
117     env.AddMethod(Configure)
118     env.AddMethod(ConfTest)
119     env.AddMethod(Fail)
120
121 def exists(env):
122     return True