/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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