/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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