/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3350 - (show annotations) (download)
Wed Apr 4 07:44:06 2018 UTC (7 months, 2 weeks ago) by jpye
File size: 79594 byte(s)
Allow SCons 3.x.
Turn off debug output in test_autodiff.c
Fix line endings for thermo_types.a4c.

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

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