/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 400 - (show annotations) (download)
Fri Mar 31 10:59:36 2006 UTC (17 years, 5 months ago) by johnpye
File size: 12256 byte(s)
Almost there with getting Jerry's tests to run. Just sorting out the linking.
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 (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 min > 3
173 or (min == 3 and pat >= 24)
174 ):
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 #----------------
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 #------------------------------------------------------
246 # CONFIGURATION
247
248 conf = Configure(env
249 , custom_tests = {
250 'CheckSwigVersion' : CheckSwigVersion
251 , 'CheckCUnit' : CheckCUnit
252 # , 'CheckIsNan' : CheckIsNan
253 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
254 }
255 , config_h = "config.h"
256 )
257
258 if not conf.CheckSwigVersion():
259 print 'SWIG version is not OK'
260 Exit(1)
261
262 # 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 # Tcl/Tk
274 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 # 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 if platform.system()=="Windows":
290 #conf.env.Append(LIBPATH='c:\Python24\libs')
291 #conf.env.Append(CPPPATH='c:\Python24\include')
292 #python_header='Python.h'
293 python_lib='python24'
294 #python_libpath=['c:\\Python24\\libs']
295 #python_cpppath=['c:\\Python24\\include']
296 else:
297 #python_header='python2.4/Python.h'
298 python_lib='python2.4'
299 #python_libpath=[]
300 #python_cpppath=['/usr/include/python2.4']
301
302 #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
310 # SWIG version
311
312 if platform.system()=="Windows":
313 #env['SWIG']=['c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe']
314 env['ENV']['SWIGFEATURES']='-O'
315 else:
316 env['ENV']['SWIGFEATURES']='-O'
317
318 # CUnit
319
320 if with_cunit_tests:
321 conf.CheckCUnit()
322
323 # TODO: -D_HPUX_SOURCE is needed
324
325 # TODO: check size of void*
326
327 # TODO: detect if dynamic libraries are possible or not
328
329 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 if not with_python:
338 print "Can't build python interface"
339 Exit(1)
340
341 #------------------------------------------------------
342 # RECIPE: 'SubstInFile', used in pygtk SConscript
343
344 import re
345 from SCons.Script import * # the usual scons stuff you get in a SConscript
346
347 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 """
357 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
379 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
393 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
398 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
411 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 #------------------------------------------------------
417 # SUBDIRECTORIES....
418
419
420 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
432 if with_tcltk_gui:
433 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
434 else:
435 print "Skipping... Tcl/Tk GUI isn't being built"
436
437 if with_python:
438 env.SConscript(['pygtk/interface/SConscript'],'env')
439 else:
440 print "Skipping... Python GUI isn't being built"
441
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