/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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