/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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