Package wafadmin :: Package Tools :: Module config_c
[hide private]
[frames] | no frames]

Source Code for Module wafadmin.Tools.config_c

   1  #!/usr/bin/env python 
   2  # encoding: utf-8 
   3  # Thomas Nagy, 2005-2008 (ita) 
   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""" 
29 30 31 -class attached_conf(type):
32 """no decorators for classes, so we use a metaclass 33 map 'conf.create_classname()' to 'classname()'"""
34 - def __init__(cls, name, bases, dict):
35 super(attached_conf, cls).__init__(name, bases, dict) 36 def fun_create(self): 37 inst = cls(self) 38 return inst
39 setattr(Configure.ConfigurationContext, 'create_' + cls.__name__, fun_create)
40
41 -class enumerator_base(object):
42 - def __init__(self, conf):
43 self.conf = conf 44 self.env = conf.env 45 self.define = '' 46 self.mandatory = 0 47 self.message = ''
48
49 - def error(self):
50 if not self.message: 51 Logs.warn('No message provided') 52 self.conf.fatal(self.message)
53
54 - def hash(self):
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
63 - def update_env(self, hashtable):
64 # skip this if hashtable is only a string 65 if not type(hashtable) is types.StringType: 66 for name in hashtable.keys(): 67 self.env.append_value(name, hashtable[name])
68
69 - def validate(self):
70 """interface, do not remove""" 71 pass
72
73 - def run(self):
74 self.validate() 75 76 ret = self.run_test() 77 if self.mandatory and not ret: self.error() 78 79 return ret
80 81 # Override this method, not run()!
82 - def run_test(self):
83 return not Configure.TEST_OK
84
85 -class configurator_base(enumerator_base):
86 - def __init__(self, conf):
87 enumerator_base.__init__(self, conf) 88 self.uselib_store = ''
89
90 -class program_enumerator(enumerator_base):
91 __metaclass__ = attached_conf
92 - def __init__(self,conf):
93 enumerator_base.__init__(self, conf) 94 95 self.name = '' 96 self.path = [] 97 self.var = None
98
99 - def error(self):
100 errmsg = 'program %s cannot be found' % self.name 101 if self.message: errmsg += '\n%s' % self.message 102 self.conf.fatal(errmsg)
103
104 - def run_test(self):
105 ret = Configure.find_program_impl(self.env, self.name, self.path, self.var) 106 self.conf.check_message('program', self.name, ret, ret) 107 if self.var: self.env[self.var] = ret 108 return ret
109
110 -class function_enumerator(enumerator_base):
111 __metaclass__ = attached_conf
112 - def __init__(self,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
126 - def error(self):
127 errmsg = 'function %s cannot be found' % self.function 128 if self.message: errmsg += '\n%s' % self.message 129 self.conf.fatal(errmsg)
130
131 - def validate(self):
132 if not self.define: 133 self.define = self.function.upper()
134
135 - def run_test(self):
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
169 -class library_enumerator(enumerator_base):
170 "find a library in a list of paths" 171 __metaclass__ = attached_conf
172 - def __init__(self, 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 = '' # to set the LIB_NAME and LIBPATH_NAME 179 self.uselib = '' 180 self.nosystem = 0 # do not use standard lib paths 181 self.want_message = 1
182
183 - def error(self):
184 errmsg = 'library %s cannot be found' % self.name 185 if self.message: errmsg += '\n%s' % self.message 186 self.conf.fatal(errmsg)
187
188 - def validate(self):
189 if not self.nosystem and not self.path: 190 self.path += stdlibpath
191
192 - def run_test(self):
193 ret = '' # returns a string 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
210 -class header_enumerator(enumerator_base):
211 "find a header in a list of paths" 212 __metaclass__ = attached_conf
213 - def __init__(self,conf):
214 enumerator_base.__init__(self, conf) 215 216 self.name = [] 217 self.path = [] 218 self.define = [] 219 self.nosystem = 0 220 self.want_message = 1
221
222 - def validate(self):
223 if not self.nosystem and not self.path: 224 self.path = stdincpath
225
226 - def error(self):
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
231 - def run_test(self):
232 ret = Configure.find_file(self.name, self.path) 233 if self.want_message: 234 self.conf.check_message('header', self.name, ret, ret) 235 if self.define: self.env[self.define] = ret 236 return ret
237
238 ## ENUMERATORS END 239 ################### 240 241 ################### 242 ## CONFIGURATORS