/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 412 - (show annotations) (download)
Mon Apr 3 03:31:30 2006 UTC (19 years, 1 month ago) by johnpye
File size: 13990 byte(s)
Trying to fix problems with the parser 'yy' and 'zz' stuff so that it works with SCons and hopefuly autotools at same time.
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 libraries?
98 opts.Add(PackageOption(
99 'CUNIT_LIBPATH'
100 ,"Where are your CUnit libraries?"
101 ,"off"
102 ))
103
104 # Where are the Tcl includes?
105 opts.Add(PackageOption(
106 'TCL_CPPPATH'
107 ,"Where are your Tcl include files?"
108 ,None
109 ))
110
111 # Where are the Tcl libs?
112 opts.Add(PackageOption(
113 'TCL_LIBPATH'
114 ,"Where are your Tcl libraries?"
115 ,None
116 ))
117
118 # Where are the Tk includes?
119 opts.Add(PackageOption(
120 'TK_CPPPATH'
121 ,"Where are your Tk include files?"
122 ,None
123 ))
124
125 # Where are the Tk libs?
126 opts.Add(PackageOption(
127 'TK_LIBPATH'
128 ,"Where are your Tk libraries?"
129 ,None
130 ))
131
132
133 # TODO: OTHER OPTIONS?
134
135 # TODO: flags for optimisation
136
137 # TODO: turning on/off bintoken functionality
138
139 # TODO: Where will the 'Makefile.bt' file be installed
140 # ....
141
142 opts.Update(env)
143 opts.Save('options.cache',env)
144
145 Help(opts.GenerateHelpText(env))
146
147 env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
148
149 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
150
151 with_python = (env['WITHOUT_PYTHON']==False)
152
153 with_cunit_tests = env['WITH_CUNIT_TESTS']
154
155 print "SOLVERS:",env['WITH_SOLVERS']
156
157 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
158 print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
159 print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
160
161 subst_dict = {
162 '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
163 , '@GLADE_FILE@':'glade/ascend.glade'
164 , '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
165 , '@ASCEND_ICON@':'glade/ascend.png'
166 , '@HELP_ROOT@':''
167 }
168
169 if env['WITH_LOCAL_HELP']:
170 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
171
172 env.Append(SUBST_DICT=subst_dict)
173
174 #------------------------------------------------------
175 # SPECIAL CONFIGURATION TESTS
176
177 #----------------
178 # SWIG
179
180 import os,re
181
182 def CheckSwigVersion(context):
183 context.Message("Checking version of SWIG... ")
184 cmd = env['SWIG']+' -version'
185 (cin,coutcerr) = os.popen4(cmd);
186 output = coutcerr.read()
187
188 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
189 expr = re.compile(restr,re.M);
190 m = expr.search(output);
191 if not m:
192 context.Result("error running SWIG or detecting SWIG version")
193 return 0
194 maj = int(m.group('maj'))
195 min = int(m.group('min'))
196 pat = int(m.group('pat'))
197
198 if maj == 1 and (
199 min > 3
200 or (min == 3 and pat >= 24)
201 ):
202 context.Result("ok, %d.%d.%d" % (maj,min,pat))
203 return 1;
204 else:
205 context.Result("too old, %d.%d.%d" % (maj,min,pat))
206 return 0;
207
208 #----------------
209 # General purpose library-and-header test
210
211 class KeepContext:
212 def __init__(self,context,varprefix):
213 self.keep = {}
214 for k in ['LIBS','LIBPATH','CPPPATH']:
215 if context.env.has_key(k):
216 self.keep[k] = context.env[k]
217
218 libpath_add = []
219 if context.env.has_key(varprefix+'_LIBPATH'):
220 libpath_add = [env[varprefix+'_LIBPATH']]
221
222 cpppath_add = []
223 if context.env.has_key(varprefix+'_CPPPATH'):
224 cpppath_add = [env[varprefix+'_CPPPATH']]
225
226 context.env.Append(
227 LIBPATH = libpath_add
228 , CPPPATH = cpppath_add
229 )
230
231 def restore(self,context):
232 for k in self.keep:
233 context.env[k]=self.keep[k];
234
235 def CheckExtLib(context,libname,text,ext='.c',varprefix=None):
236 """This method will check for variables LIBNAME_LIBPATH
237 and LIBNAME_CPPPATH and try to compile and link the
238 file with the provided text, linking with the
239 library libname."""
240
241 context.Message( 'Checking for '+libname+'... ' )
242
243 if varprefix==None:
244 varprefix = libname.upper()
245
246 keep = KeepContext(context,varprefix)
247
248 context.env.Append(LIBS=[libname])
249
250 is_ok = context.TryLink(text,ext)
251
252 keep.restore(context)
253
254 context.Result(is_ok)
255 return is_ok
256
257 #----------------
258 # CUnit test
259
260 cunit_test_text = """
261 #include <CUnit/Cunit.h>
262 int maxi(int i1, int i2){
263 return (i1 > i2) ? i1 : i2;
264 }
265
266 void test_maxi(void){
267 CU_ASSERT(maxi(0,2) == 2);
268 CU_ASSERT(maxi(0,-2) == 0);
269 CU_ASSERT(maxi(2,2) == 2);
270
271 }
272 int main(void){
273 /* CU_initialize_registry() */
274 return 0;
275 }
276 """
277
278 def CheckCUnit(context):
279 return context.CheckExtLib(context
280 ,'cunit'
281 ,cunit_test_text
282 )
283
284 #----------------
285 # Tcl test
286
287 tcl_check_text = r"""
288 #include <tcl.h>
289 #include <stdio.h>
290 int main(void){
291 printf("%s",TCL_PATCH_LEVEL);
292 return 0;
293 }
294 """
295
296 def CheckTcl(context):
297 return CheckExtLib(context,'tcl',tcl_check_text)
298
299 def CheckTclVersion(context):
300 keep = KeepContext(context,'TCL')
301 context.Message("Checking Tcl version... ")
302 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
303 keep.restore(context)
304 if not is_ok:
305 context.Result("failed to run check")
306 return 0
307 context.Result(output)
308
309 major,minor,patch = tuple(int(i) for i in output.split("."))
310 if major != 8 or minor > 3:
311 # bad version
312 return 0
313
314 # good version
315 return 1
316
317 #----------------
318 # Tcl test
319
320 tk_check_text = r"""
321 #include <tk.h>
322 #include <stdio.h>
323 int main(void){
324 printf("%s",TK_PATCH_LEVEL);
325 return 0;
326 }
327 """
328 def CheckTk(context):
329 return CheckExtLib(context,'tk',tk_check_text)
330
331 def CheckTkVersion(context):
332 keep = KeepContext(context,'TK')
333 context.Message("Checking Tk version... ")
334 (is_ok,output) = context.TryRun(tk_check_text,'.c')
335 keep.restore(context)
336 if not is_ok:
337 context.Result("failed to run check")
338 return 0
339 context.Result(output)
340
341 major,minor,patch = tuple(int(i) for i in output.split("."))
342 if major != 8 or minor > 3:
343 # bad version
344 return 0
345
346 # good version
347 return 1
348
349 #------------------------------------------------------
350 # CONFIGURATION
351
352 conf = Configure(env
353 , custom_tests = {
354 'CheckSwigVersion' : CheckSwigVersion
355 , 'CheckCUnit' : CheckCUnit
356 , 'CheckTcl' : CheckTcl
357 , 'CheckTclVersion' : CheckTclVersion
358 , 'CheckTk' : CheckTk
359 , 'CheckTkVersion' : CheckTkVersion
360 # , 'CheckIsNan' : CheckIsNan
361 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
362 }
363 , config_h = "config.h"
364 )
365
366 if not conf.CheckSwigVersion():
367 print 'SWIG version is not OK'
368 Exit(1)
369
370 # Math library
371 #if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
372 # print 'Did not find math library, exiting!'
373 # Exit(1)
374
375 # Where is 'isnan'?
376
377 if not conf.CheckFunc('isnan'):
378 print "Didn't find isnan"
379 Exit(1)
380
381 # Tcl/Tk
382
383 if conf.CheckTcl() and conf.CheckTk():
384 if with_tcltk_gui and not conf.CheckTclVersion():
385 without_tcltk_reason = "Require Tcl <= 8.3 Tcl."
386 with_tcltk_gui = False
387
388 if with_tcltk_gui and not conf.CheckTkVersion():
389 without_tcltk_reason += "Require Tk version <= 8.3. See 'scons -h'"
390 with_tcltk_gui = False
391 else:
392 without_tcltk_reason = "Tcl/Tk not found."
393 with_tcltk_gui = False
394
395 # Python... obviously we're already running python, so we just need to
396 # check that we can link to the python library OK:
397
398 if platform.system()=="Windows":
399 python_lib='python24'
400 else:
401 python_lib='python2.4'
402
403 # SWIG version
404
405 if platform.system()=="Windows":
406 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
407 env['ENV']['SWIGFEATURES']='-O'
408 else:
409 env['ENV']['SWIGFEATURES']='-O'
410
411 # CUnit
412
413 if with_cunit_tests:
414 if not conf.CheckCUnit():
415 print "CUnit not found. Use 'scons WITH_CUNIT_TESTS=0'"
416 Exit(1)
417
418 # TODO: -D_HPUX_SOURCE is needed
419
420 # TODO: check size of void*
421
422 # TODO: detect if dynamic libraries are possible or not
423
424 conf.Finish()
425
426 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
427 env.Append(PYTHON_LIB=[python_lib])
428 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
429
430 if not with_python:
431 print "Can't build python interface"
432 Exit(1)
433
434 #------------------------------------------------------
435 # RECIPE: 'SubstInFile', used in pygtk SConscript
436
437 import re
438 from SCons.Script import * # the usual scons stuff you get in a SConscript
439
440 def TOOL_SUBST(env):
441 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
442 from the source to the target.
443 The values of SUBST_DICT first have any construction variables expanded
444 (its keys are not expanded).
445 If a value of SUBST_DICT is a python callable function, it is called and
446 the result is expanded as the value.
447 If there's more than one source and more than one target, each target gets
448 substituted from the corresponding source.
449 """
450 env.Append(TOOLS = 'SUBST')
451 def do_subst_in_file(targetfile, sourcefile, dict):
452 """Replace all instances of the keys of dict with their values.
453 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
454 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
455 """
456 try:
457 f = open(sourcefile, 'rb')
458 contents = f.read()
459 f.close()
460 except:
461 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
462 for (k,v) in dict.items():
463 contents = re.sub(k, v, contents)
464 try:
465 f = open(targetfile, 'wb')
466 f.write(contents)
467 f.close()
468 except:
469 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
470 return 0 # success
471
472 def subst_in_file(target, source, env):
473 if not env.has_key('SUBST_DICT'):
474 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
475 d = dict(env['SUBST_DICT']) # copy it
476 for (k,v) in d.items():
477 if callable(v):
478 d[k] = env.subst(v())
479 elif SCons.Util.is_String(v):
480 d[k]=env.subst(v)
481 else:
482 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
483 for (t,s) in zip(target, source):
484 return do_subst_in_file(str(t), str(s), d)
485
486 def subst_in_file_string(target, source, env):
487 """This is what gets printed on the console."""
488 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
489 for (t,s) in zip(target, source)])
490
491 def subst_emitter(target, source, env):
492 """Add dependency from substituted SUBST_DICT to target.
493 Returns original target, source tuple unchanged.
494 """
495 d = env['SUBST_DICT'].copy() # copy it
496 for (k,v) in d.items():
497 if callable(v):
498 d[k] = env.subst(v())
499 elif SCons.Util.is_String(v):
500 d[k]=env.subst(v)
501 Depends(target, SCons.Node.Python.Value(d))
502 return target, source
503
504 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
505 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
506
507 TOOL_SUBST(env)
508
509 #------------------------------------------------------
510 # SUBDIRECTORIES....
511
512
513 env.Append(CPPPATH=['..'])
514
515 env.SConscript(['base/generic/general/SConscript'],'env')
516
517 env.SConscript(['base/generic/utilities/SConscript'],'env')
518
519 env.SConscript(['base/generic/compiler/SConscript'],'env')
520
521 env.SConscript(['base/generic/solver/SConscript'],'env')
522
523 env.SConscript(['base/generic/packages/SConscript'],'env')
524
525 if with_tcltk_gui:
526 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
527 else:
528 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
529
530 if with_python:
531 env.SConscript(['pygtk/interface/SConscript'],'env')
532 else:
533 print "Skipping... Python GUI isn't being built"
534
535 if with_cunit_tests:
536 testdirs = ['general','solver','utilities']
537 for testdir in testdirs:
538 path = 'base/generic/'+testdir+'/test/'
539 env.SConscript([path+'SConscript'],'env')
540 env.SConscript(['test/SConscript'],'env')
541 env.SConscript(['base/generic/test/SConscript'],'env')
542
543
544 else:
545 print "Skipping... CUnit tests aren't being built"
546
547 #------------------------------------------------------
548 # INSTALLATION
549
550 # TODO: add install options

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