/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1319 - (show annotations) (download)
Tue Mar 6 00:22:28 2007 UTC (12 years, 9 months ago) by jpye
File size: 50458 byte(s)
Added test suite for linsolqr (very early days still) for checking by Ben
1 import sys, os, commands, platform, distutils.sysconfig, os.path, re
2
3 version = "0.9.5.107"
4
5 #------------------------------------------------------
6 # OPTIONS
7 #
8 # Note that if you set the options via the command line, they will be
9 # remembered in the file 'options.cache'. It's a feature ;-)
10
11 opts = Options(['options.cache', 'config.py'])
12 #print "PLATFORM = ",platform.system()
13
14 if platform.system()=="Windows":
15 default_tcl_lib = "tcl84"
16 default_tk_lib = "tk84"
17 default_tktable_lib = "Tktable28"
18 default_install_assets = "glade/"
19 icon_extension = '.png'
20 default_tcl = "c:\\Tcl"
21 if os.environ.get('MSYSTEM')=="MINGW32":
22 default_tcl_libpath="$TCL\\bin"
23 else:
24 default_tcl_libpath="$TCL\\lib"
25 default_rel_distdir = '.'
26 default_absolute_paths = False
27
28 default_ida_prefix = "c:\\MinGW"
29 if not os.path.exists(default_ida_prefix):
30 default_ida_prefix = None
31
32 default_conopt_prefix = "c:\\Program Files\\CONOPT"
33 default_conopt_libpath="$CONOPT_PREFIX"
34 default_conopt_cpppath="$CONOPT_PREFIX"
35 default_conopt_lib="conopt3"
36 default_conopt_envvar="CONOPT_PATH"
37
38 default_prefix="c:\\MinGW"
39 default_libpath="$DEFAULT_PREFIX\\lib"
40 default_cpppath="$DEFAULT_PREFIX\\include"
41
42 if not os.path.exists(default_conopt_prefix):
43 default_conopt_prefix = None
44
45 need_libm = False
46 python_exe = "c:\\Python24\\python.exe"
47 default_with_scrollkeeper=False
48 else:
49 default_tcl_lib = "tcl8.4"
50 default_tk_lib = "tk8.4"
51 default_tktable_lib = "Tktable2.8"
52 default_install_assets = "$INSTALL_ASCDATA/glade/"
53 icon_extension = '.svg'
54 default_tcl = '/usr'
55 default_tcl_libpath = "$TCL/lib"
56 default_rel_distdir = '../share/ascend'
57 default_absolute_paths = True
58 default_ida_prefix="/usr/local"
59 default_conopt_prefix="/usr"
60 default_conopt_libpath="$CONOPT_PREFIX/lib"
61 default_conopt_cpppath="$CONOPT_PREFIX/include"
62 default_conopt_lib="consub3"
63 default_conopt_envvar="CONOPT_PATH"
64
65 default_prefix="/usr"
66 default_libpath="$DEFAULT_PREFIX/lib"
67 default_cpppath="$DEFAULT_PREFIX/include"
68
69 need_libm = True
70 if not os.path.isdir(default_tcl):
71 default_tcl = '/usr'
72 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
73 default_with_scrollkeeper=False
74
75 opts.Add(
76 'CC'
77 ,'C Compiler command'
78 ,None
79 )
80
81 opts.Add(
82 'CXX'
83 ,'C++ Compiler command'
84 ,None
85 )
86
87 opts.Add(BoolOption(
88 'GCOV'
89 , 'Whether to enable coverage testing in object code'
90 , False
91 ))
92
93 # Package linking option
94 opts.Add(EnumOption(
95 'PACKAGE_LINKING'
96 , 'Style of linking for external libraries'
97 , 'DYNAMIC_PACKAGES'
98 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
99 ))
100
101 opts.Add(BoolOption(
102 'WITH_GCCVISIBILITY'
103 ,"Whether to use GCC Visibility features (only applicable if available)"
104 ,True
105 ))
106
107 opts.Add(BoolOption(
108 'WITH_SIGNALS'
109 ,"Whether to permit use of signals for flow control in the C-level code"
110 ,True
111 ))
112
113 # You can turn off building of Tcl/Tk interface
114 opts.Add(BoolOption(
115 'WITH_TCLTK'
116 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
117 , True
118 ))
119
120 # You can turn off the building of the Python interface
121 opts.Add(BoolOption(
122 'WITH_PYTHON'
123 ,"Set to False if you don't want to build Python wrappers."
124 , True
125 ))
126
127 # Which solvers will we allow?
128 opts.Add(ListOption(
129 'WITH_SOLVERS'
130 ,"List of the solvers you want to build. The default is the minimum that"
131 +" works."
132 ,["QRSLV","CMSLV","LSOD","IDA","CONOPT","LRSLV"]
133 ,['QRSLV','MPS','SLV','OPTSQP'
134 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
135 ,'LSOD','OPTSQP',"IDA"
136 ]
137 ))
138
139 # Where will the local copy of the help files be kept?
140 opts.Add(PackageOption(
141 'WITH_LOCAL_HELP'
142 , "Directory containing the local copy of the help files (optional)"
143 , "no"
144 ))
145
146 # Will bintoken support be enabled?
147 opts.Add(BoolOption(
148 'WITH_BINTOKEN'
149 ,"Enable bintoken support? This means compiling models as C-code before"
150 +" running them, to increase solving speed for large models."
151 ,False
152 ))
153
154 # What should the default ASCENDLIBRARY path be?
155 # Note: users can change it by editing their ~/.ascend.ini
156 opts.Add(
157 'DEFAULT_ASCENDLIBRARY'
158 ,"Set the default value of the ASCENDLIBRARY -- the location where"
159 +" ASCEND will look for models when running ASCEND"
160 ,"$INSTALL_ASCDATA/models"
161 )
162
163 # Where is SWIG?
164 opts.Add(
165 'SWIG'
166 ,"SWIG location, probably only required for MinGW and MSVC users."
167 +" Enter the location as a Windows-style path, for example"
168 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
169 )
170
171 # Build the test suite?
172 opts.Add(BoolOption(
173 'WITH_CUNIT'
174 ,"You can disable CUnit tests with this option. This will basically stop"
175 +" SCons from parsing the SConscript files relating to the 'test'"
176 +" target, which just might make things marginally faster. Probably"
177 +" you can just ignore this option though. SCons will sniff for Cunit"
178 +" but build the tests only if you specify the 'test' target."
179 ,True
180 ))
181
182 # Build with MMIO matrix export support?
183 opts.Add(BoolOption(
184 'WITH_MMIO'
185 ,"Include support for exporting matrices in Matrix Market format"
186 ,True
187 ))
188
189
190 opts.Add(BoolOption(
191 'IDA_NEW_ANALYSE'
192 ,"Build with new IDA 'analyse' function? (see base/generic/solver/ida.c)"
193 ,True
194 ))
195
196 #----- default paths -----
197 opts.Add(PackageOption(
198 'DEFAULT_PREFIX'
199 ,"Where are most of the shared libraries located on your system?"
200 ,default_prefix
201 ))
202
203 #------ install location for python extensions ------
204
205 # (removed for the moment)
206
207 #------ cunit --------
208 # Where was CUNIT installed?
209 opts.Add(PackageOption(
210 'CUNIT_PREFIX'
211 ,"Where are your CUnit files?"
212 ,"$DEFAULT_PREFIX"
213 ))
214
215 # Where are the CUnit includes?
216 opts.Add(PackageOption(
217 'CUNIT_CPPPATH'
218 ,"Where are your CUnit include files?"
219 ,"$CUNIT_PREFIX/include"
220 ))
221
222 # Where are the CUnit libraries?
223 opts.Add(PackageOption(
224 'CUNIT_LIBPATH'
225 ,"Where are your CUnit libraries?"
226 ,"$CUNIT_PREFIX/lib"
227 ))
228
229 #-------- ida -------
230
231 opts.Add(PackageOption(
232 "IDA_PREFIX"
233 ,"Prefix for your IDA install (IDA ./configure --prefix)"
234 ,default_ida_prefix
235 ))
236
237 opts.Add(
238 "IDA_LIB"
239 ,"Libraries linked to for IDA"
240 ,['sundials_nvecserial','sundials_ida','m']
241 )
242
243 opts.Add(
244 'IDA_CPPPATH'
245 ,"Where is your ida.h?"
246 ,"$IDA_PREFIX/include"
247 )
248
249 opts.Add(
250 'IDA_LIBPATH'
251 ,"Where are your SUNDIALS libraries installed?"
252 ,"$IDA_PREFIX/lib"
253 )
254
255 # ----- conopt-----
256
257 opts.Add(PackageOption(
258 "CONOPT_PREFIX"
259 ,"Prefix for your CONOPT install (CONOPT ./configure --prefix)"
260 ,default_conopt_prefix
261 ))
262
263 opts.Add(
264 "CONOPT_LIB"
265 ,"Library linked to for CONOPT"
266 ,default_conopt_lib
267 )
268
269 opts.Add(
270 'CONOPT_CPPPATH'
271 ,"Where is your conopt.h?"
272 ,default_conopt_cpppath
273 )
274
275 opts.Add(
276 'CONOPT_LIBPATH'
277 ,"Where is your CONOPT libraries installed?"
278 ,default_conopt_libpath
279 )
280
281 opts.Add(
282 'CONOPT_ENVVAR'
283 ,"What environment variable should be used at runtime to override the default search location for CONOPT DLL/SO?"
284 ,default_conopt_envvar
285 )
286
287 #-------- f2c ------
288
289 opts.Add(
290 "F2C_LIB"
291 ,"F2C library (eg. g2c, gfortran, f2c)"
292 ,"g2c"
293 )
294
295 opts.Add(PackageOption(
296 "F2C_LIBPATH"
297 ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
298 ,"off"
299 ))
300
301 #------- tcl/tk --------
302
303 opts.Add(
304 'TCL'
305 ,'Base of Tcl distribution'
306 ,default_tcl
307 )
308
309 # Where are the Tcl includes?
310 opts.Add(
311 'TCL_CPPPATH'
312 ,"Where are your Tcl include files?"
313 ,"$TCL/include"
314 )
315
316 # Where are the Tcl libs?
317 opts.Add(
318 'TCL_LIBPATH'
319 ,"Where are your Tcl libraries?"
320 ,default_tcl_libpath
321 )
322
323 # What is the name of the Tcl lib?
324 opts.Add(
325 'TCL_LIB'
326 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
327 ,default_tcl_lib
328 )
329
330 # Where are the Tk includes?
331 opts.Add(
332 'TK_CPPPATH'
333 ,"Where are your Tk include files?"
334 ,'$TCL_CPPPATH'
335 )
336
337 # Where are the Tk libs?
338 opts.Add(
339 'TK_LIBPATH'
340 ,"Where are your Tk libraries?"
341 ,'$TCL_LIBPATH'
342 )
343
344 # What is the name of the Tk lib?
345 opts.Add(
346 'TK_LIB'
347 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
348 ,default_tk_lib
349 )
350
351 # Static linking to TkTable
352
353 opts.Add(BoolOption(
354 'STATIC_TCLTK'
355 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
356 ,False
357 ))
358
359 opts.Add(
360 'TKTABLE_LIBPATH'
361 ,'Location of TkTable static library'
362 ,'$TCL_LIBPATH/Tktable2.8'
363 )
364
365 opts.Add(
366 'TKTABLE_LIB'
367 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
368 ,default_tktable_lib
369 )
370
371 opts.Add(
372 'TKTABLE_CPPPATH'
373 ,'Location of TkTable header file'
374 ,'$TCL_CPPPATH'
375 )
376
377 opts.Add(
378 'X11'
379 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
380 ,'/usr/X11R6'
381 )
382
383 opts.Add(
384 'X11_LIBPATH'
385 ,'Location of X11 lib. EXPERIMENTAL'
386 ,'$X11/lib'
387 )
388
389 opts.Add(
390 'X11_CPPPATH'
391 ,'Location of X11 includes. EXPERIMENTAL'
392 ,'$X11/include'
393 )
394
395 opts.Add(
396 'X11_LIB'
397 ,'Name of X11 lib. EXPERIMENTAL'
398 ,'X11'
399 )
400
401 #----- installed file locations (for 'scons install') -----
402
403 opts.Add(
404 'INSTALL_PREFIX'
405 ,'Root location for installed files'
406 ,'/usr/local'
407 )
408
409 opts.Add(
410 'INSTALL_BIN'
411 ,'Location to put binaries during installation'
412 ,"$INSTALL_PREFIX/bin"
413 )
414
415 opts.Add(
416 'INSTALL_LIB'
417 ,'Location to put libraries during installation'
418 ,"$INSTALL_PREFIX/lib"
419 )
420
421 opts.Add(
422 'INSTALL_SHARE'
423 ,'Common shared-file location on this system'
424 ,"$INSTALL_PREFIX/share"
425 )
426
427 opts.Add(
428 'INSTALL_DOC'
429 ,'Location to install documentation files'
430 ,"$INSTALL_SHARE/doc"
431 )
432
433 opts.Add(
434 'INSTALL_ASCDATA'
435 ,"Location of ASCEND shared data (TK, python, models etc)"
436 ,"$INSTALL_SHARE/ascend"
437 )
438
439 opts.Add(
440 'INSTALL_INCLUDE'
441 ,'Location to put header files during installation'
442 ,"$INSTALL_PREFIX/include"
443 )
444
445
446 opts.Add(
447 'INSTALL_ROOT'
448 ,'For use by RPM only: location of %{buildroot} during rpmbuild'
449 ,""
450 )
451
452 #----------------------
453
454 opts.Add(
455 'PYGTK_ASSETS'
456 ,'Default location for Glade assets (placed in pygtk/config.py)'
457 ,default_install_assets
458 )
459
460 opts.Add(BoolOption(
461 'DEBUG'
462 ,"Compile source with debugger symbols, eg for use with 'gdb'"
463 ,False
464 ))
465
466 opts.Add(BoolOption(
467 'MALLOC_DEBUG'
468 ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
469 ,False
470 ))
471
472 #------ dmalloc --------
473 opts.Add(PackageOption(
474 'DMALLOC_PREFIX'
475 ,"Where are your dmalloc files?"
476 ,default_prefix
477 ))
478
479 opts.Add(PackageOption(
480 'DMALLOC_CPPPATH'
481 ,"Where are your dmalloc include files?"
482 ,default_cpppath
483 ))
484
485 opts.Add(PackageOption(
486 'DMALLOC_LIBPATH'
487 ,"Where are your dmalloc libraries?"
488 ,default_libpath
489 ))
490
491 opts.Add(BoolOption(
492 'WITH_DMALLOC'
493 ,"Link to the DMALLOC library (if available) for debugging of memory usage."
494 ,False
495 ))
496
497 #------ mfgraph --------
498 opts.Add(PackageOption(
499 'MFGRAPH_PREFIX'
500 ,"Where are your MFGRAPH files?"
501 ,default_prefix
502 ))
503
504 opts.Add(PackageOption(
505 'MFGRAPH_CPPPATH'
506 ,"Where are your MFGRAPH include files?"
507 ,default_cpppath
508 ))
509
510 opts.Add(PackageOption(
511 'MFGRAPH_LIBPATH'
512 ,"Where are your MFGRAPH libraries?"
513 ,default_libpath
514 ))
515
516 opts.Add(BoolOption(
517 'WITH_MFGRAPH'
518 ,"Link to the MFGRAPH library (if available) for debugging of memory usage."
519 ,True
520 ))
521
522 #-----------------------
523
524 opts.Add(
525 'DISTTAR_NAME'
526 ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
527 ,"ascend-"+version
528 )
529
530 opts.Add(
531 'RELEASE'
532 ,"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."
533 ,"0"
534 )
535
536 opts.Add(BoolOption(
537 'ABSOLUTE_PATHS'
538 ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
539 ,default_absolute_paths
540 ))
541
542 opts.Add(
543 'WIN_INSTALLER_NAME'
544 ,"Name of the installer .exe to create under Windows (minus the '.exe')"
545 ,"ascend-"+version
546 )
547
548 opts.Add(BoolOption(
549 'WITH_XTERM_COLORS'
550 ,"Set to 0 if you don't want xterm colour codes in the console output"
551 ,True
552 ))
553
554 opts.Add(BoolOption(
555 'WITH_EXTFNS'
556 ,"Set to 0 if you don't want to attempt to build external modules bundled"
557 + " with ASCEND."
558 ,True
559 ))
560
561 opts.Add(BoolOption(
562 'WITH_SCROLLKEEPER'
563 ,"Set to to 1 if you want to install an OMF file that can be read by scrollkeeper (eg Yelp on GNOME)"
564 ,default_with_scrollkeeper
565 ))
566
567 if platform.system()!="Windows":
568 opts.Add(BoolOption(
569 'WITH_GCCVISIBILITY'
570 , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
571 , True
572 ))
573
574
575
576 # TODO: OTHER OPTIONS?
577 # TODO: flags for optimisation
578 # TODO: turning on/off bintoken functionality
579 # TODO: Where will the 'Makefile.bt' file be installed?
580
581 # Import the outside environment
582
583 def c_escape(str):
584 return re.sub("\\\\","/",str)
585
586 envadditional={}
587
588 if platform.system()=="Windows":
589 if os.environ.get('OSTYPE')=='msys' or os.environ.get('MSYSTEM'):
590 envenv = os.environ;
591 tools = ['mingw','lex','yacc','fortran','swig','disttar','nsis']
592 #TODO removed 'doxygen' for SCons 0.96.93
593 envadditional['IS_MINGW']=True
594 else:
595 print "Assuming VC++ build environment (Note: MinGW is preferred)"
596 envenv = {
597 'PATH':os.environ['PATH']
598 ,'INCLUDE':os.environ['INCLUDE']
599 ,'LIB':os.environ['LIB']
600 ,'MSVS_IGNORE_IDE_PATHS':1
601 }
602 tools=['default','lex','yacc','fortran','swig','disttar','nsis']
603 #TODO removed 'doxygen' for SCons 0.96.93
604 envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
605 else:
606 if os.environ.get('TARGET')=='mingw':
607 envenv = os.environ
608 tools=['crossmingw','lex','yacc','disttar','nsis','doxygen']
609 envadditional['CPPPATH']=['/usr/local/lib/gcc/i386-mingw32/3.4.5/include','/usr/include']
610 else:
611 envenv = os.environ
612 tools=['default','lex','yacc','fortran','swig','disttar','nsis']
613 #TODO removed 'doxygen' for SCons 0.96.93
614
615
616 env = Environment(
617 ENV=envenv
618 , toolpath=['scons']
619 , tools=tools
620 , **envadditional
621 )
622
623 opts.Update(env)
624 opts.Save('options.cache',env)
625
626 Help(opts.GenerateHelpText(env))
627
628 with_tcltk = env.get('WITH_TCLTK')
629 without_tcltk_reason = "disabled by options/config.py"
630
631 with_python = env.get('WITH_PYTHON')
632 without_python_reason = "disabled by options/config.py"
633
634 with_cunit = env.get('WITH_CUNIT')
635 without_cunit_reason = "not requested"
636
637 with_extfns = env.get('WITH_EXTFNS')
638 without_extfn_reason = "disabled by options/config.py"
639
640 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
641 without_scrollkeeper_reason = "disabled by options/config.py"
642
643 with_dmalloc = env.get('WITH_DMALLOC')
644 without_dmalloc_reason = "disabled by options/config.py"
645
646 with_mfgraph = env.get('WITH_MFGRAPH')
647 without_mfgraph_reason = "disabled by options/config.py"
648
649 with_mmio = env.get('WITH_MMIO')
650 without_mmio_reason = "disabled by options/config.py"
651
652 with_signals = env.get('WITH_SIGNALS')
653 without_signals_reason = "disabled by options/config.py"
654
655 if platform.system()=="Windows":
656 with_installer=1
657 else:
658 with_installer=0
659 without_installer_reason = "only possible under Windows"
660
661 if 'LSOD' in env['WITH_SOLVERS']:
662 with_lsode=True
663 else:
664 with_lsode=False
665 without_lsode_reason = "not requested (WITH_SOLVERS)"
666
667 if 'IDA' in env['WITH_SOLVERS']:
668 with_ida=True
669 else:
670 with_ida=False
671 without_ida_reason = "not requested (WITH_SOLVERS)"
672
673
674 if 'CONOPT' in env['WITH_SOLVERS']:
675 with_conopt=True
676 else:
677 with_conopt=False
678 without_conopt_reason = "not requested (WITH_SOLVERS)"
679
680
681 #print "SOLVERS:",env['WITH_SOLVERS']
682 #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
683 #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
684
685 can_install = True
686 if platform.system()=='Windows':
687 can_install = False
688
689 env['CAN_INSTALL']=can_install
690 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
691
692 print "TCL_CPPPATH =",env['TCL_CPPPATH']
693 print "TCL_LIBPATH =",env['TCL_LIBPATH']
694 print "TCL_LIB =",env['TCL_LIB']
695 print "CC =",env['CC']
696 print "CXX =",env['CXX']
697 print "FORTRAN=",env.get('FORTRAN')
698
699 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
700 #------------------------------------------------------
701 # SPECIAL CONFIGURATION TESTS
702
703 need_fortran = False
704
705 #----------------
706 # SWIG
707
708 import os,re
709
710 def get_swig_version(env):
711 cmd = env['SWIG']+' -version'
712 (cin,coutcerr) = os.popen4(cmd)
713 output = coutcerr.read()
714
715 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
716 expr = re.compile(restr,re.M);
717 m = expr.search(output);
718 if not m:
719 return None
720 maj = int(m.group('maj'))
721 min = int(m.group('min'))
722 pat = int(m.group('pat'))
723
724 return (maj,min,pat)
725
726
727 def CheckSwigVersion(context):
728
729 try:
730 context.Message("Checking version of SWIG... ")
731 maj,min,pat = get_swig_version(context.env)
732 except:
733 context.Result("Failed to detect version, or failed to run SWIG")
734 return 0;
735
736 context.env['SWIGVERSION']=tuple([maj,min,pat])
737
738 if maj == 1 and (
739 min > 3
740 or (min == 3 and pat >= 24)
741 ):
742 context.Result("ok, %d.%d.%d" % (maj,min,pat))
743 return 1;
744 else:
745 context.Result("too old, %d.%d.%d" % (maj,min,pat))
746 return 0;
747
748 #----------------
749 # Scrollkeeper (Linux documentation system)
750
751 def get_scrollkeeper_omfdir(env):
752 cmd = 'scrollkeeper-config --omfdir'
753 (cin,coutcerr) = os.popen4(cmd)
754 output = coutcerr.read()
755 return output.strip()
756
757 def CheckScrollkeeperConfig(context):
758 try:
759 context.Message("Checking for scrollkeeper...")
760 dir=get_scrollkeeper_omfdir(context.env)
761 except:
762 context.Result("Failed to run 'scrollkeeper-config'")
763 return 0
764 context.env['OMFDIR']=dir
765 context.Result("OK, %s" % dir)
766 return 1
767
768 #----------------
769 # General purpose library-and-header test
770
771 class KeepContext:
772 def __init__(self,context,varprefix,static=False):
773 self.keep = {}
774 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
775 #print "Keeping env %s = %s" % (k,context.env.get(k))
776 self.keep[k]=context.env.get(k)
777
778 if context.env.has_key(varprefix+'_CPPPATH'):
779 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
780 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
781
782 if static:
783 staticlib=env[varprefix+'_LIB']
784 #print "STATIC LIB = ",staticlib
785 context.env.Append(
786 LINKFLAGS=[staticlib]
787 )
788 else:
789 if context.env.has_key(varprefix+'_LIBPATH'):
790 context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
791 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
792
793 if context.env.has_key(varprefix+'_LIB'):
794 context.env.Append(LIBS=[env[varprefix+'_LIB']])
795 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
796
797 def restore(self,context):
798 #print "RESTORING CONTEXT"
799 #print self.keep
800 #print "..."
801 for k in self.keep:
802 if self.keep[k]==None:
803 if context.env.has_key(k):
804 #print "Clearing "+str(k)
805 del context.env[k];
806 else:
807 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
808 context.env[k]=self.keep[k];
809
810 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
811 """This method will check for variables LIBNAME_LIBPATH
812 and LIBNAME_CPPPATH and try to compile and link the
813 file with the provided text, linking with the
814 library libname."""
815
816 if static:
817 context.Message( 'Checking for static '+libname+'... ' )
818 else:
819 context.Message( 'Checking for '+libname+'... ' )
820
821 if varprefix==None:
822 varprefix = libname.upper()
823
824 #print "LIBS is currently:",context.env.get('LIBS')
825 keep = KeepContext(context,varprefix,static)
826
827 if not context.env.has_key(varprefix+'_LIB'):
828 # if varprefix_LIB were in env, KeepContext would
829 # have appended it already
830 context.env.Append(LIBS=[libname])
831
832 is_ok = context.TryLink(text,ext)
833
834 #print "Link success? ",(is_ok != 0)
835
836 keep.restore(context)
837
838 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
839 # print "Restored LIBS="+str(context.env['LIBS'])
840 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
841
842 context.Result(is_ok)
843 return is_ok
844
845 #----------------
846 # GCC
847
848 gcc_test_text = """
849 #ifndef __GNUC__
850 # error "Not using GCC"
851 #endif
852
853 int main(void){
854 return __GNUC__;
855 }
856 """
857
858 def CheckGcc(context):
859 context.Message("Checking for GCC... ")
860 is_ok = context.TryCompile(gcc_test_text,".c")
861 context.Result(is_ok)
862 return is_ok
863
864 #----------------
865 # GCC VISIBILITY feature
866
867 gccvisibility_test_text = """
868 #if __GNUC__ < 4
869 # error "Require GCC version 4 or newer"
870 #endif
871
872 __attribute__ ((visibility("default"))) int x;
873
874 int main(void){
875 extern int x;
876 x = 4;
877 }
878 """
879
880 def CheckGccVisibility(context):
881 context.Message("Checking for GCC 'visibility' capability... ")
882 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
883 context.Result("disabled")
884 return 0
885 is_ok = context.TryCompile(gccvisibility_test_text,".c")
886 context.Result(is_ok)
887 return is_ok
888
889 #----------------
890 # YACC
891
892 yacc_test_text = """
893 %{
894 #include <stdio.h>
895
896 /* MSVC++ needs this before it can swallow Bison output */
897 #ifdef _MSC_VER
898 # define __STDC__
899 #endif
900 %}
901 %token MSG
902 %start ROOT
903 %%
904 ROOT:
905 MSG { printf("HELLO"); }
906 ;
907 %%
908 """
909
910 def CheckYacc(context):
911 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
912 is_ok = context.TryCompile(yacc_test_text,".y")
913 context.Result(is_ok)
914 return is_ok
915
916 #----------------
917 # LEX
918
919 lex_test_text = """
920 %{
921 #include <stdio.h>
922 %}
923 DIGIT [0-9]
924 ID [a-z][a-z0-9]*
925 %%
926 {DIGIT}+ {
927 printf("A digit: %s\\n",yytext);
928 }
929
930 [ \\t\\n]+ /* ignore */
931
932 . {
933 printf("Unrecognized guff");
934 }
935 %%
936 main(){
937 yylex();
938 }
939 """
940
941 def CheckLex(context):
942 context.Message("Checking for Lex ('%s')... " % context.env.get('LEX'))
943 is_ok = context.TryCompile(lex_test_text,".l")
944 context.Result(is_ok)
945 return is_ok
946
947 #----------------
948 # CUnit test
949
950 cunit_test_text = """
951 #include <CUnit/CUnit.h>
952 int maxi(int i1, int i2){
953 return (i1 > i2) ? i1 : i2;
954 }
955
956 void test_maxi(void){
957 CU_ASSERT(maxi(0,2) == 2);
958 CU_ASSERT(maxi(0,-2) == 0);
959 CU_ASSERT(maxi(2,2) == 2);
960
961 }
962 int main(void){
963 /* CU_initialize_registry() */
964 return 0;
965 }
966 """
967
968 def CheckCUnit(context):
969 return CheckExtLib(context,'cunit',cunit_test_text)
970
971 #----------------
972 # dmalloc test
973
974 dmalloc_test_text = """
975 #include <stdlib.h>
976 #include <dmalloc.h>
977
978 int main(void){
979 char *c;
980 c = malloc(100*sizeof(char));
981 free(c);
982 return 0;
983 }
984 """
985
986 def CheckDMalloc(context):
987 return CheckExtLib(context,'dmalloc',dmalloc_test_text)
988
989 #----------------
990 # mfgraph test
991
992 mfgraph_test_text = """
993 #include <mfgraph/mfg_draw_graph.h>
994 int main(void){
995 using namespace mfg;
996 DrawGraph g;
997 return 0;
998 }
999 """
1000
1001 def CheckMFGraph(context):
1002 return CheckExtLib(context,'mfgraph',mfgraph_test_text,ext=".cpp")
1003
1004 #----------------
1005 # MATH test
1006
1007 math_test_text = """
1008 #ifndef _ALL_SOURCE
1009 # define _ALL_SOURCE
1010 #endif
1011 #ifndef _XOPEN_SOURCE
1012 # define _XOPEN_SOURCE
1013 #endif
1014 #ifndef _XOPEN_SOURCE_EXTENDED
1015 # define _XOPEN_SOURCE_EXTENDED 1
1016 #endif
1017 #include <math.h>
1018 int main(void){
1019 double x = 1.0; double y = 1.0; int i = 1;
1020 acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
1021 j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
1022 y0(x); y1(x); yn(i,x);
1023 #ifdef _THREAD_SAFE
1024 gamma_r(x,&i);
1025 lgamma_r(x,&i);
1026 #else
1027 gamma(x);
1028 lgamma(x);
1029 #endif
1030 hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
1031 return 0;
1032 }
1033 """
1034
1035 def CheckMath(context):
1036 context.Message('Checking for IEEE math library... ')
1037 libsave=context.env.get('LIBS');
1038 context.env.AppendUnique(LIBS=['m'])
1039 is_ok=context.TryLink(math_test_text,".c")
1040 context.Result(is_ok)
1041 if not is_ok:
1042 context.env['LIBS']=libsave
1043 return is_ok
1044
1045 #----------------
1046 # libpython test
1047
1048 libpython_test_text = """
1049 #include <Python.h>
1050 int main(void){
1051 PyObject *p;
1052 p = Py_None;
1053 return 0;
1054 }
1055 """
1056
1057 def CheckPythonLib(context):
1058 context.Message('Checking for libpython... ')
1059
1060 if platform.system()=="Windows":
1061 python_lib='python%d%d'
1062 else:
1063 python_lib='python%d.%d'
1064 python_libs = [python_lib % (sys.version_info[0],sys.version_info[1])]
1065
1066 python_cpppath = [distutils.sysconfig.get_python_inc()]
1067 cfig = distutils.sysconfig.get_config_vars()
1068
1069 lastLIBS = context.env.get('LIBS')
1070 lastLIBPATH = context.env.get('LIBPATH')
1071 lastCPPPATH = context.env.get('CPPPATH')
1072 lastLINKFLAGS = context.env.get('LINKFLAGS')
1073
1074 python_libpath = []
1075 python_linkflags = []
1076 if platform.system()=="Windows":
1077 python_libpath+=[cfig['prefix']]
1078 else:
1079 # checked on Linux and SunOS
1080 if cfig['LDLIBRARY']==cfig['LIBRARY']:
1081 sys.stdout.write("(static)")
1082 python_libpath += [cfig['LIBPL']]
1083 python_linkflags += cfig['LIBS'].split(' ')
1084
1085 context.env.AppendUnique(LIBS=python_libs)
1086 context.env.AppendUnique(LIBPATH=python_libpath)
1087 context.env.AppendUnique(CPPPATH=python_cpppath)
1088 context.env.AppendUnique(LINKFLAGS=python_linkflags)
1089 result = context.TryLink(libpython_test_text,".c");
1090
1091 context.Result(result)
1092
1093 if(result):
1094 context.env['PYTHON_LIBPATH']=python_libpath
1095 context.env['PYTHON_LIB']=python_libs
1096 context.env['PYTHON_CPPPATH']=python_cpppath
1097 context.env['PYTHON_LINKFLAGS']=python_linkflags
1098
1099 context.env['LIBS'] = lastLIBS
1100 context.env['LIBPATH'] = lastLIBPATH
1101 context.env['CPPPATH'] = lastCPPPATH
1102 context.env['LINKFLAGS'] = lastLINKFLAGS
1103
1104 return result
1105
1106 #----------------
1107 # IDA test
1108
1109 sundials_version_major_required = 2
1110 sundials_version_minor_min = 2
1111 sundials_version_minor_max = 3
1112
1113 sundials_version_text = """
1114 #include <sundials/sundials_config.h>
1115 #include <stdio.h>
1116 int main(){
1117 printf("%s",SUNDIALS_PACKAGE_VERSION);
1118 return 0;
1119 }
1120 """
1121
1122 ida_test_text = """
1123 # include <ida/ida.h>
1124 # include <nvector/nvector_serial.h>
1125 # include <ida/ida_spgmr.h>
1126 int main(){
1127 void *ida_mem;
1128 ida_mem = IDACreate();
1129 return 0;
1130 }
1131 """
1132
1133 def CheckIDA(context):
1134 context.Message( 'Checking for IDA (SUNDIALS)... ' )
1135
1136 keep = KeepContext(context,"IDA")
1137
1138 is_ok = context.TryLink(ida_test_text,".c")
1139 context.Result(is_ok)
1140
1141 keep.restore(context)
1142
1143 return is_ok
1144
1145 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
1146 # so detect the version and act accordingly.
1147 def CheckIDAVersion(context):
1148 keep = KeepContext(context,'IDA')
1149 context.Message("Checking SUNDIALS version... ")
1150 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
1151 keep.restore(context)
1152 if not is_ok:
1153 context.Result("failed to run check")
1154 return 0
1155
1156 major,minor,patch = tuple([int(i) for i in output.split(".")])
1157 context.env['SUNDIALS_VERSION_MAJOR'] = major
1158 context.env['SUNDIALS_VERSION_MINOR'] = minor
1159 if major != sundials_version_major_required \
1160 or minor < sundials_version_minor_min \
1161 or minor > sundials_version_minor_max:
1162 context.Result(output+" (bad version)")
1163 # bad version
1164 return 0
1165
1166 # good version
1167 context.Result("%d.%d.%d, good" % (major,minor,patch))
1168 return 1
1169
1170 #----------------
1171 # CONOPT test
1172
1173 conopt_test_text = """
1174 #if !defined(_WIN32)
1175 # define FNAME_LCASE_DECOR
1176 #endif
1177
1178 #include <conopt.h>
1179 #include <stdlib.h>
1180 int main(){
1181 int s, *v, e;
1182 s = COIDEF_Size();
1183 v = (int *)malloc(s*sizeof(int));
1184 e = COIDEF_Ini(v);
1185 return e;
1186 }
1187 """
1188
1189 def CheckCONOPT(context):
1190 context.Message( 'Checking for CONOPT... ' )
1191
1192 keep = KeepContext(context,"CONOPT")
1193
1194 is_ok = context.TryLink(conopt_test_text,".c")
1195 context.Result(is_ok)
1196
1197 keep.restore(context)
1198
1199 return is_ok
1200
1201 #----------------
1202 # Tcl test
1203
1204 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
1205 tcltk_minor_newest_acceptable = 4
1206 tcltk_major_required = 8
1207
1208 tcl_check_text = r"""
1209 #include <tcl.h>
1210 #include <stdio.h>
1211 int main(void){
1212 printf("%s",TCL_PATCH_LEVEL);
1213 return 0;
1214 }
1215 """
1216
1217 def CheckTcl(context):
1218 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
1219
1220 def CheckTclVersion(context):
1221 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
1222 context.Message("Checking Tcl version... ")
1223 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
1224 keep.restore(context)
1225 if not is_ok:
1226 context.Result("failed to run check")
1227 return 0
1228
1229 major,minor,patch = tuple([int(i) for i in output.split(".")])
1230 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1231 context.Result(output+" (bad version)")
1232 # bad version
1233 return 0
1234
1235 # good version
1236 context.Result(output+", good")
1237 return 1
1238
1239 #----------------
1240 # Tk test
1241
1242 tk_check_text = r"""
1243 #include <tk.h>
1244 #include <stdio.h>
1245 int main(void){
1246 printf("%s",TK_PATCH_LEVEL);
1247 return 0;
1248 }
1249 """
1250 def CheckTk(context):
1251 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1252
1253
1254 def CheckTkVersion(context):
1255 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1256 context.Message("Checking Tk version... ")
1257 #print "LINKFLAGS =",context.env['LINKFLAGS']
1258 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1259 keep.restore(context)
1260 if not is_ok:
1261 context.Result("failed to run check")
1262 return 0
1263
1264 major,minor,patch = tuple([int(i) for i in output.split(".")])
1265 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1266 # bad version
1267 context.Result(output+" (bad version)")
1268 return 0
1269
1270 # good version
1271 context.Result(output+" (good)")
1272 return 1
1273
1274 #----------------
1275 # Tktable test
1276
1277 tktable_check_text = r"""
1278 #include <tkTable.h>
1279 #include <stdio.h>
1280 int main(void){
1281 Table mytable;
1282 return 0;
1283 }
1284 """
1285
1286 def CheckTkTable(context):
1287 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1288
1289 #---------------
1290 # X11 test
1291
1292 x11_check_text = r"""
1293 #include <X11/Xlib.h>
1294 #include <X11/IntrinsicP.h>
1295 #include <X11/Intrinsic.h>
1296 #include <X11/ObjectP.h>
1297 #include <X11/Object.h>
1298 int main(void){
1299 Object mything;
1300 return 0;
1301 }
1302 """
1303
1304 def CheckX11(context):
1305 return CheckExtLib(context,'X11',x11_check_text)
1306
1307 #----------------
1308 # Check that we can raise and catch sigint
1309
1310 sigint_test_text = r"""
1311 #include <signal.h>
1312 #include <setjmp.h>
1313 #include <stdlib.h>
1314 static jmp_buf g_jmpenv;
1315 void sighandler(int sig){
1316 longjmp(g_jmpenv,sig);
1317 }
1318 void testsigint(){
1319 raise(SIGINT);
1320 }
1321 int main(void){
1322 signal(SIGINT,&sighandler);
1323 switch(setjmp(g_jmpenv)){
1324 case 0:
1325 testsigint();
1326 exit(1);
1327 case SIGINT:
1328 exit(0);
1329 default:
1330 exit(2);
1331 }
1332 }
1333 """
1334
1335 def CheckSIGINT(context):
1336 context.Message("Checking SIGINT is catchable... ")
1337 (is_ok,output)=context.TryRun(sigint_test_text,".c")
1338 context.Result(is_ok)
1339 return is_ok
1340
1341 #----------------
1342 # Check that we're able to catch floating point errors
1343
1344 sigfpe_test_text = r"""
1345 #include <signal.h>
1346 #include <setjmp.h>
1347 #include <stdlib.h>
1348 #include <fenv.h>
1349 static jmp_buf g_jmpenv;
1350 void fpehandler(int sig){
1351 longjmp(g_jmpenv,sig);
1352 }
1353 int main(void){
1354 fenv_t myfenv;
1355 fegetenv(&myfenv);
1356 fesetenv(&myfenv);
1357 feenableexcept(FE_ALL_EXCEPT);
1358 signal(SIGFPE,&fpehandler);
1359 double x;
1360 switch(setjmp(g_jmpenv)){
1361 case 0:
1362 x = 1.0 / 0.0;
1363 /* failed to catch */
1364 exit(1);
1365 case SIGFPE:
1366 exit(0);
1367 }
1368 }
1369 """
1370
1371 def CheckFPE(context):
1372 context.Message("Checking C99 FPE behaviour... ")
1373 (is_ok,output) = context.TryRun(sigfpe_test_text,'.c')
1374 context.Result(is_ok)
1375 return is_ok
1376
1377 #----------------
1378 # signal reset needed?
1379
1380 sigreset_test_text = r"""
1381 #include <signal.h>
1382 #include <setjmp.h>
1383 #include <stdlib.h>
1384 #include <stdio.h>
1385 typedef void SigHandlerFn(int);
1386 static jmp_buf g_jmpenv;
1387 void sighandler(int sig){
1388 longjmp(g_jmpenv,sig);
1389 }
1390 void testsigint(){
1391 /* fprintf(stderr,"Raising SIGINT\n"); */
1392 raise(SIGINT);
1393 }
1394 int main(void){
1395 SigHandlerFn *last,*saved;
1396 saved = signal(SIGINT,&sighandler);
1397 if(saved!=SIG_DFL){
1398 fprintf(stderr,"Default handler (%p) was not correctly set\n",SIG_DFL);
1399 exit(3);
1400 }
1401 switch(setjmp(g_jmpenv)){
1402 case 0:
1403 testsigint();
1404 fprintf(stderr,"Back from SIGINT\n");
1405 exit(1);
1406 case SIGINT:
1407 break;
1408 default:
1409 exit(2);
1410 };
1411 last = signal(SIGINT,SIG_DFL);
1412 if(last!=&sighandler){
1413 printf("1");
1414 exit(0);
1415 }
1416 printf("0");
1417 exit(0);
1418 }
1419 """
1420
1421 def CheckSigReset(context):
1422 context.Message("Checking signal handler reset... ")
1423 (is_ok,output) = context.TryRun(sigreset_test_text,'.c')
1424 if not is_ok:
1425 context.Result("ERROR")
1426 return False
1427 if int(output)==1:
1428 context.Result("required");
1429 context.env['ASC_RESETNEEDED'] = True
1430 else:
1431 context.Result("not required");
1432 context.env['ASC_RESETNEEDED'] = False
1433 return is_ok
1434
1435 #----------------
1436 # GCC Version sniffing
1437
1438 # TODO FIXME
1439
1440 gcc_version4 = False
1441
1442 #------------------------------------------------------
1443 # CONFIGURATION
1444
1445 conf = Configure(env
1446 , custom_tests = {
1447 'CheckMath' : CheckMath
1448 , 'CheckSwigVersion' : CheckSwigVersion
1449 , 'CheckPythonLib' : CheckPythonLib
1450 , 'CheckCUnit' : CheckCUnit
1451 , 'CheckDMalloc' : CheckDMalloc
1452 , 'CheckMFGraph' : CheckMFGraph
1453 , 'CheckTcl' : CheckTcl
1454 , 'CheckTclVersion' : CheckTclVersion
1455 , 'CheckTk' : CheckTk
1456 , 'CheckTkVersion' : CheckTkVersion
1457 , 'CheckGcc' : CheckGcc
1458 , 'CheckGccVisibility' : CheckGccVisibility
1459 , 'CheckYacc' : CheckYacc
1460 , 'CheckLex' : CheckLex
1461 , 'CheckTkTable' : CheckTkTable
1462 , 'CheckX11' : CheckX11
1463 , 'CheckIDA' : CheckIDA
1464 , 'CheckIDAVersion' : CheckIDAVersion
1465 , 'CheckCONOPT' : CheckCONOPT
1466 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
1467 , 'CheckFPE' : CheckFPE
1468 , 'CheckSIGINT' : CheckSIGINT
1469 , 'CheckSigReset' : CheckSigReset
1470 # , 'CheckIsNan' : CheckIsNan
1471 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
1472 }
1473 # , config_h = "config.h"
1474 )
1475
1476 # stdio -- just to check that compiler is behaving
1477
1478 if not conf.CheckHeader('stdio.h'):
1479 print "CPPPATH =",env.get('CPPPATH')
1480 print "Did not find 'stdio.h'! Check your compiler configuration."
1481 print ""
1482 print "You environment is printed here:"
1483 for k,v in os.environ.iteritems():
1484 print "%-30s%s" % ("%s :" % k, v)
1485 Exit(1)
1486
1487 if not conf.CheckFunc('snprintf'):
1488 print "Didn't find snprintf";
1489 exit(1)
1490
1491 # Math library
1492
1493 conf.env['HAVE_IEEE']=True
1494
1495 if need_libm and not conf.CheckMath():
1496 conf.env['HAVE_IEEE']=False
1497 print 'Did not find math library, exiting!'
1498 Exit(1)
1499
1500 # Where is 'isnan'?
1501
1502 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1503 print "Didn't find isnan"
1504 # Exit(1)
1505
1506 # GCC visibility
1507
1508 if conf.CheckGcc():
1509 conf.env['HAVE_GCC']=True;
1510 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
1511 conf.env['HAVE_GCCVISIBILITY']=True;
1512 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1513 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1514 conf.env.Append(CCFLAGS=['-Wall'])
1515
1516 # Catching SIGINT
1517
1518 if env['WITH_SIGNALS']:
1519 if not conf.CheckSIGINT():
1520 with_signals = False
1521 without_signals_reason = "SIGINT uncatchable"
1522
1523 # Catching SIGFPE
1524
1525 if conf.CheckFPE():
1526 conf.env['HAVE_C99FPE']=True
1527 else:
1528 conf.env['HAVE_C99FPE']=False
1529
1530 # Checking for signal reset requirement
1531
1532 if not conf.CheckSigReset():
1533 print "Unable to determine if signal reset is required"
1534 Exit(1)
1535
1536 # YACC
1537
1538 if not conf.CheckYacc():
1539 print "YACC NOT FOUND OR NOT WORKING"
1540 else:
1541 conf.env['HAVE_YACC']=True
1542
1543 if not conf.CheckLex():
1544 print "YACC NOT FOUND OR NOT WORKING"
1545 else:
1546 conf.env['HAVE_LEX']=True
1547
1548 # Tcl/Tk
1549
1550 if with_tcltk:
1551 if conf.CheckTcl():
1552 if conf.CheckTclVersion():
1553 if conf.CheckTk():
1554 if with_tcltk and conf.CheckTkVersion():
1555 if env['STATIC_TCLTK']:
1556 if conf.CheckTkTable():
1557 pass
1558 else:
1559 without_tcltk_reason = "TkTable not found"
1560 with_tcltk = False
1561 else:
1562 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1563 with_tcltk = False
1564 else:
1565 without_tcltk_reason = "Tk not found."
1566 with_tcltk = False
1567 else:
1568 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1569 with_tcltk = False
1570
1571 else:
1572 without_tcltk_reason = "Tcl not found."
1573 with_tcltk = False
1574
1575 if env['STATIC_TCLTK']:
1576 conf.CheckX11()
1577
1578 # Python... obviously we're already running python, so we just need to
1579 # check that we can link to the python library OK:
1580
1581 if not conf.CheckPythonLib():
1582 without_python_reason = 'libpython2.x not found or not linkable'
1583 with_python = False
1584 env['WITH_PYTHON']=False
1585
1586 # SWIG version
1587
1588 if with_python and not conf.CheckSwigVersion():
1589 without_python_reason = 'SWIG >= 1.3.24 is required'
1590 with_python = False
1591 env['WITH_PYTHON']=False
1592
1593 # CUnit
1594
1595 if with_cunit:
1596 if not conf.CheckCUnit():
1597 without_cunit_reason = 'CUnit not found'
1598 with_cunit = False
1599 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1600
1601 # DMALLOC
1602
1603 if with_dmalloc:
1604 if not conf.CheckDMalloc():
1605 without_dmalloc_reason = 'dmalloc not found'
1606 with_dmalloc = False
1607
1608 # DMALLOC
1609
1610 if with_mfgraph:
1611 if not conf.CheckMFGraph():
1612 without_mfgraph_reason = 'mfgraph not found'
1613 with_mfgraph = False
1614 env['WITH_MFGRAPH'] = False
1615
1616 # IDA
1617
1618 if not with_ida:
1619 without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1620 elif not conf.CheckIDA():
1621 with_ida = False
1622 without_ida_reason = "IDA not found"
1623 elif not conf.CheckIDAVersion():
1624 with_ida = False
1625 without_ida_reason = "Unsupported (or undetected) SUNDIALS version"
1626
1627 # CONOPT
1628
1629 if not with_conopt:
1630 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1631 elif not conf.CheckCONOPT():
1632 with_conopt = False
1633 without_conpt_reason = "CONOPT not found"
1634
1635 # BLAS
1636
1637 need_blas=False
1638
1639 if with_lsode:
1640 need_fortran = True
1641 need_blas=True
1642
1643 if need_blas:
1644 if conf.CheckLib('blas'):
1645 with_local_blas = False
1646 without_local_blas_reason = "Found BLAS installed on system"
1647 else:
1648 with_local_blas = True
1649 need_fortran = True
1650 else:
1651 with_local_blas= False;
1652 without_local_blas_reason = "BLAS not required"
1653
1654 # FORTRAN
1655
1656 if need_fortran:
1657 conf.env.Tool('fortran')
1658 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1659 if detect_fortran:
1660 # For some reason, g77 doesn't get detected properly on MinGW
1661 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1662 conf.env.Replace(F77=detect_fortran)
1663 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1664 conf.env.Replace(F77FLAGS='')
1665 #print "F77:",conf.env['F77']
1666 #print "F77COM:",conf.env['F77COM']
1667 #print "F77FLAGS:",conf.env['F77FLAGS']
1668 fortran_builder = Builder(
1669 action='$F77COM'
1670 , suffix='.o'
1671 , src_suffix='.f'
1672 )
1673 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1674 if platform.system()=="Linux":
1675 conf.env.Append(SHFORTRANFLAGS=['-fPIC'])
1676 else:
1677 with_lsode=False;
1678 without_lsode_reason="FORTRAN-77 required but not found"
1679
1680 #else:
1681 # print "FORTRAN not required"
1682
1683 # F2C
1684
1685 if need_fortran:
1686 if platform.system()=="Windows":
1687 conf.env.Append(LIBPATH='c:\mingw\lib')
1688
1689 # scrollkeeper
1690
1691 if with_scrollkeeper:
1692 if not conf.CheckScrollkeeperConfig():
1693 with_scrollkeeper=False
1694 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
1695
1696 # TODO: -D_HPUX_SOURCE is needed
1697
1698 # TODO: check size of void*
1699
1700 # TODO: detect if dynamic libraries are possible or not
1701
1702 if platform.system()=="Windows" and env.has_key('MSVS'):
1703 _found_windows_h = conf.CheckHeader('Windows.h')
1704
1705 if not _found_windows_h:
1706 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1707 Exit(1)
1708
1709 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1710 with_python = 0;
1711 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1712
1713 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1714
1715 conf.Finish()
1716
1717 #---------------------------------------
1718 # SUBSTITUTION DICTIONARY for .in files
1719
1720 release = env.get('RELEASE')
1721 if release=="0.":
1722 release="0"
1723
1724 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1725
1726 subst_dict = {
1727 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1728 , '@GLADE_FILE@':'ascend.glade'
1729 , '@HELP_ROOT@':''
1730 , '@ICON_EXTENSION@':icon_extension
1731 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1732 , '@INSTALL_BIN@':env['INSTALL_BIN']
1733 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1734 , '@INSTALL_LIB@':env['INSTALL_LIB']
1735 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1736 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1737 , '@VERSION@':version
1738 , '@RELEASE@':release
1739 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1740 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1741 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
1742 , '@SHLIBPREFIX@':env['SHLIBPREFIX']
1743 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1744 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1745 , '@PYTHON@' : python_exe
1746 , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1747 , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1748 , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_LIBPATH"))
1749 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
1750 }
1751
1752 if env.get('WITH_LOCAL_HELP'):
1753 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1754 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1755
1756 # bool options...
1757 for k,v in {
1758 'ASC_WITH_IDA':with_ida
1759 ,'ASC_WITH_DMALLOC':with_dmalloc
1760 ,'ASC_WITH_MFGRAPH':with_mfgraph
1761 ,'ASC_WITH_CONOPT':with_conopt
1762 ,'ASC_WITH_LSODE':with_lsode
1763 ,'ASC_WITH_MMIO':with_mmio
1764 ,'ASC_SIGNAL_TRAPS':with_signals
1765 ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
1766 ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
1767 ,'HAVE_IEEE':env.get('HAVE_IEEE')
1768 ,'ASC_ABSOLUTE_PATHS':env.get('ASC_ABSOLUTE_PATHS')
1769 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
1770 ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
1771 ,'ASC_IDA_NEW_ANALYSE':env.get('IDA_NEW_ANALYSE')
1772 }.iteritems():
1773
1774 if v: subst_dict["/\\* #define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
1775
1776 if with_python:
1777 subst_dict['@ASCXX_USE_PYTHON@']="1"
1778 env['WITH_PYTHON']=1;
1779
1780 if env.has_key('HAVE_GCCVISIBILITY'):
1781 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1782
1783 env.Append(SUBST_DICT=subst_dict)
1784
1785 #for k,v in subst_dict.iteritems():
1786 # print "%-50s%s" % ("'%s'"%k,v)
1787
1788 # REMOVED: long command-line support on Win2k
1789
1790 #------------------------------------------------------
1791 # RECIPE: SWIG scanner
1792
1793 import SCons.Script
1794
1795 SWIGScanner = SCons.Scanner.ClassicCPP(
1796 "SWIGScan"
1797 , ".i"
1798 , "CPPPATH"
1799 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1800 )
1801
1802 env.Append(SCANNERS=[SWIGScanner])
1803
1804 #------------------------------------------------------
1805 # RECIPE: 'SubstInFile', used in pygtk SConscript
1806
1807 import re
1808 from SCons.Script import * # the usual scons stuff you get in a SConscript
1809
1810 def TOOL_SUBST(env):
1811 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1812 from the source to the target.
1813 The values of SUBST_DICT first have any construction variables expanded
1814 (its keys are not expanded).
1815 If a value of SUBST_DICT is a python callable function, it is called and
1816 the result is expanded as the value.
1817 If there's more than one source and more than one target, each target gets
1818 substituted from the corresponding source.
1819 """
1820 env.Append(TOOLS = 'SUBST')
1821 def do_subst_in_file(targetfile, sourcefile, dict):
1822 """Replace all instances of the keys of dict with their values.
1823 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1824 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1825 """
1826 try:
1827 f = open(sourcefile, 'rb')
1828 contents = f.read()
1829 f.close()
1830 except:
1831 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1832 for (k,v) in dict.items():
1833 try:
1834 #print "%s ---> %s" % (k,v)
1835 contents = re.sub(k, v, contents)
1836 except Exception,e:
1837 sys.stderr.write("Failed to substute '%s' with '%s': %s\n" % (k,v,e))
1838
1839 try:
1840 f = open(targetfile, 'wb')
1841 f.write(contents)
1842 f.close()
1843 except:
1844 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1845 return 0 # success
1846
1847 def subst_in_file(target, source, env):
1848 if not env.has_key('SUBST_DICT'):
1849 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1850 d = dict(env['SUBST_DICT']) # copy it
1851 for (k,v) in d.items():
1852 if callable(v):
1853 d[k] = env.subst(v())
1854 elif SCons.Util.is_String(v):
1855 d[k]=env.subst(v)
1856 else:
1857 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1858 for (t,s) in zip(target, source):
1859 return do_subst_in_file(str(t), str(s), d)
1860
1861 def subst_in_file_string(target, source, env):
1862 """This is what gets printed on the console."""
1863 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1864 for (t,s) in zip(target, source)])
1865
1866 def subst_emitter(target, source, env):
1867 """Add dependency from substituted SUBST_DICT to target.
1868 Returns original target, source tuple unchanged.
1869 """
1870 d = env['SUBST_DICT'].copy() # copy it
1871 for (k,v) in d.items():
1872 if callable(v):
1873 d[k] = env.subst(v())
1874 elif SCons.Util.is_String(v):
1875 d[k]=env.subst(v)
1876 Depends(target, SCons.Node.Python.Value(d))
1877 return target, source
1878
1879 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1880 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1881
1882 TOOL_SUBST(env)
1883
1884 #------------------------------------------------------
1885 # Recipe for 'CHMOD' ACTION
1886
1887 import SCons
1888 from SCons.Script.SConscript import SConsEnvironment
1889 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1890 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1891
1892 def InstallPerm(env, dest, files, perm):
1893 obj = env.Install(dest, files)
1894 for i in obj:
1895 env.AddPostAction(i, env.Chmod(str(i), perm))
1896
1897 SConsEnvironment.InstallPerm = InstallPerm
1898
1899 # define wrappers
1900 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1901 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1902 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1903
1904 #------------------------------------------------------
1905 # BUILD...
1906
1907 # so that #include <modulename/headername.h> works across all modules...
1908 env.AppendUnique(CPPPATH=['#base/generic'])
1909
1910 if env['DEBUG']:
1911 env.Append(CCFLAGS=['-g'])
1912
1913 if env['GCOV']:
1914 env.Append(
1915 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1916 , LIBS=['gcov']
1917 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1918 )
1919
1920 if with_ida:
1921 env.Append(WITH_IDA=1)
1922
1923 if with_conopt:
1924 env.Append(WITH_CONOPT=1)
1925
1926 #-------------
1927 # TCL/TK GUI
1928
1929 if with_tcltk:
1930 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1931 else:
1932 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
1933
1934 #-------------
1935 # PYTHON INTERFACE
1936
1937 if with_python:
1938 env.SConscript(['pygtk/SConscript'],'env')
1939 else:
1940 print "Skipping... Python bindings aren't being built:",without_python_reason
1941
1942 #------------
1943 # BASE/GENERIC SUBDIRECTORIES
1944
1945 libascend_env = env.Copy()
1946
1947 dirs = ['general','utilities','compiler','system','solver','integrator','packages','linear']
1948
1949 srcs = []
1950 for d in dirs:
1951 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1952 srcs += heresrcs
1953
1954 #-------------
1955 # IMPORTED CODE: LSODE, BLAS, etc
1956
1957 if with_lsode:
1958 srcs += env.SConscript(['lsod/SConscript'],'env')
1959 srcs += env.SConscript(['linpack/SConscript'],'env')
1960 else:
1961 print "Skipping... LSODE won't be built:", without_lsode_reason
1962
1963 if with_local_blas:
1964 srcs += env.SConscript(['blas/SConscript'],'env')
1965 else:
1966 print "Skipping... BLAS won't be built:", without_local_blas_reason
1967
1968 if not with_ida:
1969 print "Skipping... IDA won't be built:", without_ida_reason
1970
1971 if with_mmio:
1972 srcs += env.SConscript(['mmio/SConscript'],'env')
1973 else:
1974 print "Skipping... MMIO export won't be built:", without_mmio_reason
1975 #-------------
1976 # LIBASCEND -- all base/generic functionality
1977
1978 if with_dmalloc:
1979 libascend_env.Append(LIBS=['dmalloc'])
1980
1981 libascend = libascend_env.SharedLibrary('ascend',srcs)
1982
1983 env.Alias('libascend',libascend)
1984
1985 #-------------
1986 # UNIT TESTS (C CODE)
1987
1988 if with_cunit:
1989 testdirs = ['general','solver','utilities','linear']
1990 testsrcs = []
1991 for testdir in testdirs:
1992 path = 'base/generic/'+testdir+'/test/'
1993 env.SConscript([path+'SConscript'],'env')
1994 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1995
1996 #print "TESTSRCS =",testsrcs
1997
1998 env.SConscript(['test/SConscript'],'env')
1999 env.SConscript(['base/generic/test/SConscript'],'env')
2000
2001 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
2002
2003 else:
2004 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
2005
2006 #-------------
2007 # EXTERNAL FUNCTIONS
2008
2009 env['extfns']=[]
2010 modeldirs = env.SConscript(['models/SConscript'],'env')
2011
2012 if not with_extfns:
2013 print "Skipping... External modules aren't being built:",without_extfns_reason
2014
2015 env.Alias('extfns',env['extfns'])
2016
2017 #------------------------------------------------------
2018 # CREATE ASCEND-CONFIG scriptlet
2019
2020 ascendconfig = env.SubstInFile('ascend-config.in')
2021
2022 #------------------------------------------------------
2023 # INSTALLATION
2024
2025 if env.get('CAN_INSTALL'):
2026
2027 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE', 'INSTALL_DOC']
2028 install_dirs = [env.Entry(env['INSTALL_ROOT']+env[d]) for d in dirs]
2029 install_dirs += modeldirs
2030
2031 # TODO: add install options
2032 env.Alias('install',install_dirs)
2033
2034 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
2035
2036 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
2037
2038 #------------------------------------------------------
2039 # WINDOWS INSTALLER
2040 # For the windows installer, please see pygtk/SConscript
2041
2042 if with_installer:
2043 pass
2044 else:
2045 print "Skipping... Windows installer isn't being built:",without_installer_reason
2046
2047 #------------------------------------------------------
2048 # PROJECT FILE for MSVC
2049
2050 env.SConscript(['base/msvc/SConscript'],['env','libascend']);
2051
2052 #------------------------------------------------------
2053 # CREATE the SPEC file for generation of RPM packages
2054
2055 if platform.system()=="Linux":
2056 env.SubstInFile('ascend.spec.in')
2057
2058 #------------------------------------------------------
2059 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
2060
2061 if with_scrollkeeper:
2062 env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
2063 env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
2064
2065 #------------------------------------------------------
2066 # DISTRIBUTION TAR FILE
2067
2068 env['DISTTAR_FORMAT']='bz2'
2069 env.Append(
2070 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl','.out']
2071 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
2072 )
2073
2074 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
2075 , [env.Dir('#')]
2076 )
2077
2078 env.Depends(tar,'ascend.spec')
2079
2080 Alias('dist',tar)
2081
2082 #------------------------------------------------------
2083 # USER'S MANUAL
2084
2085 env.SConscript('doc/SConscript',['env'])
2086
2087 #------------------------------------------------------
2088 # LIBASCEND DOXYGEN DOCUMENTATION
2089
2090 env.SConscript('base/doc/SConscript',['env'])
2091
2092 #------------------------------------------------------
2093 # RPM BUILD
2094
2095 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
2096 # (check * for the version number used to create the tarball)
2097
2098 #------------------------------------------------------
2099 # DEFAULT TARGETS
2100
2101 default_targets =['libascend']
2102 if with_tcltk:
2103 default_targets.append('tcltk')
2104 if with_python:
2105 default_targets.append('pygtk')
2106 if with_installer:
2107 default_targets.append('installer')
2108 if with_extfns:
2109 default_targets.append('extfns')
2110
2111 env.Default(default_targets)
2112
2113 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
2114
2115 # vim: set syntax=python:
2116

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