/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 721 - (hide annotations) (download)
Mon Jul 3 06:22:42 2006 UTC (17 years, 10 months ago) by johnpye
File size: 34828 byte(s)
Added '--models' option to ascend-config.
Fixed a bug with packages.c wrt generating absolute paths to library files.
Added SCons directives to install header files in INSTALL_INCLUDE subdirs.
Changed rel.c so that init function is only run if provided in the package.
Added 'ospath_getabs' to convert relative paths into absolute paths by adding prefix of fully-resolved '.'
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 721 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
468    
469 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
470     print "TCL_LIBPATH =",env['TCL_LIBPATH']
471     print "TCL_LIB =",env['TCL_LIB']
472 johnpye 562 print "CC =",env['CC']
473     print "CXX =",env['CXX']
474 johnpye 673 print "FORTRAN=",env.get('FORTRAN')
475 johnpye 393
476 johnpye 628 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
477 johnpye 385 #------------------------------------------------------
478 johnpye 398 # SPECIAL CONFIGURATION TESTS
479    
480 johnpye 463 need_fortran = False
481    
482 johnpye 400 #----------------
483     # SWIG
484    
485 johnpye 398 import os,re
486    
487 johnpye 413 def get_swig_version(env):
488 johnpye 403 cmd = env['SWIG']+' -version'
489 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
490 johnpye 403 output = coutcerr.read()
491 johnpye 398
492 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
493     expr = re.compile(restr,re.M);
494 johnpye 398 m = expr.search(output);
495     if not m:
496 johnpye 413 return None
497 johnpye 398 maj = int(m.group('maj'))
498     min = int(m.group('min'))
499     pat = int(m.group('pat'))
500 johnpye 413
501     return (maj,min,pat)
502 johnpye 398
503 johnpye 413
504     def CheckSwigVersion(context):
505    
506     try:
507     context.Message("Checking version of SWIG... ")
508     maj,min,pat = get_swig_version(context.env)
509     except:
510     context.Result("Failed to detect version, or failed to run SWIG")
511     return 0;
512    
513 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
514    
515 johnpye 398 if maj == 1 and (
516 johnpye 400 min > 3
517     or (min == 3 and pat >= 24)
518 johnpye 398 ):
519     context.Result("ok, %d.%d.%d" % (maj,min,pat))
520     return 1;
521 johnpye 401 else:
522     context.Result("too old, %d.%d.%d" % (maj,min,pat))
523     return 0;
524 johnpye 398
525 johnpye 400 #----------------
526     # General purpose library-and-header test
527    
528 johnpye 404 class KeepContext:
529 johnpye 521 def __init__(self,context,varprefix,static=False):
530 johnpye 404 self.keep = {}
531 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
532 johnpye 705 #print "Keeping env %s = %s" % (k,context.env.get(k))
533     self.keep[k]=context.env.get(k)
534 johnpye 404
535     if context.env.has_key(varprefix+'_CPPPATH'):
536 johnpye 521 context.env.Append(CPPPATH=[env[varprefix+'_CPPPATH']])
537 johnpye 428 #print "Adding '"+str(cpppath_add)+"' to cpp path"
538    
539 johnpye 521 if static:
540     staticlib=env[varprefix+'_LIB']
541     #print "STATIC LIB = ",staticlib
542     context.env.Append(
543     LINKFLAGS=[staticlib]
544     )
545     else:
546     if context.env.has_key(varprefix+'_LIBPATH'):
547     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
548     #print "Adding '"+str(libpath_add)+"' to lib path"
549 johnpye 428
550 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
551     context.env.Append(LIBS=[env[varprefix+'_LIB']])
552 johnpye 705 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
553 johnpye 404
554     def restore(self,context):
555 johnpye 464 #print "RESTORING CONTEXT"
556     #print self.keep
557     #print "..."
558 johnpye 404 for k in self.keep:
559 johnpye 463 if self.keep[k]==None:
560 johnpye 521 if context.env.has_key(k):
561     #print "Clearing "+str(k)
562     del context.env[k];
563 johnpye 463 else:
564 johnpye 705 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
565 johnpye 463 context.env[k]=self.keep[k];
566 johnpye 404
567 johnpye 521 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
568 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
569     and LIBNAME_CPPPATH and try to compile and link the
570     file with the provided text, linking with the
571     library libname."""
572    
573 johnpye 521 if static:
574     context.Message( 'Checking for static '+libname+'... ' )
575     else:
576     context.Message( 'Checking for '+libname+'... ' )
577    
578 johnpye 400 if varprefix==None:
579     varprefix = libname.upper()
580    
581 johnpye 705 #print "LIBS is currently:",context.env.get('LIBS')
582 johnpye 521 keep = KeepContext(context,varprefix,static)
583 johnpye 400
584 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
585 johnpye 463 # if varprefix_LIB were in env, KeepContext would
586     # have appended it already
587 johnpye 705 context.env.Append(LIBS=[libname])
588 johnpye 428
589 johnpye 404 is_ok = context.TryLink(text,ext)
590 johnpye 428
591 johnpye 521 #print "Link success? ",(is_ok != 0)
592 johnpye 400
593 johnpye 405 keep.restore(context)
594 johnpye 400
595 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
596 johnpye 705 # print "Restored LIBS="+str(context.env['LIBS'])
597 johnpye 428 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
598    
599 johnpye 404 context.Result(is_ok)
600     return is_ok
601    
602     #----------------
603 johnpye 502 # GCC
604    
605     gcc_test_text = """
606     #ifndef __GNUC__
607     # error "Not using GCC"
608     #endif
609    
610     int main(void){
611     return __GNUC__;
612     }
613     """
614    
615     def CheckGcc(context):
616     context.Message("Checking for GCC... ")
617     is_ok = context.TryCompile(gcc_test_text,".c")
618     context.Result(is_ok)
619     return is_ok
620    
621     #----------------
622 johnpye 500 # GCC VISIBILITY feature
623    
624     gccvisibility_test_text = """
625     #if __GNUC__ < 4
626     # error "Require GCC version 4 or newer"
627     #endif
628    
629     __attribute__ ((visibility("default"))) int x;
630    
631     int main(void){
632     extern int x;
633     x = 4;
634     }
635     """
636    
637     def CheckGccVisibility(context):
638     context.Message("Checking for GCC 'visibility' capability... ")
639 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
640     context.Result("disabled")
641     return 0
642 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
643     context.Result(is_ok)
644     return is_ok
645 johnpye 502
646 johnpye 500 #----------------
647 johnpye 502 # YACC
648    
649     yacc_test_text = """
650 johnpye 646 %{
651     #include <stdio.h>
652     %}
653     %token MSG
654 johnpye 502 %start ROOT
655 johnpye 646 %%
656     ROOT:
657     MSG { printf("HELLO"); }
658     ;
659     %%
660 johnpye 502 """
661    
662     def CheckYacc(context):
663 johnpye 644 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
664 johnpye 502 is_ok = context.TryCompile(yacc_test_text,".y")
665     context.Result(is_ok)
666     return is_ok
667    
668     #----------------
669 johnpye 404 # CUnit test
670    
671 johnpye 400 cunit_test_text = """
672 johnpye 451 #include <CUnit/CUnit.h>
673 johnpye 400 int maxi(int i1, int i2){
674     return (i1 > i2) ? i1 : i2;
675     }
676    
677     void test_maxi(void){
678     CU_ASSERT(maxi(0,2) == 2);
679     CU_ASSERT(maxi(0,-2) == 0);
680     CU_ASSERT(maxi(2,2) == 2);
681    
682     }
683     int main(void){
684     /* CU_initialize_registry() */
685 johnpye 404 return 0;
686 johnpye 400 }
687     """
688    
689     def CheckCUnit(context):
690 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
691 johnpye 400
692 johnpye 404 #----------------
693 johnpye 673 # MATH test
694    
695     math_test_text = """
696 johnpye 705 #ifndef _ALL_SOURCE
697     # define _ALL_SOURCE
698     #endif
699     #ifndef _XOPEN_SOURCE
700     # define _XOPEN_SOURCE
701     #endif
702     #ifndef _XOPEN_SOURCE_EXTENDED
703     # define _XOPEN_SOURCE_EXTENDED 1
704     #endif
705 johnpye 673 #include <math.h>
706     int main(void){
707 johnpye 705 double x = 1.0; double y = 1.0; int i = 1;
708     acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
709     j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
710     y0(x); y1(x); yn(i,x);
711     #ifdef _THREAD_SAFE
712     gamma_r(x,&i);
713     lgamma_r(x,&i);
714     #else
715     gamma(x);
716     lgamma(x);
717     #endif
718     hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
719 johnpye 673 return 0;
720     }
721     """
722    
723     def CheckMath(context):
724 johnpye 705 context.Message('Checking for IEE math library... ')
725     libsave=context.env.get('LIBS');
726     context.env.AppendUnique(LIBS=['m'])
727     is_ok=context.TryLink(math_test_text,".c")
728     context.Result(is_ok)
729     if not is_ok:
730     context.env['LIBS']=libsave
731     return is_ok
732    
733 johnpye 673 #----------------
734     # IDA test
735    
736     ida_test_text = """
737     #include <ida.h>
738     #include <nvector_serial.h>
739     #include <ida_spgmr.h>
740     int main(){
741     void *ida_mem;
742     ida_mem = IDACreate();
743     }
744     """
745    
746     def CheckIDA(context):
747     context.Message( 'Checking for IDA (SUNDIALS)... ' )
748    
749     # add SUNDIALS subdirectories as well (what a pain)
750     if context.env.get('IDA_CPPPATH'):
751     extra = [context.env['IDA_CPPPATH']+"/ida",context.env['IDA_CPPPATH']+"/sundials"]
752     context.env.Append(CPPPATH=extra)
753    
754     if ',' in context.env.get('IDA_LIB'):
755     context.env['IDA_LIB']=context.env['IDA_LIB'].split(',')
756     #print "IDA_LIB NOW =",context.env['IDA_LIB']
757     else:
758     print "NO COMMA IN IDA_LIB:",context.env['IDA_LIB']
759    
760     keep = KeepContext(context,"IDA")
761    
762     is_ok = context.TryLink(ida_test_text,".c")
763     context.Result(is_ok)
764    
765     keep.restore(context)
766    
767     if is_ok:
768     context.env.Append(IDA_CPPPATH_EXTRA=extra)
769    
770     return is_ok
771    
772     #----------------
773 johnpye 405 # Tcl test
774 johnpye 404
775 johnpye 561 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
776     tcltk_minor_newest_acceptable = 4
777     tcltk_major_required = 8
778    
779 johnpye 404 tcl_check_text = r"""
780     #include <tcl.h>
781     #include <stdio.h>
782     int main(void){
783     printf("%s",TCL_PATCH_LEVEL);
784     return 0;
785     }
786     """
787    
788     def CheckTcl(context):
789 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
790 johnpye 405
791     def CheckTclVersion(context):
792 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
793 johnpye 405 context.Message("Checking Tcl version... ")
794     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
795 johnpye 404 keep.restore(context)
796     if not is_ok:
797 johnpye 405 context.Result("failed to run check")
798 johnpye 404 return 0
799 johnpye 405
800 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
801 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
802 johnpye 428 context.Result(output+" (bad version)")
803 johnpye 405 # bad version
804     return 0
805    
806     # good version
807 johnpye 552 context.Result(output+", good")
808 johnpye 404 return 1
809    
810 johnpye 405 #----------------
811 johnpye 463 # Tk test
812 johnpye 405
813     tk_check_text = r"""
814     #include <tk.h>
815     #include <stdio.h>
816     int main(void){
817     printf("%s",TK_PATCH_LEVEL);
818     return 0;
819     }
820     """
821     def CheckTk(context):
822 johnpye 673 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
823 johnpye 405
824 johnpye 428
825 johnpye 405 def CheckTkVersion(context):
826 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
827 johnpye 405 context.Message("Checking Tk version... ")
828 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
829 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
830 johnpye 404 keep.restore(context)
831     if not is_ok:
832     context.Result("failed to run check")
833     return 0
834    
835 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
836 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
837 johnpye 404 # bad version
838 johnpye 561 context.Result(output+" (bad version)")
839 johnpye 404 return 0
840 johnpye 400
841 johnpye 404 # good version
842 johnpye 561 context.Result(output+" (good)")
843 johnpye 404 return 1
844 johnpye 485
845     #----------------
846 johnpye 521 # Tktable test
847    
848     tktable_check_text = r"""
849     #include <tkTable.h>
850     #include <stdio.h>
851     int main(void){
852     Table mytable;
853     return 0;
854     }
855     """
856    
857     def CheckTkTable(context):
858     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
859    
860     #---------------
861     # X11 test
862    
863     x11_check_text = r"""
864     #include <X11/Xlib.h>
865     #include <X11/IntrinsicP.h>
866     #include <X11/Intrinsic.h>
867     #include <X11/ObjectP.h>
868     #include <X11/Object.h>
869     int main(void){
870     Object mything;
871     return 0;
872     }
873     """
874    
875     def CheckX11(context):
876     return CheckExtLib(context,'X11',x11_check_text)
877    
878     #----------------
879 johnpye 485 # GCC Version sniffing
880    
881     # TODO FIXME
882    
883     gcc_version4 = False
884    
885 johnpye 398 #------------------------------------------------------
886 johnpye 385 # CONFIGURATION
887    
888     conf = Configure(env
889     , custom_tests = {
890 johnpye 673 'CheckMath' : CheckMath
891     , 'CheckSwigVersion' : CheckSwigVersion
892 johnpye 400 , 'CheckCUnit' : CheckCUnit
893 johnpye 404 , 'CheckTcl' : CheckTcl
894     , 'CheckTclVersion' : CheckTclVersion
895 johnpye 405 , 'CheckTk' : CheckTk
896     , 'CheckTkVersion' : CheckTkVersion
897 johnpye 502 , 'CheckGcc' : CheckGcc
898 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
899 johnpye 502 , 'CheckYacc' : CheckYacc
900 johnpye 521 , 'CheckTkTable' : CheckTkTable
901     , 'CheckX11' : CheckX11
902 johnpye 673 , 'CheckIDA' : CheckIDA
903 johnpye 400 # , 'CheckIsNan' : CheckIsNan
904     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
905 johnpye 385 }
906 johnpye 459 # , config_h = "config.h"
907 johnpye 385 )
908    
909 johnpye 398
910 johnpye 385 # Math library
911    
912 johnpye 673 if need_libm:
913     if not conf.CheckMath():
914     print 'Did not find math library, exiting!'
915     Exit(1)
916     #pass
917 johnpye 427
918 johnpye 385 # Where is 'isnan'?
919    
920     if not conf.CheckFunc('isnan'):
921     print "Didn't find isnan"
922 johnpye 414 # Exit(1)
923 johnpye 385
924 johnpye 500 # GCC visibility
925    
926 johnpye 502 if conf.CheckGcc():
927     conf.env['HAVE_GCC']=True;
928 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
929 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
930     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
931     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
932 johnpye 709 conf.env.Append(CCFLAGS=['-Wall'])
933 johnpye 500
934 johnpye 502 # YACC
935    
936 johnpye 506 if not conf.CheckYacc():
937     print "YACC NOT FOUND OR NOT WORKING"
938     else:
939 johnpye 502 conf.env['HAVE_YACC']=True
940    
941     conf.env['HAVE_LEX']=True
942    
943 johnpye 387 # Tcl/Tk
944 johnpye 386
945 johnpye 586 if with_tcltk:
946     if conf.CheckTcl():
947     if conf.CheckTclVersion():
948     if conf.CheckTk():
949     if with_tcltk and conf.CheckTkVersion():
950     if env['STATIC_TCLTK']:
951     if conf.CheckTkTable():
952     pass
953     else:
954     without_tcltk_reason = "TkTable not found"
955     with_tcltk = False
956     else:
957     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
958     with_tcltk = False
959 johnpye 521 else:
960 johnpye 586 without_tcltk_reason = "Tk not found."
961 johnpye 551 with_tcltk = False
962 johnpye 428 else:
963 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
964 johnpye 551 with_tcltk = False
965 johnpye 586
966 johnpye 428 else:
967 johnpye 586 without_tcltk_reason = "Tcl not found."
968 johnpye 551 with_tcltk = False
969 johnpye 386
970 johnpye 521 if env['STATIC_TCLTK']:
971     conf.CheckX11()
972    
973 johnpye 395 # Python... obviously we're already running python, so we just need to
974     # check that we can link to the python library OK:
975    
976 johnpye 391 if platform.system()=="Windows":
977 johnpye 395 python_lib='python24'
978 johnpye 391 else:
979 johnpye 395 python_lib='python2.4'
980 johnpye 391
981 johnpye 395 # SWIG version
982    
983 johnpye 413 if not conf.CheckSwigVersion():
984     without_python_reason = 'SWIG >= 1.3.24 is required'
985     with_python = False
986    
987 johnpye 400 # CUnit
988    
989 johnpye 593 if with_cunit:
990 johnpye 404 if not conf.CheckCUnit():
991 johnpye 427 without_cunit_reason = 'CUnit not found'
992 johnpye 665 with_cunit = False
993 johnpye 705 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
994 johnpye 427
995 johnpye 673 # IDA
996    
997     if not with_ida:
998     without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
999     elif not conf.CheckIDA():
1000     with_ida = False
1001     without_ida_reason = "IDA not found"
1002    
1003 johnpye 427 # BLAS
1004    
1005 johnpye 459 need_blas=False
1006 johnpye 673
1007     if with_lsode:
1008     need_fortran = True
1009 johnpye 459 need_blas=True
1010 johnpye 673
1011 johnpye 459 if need_blas:
1012     if conf.CheckLib('blas'):
1013     with_local_blas = False
1014     without_local_blas_reason = "Found BLAS installed on system"
1015     else:
1016     with_local_blas = True
1017     need_fortran = True
1018 johnpye 673 else:
1019     with_local_blas= False;
1020     without_local_blas_reason = "BLAS not required"
1021 johnpye 427
1022     # FORTRAN
1023    
1024     if need_fortran:
1025 johnpye 629 conf.env.Tool('fortran')
1026     detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1027 johnpye 427 if detect_fortran:
1028     # For some reason, g77 doesn't get detected properly on MinGW
1029 johnpye 673 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1030 johnpye 427 conf.env.Replace(F77=detect_fortran)
1031     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1032     conf.env.Replace(F77FLAGS='')
1033 johnpye 428 #print "F77:",conf.env['F77']
1034     #print "F77COM:",conf.env['F77COM']
1035     #print "F77FLAGS:",conf.env['F77FLAGS']
1036 johnpye 427 fortran_builder = Builder(
1037     action='$F77COM'
1038     , suffix='.o'
1039     , src_suffix='.f'
1040     )
1041     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1042     else:
1043 johnpye 673 with_lsode=False;
1044     without_lsode_reason="FORTRAN-77 required but not found"
1045 johnpye 629
1046 johnpye 464 #else:
1047     # print "FORTRAN not required"
1048 johnpye 400
1049 johnpye 673 # F2C
1050    
1051     if need_fortran:
1052     if platform.system()=="Windows":
1053     conf.env.Append(LIBPATH='c:\mingw\lib')
1054    
1055    
1056 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
1057    
1058     # TODO: check size of void*
1059    
1060 johnpye 393 # TODO: detect if dynamic libraries are possible or not
1061    
1062 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
1063     if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
1064     print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
1065     +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
1066     env['PACKAGE_LINKING']='STATIC_PACKAGES'
1067    
1068 johnpye 534 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1069 johnpye 427 with_python = 0;
1070     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1071    
1072     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1073    
1074 johnpye 395 conf.Finish()
1075    
1076     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
1077     env.Append(PYTHON_LIB=[python_lib])
1078     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
1079    
1080 johnpye 507 #---------------------------------------
1081     # SUBSTITUTION DICTIONARY for .in files
1082    
1083 johnpye 658 release = env.get('RELEASE')
1084     if release=="0.":
1085     release="0"
1086    
1087 johnpye 507 subst_dict = {
1088     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1089     , '@GLADE_FILE@':'ascend.glade'
1090     , '@HELP_ROOT@':''
1091     , '@ICON_EXTENSION@':icon_extension
1092 johnpye 628 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1093 johnpye 507 , '@INSTALL_BIN@':env['INSTALL_BIN']
1094     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1095 johnpye 683 , '@INSTALL_LIB@':env['INSTALL_LIB']
1096 johnpye 721 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1097 johnpye 507 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1098     , '@VERSION@':version
1099 johnpye 658 , '@RELEASE@':release
1100 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1101 johnpye 507 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1102 johnpye 508 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1103     , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1104 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1105 johnpye 627 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1106 johnpye 683 , '@PYTHON@' : python_exe
1107 johnpye 507 }
1108    
1109 johnpye 594 if env.get('WITH_LOCAL_HELP'):
1110 johnpye 507 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1111     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1112    
1113 johnpye 597 # bool options...
1114 johnpye 673 for k,v in {
1115     'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1116     ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1117     ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1118 johnpye 605 }.iteritems():
1119 johnpye 597 if env.get(k):
1120 johnpye 673 # subst_dict['@'+v+'@']='1'
1121     subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1122 johnpye 594
1123 johnpye 673 if with_ida:
1124     subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1125    
1126     if with_lsode:
1127     subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1128    
1129 johnpye 507 if with_python:
1130     subst_dict['@ASCXX_USE_PYTHON@']="1"
1131 johnpye 673 env['WITH_PYTHON']=1;
1132 johnpye 507
1133     if env.has_key('HAVE_GCCVISIBILITY'):
1134     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1135    
1136     env.Append(SUBST_DICT=subst_dict)
1137    
1138 johnpye 385 #------------------------------------------------------
1139 johnpye 558 # RECIPE: SWIG scanner
1140    
1141     import SCons.Script
1142    
1143     SWIGScanner = SCons.Scanner.ClassicCPP(
1144     "SWIGScan"
1145     , ".i"
1146     , "CPPPATH"
1147     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1148     )
1149    
1150     env.Append(SCANNERS=[SWIGScanner])
1151    
1152     #------------------------------------------------------
1153 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
1154    
1155     import re
1156 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
1157 johnpye 393
1158 johnpye 395 def TOOL_SUBST(env):
1159     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1160     from the source to the target.
1161     The values of SUBST_DICT first have any construction variables expanded
1162     (its keys are not expanded).
1163     If a value of SUBST_DICT is a python callable function, it is called and
1164     the result is expanded as the value.
1165     If there's more than one source and more than one target, each target gets
1166     substituted from the corresponding source.
1167 johnpye 393 """
1168 johnpye 395 env.Append(TOOLS = 'SUBST')
1169     def do_subst_in_file(targetfile, sourcefile, dict):
1170     """Replace all instances of the keys of dict with their values.
1171     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1172     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1173     """
1174     try:
1175     f = open(sourcefile, 'rb')
1176     contents = f.read()
1177     f.close()
1178     except:
1179     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1180     for (k,v) in dict.items():
1181     contents = re.sub(k, v, contents)
1182     try:
1183     f = open(targetfile, 'wb')
1184     f.write(contents)
1185     f.close()
1186     except:
1187     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1188     return 0 # success
1189 johnpye 393
1190 johnpye 395 def subst_in_file(target, source, env):
1191     if not env.has_key('SUBST_DICT'):
1192     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1193     d = dict(env['SUBST_DICT']) # copy it
1194     for (k,v) in d.items():
1195     if callable(v):
1196     d[k] = env.subst(v())
1197     elif SCons.Util.is_String(v):
1198     d[k]=env.subst(v)
1199     else:
1200     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1201     for (t,s) in zip(target, source):
1202     return do_subst_in_file(str(t), str(s), d)
1203 johnpye 393
1204 johnpye 395 def subst_in_file_string(target, source, env):
1205     """This is what gets printed on the console."""
1206     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1207     for (t,s) in zip(target, source)])
1208 johnpye 393
1209 johnpye 395 def subst_emitter(target, source, env):
1210     """Add dependency from substituted SUBST_DICT to target.
1211     Returns original target, source tuple unchanged.
1212     """
1213     d = env['SUBST_DICT'].copy() # copy it
1214     for (k,v) in d.items():
1215     if callable(v):
1216     d[k] = env.subst(v())
1217     elif SCons.Util.is_String(v):
1218     d[k]=env.subst(v)
1219     Depends(target, SCons.Node.Python.Value(d))
1220     return target, source
1221 johnpye 393
1222 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1223     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1224    
1225     TOOL_SUBST(env)
1226    
1227 johnpye 393 #------------------------------------------------------
1228 johnpye 463 # Recipe for 'CHMOD' ACTION
1229 johnpye 439
1230     import SCons
1231     from SCons.Script.SConscript import SConsEnvironment
1232     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1233     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1234    
1235     def InstallPerm(env, dest, files, perm):
1236     obj = env.Install(dest, files)
1237     for i in obj:
1238     env.AddPostAction(i, env.Chmod(str(i), perm))
1239    
1240     SConsEnvironment.InstallPerm = InstallPerm
1241    
1242     # define wrappers
1243     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1244 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1245 johnpye 629 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1246 johnpye 463
1247 johnpye 439 #------------------------------------------------------
1248 johnpye 463 # BUILD...
1249 johnpye 385
1250 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
1251     env.Append(CPPPATH=['#base/generic'])
1252 johnpye 385
1253 johnpye 508 if env['DEBUG']:
1254     env.Append(CCFLAGS=['-g'])
1255    
1256 johnpye 591 if env['GCOV']:
1257     env.Append(
1258     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1259     , LIBS=['gcov']
1260     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1261     )
1262    
1263 johnpye 673 if with_ida:
1264     env.Append(WITH_IDA=1)
1265    
1266 johnpye 463 #-------------
1267     # TCL/TK GUI
1268 johnpye 385
1269 johnpye 551 if with_tcltk:
1270 johnpye 569 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1271 johnpye 391 else:
1272 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1273 johnpye 386
1274 johnpye 463 #-------------
1275     # PYTHON INTERFACE
1276    
1277 johnpye 387 if with_python:
1278 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
1279 johnpye 391 else:
1280 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
1281 johnpye 400
1282 johnpye 463 #------------
1283     # BASE/GENERIC SUBDIRECTORIES
1284    
1285 johnpye 673 libascend_env = env.Copy()
1286    
1287 johnpye 463 dirs = ['general','utilities','compiler','solver','packages']
1288    
1289     srcs = []
1290     for d in dirs:
1291 johnpye 673 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1292 johnpye 463 srcs += heresrcs
1293    
1294     #-------------
1295 johnpye 673 # IMPORTED CODE: LSODE, BLAS, etc
1296    
1297     if with_lsode:
1298     srcs += env.SConscript(['lsod/SConscript'],'env')
1299     srcs += env.SConscript(['linpack/SConscript'],'env')
1300     else:
1301     print "Skipping... LSODE won't be built:", without_lsode_reason
1302    
1303     if with_local_blas:
1304     srcs += env.SConscript(['blas/SConscript'],'env')
1305     else:
1306     print "Skipping... BLAS won't be built:", without_local_blas_reason
1307    
1308     if not with_ida:
1309     print "Skipping... IDA won't be built:", without_ida_reason
1310    
1311     #-------------
1312 johnpye 463 # LIBASCEND -- all base/generic functionality
1313    
1314 johnpye 673 libascend = libascend_env.SharedLibrary('ascend',srcs)
1315 johnpye 463
1316 johnpye 673 env.Alias('libascend',libascend)
1317    
1318 johnpye 463 #-------------
1319     # UNIT TESTS
1320    
1321 johnpye 593 if with_cunit:
1322 johnpye 400 testdirs = ['general','solver','utilities']
1323 johnpye 593 testsrcs = []
1324 johnpye 400 for testdir in testdirs:
1325     path = 'base/generic/'+testdir+'/test/'
1326     env.SConscript([path+'SConscript'],'env')
1327 johnpye 593 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1328    
1329     #print "TESTSRCS =",testsrcs
1330    
1331 johnpye 400 env.SConscript(['test/SConscript'],'env')
1332     env.SConscript(['base/generic/test/SConscript'],'env')
1333 johnpye 593
1334     env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1335 johnpye 400
1336     else:
1337 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1338 johnpye 400
1339 johnpye 463 #------------------------------------------------------
1340 johnpye 683 # CREATE ASCEND-CONFIG scriptlet
1341    
1342     ascendconfig = env.SubstInFile('ascend-config.in')
1343    
1344     #------------------------------------------------------
1345 johnpye 463 # INSTALLATION
1346 johnpye 427
1347 johnpye 552 if env.get('CAN_INSTALL'):
1348 johnpye 463 # the models directory only needs to be processed for installation, no other processing required.
1349     env.SConscript(['models/SConscript'],'env')
1350 johnpye 427
1351 johnpye 721 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
1352 johnpye 463 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1353 johnpye 449
1354 johnpye 463 # TODO: add install options
1355     env.Alias('install',install_dirs)
1356 johnpye 400
1357 johnpye 629 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1358 johnpye 435
1359 johnpye 683 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1360    
1361 johnpye 438 #------------------------------------------------------
1362 johnpye 631 # WINDOWS INSTALLER
1363     # For the windows installer, please see pygtk/SConscript
1364    
1365     if with_installer:
1366     pass
1367     else:
1368     print "Skipping... Windows installer isn't being built:",without_installer_reason
1369    
1370     #------------------------------------------------------
1371 johnpye 673 # PROJECT FILE for MSVC
1372    
1373     env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1374    
1375     #------------------------------------------------------
1376 johnpye 438 # CREATE the SPEC file for generation of RPM packages
1377    
1378 johnpye 463 if platform.system()=="Linux":
1379     env.SubstInFile('ascend.spec.in')
1380 johnpye 552
1381     #------------------------------------------------------
1382     # DISTRIBUTION TAR FILE
1383    
1384 johnpye 554 env['DISTTAR_FORMAT']='bz2'
1385 johnpye 556 env.Append(
1386 johnpye 566 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1387 johnpye 561 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1388 johnpye 556 )
1389 johnpye 554
1390 johnpye 563 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1391 johnpye 556 , [env.Dir('#')]
1392 johnpye 554 )
1393    
1394 johnpye 680 env.Depends(tar,'ascend.spec')
1395    
1396 johnpye 554 #------------------------------------------------------
1397     # RPM BUILD
1398    
1399     #if platform.system()=="Linux":
1400     # pass
1401    
1402     #------------------------------------------------------
1403     # DEFAULT TARGETS
1404    
1405 johnpye 673 default_targets =['libascend']
1406 johnpye 629 if with_tcltk:
1407     default_targets.append('tcltk')
1408     if with_python:
1409     default_targets.append('pygtk')
1410 johnpye 631 if with_installer:
1411     default_targets.append('installer')
1412 johnpye 554
1413 johnpye 629 env.Default(default_targets)
1414    
1415     print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1416    
1417 johnpye 705 # vim: set syntax=python:
1418    

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