/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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