/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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