/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 922 - (hide annotations) (download)
Wed Nov 8 05:25:37 2006 UTC (13 years, 1 month ago) by johnpye
File size: 42228 byte(s)
Expanded the 'ascend-config' mechanism to be supported in Windows installations (On Windows, ascend-config is installed in $INSTDIR and uses the registry instead of hard-coded file paths).

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

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