/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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