/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 406 - (hide annotations) (download)
Sat Apr 1 05:57:34 2006 UTC (14 years, 6 months ago) by johnpye
File size: 13954 byte(s)
Woops
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 404 return CheckLib(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     if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
372     print 'Did not find libm.a or m.lib, 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 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 395 # Python... obviously we're already running python, so we just need to
394     # check that we can link to the python library OK:
395    
396 johnpye 391 if platform.system()=="Windows":
397 johnpye 395 python_lib='python24'
398 johnpye 391 else:
399 johnpye 395 python_lib='python2.4'
400 johnpye 391
401 johnpye 395 # SWIG version
402    
403 johnpye 396 if platform.system()=="Windows":
404 johnpye 398 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
405 johnpye 396 env['ENV']['SWIGFEATURES']='-O'
406     else:
407     env['ENV']['SWIGFEATURES']='-O'
408 johnpye 395
409 johnpye 400 # CUnit
410    
411     if with_cunit_tests:
412 johnpye 404 if not conf.CheckCUnit():
413     print "CUnit not found. Use 'scons WITH_CUNIT_TESTS=0'"
414     Exit(1)
415 johnpye 400
416 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
417    
418     # TODO: check size of void*
419    
420 johnpye 393 # TODO: detect if dynamic libraries are possible or not
421    
422 johnpye 395 conf.Finish()
423    
424     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
425     env.Append(PYTHON_LIB=[python_lib])
426     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
427    
428 johnpye 396 if not with_python:
429     print "Can't build python interface"
430     Exit(1)
431    
432 johnpye 385 #------------------------------------------------------
433 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
434    
435     import re
436 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
437 johnpye 393
438 johnpye 395 def TOOL_SUBST(env):
439     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
440     from the source to the target.
441     The values of SUBST_DICT first have any construction variables expanded
442     (its keys are not expanded).
443     If a value of SUBST_DICT is a python callable function, it is called and
444     the result is expanded as the value.
445     If there's more than one source and more than one target, each target gets
446     substituted from the corresponding source.
447 johnpye 393 """
448 johnpye 395 env.Append(TOOLS = 'SUBST')
449     def do_subst_in_file(targetfile, sourcefile, dict):
450     """Replace all instances of the keys of dict with their values.
451     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
452     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
453     """
454     try:
455     f = open(sourcefile, 'rb')
456     contents = f.read()
457     f.close()
458     except:
459     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
460     for (k,v) in dict.items():
461     contents = re.sub(k, v, contents)
462     try:
463     f = open(targetfile, 'wb')
464     f.write(contents)
465     f.close()
466     except:
467     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
468     return 0 # success
469 johnpye 393
470 johnpye 395 def subst_in_file(target, source, env):
471     if not env.has_key('SUBST_DICT'):
472     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
473     d = dict(env['SUBST_DICT']) # copy it
474     for (k,v) in d.items():
475     if callable(v):
476     d[k] = env.subst(v())
477     elif SCons.Util.is_String(v):
478     d[k]=env.subst(v)
479     else:
480     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
481     for (t,s) in zip(target, source):
482     return do_subst_in_file(str(t), str(s), d)
483 johnpye 393
484 johnpye 395 def subst_in_file_string(target, source, env):
485     """This is what gets printed on the console."""
486     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
487     for (t,s) in zip(target, source)])
488 johnpye 393
489 johnpye 395 def subst_emitter(target, source, env):
490     """Add dependency from substituted SUBST_DICT to target.
491     Returns original target, source tuple unchanged.
492     """
493     d = env['SUBST_DICT'].copy() # copy it
494     for (k,v) in d.items():
495     if callable(v):
496     d[k] = env.subst(v())
497     elif SCons.Util.is_String(v):
498     d[k]=env.subst(v)
499     Depends(target, SCons.Node.Python.Value(d))
500     return target, source
501 johnpye 393
502 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
503     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
504    
505     TOOL_SUBST(env)
506    
507 johnpye 393 #------------------------------------------------------
508 johnpye 385 # SUBDIRECTORIES....
509    
510 johnpye 393
511 johnpye 385 env.Append(CPPPATH=['..'])
512    
513     env.SConscript(['base/generic/general/SConscript'],'env')
514    
515     env.SConscript(['base/generic/utilities/SConscript'],'env')
516    
517     env.SConscript(['base/generic/compiler/SConscript'],'env')
518    
519     env.SConscript(['base/generic/solver/SConscript'],'env')
520    
521     env.SConscript(['base/generic/packages/SConscript'],'env')
522 johnpye 386
523     if with_tcltk_gui:
524     env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
525 johnpye 391 else:
526 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
527 johnpye 386
528 johnpye 387 if with_python:
529     env.SConscript(['pygtk/interface/SConscript'],'env')
530 johnpye 391 else:
531     print "Skipping... Python GUI isn't being built"
532 johnpye 400
533     if with_cunit_tests:
534     testdirs = ['general','solver','utilities']
535     for testdir in testdirs:
536     path = 'base/generic/'+testdir+'/test/'
537     env.SConscript([path+'SConscript'],'env')
538     env.SConscript(['test/SConscript'],'env')
539     env.SConscript(['base/generic/test/SConscript'],'env')
540    
541    
542     else:
543     print "Skipping... CUnit tests aren't being built"
544    
545     #------------------------------------------------------
546     # INSTALLATION
547    
548     # TODO: add install options

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