/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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