/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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