/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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