/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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