/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2610 - (hide annotations) (download)
Thu Apr 26 18:08:07 2012 UTC (7 years, 7 months ago) by jpye
File size: 76221 byte(s)
support for IPOPT dependency DLLs in installer.
1 jpye 2017 #!/usr/bin/python invoke_using_scons
2 jpye 2007 # This is a build script for use with SCons. Use it to compile ASCEND on
3     # Linux, Windows. It should also give some success on Mac, although this is
4     # much less tested.
5    
6     # version number for this ASCEND build:
7 mahesh 2150 version = "0.9.8"
8 johnpye 439
9 jpye 2007 # shared library API numbering, for Linux (FIXME windows too?)
10     soname_major = ".1"
11     soname_minor = ".0"
12    
13     import sys, os, commands, platform, distutils.sysconfig, os.path, re, types
14 jpye 2129 import subprocess
15 jpye 2007
16     # version number for python, useful on Windows
17 jpye 1466 pyversion = "%d.%d" % (sys.version_info[0],sys.version_info[1])
18    
19 jpye 2567 # architecture label
20     winarchtag = "-win32"
21     if platform.architecture()[0] == "64bit":
22     winarchtag="-amd64"
23    
24 johnpye 385 #------------------------------------------------------
25 jpye 2007 # PLATFORM DEFAULTS
26 johnpye 385
27 johnpye 464 #print "PLATFORM = ",platform.system()
28 johnpye 385
29 jpye 2073 default_install_prefix = '/usr/local'
30     default_install_bin = "$INSTALL_PREFIX/bin"
31     default_install_lib = "$INSTALL_PREFIX/lib"
32     default_install_models = "$INSTALL_LIB/ascend/models"
33     default_install_solvers = "$INSTALL_LIB/ascend/solvers"
34     default_install_assets = "$INSTALL_ASCDATA/glade/"
35     default_install_ascdata = "$INSTALL_SHARE/ascend"
36     default_install_include = "$INSTALL_PREFIX/include"
37 jpye 2307 default_install_python = distutils.sysconfig.get_python_lib()
38     default_install_python_ascend = "$INSTALL_PYTHON/ascend"
39 jpye 2073 default_tcl = '/usr'
40     default_tcl_libpath = "$TCL/lib"
41 jpye 1488 default_tcl_cpppath = "$TCL/include"
42 jpye 1501 default_conopt_envvar="CONOPT_PATH"
43 jpye 1854 default_with_graphviz = True
44 jpye 2073 default_tcl_lib = "tcl8.5"
45     default_tk_lib = "tk8.5"
46     default_tktable_lib = "Tktable2.9"
47     default_ida_prefix="$DEFAULT_PREFIX"
48 jpye 2132 default_ipopt_libpath = "$IPOPT_PREFIX/lib"
49 jpye 2610 default_ipopt_dll = ["$IPOPT_LIBPATH/Ipopt-vs8.dll","$IPOPT_LIBPATH/IpOptFSS.dll", None, None, None] # should be five here
50 jpye 2132 default_ipopt_libs = ["$F2C_LIB","blas","lapack","pthread","ipopt"]
51 jpye 2073 default_conopt_prefix="$DEFAULT_PREFIX"
52     default_conopt_libpath="$CONOPT_PREFIX"
53     default_conopt_cpppath="$CONOPT_PREFIX"
54     default_conopt_dlpath="$CONOPT_PREFIX"
55     default_prefix="/usr"
56     default_libpath="$DEFAULT_PREFIX/lib"
57     default_cpppath="$DEFAULT_PREFIX/include"
58     default_f2c_lib="gfortran"
59 jpye 2094 default_swig="swig"
60 jpye 1488
61 jpye 2073 icon_extension = '.png'
62    
63 johnpye 464 if platform.system()=="Windows":
64 jpye 2523 if os.path.exists("c:\\MinGW"):
65     default_prefix="c:\\MinGW"
66     elif os.path.exists("c:\MinGW64"):
67     default_prefix="c:\\MinGW64"
68    
69 jpye 2073 default_libpath="$DEFAULT_PREFIX\\lib"
70     default_cpppath="$DEFAULT_PREFIX\\include"
71    
72 jpye 2007 # these correspond the the version of Tcl/Tk linked to in the NSIS scripts
73 jpye 2204 default_tcl_lib = "tcl85"
74     default_tk_lib = "tk85"
75 johnpye 464 default_tktable_lib = "Tktable28"
76 jpye 2007
77 johnpye 499 default_install_assets = "glade/"
78 johnpye 521 default_tcl = "c:\\Tcl"
79 jpye 1645 if os.environ.get('MSYSTEM'):
80 johnpye 642 default_tcl_libpath="$TCL\\bin"
81     else:
82     default_tcl_libpath="$TCL\\lib"
83 jpye 2007
84     # on Windows, we build ASCEND such that it finds it support files
85     # using paths relative to the location of the executable
86 johnpye 628 default_absolute_paths = False
87 jpye 2025 default_dist_rel_bin = '.'
88     default_tk_rel_dist = 'tcltk'
89     default_library_rel_dist = 'models'
90     default_solvers_rel_dist = 'solvers'
91 johnpye 739
92 jpye 2007 # where to look for IDA solver libraries, headers, etc.
93 jpye 2523 default_ida_prefix = "$DEFAULT_PREFIX"
94 jpye 2132
95     # IPOPT
96 jpye 2567 if platform.architecture()[0] == "64bit":
97     default_ipopt_libpath = "$IPOPT_PREFIX/lib/x64/release"
98     else:
99     default_ipopt_libpath = "$IPOPT_PREFIX/lib/win32/release"
100 jpye 2203 default_ipopt_libs = ["Ipopt"]
101 johnpye 783
102 jpye 2007 # where to look for CONOPT when compiling
103 johnpye 800 default_conopt_prefix = "c:\\Program Files\\CONOPT"
104     default_conopt_lib="conopt3"
105 johnpye 739
106 johnpye 673 need_libm = False
107 jpye 1592 python_exe = sys.executable
108 johnpye 816 default_with_scrollkeeper=False
109 jpye 1504 pathsep = ";"
110 jpye 1566
111 jpye 2094 default_f2c_lib="gfortran"
112 jpye 1597
113 jpye 2094 default_swig=WhereIs("swig.exe")
114    
115 jpye 2007 soname_minor = ""
116     soname_major = ""
117 jpye 1854 # still problems with Graphviz on Windows, leave it off now by default.
118 jpye 2073
119 jpye 2158 if not os.path.exists(default_conopt_prefix):
120     default_conopt_prefix = None
121    
122 jpye 2073 elif platform.system()=="Darwin":
123    
124 jpye 2075 default_install_prefix = ''
125 jpye 2090 default_install_bin = "$INSTALL_PREFIX/ASCEND.app/Contents"
126 jpye 2076 default_install_lib = "$INSTALL_BIN"
127 jpye 2083 default_install_models = "$INSTALL_BIN/Models"
128     default_install_solvers = "$INSTALL_BIN/Solvers"
129 jpye 2090 default_install_ascdata = "$INSTALL_BIN/Resources"
130 jpye 2076 default_install_include = "$INSTALL_BIN/Headers"
131 jpye 2075 default_install_python = "$INSTALL_BIN/Python"
132 jpye 2307 default_install_python_ascend = default_install_python
133 jpye 2073 default_install_assets = "$INSTALL_ASCDATA/glade/"
134 jpye 2083 # FIXME still need to work out the Tcl/Tk side of things...
135 jpye 2073
136     # within the bundle, we'll use relative paths
137     default_absolute_paths = False
138     default_dist_rel_bin = '.'
139     default_tk_rel_dist = 'tcltk'
140    
141 jpye 2524 # we should move these to /Library/ASCEND/Models and /Library/ASCEND/Solvers, for visibility
142 jpye 2083 default_library_rel_dist = 'Models'
143     default_solvers_rel_dist = 'Solvers'
144 jpye 2073
145     # where to look for CONOPT when compiling
146     default_conopt_prefix = "/Library/CONOPT"
147    
148     default_conopt_lib="conopt3"
149    
150     need_libm = False
151     python_exe = sys.executable
152     default_with_scrollkeeper=False
153     pathsep = ";"
154 jpye 1720
155 jpye 2158 if not os.path.exists(default_conopt_prefix):
156     default_conopt_prefix = None
157 jpye 2073
158 ballan 2438 else: # LINUX, unix we hope
159 jpye 2073
160 ballan 2438 # the scons 'philosophy' if there is one is that the scons input arguments
161     # completely determine what external tools get picked any time there might
162     # be choices.
163     # We don't follow that philosophy with regard to tcl/tk.
164     # tcl/tk are often in multiple versions and locations on any given system.
165     # This leaves us trying to guess whether we should take:
166     # - only explicit arguments, otherwise disable tcl, tk
167     # - the first tcl/tk in the users path
168     # - the tcl/tk under a given user-specified prefix
169     # - the folklore-based canonical location of distributor's tcl/tk on a given linux dist
170     # We know one thing for sure. Any tcl installation includes tclsh, and thus
171     # it's the canonical way to find anything about tcl once tclsh is picked.
172     # So all the above reduces to 'how do we find tclsh?'
173 johnpye 499 icon_extension = '.svg'
174 jpye 1488
175 ballan 2438 # here's the folklore we know.
176 jpye 1488 if os.path.exists("/etc/debian_version"):
177     default_tcl_cpppath = "/usr/include/tcl8.4"
178 jpye 1787 default_tcl_lib = "tcl8.4"
179     default_tk_lib = "tk8.4"
180     default_tktable_lib = "Tktable2.8"
181 jpye 1488
182 ballan 2036 if os.path.exists("/etc/SuSE-release"):
183     default_tcl_cpppath = "/usr/include"
184     default_tcl_lib = "tcl8.4"
185     default_tk_lib = "tk8.4"
186     default_tktable_lib = "Tktable2.9"
187    
188 jpye 2006 if os.path.exists("/etc/lsb-release"):
189     _f = file("/etc/lsb-release")
190     _r = re.compile("([A-Z][^=]*)=(.*)")
191     LSB = {}
192     for l in _f:
193     _m = _r.match(l.strip())
194     LSB[_m.group(1)] = _m.group(2)
195 ballan 2036 print LSB
196     if LSB.has_key('DISTRIB_ID') and LSB['DISTRIB_ID'] == "Ubuntu":
197 jpye 2006 if float(LSB['DISTRIB_RELEASE']) >= 9.04:
198     default_tcl_lib = "tcl8.5"
199     default_tk_lib = "tk8.5"
200     default_tktable_lib = "Tktable2.9"
201     default_tcl_cpppath = "/usr/include/tcl8.5"
202 jpye 2445 if not os.path.exists(default_tcl_cpppath):
203     default_tcl_lib = "tcl8.4"
204     default_tk_lib = "tk8.4"
205     default_tktable_lib = "Tktable2.9"
206     default_tcl_cpppath = "/usr/include/tcl8.4"
207    
208 ballan 2438 # centos 5
209     if os.path.exists("/etc/redhat-release"):
210     default_tcl_cpppath = "/usr/include"
211     default_tcl_lib = "tcl"
212     if sys.maxint > 2**32:
213     default_tcl_libpath = "/usr/lib64"
214     else:
215     default_tcl_libpath = "/usr/lib"
216     default_tk_lib = "tk"
217     default_tktable_lib = "Tktable2.9"
218 jpye 2006
219    
220 johnpye 628 default_absolute_paths = True
221 jpye 2025 default_dist_rel_bin = '..'
222     default_tk_rel_dist = 'share/ascend/tcltk'
223     default_library_rel_dist = 'lib/ascend/models'
224     default_solvers_rel_dist = 'lib/ascend/solvers'
225    
226 johnpye 800 default_conopt_libpath="$CONOPT_PREFIX/lib"
227     default_conopt_cpppath="$CONOPT_PREFIX/include"
228 jpye 1399 default_conopt_dlpath= default_conopt_libpath + ":/usr/local/lib"
229 johnpye 800 default_conopt_lib="consub3"
230    
231 johnpye 673 need_libm = True
232 johnpye 551 if not os.path.isdir(default_tcl):
233     default_tcl = '/usr'
234 johnpye 683 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
235 johnpye 816 default_with_scrollkeeper=False
236 jpye 1504 pathsep = ":"
237 jpye 2007
238 jpye 2073 if not os.path.exists(default_ida_prefix):
239     default_ida_prefix = None
240    
241 jpye 2007 soname_clean = "${SHLIBPREFIX}ascend${SHLIBSUFFIX}"
242     soname_full = "%s%s" % (soname_clean,soname_major)
243    
244     #------------------------------------------------------
245     # OPTIONS
246     #
247     # The following give the set of command-line parameters that can be passed to
248     # SCons from the commandline. Options will be 'remembered' by being cached
249     # in the file 'options.cache'; if you want to start with a clean slate, you
250     # should remove that file.
251    
252 jpye 2162 vars = Variables(['options.cache', 'config.py'])
253 jpye 1597
254 jpye 2524 vars.Add('HOST_PREFIX'
255 jpye 2523 ,"Host architecture prefix"
256     ,""
257     )
258    
259 jpye 2524 vars.Add('CC'
260 johnpye 562 ,'C Compiler command'
261 jpye 2523 ,"${HOST_PREFIX}gcc"
262 johnpye 562 )
263    
264 jpye 2524 vars.Add('CXX'
265 johnpye 562 ,'C++ Compiler command'
266 jpye 2523 ,"${HOST_PREFIX}g++"
267 johnpye 562 )
268    
269 jpye 2524 vars.Add(BoolVariable('GCOV'
270 johnpye 593 , 'Whether to enable coverage testing in object code'
271     , False
272 johnpye 591 ))
273    
274 jpye 2007 if platform.system()!="Windows":
275 jpye 2524 vars.Add(BoolVariable('WITH_GCCVISIBILITY'
276 jpye 2007 ,"Whether to use GCC Visibility features (only applicable if available)"
277     ,True
278     ))
279 johnpye 526
280 jpye 2524 vars.Add(BoolVariable('WITH_SIGNALS'
281 johnpye 1142 ,"Whether to permit use of signals for flow control in the C-level code"
282 johnpye 1234 ,True
283 johnpye 1142 ))
284    
285 johnpye 392 # You can turn off building of Tcl/Tk interface
286 jpye 2524 vars.Add(BoolVariable('WITH_TCLTK'
287 johnpye 673 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
288 johnpye 542 , True
289 johnpye 386 ))
290    
291 johnpye 392 # You can turn off the building of the Python interface
292 jpye 2524 vars.Add(BoolVariable('WITH_PYTHON'
293 johnpye 673 ,"Set to False if you don't want to build Python wrappers."
294 johnpye 542 , True
295 johnpye 387 ))
296    
297 johnpye 392 # Which solvers will we allow?
298 jpye 2524 vars.Add(ListVariable('WITH_SOLVERS'
299 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
300 jpye 1520 +" works. The option 'LSOD' is provided for backwards compatibility"
301     +"; the value 'LSODE' is preferred."
302 jpye 2422 ,["QRSLV","CMSLV","LSODE","IDA","CONOPT","LRSLV","IPOPT","DOPRI5"]
303 johnpye 392 ,['QRSLV','MPS','SLV','OPTSQP'
304     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
305 jpye 2421 ,'LSODE','LSOD','OPTSQP',"IDA","TRON","IPOPT","DOPRI5","MAKEMPS","RADAU5"
306 johnpye 392 ]
307     ))
308    
309 johnpye 393 # Where will the local copy of the help files be kept?
310 jpye 2524 vars.Add(BoolVariable('WITH_DOC'
311 jpye 1443 , "Should we try to build and install help files? If not, ASCEND will access online help files"
312 jpye 1442 , True
313 johnpye 393 ))
314    
315 jpye 2524 vars.Add(BoolVariable('WITH_DOC_BUILD'
316 jpye 1443 , "If true, we'll attempt to build docs. Set false, we'll assume we already have then (eg from the tarball)"
317     , "$WITH_DOC"
318     ))
319    
320 jpye 2524 vars.Add(BoolVariable('WITH_DOC_INSTALL'
321 jpye 1443 , "If true, SCons will install the documentation file(s). If false, assume rpm or dpkg is going to do it."
322     , "$WITH_DOC"
323     ))
324    
325 jpye 2524 vars.Add('HELP_ROOT'
326 jpye 1442 , "Location of the main help file"
327     , "$INSTALL_DOC/book.pdf"
328     )
329    
330 johnpye 393 # Will bintoken support be enabled?
331 jpye 2524 vars.Add(BoolVariable('WITH_BINTOKEN'
332 johnpye 393 ,"Enable bintoken support? This means compiling models as C-code before"
333     +" running them, to increase solving speed for large models."
334     ,False
335     ))
336    
337 johnpye 398 # What should the default ASCENDLIBRARY path be?
338     # Note: users can change it by editing their ~/.ascend.ini
339 jpye 2524 vars.Add('DEFAULT_ASCENDLIBRARY'
340 johnpye 393 ,"Set the default value of the ASCENDLIBRARY -- the location where"
341     +" ASCEND will look for models when running ASCEND"
342 jpye 1519 ,"$INSTALL_MODELS"
343 johnpye 393 )
344    
345 jpye 1519 # What should the default ASCENDLIBRARY path be?
346     # Note: users can change it by editing their ~/.ascend.ini
347 jpye 2524 vars.Add('DEFAULT_ASCENDSOLVERS'
348 jpye 1519 ,"Set the default value of ASCENDSOLVERS -- the location where"
349     +" ASCEND will look for solver shared-library files"
350     ,"$INSTALL_SOLVERS"
351     )
352    
353 johnpye 398 # Where is SWIG?
354 jpye 2524 vars.Add('SWIG'
355 johnpye 398 ,"SWIG location, probably only required for MinGW and MSVC users."
356     +" Enter the location as a Windows-style path, for example"
357 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
358 jpye 2094 ,default_swig
359 johnpye 398 )
360    
361 johnpye 400 # Build the test suite?
362 jpye 2524 vars.Add(BoolVariable('WITH_CUNIT'
363 johnpye 665 ,"You can disable CUnit tests with this option. This will basically stop"
364     +" SCons from parsing the SConscript files relating to the 'test'"
365     +" target, which just might make things marginally faster. Probably"
366     +" you can just ignore this option though. SCons will sniff for Cunit"
367     +" but build the tests only if you specify the 'test' target."
368     ,True
369 johnpye 400 ))
370 johnpye 393
371 johnpye 993 # Build with MMIO matrix export support?
372 jpye 2524 vars.Add(BoolVariable('WITH_MMIO'
373 johnpye 993 ,"Include support for exporting matrices in Matrix Market format"
374     ,True
375     ))
376    
377 johnpye 938 #----- default paths -----
378 jpye 2524 vars.Add(PackageVariable('DEFAULT_PREFIX'
379 johnpye 938 ,"Where are most of the shared libraries located on your system?"
380     ,default_prefix
381     ))
382    
383 jpye 2007 #------ cunit --------
384     # CUnit is a unit testing library that we use to test libascend.
385 johnpye 957
386 johnpye 935 # Where was CUNIT installed?
387 jpye 2524 vars.Add(PackageVariable('CUNIT_PREFIX'
388 johnpye 935 ,"Where are your CUnit files?"
389 johnpye 938 ,"$DEFAULT_PREFIX"
390 johnpye 935 ))
391    
392 johnpye 400 # Where are the CUnit includes?
393 jpye 2524 vars.Add(PackageVariable('CUNIT_CPPPATH'
394 johnpye 400 ,"Where are your CUnit include files?"
395 johnpye 938 ,"$CUNIT_PREFIX/include"
396 johnpye 400 ))
397 johnpye 392
398 johnpye 404 # Where are the CUnit libraries?
399 jpye 2524 vars.Add(PackageVariable('CUNIT_LIBPATH'
400 johnpye 404 ,"Where are your CUnit libraries?"
401 johnpye 938 ,"$CUNIT_PREFIX/lib"
402 johnpye 400 ))
403    
404 johnpye 938 # ----- conopt-----
405 johnpye 783
406 jpye 2524 vars.Add(PackageVariable("CONOPT_PREFIX"
407 johnpye 783 ,"Prefix for your CONOPT install (CONOPT ./configure --prefix)"
408 johnpye 800 ,default_conopt_prefix
409 johnpye 783 ))
410    
411 jpye 2524 vars.Add("CONOPT_LIB"
412 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'."
413 johnpye 800 ,default_conopt_lib
414 johnpye 783 )
415    
416 jpye 2524 vars.Add(BoolVariable("CONOPT_LINKED"
417 jpye 1541 ,"Do you want to dynamically link to CONOPT (only possible if CONOPT is available at buildtime)"
418     ,False
419     ))
420    
421 jpye 2524 vars.Add('CONOPT_CPPPATH'
422 johnpye 783 ,"Where is your conopt.h?"
423 johnpye 800 ,default_conopt_cpppath
424 johnpye 783 )
425    
426 jpye 2524 vars.Add('CONOPT_LIBPATH'
427 jpye 1399 ,"Where is your CONOPT library installed?"
428 johnpye 800 ,default_conopt_libpath
429 johnpye 783 )
430    
431 jpye 2524 vars.Add('CONOPT_DLPATH'
432 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)."
433 jpye 1399 ,default_conopt_dlpath
434     )
435    
436 jpye 2524 vars.Add('CONOPT_ENVVAR'
437 jpye 1747 ,"Name of the optional environment variable which will be used for the value of the searchpath for the CONOPT DLL/SO."
438 johnpye 800 ,default_conopt_envvar
439     )
440    
441 jpye 1546 #------- IPOPT -------
442    
443 jpye 2327 if platform.system()=="Windows":
444 jpye 2524 vars.Add(PackageVariable("IPOPT_PREFIX"
445 jpye 2327 ,"Prefix for your IPOPT install (IPOPT ./configure --prefix)"
446     ,default_conopt_prefix
447     ))
448 jpye 1546
449 jpye 2524 vars.Add("IPOPT_LIBS"
450 jpye 2327 ,"Library linked to for IPOPT"
451     ,default_ipopt_libs
452     )
453 jpye 1546
454 jpye 2524 vars.Add("IPOPT_LIBPATH"
455 jpye 2327 ,"Where is your IPOPT library installed"
456     ,default_ipopt_libpath
457     )
458 jpye 1546
459 jpye 2524 vars.Add('IPOPT_CPPPATH'
460 jpye 2327 ,"Where is your IPOPT coin/IpStdCInterface.h (do not include the 'coin' in the path)"
461     ,"$IPOPT_PREFIX/include"
462     )
463 jpye 1546
464 jpye 2610 for i in range(5):
465     vars.Add('IPOPT_DLL%d'%(i+1)
466     ,"Exact path of IPOPT DLL (%d) to be included in the installer (Windows only)"%(i+1)
467     ,default_ipopt_dll[i]
468     )
469 jpye 1546
470 johnpye 938 #-------- f2c ------
471    
472 jpye 2524 vars.Add("F2C_LIB"
473 johnpye 673 ,"F2C library (eg. g2c, gfortran, f2c)"
474 jpye 1566 ,default_f2c_lib # the default is gfortran now
475 johnpye 673 )
476    
477 jpye 2524 vars.Add(PackageVariable("F2C_LIBPATH"
478 johnpye 673 ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
479     ,"off"
480     ))
481    
482 jpye 2524 vars.Add("FORTRAN"
483 jpye 1398 ,"Fortran compiler (eg g77, gfortran)"
484 jpye 2523 ,"${HOST_PREFIX}gfortran"
485 jpye 1398 )
486    
487 jpye 2524 vars.Add("SHFORTRAN"
488     ,"Fortran compiler for shared library object (should normally be same as FORTRAN)"
489     ,"$FORTRAN"
490     )
491    
492 johnpye 938 #------- tcl/tk --------
493    
494 jpye 2524 vars.Add('TCL'
495 johnpye 521 ,'Base of Tcl distribution'
496     ,default_tcl
497 johnpye 534 )
498 johnpye 521
499 johnpye 404 # Where are the Tcl includes?
500 jpye 2524 vars.Add('TCL_CPPPATH'
501 johnpye 404 ,"Where are your Tcl include files?"
502 jpye 1488 ,default_tcl_cpppath
503 johnpye 534 )
504 johnpye 404
505     # Where are the Tcl libs?
506 jpye 2524 vars.Add('TCL_LIBPATH'
507 johnpye 404 ,"Where are your Tcl libraries?"
508 johnpye 541 ,default_tcl_libpath
509 johnpye 534 )
510 johnpye 404
511 johnpye 428 # What is the name of the Tcl lib?
512 jpye 2524 vars.Add('TCL_LIB'
513 johnpye 561 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
514 johnpye 464 ,default_tcl_lib
515 johnpye 428 )
516    
517 johnpye 405 # Where are the Tk includes?
518 jpye 2524 vars.Add('TK_CPPPATH'
519 johnpye 405 ,"Where are your Tk include files?"
520 johnpye 464 ,'$TCL_CPPPATH'
521 johnpye 534 )
522 johnpye 404
523 johnpye 405 # Where are the Tk libs?
524 jpye 2524 vars.Add('TK_LIBPATH'
525 johnpye 405 ,"Where are your Tk libraries?"
526 johnpye 464 ,'$TCL_LIBPATH'
527 johnpye 534 )
528 johnpye 405
529 johnpye 428 # What is the name of the Tk lib?
530 jpye 2524 vars.Add('TK_LIB'
531 johnpye 521 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
532 johnpye 464 ,default_tk_lib
533 johnpye 435 )
534    
535 johnpye 460 # Static linking to TkTable
536    
537 jpye 2524 vars.Add(BoolVariable('STATIC_TCLTK'
538 johnpye 554 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
539 johnpye 460 ,False
540     ))
541    
542 jpye 2524 vars.Add('TKTABLE_LIBPATH'
543 johnpye 460 ,'Location of TkTable static library'
544 johnpye 464 ,'$TCL_LIBPATH/Tktable2.8'
545     )
546 johnpye 460
547 jpye 2524 vars.Add('TKTABLE_LIB'
548 johnpye 521 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
549 johnpye 464 ,default_tktable_lib
550 johnpye 460 )
551    
552 jpye 2524 vars.Add('TKTABLE_CPPPATH'
553 johnpye 521 ,'Location of TkTable header file'
554     ,'$TCL_CPPPATH'
555     )
556    
557 jpye 2524 vars.Add('X11'
558 johnpye 554 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
559 johnpye 521 ,'/usr/X11R6'
560     )
561    
562 jpye 2524 vars.Add('X11_LIBPATH'
563 johnpye 554 ,'Location of X11 lib. EXPERIMENTAL'
564 johnpye 521 ,'$X11/lib'
565     )
566    
567 jpye 2524 vars.Add('X11_CPPPATH'
568 johnpye 554 ,'Location of X11 includes. EXPERIMENTAL'
569 johnpye 521 ,'$X11/include'
570     )
571    
572 jpye 2524 vars.Add('X11_LIB'
573 johnpye 554 ,'Name of X11 lib. EXPERIMENTAL'
574 johnpye 521 ,'X11'
575     )
576    
577 johnpye 938 #----- installed file locations (for 'scons install') -----
578    
579 jpye 2524 vars.Add('INSTALL_PREFIX'
580 johnpye 435 ,'Root location for installed files'
581 jpye 2073 ,default_install_prefix
582 johnpye 428 )
583    
584 jpye 2524 vars.Add('INSTALL_BIN'
585 johnpye 435 ,'Location to put binaries during installation'
586 jpye 2073 ,default_install_bin
587 johnpye 435 )
588    
589 jpye 2524 vars.Add('INSTALL_LIB'
590 johnpye 683 ,'Location to put libraries during installation'
591 jpye 2073 ,default_install_lib
592 johnpye 463 )
593    
594 jpye 2524 vars.Add('INSTALL_SHARE'
595 johnpye 628 ,'Common shared-file location on this system'
596     ,"$INSTALL_PREFIX/share"
597 johnpye 435 )
598    
599 jpye 2524 vars.Add('INSTALL_ASCDATA'
600 jpye 2025 ,"Location of ASCEND shared data (TK, python, models etc)"
601 jpye 2073 ,default_install_ascdata
602 jpye 2025 )
603    
604 jpye 2524 vars.Add('INSTALL_PYTHON'
605 jpye 2307 ,'General location for Python extensions on this system'
606 jpye 2075 ,default_install_python
607 jpye 2007 )
608    
609 jpye 2524 vars.Add('INSTALL_PYTHON_ASCEND'
610 jpye 2307 ,'Location for installation of Python modules specific to ASCEND'
611     ,default_install_python_ascend
612     )
613    
614 jpye 2524 vars.Add('INSTALL_TK'
615 jpye 2025 ,'Location for Tcl/Tk files used by ASCEND Tk GUI'
616     ,"$INSTALL_ASCDATA/tcltk"
617 johnpye 628 )
618    
619 jpye 2524 vars.Add('INSTALL_MODELS'
620 jpye 1504 ,"Location of ASCEND model files (.a4c,.a4l,.a4s)"
621 jpye 2073 ,default_install_models
622 jpye 1504 )
623    
624 jpye 2524 vars.Add('INSTALL_SOLVERS'
625 jpye 1504 ,"Location of ASCEND solvers"
626 jpye 2073 ,default_install_solvers
627 jpye 1504 )
628    
629 jpye 2524 vars.Add('INSTALL_DOC'
630 jpye 1442 ,"Location of ASCEND documentation files"
631     ,"$INSTALL_SHARE/doc/ascend-"+version
632     )
633    
634 jpye 2524 vars.Add('INSTALL_INCLUDE'
635 johnpye 435 ,'Location to put header files during installation'
636 jpye 2073 ,default_install_include
637 johnpye 435 )
638    
639 jpye 2524 vars.Add('INSTALL_ROOT'
640 johnpye 938 ,'For use by RPM only: location of %{buildroot} during rpmbuild'
641     ,""
642     )
643    
644 jpye 2524 vars.Add('EXTLIB_SUFFIX'
645 jpye 1597 ,"Filename suffix for ASCEND 'external libraries' (for use with IMPORT"
646 jpye 1598 ,"_ascend$SHLIBSUFFIX"
647 jpye 1597 )
648    
649 jpye 2524 vars.Add('EXTLIB_PREFIX'
650 jpye 1597 ,"Filename suffix for ASCEND 'external libraries' (for use with IMPORT"
651     ,"$SHLIBPREFIX"
652     )
653    
654 johnpye 938 #----------------------
655    
656 jpye 2524 vars.Add('PYGTK_ASSETS'
657 jpye 2007 ,'Default location for Glade assets (will be recorded in pygtk/config.py)'
658 johnpye 455 ,default_install_assets
659     )
660    
661 jpye 2524 vars.Add(BoolVariable('DEBUG'
662 johnpye 508 ,"Compile source with debugger symbols, eg for use with 'gdb'"
663     ,False
664     ))
665    
666 jpye 2524 vars.Add(BoolVariable('MALLOC_DEBUG'
667 johnpye 597 ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
668     ,False
669     ))
670    
671 johnpye 938 #------ dmalloc --------
672 jpye 2524 vars.Add(PackageVariable('DMALLOC_PREFIX'
673 johnpye 938 ,"Where are your dmalloc files?"
674 jpye 2581 ,"$DEFAULT_PREFIX"
675 johnpye 938 ))
676 johnpye 448
677 jpye 2524 vars.Add(PackageVariable('DMALLOC_CPPPATH'
678 johnpye 938 ,"Where are your dmalloc include files?"
679     ,default_cpppath
680     ))
681    
682 jpye 2524 vars.Add(PackageVariable('DMALLOC_LIBPATH'
683 johnpye 938 ,"Where are your dmalloc libraries?"
684     ,default_libpath
685     ))
686    
687 jpye 2524 vars.Add(BoolVariable('WITH_DMALLOC'
688 johnpye 938 ,"Link to the DMALLOC library (if available) for debugging of memory usage."
689     ,False
690     ))
691    
692 jpye 2524 vars.Add(BoolVariable('WITH_GRAPHVIZ'
693 jpye 1678 ,"Link to the GRAPHVIZ library (if available, for generating incidence graphs)"
694 jpye 1854 ,default_with_graphviz
695 johnpye 1109 ))
696    
697 jpye 1326
698     #------ ufsparse --------
699 jpye 2524 vars.Add(PackageVariable('UFSPARSE_PREFIX'
700 jpye 1326 ,"Where are your UFSPARSE files?"
701 jpye 2581 ,"$DEFAULT_PREFIX"
702 jpye 1326 ))
703    
704 jpye 2524 vars.Add(PackageVariable('UFSPARSE_CPPPATH'
705 jpye 1326 ,"Where are your UFSPARSE include files?"
706     ,default_cpppath
707     ))
708    
709 jpye 2524 vars.Add(PackageVariable('UFSPARSE_LIBPATH'
710 jpye 1326 ,"Where are your UFSPARSE libraries?"
711     ,default_libpath
712     ))
713    
714 jpye 2524 vars.Add(BoolVariable('WITH_UFSPARSE'
715 jpye 1326 ,"Link to the UFSPARSE library (if available, for additional sparse matrix routines)"
716     ,True
717     ))
718    
719 johnpye 938 #-----------------------
720    
721 jpye 2524 vars.Add(BoolVariable('UPDATE_NO_YACC_LEX'
722 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)"
723     ,False
724     ))
725    
726 jpye 2524 vars.Add('DISTTAR_NAME'
727 johnpye 563 ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
728     ,"ascend-"+version
729     )
730    
731 jpye 2524 vars.Add('RELEASE'
732 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."
733     ,"0"
734     )
735    
736 jpye 2524 vars.Add(BoolVariable('ABSOLUTE_PATHS'
737 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."
738 johnpye 628 ,default_absolute_paths
739 johnpye 605 ))
740    
741 jpye 2524 vars.Add('WIN_INSTALLER_NAME'
742 johnpye 578 ,"Name of the installer .exe to create under Windows (minus the '.exe')"
743 jpye 2567 ,"ascend-"+version+winarchtag+"-py"+pyversion+".exe"
744 johnpye 578 )
745    
746 jpye 2524 vars.Add(BoolVariable('WITH_XTERM_COLORS'
747 johnpye 594 ,"Set to 0 if you don't want xterm colour codes in the console output"
748     ,True
749     ))
750    
751 jpye 2524 vars.Add(BoolVariable('WITH_EXTFNS'
752 jpye 1504 ,"Set to 0 if you don't want to attempt to build the external modules bundled with ASCEND"
753 johnpye 761 ,True
754     ))
755    
756 jpye 2524 vars.Add(BoolVariable('WITH_SCROLLKEEPER'
757 johnpye 816 ,"Set to to 1 if you want to install an OMF file that can be read by scrollkeeper (eg Yelp on GNOME)"
758     ,default_with_scrollkeeper
759     ))
760    
761 jpye 2524 vars.Add(BoolVariable('WITH_MSVCR71'
762 jpye 1720 ,"Attempt to link against MSVCR71.DLL, to enable passing of FILE* objects to/from python"
763     ,False
764     ))
765 jpye 1557
766 johnpye 546
767 johnpye 392 # TODO: OTHER OPTIONS?
768     # TODO: flags for optimisation
769 johnpye 393 # TODO: turning on/off bintoken functionality
770 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
771 johnpye 393
772 johnpye 498 # Import the outside environment
773    
774 johnpye 800 def c_escape(str):
775     return re.sub("\\\\","/",str)
776    
777     envadditional={}
778 johnpye 740
779 jpye 1630 tools = [
780 jpye 2146 'lex', 'yacc', 'fortran', 'swig', 'substinfile'
781 mahesh 2150 ,'disttar', 'tar', 'graphviz','sundials'
782 jpye 1630 ]
783 johnpye 832 if platform.system()=="Windows":
784 jpye 2146 tools += ['nsis']
785    
786 johnpye 1078 if os.environ.get('OSTYPE')=='msys' or os.environ.get('MSYSTEM'):
787 jpye 2534 envenv = os.environ
788 jpye 1459 tools += ['mingw']
789 johnpye 832 envadditional['IS_MINGW']=True
790     else:
791 johnpye 1082 print "Assuming VC++ build environment (Note: MinGW is preferred)"
792 johnpye 832 envenv = {
793     'PATH':os.environ['PATH']
794     ,'INCLUDE':os.environ['INCLUDE']
795     ,'LIB':os.environ['LIB']
796     ,'MSVS_IGNORE_IDE_PATHS':1
797     }
798 jpye 1459 tools += ['default']
799 johnpye 832 envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
800 johnpye 498 else:
801 jpye 2524 envenv = os.environ
802     tools += ['default','doxygen','ipopt']
803 jpye 2315
804 johnpye 800 env = Environment(
805     ENV=envenv
806     , toolpath=['scons']
807     , tools=tools
808     , **envadditional
809     )
810 johnpye 498
811 jpye 2493 # Create .def files by default on Windows (or else SCons 2.0.1 never seems to be happy)
812     if platform.system()=="Windows":
813     env.Append(WINDOWS_INSERT_DEF=1)
814    
815 jpye 1420 #print "PATH =",os.environ['PATH']
816     #print "PROGSUFFIX =",env['PROGSUFFIX']
817     #print "CPPPATH =",env['CPPPATH']
818 jpye 1380
819 jpye 2162 vars.Update(env)
820 jpye 1520
821 jpye 1853 for l in ['SUNDIALS','IPOPT']:
822 jpye 1712 var = "%s_LIBS" % l
823 jpye 2161 if env.get(var) and not isinstance(env[var],types.ListType):
824 jpye 1712 env[var] = env[var].split(",")
825    
826 jpye 1520 if 'LSOD' in env['WITH_SOLVERS']:
827     if 'LSODE' not in env['WITH_SOLVERS']:
828     env['WITH_SOLVERS'].append('LSODE')
829     env['WITH_SOLVERS'].remove('LSOD')
830    
831 jpye 2162 vars.Save('options.cache',env)
832 johnpye 385
833 jpye 2162 Help(vars.GenerateHelpText(env))
834 johnpye 385
835 jpye 2534 if env['ENV'].get('HOST_PREFIX'):
836     triplet = re.compile("^[a-z0-9_]+-[a-z0-9_]+-[a-z0-9]+$")
837     if not triplet.match(env['ENV']['HOST_PREFIX']):
838     print "NOTE: invalid host triplet from environment variable HOST_PREFIX has been ignored"
839     else:
840     print "NOTE: using HOST_PREFIX=%s from environment to override HOST_PREFIX SCons variable" % env['ENV']['HOST_PREFIX']
841     env['HOST_PREFIX'] = env['ENV']['HOST_PREFIX']+"-"
842    
843 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
844 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
845 johnpye 386
846 johnpye 551 with_python = env.get('WITH_PYTHON')
847 johnpye 427 without_python_reason = "disabled by options/config.py"
848 johnpye 387
849 johnpye 593 with_cunit = env.get('WITH_CUNIT')
850 johnpye 427 without_cunit_reason = "not requested"
851 johnpye 400
852 johnpye 761 with_extfns = env.get('WITH_EXTFNS')
853     without_extfn_reason = "disabled by options/config.py"
854    
855 johnpye 816 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
856     without_scrollkeeper_reason = "disabled by options/config.py"
857    
858 johnpye 938 with_dmalloc = env.get('WITH_DMALLOC')
859     without_dmalloc_reason = "disabled by options/config.py"
860    
861 jpye 1678 with_graphviz = env.get('WITH_GRAPHVIZ')
862     without_graphiviz_reason = "disabled by options/config.py"
863 johnpye 1109
864 jpye 1326 with_ufsparse = env.get('WITH_UFSPARSE')
865     without_ufsparse_reason = "disabled by options/config.py"
866    
867 johnpye 993 with_mmio = env.get('WITH_MMIO')
868     without_mmio_reason = "disabled by options/config.py"
869    
870 johnpye 1142 with_signals = env.get('WITH_SIGNALS')
871     without_signals_reason = "disabled by options/config.py"
872    
873 jpye 1442 with_doc = env.get('WITH_DOC')
874    
875 jpye 1443 with_doc_build = env.get('WITH_DOC_BUILD');
876 jpye 1470 without_doc_build_reason = "disabled by options/config.py"
877 jpye 1443 if not with_doc:
878 jpye 1470 with_doc_build = False
879     without_doc_build_reason = "disabled by with_doc"
880 jpye 1443
881 jpye 1442 with_latex2html = False
882    
883 johnpye 631 if platform.system()=="Windows":
884     with_installer=1
885     else:
886     with_installer=0
887     without_installer_reason = "only possible under Windows"
888 johnpye 673
889 jpye 2379 notselected = "Not selected (see config option WITH_SOLVERS)"
890    
891 jpye 1734 with_lsode = 'LSODE' in env['WITH_SOLVERS']
892 jpye 2379 without_lsode_reason = notselected
893 johnpye 673
894 jpye 1734 with_ida = 'IDA' in env['WITH_SOLVERS']
895 jpye 2379 without_ida_reason = notselected
896 johnpye 783
897 jpye 1734 with_dopri5 = 'DOPRI5' in env['WITH_SOLVERS']
898 jpye 2379 without_dopri5_reason = notselected
899 johnpye 783
900 jpye 2421 with_radau5 = 'RADAU5' in env['WITH_SOLVERS']
901     without_radau5_reason = notselected
902    
903 jpye 1734 with_conopt = 'CONOPT' in env['WITH_SOLVERS']
904 jpye 2379 without_conopt_reason = notselected
905 jpye 1529
906 jpye 1734 with_ipopt = 'IPOPT' in env['WITH_SOLVERS']
907 jpye 2379 without_ipopt_reason = notselected
908 jpye 1734
909 jpye 2378 with_makemps = 'MAKEMPS' in env['WITH_SOLVERS']
910 jpye 2379 without_makemps_reason = notselected
911 jpye 1734
912 jpye 2378
913 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
914     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
915     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
916 johnpye 393
917 johnpye 463 can_install = True
918     if platform.system()=='Windows':
919     can_install = False
920    
921     env['CAN_INSTALL']=can_install
922 johnpye 721
923 jpye 1437 print "TCL=",env['TCL']
924 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
925     print "TCL_LIBPATH =",env['TCL_LIBPATH']
926     print "TCL_LIB =",env['TCL_LIB']
927 johnpye 393
928 johnpye 628 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
929 jpye 1504 print "INSTALL_ASCDATA =",env['INSTALL_ASCDATA']
930 jpye 1413 print "INSTALL_PREFIX =",env['INSTALL_PREFIX']
931 jpye 1504 print "INSTALL_MODELS =",env['INSTALL_MODELS']
932     print "INSTALL_SOLVERS =",env['INSTALL_SOLVERS']
933 jpye 2016 print "INSTALL_PYTHON =",env['INSTALL_PYTHON']
934 jpye 2307 print "INSTALL_PYTHON_ASCEND =",env['INSTALL_PYTHON_ASCEND']
935    
936 jpye 1504 print "DEFAULT_ASCENDLIBRARY =",env['DEFAULT_ASCENDLIBRARY']
937 jpye 1519 print "DEFAULT_ASCENDSOLVERS =",env['DEFAULT_ASCENDSOLVERS']
938 jpye 1504
939    
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     sundials_version_minor_min = 2
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 jpye 1701 # 'lmodern' package for LaTeX available?
1982    
1983 jpye 1723 lmodern_test_text = r"""
1984 jpye 1701 \documentclass{article}
1985 jpye 1723 \usepackage{lmodern}
1986 jpye 1701 \title{Cartesian closed categories and the price of eggs}
1987     \author{Jane Doe}
1988     \date{September 1994}
1989     \begin{document}
1990     \maketitle
1991     Hello world!
1992     \end{document}
1993     """;
1994    
1995     def CheckLModern(context):
1996     context.Message("Checking for lmodern...")
1997 jpye 1770 b = context.env.get("DVI")
1998     if not b:
1999     context.Result(False)
2000     return False
2001 jpye 2000 ff = context.env.get('LATEXFLAGS')
2002     context.env.Append(LATEXFLAGS=['-interaction=nonstopmode','-halt-on-error'])
2003     is_ok = context.TryBuild(builder=b,text=lmodern_test_text,extension=".latex")
2004     print "is_ok=",is_ok
2005     if ff is not None:
2006     context.env['LATEXFLAGS'] = ff
2007     else:
2008     del context.env['LATEXFLAGS']
2009 jpye 1701 context.Result(is_ok)
2010     return is_ok
2011    
2012     #----------------
2013 johnpye 485 # GCC Version sniffing
2014    
2015     # TODO FIXME
2016    
2017     gcc_version4 = False
2018    
2019 johnpye 398 #------------------------------------------------------
2020 johnpye 385 # CONFIGURATION
2021    
2022     conf = Configure(env
2023     , custom_tests = {
2024 jpye 1448 'CheckCC' : CheckCC
2025     , 'CheckCXX' : CheckCXX
2026 jpye 2523 , 'CheckFortran' : CheckFortran
2027 jpye 1448 , 'CheckMath' : CheckMath
2028 jpye 1656 , 'CheckMalloc' : CheckMalloc
2029     , 'CheckDLOpen' : CheckDLOpen
2030 johnpye 673 , 'CheckSwigVersion' : CheckSwigVersion
2031 johnpye 957 , 'CheckPythonLib' : CheckPythonLib
2032 johnpye 400 , 'CheckCUnit' : CheckCUnit
2033 johnpye 938 , 'CheckDMalloc' : CheckDMalloc
2034 jpye 1442 , 'CheckLyx' : CheckLyx
2035     , 'CheckLatex2HTML' : CheckLatex2HTML
2036 jpye 1701 , 'CheckLModern' : CheckLModern
2037 jpye 1678 , 'CheckGraphViz' : CheckGraphViz
2038 jpye 1721 , 'CheckGraphVizBoolean' : CheckGraphVizBoolean
2039 jpye 1326 , 'CheckUFSparse' : CheckUFSparse
2040 johnpye 404 , 'CheckTcl' : CheckTcl
2041     , 'CheckTclVersion' : CheckTclVersion
2042 johnpye 405 , 'CheckTk' : CheckTk
2043     , 'CheckTkVersion' : CheckTkVersion
2044 johnpye 502 , 'CheckGcc' : CheckGcc
2045 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
2046 johnpye 502 , 'CheckYacc' : CheckYacc
2047 johnpye 1025 , 'CheckLex' : CheckLex
2048 jpye 2355 , 'CheckLexDestroy' : CheckLexDestroy
2049 johnpye 521 , 'CheckTkTable' : CheckTkTable
2050     , 'CheckX11' : CheckX11
2051 johnpye 673 , 'CheckIDA' : CheckIDA
2052 jpye 1400 , 'CheckSUNDIALS' : CheckSUNDIALS
2053 johnpye 783 , 'CheckCONOPT' : CheckCONOPT
2054 jpye 1529 , 'CheckIPOPT' : CheckIPOPT
2055 johnpye 816 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
2056 johnpye 953 , 'CheckFPE' : CheckFPE
2057 johnpye 968 , 'CheckSIGINT' : CheckSIGINT
2058     , 'CheckSigReset' : CheckSigReset
2059 johnpye 400 # , 'CheckIsNan' : CheckIsNan
2060     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
2061 jpye 1691 }
2062 johnpye 459 # , config_h = "config.h"
2063 johnpye 385 )
2064    
2065 jpye 1357 def sconsversioncheck():
2066    
2067     # uncomment the following line to skip the version check:
2068     # return 1
2069    
2070     import SCons
2071     v = SCons.__version__.split(".")
2072     if v[0] != '0':
2073 jpye 2313 if v[0] == '1' or v[0] == '2':
2074 jpye 1999 return 1;
2075 jpye 1357 return 0
2076 jpye 1431 if int(v[1]) >= 97:
2077     return 1
2078 jpye 1357 if v[1] != '96':
2079     return 0
2080     micro = int(v[2])
2081 jpye 1394 if micro == 92 or micro == 93 or micro == 96:
2082 jpye 1357 return 1;
2083     return 0
2084    
2085     if not sconsversioncheck():
2086     print "Scons version is not OK. Please try version 0.96.92 or 0.96.93,"
2087     print "or consult the developers in the case of newer versions. Modify"
2088     print "the function 'sconsversioncheck' in the file SConstruct if you"
2089     print "want to *force* SCons to continue."
2090     Exit(1)
2091    
2092 jpye 1448 # check C compiler
2093    
2094 jpye 1654 if conf.CheckCC() is False:
2095 jpye 1448 print "Failed to build simple test file with your C compiler."
2096     print "Check your compiler is installed and running correctly."
2097     Exit(1)
2098    
2099 jpye 1654 if conf.CheckCXX() is False:
2100 jpye 1448 print "Failed to build simple test file with your C++ compiler."
2101     print "Check your compiler is installed and running correctly."
2102 jpye 1630 print "You can set your C++ compiler using the CXX scons option."
2103 jpye 1448 Exit(1)
2104    
2105 johnpye 740 # stdio -- just to check that compiler is behaving
2106 johnpye 398
2107 jpye 1654 if conf.CheckHeader('stdio.h') is False:
2108 johnpye 832 print "CPPPATH =",env.get('CPPPATH')
2109 johnpye 740 print "Did not find 'stdio.h'! Check your compiler configuration."
2110 johnpye 1080 print ""
2111     print "You environment is printed here:"
2112     for k,v in os.environ.iteritems():
2113     print "%-30s%s" % ("%s :" % k, v)
2114 johnpye 740 Exit(1)
2115    
2116 jpye 2037 # sizes of vars used in libascend eg in gl_list etc.
2117 ballan 2036
2118 jpye 2037 _sizes = {
2119     "VOID_P" : "void *"
2120     ,"INT" : "int"
2121     ,"LONG" : "long"
2122     ,"LONG_LONG" : "long long"
2123 jpye 2527 ,"UINT" : "unsigned int"
2124 jpye 2526 ,"ULONG" : "unsigned long"
2125     ,"ULONGLONG" : "unsigned long long"
2126 jpye 2037 }
2127 ballan 2036
2128 jpye 2037 for _var,_type in _sizes.iteritems():
2129     _size = conf.CheckTypeSize(_type)
2130     if not _size:
2131     print "Couldn't determine 'sizeof(%s)'" % _type
2132     Exit(1)
2133     conf.env["SIZEOF_%s" % _var] = str(_size)
2134 ballan 2036
2135 jpye 2037 # check for some string functions
2136 ballan 2036
2137 jpye 2523 if conf.CheckFunc('sprintf') is False:
2138     print "Didn't find sprintf";
2139 jpye 2037 Exit(1)
2140 johnpye 1228
2141 jpye 1678 if conf.CheckFunc('strdup'):
2142     conf.env['HAVE_STRDUP'] = True
2143    
2144 jpye 2523 if conf.CheckFunc('snprintf'):
2145     conf.env['HAVE_SNPRINTF'] = True
2146     elif conf.CheckFunc('_snprintf'):
2147     conf.env['HAVE__SNPRINTF'] = True
2148    
2149 jpye 2037 # attempt to support MSVCRT 7.1 on Windows
2150    
2151 jpye 1720 if platform.system()=="Windows" and env.get('WITH_MSVCR71'):
2152     conf.env.Append(LIBS='msvcr71')
2153    
2154 johnpye 385 # Math library
2155    
2156 johnpye 1262 conf.env['HAVE_IEEE']=True
2157    
2158 jpye 1654 if need_libm and (conf.CheckMath() is False):
2159 johnpye 1232 conf.env['HAVE_IEEE']=False
2160 johnpye 1262 print 'Did not find math library, exiting!'
2161     Exit(1)
2162 johnpye 427
2163 jpye 1656 # Malloc
2164    
2165     if conf.CheckMalloc() is False:
2166     conf.env['HAVE_MALLOC']=False
2167     print "Did not find functioning 'malloc', exiting!"
2168     Exit(1)
2169    
2170     # dlopen/LoadLibrary
2171    
2172 jpye 1659 # CURRENTLY BREAKS LATER TEST (libsave?)
2173     #if conf.CheckDLOpen() is False:
2174     # print "Did not find functioning dlopen/LoadLibrary, exiting!"
2175     # Exit(1)
2176 jpye 1656
2177 johnpye 385 # Where is 'isnan'?
2178    
2179 jpye 1654 if conf.CheckFunc('isnan') is False and conf.CheckFunc('_isnan') is False:
2180 johnpye 385 print "Didn't find isnan"
2181 johnpye 414 # Exit(1)
2182 johnpye 385
2183 johnpye 500 # GCC visibility
2184    
2185 johnpye 502 if conf.CheckGcc():
2186     conf.env['HAVE_GCC']=True;
2187 jpye 2027 if env.get('WITH_GCCVISIBILITY') and conf.CheckGccVisibility():
2188 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
2189     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
2190     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
2191 johnpye 709 conf.env.Append(CCFLAGS=['-Wall'])
2192 johnpye 500
2193 johnpye 968 # Catching SIGINT
2194    
2195 johnpye 1142 if env['WITH_SIGNALS']:
2196 jpye 1655 if not conf.CheckSIGINT():
2197 johnpye 1142 with_signals = False
2198     without_signals_reason = "SIGINT uncatchable"
2199 johnpye 968
2200 johnpye 953 # Catching SIGFPE
2201    
2202     if conf.CheckFPE():
2203 johnpye 968 conf.env['HAVE_C99FPE']=True
2204 johnpye 953 else:
2205 johnpye 968 conf.env['HAVE_C99FPE']=False
2206 johnpye 953
2207 johnpye 968 # Checking for signal reset requirement
2208    
2209 jpye 1654 if conf.CheckSigReset() is False:
2210 johnpye 968 print "Unable to determine if signal reset is required"
2211 johnpye 1260 Exit(1)
2212 johnpye 968
2213 johnpye 502 # YACC
2214    
2215 jpye 1552 if conf.CheckYacc():
2216 johnpye 502 conf.env['HAVE_YACC']=True
2217    
2218 jpye 1552 if conf.CheckLex():
2219 johnpye 1025 conf.env['HAVE_LEX']=True
2220 johnpye 502
2221 jpye 2355 if conf.CheckLexDestroy():
2222     conf.env['HAVE_LEXDESTROY']=True
2223    
2224 johnpye 387 # Tcl/Tk
2225 johnpye 386
2226 johnpye 586 if with_tcltk:
2227     if conf.CheckTcl():
2228     if conf.CheckTclVersion():
2229     if conf.CheckTk():
2230     if with_tcltk and conf.CheckTkVersion():
2231     if env['STATIC_TCLTK']:
2232     if conf.CheckTkTable():
2233     pass
2234     else:
2235     without_tcltk_reason = "TkTable not found"
2236     with_tcltk = False
2237     else:
2238     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
2239     with_tcltk = False
2240 johnpye 521 else:
2241 johnpye 586 without_tcltk_reason = "Tk not found."
2242 johnpye 551 with_tcltk = False
2243 johnpye 428 else:
2244 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
2245 johnpye 551 with_tcltk = False
2246 johnpye 586
2247 johnpye 428 else:
2248 johnpye 586 without_tcltk_reason = "Tcl not found."
2249 johnpye 551 with_tcltk = False
2250 johnpye 386
2251 johnpye 521 if env['STATIC_TCLTK']:
2252     conf.CheckX11()
2253    
2254 johnpye 395 # Python... obviously we're already running python, so we just need to
2255     # check that we can link to the python library OK:
2256    
2257 jpye 1655 if not conf.CheckPythonLib():
2258 johnpye 957 without_python_reason = 'libpython2.x not found or not linkable'
2259     with_python = False
2260 johnpye 982 env['WITH_PYTHON']=False
2261 johnpye 391
2262 johnpye 395 # SWIG version
2263    
2264 jpye 1656 if with_python and conf.CheckSwigVersion() is False:
2265 johnpye 413 without_python_reason = 'SWIG >= 1.3.24 is required'
2266     with_python = False
2267 johnpye 982 env['WITH_PYTHON']=False
2268 johnpye 413
2269 johnpye 400 # CUnit
2270    
2271 johnpye 593 if with_cunit:
2272 jpye 1655 if not conf.CheckCUnit():
2273 johnpye 427 without_cunit_reason = 'CUnit not found'
2274 johnpye 665 with_cunit = False
2275 johnpye 705 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
2276 johnpye 427
2277 johnpye 938 # DMALLOC
2278    
2279     if with_dmalloc:
2280 jpye 1655 if not conf.CheckDMalloc():
2281 johnpye 938 without_dmalloc_reason = 'dmalloc not found'
2282     with_dmalloc = False
2283    
2284 jpye 1678 # GRAPHVIZ
2285 johnpye 1109
2286 jpye 1678 if with_graphviz:
2287     if not conf.CheckGraphViz():
2288     without_graphviz_reason = 'graphviz not found'
2289     with_graphviz = False
2290     env['WITH_GRAPHVIZ'] = False
2291 jpye 1721 env['HAVE_GRAPHVIZ_BOOLEAN'] = conf.CheckGraphVizBoolean()
2292 johnpye 1109
2293 jpye 1326 # UFSPARSE
2294    
2295     if with_ufsparse:
2296 jpye 1655 if not conf.CheckUFSparse():
2297 jpye 1678 without_ufsparse_reason = 'ufsparse not found'
2298 jpye 1326 with_ufsparse = False
2299     env['WITH_UFSPARSE'] = False
2300    
2301 johnpye 673 # IDA
2302    
2303 jpye 1734 if with_ida:
2304     if not conf.CheckSUNDIALS():
2305     with_ida = False
2306     without_ida_reason = "SUNDIALS not found, or bad version"
2307     elif not conf.CheckIDA():
2308     with_ida = False
2309     without_ida_reason = "Unable to compile/link against SUNDIALS/IDA"
2310 johnpye 673
2311 johnpye 797 # CONOPT
2312 johnpye 783
2313     if not with_conopt:
2314     without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
2315 jpye 1654 elif conf.CheckCONOPT() is False:
2316 jpye 1541 if conf.env.get('CONOPT_LINKED'):
2317     conf.env['CONOPT_LINKED'] = False
2318     # we no longer require CONOPT at buildtime in order to build support for it
2319     #with_conopt = False
2320     #without_conpt_reason = "CONOPT not found"
2321 johnpye 783
2322 jpye 1529 # IPOPT
2323    
2324     if not with_ipopt:
2325     without_ipopt_reason = "Not selected (see config option WITH_SOLVERS)"
2326 jpye 1657 elif not conf.CheckIPOPT():
2327 jpye 1529 with_ipopt = False
2328     without_ipopt_reason = "IPOPT not found"
2329    
2330 johnpye 427 # BLAS
2331    
2332 johnpye 459 need_blas=False
2333 johnpye 673
2334     if with_lsode:
2335     need_fortran = True
2336 jpye 1641 need_fortran_reasons.append("LSODE")
2337 johnpye 459 need_blas=True
2338 johnpye 673
2339 jpye 2000 if with_ipopt:
2340     need_blas=True
2341    
2342 johnpye 459 if need_blas:
2343     if conf.CheckLib('blas'):
2344     with_local_blas = False
2345     without_local_blas_reason = "Found BLAS installed on system"
2346     else:
2347     with_local_blas = True
2348     need_fortran = True
2349 jpye 1641 need_fortran_reasons.append("BLAS")
2350 johnpye 673 else:
2351     with_local_blas= False;
2352     without_local_blas_reason = "BLAS not required"
2353 johnpye 427
2354     # FORTRAN
2355    
2356 jpye 2524 # we'll assume now (2012) that we always have gfortran available on our system.
2357 johnpye 629
2358 jpye 2523 if need_fortran and conf.CheckFortran() is False:
2359 jpye 1641 print "Failed to build simple test file with your Fortran compiler."
2360     print "Check your compiler is installed and running correctly."
2361     print "You can set your Fortran compiler using the FORTRAN scons option."
2362     print "The fortran compiler is REQUIRED to build:",", ".join(need_fortran_reasons)
2363     print "Perhaps try examining the value of your WITH_SOLVERS option (remove LSODE, etc)."
2364     Exit(1)
2365    
2366 johnpye 464 #else:
2367     # print "FORTRAN not required"
2368 johnpye 400
2369 johnpye 673 # F2C
2370    
2371     if need_fortran:
2372     if platform.system()=="Windows":
2373 jpye 1380 pass
2374     #conf.env.Append(LIBPATH='c:\mingw\lib')
2375 johnpye 673
2376 johnpye 816 # scrollkeeper
2377 johnpye 673
2378 johnpye 816 if with_scrollkeeper:
2379 jpye 1654 if conf.CheckScrollkeeperConfig() is False:
2380 johnpye 816 with_scrollkeeper=False
2381     without_scrollkeeper_reason="unable to detect scrollkeeper-config"
2382    
2383 jpye 1442 # lyx
2384    
2385 jpye 1470 if with_doc_build:
2386 jpye 1769 if not conf.CheckLyx():
2387 jpye 1470 with_doc_build = False
2388 jpye 1769 without_doc_build_reason="unable to locate LyX"
2389 jpye 1442
2390 jpye 2524 if with_doc_build:
2391     with_latex2html = conf.CheckLatex2HTML()
2392 jpye 1442
2393 jpye 2524 if conf.CheckLModern() is False:
2394     with_doc_build = False
2395     without_doc_build_reason="'lmodern' is not available"
2396 jpye 1701
2397 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
2398    
2399 johnpye 393 # TODO: detect if dynamic libraries are possible or not
2400    
2401 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
2402 johnpye 740 _found_windows_h = conf.CheckHeader('Windows.h')
2403    
2404     if not _found_windows_h:
2405 johnpye 741 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
2406 johnpye 740 Exit(1)
2407 johnpye 741
2408 jpye 1654 if with_python and conf.CheckHeader(['basetsd.h','BaseTsd.h']) is False:
2409 johnpye 427 with_python = 0;
2410     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
2411    
2412 johnpye 395 conf.Finish()
2413    
2414 jpye 2016 #print "-=-=-=-=-=-=-=-=- LIBS =",env.get('LIBS')
2415 jpye 1941
2416 johnpye 507 #---------------------------------------
2417     # SUBSTITUTION DICTIONARY for .in files
2418    
2419 johnpye 658 release = env.get('RELEASE')
2420     if release=="0.":
2421     release="0"
2422    
2423 johnpye 800 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
2424    
2425 johnpye 507 subst_dict = {
2426     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
2427 jpye 1519 ,'@DEFAULT_ASCENDSOLVERS@':env['DEFAULT_ASCENDSOLVERS']
2428 johnpye 507 , '@GLADE_FILE@':'ascend.glade'
2429     , '@HELP_ROOT@':''
2430     , '@ICON_EXTENSION@':icon_extension
2431 johnpye 628 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
2432 johnpye 507 , '@INSTALL_BIN@':env['INSTALL_BIN']
2433     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
2434 johnpye 683 , '@INSTALL_LIB@':env['INSTALL_LIB']
2435 johnpye 721 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
2436 jpye 1504 , '@INSTALL_SOLVERS@':env['INSTALL_SOLVERS']
2437 jpye 2016 , '@INSTALL_PYTHON@':env['INSTALL_PYTHON']
2438 jpye 2307 , '@INSTALL_PYTHON_ASCEND@':env['INSTALL_PYTHON_ASCEND']
2439 johnpye 507 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
2440     , '@VERSION@':version
2441 johnpye 658 , '@RELEASE@':release
2442 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
2443 jpye 1590 , '@WEBHELPROOT@':'http://ascendwiki.cheme.cmu.edu/Category:Documentation'
2444 johnpye 1228 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
2445     , '@SHLIBPREFIX@':env['SHLIBPREFIX']
2446 jpye 1597 , '@EXTLIB_SUFFIX@':env['EXTLIB_SUFFIX']
2447     , '@EXTLIB_PREFIX@':env['EXTLIB_PREFIX']
2448 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
2449 johnpye 683 , '@PYTHON@' : python_exe
2450 jpye 1466 , '@PYVERSION@' : pyversion
2451 johnpye 1174 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
2452 jpye 1680 , '@WITH_GRAPHVIZ@': str(int(env.get('WITH_GRAPHVIZ')))
2453 jpye 2025 #define ASC_ABSOLUTE_PATHS @ASC_ABSOLUTE_PATHS@
2454     #if ASC_ABSOLUTE_PATHS
2455     # define ASCENDDIST_DEFAULT "@ASCENDDIST_DEFAULT@"
2456 jpye 2029 # define ASCENDTK_DEFAULT "@ASCENDTK_DEFAULT@"
2457 jpye 2025 # define ASCENDLIBRARY_DEFAULT "@ASCENDLIBRARY_DEFAULT@"
2458     # define ASCENDSOLVERS_DEFAULT "@ASCENDSOLVERS_DEFAULT@"
2459     #else
2460     # define ASC_DIST_REL_BIN "@ASC_DIST_REL_BIN@"
2461     # define ASC_TK_REL_DIST "@ASC_TK_REL_DIST@"
2462     # define ASC_LIBRARY_REL_DIST "@ASC_LIBRARY_REL_DIST@"
2463     # define ASC_SOLVERS_REL_DIST "@ASC_SOLVERS_REL_DIST@"
2464     #endif
2465     , '@ASC_ABSOLUTE_PATHS@': str(int(env.get('ABSOLUTE_PATHS')))
2466     , '@ASCENDDIST_DEFAULT@': c_escape(env['INSTALL_PREFIX'])
2467     , '@ASCENDTK_DEFAULT@': c_escape(os.path.abspath(env.subst(env['INSTALL_TK'])))
2468     , '@ASCENDLIBRARY_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDLIBRARY'])))
2469     , '@ASCENDSOLVERS_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDSOLVERS'])))
2470     , '@ASC_DIST_REL_BIN@' : default_dist_rel_bin
2471     , '@ASC_TK_REL_DIST@' : default_tk_rel_dist
2472     , '@ASC_LIBRARY_REL_DIST@' : default_library_rel_dist
2473     , '@ASC_SOLVERS_REL_DIST@' : default_solvers_rel_dist
2474 jpye 2037 , '@SIZEOF_VOID_P@' : env['SIZEOF_VOID_P']
2475     , '@SIZEOF_INT@' : env['SIZEOF_INT']
2476     , '@SIZEOF_LONG@' : env['SIZEOF_LONG']
2477     , '@SIZEOF_LONG_LONG@' : env['SIZEOF_LONG_LONG']
2478 jpye 2526 , '@SIZEOF_UINT@' : env['SIZEOF_UINT']
2479     , '@SIZEOF_ULONG@' : env['SIZEOF_ULONG']
2480     , '@SIZEOF_ULONGLONG@' : env['SIZEOF_ULONGLONG']
2481 johnpye 507 }
2482    
2483 jpye 1442 if env.get('WITH_DOC'):
2484 jpye 2524 #print "WITH_DOC:",env['WITH_DOC']
2485 jpye 1442 subst_dict['@HELP_ROOT@']=env['HELP_ROOT']
2486 johnpye 507
2487 johnpye 597 # bool options...
2488 johnpye 673 for k,v in {
2489 jpye 1747 'ASC_WITH_DMALLOC':with_dmalloc
2490 jpye 1326 ,'ASC_WITH_UFSPARSE':with_ufsparse
2491 johnpye 1142 ,'ASC_WITH_MMIO':with_mmio
2492     ,'ASC_SIGNAL_TRAPS':with_signals
2493     ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
2494     ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
2495 johnpye 1261 ,'HAVE_IEEE':env.get('HAVE_IEEE')
2496 johnpye 1142 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
2497     ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
2498 jpye 2354 ,'ASC_HAVE_LEXDESTROY':env.get('HAVE_LEXDESTROY')
2499 jpye 2524 ,'HAVE_SNPRINTF':env.get('HAVE_SNPRINTF')
2500     ,'HAVE__SNPRINTF':env.get('HAVE__SNPRINTF')
2501 johnpye 1142 }.iteritems():
2502    
2503 jpye 2524 if v: subst_dict["/\\* #\\s*define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
2504 johnpye 594
2505 johnpye 507 if with_python:
2506     subst_dict['@ASCXX_USE_PYTHON@']="1"
2507 johnpye 673 env['WITH_PYTHON']=1;
2508 johnpye 507
2509 jpye 1442 if with_latex2html:
2510     env['WITH_LATEX2HTML']=1
2511    
2512 johnpye 507 if env.has_key('HAVE_GCCVISIBILITY'):
2513     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
2514    
2515     env.Append(SUBST_DICT=subst_dict)
2516    
2517 johnpye 1142 #for k,v in subst_dict.iteritems():
2518     # print "%-50s%s" % ("'%s'"%k,v)
2519 johnpye 829
2520 johnpye 1142 # REMOVED: long command-line support on Win2k
2521 johnpye 829
2522     #------------------------------------------------------
2523 johnpye 558 # RECIPE: SWIG scanner
2524    
2525     import SCons.Script
2526    
2527     SWIGScanner = SCons.Scanner.ClassicCPP(
2528     "SWIGScan"
2529     , ".i"
2530     , "CPPPATH"
2531     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
2532     )
2533    
2534     env.Append(SCANNERS=[SWIGScanner])
2535    
2536     #------------------------------------------------------
2537 johnpye 463 # Recipe for 'CHMOD' ACTION
2538 johnpye 439
2539     import SCons
2540     from SCons.Script.SConscript import SConsEnvironment
2541     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
2542     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
2543    
2544     def InstallPerm(env, dest, files, perm):
2545     obj = env.Install(dest, files)
2546     for i in obj:
2547     env.AddPostAction(i, env.Chmod(str(i), perm))
2548 jpye 2007
2549     def InstallPermAs(env, dest, filen, perm):
2550     obj = env.InstallAs(dest, filen)
2551     for i in obj:
2552     env.AddPostAction(i, env.Chmod(str(i), perm))
2553     return dest
2554 johnpye 439
2555     SConsEnvironment.InstallPerm = InstallPerm
2556    
2557     # define wrappers
2558     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
2559 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2560 johnpye 629 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2561 jpye 2076 SConsEnvironment.InstallSharedAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2562 jpye 2007 SConsEnvironment.InstallLibraryAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2563 johnpye 463
2564 johnpye 439 #------------------------------------------------------
2565 johnpye 463 # BUILD...
2566 johnpye 385
2567 jpye 2018 # so that #include <ascend/modulename/headername.h> works across all modules...
2568     env.AppendUnique(CPPPATH=['#'])
2569 johnpye 385
2570 johnpye 508 if env['DEBUG']:
2571 jose 2071 env.Append(
2572     CCFLAGS=['-g']
2573     ,LINKFLAGS=['-g']
2574     )
2575 johnpye 508
2576 johnpye 591 if env['GCOV']:
2577     env.Append(
2578     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
2579     , LIBS=['gcov']
2580     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
2581     )
2582    
2583 jpye 2421 #FIXME there must be a better way of doing this...
2584    
2585 johnpye 673 if with_ida:
2586     env.Append(WITH_IDA=1)
2587    
2588 johnpye 783 if with_conopt:
2589     env.Append(WITH_CONOPT=1)
2590    
2591 jpye 1529 if with_ipopt:
2592     env.Append(WITH_IPOPT=1)
2593    
2594 jpye 1734 if with_dopri5:
2595     env.Append(WITH_DOPRI5=1)
2596    
2597 jpye 2421 if with_radau5:
2598     env.Append(WITH_RADAU5=1)
2599    
2600 jpye 2378 if with_makemps:
2601     env.Append(WITH_MAKEMPS=1)
2602    
2603 jpye 1719 if with_graphviz and env.get('GRAPHVIZ_RPATH'):
2604 jpye 1718 env.Append(RPATH=env['GRAPHVIZ_RPATH'])
2605    
2606 johnpye 463 #-------------
2607     # TCL/TK GUI
2608 johnpye 385
2609 johnpye 551 if with_tcltk:
2610 jpye 2024 env.SConscript(['tcltk/SConscript'],'env')
2611 johnpye 391 else:
2612 johnpye 982 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
2613 johnpye 386
2614 johnpye 463 #-------------
2615     # PYTHON INTERFACE
2616    
2617 johnpye 387 if with_python:
2618 jpye 2327 env.SConscript(['ascxx/SConscript'],'env')
2619 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
2620 johnpye 391 else:
2621 johnpye 982 print "Skipping... Python bindings aren't being built:",without_python_reason
2622 johnpye