/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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