/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2024 - (hide annotations) (download)
Wed Apr 29 09:29:27 2009 UTC (11 years, 5 months ago) by jpye
File size: 68245 byte(s)
Fixing up Tcl/Tk build with renamed dirs.
1 jpye 2017 #!/usr/bin/python invoke_using_scons
2 jpye 2007 # This is a build script for use with SCons. Use it to compile ASCEND on
3     # Linux, Windows. It should also give some success on Mac, although this is
4     # much less tested.
5    
6     # version number for this ASCEND build:
7 jpye 1820 version = "0.9.5.116"
8 johnpye 439
9 jpye 2007 # shared library API numbering, for Linux (FIXME windows too?)
10     soname_major = ".1"
11     soname_minor = ".0"
12    
13     import sys, os, commands, platform, distutils.sysconfig, os.path, re, types
14    
15     # version number for python, useful on Windows
16 jpye 1466 pyversion = "%d.%d" % (sys.version_info[0],sys.version_info[1])
17    
18 johnpye 385 #------------------------------------------------------
19 jpye 2007 # PLATFORM DEFAULTS
20 johnpye 385
21 johnpye 464 #print "PLATFORM = ",platform.system()
22 johnpye 385
23 jpye 1488 default_tcl_cpppath = "$TCL/include"
24 jpye 1501 default_tron_envvar="TRON_PATH"
25     default_conopt_envvar="CONOPT_PATH"
26 jpye 1854 default_with_graphviz = True
27 jpye 1488
28 johnpye 464 if platform.system()=="Windows":
29 jpye 2007 # these correspond the the version of Tcl/Tk linked to in the NSIS scripts
30 johnpye 631 default_tcl_lib = "tcl84"
31     default_tk_lib = "tk84"
32 johnpye 464 default_tktable_lib = "Tktable28"
33 jpye 2007
34 johnpye 499 default_install_assets = "glade/"
35     icon_extension = '.png'
36 johnpye 521 default_tcl = "c:\\Tcl"
37 jpye 1645 if os.environ.get('MSYSTEM'):
38 johnpye 642 default_tcl_libpath="$TCL\\bin"
39     else:
40     default_tcl_libpath="$TCL\\lib"
41 jpye 2007
42     # on Windows, we build ASCEND such that it finds it support files
43     # using paths relative to the location of the executable
44 johnpye 627 default_rel_distdir = '.'
45 johnpye 628 default_absolute_paths = False
46 johnpye 739
47 jpye 2007 # where to look for IDA solver libraries, headers, etc.
48 johnpye 739 default_ida_prefix = "c:\\MinGW"
49     if not os.path.exists(default_ida_prefix):
50     default_ida_prefix = None
51 johnpye 783
52 jpye 2007 # where to look for CONOPT when compiling
53 johnpye 800 default_conopt_prefix = "c:\\Program Files\\CONOPT"
54     default_conopt_libpath="$CONOPT_PREFIX"
55     default_conopt_cpppath="$CONOPT_PREFIX"
56 jpye 1399 default_conopt_dlpath="$CONOPT_PREFIX"
57 johnpye 800 default_conopt_lib="conopt3"
58 jpye 2007 if not os.path.exists(default_conopt_prefix):
59     default_conopt_prefix = None
60 johnpye 935
61 jpye 2007 # FIXME remove this
62 jpye 1515 default_tron_prefix="c:\\Program Files\\TRON"
63     default_tron_dlpath="$TRON_PREFIX"
64     default_tron_lib="tron1"
65 jpye 1501
66 johnpye 938 default_prefix="c:\\MinGW"
67     default_libpath="$DEFAULT_PREFIX\\lib"
68 jpye 2007 default_cpppath="$DEFAULT_PREFIX\\include"
69 johnpye 739
70 johnpye 673 need_libm = False
71 jpye 1592 python_exe = sys.executable
72 johnpye 816 default_with_scrollkeeper=False
73 jpye 1504 pathsep = ";"
74 jpye 1566
75     default_fortran="g77"
76     default_f2c_lib="g2c"
77 jpye 2007 default_python = distutils.sysconfig.get_python_lib()
78 jpye 1597
79 jpye 2007 soname_minor = ""
80     soname_major = ""
81 jpye 1854 # still problems with Graphviz on Windows, leave it off now by default.
82 jpye 1720
83 johnpye 464 else:
84 jpye 1787 default_tcl_lib = "tcl8.5"
85     default_tk_lib = "tk8.5"
86     default_tktable_lib = "Tktable2.9"
87 johnpye 628 default_install_assets = "$INSTALL_ASCDATA/glade/"
88 johnpye 499 icon_extension = '.svg'
89 johnpye 684 default_tcl = '/usr'
90 jpye 1488 default_tcl_libpath = "$TCL/lib"
91 jpye 2007 default_python = distutils.sysconfig.get_python_lib()
92 jpye 1488
93     if os.path.exists("/etc/debian_version"):
94     default_tcl_cpppath = "/usr/include/tcl8.4"
95 jpye 1787 default_tcl_lib = "tcl8.4"
96     default_tk_lib = "tk8.4"
97     default_tktable_lib = "Tktable2.8"
98 jpye 1488
99 jpye 2006 if os.path.exists("/etc/lsb-release"):
100     _f = file("/etc/lsb-release")
101     _r = re.compile("([A-Z][^=]*)=(.*)")
102     LSB = {}
103     for l in _f:
104     _m = _r.match(l.strip())
105     LSB[_m.group(1)] = _m.group(2)
106     if LSB['DISTRIB_ID'] == "Ubuntu":
107     if float(LSB['DISTRIB_RELEASE']) >= 9.04:
108     default_tcl_lib = "tcl8.5"
109     default_tk_lib = "tk8.5"
110     default_tktable_lib = "Tktable2.9"
111     default_tcl_cpppath = "/usr/include/tcl8.5"
112    
113    
114 jpye 2016 default_rel_distdir = '..'
115 johnpye 628 default_absolute_paths = True
116 jpye 1400 default_ida_prefix="/usr"
117 johnpye 783 default_conopt_prefix="/usr"
118 johnpye 800 default_conopt_libpath="$CONOPT_PREFIX/lib"
119     default_conopt_cpppath="$CONOPT_PREFIX/include"
120 jpye 1399 default_conopt_dlpath= default_conopt_libpath + ":/usr/local/lib"
121 johnpye 800 default_conopt_lib="consub3"
122    
123 jpye 1501 default_tron_prefix="/usr"
124     default_tron_dlpath="$TRON_PREFIX/lib"
125     default_tron_lib="tron1"
126    
127 johnpye 938 default_prefix="/usr"
128     default_libpath="$DEFAULT_PREFIX/lib"
129     default_cpppath="$DEFAULT_PREFIX/include"
130    
131 johnpye 673 need_libm = True
132 johnpye 551 if not os.path.isdir(default_tcl):
133     default_tcl = '/usr'
134 johnpye 683 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
135 johnpye 816 default_with_scrollkeeper=False
136 jpye 1504 pathsep = ":"
137 jpye 1566
138     default_fortran="gfortran"
139     default_f2c_lib="gfortran"
140 jpye 1732
141 jpye 1853 #default_graphviz_libs=["graph","cdt","gvc"]
142     #default_graphviz_libpath = default_libpath
143     #if os.path.exists("/usr/lib/graphviz/libgraph.so"):
144     # # for Ubuntu 7.04
145     # default_graphviz_libpath="/usr/lib/graphviz"
146     # default_graphviz_rpath="$GRAPHVIZ_LIBPATH"
147 jpye 2007
148     soname_clean = "${SHLIBPREFIX}ascend${SHLIBSUFFIX}"
149     soname_full = "%s%s" % (soname_clean,soname_major)
150    
151     #------------------------------------------------------
152     # OPTIONS
153     #
154     # The following give the set of command-line parameters that can be passed to
155     # SCons from the commandline. Options will be 'remembered' by being cached
156     # in the file 'options.cache'; if you want to start with a clean slate, you
157     # should remove that file.
158    
159     opts = Options(['options.cache', 'config.py'])
160 jpye 1597
161 johnpye 562 opts.Add(
162     'CC'
163     ,'C Compiler command'
164     ,None
165     )
166    
167     opts.Add(
168     'CXX'
169     ,'C++ Compiler command'
170     ,None
171     )
172    
173 johnpye 591 opts.Add(BoolOption(
174     'GCOV'
175 johnpye 593 , 'Whether to enable coverage testing in object code'
176     , False
177 johnpye 591 ))
178    
179 jpye 2007 if platform.system()!="Windows":
180     opts.Add(BoolOption(
181     'WITH_GCCVISIBILITY'
182     ,"Whether to use GCC Visibility features (only applicable if available)"
183     ,True
184     ))
185 johnpye 526
186 johnpye 1142 opts.Add(BoolOption(
187     'WITH_SIGNALS'
188     ,"Whether to permit use of signals for flow control in the C-level code"
189 johnpye 1234 ,True
190 johnpye 1142 ))
191    
192 johnpye 392 # You can turn off building of Tcl/Tk interface
193 johnpye 386 opts.Add(BoolOption(
194 johnpye 542 'WITH_TCLTK'
195 johnpye 673 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
196 johnpye 542 , True
197 johnpye 386 ))
198    
199 johnpye 392 # You can turn off the building of the Python interface
200 johnpye 387 opts.Add(BoolOption(
201 johnpye 542 'WITH_PYTHON'
202 johnpye 673 ,"Set to False if you don't want to build Python wrappers."
203 johnpye 542 , True
204 johnpye 387 ))
205    
206 johnpye 392 # Which solvers will we allow?
207     opts.Add(ListOption(
208     'WITH_SOLVERS'
209 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
210 jpye 1520 +" works. The option 'LSOD' is provided for backwards compatibility"
211     +"; the value 'LSODE' is preferred."
212 jpye 1734 ,["QRSLV","CMSLV","LSODE","IDA","CONOPT","LRSLV","TRON","IPOPT","DOPRI5"]
213 johnpye 392 ,['QRSLV','MPS','SLV','OPTSQP'
214     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
215 jpye 1734 ,'LSODE','LSOD','OPTSQP',"IDA","TRON","IPOPT","DOPRI5"
216 johnpye 392 ]
217     ))
218    
219 johnpye 393 # Where will the local copy of the help files be kept?
220 jpye 1442 opts.Add(BoolOption(
221     'WITH_DOC'
222 jpye 1443 , "Should we try to build and install help files? If not, ASCEND will access online help files"
223 jpye 1442 , True
224 johnpye 393 ))
225    
226 jpye 1443 opts.Add(BoolOption(
227     'WITH_DOC_BUILD'
228     , "If true, we'll attempt to build docs. Set false, we'll assume we already have then (eg from the tarball)"
229     , "$WITH_DOC"
230     ))
231    
232     opts.Add(BoolOption(
233     'WITH_DOC_INSTALL'
234     , "If true, SCons will install the documentation file(s). If false, assume rpm or dpkg is going to do it."
235     , "$WITH_DOC"
236     ))
237    
238 jpye 1442 opts.Add(
239     'HELP_ROOT'
240     , "Location of the main help file"
241     , "$INSTALL_DOC/book.pdf"
242     )
243    
244 johnpye 393 # Will bintoken support be enabled?
245     opts.Add(BoolOption(
246     'WITH_BINTOKEN'
247     ,"Enable bintoken support? This means compiling models as C-code before"
248     +" running them, to increase solving speed for large models."
249     ,False
250     ))
251    
252 johnpye 398 # What should the default ASCENDLIBRARY path be?
253     # Note: users can change it by editing their ~/.ascend.ini
254 johnpye 393 opts.Add(
255     'DEFAULT_ASCENDLIBRARY'
256     ,"Set the default value of the ASCENDLIBRARY -- the location where"
257     +" ASCEND will look for models when running ASCEND"
258 jpye 1519 ,"$INSTALL_MODELS"
259 johnpye 393 )
260    
261 jpye 1519 # What should the default ASCENDLIBRARY path be?
262     # Note: users can change it by editing their ~/.ascend.ini
263     opts.Add(
264     'DEFAULT_ASCENDSOLVERS'
265     ,"Set the default value of ASCENDSOLVERS -- the location where"
266     +" ASCEND will look for solver shared-library files"
267     ,"$INSTALL_SOLVERS"
268     )
269    
270 johnpye 398 # Where is SWIG?
271     opts.Add(
272     'SWIG'
273     ,"SWIG location, probably only required for MinGW and MSVC users."
274     +" Enter the location as a Windows-style path, for example"
275 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
276 johnpye 398 )
277    
278 johnpye 400 # Build the test suite?
279     opts.Add(BoolOption(
280 johnpye 593 'WITH_CUNIT'
281 johnpye 665 ,"You can disable CUnit tests with this option. This will basically stop"
282     +" SCons from parsing the SConscript files relating to the 'test'"
283     +" target, which just might make things marginally faster. Probably"
284     +" you can just ignore this option though. SCons will sniff for Cunit"
285     +" but build the tests only if you specify the 'test' target."
286     ,True
287 johnpye 400 ))
288 johnpye 393
289 johnpye 993 # Build with MMIO matrix export support?
290     opts.Add(BoolOption(
291     'WITH_MMIO'
292     ,"Include support for exporting matrices in Matrix Market format"
293     ,True
294     ))
295    
296 johnpye 938 #----- default paths -----
297     opts.Add(PackageOption(
298     'DEFAULT_PREFIX'
299     ,"Where are most of the shared libraries located on your system?"
300     ,default_prefix
301     ))
302    
303 jpye 2007 #------ cunit --------
304     # CUnit is a unit testing library that we use to test libascend.
305 johnpye 957
306 johnpye 935 # Where was CUNIT installed?
307     opts.Add(PackageOption(
308     'CUNIT_PREFIX'
309     ,"Where are your CUnit files?"
310 johnpye 938 ,"$DEFAULT_PREFIX"
311 johnpye 935 ))
312    
313 johnpye 400 # Where are the CUnit includes?
314     opts.Add(PackageOption(
315     'CUNIT_CPPPATH'
316     ,"Where are your CUnit include files?"
317 johnpye 938 ,"$CUNIT_PREFIX/include"
318 johnpye 400 ))
319 johnpye 392
320 johnpye 404 # Where are the CUnit libraries?
321 johnpye 400 opts.Add(PackageOption(
322     'CUNIT_LIBPATH'
323 johnpye 404 ,"Where are your CUnit libraries?"
324 johnpye 938 ,"$CUNIT_PREFIX/lib"
325 johnpye 400 ))
326    
327 johnpye 938 #-------- ida -------
328    
329 johnpye 673 opts.Add(PackageOption(
330 jpye 1400 "SUNDIALS_PREFIX"
331 johnpye 673 ,"Prefix for your IDA install (IDA ./configure --prefix)"
332     ,default_ida_prefix
333     ))
334 johnpye 521
335 johnpye 534 opts.Add(
336 jpye 1400 'SUNDIALS_CPPPATH'
337 johnpye 673 ,"Where is your ida.h?"
338 jpye 1400 ,"$SUNDIALS_PREFIX/include"
339 johnpye 673 )
340    
341 jpye 1404 #
342 johnpye 673 opts.Add(
343 jpye 1400 'SUNDIALS_LIBPATH'
344 johnpye 673 ,"Where are your SUNDIALS libraries installed?"
345 jpye 1400 ,"$SUNDIALS_PREFIX/lib"
346 johnpye 673 )
347    
348 jpye 1404 opts.Add(
349     'SUNDIALS_LIBS'
350 jpye 1546 ,"What libraries are required for SUNDIALS?"
351 jpye 1404 ,['sundials_nvecserial','sundials_ida','m']
352     )
353    
354 johnpye 938 # ----- conopt-----
355 johnpye 783
356     opts.Add(PackageOption(
357     "CONOPT_PREFIX"
358     ,"Prefix for your CONOPT install (CONOPT ./configure --prefix)"
359 johnpye 800 ,default_conopt_prefix
360 johnpye 783 ))
361    
362 johnpye 673 opts.Add(
363 johnpye 783 "CONOPT_LIB"
364 jpye 1747 ,"Library linked to for CONOPT. This is the name of the CONOPT .so or DLL. On Windows it seems to be called 'copopt3' but on linux it seems to be called 'consub3'."
365 johnpye 800 ,default_conopt_lib
366 johnpye 783 )
367    
368 jpye 1541 opts.Add(BoolOption(
369     "CONOPT_LINKED"
370     ,"Do you want to dynamically link to CONOPT (only possible if CONOPT is available at buildtime)"
371     ,False
372     ))
373    
374 johnpye 783 opts.Add(
375     'CONOPT_CPPPATH'
376     ,"Where is your conopt.h?"
377 johnpye 800 ,default_conopt_cpppath
378 johnpye 783 )
379    
380     opts.Add(
381     'CONOPT_LIBPATH'
382 jpye 1399 ,"Where is your CONOPT library installed?"
383 johnpye 800 ,default_conopt_libpath
384 johnpye 783 )
385    
386     opts.Add(
387 jpye 1399 'CONOPT_DLPATH'
388 jpye 1747 ,"Default (fallback) search path that ASCEND should use when dlopening the CONOPT library at runtime? This is only used if the conopt environment variable doesn't exist and doesn't point to a location where the DLL/SO is found. This is in platform-specific form (paths with ';' separator in Windows, ':' separator on Linux)."
389 jpye 1399 ,default_conopt_dlpath
390     )
391    
392     opts.Add(
393 johnpye 800 'CONOPT_ENVVAR'
394 jpye 1747 ,"Name of the optional environment variable which will be used for the value of the searchpath for the CONOPT DLL/SO."
395 johnpye 800 ,default_conopt_envvar
396     )
397    
398 jpye 1546 #------- IPOPT -------
399    
400     opts.Add(PackageOption(
401     "IPOPT_PREFIX"
402     ,"Prefix for your IPOPT install (IPOPT ./configure --prefix)"
403     ,default_conopt_prefix
404     ))
405    
406     opts.Add(
407 jpye 1547 "IPOPT_LIBS"
408 jpye 1546 ,"Library linked to for IPOPT"
409 jpye 1547 ,["$F2C_LIB","blas","lapack","pthread","ipopt"]
410 jpye 1546 )
411    
412 jpye 1547
413 jpye 1546 opts.Add(
414     "IPOPT_LIBPATH"
415     ,"Where is your IPOPT library installed"
416     ,"$IPOPT_PREFIX/lib"
417     )
418    
419     opts.Add(
420     'IPOPT_CPPPATH'
421 jpye 1770 ,"Where is your IPOPT coin/IpStdCInterface.h (do not include the 'coin' in the path)"
422 jpye 1546 ,"$IPOPT_PREFIX/include"
423     )
424    
425    
426 jpye 1501 #------- TRON -------
427    
428     opts.Add(
429     'TRON_ENVVAR'
430     ,"What environment variable should be used at runtime to override the default search location for TRON DLL/SO?"
431     ,default_tron_envvar
432     )
433    
434     opts.Add(
435     "TRON_LIB"
436     ,"Library linked to for TRON"
437     ,"tron"
438     )
439    
440 jpye 1515 opts.Add(
441 jpye 1501 "TRON_PREFIX"
442     ,"Prefix for your TRON install"
443     ,default_tron_prefix
444 jpye 1515 )
445 jpye 1501
446     opts.Add(
447     'TRON_DLPATH'
448     ,"What is the default search path that ASCEND should use when dlopening the TRON library at runtime?"
449     ,default_tron_dlpath
450     )
451    
452 johnpye 938 #-------- f2c ------
453    
454 johnpye 800 opts.Add(
455 johnpye 673 "F2C_LIB"
456     ,"F2C library (eg. g2c, gfortran, f2c)"
457 jpye 1566 ,default_f2c_lib # the default is gfortran now
458 johnpye 673 )
459    
460     opts.Add(PackageOption(
461     "F2C_LIBPATH"
462     ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
463     ,"off"
464     ))
465    
466 jpye 1398 opts.Add(
467     "FORTRAN"
468     ,"Fortran compiler (eg g77, gfortran)"
469 jpye 1566 ,default_fortran
470 jpye 1398 )
471    
472 johnpye 938 #------- tcl/tk --------
473    
474 johnpye 673 opts.Add(
475 johnpye 521 'TCL'
476     ,'Base of Tcl distribution'
477     ,default_tcl
478 johnpye 534 )
479 johnpye 521
480 johnpye 404 # Where are the Tcl includes?
481 johnpye 534 opts.Add(
482 johnpye 404 'TCL_CPPPATH'
483     ,"Where are your Tcl include files?"
484 jpye 1488 ,default_tcl_cpppath
485 johnpye 534 )
486 johnpye 404
487     # Where are the Tcl libs?
488 johnpye 534 opts.Add(
489 johnpye 404 'TCL_LIBPATH'
490     ,"Where are your Tcl libraries?"
491 johnpye 541 ,default_tcl_libpath
492 johnpye 534 )
493 johnpye 404
494 johnpye 428 # What is the name of the Tcl lib?
495     opts.Add(
496     'TCL_LIB'
497 johnpye 561 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
498 johnpye 464 ,default_tcl_lib
499 johnpye 428 )
500    
501 johnpye 405 # Where are the Tk includes?
502 johnpye 534 opts.Add(
503 johnpye 405 'TK_CPPPATH'
504     ,"Where are your Tk include files?"
505 johnpye 464 ,'$TCL_CPPPATH'
506 johnpye 534 )
507 johnpye 404
508 johnpye 405 # Where are the Tk libs?
509 johnpye 534 opts.Add(
510 johnpye 405 'TK_LIBPATH'
511     ,"Where are your Tk libraries?"
512 johnpye 464 ,'$TCL_LIBPATH'
513 johnpye 534 )
514 johnpye 405
515 johnpye 428 # What is the name of the Tk lib?
516     opts.Add(
517     'TK_LIB'
518 johnpye 521 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
519 johnpye 464 ,default_tk_lib
520 johnpye 435 )
521    
522 johnpye 460 # Static linking to TkTable
523    
524     opts.Add(BoolOption(
525 johnpye 521 'STATIC_TCLTK'
526 johnpye 554 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
527 johnpye 460 ,False
528     ))
529    
530 johnpye 464 opts.Add(
531 johnpye 460 'TKTABLE_LIBPATH'
532     ,'Location of TkTable static library'
533 johnpye 464 ,'$TCL_LIBPATH/Tktable2.8'
534     )
535 johnpye 460
536 johnpye 435 opts.Add(
537 johnpye 460 'TKTABLE_LIB'
538 johnpye 521 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
539 johnpye 464 ,default_tktable_lib
540 johnpye 460 )
541    
542     opts.Add(
543 johnpye 521 'TKTABLE_CPPPATH'
544     ,'Location of TkTable header file'
545     ,'$TCL_CPPPATH'
546     )
547    
548     opts.Add(
549     'X11'
550 johnpye 554 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
551 johnpye 521 ,'/usr/X11R6'
552     )
553    
554     opts.Add(
555     'X11_LIBPATH'
556 johnpye 554 ,'Location of X11 lib. EXPERIMENTAL'
557 johnpye 521 ,'$X11/lib'
558     )
559    
560     opts.Add(
561     'X11_CPPPATH'
562 johnpye 554 ,'Location of X11 includes. EXPERIMENTAL'
563 johnpye 521 ,'$X11/include'
564     )
565    
566     opts.Add(
567     'X11_LIB'
568 johnpye 554 ,'Name of X11 lib. EXPERIMENTAL'
569 johnpye 521 ,'X11'
570     )
571    
572 johnpye 938 #----- installed file locations (for 'scons install') -----
573    
574 johnpye 521 opts.Add(
575 johnpye 435 'INSTALL_PREFIX'
576     ,'Root location for installed files'
577 johnpye 449 ,'/usr/local'
578 johnpye 428 )
579    
580 johnpye 435 opts.Add(
581     'INSTALL_BIN'
582     ,'Location to put binaries during installation'
583     ,"$INSTALL_PREFIX/bin"
584     )
585    
586     opts.Add(
587 johnpye 463 'INSTALL_LIB'
588 johnpye 683 ,'Location to put libraries during installation'
589 johnpye 463 ,"$INSTALL_PREFIX/lib"
590     )
591    
592     opts.Add(
593 ben.allan 624 'INSTALL_SHARE'
594 johnpye 628 ,'Common shared-file location on this system'
595     ,"$INSTALL_PREFIX/share"
596 johnpye 435 )
597    
598 johnpye 816 opts.Add(
599 jpye 2007 'INSTALL_PYTHON'
600     ,'Common shared-file location on this system'
601 jpye 2016 ,os.path.join(default_python,"ascend")
602 jpye 2007 )
603    
604     opts.Add(
605 johnpye 628 'INSTALL_ASCDATA'
606     ,"Location of ASCEND shared data (TK, python, models etc)"
607     ,"$INSTALL_SHARE/ascend"
608     )
609    
610     opts.Add(
611 jpye 1504 'INSTALL_MODELS'
612     ,"Location of ASCEND model files (.a4c,.a4l,.a4s)"
613 jpye 2007 ,"$INSTALL_LIB/ascend/models"
614 jpye 1504 )
615    
616     opts.Add(
617     'INSTALL_SOLVERS'
618     ,"Location of ASCEND solvers"
619 jpye 2007 ,"$INSTALL_LIB/ascend/solvers"
620 jpye 1504 )
621    
622     opts.Add(
623 jpye 1442 'INSTALL_DOC'
624     ,"Location of ASCEND documentation files"
625     ,"$INSTALL_SHARE/doc/ascend-"+version
626     )
627    
628     opts.Add(
629 johnpye 435 'INSTALL_INCLUDE'
630     ,'Location to put header files during installation'
631     ,"$INSTALL_PREFIX/include"
632     )
633    
634 johnpye 938
635 johnpye 448 opts.Add(
636 johnpye 938 'INSTALL_ROOT'
637     ,'For use by RPM only: location of %{buildroot} during rpmbuild'
638     ,""
639     )
640    
641 jpye 1597 opts.Add(
642     'EXTLIB_SUFFIX'
643     ,"Filename suffix for ASCEND 'external libraries' (for use with IMPORT"
644 jpye 1598 ,"_ascend$SHLIBSUFFIX"
645 jpye 1597 )
646    
647     opts.Add(
648     'EXTLIB_PREFIX'
649     ,"Filename suffix for ASCEND 'external libraries' (for use with IMPORT"
650     ,"$SHLIBPREFIX"
651     )
652    
653 johnpye 938 #----------------------
654    
655     opts.Add(
656 johnpye 455 'PYGTK_ASSETS'
657 jpye 2007 ,'Default location for Glade assets (will be recorded in pygtk/config.py)'
658 johnpye 455 ,default_install_assets
659     )
660    
661 johnpye 508 opts.Add(BoolOption(
662     'DEBUG'
663     ,"Compile source with debugger symbols, eg for use with 'gdb'"
664     ,False
665     ))
666    
667 johnpye 597 opts.Add(BoolOption(
668     'MALLOC_DEBUG'
669     ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
670     ,False
671     ))
672    
673 johnpye 938 #------ dmalloc --------
674     opts.Add(PackageOption(
675     'DMALLOC_PREFIX'
676     ,"Where are your dmalloc files?"
677     ,default_prefix
678     ))
679 johnpye 448
680 johnpye 938 opts.Add(PackageOption(
681     'DMALLOC_CPPPATH'
682     ,"Where are your dmalloc include files?"
683     ,default_cpppath
684     ))
685    
686     opts.Add(PackageOption(
687     'DMALLOC_LIBPATH'
688     ,"Where are your dmalloc libraries?"
689     ,default_libpath
690     ))
691    
692     opts.Add(BoolOption(
693     'WITH_DMALLOC'
694     ,"Link to the DMALLOC library (if available) for debugging of memory usage."
695     ,False
696     ))
697    
698 jpye 1853 #------ Graphviz --------
699     # opts.Add(PackageOption(
700     # 'GRAPHVIZ_PREFIX'
701     # ,"Where are your GRAPHVIZ files?"
702     # ,default_prefix
703     # ))
704     #
705     # opts.Add(PackageOption(
706     # 'GRAPHVIZ_CPPPATH'
707     # ,"Where are your GRAPHVIZ include files? (don't need the final '/graphviz')"
708     # ,default_cpppath
709     # ))
710     #
711     # opts.Add(PackageOption(
712     # 'GRAPHVIZ_LIBPATH'
713     # ,"Where are your GRAPHVIZ libraries?"
714     # ,default_graphviz_libpath
715     # ))
716     #
717     # opts.Add(
718     # 'GRAPHVIZ_LIBS'
719     # ,"What are your GRAPHVIZ libraries named?"
720     # ,default_graphviz_libs
721     # )
722     #
723     # opts.Add(PackageOption(
724     # 'GRAPHVIZ_RPATH'
725     # ,"What is your GRAPHVIZ rpath for locating libraries at runtime? (only required for old Ubuntu)"
726     # ,default_graphviz_rpath
727     # ))
728 johnpye 1109
729     opts.Add(BoolOption(
730 jpye 1678 'WITH_GRAPHVIZ'
731     ,"Link to the GRAPHVIZ library (if available, for generating incidence graphs)"
732 jpye 1854 ,default_with_graphviz
733 johnpye 1109 ))
734    
735 jpye 1326
736     #------ ufsparse --------
737     opts.Add(PackageOption(
738     'UFSPARSE_PREFIX'
739     ,"Where are your UFSPARSE files?"
740     ,default_prefix
741     ))
742    
743     opts.Add(PackageOption(
744     'UFSPARSE_CPPPATH'
745     ,"Where are your UFSPARSE include files?"
746     ,default_cpppath
747     ))
748    
749     opts.Add(PackageOption(
750     'UFSPARSE_LIBPATH'
751     ,"Where are your UFSPARSE libraries?"
752     ,default_libpath
753     ))
754    
755     opts.Add(BoolOption(
756     'WITH_UFSPARSE'
757     ,"Link to the UFSPARSE library (if available, for additional sparse matrix routines)"
758     ,True
759     ))
760    
761 johnpye 938 #-----------------------
762    
763 jpye 1557 opts.Add(BoolOption(
764     'UPDATE_NO_YACC_LEX'
765     ,"Update the *_no_yacc* and *_no_lex* files in the source tree? (these files are created so that ASCEND can be compiled in the absence of those tools)"
766     ,False
767     ))
768    
769 johnpye 563 opts.Add(
770     'DISTTAR_NAME'
771     ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
772     ,"ascend-"+version
773     )
774    
775 johnpye 656 opts.Add(
776     'RELEASE'
777     ,"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."
778     ,"0"
779     )
780    
781 johnpye 605 opts.Add(BoolOption(
782 johnpye 628 'ABSOLUTE_PATHS'
783 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."
784 johnpye 628 ,default_absolute_paths
785 johnpye 605 ))
786    
787 johnpye 578 opts.Add(
788     'WIN_INSTALLER_NAME'
789     ,"Name of the installer .exe to create under Windows (minus the '.exe')"
790 jpye 1467 ,"ascend-"+version+"-py"+pyversion+".exe"
791 johnpye 578 )
792    
793 johnpye 594 opts.Add(BoolOption(
794     'WITH_XTERM_COLORS'
795     ,"Set to 0 if you don't want xterm colour codes in the console output"
796     ,True
797     ))
798    
799 johnpye 761 opts.Add(BoolOption(
800     'WITH_EXTFNS'
801 jpye 1504 ,"Set to 0 if you don't want to attempt to build the external modules bundled with ASCEND"
802 johnpye 761 ,True
803     ))
804    
805 johnpye 816 opts.Add(BoolOption(
806     'WITH_SCROLLKEEPER'
807     ,"Set to to 1 if you want to install an OMF file that can be read by scrollkeeper (eg Yelp on GNOME)"
808     ,default_with_scrollkeeper
809     ))
810    
811 jpye 1720 opts.Add(BoolOption(
812     'WITH_MSVCR71'
813     ,"Attempt to link against MSVCR71.DLL, to enable passing of FILE* objects to/from python"
814     ,False
815     ))
816 jpye 1557
817 johnpye 546
818 johnpye 392 # TODO: OTHER OPTIONS?
819     # TODO: flags for optimisation
820 johnpye 393 # TODO: turning on/off bintoken functionality
821 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
822 johnpye 393
823 johnpye 498 # Import the outside environment
824    
825 johnpye 800 def c_escape(str):
826     return re.sub("\\\\","/",str)
827    
828     envadditional={}
829 johnpye 740
830 jpye 1630 tools = [
831 jpye 1645 'lex', 'yacc', 'fortran', 'swig', 'nsis', 'substinfile'
832 jpye 1853 ,'disttar', 'tar', 'graphviz'
833 jpye 1630 ]
834 johnpye 832 if platform.system()=="Windows":
835 johnpye 1078 if os.environ.get('OSTYPE')=='msys' or os.environ.get('MSYSTEM'):
836 johnpye 832 envenv = os.environ;
837 jpye 1459 tools += ['mingw']
838 johnpye 922 #TODO removed 'doxygen' for SCons 0.96.93
839 johnpye 832 envadditional['IS_MINGW']=True
840     else:
841 johnpye 1082 print "Assuming VC++ build environment (Note: MinGW is preferred)"
842 johnpye 832 envenv = {
843     'PATH':os.environ['PATH']
844     ,'INCLUDE':os.environ['INCLUDE']
845     ,'LIB':os.environ['LIB']
846     ,'MSVS_IGNORE_IDE_PATHS':1
847     }
848 jpye 1459 tools += ['default']
849 johnpye 922 #TODO removed 'doxygen' for SCons 0.96.93
850 johnpye 832 envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
851 johnpye 498 else:
852 johnpye 832 if os.environ.get('TARGET')=='mingw':
853     envenv = os.environ
854 jpye 1459 tools += ['crossmingw']
855 jpye 1420 envadditional['CPPPATH']=['/usr/lib/gcc/i586-mingw32msvc/3.4.5/include','/usr/include']
856     envadditional['LIBS']=['gcc']
857 johnpye 832 else:
858     envenv = os.environ
859 jpye 1459 tools += ['default']
860 johnpye 922 #TODO removed 'doxygen' for SCons 0.96.93
861 johnpye 800
862 johnpye 832
863 johnpye 800 env = Environment(
864     ENV=envenv
865     , toolpath=['scons']
866     , tools=tools
867     , **envadditional
868     )
869 johnpye 498
870 jpye 1420 #print "PATH =",os.environ['PATH']
871     #print "PROGSUFFIX =",env['PROGSUFFIX']
872     #print "CPPPATH =",env['CPPPATH']
873 jpye 1380
874 johnpye 385 opts.Update(env)
875 jpye 1520
876 jpye 1853 for l in ['SUNDIALS','IPOPT']:
877 jpye 1712 var = "%s_LIBS" % l
878     if not isinstance(env[var],types.ListType):
879     env[var] = env[var].split(",")
880    
881 jpye 1520 if 'LSOD' in env['WITH_SOLVERS']:
882     if 'LSODE' not in env['WITH_SOLVERS']:
883     env['WITH_SOLVERS'].append('LSODE')
884     env['WITH_SOLVERS'].remove('LSOD')
885    
886 johnpye 385 opts.Save('options.cache',env)
887    
888     Help(opts.GenerateHelpText(env))
889    
890 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
891 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
892 johnpye 386
893 johnpye 551 with_python = env.get('WITH_PYTHON')
894 johnpye 427 without_python_reason = "disabled by options/config.py"
895 johnpye 387
896 johnpye 593 with_cunit = env.get('WITH_CUNIT')
897 johnpye 427 without_cunit_reason = "not requested"
898 johnpye 400
899 johnpye 761 with_extfns = env.get('WITH_EXTFNS')
900     without_extfn_reason = "disabled by options/config.py"
901    
902 johnpye 816 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
903     without_scrollkeeper_reason = "disabled by options/config.py"
904    
905 johnpye 938 with_dmalloc = env.get('WITH_DMALLOC')
906     without_dmalloc_reason = "disabled by options/config.py"
907    
908 jpye 1678 with_graphviz = env.get('WITH_GRAPHVIZ')
909     without_graphiviz_reason = "disabled by options/config.py"
910 johnpye 1109
911 jpye 1326 with_ufsparse = env.get('WITH_UFSPARSE')
912     without_ufsparse_reason = "disabled by options/config.py"
913    
914 johnpye 993 with_mmio = env.get('WITH_MMIO')
915     without_mmio_reason = "disabled by options/config.py"
916    
917 johnpye 1142 with_signals = env.get('WITH_SIGNALS')
918     without_signals_reason = "disabled by options/config.py"
919    
920 jpye 1442 with_doc = env.get('WITH_DOC')
921    
922 jpye 1443 with_doc_build = env.get('WITH_DOC_BUILD');
923 jpye 1470 without_doc_build_reason = "disabled by options/config.py"
924 jpye 1443 if not with_doc:
925 jpye 1470 with_doc_build = False
926     without_doc_build_reason = "disabled by with_doc"
927 jpye 1443
928 jpye 1442 with_latex2html = False
929    
930 johnpye 631 if platform.system()=="Windows":
931     with_installer=1
932     else:
933     with_installer=0
934     without_installer_reason = "only possible under Windows"
935 johnpye 673
936 jpye 1734 with_lsode = 'LSODE' in env['WITH_SOLVERS']
937     without_lsode_reason = "Not selected (see config option WITH_SOLVERS)"
938 johnpye 673
939 jpye 1734 with_ida = 'IDA' in env['WITH_SOLVERS']
940     without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
941 johnpye 783
942 jpye 1734 with_dopri5 = 'DOPRI5' in env['WITH_SOLVERS']
943     without_dopri5_reason = "Not selected (see config option WITH_SOLVERS)"
944 johnpye 783
945 jpye 1734 with_conopt = 'CONOPT' in env['WITH_SOLVERS']
946     without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
947 jpye 1529
948 jpye 1734 with_ipopt = 'IPOPT' in env['WITH_SOLVERS']
949     without_ipopt_reason = "Not selected (see config option WITH_SOLVERS)"
950    
951    
952 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
953     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
954     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
955 johnpye 393
956 johnpye 463 can_install = True
957     if platform.system()=='Windows':
958     can_install = False
959    
960     env['CAN_INSTALL']=can_install
961 johnpye 721
962 jpye 1437 print "TCL=",env['TCL']
963 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
964     print "TCL_LIBPATH =",env['TCL_LIBPATH']
965     print "TCL_LIB =",env['TCL_LIB']
966 johnpye 562 print "CC =",env['CC']
967     print "CXX =",env['CXX']
968 johnpye 673 print "FORTRAN=",env.get('FORTRAN')
969 johnpye 393
970 johnpye 628 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
971 jpye 1504 print "INSTALL_ASCDATA =",env['INSTALL_ASCDATA']
972 jpye 1413 print "INSTALL_PREFIX =",env['INSTALL_PREFIX']
973 jpye 1504 print "INSTALL_MODELS =",env['INSTALL_MODELS']
974     print "INSTALL_SOLVERS =",env['INSTALL_SOLVERS']
975 jpye 2016 print "INSTALL_PYTHON =",env['INSTALL_PYTHON']
976 jpye 1504 print "DEFAULT_ASCENDLIBRARY =",env['DEFAULT_ASCENDLIBRARY']
977 jpye 1519 print "DEFAULT_ASCENDSOLVERS =",env['DEFAULT_ASCENDSOLVERS']
978 jpye 1504
979    
980 johnpye 385 #------------------------------------------------------
981 johnpye 398 # SPECIAL CONFIGURATION TESTS
982    
983 johnpye 463 need_fortran = False
984 jpye 1641 need_fortran_reasons = []
985 johnpye 463
986 johnpye 400 #----------------
987 jpye 1448 # CC
988    
989     cc_test_text = """
990     int main(void){
991     return 0;
992     }
993     """;
994    
995     def CheckCC(context):
996     context.Message("Checking C compiler ('%s')... " % context.env.get('CC'))
997     is_ok = context.TryCompile(cc_test_text,".c")
998     context.Result(is_ok)
999     return is_ok
1000    
1001     #----------------
1002     # CXX
1003    
1004     cxx_test_text = """
1005     template<class X>
1006     class pair{
1007     public:
1008     X a;
1009     X b;
1010     };
1011    
1012     int main(void){
1013     pair<double> P;
1014     P.a = 0;
1015     return 0;
1016     }
1017     """;
1018    
1019     def CheckCXX(context):
1020     context.Message("Checking C++ compiler ('%s')... " % context.env.get('CXX'))
1021 jpye 1630 if not context.env.get('CXX'):
1022     context.Result("not found")
1023     return False
1024     is_ok = context.TryCompile(cxx_test_text,".cpp")
1025 jpye 1448 context.Result(is_ok)
1026     return is_ok
1027    
1028 jpye 1641 #----------------
1029    
1030     f77_test_text = """
1031     C Hello World in Fortran 77
1032    
1033     PROGRAM HELLO
1034     PRINT*, 'Hello World!'
1035     END
1036     """;
1037    
1038     def CheckF77(context):
1039     context.Message("Checking Fortran 77 compiler ('%s')..." % context.env.get('FORTRAN'))
1040     if not context.env.get('FORTRAN'):
1041     context.Result('not found')
1042     return False
1043     is_ok = context.TryCompile(f77_test_text,".f")
1044     context.Result(is_ok)
1045     return is_ok
1046 jpye 1448
1047     #----------------
1048 johnpye 400 # SWIG
1049    
1050 johnpye 398 import os,re
1051    
1052 johnpye 413 def get_swig_version(env):
1053 johnpye 403 cmd = env['SWIG']+' -version'
1054 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
1055 johnpye 403 output = coutcerr.read()
1056 johnpye 398
1057 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
1058     expr = re.compile(restr,re.M);
1059 johnpye 398 m = expr.search(output);
1060     if not m:
1061 johnpye 413 return None
1062 johnpye 398 maj = int(m.group('maj'))
1063     min = int(m.group('min'))
1064     pat = int(m.group('pat'))
1065 johnpye 413
1066     return (maj,min,pat)
1067 johnpye 398
1068 johnpye 413
1069     def CheckSwigVersion(context):
1070    
1071     try:
1072     context.Message("Checking version of SWIG... ")
1073     maj,min,pat = get_swig_version(context.env)
1074     except:
1075     context.Result("Failed to detect version, or failed to run SWIG")
1076     return 0;
1077    
1078 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
1079    
1080 johnpye 398 if maj == 1 and (
1081 johnpye 400 min > 3
1082     or (min == 3 and pat >= 24)
1083 johnpye 398 ):
1084     context.Result("ok, %d.%d.%d" % (maj,min,pat))
1085     return 1;
1086 johnpye 401 else:
1087     context.Result("too old, %d.%d.%d" % (maj,min,pat))
1088     return 0;
1089 johnpye 398
1090 johnpye 400 #----------------
1091 johnpye 816 # Scrollkeeper (Linux documentation system)
1092    
1093     def get_scrollkeeper_omfdir(env):
1094     cmd = 'scrollkeeper-config --omfdir'
1095     (cin,coutcerr) = os.popen4(cmd)
1096     output = coutcerr.read()
1097     return output.strip()
1098    
1099     def CheckScrollkeeperConfig(context):
1100     try:
1101     context.Message("Checking for scrollkeeper...")
1102     dir=get_scrollkeeper_omfdir(context.env)
1103     except:
1104     context.Result("Failed to run 'scrollkeeper-config'")
1105     return 0
1106     context.env['OMFDIR']=dir
1107     context.Result("OK, %s" % dir)
1108     return 1
1109    
1110     #----------------
1111 johnpye 400 # General purpose library-and-header test
1112    
1113 johnpye 404 class KeepContext:
1114 johnpye 521 def __init__(self,context,varprefix,static=False):
1115 johnpye 404 self.keep = {}
1116 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
1117 johnpye 705 #print "Keeping env %s = %s" % (k,context.env.get(k))
1118     self.keep[k]=context.env.get(k)
1119 johnpye 404
1120     if context.env.has_key(varprefix+'_CPPPATH'):
1121 johnpye 743 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
1122 johnpye 800 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
1123 johnpye 428
1124 johnpye 521 if static:
1125     staticlib=env[varprefix+'_LIB']
1126     #print "STATIC LIB = ",staticlib
1127     context.env.Append(
1128     LINKFLAGS=[staticlib]
1129     )
1130     else:
1131     if context.env.has_key(varprefix+'_LIBPATH'):
1132     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
1133 johnpye 800 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
1134 johnpye 428
1135 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
1136     context.env.Append(LIBS=[env[varprefix+'_LIB']])
1137 johnpye 705 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
1138 jpye 1547 elif context.env.has_key(varprefix+'_LIBS'):
1139     context.env.AppendUnique(LIBS=env[varprefix+'_LIBS'])
1140 johnpye 404
1141     def restore(self,context):
1142 johnpye 464 #print "RESTORING CONTEXT"
1143     #print self.keep
1144     #print "..."
1145 johnpye 404 for k in self.keep:
1146 johnpye 463 if self.keep[k]==None:
1147 johnpye 521 if context.env.has_key(k):
1148     #print "Clearing "+str(k)
1149     del context.env[k];
1150 johnpye 463 else:
1151 johnpye 705 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
1152 johnpye 463 context.env[k]=self.keep[k];
1153 johnpye 404
1154 jpye 1721 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False,testname=None):
1155 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
1156     and LIBNAME_CPPPATH and try to compile and link the
1157     file with the provided text, linking with the
1158     library libname."""
1159    
1160 jpye 1721 if testname is None:
1161     testname = libname
1162    
1163 johnpye 521 if static:
1164 jpye 1721 context.Message( 'Checking for static '+testname+'... ' )
1165 johnpye 521 else:
1166 jpye 1721 context.Message( 'Checking for '+testname+'... ' )
1167 johnpye 521
1168 johnpye 400 if varprefix==None:
1169     varprefix = libname.upper()
1170    
1171 johnpye 705 #print "LIBS is currently:",context.env.get('LIBS')
1172 johnpye 521 keep = KeepContext(context,varprefix,static)
1173 johnpye 400
1174 jpye 1678 if not context.env.has_key(varprefix+'_LIB') and not context.env.has_key(varprefix+'_LIBS'):
1175 johnpye 463 # if varprefix_LIB were in env, KeepContext would
1176     # have appended it already
1177 johnpye 705 context.env.Append(LIBS=[libname])
1178 johnpye 428
1179 johnpye 404 is_ok = context.TryLink(text,ext)
1180 johnpye 428
1181 johnpye 521 #print "Link success? ",(is_ok != 0)
1182 johnpye 400
1183 johnpye 405 keep.restore(context)
1184 johnpye 400
1185 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
1186 johnpye 705 # print "Restored LIBS="+str(context.env['LIBS'])
1187 johnpye 428 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
1188    
1189 johnpye 404 context.Result(is_ok)
1190     return is_ok
1191    
1192     #----------------
1193 johnpye 502 # GCC
1194    
1195     gcc_test_text = """
1196     #ifndef __GNUC__
1197     # error "Not using GCC"
1198     #endif
1199    
1200     int main(void){
1201     return __GNUC__;
1202     }
1203     """
1204    
1205     def CheckGcc(context):
1206     context.Message("Checking for GCC... ")
1207     is_ok = context.TryCompile(gcc_test_text,".c")
1208     context.Result(is_ok)
1209     return is_ok
1210    
1211     #----------------
1212 johnpye 500 # GCC VISIBILITY feature
1213    
1214     gccvisibility_test_text = """
1215     #if __GNUC__ < 4
1216     # error "Require GCC version 4 or newer"
1217     #endif
1218    
1219     __attribute__ ((visibility("default"))) int x;
1220    
1221     int main(void){
1222     extern int x;
1223     x = 4;
1224     }
1225     """
1226    
1227     def CheckGccVisibility(context):
1228     context.Message("Checking for GCC 'visibility' capability... ")
1229 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
1230     context.Result("disabled")
1231     return 0
1232 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
1233     context.Result(is_ok)
1234     return is_ok
1235 johnpye 502
1236 johnpye 500 #----------------
1237 johnpye 502 # YACC
1238    
1239     yacc_test_text = """
1240 johnpye 646 %{
1241     #include <stdio.h>
1242 johnpye 741
1243     /* MSVC++ needs this before it can swallow Bison output */
1244     #ifdef _MSC_VER
1245     # define __STDC__
1246     #endif
1247 johnpye 646 %}
1248     %token MSG
1249 johnpye 502 %start ROOT
1250 johnpye 646 %%
1251     ROOT:
1252     MSG { printf("HELLO"); }
1253     ;
1254     %%
1255 johnpye 502 """
1256    
1257     def CheckYacc(context):
1258 johnpye 644 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
1259 johnpye 502 is_ok = context.TryCompile(yacc_test_text,".y")
1260     context.Result(is_ok)
1261     return is_ok
1262    
1263     #----------------
1264 johnpye 1025 # LEX
1265    
1266     lex_test_text = """
1267     %{
1268     #include <stdio.h>
1269     %}
1270     DIGIT [0-9]
1271     ID [a-z][a-z0-9]*
1272     %%
1273     {DIGIT}+ {
1274     printf("A digit: %s\\n",yytext);
1275     }
1276    
1277     [ \\t\\n]+ /* ignore */
1278    
1279     . {
1280     printf("Unrecognized guff");
1281     }
1282     %%
1283     main(){
1284     yylex();
1285     }
1286     """
1287    
1288     def CheckLex(context):
1289     context.Message("Checking for Lex ('%s')... " % context.env.get('LEX'))
1290     is_ok = context.TryCompile(lex_test_text,".l")
1291     context.Result(is_ok)
1292     return is_ok
1293    
1294     #----------------
1295 johnpye 404 # CUnit test
1296    
1297 johnpye 400 cunit_test_text = """
1298 johnpye 451 #include <CUnit/CUnit.h>
1299 johnpye 400 int maxi(int i1, int i2){
1300     return (i1 > i2) ? i1 : i2;
1301     }
1302    
1303     void test_maxi(void){
1304     CU_ASSERT(maxi(0,2) == 2);
1305     CU_ASSERT(maxi(0,-2) == 0);
1306     CU_ASSERT(maxi(2,2) == 2);
1307    
1308     }
1309     int main(void){
1310     /* CU_initialize_registry() */
1311 johnpye 404 return 0;
1312 johnpye 400 }
1313     """
1314    
1315     def CheckCUnit(context):
1316 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
1317 johnpye 400
1318 johnpye 404 #----------------
1319 johnpye 938 # dmalloc test
1320    
1321     dmalloc_test_text = """
1322     #include <stdlib.h>
1323     #include <dmalloc.h>
1324    
1325     int main(void){
1326     char *c;
1327 jpye 1733 c = (char *)malloc(100*sizeof(char));
1328 johnpye 938 free(c);
1329     return 0;
1330     }
1331     """
1332    
1333     def CheckDMalloc(context):
1334     return CheckExtLib(context,'dmalloc',dmalloc_test_text)
1335    
1336     #----------------
1337 jpye 1678 # graphviz test
1338 johnpye 1109
1339 jpye 1678 graphviz_test_text = """
1340 jpye 1714 #ifdef __WIN32__
1341     # include <gvc.h>
1342     #else
1343     # include <graphviz/gvc.h>
1344     #endif
1345 johnpye 1109 int main(void){
1346 jpye 1678 Agraph_t *g;
1347     GVC_t *gvc;
1348     gvc = gvContext();
1349     g = agopen("g", AGDIGRAPH);
1350 johnpye 1109 return 0;
1351     }
1352     """
1353    
1354 jpye 1678 def CheckGraphViz(context):
1355     return CheckExtLib(context,'graphviz',graphviz_test_text,ext=".c")
1356 johnpye 1109
1357 jpye 1721 graphviz_boolean_test = """
1358     #ifdef __WIN32__
1359 jpye 1722 # include <types.h>
1360 jpye 1721 #else
1361 jpye 1722 # include <graphviz/types.h>
1362 jpye 1721 #endif
1363 jpye 1722 #ifndef GV_TYPES_H
1364     # error WHERE IS GV_TYPES_H?
1365     #endif
1366     int main(void){
1367 jpye 1721 boolean x;
1368     x = TRUE;
1369     return 0;
1370     }
1371     """
1372    
1373     def CheckGraphVizBoolean(context):
1374     return CheckExtLib(context,'graphviz',graphviz_boolean_test,ext=".c" \
1375     ,testname="graphviz 'boolean' definition"
1376     )
1377    
1378 johnpye 1109 #----------------
1379 jpye 1326 # ufsparse test
1380    
1381     ufsparse_test_text = """
1382     #include <ufsparse/cs.h>
1383     int main(void){
1384     cs *A,*B,*C;
1385     C = cs_multiply(A,B);
1386     return 0;
1387     }
1388     """
1389    
1390     def CheckUFSparse(context):
1391     return CheckExtLib(context
1392     ,libname='cxsparse'
1393     ,varprefix='ufsparse'
1394     ,text=ufsparse_test_text
1395     ,ext=".c"
1396     )
1397    
1398     #----------------
1399 johnpye 673 # MATH test
1400    
1401     math_test_text = """
1402 johnpye 705 #ifndef _ALL_SOURCE
1403     # define _ALL_SOURCE
1404     #endif
1405     #ifndef _XOPEN_SOURCE
1406     # define _XOPEN_SOURCE
1407     #endif
1408     #ifndef _XOPEN_SOURCE_EXTENDED
1409     # define _XOPEN_SOURCE_EXTENDED 1
1410     #endif
1411 johnpye 673 #include <math.h>
1412     int main(void){
1413 johnpye 705 double x = 1.0; double y = 1.0; int i = 1;
1414     acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
1415     j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
1416     y0(x); y1(x); yn(i,x);
1417 jpye 1420 /* this part causes problems with crossmingw... */
1418 johnpye 705 #ifdef _THREAD_SAFE
1419     gamma_r(x,&i);
1420     lgamma_r(x,&i);
1421     #else
1422     gamma(x);
1423     lgamma(x);
1424     #endif
1425     hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
1426 johnpye 673 return 0;
1427     }
1428     """
1429    
1430     def CheckMath(context):
1431 johnpye 832 context.Message('Checking for IEEE math library... ')
1432 johnpye 705 libsave=context.env.get('LIBS');
1433     context.env.AppendUnique(LIBS=['m'])
1434     is_ok=context.TryLink(math_test_text,".c")
1435     context.Result(is_ok)
1436 jpye 1941 if libsave is None:
1437     del(context.env['LIBS'])
1438     else:
1439 johnpye 705 context.env['LIBS']=libsave
1440     return is_ok
1441    
1442 johnpye 673 #----------------
1443 jpye 1656 # malloc.h test
1444    
1445     malloc_test_text = """
1446 jpye 1660 #include <stdlib.h>
1447 jpye 1656 int main(){
1448     double *x;
1449     x = malloc(sizeof(double)*5);
1450     x[4] = 3.3;
1451     free(x);
1452     }
1453     """
1454    
1455     def CheckMalloc(context):
1456     context.Message("Checking for malloc...")
1457     is_ok = context.TryLink(malloc_test_text,".c")
1458     context.Result(is_ok)
1459     return is_ok
1460    
1461     #----------------
1462     # dlopen test
1463    
1464     dlopen_test_text = """
1465     #ifdef __WIN32__
1466     # include <windows.h>
1467     #else
1468     # include <dlfcn.h>
1469     #endif
1470     int main(){
1471     #ifdef __WIN32__
1472     HINSTANCE d;
1473     LoadLibrary("imaginary_and_nonexistent.dll");
1474     #else
1475     void *d;
1476     d = dlopen("imaginary_and_nonexistent.so", 1);
1477     #endif
1478     return 0;
1479     }
1480     """
1481    
1482     def CheckDLOpen(context):
1483     context.Message("Checking for ability to load shared libraries at runtime...")
1484     libsave=context.env.get('LIBS');
1485     if platform.system()!="Windows":
1486     context.env.Append(LIBS=['dl'])
1487     is_ok = context.TryLink(dlopen_test_text,".c")
1488     context.Result(is_ok)
1489     context.env['LIBS'] = libsave
1490     return is_ok
1491    
1492     #----------------
1493 johnpye 957 # libpython test
1494    
1495     libpython_test_text = """
1496     #include <Python.h>
1497     int main(void){
1498     PyObject *p;
1499     p = Py_None;
1500     return 0;
1501     }
1502     """
1503    
1504     def CheckPythonLib(context):
1505     context.Message('Checking for libpython... ')
1506    
1507     if platform.system()=="Windows":
1508     python_lib='python%d%d'
1509     else:
1510     python_lib='python%d.%d'
1511    
1512 jpye 1786 try:
1513     python_libs = [python_lib % (sys.version_info[0],sys.version_info[1])]
1514     python_cpppath = [distutils.sysconfig.get_python_inc()]
1515     cfig = distutils.sysconfig.get_config_vars()
1516     except:
1517     context.Result("not found")
1518     return 0
1519 johnpye 957
1520     lastLIBS = context.env.get('LIBS')
1521     lastLIBPATH = context.env.get('LIBPATH')
1522     lastCPPPATH = context.env.get('CPPPATH')
1523 johnpye 959 lastLINKFLAGS = context.env.get('LINKFLAGS')
1524 johnpye 957
1525     python_libpath = []
1526 johnpye 959 python_linkflags = []
1527 johnpye 965 if platform.system()=="Windows":
1528 jpye 1551 python_libpath += [os.path.join(sys.prefix,"libs")]
1529 johnpye 965 else:
1530     # checked on Linux and SunOS
1531     if cfig['LDLIBRARY']==cfig['LIBRARY']:
1532     sys.stdout.write("(static)")
1533     python_libpath += [cfig['LIBPL']]
1534     python_linkflags += cfig['LIBS'].split(' ')
1535 johnpye 957
1536 johnpye 958 context.env.AppendUnique(LIBS=python_libs)
1537 johnpye 957 context.env.AppendUnique(LIBPATH=python_libpath)
1538     context.env.AppendUnique(CPPPATH=python_cpppath)
1539 johnpye 959 context.env.AppendUnique(LINKFLAGS=python_linkflags)
1540 johnpye 957 result = context.TryLink(libpython_test_text,".c");
1541    
1542 johnpye 958 context.Result(result)
1543 johnpye 957
1544     if(result):
1545 johnpye 958 context.env['PYTHON_LIBPATH']=python_libpath
1546     context.env['PYTHON_LIB']=python_libs
1547     context.env['PYTHON_CPPPATH']=python_cpppath
1548 johnpye 959 context.env['PYTHON_LINKFLAGS']=python_linkflags
1549 johnpye 957
1550     context.env['LIBS'] = lastLIBS
1551     context.env['LIBPATH'] = lastLIBPATH
1552     context.env['CPPPATH'] = lastCPPPATH
1553 johnpye 959 context.env['LINKFLAGS'] = lastLINKFLAGS
1554 johnpye 957
1555     return result
1556    
1557     #----------------
1558 johnpye 673 # IDA test
1559    
1560 johnpye 913 sundials_version_major_required = 2
1561     sundials_version_minor_min = 2
1562     sundials_version_minor_max = 3
1563    
1564     sundials_version_text = """
1565     #include <sundials/sundials_config.h>
1566     #include <stdio.h>
1567     int main(){
1568     printf("%s",SUNDIALS_PACKAGE_VERSION);
1569     return 0;
1570     }
1571     """
1572    
1573 johnpye 673 ida_test_text = """
1574 jpye 1400 #if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR==2
1575     # include <sundials/sundials_config.h>
1576     # include <sundials/sundials_nvector.h>
1577 jpye 1405 # include <nvector_serial.h>
1578 jpye 1400 # include <ida.h>
1579     # include <ida/ida_spgmr.h>
1580     #else
1581     # include <sundials/sundials_config.h>
1582     # include <nvector/nvector_serial.h>
1583 johnpye 907 # include <ida/ida.h>
1584 jpye 1400 #endif
1585 johnpye 673 int main(){
1586     void *ida_mem;
1587     ida_mem = IDACreate();
1588 johnpye 782 return 0;
1589 johnpye 673 }
1590     """
1591    
1592 johnpye 913 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
1593     # so detect the version and act accordingly.
1594 jpye 1400 def CheckSUNDIALS(context):
1595     keep = KeepContext(context,'SUNDIALS')
1596 jpye 1402 context.Message("Checking for SUNDIALS... ")
1597 johnpye 913 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
1598     keep.restore(context)
1599     if not is_ok:
1600 jpye 1402 context.Result(0)
1601 johnpye 913 return 0
1602    
1603     major,minor,patch = tuple([int(i) for i in output.split(".")])
1604     context.env['SUNDIALS_VERSION_MAJOR'] = major
1605     context.env['SUNDIALS_VERSION_MINOR'] = minor
1606     if major != sundials_version_major_required \
1607     or minor < sundials_version_minor_min \
1608     or minor > sundials_version_minor_max:
1609     context.Result(output+" (bad version)")
1610     # bad version
1611     return 0
1612    
1613     # good version
1614 johnpye 1086 context.Result("%d.%d.%d, good" % (major,minor,patch))
1615 jpye 1400
1616 johnpye 913 return 1
1617    
1618 jpye 1400
1619     def CheckIDA(context):
1620 jpye 1402 context.Message( 'Checking for IDA... ' )
1621 jpye 1400
1622 jpye 1404 keep = KeepContext(context,"SUNDIALS")
1623 jpye 1400
1624     major = context.env['SUNDIALS_VERSION_MAJOR']
1625     minor = context.env['SUNDIALS_VERSION_MINOR']
1626    
1627 jpye 1404 cppdef = context.env.get('CPPDEFINES')
1628    
1629     context.env.Append(CPPDEFINES=[
1630     ('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR")
1631     ,('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")
1632     ])
1633    
1634     context.env['SUNDIALS_CPPPATH_EXTRA']=[]
1635     if major==2 and minor==2:
1636     context.env.Append(SUNDIALS_CPPPATH_EXTRA = ["$SUNDIALS_CPPPATH/sundials"])
1637    
1638 jpye 1400 context.env.Append(CPPDEFINES=[('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR"),('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")])
1639 jpye 1404 context.env.AppendUnique(LIBS=context.env['SUNDIALS_LIBS'])
1640     context.env.AppendUnique(CPPPATH=context.env['SUNDIALS_CPPPATH_EXTRA'])
1641 jpye 1400
1642     is_ok = context.TryLink(ida_test_text,".c")
1643     context.Result(is_ok)
1644    
1645 jpye 1404 if cppdef:
1646     context.env['CPPDEFINES']=cppdef
1647 jpye 1552 else:
1648     del context.env['CPPDEFINES']
1649    
1650 jpye 1400 keep.restore(context)
1651    
1652     return is_ok
1653    
1654    
1655 johnpye 673 #----------------
1656 johnpye 783 # CONOPT test
1657    
1658     conopt_test_text = """
1659 johnpye 800 #if !defined(_WIN32)
1660     # define FNAME_LCASE_DECOR
1661     #endif
1662    
1663 johnpye 783 #include <conopt.h>
1664     #include <stdlib.h>
1665     int main(){
1666     int s, *v, e;
1667     s = COIDEF_Size();
1668     v = (int *)malloc(s*sizeof(int));
1669     e = COIDEF_Ini(v);
1670     return e;
1671     }
1672     """
1673    
1674     def CheckCONOPT(context):
1675     context.Message( 'Checking for CONOPT... ' )
1676    
1677     keep = KeepContext(context,"CONOPT")
1678    
1679     is_ok = context.TryLink(conopt_test_text,".c")
1680     context.Result(is_ok)
1681    
1682     keep.restore(context)
1683    
1684     return is_ok
1685    
1686     #----------------
1687 jpye 1529 # IPOPT test
1688    
1689     ipopt_test_text = """
1690     #if !defined(_WIN32)
1691     # define FNAME_LCASE_DECOR
1692     #endif
1693    
1694 jpye 1770 #include <coin/IpStdCInterface.h>
1695 jpye 1529 int main(){
1696     Number n;
1697 jpye 1546 IpoptProblem nlp = 0;
1698 jpye 1941 n = 1;
1699 jpye 1529 FreeIpoptProblem(nlp); // probably a crash if you run this
1700     return 0;
1701     }
1702     """
1703    
1704     def CheckIPOPT(context):
1705     context.Message( 'Checking for IPOPT... ' )
1706    
1707     keep = KeepContext(context,"IPOPT")
1708     is_ok = context.TryLink(ipopt_test_text,".c")
1709     context.Result(is_ok)
1710    
1711     keep.restore(context)
1712    
1713     return is_ok
1714    
1715     #----------------
1716 johnpye 405 # Tcl test
1717 johnpye 404
1718 jpye 1787 # TCL and TK required version 8.1 through 8.5:
1719     tcltk_minor_newest_acceptable = 5
1720 johnpye 561 tcltk_major_required = 8
1721    
1722 johnpye 404 tcl_check_text = r"""
1723     #include <tcl.h>
1724     #include <stdio.h>
1725     int main(void){
1726     printf("%s",TCL_PATCH_LEVEL);
1727     return 0;
1728     }
1729     """
1730    
1731     def CheckTcl(context):
1732 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
1733 johnpye 405
1734     def CheckTclVersion(context):
1735 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
1736 johnpye 405 context.Message("Checking Tcl version... ")
1737     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
1738 johnpye 404 keep.restore(context)
1739     if not is_ok:
1740 johnpye 405 context.Result("failed to run check")
1741 johnpye 404 return 0
1742 johnpye 405
1743 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
1744 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1745 johnpye 428 context.Result(output+" (bad version)")
1746 johnpye 405 # bad version
1747     return 0
1748    
1749     # good version
1750 johnpye 552 context.Result(output+", good")
1751 johnpye 404 return 1
1752    
1753 johnpye 405 #----------------
1754 johnpye 463 # Tk test
1755 johnpye 405
1756     tk_check_text = r"""
1757     #include <tk.h>
1758     #include <stdio.h>
1759     int main(void){
1760     printf("%s",TK_PATCH_LEVEL);
1761     return 0;
1762     }
1763     """
1764     def CheckTk(context):
1765 johnpye 673 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1766 johnpye 405
1767 johnpye 428
1768 johnpye 405 def CheckTkVersion(context):
1769 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1770 johnpye 405 context.Message("Checking Tk version... ")
1771 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
1772 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1773 johnpye 404 keep.restore(context)
1774     if not is_ok:
1775     context.Result("failed to run check")
1776     return 0
1777    
1778 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
1779 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1780 johnpye 404 # bad version
1781 johnpye 561 context.Result(output+" (bad version)")
1782 johnpye 404 return 0
1783 johnpye 400
1784 johnpye 404 # good version
1785 johnpye 561 context.Result(output+" (good)")
1786 johnpye 404 return 1
1787 johnpye 485
1788     #----------------
1789 johnpye 521 # Tktable test
1790    
1791     tktable_check_text = r"""
1792     #include <tkTable.h>
1793     #include <stdio.h>
1794     int main(void){
1795     Table mytable;
1796     return 0;
1797     }
1798     """
1799    
1800     def CheckTkTable(context):
1801     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1802    
1803     #---------------
1804     # X11 test
1805    
1806     x11_check_text = r"""
1807     #include <X11/Xlib.h>
1808     #include <X11/IntrinsicP.h>
1809     #include <X11/Intrinsic.h>
1810     #include <X11/ObjectP.h>
1811     #include <X11/Object.h>
1812     int main(void){
1813     Object mything;
1814     return 0;
1815     }
1816     """
1817    
1818     def CheckX11(context):
1819     return CheckExtLib(context,'X11',x11_check_text)
1820    
1821     #----------------
1822 johnpye 968 # Check that we can raise and catch sigint
1823    
1824     sigint_test_text = r"""
1825     #include <signal.h>
1826     #include <setjmp.h>
1827     #include <stdlib.h>
1828     static jmp_buf g_jmpenv;
1829     void sighandler(int sig){
1830     longjmp(g_jmpenv,sig);
1831     }
1832     void testsigint(){
1833     raise(SIGINT);
1834     }
1835     int main(void){
1836     signal(SIGINT,&sighandler);
1837     switch(setjmp(g_jmpenv)){
1838     case 0:
1839     testsigint();
1840     exit(1);
1841     case SIGINT:
1842     exit(0);
1843     default:
1844     exit(2);
1845     }
1846     }
1847     """
1848    
1849     def CheckSIGINT(context):
1850     context.Message("Checking SIGINT is catchable... ")
1851     (is_ok,output)=context.TryRun(sigint_test_text,".c")
1852     context.Result(is_ok)
1853     return is_ok
1854    
1855     #----------------
1856 johnpye 953 # Check that we're able to catch floating point errors
1857    
1858     sigfpe_test_text = r"""
1859     #include <signal.h>
1860     #include <setjmp.h>
1861     #include <stdlib.h>
1862     #include <fenv.h>
1863     static jmp_buf g_jmpenv;
1864     void fpehandler(int sig){
1865     longjmp(g_jmpenv,sig);
1866     }
1867     int main(void){
1868     fenv_t myfenv;
1869     fegetenv(&myfenv);
1870     fesetenv(&myfenv);
1871     feenableexcept(FE_ALL_EXCEPT);
1872     signal(SIGFPE,&fpehandler);
1873     double x;
1874     switch(setjmp(g_jmpenv)){
1875     case 0:
1876     x = 1.0 / 0.0;
1877     /* failed to catch */
1878     exit(1);
1879     case SIGFPE:
1880     exit(0);
1881     }
1882     }
1883     """
1884    
1885     def CheckFPE(context):
1886 johnpye 968 context.Message("Checking C99 FPE behaviour... ")
1887 johnpye 953 (is_ok,output) = context.TryRun(sigfpe_test_text,'.c')
1888     context.Result(is_ok)
1889     return is_ok
1890    
1891     #----------------
1892 johnpye 968 # signal reset needed?
1893    
1894     sigreset_test_text = r"""
1895     #include <signal.h>
1896     #include <setjmp.h>
1897     #include <stdlib.h>
1898     #include <stdio.h>
1899     typedef void SigHandlerFn(int);
1900     static jmp_buf g_jmpenv;
1901     void sighandler(int sig){
1902     longjmp(g_jmpenv,sig);
1903     }
1904     void testsigint(){
1905 johnpye 1002 /* fprintf(stderr,"Raising SIGINT\n"); */
1906 johnpye 968 raise(SIGINT);
1907     }
1908     int main(void){
1909     SigHandlerFn *last,*saved;
1910     saved = signal(SIGINT,&sighandler);
1911     if(saved!=SIG_DFL){
1912 johnpye 1002 fprintf(stderr,"Default handler (%p) was not correctly set\n",SIG_DFL);
1913 johnpye 968 exit(3);
1914     }
1915     switch(setjmp(g_jmpenv)){
1916     case 0:
1917     testsigint();
1918     fprintf(stderr,"Back from SIGINT\n");
1919     exit(1);
1920     case SIGINT:
1921     break;
1922     default:
1923     exit(2);
1924     };
1925 johnpye 1002 last = signal(SIGINT,SIG_DFL);
1926 johnpye 968 if(last!=&sighandler){
1927     printf("1");
1928     exit(0);
1929     }
1930     printf("0");
1931     exit(0);
1932     }
1933     """
1934    
1935     def CheckSigReset(context):
1936     context.Message("Checking signal handler reset... ")
1937 jpye 1941 libsave=context.env.get('LIBS')
1938     context.env.AppendUnique(LIBS=['m'])
1939 johnpye 968 (is_ok,output) = context.TryRun(sigreset_test_text,'.c')
1940 jpye 1941
1941     if libsave is None:
1942     del(context.env['LIBS'])
1943     else:
1944     context.env['LIBS']=libsave
1945    
1946 johnpye 968 if not is_ok:
1947     context.Result("ERROR")
1948 johnpye 1260 return False
1949 johnpye 1002 if int(output)==1:
1950 johnpye 968 context.Result("required");
1951     context.env['ASC_RESETNEEDED'] = True
1952     else:
1953     context.Result("not required");
1954     context.env['ASC_RESETNEEDED'] = False
1955 jpye 1658 return True
1956 johnpye 968
1957     #----------------
1958 jpye 1442 # LyX on this system?
1959    
1960     def CheckLyx(context):
1961     context.Message("Checking for LyX... ")
1962     r = context.env.WhereIs("lyx")
1963 jpye 1469 if r:
1964     context.Result(r)
1965     else:
1966     context.Result(0)
1967 jpye 1442 return r
1968    
1969     #----------------
1970     # Latex2HTML on this system?
1971    
1972     def CheckLatex2HTML(context):
1973     context.Message("Checking for latex2html...")
1974     if context.env.WhereIs("latex2html"):
1975     r = True
1976     else:
1977     r = False
1978     context.Result(r)
1979     return r
1980    
1981     #----------------
1982 jpye 1701 # 'lmodern' package for LaTeX available?
1983    
1984 jpye 1723 lmodern_test_text = r"""
1985 jpye 1701 \documentclass{article}
1986 jpye 1723 \usepackage{lmodern}
1987 jpye 1701 \title{Cartesian closed categories and the price of eggs}
1988     \author{Jane Doe}
1989     \date{September 1994}
1990     \begin{document}
1991     \maketitle
1992     Hello world!
1993     \end{document}
1994     """;
1995    
1996     def CheckLModern(context):
1997     context.Message("Checking for lmodern...")
1998 jpye 1770 b = context.env.get("DVI")
1999     if not b:
2000     context.Result(False)
2001     return False
2002 jpye 2000 ff = context.env.get('LATEXFLAGS')
2003     context.env.Append(LATEXFLAGS=['-interaction=nonstopmode','-halt-on-error'])
2004     is_ok = context.TryBuild(builder=b,text=lmodern_test_text,extension=".latex")
2005     print "is_ok=",is_ok
2006     if ff is not None:
2007     context.env['LATEXFLAGS'] = ff
2008     else:
2009     del context.env['LATEXFLAGS']
2010 jpye 1701 context.Result(is_ok)
2011     return is_ok
2012    
2013     #----------------
2014 johnpye 485 # GCC Version sniffing
2015    
2016     # TODO FIXME
2017    
2018     gcc_version4 = False
2019    
2020 johnpye 398 #------------------------------------------------------
2021 johnpye 385 # CONFIGURATION
2022    
2023     conf = Configure(env
2024     , custom_tests = {
2025 jpye 1448 'CheckCC' : CheckCC
2026     , 'CheckCXX' : CheckCXX
2027 jpye 1641 , 'CheckF77' : CheckF77
2028 jpye 1448 , 'CheckMath' : CheckMath
2029 jpye 1656 , 'CheckMalloc' : CheckMalloc
2030     , 'CheckDLOpen' : CheckDLOpen
2031 johnpye 673 , 'CheckSwigVersion' : CheckSwigVersion
2032 johnpye 957 , 'CheckPythonLib' : CheckPythonLib
2033 johnpye 400 , 'CheckCUnit' : CheckCUnit
2034 johnpye 938 , 'CheckDMalloc' : CheckDMalloc
2035 jpye 1442 , 'CheckLyx' : CheckLyx
2036     , 'CheckLatex2HTML' : CheckLatex2HTML
2037 jpye 1701 , 'CheckLModern' : CheckLModern
2038 jpye 1678 , 'CheckGraphViz' : CheckGraphViz
2039 jpye 1721 , 'CheckGraphVizBoolean' : CheckGraphVizBoolean
2040 jpye 1326 , 'CheckUFSparse' : CheckUFSparse
2041 johnpye 404 , 'CheckTcl' : CheckTcl
2042     , 'CheckTclVersion' : CheckTclVersion
2043 johnpye 405 , 'CheckTk' : CheckTk
2044     , 'CheckTkVersion' : CheckTkVersion
2045 johnpye 502 , 'CheckGcc' : CheckGcc
2046 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
2047 johnpye 502 , 'CheckYacc' : CheckYacc
2048 johnpye 1025 , 'CheckLex' : CheckLex
2049 johnpye 521 , 'CheckTkTable' : CheckTkTable
2050     , 'CheckX11' : CheckX11
2051 johnpye 673 , 'CheckIDA' : CheckIDA
2052 jpye 1400 , 'CheckSUNDIALS' : CheckSUNDIALS
2053 johnpye 783 , 'CheckCONOPT' : CheckCONOPT
2054 jpye 1529 , 'CheckIPOPT' : CheckIPOPT
2055 johnpye 816 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
2056 johnpye 953 , 'CheckFPE' : CheckFPE
2057 johnpye 968 , 'CheckSIGINT' : CheckSIGINT
2058     , 'CheckSigReset' : CheckSigReset
2059 johnpye 400 # , 'CheckIsNan' : CheckIsNan
2060     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
2061 jpye 1691 }
2062 johnpye 459 # , config_h = "config.h"
2063 johnpye 385 )
2064    
2065 jpye 1357 def sconsversioncheck():
2066    
2067     # uncomment the following line to skip the version check:
2068     # return 1
2069    
2070     import SCons
2071     v = SCons.__version__.split(".")
2072     if v[0] != '0':
2073 jpye 1999 if v[0] == '1':
2074     return 1;
2075 jpye 1357 return 0
2076 jpye 1431 if int(v[1]) >= 97:
2077     return 1
2078 jpye 1357 if v[1] != '96':
2079     return 0
2080     micro = int(v[2])
2081 jpye 1394 if micro == 92 or micro == 93 or micro == 96:
2082 jpye 1357 return 1;
2083     return 0
2084    
2085     if not sconsversioncheck():
2086     print "Scons version is not OK. Please try version 0.96.92 or 0.96.93,"
2087     print "or consult the developers in the case of newer versions. Modify"
2088     print "the function 'sconsversioncheck' in the file SConstruct if you"
2089     print "want to *force* SCons to continue."
2090     Exit(1)
2091    
2092 jpye 1448 # check C compiler
2093    
2094 jpye 1654 if conf.CheckCC() is False:
2095 jpye 1448 print "Failed to build simple test file with your C compiler."
2096     print "Check your compiler is installed and running correctly."
2097     Exit(1)
2098    
2099 jpye 1654 if conf.CheckCXX() is False:
2100 jpye 1448 print "Failed to build simple test file with your C++ compiler."
2101     print "Check your compiler is installed and running correctly."
2102 jpye 1630 print "You can set your C++ compiler using the CXX scons option."
2103 jpye 1448 Exit(1)
2104    
2105 johnpye 740 # stdio -- just to check that compiler is behaving
2106 johnpye 398
2107 jpye 1654 if conf.CheckHeader('stdio.h') is False:
2108 johnpye 832 print "CPPPATH =",env.get('CPPPATH')
2109 johnpye 740 print "Did not find 'stdio.h'! Check your compiler configuration."
2110 johnpye 1080 print ""
2111     print "You environment is printed here:"
2112     for k,v in os.environ.iteritems():
2113     print "%-30s%s" % ("%s :" % k, v)
2114 johnpye 740 Exit(1)
2115    
2116 jpye 1654 if conf.CheckFunc('snprintf') is False:
2117 johnpye 1228 print "Didn't find snprintf";
2118     exit(1)
2119    
2120 jpye 1678 if conf.CheckFunc('strdup'):
2121     conf.env['HAVE_STRDUP'] = True
2122    
2123 jpye 1720 if platform.system()=="Windows" and env.get('WITH_MSVCR71'):
2124     conf.env.Append(LIBS='msvcr71')
2125    
2126 johnpye 385 # Math library
2127    
2128 johnpye 1262 conf.env['HAVE_IEEE']=True
2129    
2130 jpye 1654 if need_libm and (conf.CheckMath() is False):
2131 johnpye 1232 conf.env['HAVE_IEEE']=False
2132 johnpye 1262 print 'Did not find math library, exiting!'
2133     Exit(1)
2134 johnpye 427
2135 jpye 1656 # Malloc
2136    
2137     if conf.CheckMalloc() is False:
2138     conf.env['HAVE_MALLOC']=False
2139     print "Did not find functioning 'malloc', exiting!"
2140     Exit(1)
2141    
2142     # dlopen/LoadLibrary
2143    
2144 jpye 1659 # CURRENTLY BREAKS LATER TEST (libsave?)
2145     #if conf.CheckDLOpen() is False:
2146     # print "Did not find functioning dlopen/LoadLibrary, exiting!"
2147     # Exit(1)
2148 jpye 1656
2149 johnpye 385 # Where is 'isnan'?
2150    
2151 jpye 1654 if conf.CheckFunc('isnan') is False and conf.CheckFunc('_isnan') is False:
2152 johnpye 385 print "Didn't find isnan"
2153 johnpye 414 # Exit(1)
2154 johnpye 385
2155 johnpye 500 # GCC visibility
2156    
2157 johnpye 502 if conf.CheckGcc():
2158     conf.env['HAVE_GCC']=True;
2159 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
2160 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
2161     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
2162     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
2163 johnpye 709 conf.env.Append(CCFLAGS=['-Wall'])
2164 johnpye 500
2165 johnpye 968 # Catching SIGINT
2166    
2167 johnpye 1142 if env['WITH_SIGNALS']:
2168 jpye 1655 if not conf.CheckSIGINT():
2169 johnpye 1142 with_signals = False
2170     without_signals_reason = "SIGINT uncatchable"
2171 johnpye 968
2172 johnpye 953 # Catching SIGFPE
2173    
2174     if conf.CheckFPE():
2175 johnpye 968 conf.env['HAVE_C99FPE']=True
2176 johnpye 953 else:
2177 johnpye 968 conf.env['HAVE_C99FPE']=False
2178 johnpye 953
2179 johnpye 968 # Checking for signal reset requirement
2180    
2181 jpye 1654 if conf.CheckSigReset() is False:
2182 johnpye 968 print "Unable to determine if signal reset is required"
2183 johnpye 1260 Exit(1)
2184 johnpye 968
2185 johnpye 502 # YACC
2186    
2187 jpye 1552 if conf.CheckYacc():
2188 johnpye 502 conf.env['HAVE_YACC']=True
2189    
2190 jpye 1552 if conf.CheckLex():
2191 johnpye 1025 conf.env['HAVE_LEX']=True
2192 johnpye 502
2193 johnpye 387 # Tcl/Tk
2194 johnpye 386
2195 johnpye 586 if with_tcltk:
2196     if conf.CheckTcl():
2197     if conf.CheckTclVersion():
2198     if conf.CheckTk():
2199     if with_tcltk and conf.CheckTkVersion():
2200     if env['STATIC_TCLTK']:
2201     if conf.CheckTkTable():
2202     pass
2203     else:
2204     without_tcltk_reason = "TkTable not found"
2205     with_tcltk = False
2206     else:
2207     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
2208     with_tcltk = False
2209 johnpye 521 else:
2210 johnpye 586 without_tcltk_reason = "Tk not found."
2211 johnpye 551 with_tcltk = False
2212 johnpye 428 else:
2213 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
2214 johnpye 551 with_tcltk = False
2215 johnpye 586
2216 johnpye 428 else:
2217 johnpye 586 without_tcltk_reason = "Tcl not found."
2218 johnpye 551 with_tcltk = False
2219 johnpye 386
2220 johnpye 521 if env['STATIC_TCLTK']:
2221     conf.CheckX11()
2222    
2223 johnpye 395 # Python... obviously we're already running python, so we just need to
2224     # check that we can link to the python library OK:
2225    
2226 jpye 1655 if not conf.CheckPythonLib():
2227 johnpye 957 without_python_reason = 'libpython2.x not found or not linkable'
2228     with_python = False
2229 johnpye 982 env['WITH_PYTHON']=False
2230 johnpye 391
2231 johnpye 395 # SWIG version
2232    
2233 jpye 1656 if with_python and conf.CheckSwigVersion() is False:
2234 johnpye 413 without_python_reason = 'SWIG >= 1.3.24 is required'
2235     with_python = False
2236 johnpye 982 env['WITH_PYTHON']=False
2237 johnpye 413
2238 johnpye 400 # CUnit
2239    
2240 johnpye 593 if with_cunit:
2241 jpye 1655 if not conf.CheckCUnit():
2242 johnpye 427 without_cunit_reason = 'CUnit not found'
2243 johnpye 665 with_cunit = False
2244 johnpye 705 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
2245 johnpye 427
2246 johnpye 938 # DMALLOC
2247    
2248     if with_dmalloc:
2249 jpye 1655 if not conf.CheckDMalloc():
2250 johnpye 938 without_dmalloc_reason = 'dmalloc not found'
2251     with_dmalloc = False
2252    
2253 jpye 1678 # GRAPHVIZ
2254 johnpye 1109
2255 jpye 1678 if with_graphviz:
2256     if not conf.CheckGraphViz():
2257     without_graphviz_reason = 'graphviz not found'
2258     with_graphviz = False
2259     env['WITH_GRAPHVIZ'] = False
2260 jpye 1721 env['HAVE_GRAPHVIZ_BOOLEAN'] = conf.CheckGraphVizBoolean()
2261 johnpye 1109
2262 jpye 1326 # UFSPARSE
2263    
2264     if with_ufsparse:
2265 jpye 1655 if not conf.CheckUFSparse():
2266 jpye 1678 without_ufsparse_reason = 'ufsparse not found'
2267 jpye 1326 with_ufsparse = False
2268     env['WITH_UFSPARSE'] = False
2269    
2270 johnpye 673 # IDA
2271    
2272 jpye 1734 if with_ida:
2273     if not conf.CheckSUNDIALS():
2274     with_ida = False
2275     without_ida_reason = "SUNDIALS not found, or bad version"
2276     elif not conf.CheckIDA():
2277     with_ida = False
2278     without_ida_reason = "Unable to compile/link against SUNDIALS/IDA"
2279 johnpye 673
2280 johnpye 797 # CONOPT
2281 johnpye 783
2282     if not with_conopt:
2283     without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
2284 jpye 1654 elif conf.CheckCONOPT() is False:
2285 jpye 1541 if conf.env.get('CONOPT_LINKED'):
2286     conf.env['CONOPT_LINKED'] = False
2287     # we no longer require CONOPT at buildtime in order to build support for it
2288     #with_conopt = False
2289     #without_conpt_reason = "CONOPT not found"
2290 johnpye 783
2291 jpye 1529 # IPOPT
2292    
2293     if not with_ipopt:
2294     without_ipopt_reason = "Not selected (see config option WITH_SOLVERS)"
2295 jpye 1657 elif not conf.CheckIPOPT():
2296 jpye 1529 with_ipopt = False
2297     without_ipopt_reason = "IPOPT not found"
2298    
2299 johnpye 427 # BLAS
2300    
2301 johnpye 459 need_blas=False
2302 johnpye 673
2303     if with_lsode:
2304     need_fortran = True
2305 jpye 1641 need_fortran_reasons.append("LSODE")
2306 johnpye 459 need_blas=True
2307 johnpye 673
2308 jpye 2000 if with_ipopt:
2309     need_blas=True
2310    
2311 johnpye 459 if need_blas:
2312     if conf.CheckLib('blas'):
2313     with_local_blas = False
2314     without_local_blas_reason = "Found BLAS installed on system"
2315     else:
2316     with_local_blas = True
2317     need_fortran = True
2318 jpye 1641 need_fortran_reasons.append("BLAS")
2319 johnpye 673 else:
2320     with_local_blas= False;
2321     without_local_blas_reason = "BLAS not required"
2322 johnpye 427
2323     # FORTRAN
2324    
2325     if need_fortran:
2326 jpye 1999 print "NEED FORTRAN"
2327 jpye 2000 import SCons
2328     if SCons.__version__[0:4]=="0.97":
2329     # Older SCons verions 0.97 (eg Ubuntu 8.04) doesn't have the 'gfortran' tool'.
2330     # On this system, the 'fortran' tool seems to detect gfortran OK.
2331     conf.env.Tool('fortran')
2332     else:
2333     conf.env.Tool('g77')
2334     conf.env.Tool('gfortran')
2335 jpye 1380 detect_fortran = conf.env.Detect(['gfortran','g77'])
2336 johnpye 427 if detect_fortran:
2337     # For some reason, g77 doesn't get detected properly on MinGW
2338 johnpye 673 if not env.has_key('F77') and not env.has_key('FORTRAN'):
2339 jpye 1357 print "Fixing detection of F77 on MinGW...(?)"
2340 johnpye 427 conf.env.Replace(F77=detect_fortran)
2341     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
2342     conf.env.Replace(F77FLAGS='')
2343 johnpye 428 #print "F77:",conf.env['F77']
2344     #print "F77COM:",conf.env['F77COM']
2345     #print "F77FLAGS:",conf.env['F77FLAGS']
2346 johnpye 427 fortran_builder = Builder(
2347     action='$F77COM'
2348     , suffix='.o'
2349     , src_suffix='.f'
2350     )
2351     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
2352 johnpye 1284 if platform.system()=="Linux":
2353 jpye 2000 print "APPARENTLY FORTRAN WAS DETECTED"
2354 johnpye 1284 conf.env.Append(SHFORTRANFLAGS=['-fPIC'])
2355 johnpye 427 else:
2356 jpye 2000 print "FAILED FORTRAN DETECTION"
2357 johnpye 673 with_lsode=False;
2358     without_lsode_reason="FORTRAN-77 required but not found"
2359 jpye 2000 else:
2360     print "FORTRAN WAS NOT FOUND TO BE REQUIRED"
2361 johnpye 629
2362 jpye 1654 if need_fortran and conf.CheckF77() is False:
2363 jpye 1641 print "Failed to build simple test file with your Fortran compiler."
2364     print "Check your compiler is installed and running correctly."
2365     print "You can set your Fortran compiler using the FORTRAN scons option."
2366     print "The fortran compiler is REQUIRED to build:",", ".join(need_fortran_reasons)
2367     print "Perhaps try examining the value of your WITH_SOLVERS option (remove LSODE, etc)."
2368     Exit(1)
2369    
2370 johnpye 464 #else:
2371     # print "FORTRAN not required"
2372 johnpye 400
2373 johnpye 673 # F2C
2374    
2375     if need_fortran:
2376     if platform.system()=="Windows":
2377 jpye 1380 pass
2378     #conf.env.Append(LIBPATH='c:\mingw\lib')
2379 johnpye 673
2380 johnpye 816 # scrollkeeper
2381 johnpye 673
2382 johnpye 816 if with_scrollkeeper:
2383 jpye 1654 if conf.CheckScrollkeeperConfig() is False:
2384 johnpye 816 with_scrollkeeper=False
2385     without_scrollkeeper_reason="unable to detect scrollkeeper-config"
2386    
2387 jpye 1442 # lyx
2388    
2389 jpye 1470 if with_doc_build:
2390 jpye 1769 if not conf.CheckLyx():
2391 jpye 1470 with_doc_build = False
2392 jpye 1769 without_doc_build_reason="unable to locate LyX"
2393 jpye 1442
2394 jpye 1769 with_latex2html = conf.CheckLatex2HTML()
2395 jpye 1442
2396 jpye 1723 if conf.CheckLModern() is False:
2397     with_doc_build = False
2398     without_doc_build_reason="'lmodern' is not available"
2399 jpye 1701
2400 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
2401    
2402     # TODO: check size of void*
2403    
2404 johnpye 393 # TODO: detect if dynamic libraries are possible or not
2405    
2406 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
2407 johnpye 740 _found_windows_h = conf.CheckHeader('Windows.h')
2408    
2409     if not _found_windows_h:
2410 johnpye 741 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
2411 johnpye 740 Exit(1)
2412 johnpye 741
2413 jpye 1654 if with_python and conf.CheckHeader(['basetsd.h','BaseTsd.h']) is False:
2414 johnpye 427 with_python = 0;
2415     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
2416    
2417 johnpye 395 conf.Finish()
2418    
2419 jpye 2016 #print "-=-=-=-=-=-=-=-=- LIBS =",env.get('LIBS')
2420 jpye 1941
2421 johnpye 507 #---------------------------------------
2422     # SUBSTITUTION DICTIONARY for .in files
2423    
2424 johnpye 658 release = env.get('RELEASE')
2425     if release=="0.":
2426     release="0"
2427    
2428 johnpye 800 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
2429    
2430 johnpye 507 subst_dict = {
2431     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
2432 jpye 1519 ,'@DEFAULT_ASCENDSOLVERS@':env['DEFAULT_ASCENDSOLVERS']
2433 johnpye 507 , '@GLADE_FILE@':'ascend.glade'
2434     , '@HELP_ROOT@':''
2435     , '@ICON_EXTENSION@':icon_extension
2436 johnpye 628 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
2437 johnpye 507 , '@INSTALL_BIN@':env['INSTALL_BIN']
2438     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
2439 johnpye 683 , '@INSTALL_LIB@':env['INSTALL_LIB']
2440 johnpye 721 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
2441 jpye 1504 , '@INSTALL_SOLVERS@':env['INSTALL_SOLVERS']
2442 jpye 2016 , '@INSTALL_PYTHON@':env['INSTALL_PYTHON']
2443 johnpye 507 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
2444     , '@VERSION@':version
2445 johnpye 658 , '@RELEASE@':release
2446 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
2447 jpye 1590 , '@WEBHELPROOT@':'http://ascendwiki.cheme.cmu.edu/Category:Documentation'
2448 johnpye 1228 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
2449     , '@SHLIBPREFIX@':env['SHLIBPREFIX']
2450 jpye 1597 , '@EXTLIB_SUFFIX@':env['EXTLIB_SUFFIX']
2451     , '@EXTLIB_PREFIX@':env['EXTLIB_PREFIX']
2452 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
2453 johnpye 627 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
2454 johnpye 683 , '@PYTHON@' : python_exe
2455 jpye 1466 , '@PYVERSION@' : pyversion
2456 johnpye 1174 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
2457 jpye 1680 , '@WITH_GRAPHVIZ@': str(int(env.get('WITH_GRAPHVIZ')))
2458 johnpye 507 }
2459    
2460 jpye 1442 if env.get('WITH_DOC'):
2461     print "WITH_DOC:",env['WITH_DOC']
2462     subst_dict['@HELP_ROOT@']=env['HELP_ROOT']
2463 johnpye 507
2464 johnpye 597 # bool options...
2465 johnpye 673 for k,v in {
2466 jpye 1747 'ASC_WITH_DMALLOC':with_dmalloc
2467 jpye 1326 ,'ASC_WITH_UFSPARSE':with_ufsparse
2468 johnpye 1142 ,'ASC_WITH_MMIO':with_mmio
2469     ,'ASC_SIGNAL_TRAPS':with_signals
2470     ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
2471     ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
2472 johnpye 1261 ,'HAVE_IEEE':env.get('HAVE_IEEE')
2473 jpye 1412 ,'ASC_ABSOLUTE_PATHS':env.get('ABSOLUTE_PATHS')
2474 johnpye 1142 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
2475     ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
2476     }.iteritems():
2477    
2478     if v: subst_dict["/\\* #define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
2479 johnpye 594
2480 johnpye 507 if with_python:
2481     subst_dict['@ASCXX_USE_PYTHON@']="1"
2482 johnpye 673 env['WITH_PYTHON']=1;
2483 johnpye 507
2484 jpye 1442 if with_latex2html:
2485     env['WITH_LATEX2HTML']=1
2486    
2487 johnpye 507 if env.has_key('HAVE_GCCVISIBILITY'):
2488     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
2489    
2490     env.Append(SUBST_DICT=subst_dict)
2491    
2492 johnpye 1142 #for k,v in subst_dict.iteritems():
2493     # print "%-50s%s" % ("'%s'"%k,v)
2494 johnpye 829
2495 johnpye 1142 # REMOVED: long command-line support on Win2k
2496 johnpye 829
2497     #------------------------------------------------------
2498 johnpye 558 # RECIPE: SWIG scanner
2499    
2500     import SCons.Script
2501    
2502     SWIGScanner = SCons.Scanner.ClassicCPP(
2503     "SWIGScan"
2504     , ".i"
2505     , "CPPPATH"
2506     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
2507     )
2508    
2509     env.Append(SCANNERS=[SWIGScanner])
2510    
2511     #------------------------------------------------------
2512 johnpye 463 # Recipe for 'CHMOD' ACTION
2513 johnpye 439
2514     import SCons
2515     from SCons.Script.SConscript import SConsEnvironment
2516     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
2517     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
2518    
2519     def InstallPerm(env, dest, files, perm):
2520     obj = env.Install(dest, files)
2521     for i in obj:
2522     env.AddPostAction(i, env.Chmod(str(i), perm))
2523 jpye 2007
2524     def InstallPermAs(env, dest, filen, perm):
2525     obj = env.InstallAs(dest, filen)
2526     for i in obj:
2527     env.AddPostAction(i, env.Chmod(str(i), perm))
2528     return dest
2529 johnpye 439
2530     SConsEnvironment.InstallPerm = InstallPerm
2531    
2532     # define wrappers
2533     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
2534 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2535 johnpye 629 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2536 jpye 2007 SConsEnvironment.InstallLibraryAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2537 johnpye 463
2538 johnpye 439 #------------------------------------------------------
2539 johnpye 463 # BUILD...
2540 johnpye 385
2541 jpye 2018 # so that #include <ascend/modulename/headername.h> works across all modules...
2542     env.AppendUnique(CPPPATH=['#'])
2543 johnpye 385
2544 johnpye 508 if env['DEBUG']:
2545     env.Append(CCFLAGS=['-g'])
2546 jpye 1554 env.Append(LINKFLAGS=['-g'])
2547 johnpye 508
2548 johnpye 591 if env['GCOV']:
2549     env.Append(
2550     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
2551     , LIBS=['gcov']
2552     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
2553     )
2554    
2555 johnpye 673 if with_ida:
2556     env.Append(WITH_IDA=1)
2557    
2558 johnpye 783 if with_conopt:
2559     env.Append(WITH_CONOPT=1)
2560    
2561 jpye 1529 if with_ipopt:
2562     env.Append(WITH_IPOPT=1)
2563    
2564 jpye 1734 if with_dopri5:
2565     env.Append(WITH_DOPRI5=1)
2566    
2567 jpye 1719 if with_graphviz and env.get('GRAPHVIZ_RPATH'):
2568 jpye 1718 env.Append(RPATH=env['GRAPHVIZ_RPATH'])
2569    
2570 johnpye 463 #-------------
2571     # TCL/TK GUI
2572 johnpye 385
2573 johnpye 551 if with_tcltk:
2574 jpye 2024 env.SConscript(['tcltk/SConscript'],'env')
2575 johnpye 391 else:
2576 johnpye 982 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
2577 johnpye 386
2578 johnpye 463 #-------------
2579     # PYTHON INTERFACE
2580    
2581 johnpye 387 if with_python:
2582 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
2583 johnpye 391 else:
2584 johnpye 982 print "Skipping... Python bindings aren't being built:",without_python_reason
2585 johnpye 400
2586 johnpye 463 #------------
2587     # BASE/GENERIC SUBDIRECTORIES
2588    
2589 jpye 1786 libascend_env = env.Clone()
2590 johnpye 673
2591 johnpye 1316 dirs = ['general','utilities','compiler','system','solver','integrator','packages','linear']
2592 johnpye 463
2593     srcs = []
2594     for d in dirs:
2595 jpye 2017 heresrcs = libascend_env.SConscript('ascend/'+d+'/SConscript','libascend_env')
2596 johnpye 463 srcs += heresrcs
2597    
2598     #-------------
2599 johnpye 673 # IMPORTED CODE: LSODE, BLAS, etc
2600    
2601 jpye 1509 #if with_lsode:
2602     # srcs += env.SConscript(['lsod/SConscript'],'env')
2603     # srcs += env.SConscript(['linpack/SConscript'],'env')
2604     #else:
2605     # print "Skipping... LSODE won't be built:", without_lsode_reason
2606 johnpye 673
2607     if with_local_blas:
2608 jpye 1515 env['blasobjs'] = env.SConscript(['blas/SConscript'],'env')
2609 johnpye 673 else:
2610 jpye 1515 env['blasobjs'] = []
2611 johnpye 673 print "Skipping... BLAS won't be built:", without_local_blas_reason
2612    
2613     if not with_ida:
2614     print "Skipping... IDA won't be built:", without_ida_reason
2615    
2616 jpye 1734 if not with_dopri5:
2617     print "Skipping... DOPRI5 won't be built:", without_dopri5_reason
2618    
2619 johnpye 993 if with_mmio:
2620     srcs += env.SConscript(['mmio/SConscript'],'env')
2621     else:
2622     print "Skipping... MMIO export won't be built:", without_mmio_reason
2623 johnpye 673 #-------------
2624 jpye 2018 # LIBASCEND -- all 'core' functionality
2625 johnpye 463
2626 jpye 2018 # FIXME want to move these bits to ascend/SConscript
2627    
2628     libascend_env.Append(
2629     CPPPATH=['#']
2630     ,LIBS=['m']
2631     )
2632    
2633 jpye 2008 if platform.system()=="Linux":
2634     libascend_env.Append(LIBS=['dl'])
2635    
2636 johnpye 938 if with_dmalloc:
2637     libascend_env.Append(LIBS=['dmalloc'])
2638    
2639 jpye 1326 if with_ufsparse:
2640     libascend_env.Append(LIBS=['cxsparse'])
2641    
2642 jpye 2007 if platform.system()=="Linux":
2643     libascend_env.Append(LINKFLAGS=['-Wl,-soname,%s' % soname_full])
2644    
2645 johnpye 673 libascend = libascend_env.SharedLibrary('ascend',srcs)
2646 johnpye 463
2647 jpye 2007 # create local symlink for the soname stuff.
2648     print "SONAME =",env.subst(soname_full)
2649    
2650 jpye 1510 env['libascend'] = libascend
2651 jpye 2007 libtargets = [libascend]
2652 jpye 1510
2653 jpye 2007 if platform.system()=="Linux":
2654     if soname_major:
2655     libascend_env.Command(soname_full,libascend,Move("$TARGET","$SOURCE"))
2656     print "MAKING LINK, SONAME_MAJOR =",soname_major
2657     liblink = libascend_env.Command(soname_full, libascend, "ln -s $SOURCE $TARGET")
2658     libtargets.append(liblink)
2659 johnpye 673
2660 jpye 2007 # for use in declaring dependent shared libraries in SConscript files (eg solvers/*/SConscript)
2661    
2662     env.Alias('libascend',libtargets)
2663    
2664 johnpye 463 #-------------
2665 johnpye 761 # UNIT TESTS (C CODE)
2666 johnpye 463
2667 jpye 2017 test_env = env.Clone()
2668     test_env.Append(
2669     CPPPATH="#"
2670     )
2671    
2672 johnpye 593 if with_cunit:
2673 jpye 1638 testdirs = ['general','solver','utilities','linear','compiler']
2674 johnpye 593 testsrcs = []
2675 johnpye 400 for testdir in testdirs:
2676 jpye 2017 path = 'ascend/'+testdir+'/test/'
2677     test_env.SConscript([path+'SConscript'],'test_env')
2678     testsrcs += [i.path for i in test_env['TESTSRCS_'+testdir.upper()]]
2679 johnpye 593
2680     #print "TESTSRCS =",testsrcs
2681    
2682 jpye 2017 test_env.SConscript(['test/SConscript'],'test_env')
2683 johnpye 593
2684 jpye 2017 env.Alias('test',[env.Dir('test')])
2685 johnpye 400
2686     else:
2687 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
2688 johnpye 400
2689 johnpye 761 #-------------
2690 jpye 1504 # EXTERNAL SOLVERS
2691    
2692     env['extfns']=[]
2693    
2694 jpye 1505 env.SConscript(['solvers/SConscript'],'env')
2695 jpye 1504
2696     #-------------
2697 johnpye 761 # EXTERNAL FUNCTIONS
2698    
2699 johnpye 811 modeldirs = env.SConscript(['models/SConscript'],'env')
2700