/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3399 - (hide annotations) (download)
Thu Jun 14 08:56:46 2018 UTC (5 months, 1 week ago) by jpye
File size: 81039 byte(s)
add detection of pcre

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