/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 782 - (hide annotations) (download)
Tue Jul 25 02:09:12 2006 UTC (13 years, 4 months ago) by johnpye
File size: 35408 byte(s)
Radu Serban sent me a preview of the new version of IDA which has new header file layout.
This patch updates for the new layout.
Also couple of minor fixes for gcc warnings in numlist and library.cpp.
1 johnpye 393 import os, commands, platform, distutils.sysconfig, os.path
2 johnpye 385
3 johnpye 748 version = "0.9.5.95"
4 johnpye 439
5 johnpye 385 #------------------------------------------------------
6     # OPTIONS
7 johnpye 392 #
8     # Note that if you set the options via the command line, they will be
9     # remembered in the file 'options.cache'. It's a feature ;-)
10 johnpye 385
11     opts = Options(['options.cache', 'config.py'])
12 johnpye 464 #print "PLATFORM = ",platform.system()
13 johnpye 385
14 johnpye 464 if platform.system()=="Windows":
15 johnpye 631 default_tcl_lib = "tcl84"
16     default_tk_lib = "tk84"
17 johnpye 464 default_tktable_lib = "Tktable28"
18 johnpye 499 default_install_assets = "glade/"
19     icon_extension = '.png'
20 johnpye 521 default_tcl = "c:\\Tcl"
21 johnpye 643 if os.environ.get('MSYSTEM')=="MINGW32":
22 johnpye 642 default_tcl_libpath="$TCL\\bin"
23     else:
24     default_tcl_libpath="$TCL\\lib"
25 johnpye 627 default_rel_distdir = '.'
26 johnpye 628 default_absolute_paths = False
27 johnpye 739
28     default_ida_prefix = "c:\\MinGW"
29     if not os.path.exists(default_ida_prefix):
30     default_ida_prefix = None
31    
32 johnpye 673 need_libm = False
33 johnpye 683 python_exe = "c:\\Python24\\python.exe"
34 johnpye 464 else:
35 johnpye 673 default_tcl_lib = "tcl8.4"
36     default_tk_lib = "tk8.4"
37 johnpye 464 default_tktable_lib = "Tktable2.8"
38 johnpye 628 default_install_assets = "$INSTALL_ASCDATA/glade/"
39 johnpye 499 icon_extension = '.svg'
40 johnpye 684 default_tcl = '/usr'
41 johnpye 541 default_tcl_libpath = "$TCL/lib"
42 johnpye 627 default_rel_distdir = '../share/ascend'
43 johnpye 628 default_absolute_paths = True
44 johnpye 673 default_ida_prefix="/usr/local"
45     need_libm = True
46 johnpye 551 if not os.path.isdir(default_tcl):
47     default_tcl = '/usr'
48 johnpye 683 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
49 johnpye 551
50 johnpye 562 opts.Add(
51     'CC'
52     ,'C Compiler command'
53     ,None
54     )
55    
56     opts.Add(
57     'CXX'
58     ,'C++ Compiler command'
59     ,None
60     )
61    
62 johnpye 591 opts.Add(BoolOption(
63     'GCOV'
64 johnpye 593 , 'Whether to enable coverage testing in object code'
65     , False
66 johnpye 591 ))
67    
68 johnpye 385 # Package linking option
69 johnpye 386 opts.Add(EnumOption(
70     'PACKAGE_LINKING'
71 johnpye 385 , 'Style of linking for external libraries'
72     , 'DYNAMIC_PACKAGES'
73 johnpye 386 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
74     ))
75 johnpye 385
76 johnpye 526 opts.Add(BoolOption(
77     'WITH_GCCVISIBILITY'
78     ,"Whether to use GCC Visibility features (only applicable if available)"
79     ,True
80     ))
81    
82 johnpye 392 # You can turn off building of Tcl/Tk interface
83 johnpye 386 opts.Add(BoolOption(
84 johnpye 542 'WITH_TCLTK'
85 johnpye 673 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
86 johnpye 542 , True
87 johnpye 386 ))
88    
89 johnpye 392 # You can turn off the building of the Python interface
90 johnpye 387 opts.Add(BoolOption(
91 johnpye 542 'WITH_PYTHON'
92 johnpye 673 ,"Set to False if you don't want to build Python wrappers."
93 johnpye 542 , True
94 johnpye 387 ))
95    
96 johnpye 392 # Which solvers will we allow?
97     opts.Add(ListOption(
98     'WITH_SOLVERS'
99 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
100     +" works."
101 johnpye 673 ,["QRSLV","CMSLV","LSOD","IDA"]
102 johnpye 392 ,['QRSLV','MPS','SLV','OPTSQP'
103     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
104 johnpye 673 ,'LSOD','OPTSQP',"IDA"
105 johnpye 392 ]
106     ))
107    
108 johnpye 393 # Where will the local copy of the help files be kept?
109     opts.Add(PackageOption(
110     'WITH_LOCAL_HELP'
111     , "Directory containing the local copy of the help files (optional)"
112     , "no"
113     ))
114    
115     # Will bintoken support be enabled?
116     opts.Add(BoolOption(
117     'WITH_BINTOKEN'
118     ,"Enable bintoken support? This means compiling models as C-code before"
119     +" running them, to increase solving speed for large models."
120     ,False
121     ))
122    
123 johnpye 398 # What should the default ASCENDLIBRARY path be?
124     # Note: users can change it by editing their ~/.ascend.ini
125 johnpye 393 opts.Add(
126     'DEFAULT_ASCENDLIBRARY'
127     ,"Set the default value of the ASCENDLIBRARY -- the location where"
128     +" ASCEND will look for models when running ASCEND"
129 johnpye 628 ,"$INSTALL_ASCDATA/models"
130 johnpye 393 )
131    
132 johnpye 398 # Where is SWIG?
133     opts.Add(
134     'SWIG'
135     ,"SWIG location, probably only required for MinGW and MSVC users."
136     +" Enter the location as a Windows-style path, for example"
137 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
138 johnpye 398 )
139    
140 johnpye 400 # Build the test suite?
141     opts.Add(BoolOption(
142 johnpye 593 'WITH_CUNIT'
143 johnpye 665 ,"You can disable CUnit tests with this option. This will basically stop"
144     +" SCons from parsing the SConscript files relating to the 'test'"
145     +" target, which just might make things marginally faster. Probably"
146     +" you can just ignore this option though. SCons will sniff for Cunit"
147     +" but build the tests only if you specify the 'test' target."
148     ,True
149 johnpye 400 ))
150 johnpye 393
151 johnpye 400 # Where are the CUnit includes?
152     opts.Add(PackageOption(
153     'CUNIT_CPPPATH'
154     ,"Where are your CUnit include files?"
155 johnpye 459 ,'off'
156 johnpye 400 ))
157 johnpye 392
158 johnpye 404 # Where are the CUnit libraries?
159 johnpye 400 opts.Add(PackageOption(
160     'CUNIT_LIBPATH'
161 johnpye 404 ,"Where are your CUnit libraries?"
162 johnpye 459 ,'off'
163 johnpye 400 ))
164    
165 johnpye 673 opts.Add(PackageOption(
166     "IDA_PREFIX"
167     ,"Prefix for your IDA install (IDA ./configure --prefix)"
168     ,default_ida_prefix
169     ))
170 johnpye 521
171 johnpye 534 opts.Add(
172 johnpye 782 "IDA_LIB"
173     ,"Libraries linked to for IDA"
174     ,['sundials_ida','sundials_nvecserial','m']
175     )
176    
177     opts.Add(
178 johnpye 673 'IDA_CPPPATH'
179     ,"Where is your ida.h?"
180     ,"$IDA_PREFIX/include"
181     )
182    
183     opts.Add(
184     'IDA_LIBPATH'
185     ,"Where are your SUNDIALS libraries installed?"
186     ,"$IDA_PREFIX/lib"
187     )
188    
189     opts.Add(
190     "F2C_LIB"
191     ,"F2C library (eg. g2c, gfortran, f2c)"
192     ,"g2c"
193     )
194    
195     opts.Add(PackageOption(
196     "F2C_LIBPATH"
197     ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
198     ,"off"
199     ))
200    
201     opts.Add(
202 johnpye 521 'TCL'
203     ,'Base of Tcl distribution'
204     ,default_tcl
205 johnpye 534 )
206 johnpye 521
207 johnpye 404 # Where are the Tcl includes?
208 johnpye 534 opts.Add(
209 johnpye 404 'TCL_CPPPATH'
210     ,"Where are your Tcl include files?"
211 johnpye 521 ,"$TCL/include"
212 johnpye 534 )
213 johnpye 404
214     # Where are the Tcl libs?
215 johnpye 534 opts.Add(
216 johnpye 404 'TCL_LIBPATH'
217     ,"Where are your Tcl libraries?"
218 johnpye 541 ,default_tcl_libpath
219 johnpye 534 )
220 johnpye 404
221 johnpye 428 # What is the name of the Tcl lib?
222     opts.Add(
223     'TCL_LIB'
224 johnpye 561 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
225 johnpye 464 ,default_tcl_lib
226 johnpye 428 )
227    
228 johnpye 405 # Where are the Tk includes?
229 johnpye 534 opts.Add(
230 johnpye 405 'TK_CPPPATH'
231     ,"Where are your Tk include files?"
232 johnpye 464 ,'$TCL_CPPPATH'
233 johnpye 534 )
234 johnpye 404
235 johnpye 405 # Where are the Tk libs?
236 johnpye 534 opts.Add(
237 johnpye 405 'TK_LIBPATH'
238     ,"Where are your Tk libraries?"
239 johnpye 464 ,'$TCL_LIBPATH'
240 johnpye 534 )
241 johnpye 405
242 johnpye 428 # What is the name of the Tk lib?
243     opts.Add(
244     'TK_LIB'
245 johnpye 521 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
246 johnpye 464 ,default_tk_lib
247 johnpye 435 )
248    
249 johnpye 460 # Static linking to TkTable
250    
251     opts.Add(BoolOption(
252 johnpye 521 'STATIC_TCLTK'
253 johnpye 554 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
254 johnpye 460 ,False
255     ))
256    
257 johnpye 464 opts.Add(
258 johnpye 460 'TKTABLE_LIBPATH'
259     ,'Location of TkTable static library'
260 johnpye 464 ,'$TCL_LIBPATH/Tktable2.8'
261     )
262 johnpye 460
263 johnpye 435 opts.Add(
264 johnpye 460 'TKTABLE_LIB'
265 johnpye 521 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
266 johnpye 464 ,default_tktable_lib
267 johnpye 460 )
268    
269     opts.Add(
270 johnpye 521 'TKTABLE_CPPPATH'
271     ,'Location of TkTable header file'
272     ,'$TCL_CPPPATH'
273     )
274    
275     opts.Add(
276     'X11'
277 johnpye 554 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
278 johnpye 521 ,'/usr/X11R6'
279     )
280    
281     opts.Add(
282     'X11_LIBPATH'
283 johnpye 554 ,'Location of X11 lib. EXPERIMENTAL'
284 johnpye 521 ,'$X11/lib'
285     )
286    
287     opts.Add(
288     'X11_CPPPATH'
289 johnpye 554 ,'Location of X11 includes. EXPERIMENTAL'
290 johnpye 521 ,'$X11/include'
291     )
292    
293     opts.Add(
294     'X11_LIB'
295 johnpye 554 ,'Name of X11 lib. EXPERIMENTAL'
296 johnpye 521 ,'X11'
297     )
298    
299     opts.Add(
300 johnpye 435 'INSTALL_PREFIX'
301     ,'Root location for installed files'
302 johnpye 449 ,'/usr/local'
303 johnpye 428 )
304    
305 johnpye 435 opts.Add(
306     'INSTALL_BIN'
307     ,'Location to put binaries during installation'
308     ,"$INSTALL_PREFIX/bin"
309     )
310    
311     opts.Add(
312 johnpye 463 'INSTALL_LIB'
313 johnpye 683 ,'Location to put libraries during installation'
314 johnpye 463 ,"$INSTALL_PREFIX/lib"
315     )
316    
317     opts.Add(
318 ben.allan 624 'INSTALL_SHARE'
319 johnpye 628 ,'Common shared-file location on this system'
320     ,"$INSTALL_PREFIX/share"
321 johnpye 435 )
322    
323 johnpye 628
324 johnpye 435 opts.Add(
325 johnpye 628 'INSTALL_ASCDATA'
326     ,"Location of ASCEND shared data (TK, python, models etc)"
327     ,"$INSTALL_SHARE/ascend"
328     )
329    
330     opts.Add(
331 johnpye 435 'INSTALL_INCLUDE'
332     ,'Location to put header files during installation'
333     ,"$INSTALL_PREFIX/include"
334     )
335    
336 johnpye 448 opts.Add(
337 johnpye 455 'PYGTK_ASSETS'
338 johnpye 532 ,'Default location for Glade assets (placed in pygtk/config.py)'
339 johnpye 455 ,default_install_assets
340     )
341    
342 johnpye 508 opts.Add(BoolOption(
343     'DEBUG'
344     ,"Compile source with debugger symbols, eg for use with 'gdb'"
345     ,False
346     ))
347    
348 johnpye 597 opts.Add(BoolOption(
349     'MALLOC_DEBUG'
350     ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
351     ,False
352     ))
353    
354 johnpye 455 opts.Add(
355 johnpye 448 'INSTALL_ROOT'
356     ,'For use by RPM only: location of %{buildroot} during rpmbuild'
357     ,""
358     )
359    
360 johnpye 563 opts.Add(
361     'DISTTAR_NAME'
362     ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
363     ,"ascend-"+version
364     )
365    
366 johnpye 656 opts.Add(
367     'RELEASE'
368     ,"Release number for use in RPM spec file. This should always start with a zero for releases made by the ASCEND group, in order that third parties can make 'patch' releases of higher version numbers."
369     ,"0"
370     )
371    
372 johnpye 605 opts.Add(BoolOption(
373 johnpye 628 'ABSOLUTE_PATHS'
374 johnpye 605 ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
375 johnpye 628 ,default_absolute_paths
376 johnpye 605 ))
377    
378 johnpye 578 opts.Add(
379     'WIN_INSTALLER_NAME'
380     ,"Name of the installer .exe to create under Windows (minus the '.exe')"
381     ,"ascend-"+version
382     )
383    
384 johnpye 594 opts.Add(BoolOption(
385     'WITH_XTERM_COLORS'
386     ,"Set to 0 if you don't want xterm colour codes in the console output"
387     ,True
388     ))
389    
390 johnpye 761 opts.Add(BoolOption(
391     'WITH_EXTFNS'
392     ,"Set to 0 if you don't want to attempt to build external modules bundled"
393     + " with ASCEND."
394     ,True
395     ))
396    
397 johnpye 546 if platform.system()!="Windows":
398     opts.Add(BoolOption(
399     'WITH_GCCVISIBILITY'
400     , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
401     , True
402     ))
403    
404 johnpye 392 # TODO: OTHER OPTIONS?
405     # TODO: flags for optimisation
406 johnpye 393 # TODO: turning on/off bintoken functionality
407 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
408 johnpye 393
409 johnpye 498 # Import the outside environment
410    
411 johnpye 569 if os.environ.get('OSTYPE')=='msys':
412 johnpye 552 env = Environment(
413     ENV=os.environ
414 johnpye 766 , tools=['mingw','lex','yacc','fortran','swig','disttar','nsis','doxygen']
415 johnpye 552 , toolpath=['scons']
416     )
417 johnpye 529 env['IS_MINGW']=True
418 johnpye 740
419     elif platform.system()=="Windows":
420     env = Environment(
421     ENV={
422     'PATH':os.environ['PATH']
423     ,'INCLUDE':os.environ['INCLUDE']
424     ,'LIB':os.environ['LIB']
425     ,'MSVS_IGNORE_IDE_PATHS':1
426     }
427 johnpye 766 , tools = ['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
428 johnpye 740 , toolpath = ['scons']
429     )
430     env.Append(CPPDEFINES=['_CRT_SECURE_NO_DEPRECATE'])
431 johnpye 498 else:
432 johnpye 552 env = Environment(
433     ENV=os.environ
434 johnpye 766 , tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
435 johnpye 552 , toolpath=['scons']
436     )
437 johnpye 498
438 johnpye 385 opts.Update(env)
439     opts.Save('options.cache',env)
440    
441     Help(opts.GenerateHelpText(env))
442    
443 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
444 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
445 johnpye 386
446 johnpye 551 with_python = env.get('WITH_PYTHON')
447 johnpye 427 without_python_reason = "disabled by options/config.py"
448 johnpye 387
449 johnpye 593 with_cunit = env.get('WITH_CUNIT')
450 johnpye 427 without_cunit_reason = "not requested"
451 johnpye 400
452 johnpye 761 with_extfns = env.get('WITH_EXTFNS')
453     without_extfn_reason = "disabled by options/config.py"
454    
455 johnpye 631 if platform.system()=="Windows":
456     with_installer=1
457     else:
458     with_installer=0
459     without_installer_reason = "only possible under Windows"
460    
461 johnpye 673 if 'LSOD' in env['WITH_SOLVERS']:
462     with_lsode=True
463     else:
464     with_lsode=False
465     without_lsode_reason = "not requested (WITH_SOLVERS)"
466    
467     if 'IDA' in env['WITH_SOLVERS']:
468     with_ida=True
469     else:
470     with_ida=False
471     without_ida_reason = "not requested (WITH_SOLVERS)"
472    
473    
474 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
475     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
476     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
477 johnpye 393
478 johnpye 463 can_install = True
479     if platform.system()=='Windows':
480     can_install = False
481    
482     env['CAN_INSTALL']=can_install
483    
484 johnpye 721 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
485    
486 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
487     print "TCL_LIBPATH =",env['TCL_LIBPATH']
488     print "TCL_LIB =",env['TCL_LIB']
489 johnpye 562 print "CC =",env['CC']
490     print "CXX =",env['CXX']
491 johnpye 673 print "FORTRAN=",env.get('FORTRAN')
492 johnpye 393
493 johnpye 628 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
494 johnpye 385 #------------------------------------------------------
495 johnpye 398 # SPECIAL CONFIGURATION TESTS
496    
497 johnpye 463 need_fortran = False
498    
499 johnpye 400 #----------------
500     # SWIG
501    
502 johnpye 398 import os,re
503    
504 johnpye 413 def get_swig_version(env):
505 johnpye 403 cmd = env['SWIG']+' -version'
506 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
507 johnpye 403 output = coutcerr.read()
508 johnpye 398
509 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
510     expr = re.compile(restr,re.M);
511 johnpye 398 m = expr.search(output);
512     if not m:
513 johnpye 413 return None
514 johnpye 398 maj = int(m.group('maj'))
515     min = int(m.group('min'))
516     pat = int(m.group('pat'))
517 johnpye 413
518     return (maj,min,pat)
519 johnpye 398
520 johnpye 413
521     def CheckSwigVersion(context):
522    
523     try:
524     context.Message("Checking version of SWIG... ")
525     maj,min,pat = get_swig_version(context.env)
526     except:
527     context.Result("Failed to detect version, or failed to run SWIG")
528     return 0;
529    
530 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
531    
532 johnpye 398 if maj == 1 and (
533 johnpye 400 min > 3
534     or (min == 3 and pat >= 24)
535 johnpye 398 ):
536     context.Result("ok, %d.%d.%d" % (maj,min,pat))
537     return 1;
538 johnpye 401 else:
539     context.Result("too old, %d.%d.%d" % (maj,min,pat))
540     return 0;
541 johnpye 398
542 johnpye 400 #----------------
543     # General purpose library-and-header test
544    
545 johnpye 404 class KeepContext:
546 johnpye 521 def __init__(self,context,varprefix,static=False):
547 johnpye 404 self.keep = {}
548 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
549 johnpye 705 #print "Keeping env %s = %s" % (k,context.env.get(k))
550     self.keep[k]=context.env.get(k)
551 johnpye 404
552     if context.env.has_key(varprefix+'_CPPPATH'):
553 johnpye 743 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
554 johnpye 428 #print "Adding '"+str(cpppath_add)+"' to cpp path"
555    
556 johnpye 521 if static:
557     staticlib=env[varprefix+'_LIB']
558     #print "STATIC LIB = ",staticlib
559     context.env.Append(
560     LINKFLAGS=[staticlib]
561     )
562     else:
563     if context.env.has_key(varprefix+'_LIBPATH'):
564     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
565     #print "Adding '"+str(libpath_add)+"' to lib path"
566 johnpye 428
567 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
568     context.env.Append(LIBS=[env[varprefix+'_LIB']])
569 johnpye 705 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
570 johnpye 404
571     def restore(self,context):
572 johnpye 464 #print "RESTORING CONTEXT"
573     #print self.keep
574     #print "..."
575 johnpye 404 for k in self.keep:
576 johnpye 463 if self.keep[k]==None:
577 johnpye 521 if context.env.has_key(k):
578     #print "Clearing "+str(k)
579     del context.env[k];
580 johnpye 463 else:
581 johnpye 705 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
582 johnpye 463 context.env[k]=self.keep[k];
583 johnpye 404
584 johnpye 521 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
585 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
586     and LIBNAME_CPPPATH and try to compile and link the
587     file with the provided text, linking with the
588     library libname."""
589    
590 johnpye 521 if static:
591     context.Message( 'Checking for static '+libname+'... ' )
592     else:
593     context.Message( 'Checking for '+libname+'... ' )
594    
595 johnpye 400 if varprefix==None:
596     varprefix = libname.upper()
597    
598 johnpye 705 #print "LIBS is currently:",context.env.get('LIBS')
599 johnpye 521 keep = KeepContext(context,varprefix,static)
600 johnpye 400
601 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
602 johnpye 463 # if varprefix_LIB were in env, KeepContext would
603     # have appended it already
604 johnpye 705 context.env.Append(LIBS=[libname])
605 johnpye 428
606 johnpye 404 is_ok = context.TryLink(text,ext)
607 johnpye 428
608 johnpye 521 #print "Link success? ",(is_ok != 0)
609 johnpye 400
610 johnpye 405 keep.restore(context)
611 johnpye 400
612 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
613 johnpye 705 # print "Restored LIBS="+str(context.env['LIBS'])
614 johnpye 428 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
615    
616 johnpye 404 context.Result(is_ok)
617     return is_ok
618    
619     #----------------
620 johnpye 502 # GCC
621    
622     gcc_test_text = """
623     #ifndef __GNUC__
624     # error "Not using GCC"
625     #endif
626    
627     int main(void){
628     return __GNUC__;
629     }
630     """
631    
632     def CheckGcc(context):
633     context.Message("Checking for GCC... ")
634     is_ok = context.TryCompile(gcc_test_text,".c")
635     context.Result(is_ok)
636     return is_ok
637    
638     #----------------
639 johnpye 500 # GCC VISIBILITY feature
640    
641     gccvisibility_test_text = """
642     #if __GNUC__ < 4
643     # error "Require GCC version 4 or newer"
644     #endif
645    
646     __attribute__ ((visibility("default"))) int x;
647    
648     int main(void){
649     extern int x;
650     x = 4;
651     }
652     """
653    
654     def CheckGccVisibility(context):
655     context.Message("Checking for GCC 'visibility' capability... ")
656 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
657     context.Result("disabled")
658     return 0
659 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
660     context.Result(is_ok)
661     return is_ok
662 johnpye 502
663 johnpye 500 #----------------
664 johnpye 502 # YACC
665    
666     yacc_test_text = """
667 johnpye 646 %{
668     #include <stdio.h>
669 johnpye 741
670     /* MSVC++ needs this before it can swallow Bison output */
671     #ifdef _MSC_VER
672     # define __STDC__
673     #endif
674 johnpye 646 %}
675     %token MSG
676 johnpye 502 %start ROOT
677 johnpye 646 %%
678     ROOT:
679     MSG { printf("HELLO"); }
680     ;
681     %%
682 johnpye 502 """
683    
684     def CheckYacc(context):
685 johnpye 644 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
686 johnpye 502 is_ok = context.TryCompile(yacc_test_text,".y")
687     context.Result(is_ok)
688     return is_ok
689    
690     #----------------
691 johnpye 404 # CUnit test
692    
693 johnpye 400 cunit_test_text = """
694 johnpye 451 #include <CUnit/CUnit.h>
695 johnpye 400 int maxi(int i1, int i2){
696     return (i1 > i2) ? i1 : i2;
697     }
698    
699     void test_maxi(void){
700     CU_ASSERT(maxi(0,2) == 2);
701     CU_ASSERT(maxi(0,-2) == 0);
702     CU_ASSERT(maxi(2,2) == 2);
703    
704     }
705     int main(void){
706     /* CU_initialize_registry() */
707 johnpye 404 return 0;
708 johnpye 400 }
709     """
710    
711     def CheckCUnit(context):
712 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
713 johnpye 400
714 johnpye 404 #----------------
715 johnpye 673 # MATH test
716    
717     math_test_text = """
718 johnpye 705 #ifndef _ALL_SOURCE
719     # define _ALL_SOURCE
720     #endif
721     #ifndef _XOPEN_SOURCE
722     # define _XOPEN_SOURCE
723     #endif
724     #ifndef _XOPEN_SOURCE_EXTENDED
725     # define _XOPEN_SOURCE_EXTENDED 1
726     #endif
727 johnpye 673 #include <math.h>
728     int main(void){
729 johnpye 705 double x = 1.0; double y = 1.0; int i = 1;
730     acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
731     j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
732     y0(x); y1(x); yn(i,x);
733     #ifdef _THREAD_SAFE
734     gamma_r(x,&i);
735     lgamma_r(x,&i);
736     #else
737     gamma(x);
738     lgamma(x);
739     #endif
740     hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
741 johnpye 673 return 0;
742     }
743     """
744    
745     def CheckMath(context):
746 johnpye 705 context.Message('Checking for IEE math library... ')
747     libsave=context.env.get('LIBS');
748     context.env.AppendUnique(LIBS=['m'])
749     is_ok=context.TryLink(math_test_text,".c")
750     context.Result(is_ok)
751     if not is_ok:
752     context.env['LIBS']=libsave
753     return is_ok
754    
755 johnpye 673 #----------------
756     # IDA test
757    
758     ida_test_text = """
759 johnpye 782 #include <ida/ida.h>
760     #include <nvector/nvector_serial.h>
761     #include <ida/ida_spgmr.h>
762 johnpye 673 int main(){
763     void *ida_mem;
764     ida_mem = IDACreate();
765 johnpye 782 return 0;
766 johnpye 673 }
767     """
768    
769     def CheckIDA(context):
770     context.Message( 'Checking for IDA (SUNDIALS)... ' )
771    
772     keep = KeepContext(context,"IDA")
773    
774     is_ok = context.TryLink(ida_test_text,".c")
775     context.Result(is_ok)
776    
777     keep.restore(context)
778 johnpye 782
779 johnpye 673 return is_ok
780    
781     #----------------
782 johnpye 405 # Tcl test
783 johnpye 404
784 johnpye 561 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
785     tcltk_minor_newest_acceptable = 4
786     tcltk_major_required = 8
787    
788 johnpye 404 tcl_check_text = r"""
789     #include <tcl.h>
790     #include <stdio.h>
791     int main(void){
792     printf("%s",TCL_PATCH_LEVEL);
793     return 0;
794     }
795     """
796    
797     def CheckTcl(context):
798 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
799 johnpye 405
800     def CheckTclVersion(context):
801 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
802 johnpye 405 context.Message("Checking Tcl version... ")
803     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
804 johnpye 404 keep.restore(context)
805     if not is_ok:
806 johnpye 405 context.Result("failed to run check")
807 johnpye 404 return 0
808 johnpye 405
809 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
810 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
811 johnpye 428 context.Result(output+" (bad version)")
812 johnpye 405 # bad version
813     return 0
814    
815     # good version
816 johnpye 552 context.Result(output+", good")
817 johnpye 404 return 1
818    
819 johnpye 405 #----------------
820 johnpye 463 # Tk test
821 johnpye 405
822     tk_check_text = r"""
823     #include <tk.h>
824     #include <stdio.h>
825     int main(void){
826     printf("%s",TK_PATCH_LEVEL);
827     return 0;
828     }
829     """
830     def CheckTk(context):
831 johnpye 673 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
832 johnpye 405
833 johnpye 428
834 johnpye 405 def CheckTkVersion(context):
835 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
836 johnpye 405 context.Message("Checking Tk version... ")
837 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
838 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
839 johnpye 404 keep.restore(context)
840     if not is_ok:
841     context.Result("failed to run check")
842     return 0
843    
844 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
845 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
846 johnpye 404 # bad version
847 johnpye 561 context.Result(output+" (bad version)")
848 johnpye 404 return 0
849 johnpye 400
850 johnpye 404 # good version
851 johnpye 561 context.Result(output+" (good)")
852 johnpye 404 return 1
853 johnpye 485
854     #----------------
855 johnpye 521 # Tktable test
856    
857     tktable_check_text = r"""
858     #include <tkTable.h>
859     #include <stdio.h>
860     int main(void){
861     Table mytable;
862     return 0;
863     }
864     """
865    
866     def CheckTkTable(context):
867     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
868    
869     #---------------
870     # X11 test
871    
872     x11_check_text = r"""
873     #include <X11/Xlib.h>
874     #include <X11/IntrinsicP.h>
875     #include <X11/Intrinsic.h>
876     #include <X11/ObjectP.h>
877     #include <X11/Object.h>
878     int main(void){
879     Object mything;
880     return 0;
881     }
882     """
883    
884     def CheckX11(context):
885     return CheckExtLib(context,'X11',x11_check_text)
886    
887     #----------------
888 johnpye 485 # GCC Version sniffing
889    
890     # TODO FIXME
891    
892     gcc_version4 = False
893    
894 johnpye 398 #------------------------------------------------------
895 johnpye 385 # CONFIGURATION
896    
897     conf = Configure(env
898     , custom_tests = {
899 johnpye 673 'CheckMath' : CheckMath
900     , 'CheckSwigVersion' : CheckSwigVersion
901 johnpye 400 , 'CheckCUnit' : CheckCUnit
902 johnpye 404 , 'CheckTcl' : CheckTcl
903     , 'CheckTclVersion' : CheckTclVersion
904 johnpye 405 , 'CheckTk' : CheckTk
905     , 'CheckTkVersion' : CheckTkVersion
906 johnpye 502 , 'CheckGcc' : CheckGcc
907 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
908 johnpye 502 , 'CheckYacc' : CheckYacc
909 johnpye 521 , 'CheckTkTable' : CheckTkTable
910     , 'CheckX11' : CheckX11
911 johnpye 673 , 'CheckIDA' : CheckIDA
912 johnpye 400 # , 'CheckIsNan' : CheckIsNan
913     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
914 johnpye 385 }
915 johnpye 459 # , config_h = "config.h"
916 johnpye 385 )
917    
918 johnpye 740 # stdio -- just to check that compiler is behaving
919 johnpye 398
920 johnpye 740 if not conf.CheckHeader('stdio.h'):
921     print "Did not find 'stdio.h'! Check your compiler configuration."
922     Exit(1)
923    
924 johnpye 385 # Math library
925    
926 johnpye 673 if need_libm:
927     if not conf.CheckMath():
928     print 'Did not find math library, exiting!'
929     Exit(1)
930     #pass
931 johnpye 427
932 johnpye 385 # Where is 'isnan'?
933    
934 johnpye 740 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
935 johnpye 385 print "Didn't find isnan"
936 johnpye 414 # Exit(1)
937 johnpye 385
938 johnpye 500 # GCC visibility
939    
940 johnpye 502 if conf.CheckGcc():
941     conf.env['HAVE_GCC']=True;
942 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
943 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
944     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
945     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
946 johnpye 709 conf.env.Append(CCFLAGS=['-Wall'])
947 johnpye 500
948 johnpye 502 # YACC
949    
950 johnpye 506 if not conf.CheckYacc():
951     print "YACC NOT FOUND OR NOT WORKING"
952     else:
953 johnpye 502 conf.env['HAVE_YACC']=True
954    
955     conf.env['HAVE_LEX']=True
956    
957 johnpye 387 # Tcl/Tk
958 johnpye 386
959 johnpye 586 if with_tcltk:
960     if conf.CheckTcl():
961     if conf.CheckTclVersion():
962     if conf.CheckTk():
963     if with_tcltk and conf.CheckTkVersion():
964     if env['STATIC_TCLTK']:
965     if conf.CheckTkTable():
966     pass
967     else:
968     without_tcltk_reason = "TkTable not found"
969     with_tcltk = False
970     else:
971     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
972     with_tcltk = False
973 johnpye 521 else:
974 johnpye 586 without_tcltk_reason = "Tk not found."
975 johnpye 551 with_tcltk = False
976 johnpye 428 else:
977 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
978 johnpye 551 with_tcltk = False
979 johnpye 586
980 johnpye 428 else:
981 johnpye 586 without_tcltk_reason = "Tcl not found."
982 johnpye 551 with_tcltk = False
983 johnpye 386
984 johnpye 521 if env['STATIC_TCLTK']:
985     conf.CheckX11()
986    
987 johnpye 395 # Python... obviously we're already running python, so we just need to
988     # check that we can link to the python library OK:
989    
990 johnpye 391 if platform.system()=="Windows":
991 johnpye 395 python_lib='python24'
992 johnpye 391 else:
993 johnpye 395 python_lib='python2.4'
994 johnpye 391
995 johnpye 395 # SWIG version
996    
997 johnpye 413 if not conf.CheckSwigVersion():
998     without_python_reason = 'SWIG >= 1.3.24 is required'
999     with_python = False
1000    
1001 johnpye 400 # CUnit
1002    
1003 johnpye 593 if with_cunit:
1004 johnpye 404 if not conf.CheckCUnit():
1005 johnpye 427 without_cunit_reason = 'CUnit not found'
1006 johnpye 665 with_cunit = False
1007 johnpye 705 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1008 johnpye 427
1009 johnpye 673 # IDA
1010    
1011     if not with_ida:
1012     without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1013     elif not conf.CheckIDA():
1014     with_ida = False
1015     without_ida_reason = "IDA not found"
1016    
1017 johnpye 427 # BLAS
1018    
1019 johnpye 459 need_blas=False
1020 johnpye 673
1021     if with_lsode:
1022     need_fortran = True
1023 johnpye 459 need_blas=True
1024 johnpye 673
1025 johnpye 459 if need_blas:
1026     if conf.CheckLib('blas'):
1027     with_local_blas = False
1028     without_local_blas_reason = "Found BLAS installed on system"
1029     else:
1030     with_local_blas = True
1031     need_fortran = True
1032 johnpye 673 else:
1033     with_local_blas= False;
1034     without_local_blas_reason = "BLAS not required"
1035 johnpye 427
1036     # FORTRAN
1037    
1038     if need_fortran:
1039 johnpye 629 conf.env.Tool('fortran')
1040     detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1041 johnpye 427 if detect_fortran:
1042     # For some reason, g77 doesn't get detected properly on MinGW
1043 johnpye 673 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1044 johnpye 427 conf.env.Replace(F77=detect_fortran)
1045     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1046     conf.env.Replace(F77FLAGS='')
1047 johnpye 428 #print "F77:",conf.env['F77']
1048     #print "F77COM:",conf.env['F77COM']
1049     #print "F77FLAGS:",conf.env['F77FLAGS']
1050 johnpye 427 fortran_builder = Builder(
1051     action='$F77COM'
1052     , suffix='.o'
1053     , src_suffix='.f'
1054     )
1055     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1056     else:
1057 johnpye 673 with_lsode=False;
1058     without_lsode_reason="FORTRAN-77 required but not found"
1059 johnpye 629
1060 johnpye 464 #else:
1061     # print "FORTRAN not required"
1062 johnpye 400
1063 johnpye 673 # F2C
1064    
1065     if need_fortran:
1066     if platform.system()=="Windows":
1067     conf.env.Append(LIBPATH='c:\mingw\lib')
1068    
1069    
1070 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
1071    
1072     # TODO: check size of void*
1073    
1074 johnpye 393 # TODO: detect if dynamic libraries are possible or not
1075    
1076 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
1077 johnpye 740 _found_windows_h = conf.CheckHeader('Windows.h')
1078    
1079     if not _found_windows_h:
1080 johnpye 741 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1081 johnpye 740 Exit(1)
1082 johnpye 741
1083 johnpye 534 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1084 johnpye 427 with_python = 0;
1085     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1086    
1087     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1088    
1089 johnpye 395 conf.Finish()
1090    
1091     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
1092     env.Append(PYTHON_LIB=[python_lib])
1093     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
1094    
1095 johnpye 507 #---------------------------------------
1096     # SUBSTITUTION DICTIONARY for .in files
1097    
1098 johnpye 658 release = env.get('RELEASE')
1099     if release=="0.":
1100     release="0"
1101    
1102 johnpye 507 subst_dict = {
1103     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1104     , '@GLADE_FILE@':'ascend.glade'
1105     , '@HELP_ROOT@':''
1106     , '@ICON_EXTENSION@':icon_extension
1107 johnpye 628 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1108 johnpye 507 , '@INSTALL_BIN@':env['INSTALL_BIN']
1109     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1110 johnpye 683 , '@INSTALL_LIB@':env['INSTALL_LIB']
1111 johnpye 721 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1112 johnpye 507 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1113     , '@VERSION@':version
1114 johnpye 658 , '@RELEASE@':release
1115 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1116 johnpye 507 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1117 johnpye 508 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1118     , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1119 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1120 johnpye 627 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1121 johnpye 683 , '@PYTHON@' : python_exe
1122 johnpye 507 }
1123    
1124 johnpye 594 if env.get('WITH_LOCAL_HELP'):
1125 johnpye 507 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1126     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1127    
1128 johnpye 597 # bool options...
1129 johnpye 673 for k,v in {
1130     'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1131     ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1132     ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1133 johnpye 605 }.iteritems():
1134 johnpye 597 if env.get(k):
1135 johnpye 673 # subst_dict['@'+v+'@']='1'
1136     subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1137 johnpye 594
1138 johnpye 673 if with_ida:
1139     subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1140    
1141     if with_lsode:
1142     subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1143    
1144 johnpye 507 if with_python:
1145     subst_dict['@ASCXX_USE_PYTHON@']="1"
1146 johnpye 673 env['WITH_PYTHON']=1;
1147 johnpye 507
1148     if env.has_key('HAVE_GCCVISIBILITY'):
1149     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1150    
1151     env.Append(SUBST_DICT=subst_dict)
1152    
1153 johnpye 385 #------------------------------------------------------
1154 johnpye 558 # RECIPE: SWIG scanner
1155    
1156     import SCons.Script
1157    
1158     SWIGScanner = SCons.Scanner.ClassicCPP(
1159     "SWIGScan"
1160     , ".i"
1161     , "CPPPATH"
1162     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1163     )
1164    
1165     env.Append(SCANNERS=[SWIGScanner])
1166    
1167     #------------------------------------------------------
1168 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
1169    
1170     import re
1171 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
1172 johnpye 393
1173 johnpye 395 def TOOL_SUBST(env):
1174     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1175     from the source to the target.
1176     The values of SUBST_DICT first have any construction variables expanded
1177     (its keys are not expanded).
1178     If a value of SUBST_DICT is a python callable function, it is called and
1179     the result is expanded as the value.
1180     If there's more than one source and more than one target, each target gets
1181     substituted from the corresponding source.
1182 johnpye 393 """
1183 johnpye 395 env.Append(TOOLS = 'SUBST')
1184     def do_subst_in_file(targetfile, sourcefile, dict):
1185     """Replace all instances of the keys of dict with their values.
1186     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1187     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1188     """
1189     try:
1190     f = open(sourcefile, 'rb')
1191     contents = f.read()
1192     f.close()
1193     except:
1194     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1195     for (k,v) in dict.items():
1196     contents = re.sub(k, v, contents)
1197     try:
1198     f = open(targetfile, 'wb')
1199     f.write(contents)
1200     f.close()
1201     except:
1202     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1203     return 0 # success
1204 johnpye 393
1205 johnpye 395 def subst_in_file(target, source, env):
1206     if not env.has_key('SUBST_DICT'):
1207     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1208     d = dict(env['SUBST_DICT']) # copy it
1209     for (k,v) in d.items():
1210     if callable(v):
1211     d[k] = env.subst(v())
1212     elif SCons.Util.is_String(v):
1213     d[k]=env.subst(v)
1214     else:
1215     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1216     for (t,s) in zip(target, source):
1217     return do_subst_in_file(str(t), str(s), d)
1218 johnpye 393
1219 johnpye 395 def subst_in_file_string(target, source, env):
1220     """This is what gets printed on the console."""
1221     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1222     for (t,s) in zip(target, source)])
1223 johnpye 393
1224 johnpye 395 def subst_emitter(target, source, env):
1225     """Add dependency from substituted SUBST_DICT to target.
1226     Returns original target, source tuple unchanged.
1227     """
1228     d = env['SUBST_DICT'].copy() # copy it
1229     for (k,v) in d.items():
1230     if callable(v):
1231     d[k] = env.subst(v())
1232     elif SCons.Util.is_String(v):
1233     d[k]=env.subst(v)
1234     Depends(target, SCons.Node.Python.Value(d))
1235     return target, source
1236 johnpye 393
1237 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1238     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1239    
1240     TOOL_SUBST(env)
1241    
1242 johnpye 393 #------------------------------------------------------
1243 johnpye 463 # Recipe for 'CHMOD' ACTION
1244 johnpye 439
1245     import SCons
1246     from SCons.Script.SConscript import SConsEnvironment
1247     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1248     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1249    
1250     def InstallPerm(env, dest, files, perm):
1251     obj = env.Install(dest, files)
1252     for i in obj:
1253     env.AddPostAction(i, env.Chmod(str(i), perm))
1254    
1255     SConsEnvironment.InstallPerm = InstallPerm
1256    
1257     # define wrappers
1258     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1259 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1260 johnpye 629 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1261 johnpye 463
1262 johnpye 439 #------------------------------------------------------
1263 johnpye 463 # BUILD...
1264 johnpye 385
1265 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
1266 johnpye 743 env.AppendUnique(CPPPATH=['#base/generic'])
1267 johnpye 385
1268 johnpye 508 if env['DEBUG']:
1269     env.Append(CCFLAGS=['-g'])
1270    
1271 johnpye 591 if env['GCOV']:
1272     env.Append(
1273     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1274     , LIBS=['gcov']
1275     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1276     )
1277    
1278 johnpye 673 if with_ida:
1279     env.Append(WITH_IDA=1)
1280    
1281 johnpye 463 #-------------
1282     # TCL/TK GUI
1283 johnpye 385
1284 johnpye 551 if with_tcltk:
1285 johnpye 569 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1286 johnpye 391 else:
1287 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1288 johnpye 386
1289 johnpye 463 #-------------
1290     # PYTHON INTERFACE
1291    
1292 johnpye 387 if with_python:
1293 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
1294 johnpye 391 else:
1295 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
1296 johnpye 400
1297 johnpye 463 #------------
1298     # BASE/GENERIC SUBDIRECTORIES
1299    
1300 johnpye 673 libascend_env = env.Copy()
1301    
1302 johnpye 463 dirs = ['general','utilities','compiler','solver','packages']
1303    
1304     srcs = []
1305     for d in dirs:
1306 johnpye 673 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1307 johnpye 463 srcs += heresrcs
1308    
1309     #-------------
1310 johnpye 673 # IMPORTED CODE: LSODE, BLAS, etc
1311    
1312     if with_lsode:
1313     srcs += env.SConscript(['lsod/SConscript'],'env')
1314     srcs += env.SConscript(['linpack/SConscript'],'env')
1315     else:
1316     print "Skipping... LSODE won't be built:", without_lsode_reason
1317    
1318     if with_local_blas:
1319     srcs += env.SConscript(['blas/SConscript'],'env')
1320     else:
1321     print "Skipping... BLAS won't be built:", without_local_blas_reason
1322    
1323     if not with_ida:
1324     print "Skipping... IDA won't be built:", without_ida_reason
1325    
1326     #-------------
1327 johnpye 463 # LIBASCEND -- all base/generic functionality
1328    
1329 johnpye 673 libascend = libascend_env.SharedLibrary('ascend',srcs)
1330 johnpye 463
1331 johnpye 673 env.Alias('libascend',libascend)
1332    
1333 johnpye 463 #-------------
1334 johnpye 761 # UNIT TESTS (C CODE)
1335 johnpye 463
1336 johnpye 593 if with_cunit:
1337 johnpye 400 testdirs = ['general','solver','utilities']
1338 johnpye 593 testsrcs = []
1339 johnpye 400 for testdir in testdirs:
1340     path = 'base/generic/'+testdir+'/test/'
1341     env.SConscript([path+'SConscript'],'env')
1342 johnpye 593 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1343    
1344     #print "TESTSRCS =",testsrcs
1345    
1346 johnpye 400 env.SConscript(['test/SConscript'],'env')
1347     env.SConscript(['base/generic/test/SConscript'],'env')
1348 johnpye 593
1349     env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1350 johnpye 400
1351     else:
1352 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1353 johnpye 400
1354 johnpye 761 #-------------
1355     # EXTERNAL FUNCTIONS
1356    
1357     extfns = []
1358     if with_extfns:
1359     testdirs = ['johnpye/extfn']
1360     for testdir in testdirs:
1361     path = 'models/'+testdir+"/SConscript"
1362     extfns += env.SConscript(path,'env')
1363     else:
1364     print "Skipping... External modules aren't being built:",without_extfns_reason
1365    
1366     env.Alias('extfns',extfns)
1367    
1368 johnpye 463 #------------------------------------------------------
1369 johnpye 683 # CREATE ASCEND-CONFIG scriptlet
1370    
1371     ascendconfig = env.SubstInFile('ascend-config.in')
1372    
1373     #------------------------------------------------------
1374 johnpye 463 # INSTALLATION
1375 johnpye 427
1376 johnpye 552 if env.get('CAN_INSTALL'):
1377 johnpye 463 # the models directory only needs to be processed for installation, no other processing required.
1378     env.SConscript(['models/SConscript'],'env')
1379 johnpye 427
1380 johnpye 721 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
1381 johnpye 463 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1382 johnpye 449
1383 johnpye 463 # TODO: add install options
1384     env.Alias('install',install_dirs)
1385 johnpye 400
1386 johnpye 629 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1387 johnpye 435
1388 johnpye 683 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1389    
1390 johnpye 438 #------------------------------------------------------
1391 johnpye 631 # WINDOWS INSTALLER
1392     # For the windows installer, please see pygtk/SConscript
1393    
1394     if with_installer:
1395     pass
1396     else:
1397     print "Skipping... Windows installer isn't being built:",without_installer_reason
1398    
1399     #------------------------------------------------------
1400 johnpye 673 # PROJECT FILE for MSVC
1401    
1402     env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1403    
1404     #------------------------------------------------------
1405 johnpye 438 # CREATE the SPEC file for generation of RPM packages
1406    
1407 johnpye 463 if platform.system()=="Linux":
1408     env.SubstInFile('ascend.spec.in')
1409 johnpye 552
1410     #------------------------------------------------------
1411     # DISTRIBUTION TAR FILE
1412    
1413 johnpye 554 env['DISTTAR_FORMAT']='bz2'
1414 johnpye 556 env.Append(
1415 johnpye 566 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1416 johnpye 561 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1417 johnpye 556 )
1418 johnpye 554
1419 johnpye 563 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1420 johnpye 556 , [env.Dir('#')]
1421 johnpye 554 )
1422    
1423 johnpye 680 env.Depends(tar,'ascend.spec')
1424    
1425 johnpye 554 #------------------------------------------------------
1426 johnpye 766 # LIBASCEND DOXYGEN DOCUMENTATION
1427    
1428     env.SConscript('base/doc/SConscript',['env'])
1429    
1430     #------------------------------------------------------
1431 johnpye 554 # RPM BUILD
1432    
1433 johnpye 766 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
1434     # (check * for the version number used to create the tarball)
1435 johnpye 554
1436     #------------------------------------------------------
1437     # DEFAULT TARGETS
1438    
1439 johnpye 673 default_targets =['libascend']
1440 johnpye 629 if with_tcltk:
1441     default_targets.append('tcltk')
1442     if with_python:
1443     default_targets.append('pygtk')
1444 johnpye 631 if with_installer:
1445     default_targets.append('installer')
1446 johnpye 761 if with_extfns:
1447     default_targets.append('extfns')
1448 johnpye 554
1449 johnpye 629 env.Default(default_targets)
1450    
1451     print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1452    
1453 johnpye 705 # vim: set syntax=python:
1454    

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