/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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