/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 578 - (show annotations) (download)
Tue May 9 04:59:03 2006 UTC (18 years, 4 months ago) by johnpye
File size: 27209 byte(s)
Customisable installer .exe names.
Moved NSIS tool into the scons subdirectory, reverted to standard NsisSconsBuilder from the SCons Wiki.
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/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 conf.CheckTcl():
754 if with_tcltk and conf.CheckTclVersion():
755 if conf.CheckTk():
756 if with_tcltk and conf.CheckTkVersion():
757 if env['STATIC_TCLTK']:
758 if conf.CheckTkTable():
759 pass
760 else:
761 without_tcltk_reason = "TkTable not found"
762 with_tcltk = False
763 else:
764 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
765 with_tcltk = False
766 else:
767 without_tcltk_reason = "Tk not found."
768 with_tcltk = False
769 else:
770 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
771 with_tcltk = False
772
773 else:
774 without_tcltk_reason = "Tcl not found."
775 with_tcltk = False
776
777 if env['STATIC_TCLTK']:
778 conf.CheckX11()
779
780 # Python... obviously we're already running python, so we just need to
781 # check that we can link to the python library OK:
782
783 if platform.system()=="Windows":
784 python_lib='python24'
785 else:
786 python_lib='python2.4'
787
788 # SWIG version
789
790 if not conf.CheckSwigVersion():
791 without_python_reason = 'SWIG >= 1.3.24 is required'
792 with_python = False
793
794 # CUnit
795
796 if with_cunit_tests:
797 if not conf.CheckCUnit():
798 without_cunit_reason = 'CUnit not found'
799
800 # BLAS
801
802 need_blas=False
803 if with_tcltk:
804 need_blas=True
805 if need_blas:
806 if conf.CheckLib('blas'):
807 with_local_blas = False
808 without_local_blas_reason = "Found BLAS installed on system"
809 else:
810 with_local_blas = True
811 need_fortran = True
812
813 # FORTRAN
814
815 if need_fortran:
816 conf.env.Tool('f77')
817 detect_fortran = conf.env.Detect(['g77','f77'])
818 if detect_fortran:
819 # For some reason, g77 doesn't get detected properly on MinGW
820 if not env.has_key('F77'):
821 conf.env.Replace(F77=detect_fortran)
822 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
823 conf.env.Replace(F77FLAGS='')
824 #print "F77:",conf.env['F77']
825 #print "F77COM:",conf.env['F77COM']
826 #print "F77FLAGS:",conf.env['F77FLAGS']
827 fortran_builder = Builder(
828 action='$F77COM'
829 , suffix='.o'
830 , src_suffix='.f'
831 )
832 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
833 else:
834 print "FORTRAN-77 required but not found"
835 Exit(1)
836 #else:
837 # print "FORTRAN not required"
838
839 # TODO: -D_HPUX_SOURCE is needed
840
841 # TODO: check size of void*
842
843 # TODO: detect if dynamic libraries are possible or not
844
845 if platform.system()=="Windows" and env.has_key('MSVS'):
846 if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
847 print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
848 +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
849 env['PACKAGE_LINKING']='STATIC_PACKAGES'
850
851 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
852 with_python = 0;
853 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
854
855 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
856
857 conf.Finish()
858
859 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
860 env.Append(PYTHON_LIB=[python_lib])
861 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
862
863 #---------------------------------------
864 # SUBSTITUTION DICTIONARY for .in files
865
866 subst_dict = {
867 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
868 , '@GLADE_FILE@':'ascend.glade'
869 , '@HELP_ROOT@':''
870 , '@ICON_EXTENSION@':icon_extension
871 , '@INSTALL_DATA@':env['INSTALL_DATA']
872 , '@INSTALL_BIN@':env['INSTALL_BIN']
873 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
874 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
875 , '@VERSION@':version
876 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
877 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
878 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
879 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
880 }
881
882 if env['WITH_LOCAL_HELP']:
883 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
884 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
885
886 if with_python:
887 subst_dict['@ASCXX_USE_PYTHON@']="1"
888
889 if env.has_key('HAVE_GCCVISIBILITY'):
890 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
891
892 env.Append(SUBST_DICT=subst_dict)
893
894 #------------------------------------------------------
895 # RECIPE: SWIG scanner
896
897 import SCons.Script
898
899 SWIGScanner = SCons.Scanner.ClassicCPP(
900 "SWIGScan"
901 , ".i"
902 , "CPPPATH"
903 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
904 )
905
906 env.Append(SCANNERS=[SWIGScanner])
907
908 #------------------------------------------------------
909 # RECIPE: 'SubstInFile', used in pygtk SConscript
910
911 import re
912 from SCons.Script import * # the usual scons stuff you get in a SConscript
913
914 def TOOL_SUBST(env):
915 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
916 from the source to the target.
917 The values of SUBST_DICT first have any construction variables expanded
918 (its keys are not expanded).
919 If a value of SUBST_DICT is a python callable function, it is called and
920 the result is expanded as the value.
921 If there's more than one source and more than one target, each target gets
922 substituted from the corresponding source.
923 """
924 env.Append(TOOLS = 'SUBST')
925 def do_subst_in_file(targetfile, sourcefile, dict):
926 """Replace all instances of the keys of dict with their values.
927 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
928 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
929 """
930 try:
931 f = open(sourcefile, 'rb')
932 contents = f.read()
933 f.close()
934 except:
935 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
936 for (k,v) in dict.items():
937 contents = re.sub(k, v, contents)
938 try:
939 f = open(targetfile, 'wb')
940 f.write(contents)
941 f.close()
942 except:
943 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
944 return 0 # success
945
946 def subst_in_file(target, source, env):
947 if not env.has_key('SUBST_DICT'):
948 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
949 d = dict(env['SUBST_DICT']) # copy it
950 for (k,v) in d.items():
951 if callable(v):
952 d[k] = env.subst(v())
953 elif SCons.Util.is_String(v):
954 d[k]=env.subst(v)
955 else:
956 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
957 for (t,s) in zip(target, source):
958 return do_subst_in_file(str(t), str(s), d)
959
960 def subst_in_file_string(target, source, env):
961 """This is what gets printed on the console."""
962 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
963 for (t,s) in zip(target, source)])
964
965 def subst_emitter(target, source, env):
966 """Add dependency from substituted SUBST_DICT to target.
967 Returns original target, source tuple unchanged.
968 """
969 d = env['SUBST_DICT'].copy() # copy it
970 for (k,v) in d.items():
971 if callable(v):
972 d[k] = env.subst(v())
973 elif SCons.Util.is_String(v):
974 d[k]=env.subst(v)
975 Depends(target, SCons.Node.Python.Value(d))
976 return target, source
977
978 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
979 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
980
981 TOOL_SUBST(env)
982
983 #------------------------------------------------------
984 # Recipe for 'CHMOD' ACTION
985
986 import SCons
987 from SCons.Script.SConscript import SConsEnvironment
988 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
989 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
990
991 def InstallPerm(env, dest, files, perm):
992 obj = env.Install(dest, files)
993 for i in obj:
994 env.AddPostAction(i, env.Chmod(str(i), perm))
995
996 SConsEnvironment.InstallPerm = InstallPerm
997
998 # define wrappers
999 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1000 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1001
1002 #------------------------------------------------------
1003 # BUILD...
1004
1005 # so that #include <modulename/headername.h> works across all modules...
1006 env.Append(CPPPATH=['#base/generic'])
1007
1008 if gcc_version4:
1009 env.Append(CCFLAGS=['-fvisibility=hidden'])
1010
1011 if env['DEBUG']:
1012 env.Append(CCFLAGS=['-g'])
1013
1014 #-------------
1015 # TCL/TK GUI
1016
1017 if with_tcltk:
1018 if with_local_blas:
1019 env.SConscript(['blas/SConscript'],'env')
1020 else:
1021 print "Skipping... BLAS won't be build:", without_local_blas_reason
1022
1023 env.SConscript(['lsod/SConscript'],'env')
1024
1025 env.SConscript(['linpack/SConscript'],'env')
1026 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1027 else:
1028 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1029
1030 #-------------
1031 # PYTHON INTERFACE
1032
1033 if with_python:
1034 env.SConscript(['pygtk/SConscript'],'env')
1035 else:
1036 print "Skipping... Python GUI isn't being built:",without_python_reason
1037
1038 #------------
1039 # BASE/GENERIC SUBDIRECTORIES
1040
1041 dirs = ['general','utilities','compiler','solver','packages']
1042
1043 srcs = []
1044 for d in dirs:
1045 heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
1046 srcs += heresrcs
1047
1048 #-------------
1049 # LIBASCEND -- all base/generic functionality
1050
1051 libascend = env.SharedLibrary('ascend',srcs)
1052
1053 #-------------
1054 # UNIT TESTS
1055
1056 if with_cunit_tests:
1057 testdirs = ['general','solver','utilities']
1058 for testdir in testdirs:
1059 path = 'base/generic/'+testdir+'/test/'
1060 env.SConscript([path+'SConscript'],'env')
1061 env.SConscript(['test/SConscript'],'env')
1062 env.SConscript(['base/generic/test/SConscript'],'env')
1063
1064
1065 else:
1066 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1067
1068
1069 #------------------------------------------------------
1070 # INSTALLATION
1071
1072 if env.get('CAN_INSTALL'):
1073 # the models directory only needs to be processed for installation, no other processing required.
1074 env.SConscript(['models/SConscript'],'env')
1075
1076 dirs = ['INSTALL_BIN','INSTALL_DATA','INSTALL_LIB']
1077 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1078
1079 # TODO: add install options
1080 env.Alias('install',install_dirs)
1081
1082 env.Install(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1083
1084 #------------------------------------------------------
1085 # CREATE the SPEC file for generation of RPM packages
1086
1087 if platform.system()=="Linux":
1088 env.SubstInFile('ascend.spec.in')
1089
1090 #------------------------------------------------------
1091 # DISTRIBUTION TAR FILE
1092
1093 env['DISTTAR_FORMAT']='bz2'
1094 env.Append(
1095 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1096 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1097 )
1098
1099 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1100 , [env.Dir('#')]
1101 )
1102
1103 #------------------------------------------------------
1104 # RPM BUILD
1105
1106 #if platform.system()=="Linux":
1107 # pass
1108
1109 #------------------------------------------------------
1110 # DEFAULT TARGETS
1111
1112 env.Default(['pygtk','tcltk'])
1113

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