/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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