/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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