/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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