/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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