/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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