/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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