/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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