/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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