/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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