/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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