/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (show annotations) (download)
Fri Mar 31 14:22:06 2006 UTC (14 years, 7 months ago) by johnpye
File size: 12270 byte(s)
Fixing up message about bad SWIG version
1 import os, commands, platform, distutils.sysconfig, os.path
2
3 #------------------------------------------------------
4 # OPTIONS
5 #
6 # Note that if you set the options via the command line, they will be
7 # remembered in the file 'options.cache'. It's a feature ;-)
8
9 opts = Options(['options.cache', 'config.py'])
10 print "PLATFORM = ",platform.system()
11
12 # Import the outside environment
13 env = Environment(ENV=os.environ)
14
15 # Package linking option
16 opts.Add(EnumOption(
17 'PACKAGE_LINKING'
18 , 'Style of linking for external libraries'
19 , 'DYNAMIC_PACKAGES'
20 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
21 ))
22
23 # You can turn off building of Tcl/Tk interface
24 opts.Add(BoolOption(
25 'WITHOUT_TCLTK_GUI'
26 ,"Set to True if you don't want to build the original Tcl/Tk GUI."
27 , False
28 ))
29
30 # You can turn off the building of the Python interface
31 opts.Add(BoolOption(
32 'WITHOUT_PYTHON'
33 ,"Set to True if you don't want to build Python wrappers."
34 , False
35 ))
36
37 # Which solvers will we allow?
38 opts.Add(ListOption(
39 'WITH_SOLVERS'
40 ,"List of the solvers you want to build. The default is the minimum that"
41 +" works."
42 ,["QRSLV","CMSLV"]
43 ,['QRSLV','MPS','SLV','OPTSQP'
44 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
45 ,'LSOD','OPTSQP'
46 ]
47 ))
48
49 # Where will the local copy of the help files be kept?
50 opts.Add(PackageOption(
51 'WITH_LOCAL_HELP'
52 , "Directory containing the local copy of the help files (optional)"
53 , "no"
54 ))
55
56 # Will bintoken support be enabled?
57 opts.Add(BoolOption(
58 'WITH_BINTOKEN'
59 ,"Enable bintoken support? This means compiling models as C-code before"
60 +" running them, to increase solving speed for large models."
61 ,False
62 ))
63
64 # What should the default ASCENDLIBRARY path be?
65 # Note: users can change it by editing their ~/.ascend.ini
66 opts.Add(
67 'DEFAULT_ASCENDLIBRARY'
68 ,"Set the default value of the ASCENDLIBRARY -- the location where"
69 +" ASCEND will look for models when running ASCEND"
70 ,os.path.expanduser("~/src/ascend/trunk/models")
71 )
72
73 # Where is SWIG?
74 opts.Add(
75 'SWIG'
76 ,"SWIG location, probably only required for MinGW and MSVC users."
77 +" Enter the location as a Windows-style path, for example"
78 +" 'c:\msys\1.0\home\john\swigwin-1.3.29\swig.exe'."
79 )
80
81 # Build the test suite?
82 opts.Add(BoolOption(
83 'WITH_CUNIT_TESTS'
84 ,"Whether to build the CUnit tests. Default is off. If set to on,"
85 +" you must have CUnit installed somewhere that SCons can"
86 +" find it."
87 ,False
88 ))
89
90 # Where are the CUnit includes?
91 opts.Add(PackageOption(
92 'CUNIT_CPPPATH'
93 ,"Where are your CUnit include files?"
94 ,"off"
95 ))
96
97 # Where are the CUnit includes?
98 opts.Add(PackageOption(
99 'CUNIT_LIBPATH'
100 ,"Where are your CUnit include files?"
101 ,"off"
102 ))
103
104 # TODO: OTHER OPTIONS?
105
106 # TODO: flags for optimisation
107
108 # TODO: turning on/off bintoken functionality
109
110 # TODO: Where will the 'Makefile.bt' file be installed
111 # ....
112
113 opts.Update(env)
114 opts.Save('options.cache',env)
115
116 Help(opts.GenerateHelpText(env))
117
118 env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
119
120 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
121
122 with_python = (env['WITHOUT_PYTHON']==False)
123
124 with_cunit_tests = env['WITH_CUNIT_TESTS']
125
126 print "SOLVERS:",env['WITH_SOLVERS']
127
128 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
129 print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
130 print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
131
132 subst_dict = {
133 '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
134 , '@GLADE_FILE@':'glade/ascend.glade'
135 , '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
136 , '@ASCEND_ICON@':'glade/ascend.png'
137 , '@HELP_ROOT@':''
138 }
139
140 if env['WITH_LOCAL_HELP']:
141 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
142
143 env.Append(SUBST_DICT=subst_dict)
144
145 #------------------------------------------------------
146 # SPECIAL CONFIGURATION TESTS
147
148 #----------------
149 # SWIG
150
151 import os,re
152
153 def CheckSwigVersion(context):
154 context.Message("Checking version of SWIG")
155 (cin,cout,cerr) = os.popen3(env['SWIG']+' -version');
156 output = cout.read()
157 err = cerr.read()
158 if err:
159 context.Result("Error running -version cmd:"+err)
160 return 0
161
162 expr = re.compile("^SWIG Version (?P<maj>[0-9]+)\.(?P<min>[0-9]+)\.(?P<pat>[0-9]+)$",re.M);
163 m = expr.search(output);
164 if not m:
165 context.Result("Couldn't detect version")
166 return 0
167 maj = int(m.group('maj'))
168 min = int(m.group('min'))
169 pat = int(m.group('pat'))
170
171 if maj == 1 and (
172 min > 3
173 or (min == 3 and pat >= 24)
174 ):
175 context.Result("ok, %d.%d.%d" % (maj,min,pat))
176 return 1;
177 else:
178 context.Result("too old, %d.%d.%d" % (maj,min,pat))
179 return 0;
180
181 #----------------
182 # General purpose library-and-header test
183
184
185 def CheckExtLib(context,libname,text,ext='.c',varprefix=None):
186 """This method will check for variables LIBNAME_LIBPATH
187 and LIBNAME_CPPPATH and try to compile and link the
188 file with the provided text, linking with the
189 library libname."""
190
191 context.Message( 'Checking for '+libname+'...' )
192
193 if varprefix==None:
194 varprefix = libname.upper()
195
196 keep = {}
197 for k in ['LIBS','LIBPATH','CPPPATH']:
198 if context.env.has_key(k):
199 keep[k] = context.env[k]
200
201 libpath_add = []
202 if context.env.has_key(varprefix+'_LIBPATH'):
203 libpath_add = [env[varprefix+'_LIBPATH']]
204
205 cpppath_add = []
206 if context.env.has_key(varprefix+'_CPPPATH'):
207 cpppath_add = [env[varprefix+'_CPPPATH']]
208
209 context.env.Append(
210 LIBS = libname
211 , LIBPATH = libpath_add
212 , CPPPATH = cpppath_add
213 )
214 ret = context.TryLink(cunit_test_text,ext)
215
216 for k in keep:
217 context.env[k]=keep[k];
218
219 context.Result( ret )
220 return ret
221
222 cunit_test_text = """
223 #include <CUnit/Cunit.h>
224 int maxi(int i1, int i2){
225 return (i1 > i2) ? i1 : i2;
226 }
227
228 void test_maxi(void){
229 CU_ASSERT(maxi(0,2) == 2);
230 CU_ASSERT(maxi(0,-2) == 0);
231 CU_ASSERT(maxi(2,2) == 2);
232
233 }
234 int main(void){
235 /* CU_initialize_registry() */
236 }
237 """
238
239 def CheckCUnit(context):
240 return CheckExtLib(context
241 ,'cunit'
242 ,cunit_test_text
243 )
244
245
246 #------------------------------------------------------
247 # CONFIGURATION
248
249 conf = Configure(env
250 , custom_tests = {
251 'CheckSwigVersion' : CheckSwigVersion
252 , 'CheckCUnit' : CheckCUnit
253 # , 'CheckIsNan' : CheckIsNan
254 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
255 }
256 , config_h = "config.h"
257 )
258
259 if not conf.CheckSwigVersion():
260 print 'SWIG version is not OK'
261 Exit(1)
262
263 # Math library
264 if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
265 print 'Did not find libm.a or m.lib, exiting!'
266 Exit(1)
267
268 # Where is 'isnan'?
269
270 if not conf.CheckFunc('isnan'):
271 print "Didn't find isnan"
272 Exit(1)
273
274 # Tcl/Tk
275 if not conf.CheckHeader('tcl.h'):
276 with_tcltk_gui = False
277
278 if not conf.CheckHeader('tk.h'):
279 with_tcltk_gui = False
280
281 if not conf.CheckLib('tcl'):
282 with_tcltk_gui = False
283
284 if not conf.CheckLib('tk'):
285 with_tcktk_gui = False
286
287 # Python... obviously we're already running python, so we just need to
288 # check that we can link to the python library OK:
289
290 if platform.system()=="Windows":
291 #conf.env.Append(LIBPATH='c:\Python24\libs')
292 #conf.env.Append(CPPPATH='c:\Python24\include')
293 #python_header='Python.h'
294 python_lib='python24'
295 #python_libpath=['c:\\Python24\\libs']
296 #python_cpppath=['c:\\Python24\\include']
297 else:
298 #python_header='python2.4/Python.h'
299 python_lib='python2.4'
300 #python_libpath=[]
301 #python_cpppath=['/usr/include/python2.4']
302
303 #if not conf.CheckLibWithHeader(python_lib,python_header,'C'
304 # , LIBPATH=[distutils.sysconfig.PREFIX+"/libs"]
305 # , CPPPATH=[distutils.sysconfig.get_python_inc()]
306 #):
307 # print "Didn't find Python 2.4 ("+python_lib+")"
308 # with_python = False
309 #else:
310
311 # SWIG version
312
313 if platform.system()=="Windows":
314 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
315 env['ENV']['SWIGFEATURES']='-O'
316 else:
317 env['ENV']['SWIGFEATURES']='-O'
318
319 # CUnit
320
321 if with_cunit_tests:
322 conf.CheckCUnit()
323
324 # TODO: -D_HPUX_SOURCE is needed
325
326 # TODO: check size of void*
327
328 # TODO: detect if dynamic libraries are possible or not
329
330 conf.Finish()
331
332 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
333 env.Append(PYTHON_LIB=[python_lib])
334 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
335 print "PYTHON_LIBPATH =",env['PYTHON_LIBPATH']
336 print "PYTHON_CPPPATH =",env['PYTHON_CPPPATH']
337
338 if not with_python:
339 print "Can't build python interface"
340 Exit(1)
341
342 #------------------------------------------------------
343 # RECIPE: 'SubstInFile', used in pygtk SConscript
344
345 import re
346 from SCons.Script import * # the usual scons stuff you get in a SConscript
347
348 def TOOL_SUBST(env):
349 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
350 from the source to the target.
351 The values of SUBST_DICT first have any construction variables expanded
352 (its keys are not expanded).
353 If a value of SUBST_DICT is a python callable function, it is called and
354 the result is expanded as the value.
355 If there's more than one source and more than one target, each target gets
356 substituted from the corresponding source.
357 """
358 env.Append(TOOLS = 'SUBST')
359 def do_subst_in_file(targetfile, sourcefile, dict):
360 """Replace all instances of the keys of dict with their values.
361 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
362 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
363 """
364 try:
365 f = open(sourcefile, 'rb')
366 contents = f.read()
367 f.close()
368 except:
369 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
370 for (k,v) in dict.items():
371 contents = re.sub(k, v, contents)
372 try:
373 f = open(targetfile, 'wb')
374 f.write(contents)
375 f.close()
376 except:
377 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
378 return 0 # success
379
380 def subst_in_file(target, source, env):
381 if not env.has_key('SUBST_DICT'):
382 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
383 d = dict(env['SUBST_DICT']) # copy it
384 for (k,v) in d.items():
385 if callable(v):
386 d[k] = env.subst(v())
387 elif SCons.Util.is_String(v):
388 d[k]=env.subst(v)
389 else:
390 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
391 for (t,s) in zip(target, source):
392 return do_subst_in_file(str(t), str(s), d)
393
394 def subst_in_file_string(target, source, env):
395 """This is what gets printed on the console."""
396 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
397 for (t,s) in zip(target, source)])
398
399 def subst_emitter(target, source, env):
400 """Add dependency from substituted SUBST_DICT to target.
401 Returns original target, source tuple unchanged.
402 """
403 d = env['SUBST_DICT'].copy() # copy it
404 for (k,v) in d.items():
405 if callable(v):
406 d[k] = env.subst(v())
407 elif SCons.Util.is_String(v):
408 d[k]=env.subst(v)
409 Depends(target, SCons.Node.Python.Value(d))
410 return target, source
411
412 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
413 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
414
415 TOOL_SUBST(env)
416
417 #------------------------------------------------------
418 # SUBDIRECTORIES....
419
420
421 env.Append(CPPPATH=['..'])
422
423 env.SConscript(['base/generic/general/SConscript'],'env')
424
425 env.SConscript(['base/generic/utilities/SConscript'],'env')
426
427 env.SConscript(['base/generic/compiler/SConscript'],'env')
428
429 env.SConscript(['base/generic/solver/SConscript'],'env')
430
431 env.SConscript(['base/generic/packages/SConscript'],'env')
432
433 if with_tcltk_gui:
434 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
435 else:
436 print "Skipping... Tcl/Tk GUI isn't being built"
437
438 if with_python:
439 env.SConscript(['pygtk/interface/SConscript'],'env')
440 else:
441 print "Skipping... Python GUI isn't being built"
442
443 if with_cunit_tests:
444 testdirs = ['general','solver','utilities']
445 for testdir in testdirs:
446 path = 'base/generic/'+testdir+'/test/'
447 env.SConscript([path+'SConscript'],'env')
448 env.SConscript(['test/SConscript'],'env')
449 env.SConscript(['base/generic/test/SConscript'],'env')
450
451
452 else:
453 print "Skipping... CUnit tests aren't being built"
454
455 #------------------------------------------------------
456 # INSTALLATION
457
458 # TODO: add install options

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22