/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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