/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 403 - (show 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 import os, commands, platform, distutils.sysconfig, os.path
2
3 #------------------------------------------------------
4 # OPTIONS
5 #
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
9 opts = Options(['options.cache', 'config.py'])
10 print "PLATFORM = ",platform.system()
11
12 # Import the outside environment
13 env = Environment(ENV=os.environ)
14
15 # Package linking option
16 opts.Add(EnumOption(
17 'PACKAGE_LINKING'
18 , 'Style of linking for external libraries'
19 , 'DYNAMIC_PACKAGES'
20 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
21 ))
22
23 # You can turn off building of Tcl/Tk interface
24 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 # You can turn off the building of the Python interface
31 opts.Add(BoolOption(
32 'WITHOUT_PYTHON'
33 ,"Set to True if you don't want to build Python wrappers."
34 , False
35 ))
36
37 # Which solvers will we allow?
38 opts.Add(ListOption(
39 'WITH_SOLVERS'
40 ,"List of the solvers you want to build. The default is the minimum that"
41 +" works."
42 ,["QRSLV","CMSLV"]
43 ,['QRSLV','MPS','SLV','OPTSQP'
44 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
45 ,'LSOD','OPTSQP'
46 ]
47 ))
48
49 # 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 # What should the default ASCENDLIBRARY path be?
65 # Note: users can change it by editing their ~/.ascend.ini
66 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 # 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 # 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
90 # Where are the CUnit includes?
91 opts.Add(PackageOption(
92 'CUNIT_CPPPATH'
93 ,"Where are your CUnit include files?"
94 ,"off"
95 ))
96
97 # Where are the CUnit includes?
98 opts.Add(PackageOption(
99 'CUNIT_LIBPATH'
100 ,"Where are your CUnit include files?"
101 ,"off"
102 ))
103
104 # TODO: OTHER OPTIONS?
105
106 # TODO: flags for optimisation
107
108 # TODO: turning on/off bintoken functionality
109
110 # TODO: Where will the 'Makefile.bt' file be installed
111 # ....
112
113 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 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
121
122 with_python = (env['WITHOUT_PYTHON']==False)
123
124 with_cunit_tests = env['WITH_CUNIT_TESTS']
125
126 print "SOLVERS:",env['WITH_SOLVERS']
127
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 #------------------------------------------------------
146 # SPECIAL CONFIGURATION TESTS
147
148 #----------------
149 # SWIG
150
151 import os,re
152
153 def CheckSwigVersion(context):
154 context.Message("Checking version of SWIG")
155 cmd = env['SWIG']+' -version'
156 (cin,coutcerr) = os.popen4(cmd);
157 output = coutcerr.read()
158
159 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 m = expr.search(output);
162 if not m:
163 context.Result("error running SWIG or detecting SWIG version")
164 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 min > 3
171 or (min == 3 and pat >= 24)
172 ):
173 context.Result("ok, %d.%d.%d" % (maj,min,pat))
174 return 1;
175 else:
176 context.Result("too old, %d.%d.%d" % (maj,min,pat))
177 return 0;
178
179 #----------------
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 #------------------------------------------------------
245 # CONFIGURATION
246
247 conf = Configure(env
248 , custom_tests = {
249 'CheckSwigVersion' : CheckSwigVersion
250 , 'CheckCUnit' : CheckCUnit
251 # , 'CheckIsNan' : CheckIsNan
252 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
253 }
254 , config_h = "config.h"
255 )
256
257 if not conf.CheckSwigVersion():
258 print 'SWIG version is not OK'
259 Exit(1)
260
261 # 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 # Tcl/Tk
273 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 # 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 if platform.system()=="Windows":
289 #conf.env.Append(LIBPATH='c:\Python24\libs')
290 #conf.env.Append(CPPPATH='c:\Python24\include')
291 #python_header='Python.h'
292 python_lib='python24'
293 #python_libpath=['c:\\Python24\\libs']
294 #python_cpppath=['c:\\Python24\\include']
295 else:
296 #python_header='python2.4/Python.h'
297 python_lib='python2.4'
298 #python_libpath=[]
299 #python_cpppath=['/usr/include/python2.4']
300
301 #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
309 # SWIG version
310
311 if platform.system()=="Windows":
312 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
313 env['ENV']['SWIGFEATURES']='-O'
314 else:
315 env['ENV']['SWIGFEATURES']='-O'
316
317 # CUnit
318
319 if with_cunit_tests:
320 conf.CheckCUnit()
321
322 # TODO: -D_HPUX_SOURCE is needed
323
324 # TODO: check size of void*
325
326 # TODO: detect if dynamic libraries are possible or not
327
328 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 if not with_python:
337 print "Can't build python interface"
338 Exit(1)
339
340 #------------------------------------------------------
341 # RECIPE: 'SubstInFile', used in pygtk SConscript
342
343 import re
344 from SCons.Script import * # the usual scons stuff you get in a SConscript
345
346 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 """
356 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
378 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
392 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
397 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
410 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 #------------------------------------------------------
416 # SUBDIRECTORIES....
417
418
419 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
431 if with_tcltk_gui:
432 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
433 else:
434 print "Skipping... Tcl/Tk GUI isn't being built"
435
436 if with_python:
437 env.SConscript(['pygtk/interface/SConscript'],'env')
438 else:
439 print "Skipping... Python GUI isn't being built"
440
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