/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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