/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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