/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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