/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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