/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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