/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 845 - (show annotations) (download)
Sun Sep 17 05:55:09 2006 UTC (13 years, 2 months ago) by johnpye
File size: 40794 byte(s)
Updated installer to allow separate choices of PyGTK and Tcl/Tk GUIs at install-time.
Installer won't allow GUIs to be installed unless ActiveTcl and/or Python are located.
Bumped version to 0.9.5.99.
1 import os, commands, platform, distutils.sysconfig, os.path, re
2
3 version = "0.9.5.99"
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
28 default_ida_prefix = "c:\\MinGW"
29 if not os.path.exists(default_ida_prefix):
30 default_ida_prefix = None
31
32 default_conopt_prefix = "c:\\Program Files\\CONOPT"
33 default_conopt_libpath="$CONOPT_PREFIX"
34 default_conopt_cpppath="$CONOPT_PREFIX"
35 default_conopt_lib="conopt3"
36 default_conopt_envvar="CONOPT_PATH"
37
38 if not os.path.exists(default_conopt_prefix):
39 default_conopt_prefix = None
40
41 need_libm = False
42 python_exe = "c:\\Python24\\python.exe"
43 default_with_scrollkeeper=False
44 else:
45 default_tcl_lib = "tcl8.4"
46 default_tk_lib = "tk8.4"
47 default_tktable_lib = "Tktable2.8"
48 default_install_assets = "$INSTALL_ASCDATA/glade/"
49 icon_extension = '.svg'
50 default_tcl = '/usr'
51 default_tcl_libpath = "$TCL/lib"
52 default_rel_distdir = '../share/ascend'
53 default_absolute_paths = True
54 default_ida_prefix="/usr/local"
55 default_conopt_prefix="/usr"
56 default_conopt_libpath="$CONOPT_PREFIX/lib"
57 default_conopt_cpppath="$CONOPT_PREFIX/include"
58 default_conopt_lib="consub3"
59 default_conopt_envvar="CONOPT_PATH"
60
61 need_libm = True
62 if not os.path.isdir(default_tcl):
63 default_tcl = '/usr'
64 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
65 default_with_scrollkeeper=False
66
67 opts.Add(
68 'CC'
69 ,'C Compiler command'
70 ,None
71 )
72
73 opts.Add(
74 'CXX'
75 ,'C++ Compiler command'
76 ,None
77 )
78
79 opts.Add(BoolOption(
80 'GCOV'
81 , 'Whether to enable coverage testing in object code'
82 , False
83 ))
84
85 # Package linking option
86 opts.Add(EnumOption(
87 'PACKAGE_LINKING'
88 , 'Style of linking for external libraries'
89 , 'DYNAMIC_PACKAGES'
90 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
91 ))
92
93 opts.Add(BoolOption(
94 'WITH_GCCVISIBILITY'
95 ,"Whether to use GCC Visibility features (only applicable if available)"
96 ,True
97 ))
98
99 # You can turn off building of Tcl/Tk interface
100 opts.Add(BoolOption(
101 'WITH_TCLTK'
102 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
103 , True
104 ))
105
106 # You can turn off the building of the Python interface
107 opts.Add(BoolOption(
108 'WITH_PYTHON'
109 ,"Set to False if you don't want to build Python wrappers."
110 , True
111 ))
112
113 # Which solvers will we allow?
114 opts.Add(ListOption(
115 'WITH_SOLVERS'
116 ,"List of the solvers you want to build. The default is the minimum that"
117 +" works."
118 ,["QRSLV","CMSLV","LSOD","IDA","CONOPT","LRSLV"]
119 ,['QRSLV','MPS','SLV','OPTSQP'
120 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
121 ,'LSOD','OPTSQP',"IDA"
122 ]
123 ))
124
125 # Where will the local copy of the help files be kept?
126 opts.Add(PackageOption(
127 'WITH_LOCAL_HELP'
128 , "Directory containing the local copy of the help files (optional)"
129 , "no"
130 ))
131
132 # Will bintoken support be enabled?
133 opts.Add(BoolOption(
134 'WITH_BINTOKEN'
135 ,"Enable bintoken support? This means compiling models as C-code before"
136 +" running them, to increase solving speed for large models."
137 ,False
138 ))
139
140 # What should the default ASCENDLIBRARY path be?
141 # Note: users can change it by editing their ~/.ascend.ini
142 opts.Add(
143 'DEFAULT_ASCENDLIBRARY'
144 ,"Set the default value of the ASCENDLIBRARY -- the location where"
145 +" ASCEND will look for models when running ASCEND"
146 ,"$INSTALL_ASCDATA/models"
147 )
148
149 # Where is SWIG?
150 opts.Add(
151 'SWIG'
152 ,"SWIG location, probably only required for MinGW and MSVC users."
153 +" Enter the location as a Windows-style path, for example"
154 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
155 )
156
157 # Build the test suite?
158 opts.Add(BoolOption(
159 'WITH_CUNIT'
160 ,"You can disable CUnit tests with this option. This will basically stop"
161 +" SCons from parsing the SConscript files relating to the 'test'"
162 +" target, which just might make things marginally faster. Probably"
163 +" you can just ignore this option though. SCons will sniff for Cunit"
164 +" but build the tests only if you specify the 'test' target."
165 ,True
166 ))
167
168 # Where are the CUnit includes?
169 opts.Add(PackageOption(
170 'CUNIT_CPPPATH'
171 ,"Where are your CUnit include files?"
172 ,'off'
173 ))
174
175 # Where are the CUnit libraries?
176 opts.Add(PackageOption(
177 'CUNIT_LIBPATH'
178 ,"Where are your CUnit libraries?"
179 ,'off'
180 ))
181
182 opts.Add(PackageOption(
183 "IDA_PREFIX"
184 ,"Prefix for your IDA install (IDA ./configure --prefix)"
185 ,default_ida_prefix
186 ))
187
188 opts.Add(
189 "IDA_LIB"
190 ,"Libraries linked to for IDA"
191 ,['sundials_ida','sundials_nvecserial','m']
192 )
193
194 opts.Add(
195 'IDA_CPPPATH'
196 ,"Where is your ida.h?"
197 ,"$IDA_PREFIX/include"
198 )
199
200 opts.Add(
201 'IDA_LIBPATH'
202 ,"Where are your SUNDIALS libraries installed?"
203 ,"$IDA_PREFIX/lib"
204 )
205
206 # conopt
207
208 opts.Add(PackageOption(
209 "CONOPT_PREFIX"
210 ,"Prefix for your CONOPT install (CONOPT ./configure --prefix)"
211 ,default_conopt_prefix
212 ))
213
214 opts.Add(
215 "CONOPT_LIB"
216 ,"Library linked to for CONOPT"
217 ,default_conopt_lib
218 )
219
220 opts.Add(
221 'CONOPT_CPPPATH'
222 ,"Where is your conopt.h?"
223 ,default_conopt_cpppath
224 )
225
226 opts.Add(
227 'CONOPT_LIBPATH'
228 ,"Where is your CONOPT libraries installed?"
229 ,default_conopt_libpath
230 )
231
232 opts.Add(
233 'CONOPT_ENVVAR'
234 ,"What environment variable should be used at runtime to override the default search location for CONOPT DLL/SO?"
235 ,default_conopt_envvar
236 )
237
238 opts.Add(
239 "F2C_LIB"
240 ,"F2C library (eg. g2c, gfortran, f2c)"
241 ,"g2c"
242 )
243
244 opts.Add(PackageOption(
245 "F2C_LIBPATH"
246 ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
247 ,"off"
248 ))
249
250 opts.Add(
251 'TCL'
252 ,'Base of Tcl distribution'
253 ,default_tcl
254 )
255
256 # Where are the Tcl includes?
257 opts.Add(
258 'TCL_CPPPATH'
259 ,"Where are your Tcl include files?"
260 ,"$TCL/include"
261 )
262
263 # Where are the Tcl libs?
264 opts.Add(
265 'TCL_LIBPATH'
266 ,"Where are your Tcl libraries?"
267 ,default_tcl_libpath
268 )
269
270 # What is the name of the Tcl lib?
271 opts.Add(
272 'TCL_LIB'
273 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
274 ,default_tcl_lib
275 )
276
277 # Where are the Tk includes?
278 opts.Add(
279 'TK_CPPPATH'
280 ,"Where are your Tk include files?"
281 ,'$TCL_CPPPATH'
282 )
283
284 # Where are the Tk libs?
285 opts.Add(
286 'TK_LIBPATH'
287 ,"Where are your Tk libraries?"
288 ,'$TCL_LIBPATH'
289 )
290
291 # What is the name of the Tk lib?
292 opts.Add(
293 'TK_LIB'
294 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
295 ,default_tk_lib
296 )
297
298 # Static linking to TkTable
299
300 opts.Add(BoolOption(
301 'STATIC_TCLTK'
302 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
303 ,False
304 ))
305
306 opts.Add(
307 'TKTABLE_LIBPATH'
308 ,'Location of TkTable static library'
309 ,'$TCL_LIBPATH/Tktable2.8'
310 )
311
312 opts.Add(
313 'TKTABLE_LIB'
314 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
315 ,default_tktable_lib
316 )
317
318 opts.Add(
319 'TKTABLE_CPPPATH'
320 ,'Location of TkTable header file'
321 ,'$TCL_CPPPATH'
322 )
323
324 opts.Add(
325 'X11'
326 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
327 ,'/usr/X11R6'
328 )
329
330 opts.Add(
331 'X11_LIBPATH'
332 ,'Location of X11 lib. EXPERIMENTAL'
333 ,'$X11/lib'
334 )
335
336 opts.Add(
337 'X11_CPPPATH'
338 ,'Location of X11 includes. EXPERIMENTAL'
339 ,'$X11/include'
340 )
341
342 opts.Add(
343 'X11_LIB'
344 ,'Name of X11 lib. EXPERIMENTAL'
345 ,'X11'
346 )
347
348 opts.Add(
349 'INSTALL_PREFIX'
350 ,'Root location for installed files'
351 ,'/usr/local'
352 )
353
354 opts.Add(
355 'INSTALL_BIN'
356 ,'Location to put binaries during installation'
357 ,"$INSTALL_PREFIX/bin"
358 )
359
360 opts.Add(
361 'INSTALL_LIB'
362 ,'Location to put libraries during installation'
363 ,"$INSTALL_PREFIX/lib"
364 )
365
366 opts.Add(
367 'INSTALL_SHARE'
368 ,'Common shared-file location on this system'
369 ,"$INSTALL_PREFIX/share"
370 )
371
372 opts.Add(
373 'INSTALL_DOC'
374 ,'Location to install documentation files'
375 ,"$INSTALL_SHARE/doc/ascend"
376 )
377
378 opts.Add(
379 'INSTALL_ASCDATA'
380 ,"Location of ASCEND shared data (TK, python, models etc)"
381 ,"$INSTALL_SHARE/ascend"
382 )
383
384 opts.Add(
385 'INSTALL_INCLUDE'
386 ,'Location to put header files during installation'
387 ,"$INSTALL_PREFIX/include"
388 )
389
390 opts.Add(
391 'PYGTK_ASSETS'
392 ,'Default location for Glade assets (placed in pygtk/config.py)'
393 ,default_install_assets
394 )
395
396 opts.Add(BoolOption(
397 'DEBUG'
398 ,"Compile source with debugger symbols, eg for use with 'gdb'"
399 ,False
400 ))
401
402 opts.Add(BoolOption(
403 'MALLOC_DEBUG'
404 ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
405 ,False
406 ))
407
408 opts.Add(
409 'INSTALL_ROOT'
410 ,'For use by RPM only: location of %{buildroot} during rpmbuild'
411 ,""
412 )
413
414 opts.Add(
415 'DISTTAR_NAME'
416 ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
417 ,"ascend-"+version
418 )
419
420 opts.Add(
421 'RELEASE'
422 ,"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."
423 ,"0"
424 )
425
426 opts.Add(BoolOption(
427 'ABSOLUTE_PATHS'
428 ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
429 ,default_absolute_paths
430 ))
431
432 opts.Add(
433 'WIN_INSTALLER_NAME'
434 ,"Name of the installer .exe to create under Windows (minus the '.exe')"
435 ,"ascend-"+version
436 )
437
438 opts.Add(BoolOption(
439 'WITH_XTERM_COLORS'
440 ,"Set to 0 if you don't want xterm colour codes in the console output"
441 ,True
442 ))
443
444 opts.Add(BoolOption(
445 'WITH_EXTFNS'
446 ,"Set to 0 if you don't want to attempt to build external modules bundled"
447 + " with ASCEND."
448 ,True
449 ))
450
451 opts.Add(BoolOption(
452 'WITH_SCROLLKEEPER'
453 ,"Set to to 1 if you want to install an OMF file that can be read by scrollkeeper (eg Yelp on GNOME)"
454 ,default_with_scrollkeeper
455 ))
456
457 if platform.system()!="Windows":
458 opts.Add(BoolOption(
459 'WITH_GCCVISIBILITY'
460 , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
461 , True
462 ))
463
464
465
466 # TODO: OTHER OPTIONS?
467 # TODO: flags for optimisation
468 # TODO: turning on/off bintoken functionality
469 # TODO: Where will the 'Makefile.bt' file be installed?
470
471 # Import the outside environment
472
473 def c_escape(str):
474 return re.sub("\\\\","/",str)
475
476 envadditional={}
477
478 if platform.system()=="Windows":
479 if os.environ.get('OSTYPE')=='msys':
480 envenv = os.environ;
481 tools = ['mingw','lex','yacc','fortran','swig','disttar','nsis','doxygen']
482 envadditional['IS_MINGW']=True
483 else:
484 envenv = {
485 'PATH':os.environ['PATH']
486 ,'INCLUDE':os.environ['INCLUDE']
487 ,'LIB':os.environ['LIB']
488 ,'MSVS_IGNORE_IDE_PATHS':1
489 }
490 tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
491 envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
492 else:
493 if os.environ.get('TARGET')=='mingw':
494 envenv = os.environ
495 tools=['crossmingw','lex','yacc','disttar','nsis','doxygen']
496 envadditional['CPPPATH']=['/usr/local/lib/gcc/i386-mingw32/3.4.5/include','/usr/include']
497 else:
498 envenv = os.environ
499 tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
500
501
502 env = Environment(
503 ENV=envenv
504 , toolpath=['scons']
505 , tools=tools
506 , **envadditional
507 )
508
509 opts.Update(env)
510 opts.Save('options.cache',env)
511
512 Help(opts.GenerateHelpText(env))
513
514 with_tcltk = env.get('WITH_TCLTK')
515 without_tcltk_reason = "disabled by options/config.py"
516
517 with_python = env.get('WITH_PYTHON')
518 without_python_reason = "disabled by options/config.py"
519
520 with_cunit = env.get('WITH_CUNIT')
521 without_cunit_reason = "not requested"
522
523 with_extfns = env.get('WITH_EXTFNS')
524 without_extfn_reason = "disabled by options/config.py"
525
526 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
527 without_scrollkeeper_reason = "disabled by options/config.py"
528
529 if platform.system()=="Windows":
530 with_installer=1
531 else:
532 with_installer=0
533 without_installer_reason = "only possible under Windows"
534
535 if 'LSOD' in env['WITH_SOLVERS']:
536 with_lsode=True
537 else:
538 with_lsode=False
539 without_lsode_reason = "not requested (WITH_SOLVERS)"
540
541 if 'IDA' in env['WITH_SOLVERS']:
542 with_ida=True
543 else:
544 with_ida=False
545 without_ida_reason = "not requested (WITH_SOLVERS)"
546
547
548 if 'CONOPT' in env['WITH_SOLVERS']:
549 with_conopt=True
550 else:
551 with_conopt=False
552 without_conopt_reason = "not requested (WITH_SOLVERS)"
553
554
555 #print "SOLVERS:",env['WITH_SOLVERS']
556 #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
557 #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
558
559 can_install = True
560 if platform.system()=='Windows':
561 can_install = False
562
563 env['CAN_INSTALL']=can_install
564
565 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
566
567 print "TCL_CPPPATH =",env['TCL_CPPPATH']
568 print "TCL_LIBPATH =",env['TCL_LIBPATH']
569 print "TCL_LIB =",env['TCL_LIB']
570 print "CC =",env['CC']
571 print "CXX =",env['CXX']
572 print "FORTRAN=",env.get('FORTRAN')
573
574 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
575 #------------------------------------------------------
576 # SPECIAL CONFIGURATION TESTS
577
578 need_fortran = False
579
580 #----------------
581 # SWIG
582
583 import os,re
584
585 def get_swig_version(env):
586 cmd = env['SWIG']+' -version'
587 (cin,coutcerr) = os.popen4(cmd)
588 output = coutcerr.read()
589
590 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
591 expr = re.compile(restr,re.M);
592 m = expr.search(output);
593 if not m:
594 return None
595 maj = int(m.group('maj'))
596 min = int(m.group('min'))
597 pat = int(m.group('pat'))
598
599 return (maj,min,pat)
600
601
602 def CheckSwigVersion(context):
603
604 try:
605 context.Message("Checking version of SWIG... ")
606 maj,min,pat = get_swig_version(context.env)
607 except:
608 context.Result("Failed to detect version, or failed to run SWIG")
609 return 0;
610
611 context.env['SWIGVERSION']=tuple([maj,min,pat])
612
613 if maj == 1 and (
614 min > 3
615 or (min == 3 and pat >= 24)
616 ):
617 context.Result("ok, %d.%d.%d" % (maj,min,pat))
618 return 1;
619 else:
620 context.Result("too old, %d.%d.%d" % (maj,min,pat))
621 return 0;
622
623 #----------------
624 # Scrollkeeper (Linux documentation system)
625
626 def get_scrollkeeper_omfdir(env):
627 cmd = 'scrollkeeper-config --omfdir'
628 (cin,coutcerr) = os.popen4(cmd)
629 output = coutcerr.read()
630 return output.strip()
631
632 def CheckScrollkeeperConfig(context):
633 try:
634 context.Message("Checking for scrollkeeper...")
635 dir=get_scrollkeeper_omfdir(context.env)
636 except:
637 context.Result("Failed to run 'scrollkeeper-config'")
638 return 0
639 context.env['OMFDIR']=dir
640 context.Result("OK, %s" % dir)
641 return 1
642
643 #----------------
644 # General purpose library-and-header test
645
646 class KeepContext:
647 def __init__(self,context,varprefix,static=False):
648 self.keep = {}
649 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
650 #print "Keeping env %s = %s" % (k,context.env.get(k))
651 self.keep[k]=context.env.get(k)
652
653 if context.env.has_key(varprefix+'_CPPPATH'):
654 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
655 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
656
657 if static:
658 staticlib=env[varprefix+'_LIB']
659 #print "STATIC LIB = ",staticlib
660 context.env.Append(
661 LINKFLAGS=[staticlib]
662 )
663 else:
664 if context.env.has_key(varprefix+'_LIBPATH'):
665 context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
666 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
667
668 if context.env.has_key(varprefix+'_LIB'):
669 context.env.Append(LIBS=[env[varprefix+'_LIB']])
670 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
671
672 def restore(self,context):
673 #print "RESTORING CONTEXT"
674 #print self.keep
675 #print "..."
676 for k in self.keep:
677 if self.keep[k]==None:
678 if context.env.has_key(k):
679 #print "Clearing "+str(k)
680 del context.env[k];
681 else:
682 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
683 context.env[k]=self.keep[k];
684
685 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
686 """This method will check for variables LIBNAME_LIBPATH
687 and LIBNAME_CPPPATH and try to compile and link the
688 file with the provided text, linking with the
689 library libname."""
690
691 if static:
692 context.Message( 'Checking for static '+libname+'... ' )
693 else:
694 context.Message( 'Checking for '+libname+'... ' )
695
696 if varprefix==None:
697 varprefix = libname.upper()
698
699 #print "LIBS is currently:",context.env.get('LIBS')
700 keep = KeepContext(context,varprefix,static)
701
702 if not context.env.has_key(varprefix+'_LIB'):
703 # if varprefix_LIB were in env, KeepContext would
704 # have appended it already
705 context.env.Append(LIBS=[libname])
706
707 is_ok = context.TryLink(text,ext)
708
709 #print "Link success? ",(is_ok != 0)
710
711 keep.restore(context)
712
713 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
714 # print "Restored LIBS="+str(context.env['LIBS'])
715 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
716
717 context.Result(is_ok)
718 return is_ok
719
720 #----------------
721 # GCC
722
723 gcc_test_text = """
724 #ifndef __GNUC__
725 # error "Not using GCC"
726 #endif
727
728 int main(void){
729 return __GNUC__;
730 }
731 """
732
733 def CheckGcc(context):
734 context.Message("Checking for GCC... ")
735 is_ok = context.TryCompile(gcc_test_text,".c")
736 context.Result(is_ok)
737 return is_ok
738
739 #----------------
740 # GCC VISIBILITY feature
741
742 gccvisibility_test_text = """
743 #if __GNUC__ < 4
744 # error "Require GCC version 4 or newer"
745 #endif
746
747 __attribute__ ((visibility("default"))) int x;
748
749 int main(void){
750 extern int x;
751 x = 4;
752 }
753 """
754
755 def CheckGccVisibility(context):
756 context.Message("Checking for GCC 'visibility' capability... ")
757 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
758 context.Result("disabled")
759 return 0
760 is_ok = context.TryCompile(gccvisibility_test_text,".c")
761 context.Result(is_ok)
762 return is_ok
763
764 #----------------
765 # YACC
766
767 yacc_test_text = """
768 %{
769 #include <stdio.h>
770
771 /* MSVC++ needs this before it can swallow Bison output */
772 #ifdef _MSC_VER
773 # define __STDC__
774 #endif
775 %}
776 %token MSG
777 %start ROOT
778 %%
779 ROOT:
780 MSG { printf("HELLO"); }
781 ;
782 %%
783 """
784
785 def CheckYacc(context):
786 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
787 is_ok = context.TryCompile(yacc_test_text,".y")
788 context.Result(is_ok)
789 return is_ok
790
791 #----------------
792 # CUnit test
793
794 cunit_test_text = """
795 #include <CUnit/CUnit.h>
796 int maxi(int i1, int i2){
797 return (i1 > i2) ? i1 : i2;
798 }
799
800 void test_maxi(void){
801 CU_ASSERT(maxi(0,2) == 2);
802 CU_ASSERT(maxi(0,-2) == 0);
803 CU_ASSERT(maxi(2,2) == 2);
804
805 }
806 int main(void){
807 /* CU_initialize_registry() */
808 return 0;
809 }
810 """
811
812 def CheckCUnit(context):
813 return CheckExtLib(context,'cunit',cunit_test_text)
814
815 #----------------
816 # MATH test
817
818 math_test_text = """
819 #ifndef _ALL_SOURCE
820 # define _ALL_SOURCE
821 #endif
822 #ifndef _XOPEN_SOURCE
823 # define _XOPEN_SOURCE
824 #endif
825 #ifndef _XOPEN_SOURCE_EXTENDED
826 # define _XOPEN_SOURCE_EXTENDED 1
827 #endif
828 #include <math.h>
829 int main(void){
830 double x = 1.0; double y = 1.0; int i = 1;
831 acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
832 j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
833 y0(x); y1(x); yn(i,x);
834 #ifdef _THREAD_SAFE
835 gamma_r(x,&i);
836 lgamma_r(x,&i);
837 #else
838 gamma(x);
839 lgamma(x);
840 #endif
841 hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
842 return 0;
843 }
844 """
845
846 def CheckMath(context):
847 context.Message('Checking for IEEE math library... ')
848 libsave=context.env.get('LIBS');
849 context.env.AppendUnique(LIBS=['m'])
850 is_ok=context.TryLink(math_test_text,".c")
851 context.Result(is_ok)
852 if not is_ok:
853 context.env['LIBS']=libsave
854 return is_ok
855
856 #----------------
857 # IDA test
858
859 ida_test_text = """
860 #include <ida/ida.h>
861 #include <nvector/nvector_serial.h>
862 #include <ida/ida_spgmr.h>
863 int main(){
864 void *ida_mem;
865 ida_mem = IDACreate();
866 return 0;
867 }
868 """
869
870 def CheckIDA(context):
871 context.Message( 'Checking for IDA (SUNDIALS)... ' )
872
873 keep = KeepContext(context,"IDA")
874
875 is_ok = context.TryLink(ida_test_text,".c")
876 context.Result(is_ok)
877
878 keep.restore(context)
879
880 return is_ok
881
882 #----------------
883 # CONOPT test
884
885 conopt_test_text = """
886 #if !defined(_WIN32)
887 # define FNAME_LCASE_DECOR
888 #endif
889
890 #include <conopt.h>
891 #include <stdlib.h>
892 int main(){
893 int s, *v, e;
894 s = COIDEF_Size();
895 v = (int *)malloc(s*sizeof(int));
896 e = COIDEF_Ini(v);
897 return e;
898 }
899 """
900
901 def CheckCONOPT(context):
902 context.Message( 'Checking for CONOPT... ' )
903
904 keep = KeepContext(context,"CONOPT")
905
906 is_ok = context.TryLink(conopt_test_text,".c")
907 context.Result(is_ok)
908
909 keep.restore(context)
910
911 return is_ok
912
913 #----------------
914 # Tcl test
915
916 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
917 tcltk_minor_newest_acceptable = 4
918 tcltk_major_required = 8
919
920 tcl_check_text = r"""
921 #include <tcl.h>
922 #include <stdio.h>
923 int main(void){
924 printf("%s",TCL_PATCH_LEVEL);
925 return 0;
926 }
927 """
928
929 def CheckTcl(context):
930 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
931
932 def CheckTclVersion(context):
933 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
934 context.Message("Checking Tcl version... ")
935 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
936 keep.restore(context)
937 if not is_ok:
938 context.Result("failed to run check")
939 return 0
940
941 major,minor,patch = tuple([int(i) for i in output.split(".")])
942 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
943 context.Result(output+" (bad version)")
944 # bad version
945 return 0
946
947 # good version
948 context.Result(output+", good")
949 return 1
950
951 #----------------
952 # Tk test
953
954 tk_check_text = r"""
955 #include <tk.h>
956 #include <stdio.h>
957 int main(void){
958 printf("%s",TK_PATCH_LEVEL);
959 return 0;
960 }
961 """
962 def CheckTk(context):
963 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
964
965
966 def CheckTkVersion(context):
967 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
968 context.Message("Checking Tk version... ")
969 #print "LINKFLAGS =",context.env['LINKFLAGS']
970 (is_ok,output) = context.TryRun(tk_check_text,'.c')
971 keep.restore(context)
972 if not is_ok:
973 context.Result("failed to run check")
974 return 0
975
976 major,minor,patch = tuple([int(i) for i in output.split(".")])
977 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
978 # bad version
979 context.Result(output+" (bad version)")
980 return 0
981
982 # good version
983 context.Result(output+" (good)")
984 return 1
985
986 #----------------
987 # Tktable test
988
989 tktable_check_text = r"""
990 #include <tkTable.h>
991 #include <stdio.h>
992 int main(void){
993 Table mytable;
994 return 0;
995 }
996 """
997
998 def CheckTkTable(context):
999 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1000
1001 #---------------
1002 # X11 test
1003
1004 x11_check_text = r"""
1005 #include <X11/Xlib.h>
1006 #include <X11/IntrinsicP.h>
1007 #include <X11/Intrinsic.h>
1008 #include <X11/ObjectP.h>
1009 #include <X11/Object.h>
1010 int main(void){
1011 Object mything;
1012 return 0;
1013 }
1014 """
1015
1016 def CheckX11(context):
1017 return CheckExtLib(context,'X11',x11_check_text)
1018
1019 #----------------
1020 # GCC Version sniffing
1021
1022 # TODO FIXME
1023
1024 gcc_version4 = False
1025
1026 #------------------------------------------------------
1027 # CONFIGURATION
1028
1029 conf = Configure(env
1030 , custom_tests = {
1031 'CheckMath' : CheckMath
1032 , 'CheckSwigVersion' : CheckSwigVersion
1033 , 'CheckCUnit' : CheckCUnit
1034 , 'CheckTcl' : CheckTcl
1035 , 'CheckTclVersion' : CheckTclVersion
1036 , 'CheckTk' : CheckTk
1037 , 'CheckTkVersion' : CheckTkVersion
1038 , 'CheckGcc' : CheckGcc
1039 , 'CheckGccVisibility' : CheckGccVisibility
1040 , 'CheckYacc' : CheckYacc
1041 , 'CheckTkTable' : CheckTkTable
1042 , 'CheckX11' : CheckX11
1043 , 'CheckIDA' : CheckIDA
1044 , 'CheckCONOPT' : CheckCONOPT
1045 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
1046 # , 'CheckIsNan' : CheckIsNan
1047 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
1048 }
1049 # , config_h = "config.h"
1050 )
1051
1052 # stdio -- just to check that compiler is behaving
1053
1054 if not conf.CheckHeader('stdio.h'):
1055 print "CPPPATH =",env.get('CPPPATH')
1056 print "Did not find 'stdio.h'! Check your compiler configuration."
1057 Exit(1)
1058
1059 # Math library
1060
1061 if need_libm:
1062 if not conf.CheckMath():
1063 print 'Did not find math library, exiting!'
1064 Exit(1)
1065 #pass
1066
1067 # Where is 'isnan'?
1068
1069 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1070 print "Didn't find isnan"
1071 # Exit(1)
1072
1073 # GCC visibility
1074
1075 if conf.CheckGcc():
1076 conf.env['HAVE_GCC']=True;
1077 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
1078 conf.env['HAVE_GCCVISIBILITY']=True;
1079 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1080 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1081 conf.env.Append(CCFLAGS=['-Wall'])
1082
1083 # YACC
1084
1085 if not conf.CheckYacc():
1086 print "YACC NOT FOUND OR NOT WORKING"
1087 else:
1088 conf.env['HAVE_YACC']=True
1089
1090 conf.env['HAVE_LEX']=True
1091
1092 # Tcl/Tk
1093
1094 if with_tcltk:
1095 if conf.CheckTcl():
1096 if conf.CheckTclVersion():
1097 if conf.CheckTk():
1098 if with_tcltk and conf.CheckTkVersion():
1099 if env['STATIC_TCLTK']:
1100 if conf.CheckTkTable():
1101 pass
1102 else:
1103 without_tcltk_reason = "TkTable not found"
1104 with_tcltk = False
1105 else:
1106 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1107 with_tcltk = False
1108 else:
1109 without_tcltk_reason = "Tk not found."
1110 with_tcltk = False
1111 else:
1112 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1113 with_tcltk = False
1114
1115 else:
1116 without_tcltk_reason = "Tcl not found."
1117 with_tcltk = False
1118
1119 if env['STATIC_TCLTK']:
1120 conf.CheckX11()
1121
1122 # Python... obviously we're already running python, so we just need to
1123 # check that we can link to the python library OK:
1124
1125 if platform.system()=="Windows":
1126 python_lib='python24'
1127 else:
1128 python_lib='python2.4'
1129
1130 # SWIG version
1131
1132 if not conf.CheckSwigVersion():
1133 without_python_reason = 'SWIG >= 1.3.24 is required'
1134 with_python = False
1135
1136 # CUnit
1137
1138 if with_cunit:
1139 if not conf.CheckCUnit():
1140 without_cunit_reason = 'CUnit not found'
1141 with_cunit = False
1142 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1143
1144 # IDA
1145
1146 if not with_ida:
1147 without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1148 elif not conf.CheckIDA():
1149 with_ida = False
1150 without_ida_reason = "IDA not found"
1151
1152 # CONOPT
1153
1154 if not with_conopt:
1155 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1156 elif not conf.CheckCONOPT():
1157 with_conopt = False
1158 without_conpt_reason = "CONOPT not found"
1159
1160 # BLAS
1161
1162 need_blas=False
1163
1164 if with_lsode:
1165 need_fortran = True
1166 need_blas=True
1167
1168 if need_blas:
1169 if conf.CheckLib('blas'):
1170 with_local_blas = False
1171 without_local_blas_reason = "Found BLAS installed on system"
1172 else:
1173 with_local_blas = True
1174 need_fortran = True
1175 else:
1176 with_local_blas= False;
1177 without_local_blas_reason = "BLAS not required"
1178
1179 # FORTRAN
1180
1181 if need_fortran:
1182 conf.env.Tool('fortran')
1183 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1184 if detect_fortran:
1185 # For some reason, g77 doesn't get detected properly on MinGW
1186 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1187 conf.env.Replace(F77=detect_fortran)
1188 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1189 conf.env.Replace(F77FLAGS='')
1190 #print "F77:",conf.env['F77']
1191 #print "F77COM:",conf.env['F77COM']
1192 #print "F77FLAGS:",conf.env['F77FLAGS']
1193 fortran_builder = Builder(
1194 action='$F77COM'
1195 , suffix='.o'
1196 , src_suffix='.f'
1197 )
1198 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1199 else:
1200 with_lsode=False;
1201 without_lsode_reason="FORTRAN-77 required but not found"
1202
1203 #else:
1204 # print "FORTRAN not required"
1205
1206 # F2C
1207
1208 if need_fortran:
1209 if platform.system()=="Windows":
1210 conf.env.Append(LIBPATH='c:\mingw\lib')
1211
1212 # scrollkeeper
1213
1214 if with_scrollkeeper:
1215 if not conf.CheckScrollkeeperConfig():
1216 with_scrollkeeper=False
1217 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
1218
1219 # TODO: -D_HPUX_SOURCE is needed
1220
1221 # TODO: check size of void*
1222
1223 # TODO: detect if dynamic libraries are possible or not
1224
1225 if platform.system()=="Windows" and env.has_key('MSVS'):
1226 _found_windows_h = conf.CheckHeader('Windows.h')
1227
1228 if not _found_windows_h:
1229 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1230 Exit(1)
1231
1232 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1233 with_python = 0;
1234 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1235
1236 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1237
1238 conf.Finish()
1239
1240 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
1241 env.Append(PYTHON_LIB=[python_lib])
1242 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
1243
1244 #---------------------------------------
1245 # SUBSTITUTION DICTIONARY for .in files
1246
1247 release = env.get('RELEASE')
1248 if release=="0.":
1249 release="0"
1250
1251 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1252
1253 subst_dict = {
1254 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1255 , '@GLADE_FILE@':'ascend.glade'
1256 , '@HELP_ROOT@':''
1257 , '@ICON_EXTENSION@':icon_extension
1258 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1259 , '@INSTALL_BIN@':env['INSTALL_BIN']
1260 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1261 , '@INSTALL_LIB@':env['INSTALL_LIB']
1262 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1263 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1264 , '@VERSION@':version
1265 , '@RELEASE@':release
1266 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1267 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1268 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1269 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1270 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1271 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1272 , '@PYTHON@' : python_exe
1273 , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1274 , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1275 , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_LIBPATH"))
1276 }
1277
1278 if env.get('WITH_LOCAL_HELP'):
1279 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1280 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1281
1282 # bool options...
1283 for k,v in {
1284 'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1285 ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1286 ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1287 }.iteritems():
1288 if env.get(k):
1289 # subst_dict['@'+v+'@']='1'
1290 subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1291
1292 if with_ida:
1293 subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1294
1295 if with_conopt:
1296 subst_dict["/\\* #define ASC_WITH_CONOPT @ASC_WITH_CONOPT@ \\*/"]='#define ASC_WITH_CONOPT '
1297
1298 if with_lsode:
1299 subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1300
1301 if with_python:
1302 subst_dict['@ASCXX_USE_PYTHON@']="1"
1303 env['WITH_PYTHON']=1;
1304
1305 if env.has_key('HAVE_GCCVISIBILITY'):
1306 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1307
1308 env.Append(SUBST_DICT=subst_dict)
1309
1310 #------------------------------------------------------
1311 # RECIPE: Fix up long command-line bug on Win2k
1312
1313 # Currently this is broken, awaiting help from the SCons users list
1314
1315 if 0 and env['PLATFORM'] == 'win32':
1316 import win32file
1317 import win32event
1318 import win32process
1319 import win32security
1320 import string
1321
1322 def my_spawn(sh, escape, cmd, args, spawnenv):
1323 for var in spawnenv:
1324 spawnenv[var] = spawnenv[var].encode('ascii', 'replace')
1325
1326 sAttrs = win32security.SECURITY_ATTRIBUTES()
1327 StartupInfo = win32process.STARTUPINFO()
1328 newargs = string.join(map(escape, args[1:]), ' ')
1329 cmdline = cmd + " " + newargs
1330
1331 # check for any special operating system commands
1332 if cmd == 'del':
1333 for arg in args[1:]:
1334 win32file.DeleteFile(arg)
1335 exit_code = 0
1336 else:
1337 # otherwise execute the command.
1338 hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo)
1339 win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
1340 exit_code = win32process.GetExitCodeProcess(hProcess)
1341 win32file.CloseHandle(hProcess);
1342 win32file.CloseHandle(hThread);
1343 return exit_code
1344
1345 env['SPAWN'] = my_spawn
1346
1347 #------------------------------------------------------
1348 # RECIPE: SWIG scanner
1349
1350 import SCons.Script
1351
1352 SWIGScanner = SCons.Scanner.ClassicCPP(
1353 "SWIGScan"
1354 , ".i"
1355 , "CPPPATH"
1356 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1357 )
1358
1359 env.Append(SCANNERS=[SWIGScanner])
1360
1361 #------------------------------------------------------
1362 # RECIPE: 'SubstInFile', used in pygtk SConscript
1363
1364 import re
1365 from SCons.Script import * # the usual scons stuff you get in a SConscript
1366
1367 def TOOL_SUBST(env):
1368 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1369 from the source to the target.
1370 The values of SUBST_DICT first have any construction variables expanded
1371 (its keys are not expanded).
1372 If a value of SUBST_DICT is a python callable function, it is called and
1373 the result is expanded as the value.
1374 If there's more than one source and more than one target, each target gets
1375 substituted from the corresponding source.
1376 """
1377 env.Append(TOOLS = 'SUBST')
1378 def do_subst_in_file(targetfile, sourcefile, dict):
1379 """Replace all instances of the keys of dict with their values.
1380 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1381 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1382 """
1383 try:
1384 f = open(sourcefile, 'rb')
1385 contents = f.read()
1386 f.close()
1387 except:
1388 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1389 for (k,v) in dict.items():
1390 contents = re.sub(k, v, contents)
1391 try:
1392 f = open(targetfile, 'wb')
1393 f.write(contents)
1394 f.close()
1395 except:
1396 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1397 return 0 # success
1398
1399 def subst_in_file(target, source, env):
1400 if not env.has_key('SUBST_DICT'):
1401 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1402 d = dict(env['SUBST_DICT']) # copy it
1403 for (k,v) in d.items():
1404 if callable(v):
1405 d[k] = env.subst(v())
1406 elif SCons.Util.is_String(v):
1407 d[k]=env.subst(v)
1408 else:
1409 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1410 for (t,s) in zip(target, source):
1411 return do_subst_in_file(str(t), str(s), d)
1412
1413 def subst_in_file_string(target, source, env):
1414 """This is what gets printed on the console."""
1415 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1416 for (t,s) in zip(target, source)])
1417
1418 def subst_emitter(target, source, env):
1419 """Add dependency from substituted SUBST_DICT to target.
1420 Returns original target, source tuple unchanged.
1421 """
1422 d = env['SUBST_DICT'].copy() # copy it
1423 for (k,v) in d.items():
1424 if callable(v):
1425 d[k] = env.subst(v())
1426 elif SCons.Util.is_String(v):
1427 d[k]=env.subst(v)
1428 Depends(target, SCons.Node.Python.Value(d))
1429 return target, source
1430
1431 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1432 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1433
1434 TOOL_SUBST(env)
1435
1436 #------------------------------------------------------
1437 # Recipe for 'CHMOD' ACTION
1438
1439 import SCons
1440 from SCons.Script.SConscript import SConsEnvironment
1441 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1442 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1443
1444 def InstallPerm(env, dest, files, perm):
1445 obj = env.Install(dest, files)
1446 for i in obj:
1447 env.AddPostAction(i, env.Chmod(str(i), perm))
1448
1449 SConsEnvironment.InstallPerm = InstallPerm
1450
1451 # define wrappers
1452 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1453 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1454 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1455
1456 #------------------------------------------------------
1457 # BUILD...
1458
1459 # so that #include <modulename/headername.h> works across all modules...
1460 env.AppendUnique(CPPPATH=['#base/generic'])
1461
1462 if env['DEBUG']:
1463 env.Append(CCFLAGS=['-g'])
1464
1465 if env['GCOV']:
1466 env.Append(
1467 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1468 , LIBS=['gcov']
1469 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1470 )
1471
1472 if with_ida:
1473 env.Append(WITH_IDA=1)
1474
1475 if with_conopt:
1476 env.Append(WITH_CONOPT=1)
1477
1478 #-------------
1479 # TCL/TK GUI
1480
1481 if with_tcltk:
1482 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1483 else:
1484 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1485
1486 #-------------
1487 # PYTHON INTERFACE
1488
1489 if with_python:
1490 env.SConscript(['pygtk/SConscript'],'env')
1491 else:
1492 print "Skipping... Python GUI isn't being built:",without_python_reason
1493
1494 #------------
1495 # BASE/GENERIC SUBDIRECTORIES
1496
1497 libascend_env = env.Copy()
1498
1499 dirs = ['general','utilities','compiler','solver','packages']
1500
1501 srcs = []
1502 for d in dirs:
1503 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1504 srcs += heresrcs
1505
1506 #-------------
1507 # IMPORTED CODE: LSODE, BLAS, etc
1508
1509 if with_lsode:
1510 srcs += env.SConscript(['lsod/SConscript'],'env')
1511 srcs += env.SConscript(['linpack/SConscript'],'env')
1512 else:
1513 print "Skipping... LSODE won't be built:", without_lsode_reason
1514
1515 if with_local_blas:
1516 srcs += env.SConscript(['blas/SConscript'],'env')
1517 else:
1518 print "Skipping... BLAS won't be built:", without_local_blas_reason
1519
1520 if not with_ida:
1521 print "Skipping... IDA won't be built:", without_ida_reason
1522
1523 #-------------
1524 # LIBASCEND -- all base/generic functionality
1525
1526 libascend = libascend_env.SharedLibrary('ascend',srcs)
1527
1528 env.Alias('libascend',libascend)
1529
1530 #-------------
1531 # UNIT TESTS (C CODE)
1532
1533 if with_cunit:
1534 testdirs = ['general','solver','utilities']
1535 testsrcs = []
1536 for testdir in testdirs:
1537 path = 'base/generic/'+testdir+'/test/'
1538 env.SConscript([path+'SConscript'],'env')
1539 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1540
1541 #print "TESTSRCS =",testsrcs
1542
1543 env.SConscript(['test/SConscript'],'env')
1544 env.SConscript(['base/generic/test/SConscript'],'env')
1545
1546 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1547
1548 else:
1549 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1550
1551 #-------------
1552 # EXTERNAL FUNCTIONS
1553
1554 env['extfns']=[]
1555 modeldirs = env.SConscript(['models/SConscript'],'env')
1556
1557 if not with_extfns:
1558 print "Skipping... External modules aren't being built:",without_extfns_reason
1559
1560 env.Alias('extfns',env['extfns'])
1561
1562 #------------------------------------------------------
1563 # CREATE ASCEND-CONFIG scriptlet
1564
1565 ascendconfig = env.SubstInFile('ascend-config.in')
1566
1567 #------------------------------------------------------
1568 # INSTALLATION
1569
1570 if env.get('CAN_INSTALL'):
1571
1572 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
1573 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1574 install_dirs += modeldirs
1575
1576 # TODO: add install options
1577 env.Alias('install',install_dirs)
1578
1579 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1580
1581 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1582
1583 #------------------------------------------------------
1584 # WINDOWS INSTALLER
1585 # For the windows installer, please see pygtk/SConscript
1586
1587 if with_installer:
1588 pass
1589 else:
1590 print "Skipping... Windows installer isn't being built:",without_installer_reason
1591
1592 #------------------------------------------------------
1593 # PROJECT FILE for MSVC
1594
1595 env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1596
1597 #------------------------------------------------------
1598 # CREATE the SPEC file for generation of RPM packages
1599
1600 if platform.system()=="Linux":
1601 env.SubstInFile('ascend.spec.in')
1602
1603 #------------------------------------------------------
1604 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
1605
1606 if with_scrollkeeper:
1607 env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
1608 env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
1609
1610 #------------------------------------------------------
1611 # DISTRIBUTION TAR FILE
1612
1613 env['DISTTAR_FORMAT']='bz2'
1614 env.Append(
1615 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1616 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1617 )
1618
1619 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1620 , [env.Dir('#')]
1621 )
1622
1623 env.Depends(tar,'ascend.spec')
1624
1625 #------------------------------------------------------
1626 # USER'S MANUAL
1627
1628 env.SConscript('doc/SConscript',['env'])
1629
1630 #------------------------------------------------------
1631 # LIBASCEND DOXYGEN DOCUMENTATION
1632
1633 env.SConscript('base/doc/SConscript',['env'])
1634
1635 #------------------------------------------------------
1636 # RPM BUILD
1637
1638 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
1639 # (check * for the version number used to create the tarball)
1640
1641 #------------------------------------------------------
1642 # DEFAULT TARGETS
1643
1644 default_targets =['libascend']
1645 if with_tcltk:
1646 default_targets.append('tcltk')
1647 if with_python:
1648 default_targets.append('pygtk')
1649 if with_installer:
1650 default_targets.append('installer')
1651 if with_extfns:
1652 default_targets.append('extfns')
1653
1654 env.Default(default_targets)
1655
1656 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1657
1658 # vim: set syntax=python:
1659

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