/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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