/[ascend]/branches/georgy/SConstruct
ViewVC logotype

Contents of /branches/georgy/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3105 - (show annotations) (download)
Tue May 24 01:31:12 2016 UTC (8 years, 11 months ago) by jpye
File size: 78382 byte(s)
Creating new branch for [[User:Georgy]] for [[GSOC2016]], from trunk r3104.

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

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