/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 957 - (show annotations) (download)
Sun Dec 10 02:21:06 2006 UTC (13 years, 9 months ago) by johnpye
File size: 46241 byte(s)
Fixed for static linking to python where libpython2.x.so is not available.
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_lib = 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
973 python_libpath = []
974
975 if cfig['LDLIBRARY']==cfig['LIBRARY']:
976 print "static library only?"
977 python_libpath += [cfig['LIBPL']]
978
979 context.env.AppendUnique(LIBS=[python_lib])
980 context.env.AppendUnique(LIBPATH=python_libpath)
981 context.env.AppendUnique(CPPPATH=python_cpppath)
982 result = context.TryLink(libpython_test_text,".c");
983
984 context.Result(result)
985
986 if(result):
987 context.env.Append(PYTHON_LIBPATH=python_libpath)
988 context.env.Append(PYTHON_LIB=[python_lib])
989 context.env.Append(PYTHON_CPPPATH=python_cpppath)
990
991 context.env['LIBS'] = lastLIBS
992 context.env['LIBPATH'] = lastLIBPATH
993 context.env['CPPPATH'] = lastCPPPATH
994
995 return result
996
997 #----------------
998 # IDA test
999
1000 sundials_version_major_required = 2
1001 sundials_version_minor_min = 2
1002 sundials_version_minor_max = 3
1003
1004 sundials_version_text = """
1005 #include <sundials/sundials_config.h>
1006 #include <stdio.h>
1007 int main(){
1008 printf("%s",SUNDIALS_PACKAGE_VERSION);
1009 return 0;
1010 }
1011 """
1012
1013 ida_test_text = """
1014 # include <ida/ida.h>
1015 # include <nvector/nvector_serial.h>
1016 # include <ida/ida_spgmr.h>
1017 int main(){
1018 void *ida_mem;
1019 ida_mem = IDACreate();
1020 return 0;
1021 }
1022 """
1023
1024 def CheckIDA(context):
1025 context.Message( 'Checking for IDA (SUNDIALS)... ' )
1026
1027 keep = KeepContext(context,"IDA")
1028
1029 is_ok = context.TryLink(ida_test_text,".c")
1030 context.Result(is_ok)
1031
1032 keep.restore(context)
1033
1034 return is_ok
1035
1036 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
1037 # so detect the version and act accordingly.
1038 def CheckIDAVersion(context):
1039 keep = KeepContext(context,'IDA')
1040 context.Message("Checking SUNDIALS version... ")
1041 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
1042 keep.restore(context)
1043 if not is_ok:
1044 context.Result("failed to run check")
1045 return 0
1046
1047 major,minor,patch = tuple([int(i) for i in output.split(".")])
1048 context.env['SUNDIALS_VERSION_MAJOR'] = major
1049 context.env['SUNDIALS_VERSION_MINOR'] = minor
1050 if major != sundials_version_major_required \
1051 or minor < sundials_version_minor_min \
1052 or minor > sundials_version_minor_max:
1053 context.Result(output+" (bad version)")
1054 # bad version
1055 return 0
1056
1057 # good version
1058 context.Result(output+", good")
1059 return 1
1060
1061 #----------------
1062 # CONOPT test
1063
1064 conopt_test_text = """
1065 #if !defined(_WIN32)
1066 # define FNAME_LCASE_DECOR
1067 #endif
1068
1069 #include <conopt.h>
1070 #include <stdlib.h>
1071 int main(){
1072 int s, *v, e;
1073 s = COIDEF_Size();
1074 v = (int *)malloc(s*sizeof(int));
1075 e = COIDEF_Ini(v);
1076 return e;
1077 }
1078 """
1079
1080 def CheckCONOPT(context):
1081 context.Message( 'Checking for CONOPT... ' )
1082
1083 keep = KeepContext(context,"CONOPT")
1084
1085 is_ok = context.TryLink(conopt_test_text,".c")
1086 context.Result(is_ok)
1087
1088 keep.restore(context)
1089
1090 return is_ok
1091
1092 #----------------
1093 # Tcl test
1094
1095 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
1096 tcltk_minor_newest_acceptable = 4
1097 tcltk_major_required = 8
1098
1099 tcl_check_text = r"""
1100 #include <tcl.h>
1101 #include <stdio.h>
1102 int main(void){
1103 printf("%s",TCL_PATCH_LEVEL);
1104 return 0;
1105 }
1106 """
1107
1108 def CheckTcl(context):
1109 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
1110
1111 def CheckTclVersion(context):
1112 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
1113 context.Message("Checking Tcl version... ")
1114 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
1115 keep.restore(context)
1116 if not is_ok:
1117 context.Result("failed to run check")
1118 return 0
1119
1120 major,minor,patch = tuple([int(i) for i in output.split(".")])
1121 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1122 context.Result(output+" (bad version)")
1123 # bad version
1124 return 0
1125
1126 # good version
1127 context.Result(output+", good")
1128 return 1
1129
1130 #----------------
1131 # Tk test
1132
1133 tk_check_text = r"""
1134 #include <tk.h>
1135 #include <stdio.h>
1136 int main(void){
1137 printf("%s",TK_PATCH_LEVEL);
1138 return 0;
1139 }
1140 """
1141 def CheckTk(context):
1142 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1143
1144
1145 def CheckTkVersion(context):
1146 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1147 context.Message("Checking Tk version... ")
1148 #print "LINKFLAGS =",context.env['LINKFLAGS']
1149 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1150 keep.restore(context)
1151 if not is_ok:
1152 context.Result("failed to run check")
1153 return 0
1154
1155 major,minor,patch = tuple([int(i) for i in output.split(".")])
1156 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1157 # bad version
1158 context.Result(output+" (bad version)")
1159 return 0
1160
1161 # good version
1162 context.Result(output+" (good)")
1163 return 1
1164
1165 #----------------
1166 # Tktable test
1167
1168 tktable_check_text = r"""
1169 #include <tkTable.h>
1170 #include <stdio.h>
1171 int main(void){
1172 Table mytable;
1173 return 0;
1174 }
1175 """
1176
1177 def CheckTkTable(context):
1178 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1179
1180 #---------------
1181 # X11 test
1182
1183 x11_check_text = r"""
1184 #include <X11/Xlib.h>
1185 #include <X11/IntrinsicP.h>
1186 #include <X11/Intrinsic.h>
1187 #include <X11/ObjectP.h>
1188 #include <X11/Object.h>
1189 int main(void){
1190 Object mything;
1191 return 0;
1192 }
1193 """
1194
1195 def CheckX11(context):
1196 return CheckExtLib(context,'X11',x11_check_text)
1197
1198 #----------------
1199 # Check that we're able to catch floating point errors
1200
1201 sigfpe_test_text = r"""
1202 #include <signal.h>
1203 #include <setjmp.h>
1204 #include <stdlib.h>
1205 #include <fenv.h>
1206 static jmp_buf g_jmpenv;
1207 void fpehandler(int sig){
1208 longjmp(g_jmpenv,sig);
1209 }
1210 int main(void){
1211 fenv_t myfenv;
1212 fegetenv(&myfenv);
1213 fesetenv(&myfenv);
1214 feenableexcept(FE_ALL_EXCEPT);
1215 signal(SIGFPE,&fpehandler);
1216 double x;
1217 switch(setjmp(g_jmpenv)){
1218 case 0:
1219 x = 1.0 / 0.0;
1220 /* failed to catch */
1221 exit(1);
1222 case SIGFPE:
1223 exit(0);
1224 }
1225 }
1226 """
1227
1228 def CheckFPE(context):
1229 context.Message("Checking for C99 FPE behaviour... ")
1230 (is_ok,output) = context.TryRun(sigfpe_test_text,'.c')
1231 context.Result(is_ok)
1232 return is_ok
1233
1234 #----------------
1235 # GCC Version sniffing
1236
1237 # TODO FIXME
1238
1239 gcc_version4 = False
1240
1241 #------------------------------------------------------
1242 # CONFIGURATION
1243
1244 conf = Configure(env
1245 , custom_tests = {
1246 'CheckMath' : CheckMath
1247 , 'CheckSwigVersion' : CheckSwigVersion
1248 , 'CheckPythonLib' : CheckPythonLib
1249 , 'CheckCUnit' : CheckCUnit
1250 , 'CheckDMalloc' : CheckDMalloc
1251 , 'CheckTcl' : CheckTcl
1252 , 'CheckTclVersion' : CheckTclVersion
1253 , 'CheckTk' : CheckTk
1254 , 'CheckTkVersion' : CheckTkVersion
1255 , 'CheckGcc' : CheckGcc
1256 , 'CheckGccVisibility' : CheckGccVisibility
1257 , 'CheckYacc' : CheckYacc
1258 , 'CheckTkTable' : CheckTkTable
1259 , 'CheckX11' : CheckX11
1260 , 'CheckIDA' : CheckIDA
1261 , 'CheckIDAVersion' : CheckIDAVersion
1262 , 'CheckCONOPT' : CheckCONOPT
1263 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
1264 , 'CheckFPE' : CheckFPE
1265 # , 'CheckIsNan' : CheckIsNan
1266 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
1267 }
1268 # , config_h = "config.h"
1269 )
1270
1271 # stdio -- just to check that compiler is behaving
1272
1273 if not conf.CheckHeader('stdio.h'):
1274 print "CPPPATH =",env.get('CPPPATH')
1275 print "Did not find 'stdio.h'! Check your compiler configuration."
1276 Exit(1)
1277
1278 # Math library
1279
1280 if need_libm:
1281 if not conf.CheckMath():
1282 print 'Did not find math library, exiting!'
1283 Exit(1)
1284 #pass
1285
1286 # Where is 'isnan'?
1287
1288 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1289 print "Didn't find isnan"
1290 # Exit(1)
1291
1292 # GCC visibility
1293
1294 if conf.CheckGcc():
1295 conf.env['HAVE_GCC']=True;
1296 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
1297 conf.env['HAVE_GCCVISIBILITY']=True;
1298 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1299 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1300 conf.env.Append(CCFLAGS=['-Wall'])
1301
1302 # Catching SIGFPE
1303
1304 if conf.CheckFPE():
1305 conf.env['HAVE_SIGFPE']=True
1306 else:
1307 conf.env['HAVE_SIGFPE']=False
1308
1309 # YACC
1310
1311 if not conf.CheckYacc():
1312 print "YACC NOT FOUND OR NOT WORKING"
1313 else:
1314 conf.env['HAVE_YACC']=True
1315
1316 conf.env['HAVE_LEX']=True
1317
1318 # Tcl/Tk
1319
1320 if with_tcltk:
1321 if conf.CheckTcl():
1322 if conf.CheckTclVersion():
1323 if conf.CheckTk():
1324 if with_tcltk and conf.CheckTkVersion():
1325 if env['STATIC_TCLTK']:
1326 if conf.CheckTkTable():
1327 pass
1328 else:
1329 without_tcltk_reason = "TkTable not found"
1330 with_tcltk = False
1331 else:
1332 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1333 with_tcltk = False
1334 else:
1335 without_tcltk_reason = "Tk not found."
1336 with_tcltk = False
1337 else:
1338 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1339 with_tcltk = False
1340
1341 else:
1342 without_tcltk_reason = "Tcl not found."
1343 with_tcltk = False
1344
1345 if env['STATIC_TCLTK']:
1346 conf.CheckX11()
1347
1348 # Python... obviously we're already running python, so we just need to
1349 # check that we can link to the python library OK:
1350
1351 if not conf.CheckPythonLib():
1352 without_python_reason = 'libpython2.x not found or not linkable'
1353 with_python = False
1354
1355 # SWIG version
1356
1357 if with_python and not conf.CheckSwigVersion():
1358 without_python_reason = 'SWIG >= 1.3.24 is required'
1359 with_python = False
1360
1361 # CUnit
1362
1363 if with_cunit:
1364 if not conf.CheckCUnit():
1365 without_cunit_reason = 'CUnit not found'
1366 with_cunit = False
1367 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1368
1369 # DMALLOC
1370
1371 if with_dmalloc:
1372 if not conf.CheckDMalloc():
1373 without_dmalloc_reason = 'dmalloc not found'
1374 with_dmalloc = False
1375
1376 # IDA
1377
1378 if not with_ida:
1379 without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1380 elif not conf.CheckIDA():
1381 with_ida = False
1382 without_ida_reason = "IDA not found"
1383 elif not conf.CheckIDAVersion():
1384 with_ida = False
1385 without_ida_reason = "Unsupported (or undetected) SUNDIALS version"
1386
1387 # CONOPT
1388
1389 if not with_conopt:
1390 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1391 elif not conf.CheckCONOPT():
1392 with_conopt = False
1393 without_conpt_reason = "CONOPT not found"
1394
1395 # BLAS
1396
1397 need_blas=False
1398
1399 if with_lsode:
1400 need_fortran = True
1401 need_blas=True
1402
1403 if need_blas:
1404 if conf.CheckLib('blas'):
1405 with_local_blas = False
1406 without_local_blas_reason = "Found BLAS installed on system"
1407 else:
1408 with_local_blas = True
1409 need_fortran = True
1410 else:
1411 with_local_blas= False;
1412 without_local_blas_reason = "BLAS not required"
1413
1414 # FORTRAN
1415
1416 if need_fortran:
1417 conf.env.Tool('fortran')
1418 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1419 if detect_fortran:
1420 # For some reason, g77 doesn't get detected properly on MinGW
1421 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1422 conf.env.Replace(F77=detect_fortran)
1423 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1424 conf.env.Replace(F77FLAGS='')
1425 #print "F77:",conf.env['F77']
1426 #print "F77COM:",conf.env['F77COM']
1427 #print "F77FLAGS:",conf.env['F77FLAGS']
1428 fortran_builder = Builder(
1429 action='$F77COM'
1430 , suffix='.o'
1431 , src_suffix='.f'
1432 )
1433 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1434 else:
1435 with_lsode=False;
1436 without_lsode_reason="FORTRAN-77 required but not found"
1437
1438 #else:
1439 # print "FORTRAN not required"
1440
1441 # F2C
1442
1443 if need_fortran:
1444 if platform.system()=="Windows":
1445 conf.env.Append(LIBPATH='c:\mingw\lib')
1446
1447 # scrollkeeper
1448
1449 if with_scrollkeeper:
1450 if not conf.CheckScrollkeeperConfig():
1451 with_scrollkeeper=False
1452 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
1453
1454 # TODO: -D_HPUX_SOURCE is needed
1455
1456 # TODO: check size of void*
1457
1458 # TODO: detect if dynamic libraries are possible or not
1459
1460 if platform.system()=="Windows" and env.has_key('MSVS'):
1461 _found_windows_h = conf.CheckHeader('Windows.h')
1462
1463 if not _found_windows_h:
1464 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1465 Exit(1)
1466
1467 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1468 with_python = 0;
1469 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1470
1471 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1472
1473 conf.Finish()
1474
1475 #---------------------------------------
1476 # SUBSTITUTION DICTIONARY for .in files
1477
1478 release = env.get('RELEASE')
1479 if release=="0.":
1480 release="0"
1481
1482 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1483
1484 subst_dict = {
1485 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1486 , '@GLADE_FILE@':'ascend.glade'
1487 , '@HELP_ROOT@':''
1488 , '@ICON_EXTENSION@':icon_extension
1489 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1490 , '@INSTALL_BIN@':env['INSTALL_BIN']
1491 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1492 , '@INSTALL_LIB@':env['INSTALL_LIB']
1493 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1494 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1495 , '@VERSION@':version
1496 , '@RELEASE@':release
1497 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1498 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1499 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1500 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1501 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1502 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1503 , '@PYTHON@' : python_exe
1504 , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1505 , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1506 , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_LIBPATH"))
1507 , '@SOURCE_ROOT@':os.path.abspath(str(env.Dir("#")))
1508 }
1509
1510 if env.get('WITH_LOCAL_HELP'):
1511 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1512 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1513
1514 # bool options...
1515 for k,v in {
1516 'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1517 ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1518 ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1519 }.iteritems():
1520 if env.get(k):
1521 # subst_dict['@'+v+'@']='1'
1522 subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1523
1524 if with_ida:
1525 subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1526
1527 if with_dmalloc:
1528 subst_dict["/\\* #define ASC_WITH_DMALLOC @ASC_WITH_DMALLOC@ \\*/"]='#define ASC_WITH_DMALLOC '
1529
1530 if with_conopt:
1531 subst_dict["/\\* #define ASC_WITH_CONOPT @ASC_WITH_CONOPT@ \\*/"]='#define ASC_WITH_CONOPT '
1532
1533 if with_lsode:
1534 subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1535
1536 if with_python:
1537 subst_dict['@ASCXX_USE_PYTHON@']="1"
1538 env['WITH_PYTHON']=1;
1539
1540 if env.has_key('HAVE_GCCVISIBILITY'):
1541 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1542
1543 env.Append(SUBST_DICT=subst_dict)
1544
1545 #------------------------------------------------------
1546 # RECIPE: Fix up long command-line bug on Win2k
1547
1548 # Currently this is broken, awaiting help from the SCons users list
1549
1550 if 0 and env['PLATFORM'] == 'win32':
1551 import win32file
1552 import win32event
1553 import win32process
1554 import win32security
1555 import string
1556
1557 def my_spawn(sh, escape, cmd, args, spawnenv):
1558 for var in spawnenv:
1559 spawnenv[var] = spawnenv[var].encode('ascii', 'replace')
1560
1561 sAttrs = win32security.SECURITY_ATTRIBUTES()
1562 StartupInfo = win32process.STARTUPINFO()
1563 newargs = string.join(map(escape, args[1:]), ' ')
1564 cmdline = cmd + " " + newargs
1565
1566 # check for any special operating system commands
1567 if cmd == 'del':
1568 for arg in args[1:]:
1569 win32file.DeleteFile(arg)
1570 exit_code = 0
1571 else:
1572 # otherwise execute the command.
1573 hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo)
1574 win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
1575 exit_code = win32process.GetExitCodeProcess(hProcess)
1576 win32file.CloseHandle(hProcess);
1577 win32file.CloseHandle(hThread);
1578 return exit_code
1579
1580 env['SPAWN'] = my_spawn
1581
1582 #------------------------------------------------------
1583 # RECIPE: SWIG scanner
1584
1585 import SCons.Script
1586
1587 SWIGScanner = SCons.Scanner.ClassicCPP(
1588 "SWIGScan"
1589 , ".i"
1590 , "CPPPATH"
1591 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1592 )
1593
1594 env.Append(SCANNERS=[SWIGScanner])
1595
1596 #------------------------------------------------------
1597 # RECIPE: 'SubstInFile', used in pygtk SConscript
1598
1599 import re
1600 from SCons.Script import * # the usual scons stuff you get in a SConscript
1601
1602 def TOOL_SUBST(env):
1603 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1604 from the source to the target.
1605 The values of SUBST_DICT first have any construction variables expanded
1606 (its keys are not expanded).
1607 If a value of SUBST_DICT is a python callable function, it is called and
1608 the result is expanded as the value.
1609 If there's more than one source and more than one target, each target gets
1610 substituted from the corresponding source.
1611 """
1612 env.Append(TOOLS = 'SUBST')
1613 def do_subst_in_file(targetfile, sourcefile, dict):
1614 """Replace all instances of the keys of dict with their values.
1615 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1616 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1617 """
1618 try:
1619 f = open(sourcefile, 'rb')
1620 contents = f.read()
1621 f.close()
1622 except:
1623 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1624 for (k,v) in dict.items():
1625 contents = re.sub(k, v, contents)
1626 try:
1627 f = open(targetfile, 'wb')
1628 f.write(contents)
1629 f.close()
1630 except:
1631 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1632 return 0 # success
1633
1634 def subst_in_file(target, source, env):
1635 if not env.has_key('SUBST_DICT'):
1636 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1637 d = dict(env['SUBST_DICT']) # copy it
1638 for (k,v) in d.items():
1639 if callable(v):
1640 d[k] = env.subst(v())
1641 elif SCons.Util.is_String(v):
1642 d[k]=env.subst(v)
1643 else:
1644 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1645 for (t,s) in zip(target, source):
1646 return do_subst_in_file(str(t), str(s), d)
1647
1648 def subst_in_file_string(target, source, env):
1649 """This is what gets printed on the console."""
1650 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1651 for (t,s) in zip(target, source)])
1652
1653 def subst_emitter(target, source, env):
1654 """Add dependency from substituted SUBST_DICT to target.
1655 Returns original target, source tuple unchanged.
1656 """
1657 d = env['SUBST_DICT'].copy() # copy it
1658 for (k,v) in d.items():
1659 if callable(v):
1660 d[k] = env.subst(v())
1661 elif SCons.Util.is_String(v):
1662 d[k]=env.subst(v)
1663 Depends(target, SCons.Node.Python.Value(d))
1664 return target, source
1665
1666 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1667 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1668
1669 TOOL_SUBST(env)
1670
1671 #------------------------------------------------------
1672 # Recipe for 'CHMOD' ACTION
1673
1674 import SCons
1675 from SCons.Script.SConscript import SConsEnvironment
1676 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1677 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1678
1679 def InstallPerm(env, dest, files, perm):
1680 obj = env.Install(dest, files)
1681 for i in obj:
1682 env.AddPostAction(i, env.Chmod(str(i), perm))
1683
1684 SConsEnvironment.InstallPerm = InstallPerm
1685
1686 # define wrappers
1687 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1688 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1689 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1690
1691 #------------------------------------------------------
1692 # BUILD...
1693
1694 # so that #include <modulename/headername.h> works across all modules...
1695 env.AppendUnique(CPPPATH=['#base/generic'])
1696
1697 if env['DEBUG']:
1698 env.Append(CCFLAGS=['-g'])
1699
1700 if env['GCOV']:
1701 env.Append(
1702 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1703 , LIBS=['gcov']
1704 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1705 )
1706
1707 if with_ida:
1708 env.Append(WITH_IDA=1)
1709
1710 if with_conopt:
1711 env.Append(WITH_CONOPT=1)
1712
1713 #-------------
1714 # TCL/TK GUI
1715
1716 if with_tcltk:
1717 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1718 else:
1719 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1720
1721 #-------------
1722 # PYTHON INTERFACE
1723
1724 if with_python:
1725 env.SConscript(['pygtk/SConscript'],'env')
1726 else:
1727 print "Skipping... Python GUI isn't being built:",without_python_reason
1728
1729 #------------
1730 # BASE/GENERIC SUBDIRECTORIES
1731
1732 libascend_env = env.Copy()
1733
1734 dirs = ['general','utilities','compiler','solver','packages']
1735
1736 srcs = []
1737 for d in dirs:
1738 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1739 srcs += heresrcs
1740
1741 #-------------
1742 # IMPORTED CODE: LSODE, BLAS, etc
1743
1744 if with_lsode:
1745 srcs += env.SConscript(['lsod/SConscript'],'env')
1746 srcs += env.SConscript(['linpack/SConscript'],'env')
1747 else:
1748 print "Skipping... LSODE won't be built:", without_lsode_reason
1749
1750 if with_local_blas:
1751 srcs += env.SConscript(['blas/SConscript'],'env')
1752 else:
1753 print "Skipping... BLAS won't be built:", without_local_blas_reason
1754
1755 if not with_ida:
1756 print "Skipping... IDA won't be built:", without_ida_reason
1757
1758 #-------------
1759 # LIBASCEND -- all base/generic functionality
1760
1761 if with_dmalloc:
1762 libascend_env.Append(LIBS=['dmalloc'])
1763
1764 libascend = libascend_env.SharedLibrary('ascend',srcs)
1765
1766 env.Alias('libascend',libascend)
1767
1768 #-------------
1769 # UNIT TESTS (C CODE)
1770
1771 if with_cunit:
1772 testdirs = ['general','solver','utilities']
1773 testsrcs = []
1774 for testdir in testdirs:
1775 path = 'base/generic/'+testdir+'/test/'
1776 env.SConscript([path+'SConscript'],'env')
1777 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1778
1779 #print "TESTSRCS =",testsrcs
1780
1781 env.SConscript(['test/SConscript'],'env')
1782 env.SConscript(['base/generic/test/SConscript'],'env')
1783
1784 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1785
1786 else:
1787 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1788
1789 #-------------
1790 # EXTERNAL FUNCTIONS
1791
1792 env['extfns']=[]
1793 modeldirs = env.SConscript(['models/SConscript'],'env')
1794
1795 if not with_extfns:
1796 print "Skipping... External modules aren't being built:",without_extfns_reason
1797
1798 env.Alias('extfns',env['extfns'])
1799
1800 #------------------------------------------------------
1801 # CREATE ASCEND-CONFIG scriptlet
1802
1803 ascendconfig = env.SubstInFile('ascend-config.in')
1804
1805 #------------------------------------------------------
1806 # INSTALLATION
1807
1808 if env.get('CAN_INSTALL'):
1809
1810 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE', 'INSTALL_DOC']
1811 install_dirs = [env.Entry(env['INSTALL_ROOT']+env[d]) for d in dirs]
1812 install_dirs += modeldirs
1813
1814 # TODO: add install options
1815 env.Alias('install',install_dirs)
1816
1817 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1818
1819 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1820
1821 #------------------------------------------------------
1822 # WINDOWS INSTALLER
1823 # For the windows installer, please see pygtk/SConscript
1824
1825 if with_installer:
1826 pass
1827 else:
1828 print "Skipping... Windows installer isn't being built:",without_installer_reason
1829
1830 #------------------------------------------------------
1831 # PROJECT FILE for MSVC
1832
1833 env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1834
1835 #------------------------------------------------------
1836 # CREATE the SPEC file for generation of RPM packages
1837
1838 if platform.system()=="Linux":
1839 env.SubstInFile('ascend.spec.in')
1840
1841 #------------------------------------------------------
1842 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
1843
1844 if with_scrollkeeper:
1845 env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
1846 env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
1847
1848 #------------------------------------------------------
1849 # DISTRIBUTION TAR FILE
1850
1851 env['DISTTAR_FORMAT']='bz2'
1852 env.Append(
1853 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl','.out']
1854 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1855 )
1856
1857 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1858 , [env.Dir('#')]
1859 )
1860
1861 env.Depends(tar,'ascend.spec')
1862
1863 Alias('dist',tar)
1864
1865 #------------------------------------------------------
1866 # USER'S MANUAL
1867
1868 env.SConscript('doc/SConscript',['env'])
1869
1870 #------------------------------------------------------
1871 # LIBASCEND DOXYGEN DOCUMENTATION
1872
1873 env.SConscript('base/doc/SConscript',['env'])
1874
1875 #------------------------------------------------------
1876 # RPM BUILD
1877
1878 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
1879 # (check * for the version number used to create the tarball)
1880
1881 #------------------------------------------------------
1882 # DEFAULT TARGETS
1883
1884 default_targets =['libascend']
1885 if with_tcltk:
1886 default_targets.append('tcltk')
1887 if with_python:
1888 default_targets.append('pygtk')
1889 if with_installer:
1890 default_targets.append('installer')
1891 if with_extfns:
1892 default_targets.append('extfns')
1893
1894 env.Default(default_targets)
1895
1896 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1897
1898 # vim: set syntax=python:
1899

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