/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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