/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 922 - (show annotations) (download)
Wed Nov 8 05:25:37 2006 UTC (13 years ago) by johnpye
File size: 42228 byte(s)
Expanded the 'ascend-config' mechanism to be supported in Windows installations (On Windows, ascend-config is installed in $INSTDIR and uses the registry instead of hard-coded file paths).

1 import os, commands, platform, distutils.sysconfig, os.path, re
2
3 version = "0.9.5.103"
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_nvecserial','sundials_ida','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"
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']
482 #TODO removed 'doxygen' for SCons 0.96.93
483 envadditional['IS_MINGW']=True
484 else:
485 envenv = {
486 'PATH':os.environ['PATH']
487 ,'INCLUDE':os.environ['INCLUDE']
488 ,'LIB':os.environ['LIB']
489 ,'MSVS_IGNORE_IDE_PATHS':1
490 }
491 tools=['default','lex','yacc','fortran','swig','disttar','nsis']
492 #TODO removed 'doxygen' for SCons 0.96.93
493 envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
494 else:
495 if os.environ.get('TARGET')=='mingw':
496 envenv = os.environ
497 tools=['crossmingw','lex','yacc','disttar','nsis','doxygen']
498 envadditional['CPPPATH']=['/usr/local/lib/gcc/i386-mingw32/3.4.5/include','/usr/include']
499 else:
500 envenv = os.environ
501 tools=['default','lex','yacc','fortran','swig','disttar','nsis']
502 #TODO removed 'doxygen' for SCons 0.96.93
503
504
505 env = Environment(
506 ENV=envenv
507 , toolpath=['scons']
508 , tools=tools
509 , **envadditional
510 )
511
512 opts.Update(env)
513 opts.Save('options.cache',env)
514
515 Help(opts.GenerateHelpText(env))
516
517 with_tcltk = env.get('WITH_TCLTK')
518 without_tcltk_reason = "disabled by options/config.py"
519
520 with_python = env.get('WITH_PYTHON')
521 without_python_reason = "disabled by options/config.py"
522
523 with_cunit = env.get('WITH_CUNIT')
524 without_cunit_reason = "not requested"
525
526 with_extfns = env.get('WITH_EXTFNS')
527 without_extfn_reason = "disabled by options/config.py"
528
529 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
530 without_scrollkeeper_reason = "disabled by options/config.py"
531
532 if platform.system()=="Windows":
533 with_installer=1
534 else:
535 with_installer=0
536 without_installer_reason = "only possible under Windows"
537
538 if 'LSOD' in env['WITH_SOLVERS']:
539 with_lsode=True
540 else:
541 with_lsode=False
542 without_lsode_reason = "not requested (WITH_SOLVERS)"
543
544 if 'IDA' in env['WITH_SOLVERS']:
545 with_ida=True
546 else:
547 with_ida=False
548 without_ida_reason = "not requested (WITH_SOLVERS)"
549
550
551 if 'CONOPT' in env['WITH_SOLVERS']:
552 with_conopt=True
553 else:
554 with_conopt=False
555 without_conopt_reason = "not requested (WITH_SOLVERS)"
556
557
558 #print "SOLVERS:",env['WITH_SOLVERS']
559 #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
560 #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
561
562 can_install = True
563 if platform.system()=='Windows':
564 can_install = False
565
566 env['CAN_INSTALL']=can_install
567
568 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
569
570 print "TCL_CPPPATH =",env['TCL_CPPPATH']
571 print "TCL_LIBPATH =",env['TCL_LIBPATH']
572 print "TCL_LIB =",env['TCL_LIB']
573 print "CC =",env['CC']
574 print "CXX =",env['CXX']
575 print "FORTRAN=",env.get('FORTRAN')
576
577 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
578 #------------------------------------------------------
579 # SPECIAL CONFIGURATION TESTS
580
581 need_fortran = False
582
583 #----------------
584 # SWIG
585
586 import os,re
587
588 def get_swig_version(env):
589 cmd = env['SWIG']+' -version'
590 (cin,coutcerr) = os.popen4(cmd)
591 output = coutcerr.read()
592
593 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
594 expr = re.compile(restr,re.M);
595 m = expr.search(output);
596 if not m:
597 return None
598 maj = int(m.group('maj'))
599 min = int(m.group('min'))
600 pat = int(m.group('pat'))
601
602 return (maj,min,pat)
603
604
605 def CheckSwigVersion(context):
606
607 try:
608 context.Message("Checking version of SWIG... ")
609 maj,min,pat = get_swig_version(context.env)
610 except:
611 context.Result("Failed to detect version, or failed to run SWIG")
612 return 0;
613
614 context.env['SWIGVERSION']=tuple([maj,min,pat])
615
616 if maj == 1 and (
617 min > 3
618 or (min == 3 and pat >= 24)
619 ):
620 context.Result("ok, %d.%d.%d" % (maj,min,pat))
621 return 1;
622 else:
623 context.Result("too old, %d.%d.%d" % (maj,min,pat))
624 return 0;
625
626 #----------------
627 # Scrollkeeper (Linux documentation system)
628
629 def get_scrollkeeper_omfdir(env):
630 cmd = 'scrollkeeper-config --omfdir'
631 (cin,coutcerr) = os.popen4(cmd)
632 output = coutcerr.read()
633 return output.strip()
634
635 def CheckScrollkeeperConfig(context):
636 try:
637 context.Message("Checking for scrollkeeper...")
638 dir=get_scrollkeeper_omfdir(context.env)
639 except:
640 context.Result("Failed to run 'scrollkeeper-config'")
641 return 0
642 context.env['OMFDIR']=dir
643 context.Result("OK, %s" % dir)
644 return 1
645
646 #----------------
647 # General purpose library-and-header test
648
649 class KeepContext:
650 def __init__(self,context,varprefix,static=False):
651 self.keep = {}
652 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
653 #print "Keeping env %s = %s" % (k,context.env.get(k))
654 self.keep[k]=context.env.get(k)
655
656 if context.env.has_key(varprefix+'_CPPPATH'):
657 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
658 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
659
660 if static:
661 staticlib=env[varprefix+'_LIB']
662 #print "STATIC LIB = ",staticlib
663 context.env.Append(
664 LINKFLAGS=[staticlib]
665 )
666 else:
667 if context.env.has_key(varprefix+'_LIBPATH'):
668 context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
669 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
670
671 if context.env.has_key(varprefix+'_LIB'):
672 context.env.Append(LIBS=[env[varprefix+'_LIB']])
673 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
674
675 def restore(self,context):
676 #print "RESTORING CONTEXT"
677 #print self.keep
678 #print "..."
679 for k in self.keep:
680 if self.keep[k]==None:
681 if context.env.has_key(k):
682 #print "Clearing "+str(k)
683 del context.env[k];
684 else:
685 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
686 context.env[k]=self.keep[k];
687
688 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
689 """This method will check for variables LIBNAME_LIBPATH
690 and LIBNAME_CPPPATH and try to compile and link the
691 file with the provided text, linking with the
692 library libname."""
693
694 if static:
695 context.Message( 'Checking for static '+libname+'... ' )
696 else:
697 context.Message( 'Checking for '+libname+'... ' )
698
699 if varprefix==None:
700 varprefix = libname.upper()
701
702 #print "LIBS is currently:",context.env.get('LIBS')
703 keep = KeepContext(context,varprefix,static)
704
705 if not context.env.has_key(varprefix+'_LIB'):
706 # if varprefix_LIB were in env, KeepContext would
707 # have appended it already
708 context.env.Append(LIBS=[libname])
709
710 is_ok = context.TryLink(text,ext)
711
712 #print "Link success? ",(is_ok != 0)
713
714 keep.restore(context)
715
716 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
717 # print "Restored LIBS="+str(context.env['LIBS'])
718 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
719
720 context.Result(is_ok)
721 return is_ok
722
723 #----------------
724 # GCC
725
726 gcc_test_text = """
727 #ifndef __GNUC__
728 # error "Not using GCC"
729 #endif
730
731 int main(void){
732 return __GNUC__;
733 }
734 """
735
736 def CheckGcc(context):
737 context.Message("Checking for GCC... ")
738 is_ok = context.TryCompile(gcc_test_text,".c")
739 context.Result(is_ok)
740 return is_ok
741
742 #----------------
743 # GCC VISIBILITY feature
744
745 gccvisibility_test_text = """
746 #if __GNUC__ < 4
747 # error "Require GCC version 4 or newer"
748 #endif
749
750 __attribute__ ((visibility("default"))) int x;
751
752 int main(void){
753 extern int x;
754 x = 4;
755 }
756 """
757
758 def CheckGccVisibility(context):
759 context.Message("Checking for GCC 'visibility' capability... ")
760 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
761 context.Result("disabled")
762 return 0
763 is_ok = context.TryCompile(gccvisibility_test_text,".c")
764 context.Result(is_ok)
765 return is_ok
766
767 #----------------
768 # YACC
769
770 yacc_test_text = """
771 %{
772 #include <stdio.h>
773
774 /* MSVC++ needs this before it can swallow Bison output */
775 #ifdef _MSC_VER
776 # define __STDC__
777 #endif
778 %}
779 %token MSG
780 %start ROOT
781 %%
782 ROOT:
783 MSG { printf("HELLO"); }
784 ;
785 %%
786 """
787
788 def CheckYacc(context):
789 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
790 is_ok = context.TryCompile(yacc_test_text,".y")
791 context.Result(is_ok)
792 return is_ok
793
794 #----------------
795 # CUnit test
796
797 cunit_test_text = """
798 #include <CUnit/CUnit.h>
799 int maxi(int i1, int i2){
800 return (i1 > i2) ? i1 : i2;
801 }
802
803 void test_maxi(void){
804 CU_ASSERT(maxi(0,2) == 2);
805 CU_ASSERT(maxi(0,-2) == 0);
806 CU_ASSERT(maxi(2,2) == 2);
807
808 }
809 int main(void){
810 /* CU_initialize_registry() */
811 return 0;
812 }
813 """
814
815 def CheckCUnit(context):
816 return CheckExtLib(context,'cunit',cunit_test_text)
817
818 #----------------
819 # MATH test
820
821 math_test_text = """
822 #ifndef _ALL_SOURCE
823 # define _ALL_SOURCE
824 #endif
825 #ifndef _XOPEN_SOURCE
826 # define _XOPEN_SOURCE
827 #endif
828 #ifndef _XOPEN_SOURCE_EXTENDED
829 # define _XOPEN_SOURCE_EXTENDED 1
830 #endif
831 #include <math.h>
832 int main(void){
833 double x = 1.0; double y = 1.0; int i = 1;
834 acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
835 j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
836 y0(x); y1(x); yn(i,x);
837 #ifdef _THREAD_SAFE
838 gamma_r(x,&i);
839 lgamma_r(x,&i);
840 #else
841 gamma(x);
842 lgamma(x);
843 #endif
844 hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
845 return 0;
846 }
847 """
848
849 def CheckMath(context):
850 context.Message('Checking for IEEE math library... ')
851 libsave=context.env.get('LIBS');
852 context.env.AppendUnique(LIBS=['m'])
853 is_ok=context.TryLink(math_test_text,".c")
854 context.Result(is_ok)
855 if not is_ok:
856 context.env['LIBS']=libsave
857 return is_ok
858
859 #----------------
860 # IDA test
861
862 sundials_version_major_required = 2
863 sundials_version_minor_min = 2
864 sundials_version_minor_max = 3
865
866 sundials_version_text = """
867 #include <sundials/sundials_config.h>
868 #include <stdio.h>
869 int main(){
870 printf("%s",SUNDIALS_PACKAGE_VERSION);
871 return 0;
872 }
873 """
874
875 ida_test_text = """
876 # include <ida/ida.h>
877 # include <nvector/nvector_serial.h>
878 # include <ida/ida_spgmr.h>
879 int main(){
880 void *ida_mem;
881 ida_mem = IDACreate();
882 return 0;
883 }
884 """
885
886 def CheckIDA(context):
887 context.Message( 'Checking for IDA (SUNDIALS)... ' )
888
889 keep = KeepContext(context,"IDA")
890
891 is_ok = context.TryLink(ida_test_text,".c")
892 context.Result(is_ok)
893
894 keep.restore(context)
895
896 return is_ok
897
898 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
899 # so detect the version and act accordingly.
900 def CheckIDAVersion(context):
901 keep = KeepContext(context,'IDA')
902 context.Message("Checking SUNDIALS version... ")
903 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
904 keep.restore(context)
905 if not is_ok:
906 context.Result("failed to run check")
907 return 0
908
909 major,minor,patch = tuple([int(i) for i in output.split(".")])
910 context.env['SUNDIALS_VERSION_MAJOR'] = major
911 context.env['SUNDIALS_VERSION_MINOR'] = minor
912 if major != sundials_version_major_required \
913 or minor < sundials_version_minor_min \
914 or minor > sundials_version_minor_max:
915 context.Result(output+" (bad version)")
916 # bad version
917 return 0
918
919 # good version
920 context.Result(output+", good")
921 return 1
922
923 #----------------
924 # CONOPT test
925
926 conopt_test_text = """
927 #if !defined(_WIN32)
928 # define FNAME_LCASE_DECOR
929 #endif
930
931 #include <conopt.h>
932 #include <stdlib.h>
933 int main(){
934 int s, *v, e;
935 s = COIDEF_Size();
936 v = (int *)malloc(s*sizeof(int));
937 e = COIDEF_Ini(v);
938 return e;
939 }
940 """
941
942 def CheckCONOPT(context):
943 context.Message( 'Checking for CONOPT... ' )
944
945 keep = KeepContext(context,"CONOPT")
946
947 is_ok = context.TryLink(conopt_test_text,".c")
948 context.Result(is_ok)
949
950 keep.restore(context)
951
952 return is_ok
953
954 #----------------
955 # Tcl test
956
957 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
958 tcltk_minor_newest_acceptable = 4
959 tcltk_major_required = 8
960
961 tcl_check_text = r"""
962 #include <tcl.h>
963 #include <stdio.h>
964 int main(void){
965 printf("%s",TCL_PATCH_LEVEL);
966 return 0;
967 }
968 """
969
970 def CheckTcl(context):
971 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
972
973 def CheckTclVersion(context):
974 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
975 context.Message("Checking Tcl version... ")
976 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
977 keep.restore(context)
978 if not is_ok:
979 context.Result("failed to run check")
980 return 0
981
982 major,minor,patch = tuple([int(i) for i in output.split(".")])
983 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
984 context.Result(output+" (bad version)")
985 # bad version
986 return 0
987
988 # good version
989 context.Result(output+", good")
990 return 1
991
992 #----------------
993 # Tk test
994
995 tk_check_text = r"""
996 #include <tk.h>
997 #include <stdio.h>
998 int main(void){
999 printf("%s",TK_PATCH_LEVEL);
1000 return 0;
1001 }
1002 """
1003 def CheckTk(context):
1004 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1005
1006
1007 def CheckTkVersion(context):
1008 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1009 context.Message("Checking Tk version... ")
1010 #print "LINKFLAGS =",context.env['LINKFLAGS']
1011 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1012 keep.restore(context)
1013 if not is_ok:
1014 context.Result("failed to run check")
1015 return 0
1016
1017 major,minor,patch = tuple([int(i) for i in output.split(".")])
1018 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1019 # bad version
1020 context.Result(output+" (bad version)")
1021 return 0
1022
1023 # good version
1024 context.Result(output+" (good)")
1025 return 1
1026
1027 #----------------
1028 # Tktable test
1029
1030 tktable_check_text = r"""
1031 #include <tkTable.h>
1032 #include <stdio.h>
1033 int main(void){
1034 Table mytable;
1035 return 0;
1036 }
1037 """
1038
1039 def CheckTkTable(context):
1040 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1041
1042 #---------------
1043 # X11 test
1044
1045 x11_check_text = r"""
1046 #include <X11/Xlib.h>
1047 #include <X11/IntrinsicP.h>
1048 #include <X11/Intrinsic.h>
1049 #include <X11/ObjectP.h>
1050 #include <X11/Object.h>
1051 int main(void){
1052 Object mything;
1053 return 0;
1054 }
1055 """
1056
1057 def CheckX11(context):
1058 return CheckExtLib(context,'X11',x11_check_text)
1059
1060 #----------------
1061 # GCC Version sniffing
1062
1063 # TODO FIXME
1064
1065 gcc_version4 = False
1066
1067 #------------------------------------------------------
1068 # CONFIGURATION
1069
1070 conf = Configure(env
1071 , custom_tests = {
1072 'CheckMath' : CheckMath
1073 , 'CheckSwigVersion' : CheckSwigVersion
1074 , 'CheckCUnit' : CheckCUnit
1075 , 'CheckTcl' : CheckTcl
1076 , 'CheckTclVersion' : CheckTclVersion
1077 , 'CheckTk' : CheckTk
1078 , 'CheckTkVersion' : CheckTkVersion
1079 , 'CheckGcc' : CheckGcc
1080 , 'CheckGccVisibility' : CheckGccVisibility
1081 , 'CheckYacc' : CheckYacc
1082 , 'CheckTkTable' : CheckTkTable
1083 , 'CheckX11' : CheckX11
1084 , 'CheckIDA' : CheckIDA
1085 , 'CheckIDAVersion' : CheckIDAVersion
1086 , 'CheckCONOPT' : CheckCONOPT
1087 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
1088 # , 'CheckIsNan' : CheckIsNan
1089 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
1090 }
1091 # , config_h = "config.h"
1092 )
1093
1094 # stdio -- just to check that compiler is behaving
1095
1096 if not conf.CheckHeader('stdio.h'):
1097 print "CPPPATH =",env.get('CPPPATH')
1098 print "Did not find 'stdio.h'! Check your compiler configuration."
1099 Exit(1)
1100
1101 # Math library
1102
1103 if need_libm:
1104 if not conf.CheckMath():
1105 print 'Did not find math library, exiting!'
1106 Exit(1)
1107 #pass
1108
1109 # Where is 'isnan'?
1110
1111 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1112 print "Didn't find isnan"
1113 # Exit(1)
1114
1115 # GCC visibility
1116
1117 if conf.CheckGcc():
1118 conf.env['HAVE_GCC']=True;
1119 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
1120 conf.env['HAVE_GCCVISIBILITY']=True;
1121 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1122 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1123 conf.env.Append(CCFLAGS=['-Wall'])
1124
1125 # YACC
1126
1127 if not conf.CheckYacc():
1128 print "YACC NOT FOUND OR NOT WORKING"
1129 else:
1130 conf.env['HAVE_YACC']=True
1131
1132 conf.env['HAVE_LEX']=True
1133
1134 # Tcl/Tk
1135
1136 if with_tcltk:
1137 if conf.CheckTcl():
1138 if conf.CheckTclVersion():
1139 if conf.CheckTk():
1140 if with_tcltk and conf.CheckTkVersion():
1141 if env['STATIC_TCLTK']:
1142 if conf.CheckTkTable():
1143 pass
1144 else:
1145 without_tcltk_reason = "TkTable not found"
1146 with_tcltk = False
1147 else:
1148 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1149 with_tcltk = False
1150 else:
1151 without_tcltk_reason = "Tk not found."
1152 with_tcltk = False
1153 else:
1154 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1155 with_tcltk = False
1156
1157 else:
1158 without_tcltk_reason = "Tcl not found."
1159 with_tcltk = False
1160
1161 if env['STATIC_TCLTK']:
1162 conf.CheckX11()
1163
1164 # Python... obviously we're already running python, so we just need to
1165 # check that we can link to the python library OK:
1166
1167 if platform.system()=="Windows":
1168 python_lib='python24'
1169 else:
1170 python_lib='python2.4'
1171
1172 # SWIG version
1173
1174 if not conf.CheckSwigVersion():
1175 without_python_reason = 'SWIG >= 1.3.24 is required'
1176 with_python = False
1177
1178 # CUnit
1179
1180 if with_cunit:
1181 if not conf.CheckCUnit():
1182 without_cunit_reason = 'CUnit not found'
1183 with_cunit = False
1184 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1185
1186 # IDA
1187
1188 if not with_ida:
1189 without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1190 elif not conf.CheckIDA():
1191 with_ida = False
1192 without_ida_reason = "IDA not found"
1193 elif not conf.CheckIDAVersion():
1194 with_ida = False
1195 without_ida_reason = "Unsupported (or undetected) SUNDIALS version"
1196
1197 # CONOPT
1198
1199 if not with_conopt:
1200 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1201 elif not conf.CheckCONOPT():
1202 with_conopt = False
1203 without_conpt_reason = "CONOPT not found"
1204
1205 # BLAS
1206
1207 need_blas=False
1208
1209 if with_lsode:
1210 need_fortran = True
1211 need_blas=True
1212
1213 if need_blas:
1214 if conf.CheckLib('blas'):
1215 with_local_blas = False
1216 without_local_blas_reason = "Found BLAS installed on system"
1217 else:
1218 with_local_blas = True
1219 need_fortran = True
1220 else:
1221 with_local_blas= False;
1222 without_local_blas_reason = "BLAS not required"
1223
1224 # FORTRAN
1225
1226 if need_fortran:
1227 conf.env.Tool('fortran')
1228 detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1229 if detect_fortran:
1230 # For some reason, g77 doesn't get detected properly on MinGW
1231 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1232 conf.env.Replace(F77=detect_fortran)
1233 conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1234 conf.env.Replace(F77FLAGS='')
1235 #print "F77:",conf.env['F77']
1236 #print "F77COM:",conf.env['F77COM']
1237 #print "F77FLAGS:",conf.env['F77FLAGS']
1238 fortran_builder = Builder(
1239 action='$F77COM'
1240 , suffix='.o'
1241 , src_suffix='.f'
1242 )
1243 conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1244 else:
1245 with_lsode=False;
1246 without_lsode_reason="FORTRAN-77 required but not found"
1247
1248 #else:
1249 # print "FORTRAN not required"
1250
1251 # F2C
1252
1253 if need_fortran:
1254 if platform.system()=="Windows":
1255 conf.env.Append(LIBPATH='c:\mingw\lib')
1256
1257 # scrollkeeper
1258
1259 if with_scrollkeeper:
1260 if not conf.CheckScrollkeeperConfig():
1261 with_scrollkeeper=False
1262 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
1263
1264 # TODO: -D_HPUX_SOURCE is needed
1265
1266 # TODO: check size of void*
1267
1268 # TODO: detect if dynamic libraries are possible or not
1269
1270 if platform.system()=="Windows" and env.has_key('MSVS'):
1271 _found_windows_h = conf.CheckHeader('Windows.h')
1272
1273 if not _found_windows_h:
1274 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1275 Exit(1)
1276
1277 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1278 with_python = 0;
1279 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1280
1281 conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1282
1283 conf.Finish()
1284
1285 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
1286 env.Append(PYTHON_LIB=[python_lib])
1287 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
1288
1289 #---------------------------------------
1290 # SUBSTITUTION DICTIONARY for .in files
1291
1292 release = env.get('RELEASE')
1293 if release=="0.":
1294 release="0"
1295
1296 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1297
1298 subst_dict = {
1299 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1300 , '@GLADE_FILE@':'ascend.glade'
1301 , '@HELP_ROOT@':''
1302 , '@ICON_EXTENSION@':icon_extension
1303 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1304 , '@INSTALL_BIN@':env['INSTALL_BIN']
1305 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1306 , '@INSTALL_LIB@':env['INSTALL_LIB']
1307 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1308 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1309 , '@VERSION@':version
1310 , '@RELEASE@':release
1311 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1312 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1313 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1314 , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1315 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1316 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1317 , '@PYTHON@' : python_exe
1318 , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1319 , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1320 , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_LIBPATH"))
1321 , '@SOURCE_ROOT@':os.path.abspath(str(env.Dir("#")))
1322 }
1323
1324 if env.get('WITH_LOCAL_HELP'):
1325 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1326 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1327
1328 # bool options...
1329 for k,v in {
1330 'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1331 ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1332 ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1333 }.iteritems():
1334 if env.get(k):
1335 # subst_dict['@'+v+'@']='1'
1336 subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1337
1338 if with_ida:
1339 subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1340
1341 if with_conopt:
1342 subst_dict["/\\* #define ASC_WITH_CONOPT @ASC_WITH_CONOPT@ \\*/"]='#define ASC_WITH_CONOPT '
1343
1344 if with_lsode:
1345 subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1346
1347 if with_python:
1348 subst_dict['@ASCXX_USE_PYTHON@']="1"
1349 env['WITH_PYTHON']=1;
1350
1351 if env.has_key('HAVE_GCCVISIBILITY'):
1352 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1353
1354 env.Append(SUBST_DICT=subst_dict)
1355
1356 #------------------------------------------------------
1357 # RECIPE: Fix up long command-line bug on Win2k
1358
1359 # Currently this is broken, awaiting help from the SCons users list
1360
1361 if 0 and env['PLATFORM'] == 'win32':
1362 import win32file
1363 import win32event
1364 import win32process
1365 import win32security
1366 import string
1367
1368 def my_spawn(sh, escape, cmd, args, spawnenv):
1369 for var in spawnenv:
1370 spawnenv[var] = spawnenv[var].encode('ascii', 'replace')
1371
1372 sAttrs = win32security.SECURITY_ATTRIBUTES()
1373 StartupInfo = win32process.STARTUPINFO()
1374 newargs = string.join(map(escape, args[1:]), ' ')
1375 cmdline = cmd + " " + newargs
1376
1377 # check for any special operating system commands
1378 if cmd == 'del':
1379 for arg in args[1:]:
1380 win32file.DeleteFile(arg)
1381 exit_code = 0
1382 else:
1383 # otherwise execute the command.
1384 hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo)
1385 win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
1386 exit_code = win32process.GetExitCodeProcess(hProcess)
1387 win32file.CloseHandle(hProcess);
1388 win32file.CloseHandle(hThread);
1389 return exit_code
1390
1391 env['SPAWN'] = my_spawn
1392
1393 #------------------------------------------------------
1394 # RECIPE: SWIG scanner
1395
1396 import SCons.Script
1397
1398 SWIGScanner = SCons.Scanner.ClassicCPP(
1399 "SWIGScan"
1400 , ".i"
1401 , "CPPPATH"
1402 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1403 )
1404
1405 env.Append(SCANNERS=[SWIGScanner])
1406
1407 #------------------------------------------------------
1408 # RECIPE: 'SubstInFile', used in pygtk SConscript
1409
1410 import re
1411 from SCons.Script import * # the usual scons stuff you get in a SConscript
1412
1413 def TOOL_SUBST(env):
1414 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1415 from the source to the target.
1416 The values of SUBST_DICT first have any construction variables expanded
1417 (its keys are not expanded).
1418 If a value of SUBST_DICT is a python callable function, it is called and
1419 the result is expanded as the value.
1420 If there's more than one source and more than one target, each target gets
1421 substituted from the corresponding source.
1422 """
1423 env.Append(TOOLS = 'SUBST')
1424 def do_subst_in_file(targetfile, sourcefile, dict):
1425 """Replace all instances of the keys of dict with their values.
1426 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1427 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1428 """
1429 try:
1430 f = open(sourcefile, 'rb')
1431 contents = f.read()
1432 f.close()
1433 except:
1434 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1435 for (k,v) in dict.items():
1436 contents = re.sub(k, v, contents)
1437 try:
1438 f = open(targetfile, 'wb')
1439 f.write(contents)
1440 f.close()
1441 except:
1442 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1443 return 0 # success
1444
1445 def subst_in_file(target, source, env):
1446 if not env.has_key('SUBST_DICT'):
1447 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1448 d = dict(env['SUBST_DICT']) # copy it
1449 for (k,v) in d.items():
1450 if callable(v):
1451 d[k] = env.subst(v())
1452 elif SCons.Util.is_String(v):
1453 d[k]=env.subst(v)
1454 else:
1455 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1456 for (t,s) in zip(target, source):
1457 return do_subst_in_file(str(t), str(s), d)
1458
1459 def subst_in_file_string(target, source, env):
1460 """This is what gets printed on the console."""
1461 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1462 for (t,s) in zip(target, source)])
1463
1464 def subst_emitter(target, source, env):
1465 """Add dependency from substituted SUBST_DICT to target.
1466 Returns original target, source tuple unchanged.
1467 """
1468 d = env['SUBST_DICT'].copy() # copy it
1469 for (k,v) in d.items():
1470 if callable(v):
1471 d[k] = env.subst(v())
1472 elif SCons.Util.is_String(v):
1473 d[k]=env.subst(v)
1474 Depends(target, SCons.Node.Python.Value(d))
1475 return target, source
1476
1477 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1478 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1479
1480 TOOL_SUBST(env)
1481
1482 #------------------------------------------------------
1483 # Recipe for 'CHMOD' ACTION
1484
1485 import SCons
1486 from SCons.Script.SConscript import SConsEnvironment
1487 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1488 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1489
1490 def InstallPerm(env, dest, files, perm):
1491 obj = env.Install(dest, files)
1492 for i in obj:
1493 env.AddPostAction(i, env.Chmod(str(i), perm))
1494
1495 SConsEnvironment.InstallPerm = InstallPerm
1496
1497 # define wrappers
1498 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1499 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1500 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1501
1502 #------------------------------------------------------
1503 # BUILD...
1504
1505 # so that #include <modulename/headername.h> works across all modules...
1506 env.AppendUnique(CPPPATH=['#base/generic'])
1507
1508 if env['DEBUG']:
1509 env.Append(CCFLAGS=['-g'])
1510
1511 if env['GCOV']:
1512 env.Append(
1513 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1514 , LIBS=['gcov']
1515 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1516 )
1517
1518 if with_ida:
1519 env.Append(WITH_IDA=1)
1520
1521 if with_conopt:
1522 env.Append(WITH_CONOPT=1)
1523
1524 #-------------
1525 # TCL/TK GUI
1526
1527 if with_tcltk:
1528 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1529 else:
1530 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1531
1532 #-------------
1533 # PYTHON INTERFACE
1534
1535 if with_python:
1536 env.SConscript(['pygtk/SConscript'],'env')
1537 else:
1538 print "Skipping... Python GUI isn't being built:",without_python_reason
1539
1540 #------------
1541 # BASE/GENERIC SUBDIRECTORIES
1542
1543 libascend_env = env.Copy()
1544
1545 dirs = ['general','utilities','compiler','solver','packages']
1546
1547 srcs = []
1548 for d in dirs:
1549 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1550 srcs += heresrcs
1551
1552 #-------------
1553 # IMPORTED CODE: LSODE, BLAS, etc
1554
1555 if with_lsode:
1556 srcs += env.SConscript(['lsod/SConscript'],'env')
1557 srcs += env.SConscript(['linpack/SConscript'],'env')
1558 else:
1559 print "Skipping... LSODE won't be built:", without_lsode_reason
1560
1561 if with_local_blas:
1562 srcs += env.SConscript(['blas/SConscript'],'env')
1563 else:
1564 print "Skipping... BLAS won't be built:", without_local_blas_reason
1565
1566 if not with_ida:
1567 print "Skipping... IDA won't be built:", without_ida_reason
1568
1569 #-------------
1570 # LIBASCEND -- all base/generic functionality
1571
1572 libascend = libascend_env.SharedLibrary('ascend',srcs)
1573
1574 env.Alias('libascend',libascend)
1575
1576 #-------------
1577 # UNIT TESTS (C CODE)
1578
1579 if with_cunit:
1580 testdirs = ['general','solver','utilities']
1581 testsrcs = []
1582 for testdir in testdirs:
1583 path = 'base/generic/'+testdir+'/test/'
1584 env.SConscript([path+'SConscript'],'env')
1585 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1586
1587 #print "TESTSRCS =",testsrcs
1588
1589 env.SConscript(['test/SConscript'],'env')
1590 env.SConscript(['base/generic/test/SConscript'],'env')
1591
1592 env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1593
1594 else:
1595 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1596
1597 #-------------
1598 # EXTERNAL FUNCTIONS
1599
1600 env['extfns']=[]
1601 modeldirs = env.SConscript(['models/SConscript'],'env')
1602
1603 if not with_extfns:
1604 print "Skipping... External modules aren't being built:",without_extfns_reason
1605
1606 env.Alias('extfns',env['extfns'])
1607
1608 #------------------------------------------------------
1609 # CREATE ASCEND-CONFIG scriptlet
1610
1611 ascendconfig = env.SubstInFile('ascend-config.in')
1612
1613 #------------------------------------------------------
1614 # INSTALLATION
1615
1616 if env.get('CAN_INSTALL'):
1617
1618 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE', 'INSTALL_DOC']
1619 install_dirs = [env.Entry(env['INSTALL_ROOT']+env[d]) for d in dirs]
1620 install_dirs += modeldirs
1621
1622 # TODO: add install options
1623 env.Alias('install',install_dirs)
1624
1625 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1626
1627 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1628
1629 #------------------------------------------------------
1630 # WINDOWS INSTALLER
1631 # For the windows installer, please see pygtk/SConscript
1632
1633 if with_installer:
1634 pass
1635 else:
1636 print "Skipping... Windows installer isn't being built:",without_installer_reason
1637
1638 #------------------------------------------------------
1639 # PROJECT FILE for MSVC
1640
1641 env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1642
1643 #------------------------------------------------------
1644 # CREATE the SPEC file for generation of RPM packages
1645
1646 if platform.system()=="Linux":
1647 env.SubstInFile('ascend.spec.in')
1648
1649 #------------------------------------------------------
1650 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
1651
1652 if with_scrollkeeper:
1653 env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
1654 env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
1655
1656 #------------------------------------------------------
1657 # DISTRIBUTION TAR FILE
1658
1659 env['DISTTAR_FORMAT']='bz2'
1660 env.Append(
1661 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl','.out']
1662 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1663 )
1664
1665 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1666 , [env.Dir('#')]
1667 )
1668
1669 env.Depends(tar,'ascend.spec')
1670
1671 Alias('dist',tar)
1672
1673 #------------------------------------------------------
1674 # USER'S MANUAL
1675
1676 env.SConscript('doc/SConscript',['env'])
1677
1678 #------------------------------------------------------
1679 # LIBASCEND DOXYGEN DOCUMENTATION
1680
1681 env.SConscript('base/doc/SConscript',['env'])
1682
1683 #------------------------------------------------------
1684 # RPM BUILD
1685
1686 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
1687 # (check * for the version number used to create the tarball)
1688
1689 #------------------------------------------------------
1690 # DEFAULT TARGETS
1691
1692 default_targets =['libascend']
1693 if with_tcltk:
1694 default_targets.append('tcltk')
1695 if with_python:
1696 default_targets.append('pygtk')
1697 if with_installer:
1698 default_targets.append('installer')
1699 if with_extfns:
1700 default_targets.append('extfns')
1701
1702 env.Default(default_targets)
1703
1704 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1705
1706 # vim: set syntax=python:
1707

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