/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 644 - (show annotations) (download)
Mon May 29 07:19:36 2006 UTC (14 years, 4 months ago) by johnpye
File size: 29493 byte(s)
Fixing up Yacc/Bison detection a little.
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 %start ROOT
586 %token MSG
587 %%
588
589 ROOT:
590 MSG { print("HELLO"); }
591 ;
592 """
593
594 def CheckYacc(context):
595 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
596 is_ok = context.TryCompile(yacc_test_text,".y")
597 context.Result(is_ok)
598 return is_ok
599
600 #----------------
601 # CUnit test
602
603 cunit_test_text = """
604 #include <CUnit/CUnit.h>
605 int maxi(int i1, int i2){
606 return (i1 > i2) ? i1 : i2;
607 }
608
609 void test_maxi(void){
610 CU_ASSERT(maxi(0,2) == 2);
611 CU_ASSERT(maxi(0,-2) == 0);
612 CU_ASSERT(maxi(2,2) == 2);
613
614 }
615 int main(void){
616 /* CU_initialize_registry() */
617 return 0;
618 }
619 """
620
621 def CheckCUnit(context):
622 return CheckExtLib(context,'cunit',cunit_test_text)
623
624 #----------------
625 # Tcl test
626
627 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
628 tcltk_minor_newest_acceptable = 4
629 tcltk_major_required = 8
630
631 tcl_check_text = r"""
632 #include <tcl.h>
633 #include <stdio.h>
634 int main(void){
635 printf("%s",TCL_PATCH_LEVEL);
636 return 0;
637 }
638 """
639
640 def CheckTcl(context):
641 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
642
643 def CheckTclVersion(context):
644 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
645 context.Message("Checking Tcl version... ")
646 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
647 keep.restore(context)
648 if not is_ok:
649 context.Result("failed to run check")
650 return 0
651
652 major,minor,patch = tuple([int(i) for i in output.split(".")])
653 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
654 context.Result(output+" (bad version)")
655 # bad version
656 return 0
657
658 # good version
659 context.Result(output+", good")
660 return 1
661
662 #----------------
663 # Tk test
664
665 tk_check_text = r"""
666 #include <tk.h>
667 #include <stdio.h>
668 int main(void){
669 printf("%s",TK_PATCH_LEVEL);
670 return 0;
671 }
672 """
673 def CheckTk(context):
674 return CheckExtLib(context,'tk',tcl_check_text,static=env['STATIC_TCLTK'])
675
676
677 def CheckTkVersion(context):
678 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
679 context.Message("Checking Tk version... ")
680 #print "LINKFLAGS =",context.env['LINKFLAGS']
681 (is_ok,output) = context.TryRun(tk_check_text,'.c')
682 keep.restore(context)
683 if not is_ok:
684 context.Result("failed to run check")
685 return 0
686
687 major,minor,patch = tuple([int(i) for i in output.split(".")])
688 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
689 # bad version
690 context.Result(output+" (bad version)")
691 return 0
692
693 # good version
694 context.Result(output+" (good)")
695 return 1
696
697 #----------------
698 # Tktable test
699
700 tktable_check_text = r"""
701 #include <tkTable.h>
702 #include <stdio.h>
703 int main(void){
704 Table mytable;
705 return 0;
706 }
707 """
708
709 def CheckTkTable(context):
710 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
711
712 #---------------
713 # X11 test
714
715 x11_check_text = r"""
716 #include <X11/Xlib.h>
717 #include <X11/IntrinsicP.h>
718 #include <X11/Intrinsic.h>
719 #include <X11/ObjectP.h>
720 #include <X11/Object.h>
721 int main(void){
722 Object mything;
723 return 0;
724 }
725 """
726
727 def CheckX11(context):
728 return CheckExtLib(context,'X11',x11_check_text)
729
730 #----------------
731 # GCC Version sniffing
732
733 # TODO FIXME
734
735 gcc_version4 = False
736
737 #------------------------------------------------------
738 # CONFIGURATION
739
740 conf = Configure(env
741 , custom_tests = {
742 'CheckSwigVersion' : CheckSwigVersion
743 , 'CheckCUnit' : CheckCUnit
744 , 'CheckTcl' : CheckTcl
745 , 'CheckTclVersion' : CheckTclVersion
746 , 'CheckTk' : CheckTk
747 , 'CheckTkVersion' : CheckTkVersion
748 , 'CheckGcc' : CheckGcc
749 , 'CheckGccVisibility' : CheckGccVisibility
750 , 'CheckYacc' : CheckYacc
751 , 'CheckTkTable' : CheckTkTable
752 , 'CheckX11' : CheckX11
753 # , 'CheckIsNan' : CheckIsNan
754 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
755 }
756 # , config_h = "config.h"
757 )
758
759
760 # Math library
761
762 #if not conf.CheckFunc('sinh') and not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
763 # print 'Did not find math library, exiting!'
764 # Exit(1)
765
766 # Where is 'isnan'?
767
768 if not conf.CheckFunc('isnan'):
769 print "Didn't find isnan"
770 # Exit(1)
771
772 # GCC visibility
773
774 if conf.CheckGcc():
775 conf.env['HAVE_GCC']=True;
776 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
777 conf.env['HAVE_GCCVISIBILITY']=True;
778 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
779 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
780
781 # YACC
782
783 if not conf.CheckYacc():
784 print "YACC NOT FOUND OR NOT WORKING"
785 else:
786 conf.env['HAVE_YACC']=True
787
788 conf.env['HAVE_LEX']=True
789
790 # Tcl/Tk
791
792 if with_tcltk:
793 if conf.CheckTcl():
794 if conf.CheckTclVersion():
795 if conf.CheckTk():
796 if with_tcltk and conf.CheckTkVersion():
797 if env['STATIC_TCLTK']:
798 if conf.CheckTkTable():
799 pass
800 else:
801 without_tcltk_reason = "TkTable not found"
802 with_tcltk = False
803 else:
804 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
805 with_tcltk = False
806 else:
807 without_tcltk_reason = "Tk not found."
808 with_tcltk = False
809 else:
810 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
811 with_tcltk = False
812
813 else:
814 without_tcltk_reason = "Tcl not found."
815 with_tcltk = False
816
817 if env['STATIC_TCLTK']:
818 conf.CheckX11()
819
820 # Python... obviously we're already running python, so we just need to
821 # check that we can link to the python library OK:
822
823 if platform.system()=="Windows":
824 python_lib='python24'
825 else:
826 python_lib='python2.4'
827
828 # SWIG version
829
830 if not conf.CheckSwigVersion():
831 without_python_reason = 'SWIG >= 1.3.24 is required'
832 with_python = False
833
834 # CUnit
835
836 if with_cunit:
837 if not conf.CheckCUnit():
838 without_cunit_reason = 'CUnit not found'
839
840 # BLAS
841
842 need_blas=False
843 if with_tcltk:
844 need_blas=True
845 if need_blas:
846 if conf.CheckLib('blas'):
847 with_local_blas = False
848 without_local_blas_reason = "Found BLAS installed on system"
849 else:
850 with_local_blas = True
851 need_fortran = True
852
853 # FORTRAN
854
855 if need_fortran:
856 conf.env.Tool('fortran')
857 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
858 if detect_fortran:
859 # For some reason, g77 doesn't get detected properly on MinGW
860 if not env.has_key('F77'):
861 conf.env.Replace(F77=detect_fortran)
862 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
863 conf.env.Replace(F77FLAGS='')
864 #print "F77:",conf.env['F77']
865 #print "F77COM:",conf.env['F77COM']
866 #print "F77FLAGS:",conf.env['F77FLAGS']
867 fortran_builder = Builder(
868 action='$F77COM'
869 , suffix='.o'
870 , src_suffix='.f'
871 )
872 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
873 else:
874 with_tcltk=False;
875 without_tcltk_reason="FORTRAN-77 required but not found"
876
877 #else:
878 # print "FORTRAN not required"
879
880 # TODO: -D_HPUX_SOURCE is needed
881
882 # TODO: check size of void*
883
884 # TODO: detect if dynamic libraries are possible or not
885
886 if platform.system()=="Windows" and env.has_key('MSVS'):
887 if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
888 print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
889 +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
890 env['PACKAGE_LINKING']='STATIC_PACKAGES'
891
892 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
893 with_python = 0;
894 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
895
896 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
897
898 conf.Finish()
899
900 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
901 env.Append(PYTHON_LIB=[python_lib])
902 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
903
904 #---------------------------------------
905 # SUBSTITUTION DICTIONARY for .in files
906
907 subst_dict = {
908 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
909 , '@GLADE_FILE@':'ascend.glade'
910 , '@HELP_ROOT@':''
911 , '@ICON_EXTENSION@':icon_extension
912 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
913 , '@INSTALL_BIN@':env['INSTALL_BIN']
914 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
915 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
916 , '@VERSION@':version
917 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
918 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
919 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
920 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
921 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
922 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
923 }
924
925 if env.get('WITH_LOCAL_HELP'):
926 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
927 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
928
929 # bool options...
930 for k,v in { \
931 'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS', \
932 'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS', \
933 'MALLOC_DEBUG' : 'MALLOC_DEBUG' \
934 }.iteritems():
935 if env.get(k):
936 subst_dict['ifdef '+v]="if 1"
937
938 if with_python:
939 subst_dict['@ASCXX_USE_PYTHON@']="1"
940
941 if env.has_key('HAVE_GCCVISIBILITY'):
942 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
943
944 env.Append(SUBST_DICT=subst_dict)
945
946 #------------------------------------------------------
947 # RECIPE: SWIG scanner
948
949 import SCons.Script
950
951 SWIGScanner = SCons.Scanner.ClassicCPP(
952 "SWIGScan"
953 , ".i"
954 , "CPPPATH"
955 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
956 )
957
958 env.Append(SCANNERS=[SWIGScanner])
959
960 #------------------------------------------------------
961 # RECIPE: 'SubstInFile', used in pygtk SConscript
962
963 import re
964 from SCons.Script import * # the usual scons stuff you get in a SConscript
965
966 def TOOL_SUBST(env):
967 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
968 from the source to the target.
969 The values of SUBST_DICT first have any construction variables expanded
970 (its keys are not expanded).
971 If a value of SUBST_DICT is a python callable function, it is called and
972 the result is expanded as the value.
973 If there's more than one source and more than one target, each target gets
974 substituted from the corresponding source.
975 """
976 env.Append(TOOLS = 'SUBST')
977 def do_subst_in_file(targetfile, sourcefile, dict):
978 """Replace all instances of the keys of dict with their values.
979 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
980 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
981 """
982 try:
983 f = open(sourcefile, 'rb')
984 contents = f.read()
985 f.close()
986 except:
987 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
988 for (k,v) in dict.items():
989 contents = re.sub(k, v, contents)
990 try:
991 f = open(targetfile, 'wb')
992 f.write(contents)
993 f.close()
994 except:
995 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
996 return 0 # success
997
998 def subst_in_file(target, source, env):
999 if not env.has_key('SUBST_DICT'):
1000 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1001 d = dict(env['SUBST_DICT']) # copy it
1002 for (k,v) in d.items():
1003 if callable(v):
1004 d[k] = env.subst(v())
1005 elif SCons.Util.is_String(v):
1006 d[k]=env.subst(v)
1007 else:
1008 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1009 for (t,s) in zip(target, source):
1010 return do_subst_in_file(str(t), str(s), d)
1011
1012 def subst_in_file_string(target, source, env):
1013 """This is what gets printed on the console."""
1014 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1015 for (t,s) in zip(target, source)])
1016
1017 def subst_emitter(target, source, env):
1018 """Add dependency from substituted SUBST_DICT to target.
1019 Returns original target, source tuple unchanged.
1020 """
1021 d = env['SUBST_DICT'].copy() # copy it
1022 for (k,v) in d.items():
1023 if callable(v):
1024 d[k] = env.subst(v())
1025 elif SCons.Util.is_String(v):
1026 d[k]=env.subst(v)
1027 Depends(target, SCons.Node.Python.Value(d))
1028 return target, source
1029
1030 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1031 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1032
1033 TOOL_SUBST(env)
1034
1035 #------------------------------------------------------
1036 # Recipe for 'CHMOD' ACTION
1037
1038 import SCons
1039 from SCons.Script.SConscript import SConsEnvironment
1040 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1041 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1042
1043 def InstallPerm(env, dest, files, perm):
1044 obj = env.Install(dest, files)
1045 for i in obj:
1046 env.AddPostAction(i, env.Chmod(str(i), perm))
1047
1048 SConsEnvironment.InstallPerm = InstallPerm
1049
1050 # define wrappers
1051 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1052 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1053 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1054
1055 #------------------------------------------------------
1056 # BUILD...
1057
1058 # so that #include <modulename/headername.h> works across all modules...
1059 env.Append(CPPPATH=['#base/generic'])
1060
1061 if gcc_version4:
1062 env.Append(CCFLAGS=['-fvisibility=hidden'])
1063
1064 if env['DEBUG']:
1065 env.Append(CCFLAGS=['-g'])
1066
1067 if env['GCOV']:
1068 env.Append(
1069 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1070 , LIBS=['gcov']
1071 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1072 )
1073
1074 #-------------
1075 # TCL/TK GUI
1076
1077 if with_tcltk:
1078 if with_local_blas:
1079 env.SConscript(['blas/SConscript'],'env')
1080 else:
1081 print "Skipping... BLAS won't be build:", without_local_blas_reason
1082
1083 env.SConscript(['lsod/SConscript'],'env')
1084
1085 env.SConscript(['linpack/SConscript'],'env')
1086 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1087 else:
1088 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1089
1090 #-------------
1091 # PYTHON INTERFACE
1092
1093 if with_python:
1094 env.SConscript(['pygtk/SConscript'],'env')
1095 else:
1096 print "Skipping... Python GUI isn't being built:",without_python_reason
1097
1098 #------------
1099 # BASE/GENERIC SUBDIRECTORIES
1100
1101 dirs = ['general','utilities','compiler','solver','packages']
1102
1103 srcs = []
1104 for d in dirs:
1105 heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
1106 srcs += heresrcs
1107
1108 #-------------
1109 # LIBASCEND -- all base/generic functionality
1110
1111 libascend = env.SharedLibrary('ascend',srcs)
1112
1113 #-------------
1114 # UNIT TESTS
1115
1116 if with_cunit:
1117 testdirs = ['general','solver','utilities']
1118 testsrcs = []
1119 for testdir in testdirs:
1120 path = 'base/generic/'+testdir+'/test/'
1121 env.SConscript([path+'SConscript'],'env')
1122 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1123
1124 #print "TESTSRCS =",testsrcs
1125
1126 env.SConscript(['test/SConscript'],'env')
1127 env.SConscript(['base/generic/test/SConscript'],'env')
1128
1129 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1130
1131 else:
1132 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1133
1134 #------------------------------------------------------
1135 # INSTALLATION
1136
1137 if env.get('CAN_INSTALL'):
1138 # the models directory only needs to be processed for installation, no other processing required.
1139 env.SConscript(['models/SConscript'],'env')
1140
1141 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB']
1142 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1143
1144 # TODO: add install options
1145 env.Alias('install',install_dirs)
1146
1147 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1148
1149 #------------------------------------------------------
1150 # WINDOWS INSTALLER
1151 # For the windows installer, please see pygtk/SConscript
1152
1153 if with_installer:
1154 pass
1155 else:
1156 print "Skipping... Windows installer isn't being built:",without_installer_reason
1157
1158 #------------------------------------------------------
1159 # CREATE the SPEC file for generation of RPM packages
1160
1161 if platform.system()=="Linux":
1162 env.SubstInFile('ascend.spec.in')
1163
1164 #------------------------------------------------------
1165 # DISTRIBUTION TAR FILE
1166
1167 env['DISTTAR_FORMAT']='bz2'
1168 env.Append(
1169 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1170 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1171 )
1172
1173 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1174 , [env.Dir('#')]
1175 )
1176
1177 #------------------------------------------------------
1178 # RPM BUILD
1179
1180 #if platform.system()=="Linux":
1181 # pass
1182
1183 #------------------------------------------------------
1184 # DEFAULT TARGETS
1185
1186 default_targets =[]
1187 if with_tcltk:
1188 default_targets.append('tcltk')
1189 if with_python:
1190 default_targets.append('pygtk')
1191 if with_installer:
1192 default_targets.append('installer')
1193
1194 env.Default(default_targets)
1195
1196 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1197

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