/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2523 - (hide annotations) (download)
Wed Jan 18 23:41:37 2012 UTC (7 years, 10 months ago) by jpye
File size: 76815 byte(s)
Working on building on MinGW-64. Test suite compiles, but some questionable cahnges to assertimpl.c were made (bug 524).
Removed support for solver 'tron' (never completed).

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