/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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