/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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