/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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