/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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