/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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