/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 656 - (show annotations) (download)
Fri Jun 2 06:36:32 2006 UTC (13 years, 6 months ago) by johnpye
File size: 29801 byte(s)
Removed dependency on ccache.
Added RELEASE flag to allow BuildBot to control RPM versions.
1 import os, commands, platform, distutils.sysconfig, os.path
2
3 version = "0.9.5.93"
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(
321 'RELEASE'
322 ,"Release number for use in RPM spec file. This should always start with a zero for releases made by the ASCEND group, in order that third parties can make 'patch' releases of higher version numbers."
323 ,"0"
324 )
325
326 opts.Add(BoolOption(
327 'ABSOLUTE_PATHS'
328 ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
329 ,default_absolute_paths
330 ))
331
332 opts.Add(
333 'WIN_INSTALLER_NAME'
334 ,"Name of the installer .exe to create under Windows (minus the '.exe')"
335 ,"ascend-"+version
336 )
337
338 opts.Add(BoolOption(
339 'WITH_XTERM_COLORS'
340 ,"Set to 0 if you don't want xterm colour codes in the console output"
341 ,True
342 ))
343
344 if platform.system()!="Windows":
345 opts.Add(BoolOption(
346 'WITH_GCCVISIBILITY'
347 , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
348 , True
349 ))
350
351 # TODO: OTHER OPTIONS?
352 # TODO: flags for optimisation
353 # TODO: turning on/off bintoken functionality
354 # TODO: Where will the 'Makefile.bt' file be installed?
355
356 # Import the outside environment
357
358 if os.environ.get('OSTYPE')=='msys':
359 env = Environment(
360 ENV=os.environ
361 , tools=['mingw','lex','yacc','fortran','swig','disttar','nsis']
362 , toolpath=['scons']
363 )
364 env['IS_MINGW']=True
365 else:
366 env = Environment(
367 ENV=os.environ
368 ,tools=['default','lex','yacc','fortran','swig','disttar','nsis']
369 , toolpath=['scons']
370 )
371
372 if platform.system()=='Windows' and env.has_key('MSVS'):
373 print "INCLUDE =",env['ENV']['INCLUDE']
374 print "LIB =",env['ENV']['LIB']
375 print "PATH =",env['ENV']['PATH']
376 env.Append(CPPPATH=env['ENV']['INCLUDE'])
377 env.Append(LIBPATH=env['ENV']['LIB'])
378 env.Append(CPPDEFINES=['_CRT_SECURE_NO_DEPRECATE'])
379 env.Append(CCFLAGS=['/Za'])
380
381 opts.Update(env)
382 opts.Save('options.cache',env)
383
384 Help(opts.GenerateHelpText(env))
385
386 with_tcltk = env.get('WITH_TCLTK')
387 without_tcltk_reason = "disabled by options/config.py"
388
389 with_python = env.get('WITH_PYTHON')
390 without_python_reason = "disabled by options/config.py"
391
392 with_cunit = env.get('WITH_CUNIT')
393 without_cunit_reason = "not requested"
394
395 if platform.system()=="Windows":
396 with_installer=1
397 else:
398 with_installer=0
399 without_installer_reason = "only possible under Windows"
400
401 #print "SOLVERS:",env['WITH_SOLVERS']
402 #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
403 #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
404
405 can_install = True
406 if platform.system()=='Windows':
407 can_install = False
408
409 env['CAN_INSTALL']=can_install
410
411 print "TCL_CPPPATH =",env['TCL_CPPPATH']
412 print "TCL_LIBPATH =",env['TCL_LIBPATH']
413 print "TCL_LIB =",env['TCL_LIB']
414 print "CC =",env['CC']
415 print "CXX =",env['CXX']
416
417 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
418 #------------------------------------------------------
419 # SPECIAL CONFIGURATION TESTS
420
421 need_fortran = False
422
423 #----------------
424 # SWIG
425
426 import os,re
427
428 def get_swig_version(env):
429 cmd = env['SWIG']+' -version'
430 (cin,coutcerr) = os.popen4(cmd)
431 output = coutcerr.read()
432
433 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
434 expr = re.compile(restr,re.M);
435 m = expr.search(output);
436 if not m:
437 return None
438 maj = int(m.group('maj'))
439 min = int(m.group('min'))
440 pat = int(m.group('pat'))
441
442 return (maj,min,pat)
443
444
445 def CheckSwigVersion(context):
446
447 try:
448 context.Message("Checking version of SWIG... ")
449 maj,min,pat = get_swig_version(context.env)
450 except:
451 context.Result("Failed to detect version, or failed to run SWIG")
452 return 0;
453
454 context.env['SWIGVERSION']=tuple([maj,min,pat])
455
456 if maj == 1 and (
457 min > 3
458 or (min == 3 and pat >= 24)
459 ):
460 context.Result("ok, %d.%d.%d" % (maj,min,pat))
461 return 1;
462 else:
463 context.Result("too old, %d.%d.%d" % (maj,min,pat))
464 return 0;
465
466 #----------------
467 # General purpose library-and-header test
468
469 class KeepContext:
470 def __init__(self,context,varprefix,static=False):
471 self.keep = {}
472 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
473 if context.env.has_key(k):
474 self.keep[k] = context.env[k]
475 else:
476 self.keep[k] = None
477
478 if context.env.has_key(varprefix+'_CPPPATH'):
479 context.env.Append(CPPPATH=[env[varprefix+'_CPPPATH']])
480 #print "Adding '"+str(cpppath_add)+"' to cpp path"
481
482 if static:
483 staticlib=env[varprefix+'_LIB']
484 #print "STATIC LIB = ",staticlib
485 context.env.Append(
486 LINKFLAGS=[staticlib]
487 )
488 else:
489 if context.env.has_key(varprefix+'_LIBPATH'):
490 context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
491 #print "Adding '"+str(libpath_add)+"' to lib path"
492
493 if context.env.has_key(varprefix+'_LIB'):
494 context.env.Append(LIBS=[env[varprefix+'_LIB']])
495 #print "Adding '"+str(libs_add)+"' to libs"
496
497 def restore(self,context):
498 #print "RESTORING CONTEXT"
499 #print self.keep
500 #print "..."
501 for k in self.keep:
502 if self.keep[k]==None:
503 if context.env.has_key(k):
504 #print "Clearing "+str(k)
505 del context.env[k];
506 else:
507 #print "Restoring "+str(k)+" to '"+self.keep[k]+"'"
508 context.env[k]=self.keep[k];
509
510 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
511 """This method will check for variables LIBNAME_LIBPATH
512 and LIBNAME_CPPPATH and try to compile and link the
513 file with the provided text, linking with the
514 library libname."""
515
516 if static:
517 context.Message( 'Checking for static '+libname+'... ' )
518 else:
519 context.Message( 'Checking for '+libname+'... ' )
520
521 if varprefix==None:
522 varprefix = libname.upper()
523
524 keep = KeepContext(context,varprefix,static)
525
526 if not context.env.has_key(varprefix+'_LIB'):
527 # if varprefix_LIB were in env, KeepContext would
528 # have appended it already
529 context.env.Append(LIBS=libname)
530
531 is_ok = context.TryLink(text,ext)
532
533 #print "Link success? ",(is_ok != 0)
534
535 keep.restore(context)
536
537 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
538 # print "Restored LIBS="+libname
539 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
540
541 context.Result(is_ok)
542 return is_ok
543
544 #----------------
545 # GCC
546
547 gcc_test_text = """
548 #ifndef __GNUC__
549 # error "Not using GCC"
550 #endif
551
552 int main(void){
553 return __GNUC__;
554 }
555 """
556
557 def CheckGcc(context):
558 context.Message("Checking for GCC... ")
559 is_ok = context.TryCompile(gcc_test_text,".c")
560 context.Result(is_ok)
561 return is_ok
562
563 #----------------
564 # GCC VISIBILITY feature
565
566 gccvisibility_test_text = """
567 #if __GNUC__ < 4
568 # error "Require GCC version 4 or newer"
569 #endif
570
571 __attribute__ ((visibility("default"))) int x;
572
573 int main(void){
574 extern int x;
575 x = 4;
576 }
577 """
578
579 def CheckGccVisibility(context):
580 context.Message("Checking for GCC 'visibility' capability... ")
581 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
582 context.Result("disabled")
583 return 0
584 is_ok = context.TryCompile(gccvisibility_test_text,".c")
585 context.Result(is_ok)
586 return is_ok
587
588 #----------------
589 # YACC
590
591 yacc_test_text = """
592 %{
593 #include <stdio.h>
594 %}
595 %token MSG
596 %start ROOT
597 %%
598 ROOT:
599 MSG { printf("HELLO"); }
600 ;
601 %%
602 """
603
604 def CheckYacc(context):
605 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
606 is_ok = context.TryCompile(yacc_test_text,".y")
607 context.Result(is_ok)
608 return is_ok
609
610 #----------------
611 # CUnit test
612
613 cunit_test_text = """
614 #include <CUnit/CUnit.h>
615 int maxi(int i1, int i2){
616 return (i1 > i2) ? i1 : i2;
617 }
618
619 void test_maxi(void){
620 CU_ASSERT(maxi(0,2) == 2);
621 CU_ASSERT(maxi(0,-2) == 0);
622 CU_ASSERT(maxi(2,2) == 2);
623
624 }
625 int main(void){
626 /* CU_initialize_registry() */
627 return 0;
628 }
629 """
630
631 def CheckCUnit(context):
632 return CheckExtLib(context,'cunit',cunit_test_text)
633
634 #----------------
635 # Tcl test
636
637 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
638 tcltk_minor_newest_acceptable = 4
639 tcltk_major_required = 8
640
641 tcl_check_text = r"""
642 #include <tcl.h>
643 #include <stdio.h>
644 int main(void){
645 printf("%s",TCL_PATCH_LEVEL);
646 return 0;
647 }
648 """
649
650 def CheckTcl(context):
651 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
652
653 def CheckTclVersion(context):
654 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
655 context.Message("Checking Tcl version... ")
656 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
657 keep.restore(context)
658 if not is_ok:
659 context.Result("failed to run check")
660 return 0
661
662 major,minor,patch = tuple([int(i) for i in output.split(".")])
663 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
664 context.Result(output+" (bad version)")
665 # bad version
666 return 0
667
668 # good version
669 context.Result(output+", good")
670 return 1
671
672 #----------------
673 # Tk test
674
675 tk_check_text = r"""
676 #include <tk.h>
677 #include <stdio.h>
678 int main(void){
679 printf("%s",TK_PATCH_LEVEL);
680 return 0;
681 }
682 """
683 def CheckTk(context):
684 return CheckExtLib(context,'tk',tcl_check_text,static=env['STATIC_TCLTK'])
685
686
687 def CheckTkVersion(context):
688 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
689 context.Message("Checking Tk version... ")
690 #print "LINKFLAGS =",context.env['LINKFLAGS']
691 (is_ok,output) = context.TryRun(tk_check_text,'.c')
692 keep.restore(context)
693 if not is_ok:
694 context.Result("failed to run check")
695 return 0
696
697 major,minor,patch = tuple([int(i) for i in output.split(".")])
698 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
699 # bad version
700 context.Result(output+" (bad version)")
701 return 0
702
703 # good version
704 context.Result(output+" (good)")
705 return 1
706
707 #----------------
708 # Tktable test
709
710 tktable_check_text = r"""
711 #include <tkTable.h>
712 #include <stdio.h>
713 int main(void){
714 Table mytable;
715 return 0;
716 }
717 """
718
719 def CheckTkTable(context):
720 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
721
722 #---------------
723 # X11 test
724
725 x11_check_text = r"""
726 #include <X11/Xlib.h>
727 #include <X11/IntrinsicP.h>
728 #include <X11/Intrinsic.h>
729 #include <X11/ObjectP.h>
730 #include <X11/Object.h>
731 int main(void){
732 Object mything;
733 return 0;
734 }
735 """
736
737 def CheckX11(context):
738 return CheckExtLib(context,'X11',x11_check_text)
739
740 #----------------
741 # GCC Version sniffing
742
743 # TODO FIXME
744
745 gcc_version4 = False
746
747 #------------------------------------------------------
748 # CONFIGURATION
749
750 conf = Configure(env
751 , custom_tests = {
752 'CheckSwigVersion' : CheckSwigVersion
753 , 'CheckCUnit' : CheckCUnit
754 , 'CheckTcl' : CheckTcl
755 , 'CheckTclVersion' : CheckTclVersion
756 , 'CheckTk' : CheckTk
757 , 'CheckTkVersion' : CheckTkVersion
758 , 'CheckGcc' : CheckGcc
759 , 'CheckGccVisibility' : CheckGccVisibility
760 , 'CheckYacc' : CheckYacc
761 , 'CheckTkTable' : CheckTkTable
762 , 'CheckX11' : CheckX11
763 # , 'CheckIsNan' : CheckIsNan
764 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
765 }
766 # , config_h = "config.h"
767 )
768
769
770 # Math library
771
772 #if not conf.CheckFunc('sinh') and not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
773 # print 'Did not find math library, exiting!'
774 # Exit(1)
775
776 # Where is 'isnan'?
777
778 if not conf.CheckFunc('isnan'):
779 print "Didn't find isnan"
780 # Exit(1)
781
782 # GCC visibility
783
784 if conf.CheckGcc():
785 conf.env['HAVE_GCC']=True;
786 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
787 conf.env['HAVE_GCCVISIBILITY']=True;
788 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
789 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
790
791 # YACC
792
793 if not conf.CheckYacc():
794 print "YACC NOT FOUND OR NOT WORKING"
795 else:
796 conf.env['HAVE_YACC']=True
797
798 conf.env['HAVE_LEX']=True
799
800 # Tcl/Tk
801
802 if with_tcltk:
803 if conf.CheckTcl():
804 if conf.CheckTclVersion():
805 if conf.CheckTk():
806 if with_tcltk and conf.CheckTkVersion():
807 if env['STATIC_TCLTK']:
808 if conf.CheckTkTable():
809 pass
810 else:
811 without_tcltk_reason = "TkTable not found"
812 with_tcltk = False
813 else:
814 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
815 with_tcltk = False
816 else:
817 without_tcltk_reason = "Tk not found."
818 with_tcltk = False
819 else:
820 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
821 with_tcltk = False
822
823 else:
824 without_tcltk_reason = "Tcl not found."
825 with_tcltk = False
826
827 if env['STATIC_TCLTK']:
828 conf.CheckX11()
829
830 # Python... obviously we're already running python, so we just need to
831 # check that we can link to the python library OK:
832
833 if platform.system()=="Windows":
834 python_lib='python24'
835 else:
836 python_lib='python2.4'
837
838 # SWIG version
839
840 if not conf.CheckSwigVersion():
841 without_python_reason = 'SWIG >= 1.3.24 is required'
842 with_python = False
843
844 # CUnit
845
846 if with_cunit:
847 if not conf.CheckCUnit():
848 without_cunit_reason = 'CUnit not found'
849
850 # BLAS
851
852 need_blas=False
853 if with_tcltk:
854 need_blas=True
855 if need_blas:
856 if conf.CheckLib('blas'):
857 with_local_blas = False
858 without_local_blas_reason = "Found BLAS installed on system"
859 else:
860 with_local_blas = True
861 need_fortran = True
862
863 # FORTRAN
864
865 if need_fortran:
866 conf.env.Tool('fortran')
867 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
868 if detect_fortran:
869 # For some reason, g77 doesn't get detected properly on MinGW
870 if not env.has_key('F77'):
871 conf.env.Replace(F77=detect_fortran)
872 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
873 conf.env.Replace(F77FLAGS='')
874 #print "F77:",conf.env['F77']
875 #print "F77COM:",conf.env['F77COM']
876 #print "F77FLAGS:",conf.env['F77FLAGS']
877 fortran_builder = Builder(
878 action='$F77COM'
879 , suffix='.o'
880 , src_suffix='.f'
881 )
882 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
883 else:
884 with_tcltk=False;
885 without_tcltk_reason="FORTRAN-77 required but not found"
886
887 #else:
888 # print "FORTRAN not required"
889
890 # TODO: -D_HPUX_SOURCE is needed
891
892 # TODO: check size of void*
893
894 # TODO: detect if dynamic libraries are possible or not
895
896 if platform.system()=="Windows" and env.has_key('MSVS'):
897 if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
898 print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
899 +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
900 env['PACKAGE_LINKING']='STATIC_PACKAGES'
901
902 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
903 with_python = 0;
904 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
905
906 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
907
908 conf.Finish()
909
910 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
911 env.Append(PYTHON_LIB=[python_lib])
912 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
913
914 #---------------------------------------
915 # SUBSTITUTION DICTIONARY for .in files
916
917 subst_dict = {
918 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
919 , '@GLADE_FILE@':'ascend.glade'
920 , '@HELP_ROOT@':''
921 , '@ICON_EXTENSION@':icon_extension
922 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
923 , '@INSTALL_BIN@':env['INSTALL_BIN']
924 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
925 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
926 , '@VERSION@':version
927 , '@RELEASE@':env.get('RELEASE')
928 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
929 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
930 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
931 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
932 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
933 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
934 }
935
936 if env.get('WITH_LOCAL_HELP'):
937 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
938 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
939
940 # bool options...
941 for k,v in { \
942 'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS', \
943 'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS', \
944 'MALLOC_DEBUG' : 'MALLOC_DEBUG' \
945 }.iteritems():
946 if env.get(k):
947 subst_dict['ifdef '+v]="if 1"
948
949 if with_python:
950 subst_dict['@ASCXX_USE_PYTHON@']="1"
951
952 if env.has_key('HAVE_GCCVISIBILITY'):
953 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
954
955 env.Append(SUBST_DICT=subst_dict)
956
957 #------------------------------------------------------
958 # RECIPE: SWIG scanner
959
960 import SCons.Script
961
962 SWIGScanner = SCons.Scanner.ClassicCPP(
963 "SWIGScan"
964 , ".i"
965 , "CPPPATH"
966 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
967 )
968
969 env.Append(SCANNERS=[SWIGScanner])
970
971 #------------------------------------------------------
972 # RECIPE: 'SubstInFile', used in pygtk SConscript
973
974 import re
975 from SCons.Script import * # the usual scons stuff you get in a SConscript
976
977 def TOOL_SUBST(env):
978 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
979 from the source to the target.
980 The values of SUBST_DICT first have any construction variables expanded
981 (its keys are not expanded).
982 If a value of SUBST_DICT is a python callable function, it is called and
983 the result is expanded as the value.
984 If there's more than one source and more than one target, each target gets
985 substituted from the corresponding source.
986 """
987 env.Append(TOOLS = 'SUBST')
988 def do_subst_in_file(targetfile, sourcefile, dict):
989 """Replace all instances of the keys of dict with their values.
990 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
991 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
992 """
993 try:
994 f = open(sourcefile, 'rb')
995 contents = f.read()
996 f.close()
997 except:
998 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
999 for (k,v) in dict.items():
1000 contents = re.sub(k, v, contents)
1001 try:
1002 f = open(targetfile, 'wb')
1003 f.write(contents)
1004 f.close()
1005 except:
1006 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1007 return 0 # success
1008
1009 def subst_in_file(target, source, env):
1010 if not env.has_key('SUBST_DICT'):
1011 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1012 d = dict(env['SUBST_DICT']) # copy it
1013 for (k,v) in d.items():
1014 if callable(v):
1015 d[k] = env.subst(v())
1016 elif SCons.Util.is_String(v):
1017 d[k]=env.subst(v)
1018 else:
1019 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1020 for (t,s) in zip(target, source):
1021 return do_subst_in_file(str(t), str(s), d)
1022
1023 def subst_in_file_string(target, source, env):
1024 """This is what gets printed on the console."""
1025 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1026 for (t,s) in zip(target, source)])
1027
1028 def subst_emitter(target, source, env):
1029 """Add dependency from substituted SUBST_DICT to target.
1030 Returns original target, source tuple unchanged.
1031 """
1032 d = env['SUBST_DICT'].copy() # copy it
1033 for (k,v) in d.items():
1034 if callable(v):
1035 d[k] = env.subst(v())
1036 elif SCons.Util.is_String(v):
1037 d[k]=env.subst(v)
1038 Depends(target, SCons.Node.Python.Value(d))
1039 return target, source
1040
1041 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1042 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1043
1044 TOOL_SUBST(env)
1045
1046 #------------------------------------------------------
1047 # Recipe for 'CHMOD' ACTION
1048
1049 import SCons
1050 from SCons.Script.SConscript import SConsEnvironment
1051 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1052 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1053
1054 def InstallPerm(env, dest, files, perm):
1055 obj = env.Install(dest, files)
1056 for i in obj:
1057 env.AddPostAction(i, env.Chmod(str(i), perm))
1058
1059 SConsEnvironment.InstallPerm = InstallPerm
1060
1061 # define wrappers
1062 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1063 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1064 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1065
1066 #------------------------------------------------------
1067 # BUILD...
1068
1069 # so that #include <modulename/headername.h> works across all modules...
1070 env.Append(CPPPATH=['#base/generic'])
1071
1072 if gcc_version4:
1073 env.Append(CCFLAGS=['-fvisibility=hidden'])
1074
1075 if env['DEBUG']:
1076 env.Append(CCFLAGS=['-g'])
1077
1078 if env['GCOV']:
1079 env.Append(
1080 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1081 , LIBS=['gcov']
1082 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1083 )
1084
1085 #-------------
1086 # TCL/TK GUI
1087
1088 if with_tcltk:
1089 if with_local_blas:
1090 env.SConscript(['blas/SConscript'],'env')
1091 else:
1092 print "Skipping... BLAS won't be build:", without_local_blas_reason
1093
1094 env.SConscript(['lsod/SConscript'],'env')
1095
1096 env.SConscript(['linpack/SConscript'],'env')
1097 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1098 else:
1099 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1100
1101 #-------------
1102 # PYTHON INTERFACE
1103
1104 if with_python:
1105 env.SConscript(['pygtk/SConscript'],'env')
1106 else:
1107 print "Skipping... Python GUI isn't being built:",without_python_reason
1108
1109 #------------
1110 # BASE/GENERIC SUBDIRECTORIES
1111
1112 dirs = ['general','utilities','compiler','solver','packages']
1113
1114 srcs = []
1115 for d in dirs:
1116 heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
1117 srcs += heresrcs
1118
1119 #-------------
1120 # LIBASCEND -- all base/generic functionality
1121
1122 libascend = env.SharedLibrary('ascend',srcs)
1123
1124 #-------------
1125 # UNIT TESTS
1126
1127 if with_cunit:
1128 testdirs = ['general','solver','utilities']
1129 testsrcs = []
1130 for testdir in testdirs:
1131 path = 'base/generic/'+testdir+'/test/'
1132 env.SConscript([path+'SConscript'],'env')
1133 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1134
1135 #print "TESTSRCS =",testsrcs
1136
1137 env.SConscript(['test/SConscript'],'env')
1138 env.SConscript(['base/generic/test/SConscript'],'env')
1139
1140 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1141
1142 else:
1143 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1144
1145 #------------------------------------------------------
1146 # INSTALLATION
1147
1148 if env.get('CAN_INSTALL'):
1149 # the models directory only needs to be processed for installation, no other processing required.
1150 env.SConscript(['models/SConscript'],'env')
1151
1152 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB']
1153 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1154
1155 # TODO: add install options
1156 env.Alias('install',install_dirs)
1157
1158 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1159
1160 #------------------------------------------------------
1161 # WINDOWS INSTALLER
1162 # For the windows installer, please see pygtk/SConscript
1163
1164 if with_installer:
1165 pass
1166 else:
1167 print "Skipping... Windows installer isn't being built:",without_installer_reason
1168
1169 #------------------------------------------------------
1170 # CREATE the SPEC file for generation of RPM packages
1171
1172 if platform.system()=="Linux":
1173 env.SubstInFile('ascend.spec.in')
1174
1175 #------------------------------------------------------
1176 # DISTRIBUTION TAR FILE
1177
1178 env['DISTTAR_FORMAT']='bz2'
1179 env.Append(
1180 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1181 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1182 )
1183
1184 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1185 , [env.Dir('#')]
1186 )
1187
1188 #------------------------------------------------------
1189 # RPM BUILD
1190
1191 #if platform.system()=="Linux":
1192 # pass
1193
1194 #------------------------------------------------------
1195 # DEFAULT TARGETS
1196
1197 default_targets =[]
1198 if with_tcltk:
1199 default_targets.append('tcltk')
1200 if with_python:
1201 default_targets.append('pygtk')
1202 if with_installer:
1203 default_targets.append('installer')
1204
1205 env.Default(default_targets)
1206
1207 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1208

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