/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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