/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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