/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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