/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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