/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 415 - (show annotations) (download)
Mon Apr 3 04:56:45 2006 UTC (13 years, 8 months ago) by johnpye
File size: 14254 byte(s)
Small correction to keep MinGW build working
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 if platform.system()=='Windows' and env.has_key('MSVS'):
16 print "INCLUDE =",env['ENV']['INCLUDE']
17 env.Append(CPPPATH=env['ENV']['INCLUDE'])
18 env.Append(LIBPATH=env['ENV']['LIB'])
19
20 # Package linking option
21 opts.Add(EnumOption(
22 'PACKAGE_LINKING'
23 , 'Style of linking for external libraries'
24 , 'DYNAMIC_PACKAGES'
25 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
26 ))
27
28 # You can turn off building of Tcl/Tk interface
29 opts.Add(BoolOption(
30 'WITHOUT_TCLTK_GUI'
31 ,"Set to True if you don't want to build the original Tcl/Tk GUI."
32 , False
33 ))
34
35 # You can turn off the building of the Python interface
36 opts.Add(BoolOption(
37 'WITHOUT_PYTHON'
38 ,"Set to True if you don't want to build Python wrappers."
39 , False
40 ))
41
42 # Which solvers will we allow?
43 opts.Add(ListOption(
44 'WITH_SOLVERS'
45 ,"List of the solvers you want to build. The default is the minimum that"
46 +" works."
47 ,["QRSLV","CMSLV"]
48 ,['QRSLV','MPS','SLV','OPTSQP'
49 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
50 ,'LSOD','OPTSQP'
51 ]
52 ))
53
54 # Where will the local copy of the help files be kept?
55 opts.Add(PackageOption(
56 'WITH_LOCAL_HELP'
57 , "Directory containing the local copy of the help files (optional)"
58 , "no"
59 ))
60
61 # Will bintoken support be enabled?
62 opts.Add(BoolOption(
63 'WITH_BINTOKEN'
64 ,"Enable bintoken support? This means compiling models as C-code before"
65 +" running them, to increase solving speed for large models."
66 ,False
67 ))
68
69 # What should the default ASCENDLIBRARY path be?
70 # Note: users can change it by editing their ~/.ascend.ini
71 opts.Add(
72 'DEFAULT_ASCENDLIBRARY'
73 ,"Set the default value of the ASCENDLIBRARY -- the location where"
74 +" ASCEND will look for models when running ASCEND"
75 ,os.path.expanduser("~/src/ascend/trunk/models")
76 )
77
78 # Where is SWIG?
79 opts.Add(
80 'SWIG'
81 ,"SWIG location, probably only required for MinGW and MSVC users."
82 +" Enter the location as a Windows-style path, for example"
83 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
84 )
85
86 # Build the test suite?
87 opts.Add(BoolOption(
88 'WITH_CUNIT_TESTS'
89 ,"Whether to build the CUnit tests. Default is off. If set to on,"
90 +" you must have CUnit installed somewhere that SCons can"
91 +" find it."
92 ,False
93 ))
94
95 # Where are the CUnit includes?
96 opts.Add(PackageOption(
97 'CUNIT_CPPPATH'
98 ,"Where are your CUnit include files?"
99 ,"off"
100 ))
101
102 # Where are the CUnit libraries?
103 opts.Add(PackageOption(
104 'CUNIT_LIBPATH'
105 ,"Where are your CUnit libraries?"
106 ,"off"
107 ))
108
109 # Where are the Tcl includes?
110 opts.Add(PackageOption(
111 'TCL_CPPPATH'
112 ,"Where are your Tcl include files?"
113 ,None
114 ))
115
116 # Where are the Tcl libs?
117 opts.Add(PackageOption(
118 'TCL_LIBPATH'
119 ,"Where are your Tcl libraries?"
120 ,None
121 ))
122
123 # Where are the Tk includes?
124 opts.Add(PackageOption(
125 'TK_CPPPATH'
126 ,"Where are your Tk include files?"
127 ,None
128 ))
129
130 # Where are the Tk libs?
131 opts.Add(PackageOption(
132 'TK_LIBPATH'
133 ,"Where are your Tk libraries?"
134 ,None
135 ))
136
137
138 # TODO: OTHER OPTIONS?
139
140 # TODO: flags for optimisation
141
142 # TODO: turning on/off bintoken functionality
143
144 # TODO: Where will the 'Makefile.bt' file be installed
145 # ....
146
147 opts.Update(env)
148 opts.Save('options.cache',env)
149
150 Help(opts.GenerateHelpText(env))
151
152 env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
153
154 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
155
156 with_python = (env['WITHOUT_PYTHON']==False)
157 without_python_reason = None
158
159 with_cunit_tests = env['WITH_CUNIT_TESTS']
160
161 print "SOLVERS:",env['WITH_SOLVERS']
162
163 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
164 print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
165 print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
166
167 subst_dict = {
168 '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
169 , '@GLADE_FILE@':'glade/ascend.glade'
170 , '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
171 , '@ASCEND_ICON@':'glade/ascend.png'
172 , '@HELP_ROOT@':''
173 }
174
175 if env['WITH_LOCAL_HELP']:
176 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
177
178 env.Append(SUBST_DICT=subst_dict)
179
180 #------------------------------------------------------
181 # SPECIAL CONFIGURATION TESTS
182
183 #----------------
184 # SWIG
185
186 import os,re
187
188 def get_swig_version(env):
189 cmd = env['SWIG']+' -version'
190 (cin,coutcerr) = os.popen4(cmd);
191 output = coutcerr.read()
192
193 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
194 expr = re.compile(restr,re.M);
195 m = expr.search(output);
196 if not m:
197 return None
198 maj = int(m.group('maj'))
199 min = int(m.group('min'))
200 pat = int(m.group('pat'))
201
202 return (maj,min,pat)
203
204
205 def CheckSwigVersion(context):
206
207 try:
208 context.Message("Checking version of SWIG... ")
209 maj,min,pat = get_swig_version(context.env)
210 except:
211 context.Result("Failed to detect version, or failed to run SWIG")
212 return 0;
213
214 if maj == 1 and (
215 min > 3
216 or (min == 3 and pat >= 24)
217 ):
218 context.Result("ok, %d.%d.%d" % (maj,min,pat))
219 return 1;
220 else:
221 context.Result("too old, %d.%d.%d" % (maj,min,pat))
222 return 0;
223
224 #----------------
225 # General purpose library-and-header test
226
227 class KeepContext:
228 def __init__(self,context,varprefix):
229 self.keep = {}
230 for k in ['LIBS','LIBPATH','CPPPATH']:
231 if context.env.has_key(k):
232 self.keep[k] = context.env[k]
233
234 libpath_add = []
235 if context.env.has_key(varprefix+'_LIBPATH'):
236 libpath_add = [env[varprefix+'_LIBPATH']]
237
238 cpppath_add = []
239 if context.env.has_key(varprefix+'_CPPPATH'):
240 cpppath_add = [env[varprefix+'_CPPPATH']]
241
242 context.env.Append(
243 LIBPATH = libpath_add
244 , CPPPATH = cpppath_add
245 )
246
247 def restore(self,context):
248 for k in self.keep:
249 context.env[k]=self.keep[k];
250
251 def CheckExtLib(context,libname,text,ext='.c',varprefix=None):
252 """This method will check for variables LIBNAME_LIBPATH
253 and LIBNAME_CPPPATH and try to compile and link the
254 file with the provided text, linking with the
255 library libname."""
256
257 context.Message( 'Checking for '+libname+'... ' )
258
259 if varprefix==None:
260 varprefix = libname.upper()
261
262 keep = KeepContext(context,varprefix)
263
264 context.env.Append(LIBS=[libname])
265
266 is_ok = context.TryLink(text,ext)
267
268 keep.restore(context)
269
270 context.Result(is_ok)
271 return is_ok
272
273 #----------------
274 # CUnit test
275
276 cunit_test_text = """
277 #include <CUnit/Cunit.h>
278 int maxi(int i1, int i2){
279 return (i1 > i2) ? i1 : i2;
280 }
281
282 void test_maxi(void){
283 CU_ASSERT(maxi(0,2) == 2);
284 CU_ASSERT(maxi(0,-2) == 0);
285 CU_ASSERT(maxi(2,2) == 2);
286
287 }
288 int main(void){
289 /* CU_initialize_registry() */
290 return 0;
291 }
292 """
293
294 def CheckCUnit(context):
295 return context.CheckExtLib(context
296 ,'cunit'
297 ,cunit_test_text
298 )
299
300 #----------------
301 # Tcl test
302
303 tcl_check_text = r"""
304 #include <tcl.h>
305 #include <stdio.h>
306 int main(void){
307 printf("%s",TCL_PATCH_LEVEL);
308 return 0;
309 }
310 """
311
312 def CheckTcl(context):
313 return CheckExtLib(context,'tcl',tcl_check_text)
314
315 def CheckTclVersion(context):
316 keep = KeepContext(context,'TCL')
317 context.Message("Checking Tcl version... ")
318 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
319 keep.restore(context)
320 if not is_ok:
321 context.Result("failed to run check")
322 return 0
323 context.Result(output)
324
325 major,minor,patch = tuple(int(i) for i in output.split("."))
326 if major != 8 or minor > 3:
327 # bad version
328 return 0
329
330 # good version
331 return 1
332
333 #----------------
334 # Tcl test
335
336 tk_check_text = r"""
337 #include <tk.h>
338 #include <stdio.h>
339 int main(void){
340 printf("%s",TK_PATCH_LEVEL);
341 return 0;
342 }
343 """
344 def CheckTk(context):
345 return CheckExtLib(context,'tk',tk_check_text)
346
347 def CheckTkVersion(context):
348 keep = KeepContext(context,'TK')
349 context.Message("Checking Tk version... ")
350 (is_ok,output) = context.TryRun(tk_check_text,'.c')
351 keep.restore(context)
352 if not is_ok:
353 context.Result("failed to run check")
354 return 0
355 context.Result(output)
356
357 major,minor,patch = tuple(int(i) for i in output.split("."))
358 if major != 8 or minor > 3:
359 # bad version
360 return 0
361
362 # good version
363 return 1
364
365 #------------------------------------------------------
366 # CONFIGURATION
367
368 conf = Configure(env
369 , custom_tests = {
370 'CheckSwigVersion' : CheckSwigVersion
371 , 'CheckCUnit' : CheckCUnit
372 , 'CheckTcl' : CheckTcl
373 , 'CheckTclVersion' : CheckTclVersion
374 , 'CheckTk' : CheckTk
375 , 'CheckTkVersion' : CheckTkVersion
376 # , 'CheckIsNan' : CheckIsNan
377 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
378 }
379 , config_h = "config.h"
380 )
381
382
383 # Math library
384 if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
385 print 'Did not find math library, exiting!'
386 Exit(1)
387
388 # Where is 'isnan'?
389
390 if not conf.CheckFunc('isnan'):
391 print "Didn't find isnan"
392 # Exit(1)
393
394 # Tcl/Tk
395
396 if conf.CheckTcl() and conf.CheckTk():
397 if with_tcltk_gui and not conf.CheckTclVersion():
398 without_tcltk_reason = "Require Tcl <= 8.3 Tcl."
399 with_tcltk_gui = False
400
401 if with_tcltk_gui and not conf.CheckTkVersion():
402 without_tcltk_reason += "Require Tk version <= 8.3. See 'scons -h'"
403 with_tcltk_gui = False
404 else:
405 without_tcltk_reason = "Tcl/Tk not found."
406 with_tcltk_gui = False
407
408 # Python... obviously we're already running python, so we just need to
409 # check that we can link to the python library OK:
410
411 if platform.system()=="Windows":
412 python_lib='python24'
413 else:
414 python_lib='python2.4'
415
416 # SWIG version
417
418 if platform.system()=="Windows":
419 env['ENV']['SWIGFEATURES']='-O'
420 else:
421 env['ENV']['SWIGFEATURES']='-O'
422
423
424 if not conf.CheckSwigVersion():
425 without_python_reason = 'SWIG >= 1.3.24 is required'
426 with_python = False
427
428 # CUnit
429
430 if with_cunit_tests:
431 if not conf.CheckCUnit():
432 print "CUnit not found. Use 'scons WITH_CUNIT_TESTS=0'"
433 Exit(1)
434
435 # TODO: -D_HPUX_SOURCE is needed
436
437 # TODO: check size of void*
438
439 # TODO: detect if dynamic libraries are possible or not
440
441 conf.Finish()
442
443 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
444 env.Append(PYTHON_LIB=[python_lib])
445 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
446
447 #------------------------------------------------------
448 # RECIPE: 'SubstInFile', used in pygtk SConscript
449
450 import re
451 from SCons.Script import * # the usual scons stuff you get in a SConscript
452
453 def TOOL_SUBST(env):
454 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
455 from the source to the target.
456 The values of SUBST_DICT first have any construction variables expanded
457 (its keys are not expanded).
458 If a value of SUBST_DICT is a python callable function, it is called and
459 the result is expanded as the value.
460 If there's more than one source and more than one target, each target gets
461 substituted from the corresponding source.
462 """
463 env.Append(TOOLS = 'SUBST')
464 def do_subst_in_file(targetfile, sourcefile, dict):
465 """Replace all instances of the keys of dict with their values.
466 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
467 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
468 """
469 try:
470 f = open(sourcefile, 'rb')
471 contents = f.read()
472 f.close()
473 except:
474 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
475 for (k,v) in dict.items():
476 contents = re.sub(k, v, contents)
477 try:
478 f = open(targetfile, 'wb')
479 f.write(contents)
480 f.close()
481 except:
482 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
483 return 0 # success
484
485 def subst_in_file(target, source, env):
486 if not env.has_key('SUBST_DICT'):
487 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
488 d = dict(env['SUBST_DICT']) # copy it
489 for (k,v) in d.items():
490 if callable(v):
491 d[k] = env.subst(v())
492 elif SCons.Util.is_String(v):
493 d[k]=env.subst(v)
494 else:
495 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
496 for (t,s) in zip(target, source):
497 return do_subst_in_file(str(t), str(s), d)
498
499 def subst_in_file_string(target, source, env):
500 """This is what gets printed on the console."""
501 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
502 for (t,s) in zip(target, source)])
503
504 def subst_emitter(target, source, env):
505 """Add dependency from substituted SUBST_DICT to target.
506 Returns original target, source tuple unchanged.
507 """
508 d = env['SUBST_DICT'].copy() # copy it
509 for (k,v) in d.items():
510 if callable(v):
511 d[k] = env.subst(v())
512 elif SCons.Util.is_String(v):
513 d[k]=env.subst(v)
514 Depends(target, SCons.Node.Python.Value(d))
515 return target, source
516
517 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
518 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
519
520 TOOL_SUBST(env)
521
522 #------------------------------------------------------
523 # SUBDIRECTORIES....
524
525
526 env.Append(CPPPATH=['..'])
527
528 env.SConscript(['base/generic/general/SConscript'],'env')
529
530 env.SConscript(['base/generic/utilities/SConscript'],'env')
531
532 env.SConscript(['base/generic/compiler/SConscript'],'env')
533
534 env.SConscript(['base/generic/solver/SConscript'],'env')
535
536 env.SConscript(['base/generic/packages/SConscript'],'env')
537
538 if with_tcltk_gui:
539 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
540 else:
541 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
542
543 if with_python:
544 env.SConscript(['pygtk/interface/SConscript'],'env')
545 else:
546 print "Skipping... Python GUI isn't being built:",without_python_reason
547
548 if with_cunit_tests:
549 testdirs = ['general','solver','utilities']
550 for testdir in testdirs:
551 path = 'base/generic/'+testdir+'/test/'
552 env.SConscript([path+'SConscript'],'env')
553 env.SConscript(['test/SConscript'],'env')
554 env.SConscript(['base/generic/test/SConscript'],'env')
555
556
557 else:
558 print "Skipping... CUnit tests aren't being built"
559
560 #------------------------------------------------------
561 # INSTALLATION
562
563 # TODO: add install options

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