/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 596 - (show annotations) (download)
Fri May 12 11:37:24 2006 UTC (14 years, 4 months ago) by johnpye
File size: 27980 byte(s)
fixed for scons, can't work out a way to allows @MISSING_SOMETHING@ to fallback safely, unfort.
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_XTERM_COLORS@']="1"
903 else:
904 subst_dict['@ASC_XTERM_COLORS@']='0'
905
906 if with_python:
907 subst_dict['@ASCXX_USE_PYTHON@']="1"
908
909 if env.has_key('HAVE_GCCVISIBILITY'):
910 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
911
912 env.Append(SUBST_DICT=subst_dict)
913
914 #------------------------------------------------------
915 # RECIPE: SWIG scanner
916
917 import SCons.Script
918
919 SWIGScanner = SCons.Scanner.ClassicCPP(
920 "SWIGScan"
921 , ".i"
922 , "CPPPATH"
923 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
924 )
925
926 env.Append(SCANNERS=[SWIGScanner])
927
928 #------------------------------------------------------
929 # RECIPE: 'SubstInFile', used in pygtk SConscript
930
931 import re
932 from SCons.Script import * # the usual scons stuff you get in a SConscript
933
934 def TOOL_SUBST(env):
935 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
936 from the source to the target.
937 The values of SUBST_DICT first have any construction variables expanded
938 (its keys are not expanded).
939 If a value of SUBST_DICT is a python callable function, it is called and
940 the result is expanded as the value.
941 If there's more than one source and more than one target, each target gets
942 substituted from the corresponding source.
943 """
944 env.Append(TOOLS = 'SUBST')
945 def do_subst_in_file(targetfile, sourcefile, dict):
946 """Replace all instances of the keys of dict with their values.
947 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
948 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
949 """
950 try:
951 f = open(sourcefile, 'rb')
952 contents = f.read()
953 f.close()
954 except:
955 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
956 for (k,v) in dict.items():
957 contents = re.sub(k, v, contents)
958 try:
959 f = open(targetfile, 'wb')
960 f.write(contents)
961 f.close()
962 except:
963 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
964 return 0 # success
965
966 def subst_in_file(target, source, env):
967 if not env.has_key('SUBST_DICT'):
968 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
969 d = dict(env['SUBST_DICT']) # copy it
970 for (k,v) in d.items():
971 if callable(v):
972 d[k] = env.subst(v())
973 elif SCons.Util.is_String(v):
974 d[k]=env.subst(v)
975 else:
976 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
977 for (t,s) in zip(target, source):
978 return do_subst_in_file(str(t), str(s), d)
979
980 def subst_in_file_string(target, source, env):
981 """This is what gets printed on the console."""
982 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
983 for (t,s) in zip(target, source)])
984
985 def subst_emitter(target, source, env):
986 """Add dependency from substituted SUBST_DICT to target.
987 Returns original target, source tuple unchanged.
988 """
989 d = env['SUBST_DICT'].copy() # copy it
990 for (k,v) in d.items():
991 if callable(v):
992 d[k] = env.subst(v())
993 elif SCons.Util.is_String(v):
994 d[k]=env.subst(v)
995 Depends(target, SCons.Node.Python.Value(d))
996 return target, source
997
998 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
999 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1000
1001 TOOL_SUBST(env)
1002
1003 #------------------------------------------------------
1004 # Recipe for 'CHMOD' ACTION
1005
1006 import SCons
1007 from SCons.Script.SConscript import SConsEnvironment
1008 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1009 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1010
1011 def InstallPerm(env, dest, files, perm):
1012 obj = env.Install(dest, files)
1013 for i in obj:
1014 env.AddPostAction(i, env.Chmod(str(i), perm))
1015
1016 SConsEnvironment.InstallPerm = InstallPerm
1017
1018 # define wrappers
1019 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1020 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1021
1022 #------------------------------------------------------
1023 # BUILD...
1024
1025 # so that #include <modulename/headername.h> works across all modules...
1026 env.Append(CPPPATH=['#base/generic'])
1027
1028 if gcc_version4:
1029 env.Append(CCFLAGS=['-fvisibility=hidden'])
1030
1031 if env['DEBUG']:
1032 env.Append(CCFLAGS=['-g'])
1033
1034 if env['GCOV']:
1035 env.Append(
1036 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1037 , LIBS=['gcov']
1038 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1039 )
1040
1041 #-------------
1042 # TCL/TK GUI
1043
1044 if with_tcltk:
1045 if with_local_blas:
1046 env.SConscript(['blas/SConscript'],'env')
1047 else:
1048 print "Skipping... BLAS won't be build:", without_local_blas_reason
1049
1050 env.SConscript(['lsod/SConscript'],'env')
1051
1052 env.SConscript(['linpack/SConscript'],'env')
1053 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1054 else:
1055 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1056
1057 #-------------
1058 # PYTHON INTERFACE
1059
1060 if with_python:
1061 env.SConscript(['pygtk/SConscript'],'env')
1062 else:
1063 print "Skipping... Python GUI isn't being built:",without_python_reason
1064
1065 #------------
1066 # BASE/GENERIC SUBDIRECTORIES
1067
1068 dirs = ['general','utilities','compiler','solver','packages']
1069
1070 srcs = []
1071 for d in dirs:
1072 heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
1073 srcs += heresrcs
1074
1075 #-------------
1076 # LIBASCEND -- all base/generic functionality
1077
1078 libascend = env.SharedLibrary('ascend',srcs)
1079
1080 #-------------
1081 # UNIT TESTS
1082
1083 if with_cunit:
1084 testdirs = ['general','solver','utilities']
1085 testsrcs = []
1086 for testdir in testdirs:
1087 path = 'base/generic/'+testdir+'/test/'
1088 env.SConscript([path+'SConscript'],'env')
1089 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1090
1091 #print "TESTSRCS =",testsrcs
1092
1093 env.SConscript(['test/SConscript'],'env')
1094 env.SConscript(['base/generic/test/SConscript'],'env')
1095
1096 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1097
1098 else:
1099 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1100
1101
1102 #------------------------------------------------------
1103 # INSTALLATION
1104
1105 if env.get('CAN_INSTALL'):
1106 # the models directory only needs to be processed for installation, no other processing required.
1107 env.SConscript(['models/SConscript'],'env')
1108
1109 dirs = ['INSTALL_BIN','INSTALL_DATA','INSTALL_LIB']
1110 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1111
1112 # TODO: add install options
1113 env.Alias('install',install_dirs)
1114
1115 env.Install(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1116
1117 #------------------------------------------------------
1118 # CREATE the SPEC file for generation of RPM packages
1119
1120 if platform.system()=="Linux":
1121 env.SubstInFile('ascend.spec.in')
1122
1123 #------------------------------------------------------
1124 # DISTRIBUTION TAR FILE
1125
1126 env['DISTTAR_FORMAT']='bz2'
1127 env.Append(
1128 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1129 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1130 )
1131
1132 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1133 , [env.Dir('#')]
1134 )
1135
1136 #------------------------------------------------------
1137 # RPM BUILD
1138
1139 #if platform.system()=="Linux":
1140 # pass
1141
1142 #------------------------------------------------------
1143 # DEFAULT TARGETS
1144
1145 env.Default(['pygtk','tcltk'])
1146

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