/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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