/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 412 - (hide annotations) (download)
Mon Apr 3 03:31:30 2006 UTC (14 years 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 johnpye 393 import os, commands, platform, distutils.sysconfig, os.path
2 johnpye 385
3     #------------------------------------------------------
4     # OPTIONS
5 johnpye 392 #
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 johnpye 385
9     opts = Options(['options.cache', 'config.py'])
10     print "PLATFORM = ",platform.system()
11    
12 johnpye 392 # Import the outside environment
13     env = Environment(ENV=os.environ)
14 johnpye 385
15     # Package linking option
16 johnpye 386 opts.Add(EnumOption(
17     'PACKAGE_LINKING'
18 johnpye 385 , 'Style of linking for external libraries'
19     , 'DYNAMIC_PACKAGES'
20 johnpye 386 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
21     ))
22 johnpye 385
23 johnpye 392 # You can turn off building of Tcl/Tk interface
24 johnpye 386 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 johnpye 392 # You can turn off the building of the Python interface
31 johnpye 387 opts.Add(BoolOption(
32     'WITHOUT_PYTHON'
33     ,"Set to True if you don't want to build Python wrappers."
34     , False
35     ))
36    
37 johnpye 392 # Which solvers will we allow?
38     opts.Add(ListOption(
39     'WITH_SOLVERS'
40 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
41     +" works."
42 johnpye 392 ,["QRSLV","CMSLV"]
43     ,['QRSLV','MPS','SLV','OPTSQP'
44     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
45     ,'LSOD','OPTSQP'
46     ]
47     ))
48    
49 johnpye 393 # 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 johnpye 398 # What should the default ASCENDLIBRARY path be?
65     # Note: users can change it by editing their ~/.ascend.ini
66 johnpye 393 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 johnpye 398 # 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 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
79 johnpye 398 )
80    
81 johnpye 400 # 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 johnpye 393
90 johnpye 400 # Where are the CUnit includes?
91     opts.Add(PackageOption(
92     'CUNIT_CPPPATH'
93     ,"Where are your CUnit include files?"
94     ,"off"
95     ))
96 johnpye 392
97 johnpye 404 # Where are the CUnit libraries?
98 johnpye 400 opts.Add(PackageOption(
99     'CUNIT_LIBPATH'
100 johnpye 404 ,"Where are your CUnit libraries?"
101 johnpye 400 ,"off"
102     ))
103    
104 johnpye 404 # 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 johnpye 405 # Where are the Tk includes?
119     opts.Add(PackageOption(
120     'TK_CPPPATH'
121     ,"Where are your Tk include files?"
122     ,None
123     ))
124 johnpye 404
125 johnpye 405 # Where are the Tk libs?
126     opts.Add(PackageOption(
127     'TK_LIBPATH'
128     ,"Where are your Tk libraries?"
129     ,None
130     ))
131    
132    
133 johnpye 392 # TODO: OTHER OPTIONS?
134    
135     # TODO: flags for optimisation
136    
137 johnpye 393 # TODO: turning on/off bintoken functionality
138    
139 johnpye 400 # TODO: Where will the 'Makefile.bt' file be installed
140     # ....
141    
142 johnpye 385 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 johnpye 386 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
150    
151 johnpye 387 with_python = (env['WITHOUT_PYTHON']==False)
152    
153 johnpye 400 with_cunit_tests = env['WITH_CUNIT_TESTS']
154    
155 johnpye 392 print "SOLVERS:",env['WITH_SOLVERS']
156 johnpye 393
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 johnpye 385 #------------------------------------------------------
175 johnpye 398 # SPECIAL CONFIGURATION TESTS
176    
177 johnpye 400 #----------------
178     # SWIG
179    
180 johnpye 398 import os,re
181    
182     def CheckSwigVersion(context):
183 johnpye 405 context.Message("Checking version of SWIG... ")
184 johnpye 403 cmd = env['SWIG']+' -version'
185     (cin,coutcerr) = os.popen4(cmd);
186     output = coutcerr.read()
187 johnpye 398
188 johnpye 403 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 johnpye 398 m = expr.search(output);
191     if not m:
192 johnpye 403 context.Result("error running SWIG or detecting SWIG version")
193 johnpye 398 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 johnpye 400 min > 3
200     or (min == 3 and pat >= 24)
201 johnpye 398 ):
202     context.Result("ok, %d.%d.%d" % (maj,min,pat))
203     return 1;
204 johnpye 401 else:
205     context.Result("too old, %d.%d.%d" % (maj,min,pat))
206     return 0;
207 johnpye 398
208 johnpye 400 #----------------
209     # General purpose library-and-header test
210    
211 johnpye 404 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 johnpye 400
222 johnpye 404 cpppath_add = []
223     if context.env.has_key(varprefix+'_CPPPATH'):
224     cpppath_add = [env[varprefix+'_CPPPATH']]
225 johnpye 405
226     context.env.Append(
227     LIBPATH = libpath_add
228     , CPPPATH = cpppath_add
229     )
230 johnpye 404
231     def restore(self,context):
232     for k in self.keep:
233     context.env[k]=self.keep[k];
234    
235 johnpye 400 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 johnpye 405 context.Message( 'Checking for '+libname+'... ' )
242 johnpye 400
243     if varprefix==None:
244     varprefix = libname.upper()
245    
246 johnpye 404 keep = KeepContext(context,varprefix)
247 johnpye 400
248 johnpye 405 context.env.Append(LIBS=[libname])
249    
250 johnpye 404 is_ok = context.TryLink(text,ext)
251 johnpye 400
252 johnpye 405 keep.restore(context)
253 johnpye 400
254 johnpye 404 context.Result(is_ok)
255     return is_ok
256    
257     #----------------
258     # CUnit test
259    
260 johnpye 400 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 johnpye 404 return 0;
275 johnpye 400 }
276     """
277    
278     def CheckCUnit(context):
279 johnpye 412 return context.CheckExtLib(context
280 johnpye 400 ,'cunit'
281     ,cunit_test_text
282     )
283    
284 johnpye 404 #----------------
285 johnpye 405 # Tcl test
286 johnpye 404
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 johnpye 405 return CheckExtLib(context,'tcl',tcl_check_text)
298    
299     def CheckTclVersion(context):
300 johnpye 404 keep = KeepContext(context,'TCL')
301 johnpye 405 context.Message("Checking Tcl version... ")
302     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
303 johnpye 404 keep.restore(context)
304     if not is_ok:
305 johnpye 405 context.Result("failed to run check")
306 johnpye 404 return 0
307 johnpye 405 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 johnpye 404 return 1
316    
317 johnpye 405 #----------------
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 johnpye 404 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 johnpye 400
346 johnpye 404 # good version
347     return 1
348    
349 johnpye 398 #------------------------------------------------------
350 johnpye 385 # CONFIGURATION
351    
352     conf = Configure(env
353     , custom_tests = {
354 johnpye 398 'CheckSwigVersion' : CheckSwigVersion
355 johnpye 400 , 'CheckCUnit' : CheckCUnit
356 johnpye 404 , 'CheckTcl' : CheckTcl
357     , 'CheckTclVersion' : CheckTclVersion
358 johnpye 405 , 'CheckTk' : CheckTk
359     , 'CheckTkVersion' : CheckTkVersion
360 johnpye 400 # , 'CheckIsNan' : CheckIsNan
361     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
362 johnpye 385 }
363     , config_h = "config.h"
364     )
365    
366 johnpye 398 if not conf.CheckSwigVersion():
367     print 'SWIG version is not OK'
368     Exit(1)
369    
370 johnpye 385 # Math library
371 johnpye 412 #if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
372     # print 'Did not find math library, exiting!'
373     # Exit(1)
374 johnpye 385
375     # Where is 'isnan'?
376    
377     if not conf.CheckFunc('isnan'):
378     print "Didn't find isnan"
379     Exit(1)
380    
381 johnpye 387 # Tcl/Tk
382 johnpye 386
383 johnpye 405 if conf.CheckTcl() and conf.CheckTk():
384 johnpye 404 if with_tcltk_gui and not conf.CheckTclVersion():
385 johnpye 405 without_tcltk_reason = "Require Tcl <= 8.3 Tcl."
386 johnpye 404 with_tcltk_gui = False
387 johnpye 386
388 johnpye 405 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 johnpye 412 with_tcltk_gui = False
394    
395 johnpye 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 johnpye 391 if platform.system()=="Windows":
399 johnpye 395 python_lib='python24'
400 johnpye 391 else:
401 johnpye 395 python_lib='python2.4'
402 johnpye 391
403 johnpye 395 # SWIG version
404    
405 johnpye 396 if platform.system()=="Windows":
406 johnpye 398 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
407 johnpye 396 env['ENV']['SWIGFEATURES']='-O'
408     else:
409     env['ENV']['SWIGFEATURES']='-O'
410 johnpye 395
411 johnpye 400 # CUnit
412    
413     if with_cunit_tests:
414 johnpye 404 if not conf.CheckCUnit():
415     print "CUnit not found. Use 'scons WITH_CUNIT_TESTS=0'"
416     Exit(1)
417 johnpye 400
418 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
419    
420     # TODO: check size of void*
421    
422 johnpye 393 # TODO: detect if dynamic libraries are possible or not
423    
424 johnpye 395 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 johnpye 396 if not with_python:
431     print "Can't build python interface"
432     Exit(1)
433    
434 johnpye 385 #------------------------------------------------------
435 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
436    
437     import re
438 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
439 johnpye 393
440 johnpye 395 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 johnpye 393 """
450 johnpye 395 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 johnpye 393
472 johnpye 395 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 johnpye 393
486 johnpye 395 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 johnpye 393
491 johnpye 395 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 johnpye 393
504 johnpye 395 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 johnpye 393 #------------------------------------------------------
510 johnpye 385 # SUBDIRECTORIES....
511    
512 johnpye 393
513 johnpye 385 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 johnpye 386
525     if with_tcltk_gui:
526     env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
527 johnpye 391 else:
528 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
529 johnpye 386
530 johnpye 387 if with_python:
531     env.SConscript(['pygtk/interface/SConscript'],'env')
532 johnpye 391 else:
533     print "Skipping... Python GUI isn't being built"
534 johnpye 400
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