/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1420 - (hide annotations) (download)
Wed Apr 25 11:30:47 2007 UTC (15 years, 10 months ago) by jpye
File size: 53592 byte(s)
Some experimenting with crossmingw cross compiling.
Removed shebangs from files that shouldn't have them.
1 johnpye 955 import sys, os, commands, platform, distutils.sysconfig, os.path, re
2 johnpye 385
3 jpye 1417 version = "0.9.5.109"
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 jpye 1420 tools=['crossmingw','nsis']
637     envadditional['CPPPATH']=['/usr/lib/gcc/i586-mingw32msvc/3.4.5/include','/usr/include']
638     envadditional['LIBS']=['gcc']
639 johnpye 832 else:
640     envenv = os.environ
641 johnpye 922 tools=['default','lex','yacc','fortran','swig','disttar','nsis']
642     #TODO removed 'doxygen' for SCons 0.96.93
643 johnpye 800
644 johnpye 832
645 johnpye 800 env = Environment(
646     ENV=envenv
647     , toolpath=['scons']
648     , tools=tools
649     , **envadditional
650     )
651 johnpye 498
652 jpye 1420 #print "PATH =",os.environ['PATH']
653     #print "PROGSUFFIX =",env['PROGSUFFIX']
654     #print "CPPPATH =",env['CPPPATH']
655 jpye 1380
656 johnpye 385 opts.Update(env)
657     opts.Save('options.cache',env)
658    
659     Help(opts.GenerateHelpText(env))
660    
661 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
662 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
663 johnpye 386
664 johnpye 551 with_python = env.get('WITH_PYTHON')
665 johnpye 427 without_python_reason = "disabled by options/config.py"
666 johnpye 387
667 johnpye 593 with_cunit = env.get('WITH_CUNIT')
668 johnpye 427 without_cunit_reason = "not requested"
669 johnpye 400
670 johnpye 761 with_extfns = env.get('WITH_EXTFNS')
671     without_extfn_reason = "disabled by options/config.py"
672    
673 johnpye 816 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
674     without_scrollkeeper_reason = "disabled by options/config.py"
675    
676 johnpye 938 with_dmalloc = env.get('WITH_DMALLOC')
677     without_dmalloc_reason = "disabled by options/config.py"
678    
679 johnpye 1109 with_mfgraph = env.get('WITH_MFGRAPH')
680     without_mfgraph_reason = "disabled by options/config.py"
681    
682 jpye 1326 with_ufsparse = env.get('WITH_UFSPARSE')
683     without_ufsparse_reason = "disabled by options/config.py"
684    
685 johnpye 993 with_mmio = env.get('WITH_MMIO')
686     without_mmio_reason = "disabled by options/config.py"
687    
688 johnpye 1142 with_signals = env.get('WITH_SIGNALS')
689     without_signals_reason = "disabled by options/config.py"
690    
691 johnpye 631 if platform.system()=="Windows":
692     with_installer=1
693     else:
694     with_installer=0
695     without_installer_reason = "only possible under Windows"
696    
697 johnpye 673 if 'LSOD' in env['WITH_SOLVERS']:
698     with_lsode=True
699     else:
700     with_lsode=False
701     without_lsode_reason = "not requested (WITH_SOLVERS)"
702    
703     if 'IDA' in env['WITH_SOLVERS']:
704     with_ida=True
705     else:
706     with_ida=False
707     without_ida_reason = "not requested (WITH_SOLVERS)"
708    
709    
710 johnpye 783 if 'CONOPT' in env['WITH_SOLVERS']:
711     with_conopt=True
712     else:
713     with_conopt=False
714     without_conopt_reason = "not requested (WITH_SOLVERS)"
715    
716    
717 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
718     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
719     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
720 johnpye 393
721 johnpye 463 can_install = True
722     if platform.system()=='Windows':
723     can_install = False
724    
725     env['CAN_INSTALL']=can_install
726 johnpye 721 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
727    
728 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
729     print "TCL_LIBPATH =",env['TCL_LIBPATH']
730     print "TCL_LIB =",env['TCL_LIB']
731 johnpye 562 print "CC =",env['CC']
732     print "CXX =",env['CXX']
733 johnpye 673 print "FORTRAN=",env.get('FORTRAN')
734 johnpye 393
735 johnpye 628 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
736 jpye 1413 print "INSTALL_PREFIX =",env['INSTALL_PREFIX']
737 johnpye 385 #------------------------------------------------------
738 johnpye 398 # SPECIAL CONFIGURATION TESTS
739    
740 johnpye 463 need_fortran = False
741    
742 johnpye 400 #----------------
743     # SWIG
744    
745 johnpye 398 import os,re
746    
747 johnpye 413 def get_swig_version(env):
748 johnpye 403 cmd = env['SWIG']+' -version'
749 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
750 johnpye 403 output = coutcerr.read()
751 johnpye 398
752 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
753     expr = re.compile(restr,re.M);
754 johnpye 398 m = expr.search(output);
755     if not m:
756 johnpye 413 return None
757 johnpye 398 maj = int(m.group('maj'))
758     min = int(m.group('min'))
759     pat = int(m.group('pat'))
760 johnpye 413
761     return (maj,min,pat)
762 johnpye 398
763 johnpye 413
764     def CheckSwigVersion(context):
765    
766     try:
767     context.Message("Checking version of SWIG... ")
768     maj,min,pat = get_swig_version(context.env)
769     except:
770     context.Result("Failed to detect version, or failed to run SWIG")
771     return 0;
772    
773 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
774    
775 johnpye 398 if maj == 1 and (
776 johnpye 400 min > 3
777     or (min == 3 and pat >= 24)
778 johnpye 398 ):
779     context.Result("ok, %d.%d.%d" % (maj,min,pat))
780     return 1;
781 johnpye 401 else:
782     context.Result("too old, %d.%d.%d" % (maj,min,pat))
783     return 0;
784 johnpye 398
785 johnpye 400 #----------------
786 johnpye 816 # Scrollkeeper (Linux documentation system)
787    
788     def get_scrollkeeper_omfdir(env):
789     cmd = 'scrollkeeper-config --omfdir'
790     (cin,coutcerr) = os.popen4(cmd)
791     output = coutcerr.read()
792     return output.strip()
793    
794     def CheckScrollkeeperConfig(context):
795     try:
796     context.Message("Checking for scrollkeeper...")
797     dir=get_scrollkeeper_omfdir(context.env)
798     except:
799     context.Result("Failed to run 'scrollkeeper-config'")
800     return 0
801     context.env['OMFDIR']=dir
802     context.Result("OK, %s" % dir)
803     return 1
804    
805     #----------------
806 johnpye 400 # General purpose library-and-header test
807    
808 johnpye 404 class KeepContext:
809 johnpye 521 def __init__(self,context,varprefix,static=False):
810 johnpye 404 self.keep = {}
811 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
812 johnpye 705 #print "Keeping env %s = %s" % (k,context.env.get(k))
813     self.keep[k]=context.env.get(k)
814 johnpye 404
815     if context.env.has_key(varprefix+'_CPPPATH'):
816 johnpye 743 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
817 johnpye 800 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
818 johnpye 428
819 johnpye 521 if static:
820     staticlib=env[varprefix+'_LIB']
821     #print "STATIC LIB = ",staticlib
822     context.env.Append(
823     LINKFLAGS=[staticlib]
824     )
825     else:
826     if context.env.has_key(varprefix+'_LIBPATH'):
827     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
828 johnpye 800 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
829 johnpye 428
830 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
831     context.env.Append(LIBS=[env[varprefix+'_LIB']])
832 johnpye 705 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
833 johnpye 404
834     def restore(self,context):
835 johnpye 464 #print "RESTORING CONTEXT"
836     #print self.keep
837     #print "..."
838 johnpye 404 for k in self.keep:
839 johnpye 463 if self.keep[k]==None:
840 johnpye 521 if context.env.has_key(k):
841     #print "Clearing "+str(k)
842     del context.env[k];
843 johnpye 463 else:
844 johnpye 705 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
845 johnpye 463 context.env[k]=self.keep[k];
846 johnpye 404
847 johnpye 521 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
848 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
849     and LIBNAME_CPPPATH and try to compile and link the
850     file with the provided text, linking with the
851     library libname."""
852    
853 johnpye 521 if static:
854     context.Message( 'Checking for static '+libname+'... ' )
855     else:
856     context.Message( 'Checking for '+libname+'... ' )
857    
858 johnpye 400 if varprefix==None:
859     varprefix = libname.upper()
860    
861 johnpye 705 #print "LIBS is currently:",context.env.get('LIBS')
862 johnpye 521 keep = KeepContext(context,varprefix,static)
863 johnpye 400
864 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
865 johnpye 463 # if varprefix_LIB were in env, KeepContext would
866     # have appended it already
867 johnpye 705 context.env.Append(LIBS=[libname])
868 johnpye 428
869 johnpye 404 is_ok = context.TryLink(text,ext)
870 johnpye 428
871 johnpye 521 #print "Link success? ",(is_ok != 0)
872 johnpye 400
873 johnpye 405 keep.restore(context)
874 johnpye 400
875 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
876 johnpye 705 # print "Restored LIBS="+str(context.env['LIBS'])
877 johnpye 428 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
878    
879 johnpye 404 context.Result(is_ok)
880     return is_ok
881    
882     #----------------
883 johnpye 502 # GCC
884    
885     gcc_test_text = """
886     #ifndef __GNUC__
887     # error "Not using GCC"
888     #endif
889    
890     int main(void){
891     return __GNUC__;
892     }
893     """
894    
895     def CheckGcc(context):
896     context.Message("Checking for GCC... ")
897     is_ok = context.TryCompile(gcc_test_text,".c")
898     context.Result(is_ok)
899     return is_ok
900    
901     #----------------
902 johnpye 500 # GCC VISIBILITY feature
903    
904     gccvisibility_test_text = """
905     #if __GNUC__ < 4
906     # error "Require GCC version 4 or newer"
907     #endif
908    
909     __attribute__ ((visibility("default"))) int x;
910    
911     int main(void){
912     extern int x;
913     x = 4;
914     }
915     """
916    
917     def CheckGccVisibility(context):
918     context.Message("Checking for GCC 'visibility' capability... ")
919 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
920     context.Result("disabled")
921     return 0
922 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
923     context.Result(is_ok)
924     return is_ok
925 johnpye 502
926 johnpye 500 #----------------
927 johnpye 502 # YACC
928    
929     yacc_test_text = """
930 johnpye 646 %{
931     #include <stdio.h>
932 johnpye 741
933     /* MSVC++ needs this before it can swallow Bison output */
934     #ifdef _MSC_VER
935     # define __STDC__
936     #endif
937 johnpye 646 %}
938     %token MSG
939 johnpye 502 %start ROOT
940 johnpye 646 %%
941     ROOT:
942     MSG { printf("HELLO"); }
943     ;
944     %%
945 johnpye 502 """
946    
947     def CheckYacc(context):
948 johnpye 644 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
949 johnpye 502 is_ok = context.TryCompile(yacc_test_text,".y")
950     context.Result(is_ok)
951     return is_ok
952    
953     #----------------
954 johnpye 1025 # LEX
955    
956     lex_test_text = """
957     %{
958     #include <stdio.h>
959     %}
960     DIGIT [0-9]
961     ID [a-z][a-z0-9]*
962     %%
963     {DIGIT}+ {
964     printf("A digit: %s\\n",yytext);
965     }
966    
967     [ \\t\\n]+ /* ignore */
968    
969     . {
970     printf("Unrecognized guff");
971     }
972     %%
973     main(){
974     yylex();
975     }
976     """
977    
978     def CheckLex(context):
979     context.Message("Checking for Lex ('%s')... " % context.env.get('LEX'))
980     is_ok = context.TryCompile(lex_test_text,".l")
981     context.Result(is_ok)
982     return is_ok
983    
984     #----------------
985 johnpye 404 # CUnit test
986    
987 johnpye 400 cunit_test_text = """
988 johnpye 451 #include <CUnit/CUnit.h>
989 johnpye 400 int maxi(int i1, int i2){
990     return (i1 > i2) ? i1 : i2;
991     }
992    
993     void test_maxi(void){
994     CU_ASSERT(maxi(0,2) == 2);
995     CU_ASSERT(maxi(0,-2) == 0);
996     CU_ASSERT(maxi(2,2) == 2);
997    
998     }
999     int main(void){
1000     /* CU_initialize_registry() */
1001 johnpye 404 return 0;
1002 johnpye 400 }
1003     """
1004    
1005     def CheckCUnit(context):
1006 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
1007 johnpye 400
1008 johnpye 404 #----------------
1009 johnpye 938 # dmalloc test
1010    
1011     dmalloc_test_text = """
1012     #include <stdlib.h>
1013     #include <dmalloc.h>
1014    
1015     int main(void){
1016     char *c;
1017     c = malloc(100*sizeof(char));
1018     free(c);
1019     return 0;
1020     }
1021     """
1022    
1023     def CheckDMalloc(context):
1024     return CheckExtLib(context,'dmalloc',dmalloc_test_text)
1025    
1026     #----------------
1027 johnpye 1109 # mfgraph test
1028    
1029     mfgraph_test_text = """
1030     #include <mfgraph/mfg_draw_graph.h>
1031     int main(void){
1032     using namespace mfg;
1033     DrawGraph g;
1034     return 0;
1035     }
1036     """
1037    
1038     def CheckMFGraph(context):
1039     return CheckExtLib(context,'mfgraph',mfgraph_test_text,ext=".cpp")
1040    
1041     #----------------
1042 jpye 1326 # ufsparse test
1043    
1044     ufsparse_test_text = """
1045     #include <ufsparse/cs.h>
1046     int main(void){
1047     cs *A,*B,*C;
1048     C = cs_multiply(A,B);
1049     return 0;
1050     }
1051     """
1052    
1053     def CheckUFSparse(context):
1054     return CheckExtLib(context
1055     ,libname='cxsparse'
1056     ,varprefix='ufsparse'
1057     ,text=ufsparse_test_text
1058     ,ext=".c"
1059     )
1060    
1061     #----------------
1062 johnpye 673 # MATH test
1063    
1064     math_test_text = """
1065 johnpye 705 #ifndef _ALL_SOURCE
1066     # define _ALL_SOURCE
1067     #endif
1068     #ifndef _XOPEN_SOURCE
1069     # define _XOPEN_SOURCE
1070     #endif
1071     #ifndef _XOPEN_SOURCE_EXTENDED
1072     # define _XOPEN_SOURCE_EXTENDED 1
1073     #endif
1074 johnpye 673 #include <math.h>
1075     int main(void){
1076 johnpye 705 double x = 1.0; double y = 1.0; int i = 1;
1077     acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
1078     j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
1079     y0(x); y1(x); yn(i,x);
1080 jpye 1420 /* this part causes problems with crossmingw... */
1081 johnpye 705 #ifdef _THREAD_SAFE
1082     gamma_r(x,&i);
1083     lgamma_r(x,&i);
1084     #else
1085     gamma(x);
1086     lgamma(x);
1087     #endif
1088     hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
1089 johnpye 673 return 0;
1090     }
1091     """
1092    
1093     def CheckMath(context):
1094 johnpye 832 context.Message('Checking for IEEE math library... ')
1095 johnpye 705 libsave=context.env.get('LIBS');
1096     context.env.AppendUnique(LIBS=['m'])
1097     is_ok=context.TryLink(math_test_text,".c")
1098     context.Result(is_ok)
1099     if not is_ok:
1100     context.env['LIBS']=libsave
1101     return is_ok
1102    
1103 johnpye 673 #----------------
1104 johnpye 957 # libpython test
1105    
1106     libpython_test_text = """
1107     #include <Python.h>
1108     int main(void){
1109     PyObject *p;
1110     p = Py_None;
1111     return 0;
1112     }
1113     """
1114    
1115     def CheckPythonLib(context):
1116     context.Message('Checking for libpython... ')
1117    
1118     if platform.system()=="Windows":
1119     python_lib='python%d%d'
1120     else:
1121     python_lib='python%d.%d'
1122 johnpye 958 python_libs = [python_lib % (sys.version_info[0],sys.version_info[1])]
1123 johnpye 957
1124     python_cpppath = [distutils.sysconfig.get_python_inc()]
1125     cfig = distutils.sysconfig.get_config_vars()
1126    
1127     lastLIBS = context.env.get('LIBS')
1128     lastLIBPATH = context.env.get('LIBPATH')
1129     lastCPPPATH = context.env.get('CPPPATH')
1130 johnpye 959 lastLINKFLAGS = context.env.get('LINKFLAGS')
1131 johnpye 957
1132     python_libpath = []
1133 johnpye 959 python_linkflags = []
1134 johnpye 965 if platform.system()=="Windows":
1135 johnpye 980 python_libpath+=[cfig['prefix']]
1136 johnpye 965 else:
1137     # checked on Linux and SunOS
1138     if cfig['LDLIBRARY']==cfig['LIBRARY']:
1139     sys.stdout.write("(static)")
1140     python_libpath += [cfig['LIBPL']]
1141     python_linkflags += cfig['LIBS'].split(' ')
1142 johnpye 957
1143 johnpye 958 context.env.AppendUnique(LIBS=python_libs)
1144 johnpye 957 context.env.AppendUnique(LIBPATH=python_libpath)
1145     context.env.AppendUnique(CPPPATH=python_cpppath)
1146 johnpye 959 context.env.AppendUnique(LINKFLAGS=python_linkflags)
1147 johnpye 957 result = context.TryLink(libpython_test_text,".c");
1148    
1149 johnpye 958 context.Result(result)
1150 johnpye 957
1151     if(result):
1152 johnpye 958 context.env['PYTHON_LIBPATH']=python_libpath
1153     context.env['PYTHON_LIB']=python_libs
1154     context.env['PYTHON_CPPPATH']=python_cpppath
1155 johnpye 959 context.env['PYTHON_LINKFLAGS']=python_linkflags
1156 johnpye 957
1157     context.env['LIBS'] = lastLIBS
1158     context.env['LIBPATH'] = lastLIBPATH
1159     context.env['CPPPATH'] = lastCPPPATH
1160 johnpye 959 context.env['LINKFLAGS'] = lastLINKFLAGS
1161 johnpye 957
1162     return result
1163    
1164     #----------------
1165 johnpye 673 # IDA test
1166    
1167 johnpye 913 sundials_version_major_required = 2
1168     sundials_version_minor_min = 2
1169     sundials_version_minor_max = 3
1170    
1171     sundials_version_text = """
1172     #include <sundials/sundials_config.h>
1173     #include <stdio.h>
1174     int main(){
1175     printf("%s",SUNDIALS_PACKAGE_VERSION);
1176     return 0;
1177     }
1178     """
1179    
1180 johnpye 673 ida_test_text = """
1181 jpye 1400 #if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR==2
1182     # include <sundials/sundials_config.h>
1183     # include <sundials/sundials_nvector.h>
1184 jpye 1405 # include <nvector_serial.h>
1185 jpye 1400 # include <ida.h>
1186     # include <ida/ida_spgmr.h>
1187     #else
1188     # include <sundials/sundials_config.h>
1189     # include <nvector/nvector_serial.h>
1190 johnpye 907 # include <ida/ida.h>
1191 jpye 1400 #endif
1192 johnpye 673 int main(){
1193     void *ida_mem;
1194     ida_mem = IDACreate();
1195 johnpye 782 return 0;
1196 johnpye 673 }
1197     """
1198    
1199 johnpye 913 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
1200     # so detect the version and act accordingly.
1201 jpye 1400 def CheckSUNDIALS(context):
1202     keep = KeepContext(context,'SUNDIALS')
1203 jpye 1402 context.Message("Checking for SUNDIALS... ")
1204 johnpye 913 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
1205     keep.restore(context)
1206     if not is_ok:
1207 jpye 1402 context.Result(0)
1208 johnpye 913 return 0
1209    
1210     major,minor,patch = tuple([int(i) for i in output.split(".")])
1211     context.env['SUNDIALS_VERSION_MAJOR'] = major
1212     context.env['SUNDIALS_VERSION_MINOR'] = minor
1213     if major != sundials_version_major_required \
1214     or minor < sundials_version_minor_min \
1215     or minor > sundials_version_minor_max:
1216     context.Result(output+" (bad version)")
1217     # bad version
1218     return 0
1219    
1220     # good version
1221 johnpye 1086 context.Result("%d.%d.%d, good" % (major,minor,patch))
1222 jpye 1400
1223 johnpye 913 return 1
1224    
1225 jpye 1400
1226     def CheckIDA(context):
1227 jpye 1402 context.Message( 'Checking for IDA... ' )
1228 jpye 1400
1229 jpye 1404 keep = KeepContext(context,"SUNDIALS")
1230 jpye 1400
1231     major = context.env['SUNDIALS_VERSION_MAJOR']
1232     minor = context.env['SUNDIALS_VERSION_MINOR']
1233    
1234 jpye 1404 cppdef = context.env.get('CPPDEFINES')
1235    
1236     context.env.Append(CPPDEFINES=[
1237     ('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR")
1238     ,('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")
1239     ])
1240    
1241     context.env['SUNDIALS_CPPPATH_EXTRA']=[]
1242     if major==2 and minor==2:
1243     context.env.Append(SUNDIALS_CPPPATH_EXTRA = ["$SUNDIALS_CPPPATH/sundials"])
1244    
1245 jpye 1400 context.env.Append(CPPDEFINES=[('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR"),('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")])
1246 jpye 1404 context.env.AppendUnique(LIBS=context.env['SUNDIALS_LIBS'])
1247     context.env.AppendUnique(CPPPATH=context.env['SUNDIALS_CPPPATH_EXTRA'])
1248 jpye 1400
1249     is_ok = context.TryLink(ida_test_text,".c")
1250     context.Result(is_ok)
1251    
1252 jpye 1404 if cppdef:
1253     context.env['CPPDEFINES']=cppdef
1254 jpye 1400 keep.restore(context)
1255    
1256     return is_ok
1257    
1258    
1259 johnpye 673 #----------------
1260 johnpye 783 # CONOPT test
1261    
1262     conopt_test_text = """
1263 johnpye 800 #if !defined(_WIN32)
1264     # define FNAME_LCASE_DECOR
1265     #endif
1266    
1267 johnpye 783 #include <conopt.h>
1268     #include <stdlib.h>
1269     int main(){
1270     int s, *v, e;
1271     s = COIDEF_Size();
1272     v = (int *)malloc(s*sizeof(int));
1273     e = COIDEF_Ini(v);
1274     return e;
1275     }
1276     """
1277    
1278     def CheckCONOPT(context):
1279     context.Message( 'Checking for CONOPT... ' )
1280    
1281     keep = KeepContext(context,"CONOPT")
1282    
1283     is_ok = context.TryLink(conopt_test_text,".c")
1284     context.Result(is_ok)
1285    
1286     keep.restore(context)
1287    
1288     return is_ok
1289    
1290     #----------------
1291 johnpye 405 # Tcl test
1292 johnpye 404
1293 johnpye 561 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
1294     tcltk_minor_newest_acceptable = 4
1295     tcltk_major_required = 8
1296    
1297 johnpye 404 tcl_check_text = r"""
1298     #include <tcl.h>
1299     #include <stdio.h>
1300     int main(void){
1301     printf("%s",TCL_PATCH_LEVEL);
1302     return 0;
1303     }
1304     """
1305    
1306     def CheckTcl(context):
1307 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
1308 johnpye 405
1309     def CheckTclVersion(context):
1310 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
1311 johnpye 405 context.Message("Checking Tcl version... ")
1312     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
1313 johnpye 404 keep.restore(context)
1314     if not is_ok:
1315 johnpye 405 context.Result("failed to run check")
1316 johnpye 404 return 0
1317 johnpye 405
1318 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
1319 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1320 johnpye 428 context.Result(output+" (bad version)")
1321 johnpye 405 # bad version
1322     return 0
1323    
1324     # good version
1325 johnpye 552 context.Result(output+", good")
1326 johnpye 404 return 1
1327    
1328 johnpye 405 #----------------
1329 johnpye 463 # Tk test
1330 johnpye 405
1331     tk_check_text = r"""
1332     #include <tk.h>
1333     #include <stdio.h>
1334     int main(void){
1335     printf("%s",TK_PATCH_LEVEL);
1336     return 0;
1337     }
1338     """
1339     def CheckTk(context):
1340 johnpye 673 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1341 johnpye 405
1342 johnpye 428
1343 johnpye 405 def CheckTkVersion(context):
1344 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1345 johnpye 405 context.Message("Checking Tk version... ")
1346 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
1347 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1348 johnpye 404 keep.restore(context)
1349     if not is_ok:
1350     context.Result("failed to run check")
1351     return 0
1352    
1353 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
1354 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1355 johnpye 404 # bad version
1356 johnpye 561 context.Result(output+" (bad version)")
1357 johnpye 404 return 0
1358 johnpye 400
1359 johnpye 404 # good version
1360 johnpye 561 context.Result(output+" (good)")
1361 johnpye 404 return 1
1362 johnpye 485
1363     #----------------
1364 johnpye 521 # Tktable test
1365    
1366     tktable_check_text = r"""
1367     #include <tkTable.h>
1368     #include <stdio.h>
1369     int main(void){
1370     Table mytable;
1371     return 0;
1372     }
1373     """
1374    
1375     def CheckTkTable(context):
1376     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1377    
1378     #---------------
1379     # X11 test
1380    
1381     x11_check_text = r"""
1382     #include <X11/Xlib.h>
1383     #include <X11/IntrinsicP.h>
1384     #include <X11/Intrinsic.h>
1385     #include <X11/ObjectP.h>
1386     #include <X11/Object.h>
1387     int main(void){
1388     Object mything;
1389     return 0;
1390     }
1391     """
1392    
1393     def CheckX11(context):
1394     return CheckExtLib(context,'X11',x11_check_text)
1395    
1396     #----------------
1397 johnpye 968 # Check that we can raise and catch sigint
1398    
1399     sigint_test_text = r"""
1400     #include <signal.h>
1401     #include <setjmp.h>
1402     #include <stdlib.h>
1403     static jmp_buf g_jmpenv;
1404     void sighandler(int sig){
1405     longjmp(g_jmpenv,sig);
1406     }
1407     void testsigint(){
1408     raise(SIGINT);
1409     }
1410     int main(void){
1411     signal(SIGINT,&sighandler);
1412     switch(setjmp(g_jmpenv)){
1413     case 0:
1414     testsigint();
1415     exit(1);
1416     case SIGINT:
1417     exit(0);
1418     default:
1419     exit(2);
1420     }
1421     }
1422     """
1423    
1424     def CheckSIGINT(context):
1425     context.Message("Checking SIGINT is catchable... ")
1426     (is_ok,output)=context.TryRun(sigint_test_text,".c")
1427     context.Result(is_ok)
1428     return is_ok
1429    
1430     #----------------
1431 johnpye 953 # Check that we're able to catch floating point errors
1432    
1433     sigfpe_test_text = r"""
1434     #include <signal.h>
1435     #include <setjmp.h>
1436     #include <stdlib.h>
1437     #include <fenv.h>
1438     static jmp_buf g_jmpenv;
1439     void fpehandler(int sig){
1440     longjmp(g_jmpenv,sig);
1441     }
1442     int main(void){
1443     fenv_t myfenv;
1444     fegetenv(&myfenv);
1445     fesetenv(&myfenv);
1446     feenableexcept(FE_ALL_EXCEPT);
1447     signal(SIGFPE,&fpehandler);
1448     double x;
1449     switch(setjmp(g_jmpenv)){
1450     case 0:
1451     x = 1.0 / 0.0;
1452     /* failed to catch */
1453     exit(1);
1454     case SIGFPE:
1455     exit(0);
1456     }
1457     }
1458     """
1459    
1460     def CheckFPE(context):
1461 johnpye 968 context.Message("Checking C99 FPE behaviour... ")
1462 johnpye 953 (is_ok,output) = context.TryRun(sigfpe_test_text,'.c')
1463     context.Result(is_ok)
1464     return is_ok
1465    
1466     #----------------
1467 johnpye 968 # signal reset needed?
1468    
1469     sigreset_test_text = r"""
1470     #include <signal.h>
1471     #include <setjmp.h>
1472     #include <stdlib.h>
1473     #include <stdio.h>
1474     typedef void SigHandlerFn(int);
1475     static jmp_buf g_jmpenv;
1476     void sighandler(int sig){
1477     longjmp(g_jmpenv,sig);
1478     }
1479     void testsigint(){
1480 johnpye 1002 /* fprintf(stderr,"Raising SIGINT\n"); */
1481 johnpye 968 raise(SIGINT);
1482     }
1483     int main(void){
1484     SigHandlerFn *last,*saved;
1485     saved = signal(SIGINT,&sighandler);
1486     if(saved!=SIG_DFL){
1487 johnpye 1002 fprintf(stderr,"Default handler (%p) was not correctly set\n",SIG_DFL);
1488 johnpye 968 exit(3);
1489     }
1490     switch(setjmp(g_jmpenv)){
1491     case 0:
1492     testsigint();
1493     fprintf(stderr,"Back from SIGINT\n");
1494     exit(1);
1495     case SIGINT:
1496     break;
1497     default:
1498     exit(2);
1499     };
1500 johnpye 1002 last = signal(SIGINT,SIG_DFL);
1501 johnpye 968 if(last!=&sighandler){
1502     printf("1");
1503     exit(0);
1504     }
1505     printf("0");
1506     exit(0);
1507     }
1508     """
1509    
1510     def CheckSigReset(context):
1511     context.Message("Checking signal handler reset... ")
1512     (is_ok,output) = context.TryRun(sigreset_test_text,'.c')
1513     if not is_ok:
1514     context.Result("ERROR")
1515 johnpye 1260 return False
1516 johnpye 1002 if int(output)==1:
1517 johnpye 968 context.Result("required");
1518     context.env['ASC_RESETNEEDED'] = True
1519     else:
1520     context.Result("not required");
1521     context.env['ASC_RESETNEEDED'] = False
1522     return is_ok
1523    
1524     #----------------
1525 johnpye 485 # GCC Version sniffing
1526    
1527     # TODO FIXME
1528    
1529     gcc_version4 = False
1530    
1531 johnpye 398 #------------------------------------------------------
1532 johnpye 385 # CONFIGURATION
1533    
1534     conf = Configure(env
1535     , custom_tests = {
1536 johnpye 673 'CheckMath' : CheckMath
1537     , 'CheckSwigVersion' : CheckSwigVersion
1538 johnpye 957 , 'CheckPythonLib' : CheckPythonLib
1539 johnpye 400 , 'CheckCUnit' : CheckCUnit
1540 johnpye 938 , 'CheckDMalloc' : CheckDMalloc
1541 johnpye 1109 , 'CheckMFGraph' : CheckMFGraph
1542 jpye 1326 , 'CheckUFSparse' : CheckUFSparse
1543 johnpye 404 , 'CheckTcl' : CheckTcl
1544     , 'CheckTclVersion' : CheckTclVersion
1545 johnpye 405 , 'CheckTk' : CheckTk
1546     , 'CheckTkVersion' : CheckTkVersion
1547 johnpye 502 , 'CheckGcc' : CheckGcc
1548 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
1549 johnpye 502 , 'CheckYacc' : CheckYacc
1550 johnpye 1025 , 'CheckLex' : CheckLex
1551 johnpye 521 , 'CheckTkTable' : CheckTkTable
1552     , 'CheckX11' : CheckX11
1553 johnpye 673 , 'CheckIDA' : CheckIDA
1554 jpye 1400 , 'CheckSUNDIALS' : CheckSUNDIALS
1555 johnpye 783 , 'CheckCONOPT' : CheckCONOPT
1556 johnpye 816 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
1557 johnpye 953 , 'CheckFPE' : CheckFPE
1558 johnpye 968 , 'CheckSIGINT' : CheckSIGINT
1559     , 'CheckSigReset' : CheckSigReset
1560 johnpye 400 # , 'CheckIsNan' : CheckIsNan
1561     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
1562 johnpye 385 }
1563 johnpye 459 # , config_h = "config.h"
1564 johnpye 385 )
1565    
1566 jpye 1357 def sconsversioncheck():
1567    
1568     # uncomment the following line to skip the version check:
1569     # return 1
1570    
1571     import SCons
1572     v = SCons.__version__.split(".")
1573     if v[0] != '0':
1574     return 0
1575     if v[1] != '96':
1576     return 0
1577     micro = int(v[2])
1578 jpye 1394 if micro == 92 or micro == 93 or micro == 96:
1579 jpye 1357 return 1;
1580     return 0
1581    
1582     if not sconsversioncheck():
1583     print "Scons version is not OK. Please try version 0.96.92 or 0.96.93,"
1584     print "or consult the developers in the case of newer versions. Modify"
1585     print "the function 'sconsversioncheck' in the file SConstruct if you"
1586     print "want to *force* SCons to continue."
1587     Exit(1)
1588    
1589 johnpye 740 # stdio -- just to check that compiler is behaving
1590 johnpye 398
1591 johnpye 740 if not conf.CheckHeader('stdio.h'):
1592 johnpye 832 print "CPPPATH =",env.get('CPPPATH')
1593 johnpye 740 print "Did not find 'stdio.h'! Check your compiler configuration."
1594 johnpye 1080 print ""
1595     print "You environment is printed here:"
1596     for k,v in os.environ.iteritems():
1597     print "%-30s%s" % ("%s :" % k, v)
1598 johnpye 740 Exit(1)
1599    
1600 johnpye 1228 if not conf.CheckFunc('snprintf'):
1601     print "Didn't find snprintf";
1602     exit(1)
1603    
1604 johnpye 385 # Math library
1605    
1606 johnpye 1262 conf.env['HAVE_IEEE']=True
1607    
1608     if need_libm and not conf.CheckMath():
1609 johnpye 1232 conf.env['HAVE_IEEE']=False
1610 johnpye 1262 print 'Did not find math library, exiting!'
1611     Exit(1)
1612 johnpye 427
1613 johnpye 385 # Where is 'isnan'?
1614    
1615 johnpye 740 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1616 johnpye 385 print "Didn't find isnan"
1617 johnpye 414 # Exit(1)
1618 johnpye 385
1619 johnpye 500 # GCC visibility
1620    
1621 johnpye 502 if conf.CheckGcc():
1622     conf.env['HAVE_GCC']=True;
1623 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
1624 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
1625     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1626     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1627 johnpye 709 conf.env.Append(CCFLAGS=['-Wall'])
1628 johnpye 500
1629 johnpye 968 # Catching SIGINT
1630    
1631 johnpye 1142 if env['WITH_SIGNALS']:
1632     if not conf.CheckSIGINT():
1633     with_signals = False
1634     without_signals_reason = "SIGINT uncatchable"
1635 johnpye 968
1636 johnpye 953 # Catching SIGFPE
1637    
1638     if conf.CheckFPE():
1639 johnpye 968 conf.env['HAVE_C99FPE']=True
1640 johnpye 953 else:
1641 johnpye 968 conf.env['HAVE_C99FPE']=False
1642 johnpye 953
1643 johnpye 968 # Checking for signal reset requirement
1644    
1645     if not conf.CheckSigReset():
1646     print "Unable to determine if signal reset is required"
1647 johnpye 1260 Exit(1)
1648 johnpye 968
1649 johnpye 502 # YACC
1650    
1651 johnpye 506 if not conf.CheckYacc():
1652     print "YACC NOT FOUND OR NOT WORKING"
1653     else:
1654 johnpye 502 conf.env['HAVE_YACC']=True
1655    
1656 johnpye 1025 if not conf.CheckLex():
1657     print "YACC NOT FOUND OR NOT WORKING"
1658     else:
1659     conf.env['HAVE_LEX']=True
1660 johnpye 502
1661 johnpye 387 # Tcl/Tk
1662 johnpye 386
1663 johnpye 586 if with_tcltk:
1664     if conf.CheckTcl():
1665     if conf.CheckTclVersion():
1666     if conf.CheckTk():
1667     if with_tcltk and conf.CheckTkVersion():
1668     if env['STATIC_TCLTK']:
1669     if conf.CheckTkTable():
1670     pass
1671     else:
1672     without_tcltk_reason = "TkTable not found"
1673     with_tcltk = False
1674     else:
1675     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1676     with_tcltk = False
1677 johnpye 521 else:
1678 johnpye 586 without_tcltk_reason = "Tk not found."
1679 johnpye 551 with_tcltk = False
1680 johnpye 428 else:
1681 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1682 johnpye 551 with_tcltk = False
1683 johnpye 586
1684 johnpye 428 else:
1685 johnpye 586 without_tcltk_reason = "Tcl not found."
1686 johnpye 551 with_tcltk = False
1687 johnpye 386
1688 johnpye 521 if env['STATIC_TCLTK']:
1689     conf.CheckX11()
1690    
1691 johnpye 395 # Python... obviously we're already running python, so we just need to
1692     # check that we can link to the python library OK:
1693    
1694 johnpye 957 if not conf.CheckPythonLib():
1695     without_python_reason = 'libpython2.x not found or not linkable'
1696     with_python = False
1697 johnpye 982 env['WITH_PYTHON']=False
1698 johnpye 391
1699 johnpye 395 # SWIG version
1700    
1701 johnpye 957 if with_python and not conf.CheckSwigVersion():
1702 johnpye 413 without_python_reason = 'SWIG >= 1.3.24 is required'
1703     with_python = False
1704 johnpye 982 env['WITH_PYTHON']=False
1705 johnpye 413
1706 johnpye 400 # CUnit
1707    
1708 johnpye 593 if with_cunit:
1709 johnpye 404 if not conf.CheckCUnit():
1710 johnpye 427 without_cunit_reason = 'CUnit not found'
1711 johnpye 665 with_cunit = False
1712 johnpye 705 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1713 johnpye 427
1714 johnpye 938 # DMALLOC
1715    
1716     if with_dmalloc:
1717     if not conf.CheckDMalloc():
1718     without_dmalloc_reason = 'dmalloc not found'
1719     with_dmalloc = False
1720    
1721 jpye 1326 # MFGRAPH
1722 johnpye 1109
1723     if with_mfgraph:
1724     if not conf.CheckMFGraph():
1725     without_mfgraph_reason = 'mfgraph not found'
1726 johnpye 1113 with_mfgraph = False
1727 johnpye 1114 env['WITH_MFGRAPH'] = False
1728 johnpye 1109
1729 jpye 1326 # UFSPARSE
1730    
1731     if with_ufsparse:
1732     if not conf.CheckUFSparse():
1733     without_ufsparse_reason = 'mfgraph not found'
1734     with_ufsparse = False
1735     env['WITH_UFSPARSE'] = False
1736    
1737 johnpye 673 # IDA
1738    
1739     if not with_ida:
1740     without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1741 jpye 1400 elif not conf.CheckSUNDIALS():
1742     with_ida = False
1743     without_ida_reason = "SUNDIALS not found, or bad version"
1744 johnpye 673 elif not conf.CheckIDA():
1745     with_ida = False
1746 jpye 1400 without_ida_reason = "Unable to compile/link against SUNDIALS/IDA"
1747 johnpye 673
1748 johnpye 797 # CONOPT
1749 johnpye 783
1750     if not with_conopt:
1751     without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1752     elif not conf.CheckCONOPT():
1753 johnpye 797 with_conopt = False
1754     without_conpt_reason = "CONOPT not found"
1755 johnpye 783
1756 johnpye 427 # BLAS
1757    
1758 johnpye 459 need_blas=False
1759 johnpye 673
1760     if with_lsode:
1761     need_fortran = True
1762 johnpye 459 need_blas=True
1763 johnpye 673
1764 johnpye 459 if need_blas:
1765     if conf.CheckLib('blas'):
1766     with_local_blas = False
1767     without_local_blas_reason = "Found BLAS installed on system"
1768     else:
1769     with_local_blas = True
1770     need_fortran = True
1771 johnpye 673 else:
1772     with_local_blas= False;
1773     without_local_blas_reason = "BLAS not required"
1774 johnpye 427
1775     # FORTRAN
1776    
1777     if need_fortran:
1778 johnpye 629 conf.env.Tool('fortran')
1779 jpye 1380 detect_fortran = conf.env.Detect(['gfortran','g77'])
1780 johnpye 427 if detect_fortran:
1781     # For some reason, g77 doesn't get detected properly on MinGW
1782 johnpye 673 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1783 jpye 1357 print "Fixing detection of F77 on MinGW...(?)"
1784 johnpye 427 conf.env.Replace(F77=detect_fortran)
1785     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1786     conf.env.Replace(F77FLAGS='')
1787 johnpye 428 #print "F77:",conf.env['F77']
1788     #print "F77COM:",conf.env['F77COM']
1789     #print "F77FLAGS:",conf.env['F77FLAGS']
1790 johnpye 427 fortran_builder = Builder(
1791     action='$F77COM'
1792     , suffix='.o'
1793     , src_suffix='.f'
1794     )
1795     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1796 johnpye 1284 if platform.system()=="Linux":
1797     conf.env.Append(SHFORTRANFLAGS=['-fPIC'])
1798 johnpye 427 else:
1799 johnpye 673 with_lsode=False;
1800     without_lsode_reason="FORTRAN-77 required but not found"
1801 johnpye 629
1802 johnpye 464 #else:
1803     # print "FORTRAN not required"
1804 johnpye 400
1805 johnpye 673 # F2C
1806    
1807     if need_fortran:
1808     if platform.system()=="Windows":
1809 jpye 1380 pass
1810     #conf.env.Append(LIBPATH='c:\mingw\lib')
1811 johnpye 673
1812 johnpye 816 # scrollkeeper
1813 johnpye 673
1814 johnpye 816 if with_scrollkeeper:
1815     if not conf.CheckScrollkeeperConfig():
1816     with_scrollkeeper=False
1817     without_scrollkeeper_reason="unable to detect scrollkeeper-config"
1818    
1819 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
1820    
1821     # TODO: check size of void*
1822    
1823 johnpye 393 # TODO: detect if dynamic libraries are possible or not
1824    
1825 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
1826 johnpye 740 _found_windows_h = conf.CheckHeader('Windows.h')
1827    
1828     if not _found_windows_h:
1829 johnpye 741 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1830 johnpye 740 Exit(1)
1831 johnpye 741
1832 johnpye 534 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1833 johnpye 427 with_python = 0;
1834     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1835    
1836     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1837    
1838 johnpye 395 conf.Finish()
1839    
1840 johnpye 507 #---------------------------------------
1841     # SUBSTITUTION DICTIONARY for .in files
1842    
1843 johnpye 658 release = env.get('RELEASE')
1844     if release=="0.":
1845     release="0"
1846    
1847 johnpye 800 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1848    
1849 johnpye 507 subst_dict = {
1850     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1851     , '@GLADE_FILE@':'ascend.glade'
1852     , '@HELP_ROOT@':''
1853     , '@ICON_EXTENSION@':icon_extension
1854 johnpye 628 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1855 johnpye 507 , '@INSTALL_BIN@':env['INSTALL_BIN']
1856     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1857 johnpye 683 , '@INSTALL_LIB@':env['INSTALL_LIB']
1858 johnpye 721 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1859 johnpye 507 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1860     , '@VERSION@':version
1861 johnpye 658 , '@RELEASE@':release
1862 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1863 johnpye 507 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1864 johnpye 1228 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
1865     , '@SHLIBPREFIX@':env['SHLIBPREFIX']
1866 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1867 johnpye 627 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1868 johnpye 683 , '@PYTHON@' : python_exe
1869 johnpye 800 , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1870     , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1871 jpye 1399 , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_DLPATH"))
1872 johnpye 1174 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
1873 johnpye 507 }
1874    
1875 johnpye 594 if env.get('WITH_LOCAL_HELP'):
1876 johnpye 507 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1877     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1878    
1879 johnpye 597 # bool options...
1880 johnpye 673 for k,v in {
1881 johnpye 1142 'ASC_WITH_IDA':with_ida
1882     ,'ASC_WITH_DMALLOC':with_dmalloc
1883     ,'ASC_WITH_MFGRAPH':with_mfgraph
1884 jpye 1326 ,'ASC_WITH_UFSPARSE':with_ufsparse
1885 johnpye 1142 ,'ASC_WITH_CONOPT':with_conopt
1886     ,'ASC_WITH_LSODE':with_lsode
1887     ,'ASC_WITH_MMIO':with_mmio
1888     ,'ASC_SIGNAL_TRAPS':with_signals
1889     ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
1890     ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
1891 johnpye 1261 ,'HAVE_IEEE':env.get('HAVE_IEEE')
1892 jpye 1412 ,'ASC_ABSOLUTE_PATHS':env.get('ABSOLUTE_PATHS')
1893 johnpye 1142 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
1894     ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
1895     }.iteritems():
1896    
1897     if v: subst_dict["/\\* #define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
1898 johnpye 594
1899 johnpye 507 if with_python:
1900     subst_dict['@ASCXX_USE_PYTHON@']="1"
1901 johnpye 673 env['WITH_PYTHON']=1;
1902 johnpye 507
1903     if env.has_key('HAVE_GCCVISIBILITY'):
1904     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1905    
1906     env.Append(SUBST_DICT=subst_dict)
1907    
1908 johnpye 1142 #for k,v in subst_dict.iteritems():
1909     # print "%-50s%s" % ("'%s'"%k,v)
1910 johnpye 829
1911 johnpye 1142 # REMOVED: long command-line support on Win2k
1912 johnpye 829
1913     #------------------------------------------------------
1914 johnpye 558 # RECIPE: SWIG scanner
1915    
1916     import SCons.Script
1917    
1918     SWIGScanner = SCons.Scanner.ClassicCPP(
1919     "SWIGScan"
1920     , ".i"
1921     , "CPPPATH"
1922     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1923     )
1924    
1925     env.Append(SCANNERS=[SWIGScanner])
1926    
1927     #------------------------------------------------------
1928 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
1929    
1930     import re
1931 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
1932 johnpye 393
1933 johnpye 395 def TOOL_SUBST(env):
1934     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1935     from the source to the target.
1936     The values of SUBST_DICT first have any construction variables expanded
1937     (its keys are not expanded).
1938     If a value of SUBST_DICT is a python callable function, it is called and
1939     the result is expanded as the value.
1940     If there's more than one source and more than one target, each target gets
1941     substituted from the corresponding source.
1942 johnpye 393 """
1943 johnpye 395 env.Append(TOOLS = 'SUBST')
1944     def do_subst_in_file(targetfile, sourcefile, dict):
1945     """Replace all instances of the keys of dict with their values.
1946     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1947     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1948     """
1949     try:
1950     f = open(sourcefile, 'rb')
1951     contents = f.read()
1952     f.close()
1953     except:
1954     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1955     for (k,v) in dict.items():
1956 johnpye 1088 try:
1957 johnpye 1090 #print "%s ---> %s" % (k,v)
1958 johnpye 1088 contents = re.sub(k, v, contents)
1959     except Exception,e:
1960     sys.stderr.write("Failed to substute '%s' with '%s': %s\n" % (k,v,e))
1961    
1962 johnpye 395 try:
1963     f = open(targetfile, 'wb')
1964     f.write(contents)
1965     f.close()
1966     except:
1967     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1968     return 0 # success
1969 johnpye 393
1970 johnpye 395 def subst_in_file(target, source, env):
1971     if not env.has_key('SUBST_DICT'):
1972     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1973     d = dict(env['SUBST_DICT']) # copy it
1974     for (k,v) in d.items():
1975     if callable(v):
1976     d[k] = env.subst(v())
1977     elif SCons.Util.is_String(v):
1978     d[k]=env.subst(v)
1979     else:
1980     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1981     for (t,s) in zip(target, source):
1982     return do_subst_in_file(str(t), str(s), d)
1983 johnpye 393
1984 johnpye 395 def subst_in_file_string(target, source, env):
1985     """This is what gets printed on the console."""
1986     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1987     for (t,s) in zip(target, source)])
1988 johnpye 393
1989 johnpye 395 def subst_emitter(target, source, env):
1990     """Add dependency from substituted SUBST_DICT to target.
1991     Returns original target, source tuple unchanged.
1992     """
1993     d = env['SUBST_DICT'].copy() # copy it
1994     for (k,v) in d.items():
1995     if callable(v):
1996     d[k] = env.subst(v())
1997     elif SCons.Util.is_String(v):
1998     d[k]=env.subst(v)
1999     Depends(target, SCons.Node.Python.Value(d))
2000     return target, source
2001 johnpye 393
2002 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
2003     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
2004    
2005     TOOL_SUBST(env)
2006    
2007 johnpye 393 #------------------------------------------------------
2008 johnpye 463 # Recipe for 'CHMOD' ACTION
2009 johnpye 439
2010     import SCons
2011     from SCons.Script.SConscript import SConsEnvironment
2012     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
2013     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
2014    
2015     def InstallPerm(env, dest, files, perm):
2016     obj = env.Install(dest, files)
2017     for i in obj:
2018     env.AddPostAction(i, env.Chmod(str(i), perm))
2019    
2020     SConsEnvironment.InstallPerm = InstallPerm
2021    
2022     # define wrappers
2023     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
2024 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2025 johnpye 629 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2026 johnpye 463
2027 johnpye 439 #------------------------------------------------------
2028 johnpye 463 # BUILD...
2029 johnpye 385
2030 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
2031 johnpye 743 env.AppendUnique(CPPPATH=['#base/generic'])
2032 johnpye 385
2033 johnpye 508 if env['DEBUG']:
2034     env.Append(CCFLAGS=['-g'])
2035    
2036 johnpye 591 if env['GCOV']:
2037     env.Append(
2038     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
2039     , LIBS=['gcov']
2040     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
2041     )
2042    
2043 johnpye 673 if with_ida:
2044     env.Append(WITH_IDA=1)
2045    
2046 johnpye 783 if with_conopt:
2047     env.Append(WITH_CONOPT=1)
2048    
2049 johnpye 463 #-------------
2050     # TCL/TK GUI
2051 johnpye 385
2052 johnpye 551 if with_tcltk:
2053 johnpye 569 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
2054 johnpye 391 else:
2055 johnpye 982 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
2056 johnpye 386
2057 johnpye 463 #-------------
2058     # PYTHON INTERFACE
2059    
2060 johnpye 387 if with_python:
2061 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
2062 johnpye 391 else:
2063 johnpye 982 print "Skipping... Python bindings aren't being built:",without_python_reason
2064 johnpye 400
2065 johnpye 463 #------------
2066     # BASE/GENERIC SUBDIRECTORIES
2067    
2068 johnpye 673 libascend_env = env.Copy()
2069    
2070 johnpye 1316 dirs = ['general','utilities','compiler','system','solver','integrator','packages','linear']
2071 johnpye 463
2072     srcs = []
2073     for d in dirs:
2074 johnpye 673 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
2075 johnpye 463 srcs += heresrcs
2076    
2077     #-------------
2078 johnpye 673 # IMPORTED CODE: LSODE, BLAS, etc
2079    
2080     if with_lsode:
2081     srcs += env.SConscript(['lsod/SConscript'],'env')
2082     srcs += env.SConscript(['linpack/SConscript'],'env')
2083     else:
2084     print "Skipping... LSODE won't be built:", without_lsode_reason
2085    
2086     if with_local_blas:
2087     srcs += env.SConscript(['blas/SConscript'],'env')
2088     else:
2089     print "Skipping... BLAS won't be built:", without_local_blas_reason
2090    
2091     if not with_ida:
2092     print "Skipping... IDA won't be built:", without_ida_reason
2093    
2094 johnpye 993 if with_mmio:
2095     srcs += env.SConscript(['mmio/SConscript'],'env')
2096     else:
2097     print "Skipping... MMIO export won't be built:", without_mmio_reason
2098 johnpye 673 #-------------
2099 johnpye 463 # LIBASCEND -- all base/generic functionality
2100    
2101 johnpye 938 if with_dmalloc:
2102     libascend_env.Append(LIBS=['dmalloc'])
2103    
2104 jpye 1326 if with_ufsparse:
2105     libascend_env.Append(LIBS=['cxsparse'])
2106    
2107 johnpye 673 libascend = libascend_env.SharedLibrary('ascend',srcs)
2108 johnpye 463
2109 johnpye 673 env.Alias('libascend',libascend)
2110    
2111 johnpye 463 #-------------
2112 johnpye 761 # UNIT TESTS (C CODE)
2113 johnpye 463
2114 johnpye 593 if with_cunit:
2115 jpye 1319 testdirs = ['general','solver','utilities','linear']
2116 johnpye 593 testsrcs = []
2117 johnpye 400 for testdir in testdirs:
2118     path = 'base/generic/'+testdir+'/test/'
2119     env.SConscript([path+'SConscript'],'env')
2120 johnpye 593 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
2121    
2122     #print "TESTSRCS =",testsrcs
2123    
2124 johnpye 400 env.SConscript(['test/SConscript'],'env')
2125     env.SConscript(['base/generic/test/SConscript'],'env')
2126 johnpye 593
2127     env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
2128 johnpye 400
2129     else:
2130 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
2131 johnpye 400
2132 johnpye 761 #-------------
2133     # EXTERNAL FUNCTIONS
2134    
2135 johnpye 811 env['extfns']=[]
2136     modeldirs = env.SConscript(['models/SConscript'],'env')
2137    
2138     if not with_extfns:
2139 johnpye 761 print "Skipping... External modules aren't being built:",without_extfns_reason
2140    
2141 johnpye 811 env.Alias('extfns',env['extfns'])
2142 johnpye 761
2143 johnpye 463 #------------------------------------------------------
2144 johnpye 683 # CREATE ASCEND-CONFIG scriptlet
2145    
2146     ascendconfig = env.SubstInFile('ascend-config.in')
2147    
2148     #------------------------------------------------------
2149 johnpye 463 # INSTALLATION
2150 johnpye 427
2151 johnpye 552 if env.get('CAN_INSTALL'):
2152 johnpye 427
2153 jpye 1335 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
2154 johnpye 884 install_dirs = [env.Entry(env['INSTALL_ROOT']+env[d]) for d in dirs]
2155 johnpye 811 install_dirs += modeldirs
2156 johnpye 449
2157 johnpye 463 # TODO: add install options
2158     env.Alias('install',install_dirs)
2159 johnpye 400
2160 johnpye 629 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
2161 johnpye 435
2162 johnpye 683 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
2163    
2164 johnpye 438 #------------------------------------------------------
2165 johnpye 631 # WINDOWS INSTALLER
2166     # For the windows installer, please see pygtk/SConscript
2167    
2168     if with_installer:
2169     pass
2170     else:
2171     print "Skipping... Windows installer isn't being built:",without_installer_reason
2172    
2173     #------------------------------------------------------
2174 johnpye 673 # PROJECT FILE for MSVC
2175    
2176     env.SConscript(['base/msvc/SConscript'],['env','libascend']);
2177    
2178     #------------------------------------------------------
2179 johnpye 438 # CREATE the SPEC file for generation of RPM packages
2180    
2181 johnpye 463 if platform.system()=="Linux":
2182     env.SubstInFile('ascend.spec.in')
2183 johnpye 552
2184     #------------------------------------------------------
2185 johnpye 816 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
2186    
2187     if with_scrollkeeper:
2188     env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
2189     env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
2190    
2191     #------------------------------------------------------
2192 johnpye 552 # DISTRIBUTION TAR FILE
2193    
2194 johnpye 554 env['DISTTAR_FORMAT']='bz2'
2195 johnpye 556 env.Append(
2196 johnpye 862 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl','.out']
2197 jpye 1417 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist','debian']
2198 johnpye 556 )
2199 johnpye 554
2200 johnpye 563 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
2201 johnpye 556 , [env.Dir('#')]
2202 johnpye 554 )
2203    
2204 johnpye 680 env.Depends(tar,'ascend.spec')
2205    
2206 johnpye 862 Alias('dist',tar)
2207    
2208 johnpye 554 #------------------------------------------------------
2209 johnpye 816 # USER'S MANUAL
2210    
2211     env.SConscript('doc/SConscript',['env'])
2212    
2213     #------------------------------------------------------
2214 johnpye 766 # LIBASCEND DOXYGEN DOCUMENTATION
2215    
2216     env.SConscript('base/doc/SConscript',['env'])
2217    
2218     #------------------------------------------------------
2219 johnpye 554 # RPM BUILD
2220    
2221 johnpye 766 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
2222     # (check * for the version number used to create the tarball)
2223 johnpye 554
2224     #------------------------------------------------------
2225     # DEFAULT TARGETS
2226    
2227 johnpye 673 default_targets =['libascend']
2228 johnpye 629 if with_tcltk:
2229     default_targets.append('tcltk')
2230     if with_python:
2231     default_targets.append('pygtk')
2232 johnpye 631 if with_installer:
2233     default_targets.append('installer')
2234 johnpye 761 if with_extfns:
2235     default_targets.append('extfns')
2236 johnpye 554
2237 johnpye 629 env.Default(default_targets)
2238    
2239     print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
2240    
2241 johnpye 705 # vim: set syntax=python:

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