/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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