/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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