/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 593 - (show annotations) (download)
Fri May 12 10:03:59 2006 UTC (13 years, 6 months ago) by johnpye
File size: 27735 byte(s)
Bumped version to 0.9.5.91.
Changed WITH_CUNIT_TESTS to WITH_CUNIT.
Added GCOV scons option.
Fixed up 'test' target for SCons.
Added lots of export symbols to libascend.so.

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

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