/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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