/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 400 - (hide annotations) (download)
Fri Mar 31 10:59:36 2006 UTC (13 years, 8 months ago) by johnpye
File size: 12256 byte(s)
Almost there with getting Jerry's tests to run. Just sorting out the linking.
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     +" 'c:\msys\1.0\home\john\swigwin-1.3.29\swig.exe'."
79     )
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 400 # Where are the CUnit includes?
98     opts.Add(PackageOption(
99     'CUNIT_LIBPATH'
100     ,"Where are your CUnit include files?"
101     ,"off"
102     ))
103    
104 johnpye 392 # TODO: OTHER OPTIONS?
105    
106     # TODO: flags for optimisation
107    
108 johnpye 393 # TODO: turning on/off bintoken functionality
109    
110 johnpye 400 # TODO: Where will the 'Makefile.bt' file be installed
111     # ....
112    
113 johnpye 385 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 johnpye 386 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
121    
122 johnpye 387 with_python = (env['WITHOUT_PYTHON']==False)
123    
124 johnpye 400 with_cunit_tests = env['WITH_CUNIT_TESTS']
125    
126 johnpye 392 print "SOLVERS:",env['WITH_SOLVERS']
127 johnpye 393
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 johnpye 385 #------------------------------------------------------
146 johnpye 398 # SPECIAL CONFIGURATION TESTS
147    
148 johnpye 400 #----------------
149     # SWIG
150    
151 johnpye 398 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 johnpye 400 min > 3
173     or (min == 3 and pat >= 24)
174 johnpye 398 ):
175     context.Result("ok, %d.%d.%d" % (maj,min,pat))
176     return 1;
177     context.Result("ok, %d.%d.%d" % (maj,min,pat))
178     return 0;
179    
180 johnpye 400 #----------------
181     # General purpose library-and-header test
182    
183    
184     def CheckExtLib(context,libname,text,ext='.c',varprefix=None):
185     """This method will check for variables LIBNAME_LIBPATH
186     and LIBNAME_CPPPATH and try to compile and link the
187     file with the provided text, linking with the
188     library libname."""
189    
190     context.Message( 'Checking for '+libname+'...' )
191    
192     if varprefix==None:
193     varprefix = libname.upper()
194    
195     keep = {}
196     for k in ['LIBS','LIBPATH','CPPPATH']:
197     if context.env.has_key(k):
198     keep[k] = context.env[k]
199    
200     libpath_add = []
201     if context.env.has_key(varprefix+'_LIBPATH'):
202     libpath_add = [env[varprefix+'_LIBPATH']]
203    
204     cpppath_add = []
205     if context.env.has_key(varprefix+'_CPPPATH'):
206     cpppath_add = [env[varprefix+'_CPPPATH']]
207    
208     context.env.Append(
209     LIBS = libname
210     , LIBPATH = libpath_add
211     , CPPPATH = cpppath_add
212     )
213     ret = context.TryLink(cunit_test_text,ext)
214    
215     for k in keep:
216     context.env[k]=keep[k];
217    
218     context.Result( ret )
219     return ret
220    
221     cunit_test_text = """
222     #include <CUnit/Cunit.h>
223     int maxi(int i1, int i2){
224     return (i1 > i2) ? i1 : i2;
225     }
226    
227     void test_maxi(void){
228     CU_ASSERT(maxi(0,2) == 2);
229     CU_ASSERT(maxi(0,-2) == 0);
230     CU_ASSERT(maxi(2,2) == 2);
231    
232     }
233     int main(void){
234     /* CU_initialize_registry() */
235     }
236     """
237    
238     def CheckCUnit(context):
239     return CheckExtLib(context
240     ,'cunit'
241     ,cunit_test_text
242     )
243    
244    
245 johnpye 398 #------------------------------------------------------
246 johnpye 385 # CONFIGURATION
247    
248     conf = Configure(env
249     , custom_tests = {
250 johnpye 398 'CheckSwigVersion' : CheckSwigVersion
251 johnpye 400 , 'CheckCUnit' : CheckCUnit
252     # , 'CheckIsNan' : CheckIsNan
253     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
254 johnpye 385 }
255     , config_h = "config.h"
256     )
257    
258 johnpye 398 if not conf.CheckSwigVersion():
259     print 'SWIG version is not OK'
260     Exit(1)
261    
262 johnpye 385 # Math library
263     if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
264     print 'Did not find libm.a or m.lib, exiting!'
265     Exit(1)
266    
267     # Where is 'isnan'?
268    
269     if not conf.CheckFunc('isnan'):
270     print "Didn't find isnan"
271     Exit(1)
272    
273 johnpye 387 # Tcl/Tk
274 johnpye 386 if not conf.CheckHeader('tcl.h'):
275     with_tcltk_gui = False
276    
277     if not conf.CheckHeader('tk.h'):
278     with_tcltk_gui = False
279    
280     if not conf.CheckLib('tcl'):
281     with_tcltk_gui = False
282    
283     if not conf.CheckLib('tk'):
284     with_tcktk_gui = False
285    
286 johnpye 395 # Python... obviously we're already running python, so we just need to
287     # check that we can link to the python library OK:
288    
289 johnpye 391 if platform.system()=="Windows":
290 johnpye 392 #conf.env.Append(LIBPATH='c:\Python24\libs')
291     #conf.env.Append(CPPPATH='c:\Python24\include')
292 johnpye 395 #python_header='Python.h'
293     python_lib='python24'
294 johnpye 392 #python_libpath=['c:\\Python24\\libs']
295     #python_cpppath=['c:\\Python24\\include']
296 johnpye 391 else:
297 johnpye 395 #python_header='python2.4/Python.h'
298     python_lib='python2.4'
299 johnpye 392 #python_libpath=[]
300     #python_cpppath=['/usr/include/python2.4']
301 johnpye 391
302 johnpye 395 #if not conf.CheckLibWithHeader(python_lib,python_header,'C'
303     # , LIBPATH=[distutils.sysconfig.PREFIX+"/libs"]
304     # , CPPPATH=[distutils.sysconfig.get_python_inc()]
305     #):
306     # print "Didn't find Python 2.4 ("+python_lib+")"
307     # with_python = False
308     #else:
309 johnpye 387
310 johnpye 395 # SWIG version
311    
312 johnpye 396 if platform.system()=="Windows":
313 johnpye 398 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
314 johnpye 396 env['ENV']['SWIGFEATURES']='-O'
315     else:
316     env['ENV']['SWIGFEATURES']='-O'
317 johnpye 395
318 johnpye 400 # CUnit
319    
320     if with_cunit_tests:
321     conf.CheckCUnit()
322    
323 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
324    
325     # TODO: check size of void*
326    
327 johnpye 393 # TODO: detect if dynamic libraries are possible or not
328    
329 johnpye 395 conf.Finish()
330    
331     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
332     env.Append(PYTHON_LIB=[python_lib])
333     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
334     print "PYTHON_LIBPATH =",env['PYTHON_LIBPATH']
335     print "PYTHON_CPPPATH =",env['PYTHON_CPPPATH']
336    
337 johnpye 396 if not with_python:
338     print "Can't build python interface"
339     Exit(1)
340    
341 johnpye 385 #------------------------------------------------------
342 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
343    
344     import re
345 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
346 johnpye 393
347 johnpye 395 def TOOL_SUBST(env):
348     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
349     from the source to the target.
350     The values of SUBST_DICT first have any construction variables expanded
351     (its keys are not expanded).
352     If a value of SUBST_DICT is a python callable function, it is called and
353     the result is expanded as the value.
354     If there's more than one source and more than one target, each target gets
355     substituted from the corresponding source.
356 johnpye 393 """
357 johnpye 395 env.Append(TOOLS = 'SUBST')
358     def do_subst_in_file(targetfile, sourcefile, dict):
359     """Replace all instances of the keys of dict with their values.
360     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
361     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
362     """
363     try:
364     f = open(sourcefile, 'rb')
365     contents = f.read()
366     f.close()
367     except:
368     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
369     for (k,v) in dict.items():
370     contents = re.sub(k, v, contents)
371     try:
372     f = open(targetfile, 'wb')
373     f.write(contents)
374     f.close()
375     except:
376     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
377     return 0 # success
378 johnpye 393
379 johnpye 395 def subst_in_file(target, source, env):
380     if not env.has_key('SUBST_DICT'):
381     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
382     d = dict(env['SUBST_DICT']) # copy it
383     for (k,v) in d.items():
384     if callable(v):
385     d[k] = env.subst(v())
386     elif SCons.Util.is_String(v):
387     d[k]=env.subst(v)
388     else:
389     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
390     for (t,s) in zip(target, source):
391     return do_subst_in_file(str(t), str(s), d)
392 johnpye 393
393 johnpye 395 def subst_in_file_string(target, source, env):
394     """This is what gets printed on the console."""
395     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
396     for (t,s) in zip(target, source)])
397 johnpye 393
398 johnpye 395 def subst_emitter(target, source, env):
399     """Add dependency from substituted SUBST_DICT to target.
400     Returns original target, source tuple unchanged.
401     """
402     d = env['SUBST_DICT'].copy() # copy it
403     for (k,v) in d.items():
404     if callable(v):
405     d[k] = env.subst(v())
406     elif SCons.Util.is_String(v):
407     d[k]=env.subst(v)
408     Depends(target, SCons.Node.Python.Value(d))
409     return target, source
410 johnpye 393
411 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
412     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
413    
414     TOOL_SUBST(env)
415    
416 johnpye 393 #------------------------------------------------------
417 johnpye 385 # SUBDIRECTORIES....
418    
419 johnpye 393
420 johnpye 385 env.Append(CPPPATH=['..'])
421    
422     env.SConscript(['base/generic/general/SConscript'],'env')
423    
424     env.SConscript(['base/generic/utilities/SConscript'],'env')
425    
426     env.SConscript(['base/generic/compiler/SConscript'],'env')
427    
428     env.SConscript(['base/generic/solver/SConscript'],'env')
429    
430     env.SConscript(['base/generic/packages/SConscript'],'env')
431 johnpye 386
432     if with_tcltk_gui:
433     env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
434 johnpye 391 else:
435     print "Skipping... Tcl/Tk GUI isn't being built"
436 johnpye 386
437 johnpye 387 if with_python:
438     env.SConscript(['pygtk/interface/SConscript'],'env')
439 johnpye 391 else:
440     print "Skipping... Python GUI isn't being built"
441 johnpye 400
442     if with_cunit_tests:
443     testdirs = ['general','solver','utilities']
444     for testdir in testdirs:
445     path = 'base/generic/'+testdir+'/test/'
446     env.SConscript([path+'SConscript'],'env')
447     env.SConscript(['test/SConscript'],'env')
448     env.SConscript(['base/generic/test/SConscript'],'env')
449    
450    
451     else:
452     print "Skipping... CUnit tests aren't being built"
453    
454     #------------------------------------------------------
455     # INSTALLATION
456    
457     # TODO: add install options

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