/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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