/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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