/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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