/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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