/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 742 - (show annotations) (download)
Thu Jul 6 13:47:41 2006 UTC (13 years, 5 months ago) by johnpye
File size: 35081 byte(s)
I think this almost resolves all the Visual C++ issues.
Just an outstanding issue with the use of the option struct in LibraryProc.c
eg use of &g_compiler_warnings in initialiser.
1 import os, commands, platform, distutils.sysconfig, os.path
2
3 version = "0.9.5.94"
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 need_libm = False
33 python_exe = "c:\\Python24\\python.exe"
34 else:
35 default_tcl_lib = "tcl8.4"
36 default_tk_lib = "tk8.4"
37 default_tktable_lib = "Tktable2.8"
38 default_install_assets = "$INSTALL_ASCDATA/glade/"
39 icon_extension = '.svg'
40 default_tcl = '/usr'
41 default_tcl_libpath = "$TCL/lib"
42 default_rel_distdir = '../share/ascend'
43 default_absolute_paths = True
44 default_ida_prefix="/usr/local"
45 need_libm = True
46 if not os.path.isdir(default_tcl):
47 default_tcl = '/usr'
48 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
49
50 opts.Add(
51 'CC'
52 ,'C Compiler command'
53 ,None
54 )
55
56 opts.Add(
57 'CXX'
58 ,'C++ Compiler command'
59 ,None
60 )
61
62 opts.Add(BoolOption(
63 'GCOV'
64 , 'Whether to enable coverage testing in object code'
65 , False
66 ))
67
68 # Package linking option
69 opts.Add(EnumOption(
70 'PACKAGE_LINKING'
71 , 'Style of linking for external libraries'
72 , 'DYNAMIC_PACKAGES'
73 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
74 ))
75
76 opts.Add(BoolOption(
77 'WITH_GCCVISIBILITY'
78 ,"Whether to use GCC Visibility features (only applicable if available)"
79 ,True
80 ))
81
82 # You can turn off building of Tcl/Tk interface
83 opts.Add(BoolOption(
84 'WITH_TCLTK'
85 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
86 , True
87 ))
88
89 # You can turn off the building of the Python interface
90 opts.Add(BoolOption(
91 'WITH_PYTHON'
92 ,"Set to False if you don't want to build Python wrappers."
93 , True
94 ))
95
96 # Which solvers will we allow?
97 opts.Add(ListOption(
98 'WITH_SOLVERS'
99 ,"List of the solvers you want to build. The default is the minimum that"
100 +" works."
101 ,["QRSLV","CMSLV","LSOD","IDA"]
102 ,['QRSLV','MPS','SLV','OPTSQP'
103 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
104 ,'LSOD','OPTSQP',"IDA"
105 ]
106 ))
107
108 # Where will the local copy of the help files be kept?
109 opts.Add(PackageOption(
110 'WITH_LOCAL_HELP'
111 , "Directory containing the local copy of the help files (optional)"
112 , "no"
113 ))
114
115 # Will bintoken support be enabled?
116 opts.Add(BoolOption(
117 'WITH_BINTOKEN'
118 ,"Enable bintoken support? This means compiling models as C-code before"
119 +" running them, to increase solving speed for large models."
120 ,False
121 ))
122
123 # What should the default ASCENDLIBRARY path be?
124 # Note: users can change it by editing their ~/.ascend.ini
125 opts.Add(
126 'DEFAULT_ASCENDLIBRARY'
127 ,"Set the default value of the ASCENDLIBRARY -- the location where"
128 +" ASCEND will look for models when running ASCEND"
129 ,"$INSTALL_ASCDATA/models"
130 )
131
132 # Where is SWIG?
133 opts.Add(
134 'SWIG'
135 ,"SWIG location, probably only required for MinGW and MSVC users."
136 +" Enter the location as a Windows-style path, for example"
137 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
138 )
139
140 # Build the test suite?
141 opts.Add(BoolOption(
142 'WITH_CUNIT'
143 ,"You can disable CUnit tests with this option. This will basically stop"
144 +" SCons from parsing the SConscript files relating to the 'test'"
145 +" target, which just might make things marginally faster. Probably"
146 +" you can just ignore this option though. SCons will sniff for Cunit"
147 +" but build the tests only if you specify the 'test' target."
148 ,True
149 ))
150
151 # Where are the CUnit includes?
152 opts.Add(PackageOption(
153 'CUNIT_CPPPATH'
154 ,"Where are your CUnit include files?"
155 ,'off'
156 ))
157
158 # Where are the CUnit libraries?
159 opts.Add(PackageOption(
160 'CUNIT_LIBPATH'
161 ,"Where are your CUnit libraries?"
162 ,'off'
163 ))
164
165 opts.Add(PackageOption(
166 "IDA_PREFIX"
167 ,"Prefix for your IDA install (IDA ./configure --prefix)"
168 ,default_ida_prefix
169 ))
170
171 opts.Add(
172 'IDA_CPPPATH'
173 ,"Where is your ida.h?"
174 ,"$IDA_PREFIX/include"
175 )
176
177 opts.Add(
178 'IDA_LIBPATH'
179 ,"Where are your SUNDIALS libraries installed?"
180 ,"$IDA_PREFIX/lib"
181 )
182
183 opts.Add(
184 "IDA_LIB"
185 ,"What libraries to link to for use of IDA (comma-separated). Note that"
186 +" you will need to include the math library in this list (for now)."
187 ,'sundials_ida,sundials_nvecserial,m'
188 )
189
190 opts.Add(
191 "F2C_LIB"
192 ,"F2C library (eg. g2c, gfortran, f2c)"
193 ,"g2c"
194 )
195
196 opts.Add(PackageOption(
197 "F2C_LIBPATH"
198 ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
199 ,"off"
200 ))
201
202 opts.Add(
203 'TCL'
204 ,'Base of Tcl distribution'
205 ,default_tcl
206 )
207
208 # Where are the Tcl includes?
209 opts.Add(
210 'TCL_CPPPATH'
211 ,"Where are your Tcl include files?"
212 ,"$TCL/include"
213 )
214
215 # Where are the Tcl libs?
216 opts.Add(
217 'TCL_LIBPATH'
218 ,"Where are your Tcl libraries?"
219 ,default_tcl_libpath
220 )
221
222 # What is the name of the Tcl lib?
223 opts.Add(
224 'TCL_LIB'
225 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
226 ,default_tcl_lib
227 )
228
229 # Where are the Tk includes?
230 opts.Add(
231 'TK_CPPPATH'
232 ,"Where are your Tk include files?"
233 ,'$TCL_CPPPATH'
234 )
235
236 # Where are the Tk libs?
237 opts.Add(
238 'TK_LIBPATH'
239 ,"Where are your Tk libraries?"
240 ,'$TCL_LIBPATH'
241 )
242
243 # What is the name of the Tk lib?
244 opts.Add(
245 'TK_LIB'
246 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
247 ,default_tk_lib
248 )
249
250 # Static linking to TkTable
251
252 opts.Add(BoolOption(
253 'STATIC_TCLTK'
254 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
255 ,False
256 ))
257
258 opts.Add(
259 'TKTABLE_LIBPATH'
260 ,'Location of TkTable static library'
261 ,'$TCL_LIBPATH/Tktable2.8'
262 )
263
264 opts.Add(
265 'TKTABLE_LIB'
266 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
267 ,default_tktable_lib
268 )
269
270 opts.Add(
271 'TKTABLE_CPPPATH'
272 ,'Location of TkTable header file'
273 ,'$TCL_CPPPATH'
274 )
275
276 opts.Add(
277 'X11'
278 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
279 ,'/usr/X11R6'
280 )
281
282 opts.Add(
283 'X11_LIBPATH'
284 ,'Location of X11 lib. EXPERIMENTAL'
285 ,'$X11/lib'
286 )
287
288 opts.Add(
289 'X11_CPPPATH'
290 ,'Location of X11 includes. EXPERIMENTAL'
291 ,'$X11/include'
292 )
293
294 opts.Add(
295 'X11_LIB'
296 ,'Name of X11 lib. EXPERIMENTAL'
297 ,'X11'
298 )
299
300 opts.Add(
301 'INSTALL_PREFIX'
302 ,'Root location for installed files'
303 ,'/usr/local'
304 )
305
306 opts.Add(
307 'INSTALL_BIN'
308 ,'Location to put binaries during installation'
309 ,"$INSTALL_PREFIX/bin"
310 )
311
312 opts.Add(
313 'INSTALL_LIB'
314 ,'Location to put libraries during installation'
315 ,"$INSTALL_PREFIX/lib"
316 )
317
318 opts.Add(
319 'INSTALL_SHARE'
320 ,'Common shared-file location on this system'
321 ,"$INSTALL_PREFIX/share"
322 )
323
324
325 opts.Add(
326 'INSTALL_ASCDATA'
327 ,"Location of ASCEND shared data (TK, python, models etc)"
328 ,"$INSTALL_SHARE/ascend"
329 )
330
331 opts.Add(
332 'INSTALL_INCLUDE'
333 ,'Location to put header files during installation'
334 ,"$INSTALL_PREFIX/include"
335 )
336
337 opts.Add(
338 'PYGTK_ASSETS'
339 ,'Default location for Glade assets (placed in pygtk/config.py)'
340 ,default_install_assets
341 )
342
343 opts.Add(BoolOption(
344 'DEBUG'
345 ,"Compile source with debugger symbols, eg for use with 'gdb'"
346 ,False
347 ))
348
349 opts.Add(BoolOption(
350 'MALLOC_DEBUG'
351 ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
352 ,False
353 ))
354
355 opts.Add(
356 'INSTALL_ROOT'
357 ,'For use by RPM only: location of %{buildroot} during rpmbuild'
358 ,""
359 )
360
361 opts.Add(
362 'DISTTAR_NAME'
363 ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
364 ,"ascend-"+version
365 )
366
367 opts.Add(
368 'RELEASE'
369 ,"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."
370 ,"0"
371 )
372
373 opts.Add(BoolOption(
374 'ABSOLUTE_PATHS'
375 ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
376 ,default_absolute_paths
377 ))
378
379 opts.Add(
380 'WIN_INSTALLER_NAME'
381 ,"Name of the installer .exe to create under Windows (minus the '.exe')"
382 ,"ascend-"+version
383 )
384
385 opts.Add(BoolOption(
386 'WITH_XTERM_COLORS'
387 ,"Set to 0 if you don't want xterm colour codes in the console output"
388 ,True
389 ))
390
391 if platform.system()!="Windows":
392 opts.Add(BoolOption(
393 'WITH_GCCVISIBILITY'
394 , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
395 , True
396 ))
397
398 # TODO: OTHER OPTIONS?
399 # TODO: flags for optimisation
400 # TODO: turning on/off bintoken functionality
401 # TODO: Where will the 'Makefile.bt' file be installed?
402
403 # Import the outside environment
404
405 if os.environ.get('OSTYPE')=='msys':
406 env = Environment(
407 ENV=os.environ
408 , tools=['mingw','lex','yacc','fortran','swig','disttar','nsis']
409 , toolpath=['scons']
410 )
411 env['IS_MINGW']=True
412
413 elif platform.system()=="Windows":
414 env = Environment(
415 ENV={
416 'PATH':os.environ['PATH']
417 ,'INCLUDE':os.environ['INCLUDE']
418 ,'LIB':os.environ['LIB']
419 ,'MSVS_IGNORE_IDE_PATHS':1
420 }
421 , tools = ['default','lex','yacc','fortran','swig','disttar','nsis']
422 , toolpath = ['scons']
423 )
424 env.Append(CPPDEFINES=['_CRT_SECURE_NO_DEPRECATE'])
425 else:
426 env = Environment(
427 ENV=os.environ
428 , tools=['default','lex','yacc','fortran','swig','disttar','nsis']
429 , toolpath=['scons']
430 )
431
432 opts.Update(env)
433 opts.Save('options.cache',env)
434
435 Help(opts.GenerateHelpText(env))
436
437 with_tcltk = env.get('WITH_TCLTK')
438 without_tcltk_reason = "disabled by options/config.py"
439
440 with_python = env.get('WITH_PYTHON')
441 without_python_reason = "disabled by options/config.py"
442
443 with_cunit = env.get('WITH_CUNIT')
444 without_cunit_reason = "not requested"
445
446 if platform.system()=="Windows":
447 with_installer=1
448 else:
449 with_installer=0
450 without_installer_reason = "only possible under Windows"
451
452 if 'LSOD' in env['WITH_SOLVERS']:
453 with_lsode=True
454 else:
455 with_lsode=False
456 without_lsode_reason = "not requested (WITH_SOLVERS)"
457
458 if 'IDA' in env['WITH_SOLVERS']:
459 with_ida=True
460 else:
461 with_ida=False
462 without_ida_reason = "not requested (WITH_SOLVERS)"
463
464
465 #print "SOLVERS:",env['WITH_SOLVERS']
466 #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
467 #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
468
469 can_install = True
470 if platform.system()=='Windows':
471 can_install = False
472
473 env['CAN_INSTALL']=can_install
474
475 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
476
477 print "TCL_CPPPATH =",env['TCL_CPPPATH']
478 print "TCL_LIBPATH =",env['TCL_LIBPATH']
479 print "TCL_LIB =",env['TCL_LIB']
480 print "CC =",env['CC']
481 print "CXX =",env['CXX']
482 print "FORTRAN=",env.get('FORTRAN')
483
484 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
485 #------------------------------------------------------
486 # SPECIAL CONFIGURATION TESTS
487
488 need_fortran = False
489
490 #----------------
491 # SWIG
492
493 import os,re
494
495 def get_swig_version(env):
496 cmd = env['SWIG']+' -version'
497 (cin,coutcerr) = os.popen4(cmd)
498 output = coutcerr.read()
499
500 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
501 expr = re.compile(restr,re.M);
502 m = expr.search(output);
503 if not m:
504 return None
505 maj = int(m.group('maj'))
506 min = int(m.group('min'))
507 pat = int(m.group('pat'))
508
509 return (maj,min,pat)
510
511
512 def CheckSwigVersion(context):
513
514 try:
515 context.Message("Checking version of SWIG... ")
516 maj,min,pat = get_swig_version(context.env)
517 except:
518 context.Result("Failed to detect version, or failed to run SWIG")
519 return 0;
520
521 context.env['SWIGVERSION']=tuple([maj,min,pat])
522
523 if maj == 1 and (
524 min > 3
525 or (min == 3 and pat >= 24)
526 ):
527 context.Result("ok, %d.%d.%d" % (maj,min,pat))
528 return 1;
529 else:
530 context.Result("too old, %d.%d.%d" % (maj,min,pat))
531 return 0;
532
533 #----------------
534 # General purpose library-and-header test
535
536 class KeepContext:
537 def __init__(self,context,varprefix,static=False):
538 self.keep = {}
539 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
540 #print "Keeping env %s = %s" % (k,context.env.get(k))
541 self.keep[k]=context.env.get(k)
542
543 if context.env.has_key(varprefix+'_CPPPATH'):
544 context.env.Append(CPPPATH=[env[varprefix+'_CPPPATH']])
545 #print "Adding '"+str(cpppath_add)+"' to cpp path"
546
547 if static:
548 staticlib=env[varprefix+'_LIB']
549 #print "STATIC LIB = ",staticlib
550 context.env.Append(
551 LINKFLAGS=[staticlib]
552 )
553 else:
554 if context.env.has_key(varprefix+'_LIBPATH'):
555 context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
556 #print "Adding '"+str(libpath_add)+"' to lib path"
557
558 if context.env.has_key(varprefix+'_LIB'):
559 context.env.Append(LIBS=[env[varprefix+'_LIB']])
560 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
561
562 def restore(self,context):
563 #print "RESTORING CONTEXT"
564 #print self.keep
565 #print "..."
566 for k in self.keep:
567 if self.keep[k]==None:
568 if context.env.has_key(k):
569 #print "Clearing "+str(k)
570 del context.env[k];
571 else:
572 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
573 context.env[k]=self.keep[k];
574
575 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
576 """This method will check for variables LIBNAME_LIBPATH
577 and LIBNAME_CPPPATH and try to compile and link the
578 file with the provided text, linking with the
579 library libname."""
580
581 if static:
582 context.Message( 'Checking for static '+libname+'... ' )
583 else:
584 context.Message( 'Checking for '+libname+'... ' )
585
586 if varprefix==None:
587 varprefix = libname.upper()
588
589 #print "LIBS is currently:",context.env.get('LIBS')
590 keep = KeepContext(context,varprefix,static)
591
592 if not context.env.has_key(varprefix+'_LIB'):
593 # if varprefix_LIB were in env, KeepContext would
594 # have appended it already
595 context.env.Append(LIBS=[libname])
596
597 is_ok = context.TryLink(text,ext)
598
599 #print "Link success? ",(is_ok != 0)
600
601 keep.restore(context)
602
603 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
604 # print "Restored LIBS="+str(context.env['LIBS'])
605 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
606
607 context.Result(is_ok)
608 return is_ok
609
610 #----------------
611 # GCC
612
613 gcc_test_text = """
614 #ifndef __GNUC__
615 # error "Not using GCC"
616 #endif
617
618 int main(void){
619 return __GNUC__;
620 }
621 """
622
623 def CheckGcc(context):
624 context.Message("Checking for GCC... ")
625 is_ok = context.TryCompile(gcc_test_text,".c")
626 context.Result(is_ok)
627 return is_ok
628
629 #----------------
630 # GCC VISIBILITY feature
631
632 gccvisibility_test_text = """
633 #if __GNUC__ < 4
634 # error "Require GCC version 4 or newer"
635 #endif
636
637 __attribute__ ((visibility("default"))) int x;
638
639 int main(void){
640 extern int x;
641 x = 4;
642 }
643 """
644
645 def CheckGccVisibility(context):
646 context.Message("Checking for GCC 'visibility' capability... ")
647 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
648 context.Result("disabled")
649 return 0
650 is_ok = context.TryCompile(gccvisibility_test_text,".c")
651 context.Result(is_ok)
652 return is_ok
653
654 #----------------
655 # YACC
656
657 yacc_test_text = """
658 %{
659 #include <stdio.h>
660
661 /* MSVC++ needs this before it can swallow Bison output */
662 #ifdef _MSC_VER
663 # define __STDC__
664 #endif
665 %}
666 %token MSG
667 %start ROOT
668 %%
669 ROOT:
670 MSG { printf("HELLO"); }
671 ;
672 %%
673 """
674
675 def CheckYacc(context):
676 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
677 is_ok = context.TryCompile(yacc_test_text,".y")
678 context.Result(is_ok)
679 return is_ok
680
681 #----------------
682 # CUnit test
683
684 cunit_test_text = """
685 #include <CUnit/CUnit.h>
686 int maxi(int i1, int i2){
687 return (i1 > i2) ? i1 : i2;
688 }
689
690 void test_maxi(void){
691 CU_ASSERT(maxi(0,2) == 2);
692 CU_ASSERT(maxi(0,-2) == 0);
693 CU_ASSERT(maxi(2,2) == 2);
694
695 }
696 int main(void){
697 /* CU_initialize_registry() */
698 return 0;
699 }
700 """
701
702 def CheckCUnit(context):
703 return CheckExtLib(context,'cunit',cunit_test_text)
704
705 #----------------
706 # MATH test
707
708 math_test_text = """
709 #ifndef _ALL_SOURCE
710 # define _ALL_SOURCE
711 #endif
712 #ifndef _XOPEN_SOURCE
713 # define _XOPEN_SOURCE
714 #endif
715 #ifndef _XOPEN_SOURCE_EXTENDED
716 # define _XOPEN_SOURCE_EXTENDED 1
717 #endif
718 #include <math.h>
719 int main(void){
720 double x = 1.0; double y = 1.0; int i = 1;
721 acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
722 j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
723 y0(x); y1(x); yn(i,x);
724 #ifdef _THREAD_SAFE
725 gamma_r(x,&i);
726 lgamma_r(x,&i);
727 #else
728 gamma(x);
729 lgamma(x);
730 #endif
731 hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
732 return 0;
733 }
734 """
735
736 def CheckMath(context):
737 context.Message('Checking for IEE math library... ')
738 libsave=context.env.get('LIBS');
739 context.env.AppendUnique(LIBS=['m'])
740 is_ok=context.TryLink(math_test_text,".c")
741 context.Result(is_ok)
742 if not is_ok:
743 context.env['LIBS']=libsave
744 return is_ok
745
746 #----------------
747 # IDA test
748
749 ida_test_text = """
750 #include <ida.h>
751 #include <nvector_serial.h>
752 #include <ida_spgmr.h>
753 int main(){
754 void *ida_mem;
755 ida_mem = IDACreate();
756 }
757 """
758
759 def CheckIDA(context):
760 context.Message( 'Checking for IDA (SUNDIALS)... ' )
761
762 # add SUNDIALS subdirectories as well (what a pain)
763 if context.env.get('IDA_CPPPATH'):
764 extra = [context.env['IDA_CPPPATH']+"/ida",context.env['IDA_CPPPATH']+"/sundials"]
765 context.env.Append(CPPPATH=extra)
766
767 if ',' in context.env.get('IDA_LIB'):
768 context.env['IDA_LIB']=context.env['IDA_LIB'].split(',')
769 #print "IDA_LIB NOW =",context.env['IDA_LIB']
770 else:
771 print "NO COMMA IN IDA_LIB:",context.env['IDA_LIB']
772
773 keep = KeepContext(context,"IDA")
774
775 is_ok = context.TryLink(ida_test_text,".c")
776 context.Result(is_ok)
777
778 keep.restore(context)
779
780 if is_ok:
781 context.env.Append(IDA_CPPPATH_EXTRA=extra)
782
783 return is_ok
784
785 #----------------
786 # Tcl test
787
788 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
789 tcltk_minor_newest_acceptable = 4
790 tcltk_major_required = 8
791
792 tcl_check_text = r"""
793 #include <tcl.h>
794 #include <stdio.h>
795 int main(void){
796 printf("%s",TCL_PATCH_LEVEL);
797 return 0;
798 }
799 """
800
801 def CheckTcl(context):
802 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
803
804 def CheckTclVersion(context):
805 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
806 context.Message("Checking Tcl version... ")
807 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
808 keep.restore(context)
809 if not is_ok:
810 context.Result("failed to run check")
811 return 0
812
813 major,minor,patch = tuple([int(i) for i in output.split(".")])
814 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
815 context.Result(output+" (bad version)")
816 # bad version
817 return 0
818
819 # good version
820 context.Result(output+", good")
821 return 1
822
823 #----------------
824 # Tk test
825
826 tk_check_text = r"""
827 #include <tk.h>
828 #include <stdio.h>
829 int main(void){
830 printf("%s",TK_PATCH_LEVEL);
831 return 0;
832 }
833 """
834 def CheckTk(context):
835 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
836
837
838 def CheckTkVersion(context):
839 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
840 context.Message("Checking Tk version... ")
841 #print "LINKFLAGS =",context.env['LINKFLAGS']
842 (is_ok,output) = context.TryRun(tk_check_text,'.c')
843 keep.restore(context)
844 if not is_ok:
845 context.Result("failed to run check")
846 return 0
847
848 major,minor,patch = tuple([int(i) for i in output.split(".")])
849 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
850 # bad version
851 context.Result(output+" (bad version)")
852 return 0
853
854 # good version
855 context.Result(output+" (good)")
856 return 1
857
858 #----------------
859 # Tktable test
860
861 tktable_check_text = r"""
862 #include <tkTable.h>
863 #include <stdio.h>
864 int main(void){
865 Table mytable;
866 return 0;
867 }
868 """
869
870 def CheckTkTable(context):
871 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
872
873 #---------------
874 # X11 test
875
876 x11_check_text = r"""
877 #include <X11/Xlib.h>
878 #include <X11/IntrinsicP.h>
879 #include <X11/Intrinsic.h>
880 #include <X11/ObjectP.h>
881 #include <X11/Object.h>
882 int main(void){
883 Object mything;
884 return 0;
885 }
886 """
887
888 def CheckX11(context):
889 return CheckExtLib(context,'X11',x11_check_text)
890
891 #----------------
892 # GCC Version sniffing
893
894 # TODO FIXME
895
896 gcc_version4 = False
897
898 #------------------------------------------------------
899 # CONFIGURATION
900
901 conf = Configure(env
902 , custom_tests = {
903 'CheckMath' : CheckMath
904 , 'CheckSwigVersion' : CheckSwigVersion
905 , 'CheckCUnit' : CheckCUnit
906 , 'CheckTcl' : CheckTcl
907 , 'CheckTclVersion' : CheckTclVersion
908 , 'CheckTk' : CheckTk
909 , 'CheckTkVersion' : CheckTkVersion
910 , 'CheckGcc' : CheckGcc
911 , 'CheckGccVisibility' : CheckGccVisibility
912 , 'CheckYacc' : CheckYacc
913 , 'CheckTkTable' : CheckTkTable
914 , 'CheckX11' : CheckX11
915 , 'CheckIDA' : CheckIDA
916 # , 'CheckIsNan' : CheckIsNan
917 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
918 }
919 # , config_h = "config.h"
920 )
921
922 # stdio -- just to check that compiler is behaving
923
924 if not conf.CheckHeader('stdio.h'):
925 print "Did not find 'stdio.h'! Check your compiler configuration."
926 Exit(1)
927
928 # Math library
929
930 if need_libm:
931 if not conf.CheckMath():
932 print 'Did not find math library, exiting!'
933 Exit(1)
934 #pass
935
936 # Where is 'isnan'?
937
938 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
939 print "Didn't find isnan"
940 # Exit(1)
941
942 # GCC visibility
943
944 if conf.CheckGcc():
945 conf.env['HAVE_GCC']=True;
946 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
947 conf.env['HAVE_GCCVISIBILITY']=True;
948 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
949 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
950 conf.env.Append(CCFLAGS=['-Wall'])
951
952 # YACC
953
954 if not conf.CheckYacc():
955 print "YACC NOT FOUND OR NOT WORKING"
956 else:
957 conf.env['HAVE_YACC']=True
958
959 conf.env['HAVE_LEX']=True
960
961 # Tcl/Tk
962
963 if with_tcltk:
964 if conf.CheckTcl():
965 if conf.CheckTclVersion():
966 if conf.CheckTk():
967 if with_tcltk and conf.CheckTkVersion():
968 if env['STATIC_TCLTK']:
969 if conf.CheckTkTable():
970 pass
971 else:
972 without_tcltk_reason = "TkTable not found"
973 with_tcltk = False
974 else:
975 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
976 with_tcltk = False
977 else:
978 without_tcltk_reason = "Tk not found."
979 with_tcltk = False
980 else:
981 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
982 with_tcltk = False
983
984 else:
985 without_tcltk_reason = "Tcl not found."
986 with_tcltk = False
987
988 if env['STATIC_TCLTK']:
989 conf.CheckX11()
990
991 # Python... obviously we're already running python, so we just need to
992 # check that we can link to the python library OK:
993
994 if platform.system()=="Windows":
995 python_lib='python24'
996 else:
997 python_lib='python2.4'
998
999 # SWIG version
1000
1001 if not conf.CheckSwigVersion():
1002 without_python_reason = 'SWIG >= 1.3.24 is required'
1003 with_python = False
1004
1005 # CUnit
1006
1007 if with_cunit:
1008 if not conf.CheckCUnit():
1009 without_cunit_reason = 'CUnit not found'
1010 with_cunit = False
1011 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1012
1013 # IDA
1014
1015 if not with_ida:
1016 without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1017 elif not conf.CheckIDA():
1018 with_ida = False
1019 without_ida_reason = "IDA not found"
1020
1021 # BLAS
1022
1023 need_blas=False
1024
1025 if with_lsode:
1026 need_fortran = True
1027 need_blas=True
1028
1029 if need_blas:
1030 if conf.CheckLib('blas'):
1031 with_local_blas = False
1032 without_local_blas_reason = "Found BLAS installed on system"
1033 else:
1034 with_local_blas = True
1035 need_fortran = True
1036 else:
1037 with_local_blas= False;
1038 without_local_blas_reason = "BLAS not required"
1039
1040 # FORTRAN
1041
1042 if need_fortran:
1043 conf.env.Tool('fortran')
1044 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1045 if detect_fortran:
1046 # For some reason, g77 doesn't get detected properly on MinGW
1047 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1048 conf.env.Replace(F77=detect_fortran)
1049 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1050 conf.env.Replace(F77FLAGS='')
1051 #print "F77:",conf.env['F77']
1052 #print "F77COM:",conf.env['F77COM']
1053 #print "F77FLAGS:",conf.env['F77FLAGS']
1054 fortran_builder = Builder(
1055 action='$F77COM'
1056 , suffix='.o'
1057 , src_suffix='.f'
1058 )
1059 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1060 else:
1061 with_lsode=False;
1062 without_lsode_reason="FORTRAN-77 required but not found"
1063
1064 #else:
1065 # print "FORTRAN not required"
1066
1067 # F2C
1068
1069 if need_fortran:
1070 if platform.system()=="Windows":
1071 conf.env.Append(LIBPATH='c:\mingw\lib')
1072
1073
1074 # TODO: -D_HPUX_SOURCE is needed
1075
1076 # TODO: check size of void*
1077
1078 # TODO: detect if dynamic libraries are possible or not
1079
1080 if platform.system()=="Windows" and env.has_key('MSVS'):
1081 _found_windows_h = conf.CheckHeader('Windows.h')
1082
1083 if not _found_windows_h:
1084 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1085 Exit(1)
1086
1087 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1088 with_python = 0;
1089 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1090
1091 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1092
1093 conf.Finish()
1094
1095 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
1096 env.Append(PYTHON_LIB=[python_lib])
1097 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
1098
1099 #---------------------------------------
1100 # SUBSTITUTION DICTIONARY for .in files
1101
1102 release = env.get('RELEASE')
1103 if release=="0.":
1104 release="0"
1105
1106 subst_dict = {
1107 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1108 , '@GLADE_FILE@':'ascend.glade'
1109 , '@HELP_ROOT@':''
1110 , '@ICON_EXTENSION@':icon_extension
1111 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1112 , '@INSTALL_BIN@':env['INSTALL_BIN']
1113 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1114 , '@INSTALL_LIB@':env['INSTALL_LIB']
1115 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1116 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1117 , '@VERSION@':version
1118 , '@RELEASE@':release
1119 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1120 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1121 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1122 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1123 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1124 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1125 , '@PYTHON@' : python_exe
1126 }
1127
1128 if env.get('WITH_LOCAL_HELP'):
1129 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1130 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1131
1132 # bool options...
1133 for k,v in {
1134 'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1135 ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1136 ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1137 }.iteritems():
1138 if env.get(k):
1139 # subst_dict['@'+v+'@']='1'
1140 subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1141
1142 if with_ida:
1143 subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1144
1145 if with_lsode:
1146 subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1147
1148 if with_python:
1149 subst_dict['@ASCXX_USE_PYTHON@']="1"
1150 env['WITH_PYTHON']=1;
1151
1152 if env.has_key('HAVE_GCCVISIBILITY'):
1153 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1154
1155 env.Append(SUBST_DICT=subst_dict)
1156
1157 #------------------------------------------------------
1158 # RECIPE: SWIG scanner
1159
1160 import SCons.Script
1161
1162 SWIGScanner = SCons.Scanner.ClassicCPP(
1163 "SWIGScan"
1164 , ".i"
1165 , "CPPPATH"
1166 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1167 )
1168
1169 env.Append(SCANNERS=[SWIGScanner])
1170
1171 #------------------------------------------------------
1172 # RECIPE: 'SubstInFile', used in pygtk SConscript
1173
1174 import re
1175 from SCons.Script import * # the usual scons stuff you get in a SConscript
1176
1177 def TOOL_SUBST(env):
1178 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1179 from the source to the target.
1180 The values of SUBST_DICT first have any construction variables expanded
1181 (its keys are not expanded).
1182 If a value of SUBST_DICT is a python callable function, it is called and
1183 the result is expanded as the value.
1184 If there's more than one source and more than one target, each target gets
1185 substituted from the corresponding source.
1186 """
1187 env.Append(TOOLS = 'SUBST')
1188 def do_subst_in_file(targetfile, sourcefile, dict):
1189 """Replace all instances of the keys of dict with their values.
1190 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1191 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1192 """
1193 try:
1194 f = open(sourcefile, 'rb')
1195 contents = f.read()
1196 f.close()
1197 except:
1198 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1199 for (k,v) in dict.items():
1200 contents = re.sub(k, v, contents)
1201 try:
1202 f = open(targetfile, 'wb')
1203 f.write(contents)
1204 f.close()
1205 except:
1206 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1207 return 0 # success
1208
1209 def subst_in_file(target, source, env):
1210 if not env.has_key('SUBST_DICT'):
1211 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1212 d = dict(env['SUBST_DICT']) # copy it
1213 for (k,v) in d.items():
1214 if callable(v):
1215 d[k] = env.subst(v())
1216 elif SCons.Util.is_String(v):
1217 d[k]=env.subst(v)
1218 else:
1219 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1220 for (t,s) in zip(target, source):
1221 return do_subst_in_file(str(t), str(s), d)
1222
1223 def subst_in_file_string(target, source, env):
1224 """This is what gets printed on the console."""
1225 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1226 for (t,s) in zip(target, source)])
1227
1228 def subst_emitter(target, source, env):
1229 """Add dependency from substituted SUBST_DICT to target.
1230 Returns original target, source tuple unchanged.
1231 """
1232 d = env['SUBST_DICT'].copy() # copy it
1233 for (k,v) in d.items():
1234 if callable(v):
1235 d[k] = env.subst(v())
1236 elif SCons.Util.is_String(v):
1237 d[k]=env.subst(v)
1238 Depends(target, SCons.Node.Python.Value(d))
1239 return target, source
1240
1241 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1242 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1243
1244 TOOL_SUBST(env)
1245
1246 #------------------------------------------------------
1247 # Recipe for 'CHMOD' ACTION
1248
1249 import SCons
1250 from SCons.Script.SConscript import SConsEnvironment
1251 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1252 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1253
1254 def InstallPerm(env, dest, files, perm):
1255 obj = env.Install(dest, files)
1256 for i in obj:
1257 env.AddPostAction(i, env.Chmod(str(i), perm))
1258
1259 SConsEnvironment.InstallPerm = InstallPerm
1260
1261 # define wrappers
1262 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1263 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1264 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1265
1266 #------------------------------------------------------
1267 # BUILD...
1268
1269 # so that #include <modulename/headername.h> works across all modules...
1270 env.Append(CPPPATH=['#base/generic'])
1271
1272 if env['DEBUG']:
1273 env.Append(CCFLAGS=['-g'])
1274
1275 if env['GCOV']:
1276 env.Append(
1277 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1278 , LIBS=['gcov']
1279 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1280 )
1281
1282 if with_ida:
1283 env.Append(WITH_IDA=1)
1284
1285 #-------------
1286 # TCL/TK GUI
1287
1288 if with_tcltk:
1289 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1290 else:
1291 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1292
1293 #-------------
1294 # PYTHON INTERFACE
1295
1296 if with_python:
1297 env.SConscript(['pygtk/SConscript'],'env')
1298 else:
1299 print "Skipping... Python GUI isn't being built:",without_python_reason
1300
1301 #------------
1302 # BASE/GENERIC SUBDIRECTORIES
1303
1304 libascend_env = env.Copy()
1305
1306 dirs = ['general','utilities','compiler','solver','packages']
1307
1308 srcs = []
1309 for d in dirs:
1310 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1311 srcs += heresrcs
1312
1313 #-------------
1314 # IMPORTED CODE: LSODE, BLAS, etc
1315
1316 if with_lsode:
1317 srcs += env.SConscript(['lsod/SConscript'],'env')
1318 srcs += env.SConscript(['linpack/SConscript'],'env')
1319 else:
1320 print "Skipping... LSODE won't be built:", without_lsode_reason
1321
1322 if with_local_blas:
1323 srcs += env.SConscript(['blas/SConscript'],'env')
1324 else:
1325 print "Skipping... BLAS won't be built:", without_local_blas_reason
1326
1327 if not with_ida:
1328 print "Skipping... IDA won't be built:", without_ida_reason
1329
1330 #-------------
1331 # LIBASCEND -- all base/generic functionality
1332
1333 libascend = libascend_env.SharedLibrary('ascend',srcs)
1334
1335 env.Alias('libascend',libascend)
1336
1337 #-------------
1338 # UNIT TESTS
1339
1340 if with_cunit:
1341 testdirs = ['general','solver','utilities']
1342 testsrcs = []
1343 for testdir in testdirs:
1344 path = 'base/generic/'+testdir+'/test/'
1345 env.SConscript([path+'SConscript'],'env')
1346 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1347
1348 #print "TESTSRCS =",testsrcs
1349
1350 env.SConscript(['test/SConscript'],'env')
1351 env.SConscript(['base/generic/test/SConscript'],'env')
1352
1353 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1354
1355 else:
1356 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1357
1358 #------------------------------------------------------
1359 # CREATE ASCEND-CONFIG scriptlet
1360
1361 ascendconfig = env.SubstInFile('ascend-config.in')
1362
1363 #------------------------------------------------------
1364 # INSTALLATION
1365
1366 if env.get('CAN_INSTALL'):
1367 # the models directory only needs to be processed for installation, no other processing required.
1368 env.SConscript(['models/SConscript'],'env')
1369
1370 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
1371 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1372
1373 # TODO: add install options
1374 env.Alias('install',install_dirs)
1375
1376 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1377
1378 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1379
1380 #------------------------------------------------------
1381 # WINDOWS INSTALLER
1382 # For the windows installer, please see pygtk/SConscript
1383
1384 if with_installer:
1385 pass
1386 else:
1387 print "Skipping... Windows installer isn't being built:",without_installer_reason
1388
1389 #------------------------------------------------------
1390 # PROJECT FILE for MSVC
1391
1392 env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1393
1394 #------------------------------------------------------
1395 # CREATE the SPEC file for generation of RPM packages
1396
1397 if platform.system()=="Linux":
1398 env.SubstInFile('ascend.spec.in')
1399
1400 #------------------------------------------------------
1401 # DISTRIBUTION TAR FILE
1402
1403 env['DISTTAR_FORMAT']='bz2'
1404 env.Append(
1405 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1406 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1407 )
1408
1409 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1410 , [env.Dir('#')]
1411 )
1412
1413 env.Depends(tar,'ascend.spec')
1414
1415 #------------------------------------------------------
1416 # RPM BUILD
1417
1418 #if platform.system()=="Linux":
1419 # pass
1420
1421 #------------------------------------------------------
1422 # DEFAULT TARGETS
1423
1424 default_targets =['libascend']
1425 if with_tcltk:
1426 default_targets.append('tcltk')
1427 if with_python:
1428 default_targets.append('pygtk')
1429 if with_installer:
1430 default_targets.append('installer')
1431
1432 env.Default(default_targets)
1433
1434 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1435
1436 # vim: set syntax=python:
1437

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