/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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