/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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