/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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