/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22