/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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