/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3287 - (show annotations) (download)
Tue Nov 28 05:12:25 2017 UTC (9 months, 3 weeks ago) by jpye
File size: 78905 byte(s)
add test of energyplus format reader.

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

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