/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2786 - (show annotations) (download)
Wed Jun 25 05:35:51 2014 UTC (4 years, 3 months ago) by jpye
File size: 77426 byte(s)
reinstated RPM build for Fedora 20, tcltk GUI not included sorry
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.9"
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 varprefix = libname.upper()
1181
1182 #print "LIBS is currently:",context.env.get('LIBS')
1183 keep = KeepContext(context,varprefix,static)
1184
1185 if not context.env.has_key(varprefix+'_LIB') and not context.env.has_key(varprefix+'_LIBS'):
1186 # if varprefix_LIB were in env, KeepContext would
1187 # have appended it already
1188 context.env.Append(LIBS=[libname])
1189
1190 is_ok = context.TryLink(text,ext)
1191
1192 #print "Link success? ",(is_ok != 0)
1193
1194 keep.restore(context)
1195
1196 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
1197 # print "Restored LIBS="+str(context.env['LIBS'])
1198 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
1199
1200 context.Result(is_ok)
1201 return is_ok
1202
1203 #----------------
1204 # GCC
1205
1206 gcc_test_text = """
1207 #ifndef __GNUC__
1208 # error "Not using GCC"
1209 #endif
1210
1211 int main(void){
1212 return __GNUC__;
1213 }
1214 """
1215
1216 def CheckGcc(context):
1217 context.Message("Checking for GCC... ")
1218 is_ok = context.TryCompile(gcc_test_text,".c")
1219 context.Result(is_ok)
1220 return is_ok
1221
1222 #----------------
1223 # GCC VISIBILITY feature
1224
1225 gccvisibility_test_text = """
1226 #if __GNUC__ < 4
1227 # error "Require GCC version 4 or newer"
1228 #endif
1229
1230 __attribute__ ((visibility("default"))) int x;
1231
1232 int main(void){
1233 extern int x;
1234 x = 4;
1235 }
1236 """
1237
1238 def CheckGccVisibility(context):
1239 context.Message("Checking for GCC 'visibility' capability... ")
1240 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
1241 context.Result("disabled")
1242 return 0
1243 is_ok = context.TryCompile(gccvisibility_test_text,".c")
1244 context.Result(is_ok)
1245 return is_ok
1246
1247 #----------------
1248 # YACC
1249
1250 yacc_test_text = """
1251 %{
1252 #include <stdio.h>
1253
1254 /* MSVC++ needs this before it can swallow Bison output */
1255 #ifdef _MSC_VER
1256 # define __STDC__
1257 #endif
1258 %}
1259 %token MSG
1260 %start ROOT
1261 %%
1262 ROOT:
1263 MSG { printf("HELLO"); }
1264 ;
1265 %%
1266 """
1267
1268 def CheckYacc(context):
1269 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
1270 is_ok = context.TryCompile(yacc_test_text,".y")
1271 context.Result(is_ok)
1272 return is_ok
1273
1274 #----------------
1275 # LEX
1276
1277 lex_test_text = """
1278 %{
1279 #include <stdio.h>
1280 %}
1281 DIGIT [0-9]
1282 ID [a-z][a-z0-9]*
1283 %%
1284 {DIGIT}+ {
1285 printf("A digit: %s\\n",yytext);
1286 }
1287
1288 [ \\t\\n]+ /* ignore */
1289
1290 . {
1291 printf("Unrecognized guff");
1292 }
1293 %%
1294 main(){
1295 yylex();
1296 }
1297 """
1298
1299 def CheckLex(context):
1300 context.Message("Checking for Lex ('%s')... " % context.env.get('LEX'))
1301 is_ok = context.TryCompile(lex_test_text,".l")
1302 context.Result(is_ok)
1303 return is_ok
1304
1305 lexdestroy_test_text = """
1306 %{
1307 #include <stdio.h>
1308 #include <unistd.h>
1309 %}
1310
1311 %%
1312 username printf("%s", getlogin());
1313 %%
1314
1315 int yywrap(void){
1316 return 1;
1317 }
1318
1319 main(){
1320 //yylex();
1321 yylex_destroy();
1322 }
1323
1324 """
1325
1326 def CheckLexDestroy(context):
1327 context.Message("Checking for yylex_destroy... ")
1328 is_ok, outstring = context.TryRun(lexdestroy_test_text,".l")
1329 context.Result(is_ok)
1330 return is_ok
1331
1332 #----------------
1333 # CUnit test
1334
1335 cunit_test_text = """
1336 #include <CUnit/CUnit.h>
1337 int maxi(int i1, int i2){
1338 return (i1 > i2) ? i1 : i2;
1339 }
1340
1341 void test_maxi(void){
1342 CU_ASSERT(maxi(0,2) == 2);
1343 CU_ASSERT(maxi(0,-2) == 0);
1344 CU_ASSERT(maxi(2,2) == 2);
1345
1346 }
1347 int main(void){
1348 /* CU_initialize_registry() */
1349 return 0;
1350 }
1351 """
1352
1353 def CheckCUnit(context):
1354 return CheckExtLib(context,'cunit',cunit_test_text)
1355
1356 #----------------
1357 # dmalloc test
1358
1359 dmalloc_test_text = """
1360 #include <stdlib.h>
1361 #include <dmalloc.h>
1362
1363 int main(void){
1364 char *c;
1365 c = (char *)malloc(100*sizeof(char));
1366 free(c);
1367 return 0;
1368 }
1369 """
1370
1371 def CheckDMalloc(context):
1372 return CheckExtLib(context,'dmalloc',dmalloc_test_text)
1373
1374 #----------------
1375 # graphviz test
1376
1377 graphviz_test_text = """
1378 #ifdef __WIN32__
1379 # include <gvc.h>
1380 #else
1381 # include <graphviz/gvc.h>
1382 #endif
1383 int main(void){
1384 Agraph_t *g;
1385 GVC_t *gvc;
1386 gvc = gvContext();
1387 g = agopen("g", AGDIGRAPH);
1388 return 0;
1389 }
1390 """
1391
1392 def CheckGraphViz(context):
1393 return CheckExtLib(context,'graphviz',graphviz_test_text,ext=".c")
1394
1395 graphviz_boolean_test = """
1396 #ifdef __WIN32__
1397 # include <types.h>
1398 #else
1399 # include <graphviz/types.h>
1400 #endif
1401 #ifndef GV_TYPES_H
1402 # error WHERE IS GV_TYPES_H?
1403 #endif
1404 int main(void){
1405 boolean x;
1406 x = TRUE;
1407 return 0;
1408 }
1409 """
1410
1411 def CheckGraphVizBoolean(context):
1412 return CheckExtLib(context,'graphviz',graphviz_boolean_test,ext=".c" \
1413 ,testname="graphviz 'boolean' definition"
1414 )
1415
1416 #----------------
1417 # ufsparse test
1418
1419 ufsparse_test_text = """
1420 #include <ufsparse/cs.h>
1421 int main(void){
1422 cs *A,*B,*C;
1423 C = cs_multiply(A,B);
1424 return 0;
1425 }
1426 """
1427
1428 def CheckUFSparse(context):
1429 return CheckExtLib(context
1430 ,libname='cxsparse'
1431 ,varprefix='ufsparse'
1432 ,text=ufsparse_test_text
1433 ,ext=".c"
1434 )
1435
1436 #----------------
1437 # MATH test
1438
1439 math_test_text = """
1440 #ifndef _ALL_SOURCE
1441 # define _ALL_SOURCE
1442 #endif
1443 #ifndef _XOPEN_SOURCE
1444 # define _XOPEN_SOURCE
1445 #endif
1446 #ifndef _XOPEN_SOURCE_EXTENDED
1447 # define _XOPEN_SOURCE_EXTENDED 1
1448 #endif
1449 #include <math.h>
1450 int main(void){
1451 double x = 1.0; double y = 1.0; int i = 1;
1452 acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
1453 j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
1454 y0(x); y1(x); yn(i,x);
1455 /* this part causes problems with crossmingw... */
1456 #ifdef _THREAD_SAFE
1457 gamma_r(x,&i);
1458 lgamma_r(x,&i);
1459 #else
1460 gamma(x);
1461 lgamma(x);
1462 #endif
1463 hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
1464 return 0;
1465 }
1466 """
1467
1468 def CheckMath(context):
1469 context.Message('Checking for IEEE math library... ')
1470 libsave=context.env.get('LIBS');
1471 context.env.AppendUnique(LIBS=['m'])
1472 is_ok=context.TryLink(math_test_text,".c")
1473 context.Result(is_ok)
1474 if libsave is None:
1475 del(context.env['LIBS'])
1476 else:
1477 context.env['LIBS']=libsave
1478 return is_ok
1479
1480 #----------------
1481 # malloc.h test
1482
1483 malloc_test_text = """
1484 #include <stdlib.h>
1485 int main(){
1486 double *x;
1487 x = malloc(sizeof(double)*5);
1488 x[4] = 3.3;
1489 free(x);
1490 }
1491 """
1492
1493 def CheckMalloc(context):
1494 context.Message("Checking for malloc...")
1495 is_ok = context.TryLink(malloc_test_text,".c")
1496 context.Result(is_ok)
1497 return is_ok
1498
1499 #----------------
1500 # dlopen test
1501
1502 dlopen_test_text = """
1503 #ifdef __WIN32__
1504 # include <windows.h>
1505 #else
1506 # include <dlfcn.h>
1507 #endif
1508 int main(){
1509 #ifdef __WIN32__
1510 HINSTANCE d;
1511 LoadLibrary("imaginary_and_nonexistent.dll");
1512 #else
1513 void *d;
1514 d = dlopen("imaginary_and_nonexistent.so", 1);
1515 #endif
1516 return 0;
1517 }
1518 """
1519
1520 def CheckDLOpen(context):
1521 context.Message("Checking for ability to load shared libraries at runtime...")
1522 libsave=context.env.get('LIBS');
1523 if platform.system()!="Windows":
1524 context.env.Append(LIBS=['dl'])
1525 is_ok = context.TryLink(dlopen_test_text,".c")
1526 context.Result(is_ok)
1527 context.env['LIBS'] = libsave
1528 return is_ok
1529
1530 #----------------
1531 # libpython test
1532
1533 libpython_test_text = """
1534 #include <Python.h>
1535 PyObject *get10(void){
1536 PyObject *p = Py_BuildValue("i", 10);
1537 return p;
1538 }
1539 int main(void){
1540 return 0;
1541 }
1542 """
1543
1544 def CheckPythonLib(context):
1545 context.Message('Checking for libpython... ')
1546
1547 if platform.system()=="Windows":
1548 python_lib='python%d%d'
1549 else:
1550 python_lib='python%d.%d'
1551
1552 try:
1553 python_libs = [python_lib % (sys.version_info[0],sys.version_info[1])]
1554 python_cpppath = [distutils.sysconfig.get_python_inc()]
1555 cfig = distutils.sysconfig.get_config_vars()
1556 except:
1557 context.Result("not found")
1558 return 0
1559
1560 lastLIBS = context.env.get('LIBS')
1561 lastLIBPATH = context.env.get('LIBPATH')
1562 lastCPPPATH = context.env.get('CPPPATH')
1563 lastLINKFLAGS = context.env.get('LINKFLAGS')
1564
1565 python_libpath = []
1566 python_linkflags = []
1567 if platform.system()=="Windows":
1568 python_libpath += [os.path.join(sys.prefix,"libs")]
1569 elif platform.system()=="Darwin":
1570 python_libpath += [cfig['LIBPL']]
1571 python_linkflags += cfig['LIBS'].split(' ')
1572 else:
1573 # checked on Linux and SunOS
1574 if cfig['LDLIBRARY']==cfig['LIBRARY']:
1575 sys.stdout.write("(static)")
1576 python_libpath += [cfig['LIBPL']]
1577 python_linkflags += cfig['LIBS'].split(' ')
1578
1579 context.env.AppendUnique(LIBS=python_libs)
1580 context.env.AppendUnique(LIBPATH=python_libpath)
1581 context.env.AppendUnique(CPPPATH=python_cpppath)
1582 context.env.AppendUnique(LINKFLAGS=python_linkflags)
1583 result = context.TryLink(libpython_test_text,".c");
1584
1585 context.Result(result)
1586
1587 if(result):
1588 context.env['PYTHON_LIBPATH']=python_libpath
1589 context.env['PYTHON_LIB']=python_libs
1590 context.env['PYTHON_CPPPATH']=python_cpppath
1591 context.env['PYTHON_LINKFLAGS']=python_linkflags
1592
1593 context.env['LIBS'] = lastLIBS
1594 context.env['LIBPATH'] = lastLIBPATH
1595 context.env['CPPPATH'] = lastCPPPATH
1596 context.env['LINKFLAGS'] = lastLINKFLAGS
1597
1598 return result
1599
1600 #----------------
1601 # IDA test
1602
1603 sundials_version_major_required = 2
1604 sundials_version_minor_min = 4
1605 sundials_version_minor_max = 4
1606
1607 sundials_version_text = """
1608 #include <sundials/sundials_config.h>
1609 #include <stdio.h>
1610 int main(){
1611 printf("%s",SUNDIALS_PACKAGE_VERSION);
1612 return 0;
1613 }
1614 """
1615
1616 ida_test_text = """
1617 #if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR==2
1618 # include <sundials/sundials_config.h>
1619 # include <sundials/sundials_nvector.h>
1620 # include <nvector_serial.h>
1621 # include <ida.h>
1622 # include <ida/ida_spgmr.h>
1623 #else
1624 # include <sundials/sundials_config.h>
1625 # include <nvector/nvector_serial.h>
1626 # include <ida/ida.h>
1627 #endif
1628 int main(){
1629 void *ida_mem;
1630 ida_mem = IDACreate();
1631 return 0;
1632 }
1633 """
1634
1635 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
1636 # so detect the version and act accordingly.
1637 def CheckSUNDIALS(context):
1638 keep = KeepContext(context,'SUNDIALS')
1639 context.Message("Checking for SUNDIALS... ")
1640 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
1641 keep.restore(context)
1642 if not is_ok:
1643 context.Result(0)
1644 return 0
1645
1646 major,minor,patch = tuple([int(i) for i in output.split(".")])
1647 context.env['SUNDIALS_VERSION_MAJOR'] = major
1648 context.env['SUNDIALS_VERSION_MINOR'] = minor
1649 if major != sundials_version_major_required \
1650 or minor < sundials_version_minor_min \
1651 or minor > sundials_version_minor_max:
1652 context.Result(output+" (bad version)")
1653 # bad version
1654 return 0
1655
1656 # good version
1657 context.Result("%d.%d.%d, good" % (major,minor,patch))
1658
1659 return 1
1660
1661
1662 def CheckIDA(context):
1663 context.Message( 'Checking for IDA... ' )
1664
1665 keep = KeepContext(context,"SUNDIALS")
1666
1667 major = context.env['SUNDIALS_VERSION_MAJOR']
1668 minor = context.env['SUNDIALS_VERSION_MINOR']
1669
1670 cppdef = context.env.get('CPPDEFINES')
1671
1672 context.env.Append(CPPDEFINES=[
1673 ('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR")
1674 ,('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")
1675 ])
1676
1677 context.env['SUNDIALS_CPPPATH_EXTRA']=[]
1678 if major==2 and minor==2:
1679 context.env.Append(SUNDIALS_CPPPATH_EXTRA = ["$SUNDIALS_CPPPATH/sundials"])
1680
1681 context.env.Append(CPPDEFINES=[('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR"),('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")])
1682 context.env.AppendUnique(LIBS=context.env['SUNDIALS_LIBS'])
1683 context.env.AppendUnique(CPPPATH=context.env['SUNDIALS_CPPPATH_EXTRA'])
1684
1685 is_ok = context.TryLink(ida_test_text,".c")
1686 context.Result(is_ok)
1687
1688 if cppdef:
1689 context.env['CPPDEFINES']=cppdef
1690 else:
1691 del context.env['CPPDEFINES']
1692
1693 keep.restore(context)
1694
1695 return is_ok
1696
1697
1698 #----------------
1699 # CONOPT test
1700
1701 conopt_test_text = """
1702 #if !defined(_WIN32)
1703 # define FNAME_LCASE_DECOR
1704 #endif
1705
1706 #include <conopt.h>
1707 #include <stdlib.h>
1708 int main(){
1709 int s, *v, e;
1710 s = COIDEF_Size();
1711 v = (int *)malloc(s*sizeof(int));
1712 e = COIDEF_Ini(v);
1713 return e;
1714 }
1715 """
1716
1717 def CheckCONOPT(context):
1718 context.Message( 'Checking for CONOPT... ' )
1719
1720 keep = KeepContext(context,"CONOPT")
1721
1722 is_ok = context.TryLink(conopt_test_text,".c")
1723 context.Result(is_ok)
1724
1725 keep.restore(context)
1726
1727 return is_ok
1728
1729 #----------------
1730 # IPOPT test
1731
1732 ipopt_test_text = """
1733 #if !defined(_WIN32)
1734 # define FNAME_LCASE_DECOR
1735 #endif
1736
1737 #include <coin/IpStdCInterface.h>
1738 int main(){
1739 Number n;
1740 IpoptProblem nlp = 0;
1741 n = 1;
1742 FreeIpoptProblem(nlp); // probably a crash if you run this
1743 return 0;
1744 }
1745 """
1746
1747 def CheckIPOPT(context):
1748 context.Message( 'Checking for IPOPT... ' )
1749
1750 keep = KeepContext(context,"IPOPT")
1751 is_ok = context.TryLink(ipopt_test_text,".c")
1752 context.Result(is_ok)
1753
1754 keep.restore(context)
1755
1756 return is_ok
1757
1758 #----------------
1759 # Tcl test
1760
1761 # TCL and TK required version 8.1 through 8.5:
1762 tcltk_minor_newest_acceptable = 5
1763 tcltk_major_required = 8
1764
1765 tcl_check_text = r"""
1766 #include <tcl.h>
1767 #include <stdio.h>
1768 int main(void){
1769 printf("%s",TCL_PATCH_LEVEL);
1770 return 0;
1771 }
1772 """
1773
1774 def CheckTcl(context):
1775 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
1776
1777 def CheckTclVersion(context):
1778 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
1779 context.Message("Checking Tcl version... ")
1780 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
1781 keep.restore(context)
1782 if not is_ok:
1783 context.Result("failed to run check")
1784 return 0
1785
1786 major,minor,patch = tuple([int(i) for i in output.split(".")])
1787 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1788 context.Result(output+" (bad version)")
1789 # bad version
1790 return 0
1791
1792 # good version
1793 context.Result(output+", good")
1794 return 1
1795
1796 #----------------
1797 # Tk test
1798
1799 tk_check_text = r"""
1800 #include <tk.h>
1801 #include <stdio.h>
1802 int main(void){
1803 printf("%s",TK_PATCH_LEVEL);
1804 return 0;
1805 }
1806 """
1807 def CheckTk(context):
1808 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1809
1810
1811 def CheckTkVersion(context):
1812 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1813 context.Message("Checking Tk version... ")
1814 #print "LINKFLAGS =",context.env['LINKFLAGS']
1815 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1816 keep.restore(context)
1817 if not is_ok:
1818 context.Result("failed to run check")
1819 return 0
1820
1821 major,minor,patch = tuple([int(i) for i in output.split(".")])
1822 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1823 # bad version
1824 context.Result(output+" (bad version)")
1825 return 0
1826
1827 # good version
1828 context.Result(output+" (good)")
1829 return 1
1830
1831 #----------------
1832 # Tktable test
1833
1834 tktable_check_text = r"""
1835 #include <tkTable.h>
1836 #include <stdio.h>
1837 int main(void){
1838 Table mytable;
1839 return 0;
1840 }
1841 """
1842
1843 def CheckTkTable(context):
1844 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1845
1846 #---------------
1847 # X11 test
1848
1849 x11_check_text = r"""
1850 #include <X11/Xlib.h>
1851 #include <X11/IntrinsicP.h>
1852 #include <X11/Intrinsic.h>
1853 #include <X11/ObjectP.h>
1854 #include <X11/Object.h>
1855 int main(void){
1856 Object mything;
1857 return 0;
1858 }
1859 """
1860
1861 def CheckX11(context):
1862 return CheckExtLib(context,'X11',x11_check_text)
1863
1864 #----------------
1865 # Check that we can raise and catch sigint
1866
1867 sigint_test_text = r"""
1868 #include <signal.h>
1869 #include <setjmp.h>
1870 #include <stdlib.h>
1871 static jmp_buf g_jmpenv;
1872 void sighandler(int sig){
1873 longjmp(g_jmpenv,sig);
1874 }
1875 void testsigint(){
1876 raise(SIGINT);
1877 }
1878 int main(void){
1879 signal(SIGINT,&sighandler);
1880 switch(setjmp(g_jmpenv)){
1881 case 0:
1882 testsigint();
1883 exit(1);
1884 case SIGINT:
1885 exit(0);
1886 default:
1887 exit(2);
1888 }
1889 }
1890 """
1891
1892 def CheckSIGINT(context):
1893 context.Message("Checking SIGINT is catchable... ")
1894 (is_ok,output)=context.TryRun(sigint_test_text,".c")
1895 context.Result(is_ok)
1896 return is_ok
1897
1898 #----------------
1899 # Check that we're able to catch floating point errors
1900
1901 sigfpe_test_text = r"""
1902 #include <signal.h>
1903 #include <setjmp.h>
1904 #include <stdlib.h>
1905 #include <fenv.h>
1906 static jmp_buf g_jmpenv;
1907 void fpehandler(int sig){
1908 longjmp(g_jmpenv,sig);
1909 }
1910 int main(void){
1911 fenv_t myfenv;
1912 fegetenv(&myfenv);
1913 fesetenv(&myfenv);
1914 feenableexcept(FE_ALL_EXCEPT);
1915 signal(SIGFPE,&fpehandler);
1916 double x;
1917 switch(setjmp(g_jmpenv)){
1918 case 0:
1919 x = 1.0 / 0.0;
1920 /* failed to catch */
1921 exit(1);
1922 case SIGFPE:
1923 exit(0);
1924 }
1925 }
1926 """
1927
1928 def CheckFPE(context):
1929 context.Message("Checking C99 FPE behaviour... ")
1930 (is_ok,output) = context.TryRun(sigfpe_test_text,'.c')
1931 context.Result(is_ok)
1932 return is_ok
1933
1934 #----------------
1935 # signal reset needed?
1936
1937 sigreset_test_text = r"""
1938 #include <signal.h>
1939 #include <setjmp.h>
1940 #include <stdlib.h>
1941 #include <stdio.h>
1942 typedef void SigHandlerFn(int);
1943 static jmp_buf g_jmpenv;
1944 void sighandler(int sig){
1945 longjmp(g_jmpenv,sig);
1946 }
1947 void testsigint(){
1948 /* fprintf(stderr,"Raising SIGINT\n"); */
1949 raise(SIGINT);
1950 }
1951 int main(void){
1952 SigHandlerFn *last,*saved;
1953 saved = signal(SIGINT,&sighandler);
1954 if(saved!=SIG_DFL){
1955 fprintf(stderr,"Default handler (%p) was not correctly set\n",SIG_DFL);
1956 exit(3);
1957 }
1958 switch(setjmp(g_jmpenv)){
1959 case 0:
1960 testsigint();
1961 fprintf(stderr,"Back from SIGINT\n");
1962 exit(1);
1963 case SIGINT:
1964 break;
1965 default:
1966 exit(2);
1967 };
1968 last = signal(SIGINT,SIG_DFL);
1969 if(last!=&sighandler){
1970 printf("1");
1971 exit(0);
1972 }
1973 printf("0");
1974 exit(0);
1975 }
1976 """
1977
1978 def CheckSigReset(context):
1979 context.Message("Checking signal handler reset... ")
1980 libsave=context.env.get('LIBS')
1981 context.env.AppendUnique(LIBS=['m'])
1982 (is_ok,output) = context.TryRun(sigreset_test_text,'.c')
1983
1984 if libsave is None:
1985 del(context.env['LIBS'])
1986 else:
1987 context.env['LIBS']=libsave
1988
1989 if not is_ok:
1990 context.Result("ERROR")
1991 return False
1992 if int(output)==1:
1993 context.Result("required");
1994 context.env['ASC_RESETNEEDED'] = True
1995 else:
1996 context.Result("not required");
1997 context.env['ASC_RESETNEEDED'] = False
1998 return True
1999
2000 #----------------
2001 # LyX on this system?
2002
2003 def CheckLyx(context):
2004 context.Message("Checking for LyX... ")
2005 r = context.env.WhereIs("lyx")
2006 if r:
2007 context.Result(r)
2008 else:
2009 context.Result(0)
2010 return r
2011
2012 #----------------
2013 # Latex2HTML on this system?
2014
2015 def CheckLatex2HTML(context):
2016 context.Message("Checking for latex2html...")
2017 if context.env.WhereIs("latex2html"):
2018 r = True
2019 else:
2020 r = False
2021 context.Result(r)
2022 return r
2023
2024 #----------------
2025 # Check usable 'erf' function
2026
2027 erf_test_text = r"""
2028 #include <math.h>
2029 int main(){
2030 double x = erf(0.5);
2031 return 0;
2032 }
2033 """
2034 def CheckErf(context):
2035 context.Message("Checking for erf... ")
2036 libsave=context.env.get('LIBS')
2037 context.env.AppendUnique(LIBS=['m'])
2038 (is_ok,output) = context.TryRun(erf_test_text,'.c')
2039 context.Result(is_ok)
2040
2041 #----------------
2042 # GCC Version sniffing
2043
2044 # TODO FIXME
2045
2046 gcc_version4 = False
2047
2048 #------------------------------------------------------
2049 # CONFIGURATION
2050
2051 conf = Configure(env
2052 , custom_tests = {
2053 'CheckCC' : CheckCC
2054 , 'CheckCXX' : CheckCXX
2055 , 'CheckFortran' : CheckFortran
2056 , 'CheckMath' : CheckMath
2057 , 'CheckMalloc' : CheckMalloc
2058 , 'CheckASan' : CheckASan
2059 , 'CheckDLOpen' : CheckDLOpen
2060 , 'CheckSwigVersion' : CheckSwigVersion
2061 , 'CheckPythonLib' : CheckPythonLib
2062 , 'CheckCUnit' : CheckCUnit
2063 , 'CheckDMalloc' : CheckDMalloc
2064 , 'CheckLyx' : CheckLyx
2065 , 'CheckLatex2HTML' : CheckLatex2HTML
2066 , 'CheckGraphViz' : CheckGraphViz
2067 , 'CheckGraphVizBoolean' : CheckGraphVizBoolean
2068 , 'CheckUFSparse' : CheckUFSparse
2069 , 'CheckTcl' : CheckTcl
2070 , 'CheckTclVersion' : CheckTclVersion
2071 , 'CheckTk' : CheckTk
2072 , 'CheckTkVersion' : CheckTkVersion
2073 , 'CheckGcc' : CheckGcc
2074 , 'CheckGccVisibility' : CheckGccVisibility
2075 , 'CheckYacc' : CheckYacc
2076 , 'CheckLex' : CheckLex
2077 , 'CheckLexDestroy' : CheckLexDestroy
2078 , 'CheckTkTable' : CheckTkTable
2079 , 'CheckX11' : CheckX11
2080 , 'CheckIDA' : CheckIDA
2081 , 'CheckSUNDIALS' : CheckSUNDIALS
2082 , 'CheckCONOPT' : CheckCONOPT
2083 , 'CheckIPOPT' : CheckIPOPT
2084 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
2085 , 'CheckFPE' : CheckFPE
2086 , 'CheckSIGINT' : CheckSIGINT
2087 , 'CheckSigReset' : CheckSigReset
2088 , 'CheckErf' : CheckErf
2089 # , 'CheckIsNan' : CheckIsNan
2090 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
2091 }
2092 # , config_h = "config.h"
2093 )
2094
2095 def sconsversioncheck():
2096
2097 # uncomment the following line to skip the version check:
2098 # return 1
2099
2100 import SCons
2101 v = SCons.__version__.split(".")
2102 if v[0] != '0':
2103 if v[0] == '1' or v[0] == '2':
2104 return 1;
2105 return 0
2106 if int(v[1]) >= 97:
2107 return 1
2108 if v[1] != '96':
2109 return 0
2110 micro = int(v[2])
2111 if micro == 92 or micro == 93 or micro == 96:
2112 return 1;
2113 return 0
2114
2115 if not sconsversioncheck():
2116 print "Scons version is not OK. Please try version 0.96.92 or 0.96.93,"
2117 print "or consult the developers in the case of newer versions. Modify"
2118 print "the function 'sconsversioncheck' in the file SConstruct if you"
2119 print "want to *force* SCons to continue."
2120 Exit(1)
2121
2122 # check C compiler
2123
2124 if conf.CheckCC() is False:
2125 print "Failed to build simple test file with your C compiler."
2126 print "Check your compiler is installed and running correctly."
2127 Exit(1)
2128
2129 if conf.CheckCXX() is False:
2130 print "Failed to build simple test file with your C++ compiler."
2131 print "Check your compiler is installed and running correctly."
2132 print "You can set your C++ compiler using the CXX scons option."
2133 Exit(1)
2134
2135 if conf.CheckASan() is False:
2136 conf.env['HAVE_ASAN'] = True
2137 else:
2138 conf.env['HAVE_ASAN'] = False
2139
2140 # stdio -- just to check that compiler is behaving
2141
2142 if conf.CheckHeader('stdio.h') is False:
2143 print "CPPPATH =",env.get('CPPPATH')
2144 print "Did not find 'stdio.h'! Check your compiler configuration."
2145 print ""
2146 print "You environment is printed here:"
2147 for k,v in os.environ.iteritems():
2148 print "%-30s%s" % ("%s :" % k, v)
2149 Exit(1)
2150
2151 # sizes of vars used in libascend eg in gl_list etc.
2152
2153 _sizes = {
2154 "VOID_P" : "void *"
2155 ,"INT" : "int"
2156 ,"LONG" : "long"
2157 ,"LONG_LONG" : "long long"
2158 ,"UINT" : "unsigned int"
2159 ,"ULONG" : "unsigned long"
2160 ,"ULONGLONG" : "unsigned long long"
2161 }
2162
2163 for _var,_type in _sizes.iteritems():
2164 _size = conf.CheckTypeSize(_type)
2165 if not _size:
2166 print "Couldn't determine 'sizeof(%s)'" % _type
2167 Exit(1)
2168 conf.env["SIZEOF_%s" % _var] = str(_size)
2169
2170 # check for some string functions
2171
2172 if conf.CheckFunc('sprintf') is False:
2173 print "Didn't find sprintf";
2174 Exit(1)
2175
2176 if conf.CheckErf() is False:
2177 print "Didn't find erf";
2178 Exit(1)
2179 else:
2180 conf.env['HAVE_ERF'] = True
2181
2182 if conf.CheckFunc('strdup'):
2183 conf.env['HAVE_STRDUP'] = True
2184
2185 if conf.CheckFunc('snprintf'):
2186 conf.env['HAVE_SNPRINTF'] = True
2187 elif conf.CheckFunc('_snprintf'):
2188 conf.env['HAVE__SNPRINTF'] = True
2189
2190 if conf.CheckFunc('cpow'):
2191 conf.env['HAVE_CPOW'] = True
2192
2193 # attempt to support MSVCRT 7.1 on Windows
2194
2195 if platform.system()=="Windows" and env.get('WITH_MSVCR71'):
2196 conf.env.Append(LIBS='msvcr71')
2197
2198 # Math library
2199
2200 conf.env['HAVE_IEEE']=True
2201
2202 if need_libm and (conf.CheckMath() is False):
2203 conf.env['HAVE_IEEE']=False
2204 print 'Did not find math library, exiting!'
2205 Exit(1)
2206
2207 # Malloc
2208
2209 if conf.CheckMalloc() is False:
2210 conf.env['HAVE_MALLOC']=False
2211 print "Did not find functioning 'malloc', exiting!"
2212 Exit(1)
2213
2214 # dlopen/LoadLibrary
2215
2216 # CURRENTLY BREAKS LATER TEST (libsave?)
2217 #if conf.CheckDLOpen() is False:
2218 # print "Did not find functioning dlopen/LoadLibrary, exiting!"
2219 # Exit(1)
2220
2221 # Where is 'isnan'?
2222
2223 if conf.CheckFunc('isnan') is False and conf.CheckFunc('_isnan') is False:
2224 print "Didn't find isnan"
2225 # Exit(1)
2226
2227 # GCC visibility
2228
2229 if conf.CheckGcc():
2230 conf.env['HAVE_GCC']=True;
2231 if env.get('WITH_GCCVISIBILITY') and conf.CheckGccVisibility():
2232 conf.env['HAVE_GCCVISIBILITY']=True;
2233 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
2234 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
2235 conf.env.Append(CCFLAGS=['-Wall'])
2236
2237 # Catching SIGINT
2238
2239 if env['WITH_SIGNALS']:
2240 if not conf.CheckSIGINT():
2241 with_signals = False
2242 without_signals_reason = "SIGINT uncatchable"
2243
2244 # Catching SIGFPE
2245
2246 if conf.CheckFPE():
2247 conf.env['HAVE_C99FPE']=True
2248 else:
2249 conf.env['HAVE_C99FPE']=False
2250
2251 # Checking for signal reset requirement
2252
2253 if conf.CheckSigReset() is False:
2254 print "Unable to determine if signal reset is required"
2255 Exit(1)
2256
2257 # YACC
2258
2259 if conf.CheckYacc():
2260 conf.env['HAVE_YACC']=True
2261
2262 if conf.CheckLex():
2263 conf.env['HAVE_LEX']=True
2264
2265 if conf.CheckLexDestroy():
2266 conf.env['HAVE_LEXDESTROY']=True
2267
2268 # Tcl/Tk
2269
2270 if with_tcltk:
2271 if conf.CheckTcl():
2272 if conf.CheckTclVersion():
2273 if conf.CheckTk():
2274 if with_tcltk and conf.CheckTkVersion():
2275 if env['STATIC_TCLTK']:
2276 if conf.CheckTkTable():
2277 pass
2278 else:
2279 without_tcltk_reason = "TkTable not found"
2280 with_tcltk = False
2281 else:
2282 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
2283 with_tcltk = False
2284 else:
2285 without_tcltk_reason = "Tk not found."
2286 with_tcltk = False
2287 else:
2288 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
2289 with_tcltk = False
2290
2291 else:
2292 without_tcltk_reason = "Tcl not found."
2293 with_tcltk = False
2294
2295 if env['STATIC_TCLTK']:
2296 conf.CheckX11()
2297
2298 # Python... obviously we're already running python, so we just need to
2299 # check that we can link to the python library OK:
2300
2301 if not conf.CheckPythonLib():
2302 without_python_reason = 'libpython2.x not found or not linkable'
2303 with_python = False
2304 env['WITH_PYTHON']=False
2305
2306 # SWIG version
2307
2308 if with_python and conf.CheckSwigVersion() is False:
2309 without_python_reason = 'SWIG >= 1.3.24 is required'
2310 with_python = False
2311 env['WITH_PYTHON']=False
2312
2313 # CUnit
2314
2315 if with_cunit:
2316 if not conf.CheckCUnit():
2317 without_cunit_reason = 'CUnit not found'
2318 with_cunit = False
2319 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
2320
2321 # DMALLOC
2322
2323 if with_dmalloc:
2324 if not conf.CheckDMalloc():
2325 without_dmalloc_reason = 'dmalloc not found'
2326 with_dmalloc = False
2327
2328 # GRAPHVIZ
2329
2330 if with_graphviz:
2331 if not conf.CheckGraphViz():
2332 without_graphviz_reason = 'graphviz not found'
2333 with_graphviz = False
2334 env['WITH_GRAPHVIZ'] = False
2335 env['HAVE_GRAPHVIZ_BOOLEAN'] = conf.CheckGraphVizBoolean()
2336
2337 # UFSPARSE
2338
2339 if with_ufsparse:
2340 if not conf.CheckUFSparse():
2341 without_ufsparse_reason = 'ufsparse not found'
2342 with_ufsparse = False
2343 env['WITH_UFSPARSE'] = False
2344
2345 # IDA
2346
2347 if with_ida:
2348 if not conf.CheckSUNDIALS():
2349 with_ida = False
2350 without_ida_reason = "SUNDIALS not found, or bad version"
2351 elif not conf.CheckIDA():
2352 with_ida = False
2353 without_ida_reason = "Unable to compile/link against SUNDIALS/IDA"
2354
2355 # CONOPT
2356
2357 if not with_conopt:
2358 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
2359 elif conf.CheckCONOPT() is False:
2360 if conf.env.get('CONOPT_LINKED'):
2361 conf.env['CONOPT_LINKED'] = False
2362 # we no longer require CONOPT at buildtime in order to build support for it
2363 #with_conopt = False
2364 #without_conpt_reason = "CONOPT not found"
2365
2366 # IPOPT
2367
2368 if not with_ipopt:
2369 without_ipopt_reason = "Not selected (see config option WITH_SOLVERS)"
2370 elif not conf.CheckIPOPT():
2371 with_ipopt = False
2372 without_ipopt_reason = "IPOPT not found"
2373
2374 # BLAS
2375
2376 need_blas=False
2377
2378 if with_lsode:
2379 need_fortran = True
2380 need_fortran_reasons.append("LSODE")
2381 need_blas=True
2382
2383 if with_ipopt:
2384 need_blas=True
2385
2386 if need_blas:
2387 if conf.CheckLib('blas'):
2388 with_local_blas = False
2389 without_local_blas_reason = "Found BLAS installed on system"
2390 else:
2391 with_local_blas = True
2392 need_fortran = True
2393 need_fortran_reasons.append("BLAS")
2394 else:
2395 with_local_blas= False;
2396 without_local_blas_reason = "BLAS not required"
2397
2398 # FORTRAN
2399
2400 # we'll assume now (2012) that we always have gfortran available on our system.
2401
2402 if need_fortran and conf.CheckFortran() is False:
2403 print "Failed to build simple test file with your Fortran compiler."
2404 print "Check your compiler is installed and running correctly."
2405 print "You can set your Fortran compiler using the FORTRAN scons option."
2406 print "The fortran compiler is REQUIRED to build:",", ".join(need_fortran_reasons)
2407 print "Perhaps try examining the value of your WITH_SOLVERS option (remove LSODE, etc)."
2408 Exit(1)
2409
2410 #else:
2411 # print "FORTRAN not required"
2412
2413 # F2C
2414
2415 if need_fortran:
2416 if platform.system()=="Windows":
2417 pass
2418 #conf.env.Append(LIBPATH='c:\mingw\lib')
2419
2420 # scrollkeeper
2421
2422 if with_scrollkeeper:
2423 if conf.CheckScrollkeeperConfig() is False:
2424 with_scrollkeeper=False
2425 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
2426
2427 # lyx
2428
2429 if with_doc_build:
2430 if not conf.CheckLyx():
2431 with_doc_build = False
2432 without_doc_build_reason="unable to locate LyX"
2433
2434 # TODO: -D_HPUX_SOURCE is needed
2435
2436 # TODO: detect if dynamic libraries are possible or not
2437
2438 if platform.system()=="Windows" and env.has_key('MSVS'):
2439 _found_windows_h = conf.CheckHeader('Windows.h')
2440
2441 if not _found_windows_h:
2442 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
2443 Exit(1)
2444
2445 if with_python and conf.CheckHeader(['basetsd.h','BaseTsd.h']) is False:
2446 with_python = 0;
2447 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
2448
2449 conf.Finish()
2450
2451 #print "-=-=-=-=-=-=-=-=- LIBS =",env.get('LIBS')
2452
2453 #---------------------------------------
2454 # SUBSTITUTION DICTIONARY for .in files
2455
2456 release = env.get('RELEASE')
2457 if release=="0.":
2458 release="0"
2459
2460 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
2461
2462 subst_dict = {
2463 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
2464 ,'@DEFAULT_ASCENDSOLVERS@':env['DEFAULT_ASCENDSOLVERS']
2465 , '@GLADE_FILE@':'ascend.glade'
2466 , '@HELP_ROOT@':''
2467 , '@ICON_EXTENSION@':icon_extension
2468 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
2469 , '@INSTALL_BIN@':env['INSTALL_BIN']
2470 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
2471 , '@INSTALL_LIB@':env['INSTALL_LIB']
2472 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
2473 , '@INSTALL_SOLVERS@':env['INSTALL_SOLVERS']
2474 , '@INSTALL_PYTHON@':env['INSTALL_PYTHON']
2475 , '@INSTALL_PYTHON_ASCEND@':env['INSTALL_PYTHON_ASCEND']
2476 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
2477 , '@VERSION@':version
2478 , '@RELEASE@':release
2479 , '@SONAME_MAJOR_INT@':soname_major_int
2480 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
2481 , '@WEBHELPROOT@':'http://ascendwiki.cheme.cmu.edu/Category:Documentation'
2482 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
2483 , '@SHLIBPREFIX@':env['SHLIBPREFIX']
2484 , '@EXTLIB_SUFFIX@':env['EXTLIB_SUFFIX']
2485 , '@EXTLIB_PREFIX@':env['EXTLIB_PREFIX']
2486 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
2487 , '@PYTHON@' : python_exe
2488 , '@PYVERSION@' : pyversion
2489 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
2490 , '@WITH_GRAPHVIZ@': str(int(env.get('WITH_GRAPHVIZ')))
2491 #define ASC_ABSOLUTE_PATHS @ASC_ABSOLUTE_PATHS@
2492 #if ASC_ABSOLUTE_PATHS
2493 # define ASCENDDIST_DEFAULT "@ASCENDDIST_DEFAULT@"
2494 # define ASCENDTK_DEFAULT "@ASCENDTK_DEFAULT@"
2495 # define ASCENDLIBRARY_DEFAULT "@ASCENDLIBRARY_DEFAULT@"
2496 # define ASCENDSOLVERS_DEFAULT "@ASCENDSOLVERS_DEFAULT@"
2497 #else
2498 # define ASC_DIST_REL_BIN "@ASC_DIST_REL_BIN@"
2499 # define ASC_TK_REL_DIST "@ASC_TK_REL_DIST@"
2500 # define ASC_LIBRARY_REL_DIST "@ASC_LIBRARY_REL_DIST@"
2501 # define ASC_SOLVERS_REL_DIST "@ASC_SOLVERS_REL_DIST@"
2502 #endif
2503 , '@ASC_ABSOLUTE_PATHS@': str(int(env.get('ABSOLUTE_PATHS')))
2504 , '@ASCENDDIST_DEFAULT@': c_escape(env['INSTALL_PREFIX'])
2505 , '@ASCENDTK_DEFAULT@': c_escape(os.path.abspath(env.subst(env['INSTALL_TK'])))
2506 , '@ASCENDLIBRARY_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDLIBRARY'])))
2507 , '@ASCENDSOLVERS_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDSOLVERS'])))
2508 , '@ASC_DIST_REL_BIN@' : default_dist_rel_bin
2509 , '@ASC_TK_REL_DIST@' : default_tk_rel_dist
2510 , '@ASC_LIBRARY_REL_DIST@' : default_library_rel_dist
2511 , '@ASC_SOLVERS_REL_DIST@' : default_solvers_rel_dist
2512 , '@SIZEOF_VOID_P@' : env['SIZEOF_VOID_P']
2513 , '@SIZEOF_INT@' : env['SIZEOF_INT']
2514 , '@SIZEOF_LONG@' : env['SIZEOF_LONG']
2515 , '@SIZEOF_LONG_LONG@' : env['SIZEOF_LONG_LONG']
2516 , '@SIZEOF_UINT@' : env['SIZEOF_UINT']
2517 , '@SIZEOF_ULONG@' : env['SIZEOF_ULONG']
2518 , '@SIZEOF_ULONGLONG@' : env['SIZEOF_ULONGLONG']
2519 }
2520
2521 if env.get('WITH_DOC'):
2522 #print "WITH_DOC:",env['WITH_DOC']
2523 subst_dict['@HELP_ROOT@']=env['HELP_ROOT']
2524
2525 # bool options...
2526 for k,v in {
2527 'ASC_WITH_DMALLOC':with_dmalloc
2528 ,'ASC_WITH_UFSPARSE':with_ufsparse
2529 ,'ASC_WITH_MMIO':with_mmio
2530 ,'ASC_SIGNAL_TRAPS':with_signals
2531 ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
2532 ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
2533 ,'HAVE_IEEE':env.get('HAVE_IEEE')
2534 ,'HAVE_ERF':env.get('HAVE_ERF')
2535 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
2536 ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
2537 ,'ASC_HAVE_LEXDESTROY':env.get('HAVE_LEXDESTROY')
2538 ,'HAVE_SNPRINTF':env.get('HAVE_SNPRINTF')
2539 ,'HAVE__SNPRINTF':env.get('HAVE__SNPRINTF')
2540 }.iteritems():
2541
2542 if v: subst_dict["/\\* #\\s*define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
2543
2544 if with_python:
2545 subst_dict['@ASCXX_USE_PYTHON@']="1"
2546 env['WITH_PYTHON']=1;
2547
2548 if with_latex2html:
2549 env['WITH_LATEX2HTML']=1
2550
2551 if env.has_key('HAVE_GCCVISIBILITY'):
2552 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
2553
2554 env.Append(SUBST_DICT=subst_dict)
2555
2556 #for k,v in subst_dict.iteritems():
2557 # print "%-50s%s" % ("'%s'"%k,v)
2558
2559 # REMOVED: long command-line support on Win2k
2560
2561 #------------------------------------------------------
2562 # RECIPE: SWIG scanner
2563
2564 import SCons.Script
2565
2566 SWIGScanner = SCons.Scanner.ClassicCPP(
2567 "SWIGScan"
2568 , ".i"
2569 , "CPPPATH"
2570 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
2571 )
2572
2573 env.Append(SCANNERS=[SWIGScanner])
2574
2575 #------------------------------------------------------
2576 # Recipe for 'CHMOD' ACTION
2577
2578 import SCons
2579 from SCons.Script.SConscript import SConsEnvironment
2580 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
2581 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
2582
2583 def InstallPerm(env, dest, files, perm):
2584 obj = env.Install(dest, files)
2585 for i in obj:
2586 env.AddPostAction(i, env.Chmod(str(i), perm))
2587
2588 def InstallPermAs(env, dest, filen, perm):
2589 obj = env.InstallAs(dest, filen)
2590 for i in obj:
2591 env.AddPostAction(i, env.Chmod(str(i), perm))
2592 return dest
2593
2594 SConsEnvironment.InstallPerm = InstallPerm
2595
2596 # define wrappers
2597 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
2598 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2599 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2600 SConsEnvironment.InstallSharedAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2601 SConsEnvironment.InstallLibraryAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2602
2603 #------------------------------------------------------
2604 # BUILD...
2605
2606 # so that #include <ascend/modulename/headername.h> works across all modules...
2607 env.AppendUnique(CPPPATH=['#'])
2608
2609 if env['DEBUG']:
2610 env.Append(
2611 CCFLAGS=['-g']
2612 ,LINKFLAGS=['-g']
2613 )
2614
2615 if env['GCOV']:
2616 env.Append(
2617 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
2618 , LIBS=['gcov']
2619 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
2620 )
2621
2622 #FIXME there must be a better way of doing this...
2623
2624 if with_ida:
2625 env.Append(WITH_IDA=1)
2626
2627 if with_conopt:
2628 env.Append(WITH_CONOPT=1)
2629
2630 if with_ipopt:
2631 env.Append(WITH_IPOPT=1)
2632
2633 if with_dopri5:
2634 env.Append(WITH_DOPRI5=1)
2635
2636 if with_radau5:
2637 env.Append(WITH_RADAU5=1)
2638
2639 if with_makemps:
2640 env.Append(WITH_MAKEMPS=1)
2641
2642 if with_graphviz and env.get('GRAPHVIZ_RPATH'):
2643 env.Append(RPATH=env['GRAPHVIZ_RPATH'])
2644
2645 #-------------
2646 # TCL/TK GUI
2647
2648 if with_tcltk:
2649 env.SConscript(['tcltk/SConscript'],'env')
2650 else:
2651 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
2652
2653 #-------------
2654 # PYTHON INTERFACE
2655
2656 if with_python:
2657 env.SConscript(['ascxx/SConscript'],'env')
2658 env.SConscript(['pygtk/SConscript'],'env')
2659 else:
2660 print "Skipping... Python bindings aren't being built:",without_python_reason
2661
2662 #------------
2663 # BASE/GENERIC SUBDIRECTORIES
2664
2665 libascend_env = env.Clone()
2666
2667 dirs = ['general','utilities','compiler','system','solver','integrator','packages','linear']
2668
2669 srcs = []
2670 for d in dirs:
2671 heresrcs = libascend_env.SConscript('ascend/'+d+'/SConscript','libascend_env')
2672 srcs += heresrcs
2673
2674 #-------------
2675 # IMPORTED CODE: LSODE, BLAS, etc
2676
2677 if with_local_blas:
2678 env['blasobjs'] = env.SConscript(['blas/SConscript'],'env')
2679 else:
2680 env['blasobjs'] = []
2681 print "Skipping... BLAS won't be built:", without_local_blas_reason
2682
2683 if not with_ida:
2684 print "Skipping... IDA won't be built:", without_ida_reason
2685
2686 if not with_dopri5:
2687 print "Skipping... DOPRI5 won't be built:", without_dopri5_reason
2688
2689 if with_mmio:
2690 srcs += env.SConscript(['mmio/SConscript'],'env')
2691 else:
2692 print "Skipping... MMIO export won't be built:", without_mmio_reason
2693 #-------------
2694 # LIBASCEND -- all 'core' functionality
2695
2696 # FIXME want to move these bits to ascend/SConscript
2697
2698 libascend_env.Append(
2699 CPPPATH=['#']
2700 ,LIBS=['m']
2701 )
2702
2703 if platform.system()=="Linux":
2704 libascend_env.Append(LIBS=['dl'])
2705
2706 if with_dmalloc:
2707 libascend_env.Append(LIBS=['dmalloc'])
2708
2709 if with_ufsparse:
2710 libascend_env.Append(LIBS=['cxsparse'])
2711
2712 if platform.system()=="Linux":
2713 libascend_env.Append(LINKFLAGS=['-Wl,-soname,%s' % soname_full])
2714
2715 libascend = libascend_env.SharedLibrary('ascend',srcs)
2716
2717 # create local symlink for the soname stuff.
2718 #print "SONAME =",env.subst(soname_full)
2719
2720 env['libascend'] = libascend
2721 libtargets = [libascend]
2722
2723 if platform.system()=="Linux":
2724 if soname_major:
2725 libascend_env.Command(soname_full,libascend,Move("$TARGET","$SOURCE"))
2726 #print "MAKING LINK, SONAME_MAJOR =",soname_major
2727 liblink = libascend_env.Command(soname_full, libascend, "ln -s $SOURCE $TARGET")
2728 libtargets.append(liblink)
2729
2730 # for use in declaring dependent shared libraries in SConscript files (eg solvers/*/SConscript)
2731
2732 env.Alias('libascend',libtargets)
2733
2734 #-------------
2735 # UNIT TESTS (C CODE)
2736
2737 test_env = env.Clone()
2738 test_env.Append(
2739 CPPPATH="#"
2740 )
2741
2742 if with_cunit:
2743 testdirs = ['general','solver','utilities','linear','compiler','system','packages','integrator']
2744 testsrcs = []
2745 for testdir in testdirs:
2746 path = 'ascend/'+testdir+'/test/'
2747 test_env.SConscript([path+'SConscript'],'test_env')
2748 testsrcs += [i.path for i in test_env['TESTSRCS_'+testdir.upper()]]
2749 test_env['TESTDIRS'] = testdirs
2750
2751 #print "TESTSRCS =",testsrcs
2752
2753 test_env.SConscript(['test/SConscript'],'test_env')
2754
2755 env.Alias('test',[env.Dir('test')])
2756
2757 else:
2758 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
2759
2760 #-------------
2761 # EXTERNAL SOLVERS
2762
2763 env['extfns']=[]
2764 env['BUILDING_ASCEND'] = 1
2765
2766 env.SConscript(['solvers/SConscript'],'env')
2767
2768 #-------------
2769 # EXTERNAL FUNCTIONS
2770
2771 modeldirs = env.SConscript(['models/SConscript'],'env')
2772
2773 if not with_extfns:
2774 print "Skipping... External modules aren't being built:",without_extfns_reason
2775
2776 for _f in env['extfns']:
2777 env.Depends(_f,'libascend')
2778 env.Alias('extfns',env['extfns'])
2779
2780 #-------------
2781 # FPROPS python bindings
2782
2783 env.Alias('pyfprops',env.get('pyfprops'))
2784
2785 #------------------------------------------------------
2786 # CREATE ASCEND-CONFIG scriptlet
2787
2788 ascendconfig = env.SubstInFile('ascend-config.in')
2789
2790 #------------------------------------------------------
2791 # INSTALLATION
2792
2793 if env.get('CAN_INSTALL'):
2794
2795 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE','INSTALL_DOC','INSTALL_PYTHON']
2796 install_dirs = [Dir(env.subst("$INSTALL_ROOT$"+d)) for d in dirs]
2797 install_dirs += modeldirs + [Dir(env.subst("$INSTALL_ROOT$INSTALL_SOLVERS"))]
2798
2799 #env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_LIB")),libascend)
2800
2801 libname = "${INSTALL_LIB}/%s%s" % (soname_full,soname_minor)
2802 install_lib = env.InstallLibraryAs("${INSTALL_ROOT}"+libname, [libascend])
2803 if env['ABSOLUTE_PATHS']:
2804 link_target = libname
2805 else:
2806 link_target = "%s%s" % (soname_full,soname_minor)
2807
2808 link1 = "${INSTALL_LIB}/%s" % soname_clean
2809 install_link1 = None
2810 if env.subst(link1) != env.subst(libname):
2811 # v--link to create v--file to link to command
2812 install_link1 = env.Command("${INSTALL_ROOT}"+link1,install_lib
2813 # v-- command to do it (note the trick about
2814 ,"ln -f -s %s $TARGET" % link_target
2815 )
2816
2817 link2 = "${INSTALL_LIB}/%s" % soname_full
2818 install_link2 = None
2819 if soname_minor:
2820 install_link2 = env.Command("${INSTALL_ROOT}"+link2,install_lib
2821 ,"ln -f -s %s $TARGET" % link_target
2822 )
2823
2824 env.InstallProgram(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN")),ascendconfig)
2825
2826 # MAC OS X INSTALL STUFF
2827 # in this case, we're installing to INSTALL_PREFIX, assumed to be a folder
2828 # created using Disk Utility as a new DMG which will be distributed.
2829 if platform.system()=="Darwin":
2830 # extra stuff for inside the .app
2831 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN")),"mac/Info.plist")
2832 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN/Resources/")),"mac/ascend.icns")
2833
2834 # related files the .dmg folder
2835 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"README-osx.txt")
2836 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"LICENSE.txt")
2837 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"CHANGELOG.txt")
2838 env.Command("$INSTALL_ROOT$INSTALL_PREFIX/Applications Folder","/Applications","ln -f -s $SOURCE $TARGET")
2839 install_dirs += [Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX"))]
2840
2841 # GTK libraries and related files
2842 gtkfiles = []
2843 gtksource = "dist/PyGTK.bundle/"
2844 def visit(gtkfiles,dirname,fnames):
2845 gtkfiles += Glob("%s/*" % dirname)
2846 os.path.walk(gtksource,visit,gtkfiles)
2847
2848 #print "GTKFILES ="
2849 #
2850 for f in gtkfiles:
2851 r = os.path.commonprefix([gtksource,f.path])
2852 dirname,filename = os.path.split(f.path[len(r):])
2853 dest = os.path.join(env.subst("$INSTALL_ROOT$INSTALL_BIN/PyGTK.bundle"),dirname)
2854 # print "%s --> %s" %(f,dest)
2855 env.Install(Dir(dest),f)
2856
2857 # ALIAS FOR ALL INSTALLATION
2858 env.Alias('install',install_dirs)
2859
2860 #------------------------------------------------------
2861 # WINDOWS INSTALLER
2862
2863 if not env.get('NSIS'):
2864 with_installer = False
2865 without_installer_reason = "NSIS not found"
2866
2867 if with_installer:
2868 pyarch = ""
2869 instarch = "win32"
2870 if platform.architecture()[0] == "64bit":
2871 instarch = "x64"
2872 pyarch = ".amd64"
2873 inst64 = 1
2874 nsisdefs = {
2875 'OUTFILE':"#dist/$WIN_INSTALLER_NAME"
2876 ,"VERSION":version
2877 ,'PYVERSION':pyversion
2878 ,'PYPATCH':".%d"%sys.version_info[2]
2879 ,'PYARCH':str(pyarch)
2880 ,'INSTARCH':str(instarch)
2881 }
2882 # support up to 5 extra dependency DLLs to accompany IPOPT
2883 for i in range(5):
2884 _fl = ''; _dl = ''
2885 if env.get('IPOPT_DLL%d'%(i+1)):
2886 _fl = "File %s"%os.path.normcase(os.path.normpath(env.subst("$IPOPT_DLL%d"%(i+1))))
2887 _dl = "Delete \"$$INSTDIR\\%s\""%os.path.split(env.subst("$IPOPT_DLL%d"%(i+1)))[1]
2888 nsisdefs['FILE_IPOPT_%d'%(i+1)] = _fl
2889 nsisdefs['DEL_IPOPT_%d'%(i+1)] = _dl
2890 env.Append(NSISDEFINES=nsisdefs)
2891 installer = env.Installer('nsis/installer.nsi')
2892
2893 for i in range(5):
2894 if env.get('IPOPT_DLL%d'%(i+1)):
2895 env.Depends(installer,env['IPOPT_DLL%d'%(i+1)])
2896
2897 env.Depends(installer,["pygtk","ascxx","tcltk","ascend.dll","models","solvers","ascend-config",'pygtk/ascend'])
2898 env.Depends(installer,"doc/book.pdf")
2899 env.Depends(installer,["nsis/detect.nsi","nsis/dependencies.nsi","nsis/download.nsi"])
2900 env.Alias('installer',installer)
2901 else:
2902 print "Skipping... Windows installer isn't being built:",without_installer_reason
2903
2904 #------------------------------------------------------
2905 # CREATE the SPEC file for generation of RPM packages
2906
2907 if platform.system()=="Linux":
2908 env.SubstInFile('ascend.spec.in')
2909
2910 #------------------------------------------------------
2911 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
2912
2913 #if with_scrollkeeper:
2914 # #env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
2915 # #env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
2916
2917 #------------------------------------------------------
2918 # DISTRIBUTION TAR FILE
2919
2920 env['DISTTAR_FORMAT']='bz2'
2921 env.Append(
2922 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.lib','.cc','.cache',
2923 '.pyc','.cvsignore','.dblite','.log','.pl','.out','.exe','.aux','.idx',
2924 '.toc','.lof','.lot','.mm','.warnings','.tm2','.swp',',tmp','.gz',
2925 '.bz2','.7z','.deb','.dsc','.changes','.bak','.tex','.tmp','.def']
2926 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist','debian','doxy']
2927 , DISTTAR_EXCLUDERES=[r"_wrap\.cc?$", r"~$", r"ascxx/ascpy\.py","ascxx/testipopt$"
2928 ,r"/lib.*\.so\.[.0-9]+$", r"tcltk/asc4dev$", r"tcltk/interface/typelex\.c$"
2929 ,r"ascend/compiler/ascParse\.[ch]$", r"ascend/solver/conoptconfig\.h$"
2930 ,r"ascend/utilities/config\.h$", r"pygtk/config\.h$", r"pygtk/config\.py$"
2931 ,r"pygtk/ascdev$", r"ascxx/testconopt$", r"ascend/compiler/scanner\.c$"
2932 ,r"datareader/.*TY\.csv$"
2933 ,r"[a-z]+/.*/.*\.spec$"
2934 ,r"ascxx/ascpy_wrap\.h",r"ascxx/config\.h$"
2935 ,r"tcltk/interface/ascend4$",r"ascxx/testslvreq$",r"test/test$"
2936 ,r"models/johnpye/datareader/.*\.tm2\.Z$"
2937 ,r"models/johnpye/fprops/[a-z][a-z0-9]+(.*\.exe)?$" # FPROPS test executables
2938 ,r"fprops/fluids/fluids_list\.h$" # FPROPS fluids list
2939 ,r"fprops/test/ph$"
2940 ,r"fprops/test/sat$"
2941 ,r"fprops/test/sat1$"
2942 ]
2943 )
2944
2945 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
2946 , [env.Dir('#')]
2947 )
2948
2949 env.Depends(tar,'ascend.spec')
2950 env.Depends(tar,'doc/book.pdf')
2951
2952 #------------------------------------------------------
2953 # DEBIAN TARBALL for use with Build Service
2954
2955 import glob
2956 deb_files = glob.glob('debian/*.install')
2957 deb_files += glob.glob('debian/*.docs')
2958 deb_files += glob.glob('debian/*.dirs')
2959 deb_files += glob.glob('debian/*.man')
2960 deb_files += glob.glob('debian/*.manpages')
2961 deb_files += ['debian/%s' % s for s in ['rules','control','changelog','compat','copyright','dirs']]
2962
2963 deb_tar = env.Tar(
2964 'dist/debian.tar.gz'
2965 ,deb_files
2966 ,TARFLAGS = ['cz']
2967 )
2968
2969 Alias('dist',[tar,deb_tar])
2970
2971 #------------------------------------------------------
2972 # DOCUMENTATION
2973
2974 #print "WITH_DOC_BUILD = ",with_doc_build
2975
2976 if with_doc_build:
2977 #user's manual
2978 env.SConscript('doc/SConscript',['env'])
2979 else:
2980 print "Skipping... Documentation isn't being built:",without_doc_build_reason
2981
2982 #------------------------------------------------------
2983 # RPM BUILD
2984
2985 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
2986 # (check * for the version number used to create the tarball)
2987
2988 #------------------------------------------------------
2989 # DEFAULT TARGETS
2990
2991 default_targets =['libascend','solvers']
2992 if with_tcltk:
2993 default_targets.append('tcltk')
2994 if with_python:
2995 default_targets.append('ascxx')
2996 default_targets.append('pygtk')
2997 default_targets.append('pyfprops')
2998 if with_extfns:
2999 default_targets.append('extfns')
3000 if with_doc_build:
3001 default_targets.append('doc')
3002
3003 env.Default(default_targets)
3004
3005 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
3006
3007 # vim: set syntax=python:

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