/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2036 - (hide annotations) (download)
Mon May 18 15:03:16 2009 UTC (10 years, 6 months ago) by ballan
File size: 70618 byte(s)
issues resolved:
295
390
301
cmslv.c: unused var cleanup.
lsode/SConscript: fortran flags bugs-- may not work with 0.9x scons.
works with 1.2+. when adding -w, or any special flags, be sure to add
them and not replace the original flag.
system/var.c: 64bit clarity.
system/discrete.c: 64bit clarity.
system/analyze*: g_reuse declared in wrong place. 64bit clarity
system/diffvars: missing prototype function, 64bit clarity.
compiler/numlist.*: changed from int to glint.
compiler/simlist.c: missing includes needed for 64bit clarity.
compiler/instance_io.c: missing includes needed for 64bit clarity.
compiler/initialize.[ch]: const clarifications.
compiler/packages.c: const clarifications.
compiler/module.c: const clarifications.
compiler/statio.c: unused var cleanup.
compiler/procframe; const clarification. memory deallocation bugs.
compiler/notequery.c: repaired multiple casting and 64bit issues.
compiler/importhandler.c: const and free issues fixed.
compiler/type_desc.c: ridiculous if constructs clarified.
compiler/createinst.c: casting stupidity repaired.
linear/ranki2.c: missing includes needed for 64bitness.
solver/solver.c: const issues clarified.
utilities/ascConfig.h: added GLint typedefs for dealing with gllist
64bit portability.
utilities/ascPanic.c: removed extraneous const.
general/ospath.c: safer,quieter handling for string pointer difference.
integrator/integrator.c: const issues clarified.
packages/sensitivity.c: missing includes needed fo 64bit sanity.
tcltk/interface/Integrators.c: 64 bitness.
tcltk/interface/SimsProc.c: const errors.
tcltk/interface/Driver.c: fixed env var handling wrt ascend-config (295)
models/test/z*a4c: fixed meters -> m conversion; someone never ran the
test suite after teasing the default units to ambiguous abbreviations.
SConstruct: added sizeof checks; output might be better put in a ascend
system-wide header.


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