/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3413 - (hide annotations) (download)
Wed Jun 26 09:33:37 2019 UTC (5 months, 2 weeks ago) by jpye
File size: 81072 byte(s)
FPROPS 'cutest' doesn't get built if CUnit not detected via ASCEND.

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