/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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