1
2
3
4
5 """
6 c/c++ configuration routines
7
8 classes such as program_enumerator are attached to the Configure class,
9 avoiding lots of imports in user scripts
10
11 Usage example (see demos/adv/wscript):
12 program_enumerator -> conf.create_program_enumerator
13
14 The functions preceded by "@conf" are attached in the same manner
15 """
16
17 import os, types, imp, cPickle, sys, shlex, warnings
18 from Utils import md5
19 import Build, Utils, Configure, Task, Options
20 from Logs import warn, debug
21 from Constants import *
22 from Configure import conf, conftest
23
24 stdincpath = ['/usr/include/', '/usr/local/include/']
25 """standard include paths"""
26
27 stdlibpath = ['/usr/lib/', '/usr/local/lib/', '/lib']
28 """standard library search paths"""
32 """no decorators for classes, so we use a metaclass
33 map 'conf.create_classname()' to 'classname()'"""
39 setattr(Configure.ConfigurationContext, 'create_' + cls.__name__, fun_create)
40
48
50 if not self.message:
51 Logs.warn('No message provided')
52 self.conf.fatal(self.message)
53
55 m = md5()
56 classvars = vars(self)
57 for (var, value) in classvars.iteritems():
58 if callable(var) or value == self or value == self.env or value == self.conf:
59 continue
60 m.update(str(value))
61 return m.digest()
62
64
65 if not type(hashtable) is types.StringType:
66 for name in hashtable.keys():
67 self.env.append_value(name, hashtable[name])
68
70 """interface, do not remove"""
71 pass
72
74 self.validate()
75
76 ret = self.run_test()
77 if self.mandatory and not ret: self.error()
78
79 return ret
80
81
84
89
91 __metaclass__ = attached_conf
98
100 errmsg = 'program %s cannot be found' % self.name
101 if self.message: errmsg += '\n%s' % self.message
102 self.conf.fatal(errmsg)
103
109
111 __metaclass__ = attached_conf
113 enumerator_base.__init__(self, conf)
114
115 self.function = ''
116 self.define = ''
117
118 self.headers = []
119 self.header_code = ''
120 self.custom_code = ''
121
122 self.include_paths = []
123 self.libs = []
124 self.lib_paths = []
125
127 errmsg = 'function %s cannot be found' % self.function
128 if self.message: errmsg += '\n%s' % self.message
129 self.conf.fatal(errmsg)
130
132 if not self.define:
133 self.define = self.function.upper()
134
136 ret = not Configure.TEST_OK
137
138 oldlibpath = self.env['LIBPATH']
139 oldlib = self.env['LIB']
140
141 code = []
142 code.append(self.header_code)
143 code.append('\n')
144 for header in self.headers:
145 code.append('#include <%s>\n' % header)
146
147 if self.custom_code:
148 code.append('int main(){%s\nreturn 0;}\n' % self.custom_code)
149 else:
150 code.append('int main(){\nvoid *p;\np=(void*)(%s);\nreturn 0;\n}\n' % self.function)
151
152 self.env['LIB'] = Utils.to_list(self.libs)
153 self.env['LIBPATH'] = Utils.to_list(self.lib_paths)
154
155 obj = check_data()
156 obj.code = "\n".join(code)
157 obj.includes = self.include_paths
158 obj.env = self.env
159
160 ret = int(self.conf.run_check(obj))
161 self.conf.check_message('function %s' % self.function, '', ret, option='')
162 self.conf.define_cond(self.define, ret)
163
164 self.env['LIB'] = oldlib
165 self.env['LIBPATH'] = oldlibpath
166
167 return ret
168
170 "find a library in a list of paths"
171 __metaclass__ = attached_conf
173 enumerator_base.__init__(self, conf)
174
175 self.name = ''
176 self.path = []
177 self.code = 'int main() {return 0;}\n'
178 self.uselib_store = ''
179 self.uselib = ''
180 self.nosystem = 0
181 self.want_message = 1
182
184 errmsg = 'library %s cannot be found' % self.name
185 if self.message: errmsg += '\n%s' % self.message
186 self.conf.fatal(errmsg)
187
189 if not self.nosystem and not self.path:
190 self.path += stdlibpath
191
193 ret = ''
194
195 patterns = [self.env['shlib_PATTERN'], 'lib%s.dll.a', 'lib%s.lib', self.env['staticlib_PATTERN']]
196 for x in patterns:
197 name = x % self.name
198 ret = Configure.find_file(name, self.path)
199 if ret: break
200
201 if self.want_message:
202 self.conf.check_message('library '+self.name, '', ret, option=ret)
203
204 if self.uselib_store:
205 self.env.append_value('LIB_' + self.uselib_store, self.name)
206 self.env.append_value('LIBPATH_' + self.uselib_store, ret)
207
208 return ret
209
211 "find a header in a list of paths"
212 __metaclass__ = attached_conf
221
223 if not self.nosystem and not self.path:
224 self.path = stdincpath
225
227 errmsg = 'cannot find %s in %s' % (self.name, str(self.path))
228 if self.message: errmsg += '\n%s' % self.message
229 self.conf.fatal(errmsg)
230
237