/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (hide annotations) (download)
Tue Aug 15 14:40:33 2006 UTC (14 years, 1 month ago) by johnpye
File size: 39176 byte(s)
Adding the 'sun.c' and 'sun.h' files back into ASCEND so that we don't need dependency on libradtran.
Added detection of Scrollkeeper, the freedesktop.org documentation manager.
Added placeholder SConscript file for building the user's manual.
1 johnpye 800 import os, commands, platform, distutils.sysconfig, os.path, re
2 johnpye 385
3 johnpye 794 version = "0.9.5.96"
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     ,['sundials_ida','sundials_nvecserial','m']
192     )
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     ,"$INSTALL_SHARE/doc/ascend"
376     )
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 392 # TODO: OTHER OPTIONS?
465     # TODO: flags for optimisation
466 johnpye 393 # TODO: turning on/off bintoken functionality
467 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
468 johnpye 393
469 johnpye 498 # Import the outside environment
470    
471 johnpye 800 def c_escape(str):
472     return re.sub("\\\\","/",str)
473    
474     envadditional={}
475 johnpye 569 if os.environ.get('OSTYPE')=='msys':
476 johnpye 800 envenv = os.environ;
477     tools = ['mingw','lex','yacc','fortran','swig','disttar','nsis','doxygen']
478     envadditional['IS_MINGW']=True
479 johnpye 740
480     elif platform.system()=="Windows":
481 johnpye 800 envenv = {
482     'PATH':os.environ['PATH']
483     ,'INCLUDE':os.environ['INCLUDE']
484     ,'LIB':os.environ['LIB']
485     ,'MSVS_IGNORE_IDE_PATHS':1
486     }
487     tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
488     envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
489 johnpye 498 else:
490 johnpye 800 envenv = os.environ
491     tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
492    
493     env = Environment(
494     ENV=envenv
495     , toolpath=['scons']
496     , tools=tools
497     , **envadditional
498     )
499 johnpye 498
500 johnpye 385 opts.Update(env)
501     opts.Save('options.cache',env)
502    
503     Help(opts.GenerateHelpText(env))
504    
505 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
506 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
507 johnpye 386
508 johnpye 551 with_python = env.get('WITH_PYTHON')
509 johnpye 427 without_python_reason = "disabled by options/config.py"
510 johnpye 387
511 johnpye 593 with_cunit = env.get('WITH_CUNIT')
512 johnpye 427 without_cunit_reason = "not requested"
513 johnpye 400
514 johnpye 761 with_extfns = env.get('WITH_EXTFNS')
515     without_extfn_reason = "disabled by options/config.py"
516    
517 johnpye 816 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
518     without_scrollkeeper_reason = "disabled by options/config.py"
519    
520 johnpye 631 if platform.system()=="Windows":
521     with_installer=1
522     else:
523     with_installer=0
524     without_installer_reason = "only possible under Windows"
525    
526 johnpye 673 if 'LSOD' in env['WITH_SOLVERS']:
527     with_lsode=True
528     else:
529     with_lsode=False
530     without_lsode_reason = "not requested (WITH_SOLVERS)"
531    
532     if 'IDA' in env['WITH_SOLVERS']:
533     with_ida=True
534     else:
535     with_ida=False
536     without_ida_reason = "not requested (WITH_SOLVERS)"
537    
538    
539 johnpye 783 if 'CONOPT' in env['WITH_SOLVERS']:
540     with_conopt=True
541     else:
542     with_conopt=False
543     without_conopt_reason = "not requested (WITH_SOLVERS)"
544    
545    
546 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
547     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
548     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
549 johnpye 393
550 johnpye 463 can_install = True
551     if platform.system()=='Windows':
552     can_install = False
553    
554     env['CAN_INSTALL']=can_install
555    
556 johnpye 721 env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
557    
558 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
559     print "TCL_LIBPATH =",env['TCL_LIBPATH']
560     print "TCL_LIB =",env['TCL_LIB']
561 johnpye 562 print "CC =",env['CC']
562     print "CXX =",env['CXX']
563 johnpye 673 print "FORTRAN=",env.get('FORTRAN')
564 johnpye 393
565 johnpye 628 print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
566 johnpye 385 #------------------------------------------------------
567 johnpye 398 # SPECIAL CONFIGURATION TESTS
568    
569 johnpye 463 need_fortran = False
570    
571 johnpye 400 #----------------
572     # SWIG
573    
574 johnpye 398 import os,re
575    
576 johnpye 413 def get_swig_version(env):
577 johnpye 403 cmd = env['SWIG']+' -version'
578 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
579 johnpye 403 output = coutcerr.read()
580 johnpye 398
581 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
582     expr = re.compile(restr,re.M);
583 johnpye 398 m = expr.search(output);
584     if not m:
585 johnpye 413 return None
586 johnpye 398 maj = int(m.group('maj'))
587     min = int(m.group('min'))
588     pat = int(m.group('pat'))
589 johnpye 413
590     return (maj,min,pat)
591 johnpye 398
592 johnpye 413
593     def CheckSwigVersion(context):
594    
595     try:
596     context.Message("Checking version of SWIG... ")
597     maj,min,pat = get_swig_version(context.env)
598     except:
599     context.Result("Failed to detect version, or failed to run SWIG")
600     return 0;
601    
602 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
603    
604 johnpye 398 if maj == 1 and (
605 johnpye 400 min > 3
606     or (min == 3 and pat >= 24)
607 johnpye 398 ):
608     context.Result("ok, %d.%d.%d" % (maj,min,pat))
609     return 1;
610 johnpye 401 else:
611     context.Result("too old, %d.%d.%d" % (maj,min,pat))
612     return 0;
613 johnpye 398
614 johnpye 400 #----------------
615 johnpye 816 # Scrollkeeper (Linux documentation system)
616    
617     def get_scrollkeeper_omfdir(env):
618     cmd = 'scrollkeeper-config --omfdir'
619     (cin,coutcerr) = os.popen4(cmd)
620     output = coutcerr.read()
621     return output.strip()
622    
623     def CheckScrollkeeperConfig(context):
624     try:
625     context.Message("Checking for scrollkeeper...")
626     dir=get_scrollkeeper_omfdir(context.env)
627     except:
628     context.Result("Failed to run 'scrollkeeper-config'")
629     return 0
630     context.env['OMFDIR']=dir
631     context.Result("OK, %s" % dir)
632     return 1
633    
634     #----------------
635 johnpye 400 # General purpose library-and-header test
636    
637 johnpye 404 class KeepContext:
638 johnpye 521 def __init__(self,context,varprefix,static=False):
639 johnpye 404 self.keep = {}
640 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
641 johnpye 705 #print "Keeping env %s = %s" % (k,context.env.get(k))
642     self.keep[k]=context.env.get(k)
643 johnpye 404
644     if context.env.has_key(varprefix+'_CPPPATH'):
645 johnpye 743 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
646 johnpye 800 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
647 johnpye 428
648 johnpye 521 if static:
649     staticlib=env[varprefix+'_LIB']
650     #print "STATIC LIB = ",staticlib
651     context.env.Append(
652     LINKFLAGS=[staticlib]
653     )
654     else:
655     if context.env.has_key(varprefix+'_LIBPATH'):
656     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
657 johnpye 800 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
658 johnpye 428
659 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
660     context.env.Append(LIBS=[env[varprefix+'_LIB']])
661 johnpye 705 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
662 johnpye 404
663     def restore(self,context):
664 johnpye 464 #print "RESTORING CONTEXT"
665     #print self.keep
666     #print "..."
667 johnpye 404 for k in self.keep:
668 johnpye 463 if self.keep[k]==None:
669 johnpye 521 if context.env.has_key(k):
670     #print "Clearing "+str(k)
671     del context.env[k];
672 johnpye 463 else:
673 johnpye 705 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
674 johnpye 463 context.env[k]=self.keep[k];
675 johnpye 404
676 johnpye 521 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
677 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
678     and LIBNAME_CPPPATH and try to compile and link the
679     file with the provided text, linking with the
680     library libname."""
681    
682 johnpye 521 if static:
683     context.Message( 'Checking for static '+libname+'... ' )
684     else:
685     context.Message( 'Checking for '+libname+'... ' )
686    
687 johnpye 400 if varprefix==None:
688     varprefix = libname.upper()
689    
690 johnpye 705 #print "LIBS is currently:",context.env.get('LIBS')
691 johnpye 521 keep = KeepContext(context,varprefix,static)
692 johnpye 400
693 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
694 johnpye 463 # if varprefix_LIB were in env, KeepContext would
695     # have appended it already
696 johnpye 705 context.env.Append(LIBS=[libname])
697 johnpye 428
698 johnpye 404 is_ok = context.TryLink(text,ext)
699 johnpye 428
700 johnpye 521 #print "Link success? ",(is_ok != 0)
701 johnpye 400
702 johnpye 405 keep.restore(context)
703 johnpye 400
704 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
705 johnpye 705 # print "Restored LIBS="+str(context.env['LIBS'])
706 johnpye 428 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
707    
708 johnpye 404 context.Result(is_ok)
709     return is_ok
710    
711     #----------------
712 johnpye 502 # GCC
713    
714     gcc_test_text = """
715     #ifndef __GNUC__
716     # error "Not using GCC"
717     #endif
718    
719     int main(void){
720     return __GNUC__;
721     }
722     """
723    
724     def CheckGcc(context):
725     context.Message("Checking for GCC... ")
726     is_ok = context.TryCompile(gcc_test_text,".c")
727     context.Result(is_ok)
728     return is_ok
729    
730     #----------------
731 johnpye 500 # GCC VISIBILITY feature
732    
733     gccvisibility_test_text = """
734     #if __GNUC__ < 4
735     # error "Require GCC version 4 or newer"
736     #endif
737    
738     __attribute__ ((visibility("default"))) int x;
739    
740     int main(void){
741     extern int x;
742     x = 4;
743     }
744     """
745    
746     def CheckGccVisibility(context):
747     context.Message("Checking for GCC 'visibility' capability... ")
748 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
749     context.Result("disabled")
750     return 0
751 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
752     context.Result(is_ok)
753     return is_ok
754 johnpye 502
755 johnpye 500 #----------------
756 johnpye 502 # YACC
757    
758     yacc_test_text = """
759 johnpye 646 %{
760     #include <stdio.h>
761 johnpye 741
762     /* MSVC++ needs this before it can swallow Bison output */
763     #ifdef _MSC_VER
764     # define __STDC__
765     #endif
766 johnpye 646 %}
767     %token MSG
768 johnpye 502 %start ROOT
769 johnpye 646 %%
770     ROOT:
771     MSG { printf("HELLO"); }
772     ;
773     %%
774 johnpye 502 """
775    
776     def CheckYacc(context):
777 johnpye 644 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
778 johnpye 502 is_ok = context.TryCompile(yacc_test_text,".y")
779     context.Result(is_ok)
780     return is_ok
781    
782     #----------------
783 johnpye 404 # CUnit test
784    
785 johnpye 400 cunit_test_text = """
786 johnpye 451 #include <CUnit/CUnit.h>
787 johnpye 400 int maxi(int i1, int i2){
788     return (i1 > i2) ? i1 : i2;
789     }
790    
791     void test_maxi(void){
792     CU_ASSERT(maxi(0,2) == 2);
793     CU_ASSERT(maxi(0,-2) == 0);
794     CU_ASSERT(maxi(2,2) == 2);
795    
796     }
797     int main(void){
798     /* CU_initialize_registry() */
799 johnpye 404 return 0;
800 johnpye 400 }
801     """
802    
803     def CheckCUnit(context):
804 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
805 johnpye 400
806 johnpye 404 #----------------
807 johnpye 673 # MATH test
808    
809     math_test_text = """
810 johnpye 705 #ifndef _ALL_SOURCE
811     # define _ALL_SOURCE
812     #endif
813     #ifndef _XOPEN_SOURCE
814     # define _XOPEN_SOURCE
815     #endif
816     #ifndef _XOPEN_SOURCE_EXTENDED
817     # define _XOPEN_SOURCE_EXTENDED 1
818     #endif
819 johnpye 673 #include <math.h>
820     int main(void){
821 johnpye 705 double x = 1.0; double y = 1.0; int i = 1;
822     acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
823     j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
824     y0(x); y1(x); yn(i,x);
825     #ifdef _THREAD_SAFE
826     gamma_r(x,&i);
827     lgamma_r(x,&i);
828     #else
829     gamma(x);
830     lgamma(x);
831     #endif
832     hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
833 johnpye 673 return 0;
834     }
835     """
836    
837     def CheckMath(context):
838 johnpye 705 context.Message('Checking for IEE math library... ')
839     libsave=context.env.get('LIBS');
840     context.env.AppendUnique(LIBS=['m'])
841     is_ok=context.TryLink(math_test_text,".c")
842     context.Result(is_ok)
843     if not is_ok:
844     context.env['LIBS']=libsave
845     return is_ok
846    
847 johnpye 673 #----------------
848     # IDA test
849    
850     ida_test_text = """
851 johnpye 782 #include <ida/ida.h>
852     #include <nvector/nvector_serial.h>
853     #include <ida/ida_spgmr.h>
854 johnpye 673 int main(){
855     void *ida_mem;
856     ida_mem = IDACreate();
857 johnpye 782 return 0;
858 johnpye 673 }
859     """
860    
861     def CheckIDA(context):
862     context.Message( 'Checking for IDA (SUNDIALS)... ' )
863    
864     keep = KeepContext(context,"IDA")
865    
866     is_ok = context.TryLink(ida_test_text,".c")
867     context.Result(is_ok)
868    
869     keep.restore(context)
870 johnpye 782
871 johnpye 673 return is_ok
872    
873     #----------------
874 johnpye 783 # CONOPT test
875    
876     conopt_test_text = """
877 johnpye 800 #if !defined(_WIN32)
878     # define FNAME_LCASE_DECOR
879     #endif
880    
881 johnpye 783 #include <conopt.h>
882     #include <stdlib.h>
883     int main(){
884     int s, *v, e;
885     s = COIDEF_Size();
886     v = (int *)malloc(s*sizeof(int));
887     e = COIDEF_Ini(v);
888     return e;
889     }
890     """
891    
892     def CheckCONOPT(context):
893     context.Message( 'Checking for CONOPT... ' )
894    
895     keep = KeepContext(context,"CONOPT")
896    
897     is_ok = context.TryLink(conopt_test_text,".c")
898     context.Result(is_ok)
899    
900     keep.restore(context)
901    
902     return is_ok
903    
904     #----------------
905 johnpye 405 # Tcl test
906 johnpye 404
907 johnpye 561 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
908     tcltk_minor_newest_acceptable = 4
909     tcltk_major_required = 8
910    
911 johnpye 404 tcl_check_text = r"""
912     #include <tcl.h>
913     #include <stdio.h>
914     int main(void){
915     printf("%s",TCL_PATCH_LEVEL);
916     return 0;
917     }
918     """
919    
920     def CheckTcl(context):
921 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
922 johnpye 405
923     def CheckTclVersion(context):
924 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
925 johnpye 405 context.Message("Checking Tcl version... ")
926     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
927 johnpye 404 keep.restore(context)
928     if not is_ok:
929 johnpye 405 context.Result("failed to run check")
930 johnpye 404 return 0
931 johnpye 405
932 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
933 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
934 johnpye 428 context.Result(output+" (bad version)")
935 johnpye 405 # bad version
936     return 0
937    
938     # good version
939 johnpye 552 context.Result(output+", good")
940 johnpye 404 return 1
941    
942 johnpye 405 #----------------
943 johnpye 463 # Tk test
944 johnpye 405
945     tk_check_text = r"""
946     #include <tk.h>
947     #include <stdio.h>
948     int main(void){
949     printf("%s",TK_PATCH_LEVEL);
950     return 0;
951     }
952     """
953     def CheckTk(context):
954 johnpye 673 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
955 johnpye 405
956 johnpye 428
957 johnpye 405 def CheckTkVersion(context):
958 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
959 johnpye 405 context.Message("Checking Tk version... ")
960 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
961 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
962 johnpye 404 keep.restore(context)
963     if not is_ok:
964     context.Result("failed to run check")
965     return 0
966    
967 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
968 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
969 johnpye 404 # bad version
970 johnpye 561 context.Result(output+" (bad version)")
971 johnpye 404 return 0
972 johnpye 400
973 johnpye 404 # good version
974 johnpye 561 context.Result(output+" (good)")
975 johnpye 404 return 1
976 johnpye 485
977     #----------------
978 johnpye 521 # Tktable test
979    
980     tktable_check_text = r"""
981     #include <tkTable.h>
982     #include <stdio.h>
983     int main(void){
984     Table mytable;
985     return 0;
986     }
987     """
988    
989     def CheckTkTable(context):
990     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
991    
992     #---------------
993     # X11 test
994    
995     x11_check_text = r"""
996     #include <X11/Xlib.h>
997     #include <X11/IntrinsicP.h>
998     #include <X11/Intrinsic.h>
999     #include <X11/ObjectP.h>
1000     #include <X11/Object.h>
1001     int main(void){
1002     Object mything;
1003     return 0;
1004     }
1005     """
1006    
1007     def CheckX11(context):
1008     return CheckExtLib(context,'X11',x11_check_text)
1009    
1010     #----------------
1011 johnpye 485 # GCC Version sniffing
1012    
1013     # TODO FIXME
1014    
1015     gcc_version4 = False
1016    
1017 johnpye 398 #------------------------------------------------------
1018 johnpye 385 # CONFIGURATION
1019    
1020     conf = Configure(env
1021     , custom_tests = {
1022 johnpye 673 'CheckMath' : CheckMath
1023     , 'CheckSwigVersion' : CheckSwigVersion
1024 johnpye 400 , 'CheckCUnit' : CheckCUnit
1025 johnpye 404 , 'CheckTcl' : CheckTcl
1026     , 'CheckTclVersion' : CheckTclVersion
1027 johnpye 405 , 'CheckTk' : CheckTk
1028     , 'CheckTkVersion' : CheckTkVersion
1029 johnpye 502 , 'CheckGcc' : CheckGcc
1030 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
1031 johnpye 502 , 'CheckYacc' : CheckYacc
1032 johnpye 521 , 'CheckTkTable' : CheckTkTable
1033     , 'CheckX11' : CheckX11
1034 johnpye 673 , 'CheckIDA' : CheckIDA
1035 johnpye 783 , 'CheckCONOPT' : CheckCONOPT
1036 johnpye 816 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
1037 johnpye 400 # , 'CheckIsNan' : CheckIsNan
1038     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
1039 johnpye 385 }
1040 johnpye 459 # , config_h = "config.h"
1041 johnpye 385 )
1042    
1043 johnpye 740 # stdio -- just to check that compiler is behaving
1044 johnpye 398
1045 johnpye 740 if not conf.CheckHeader('stdio.h'):
1046     print "Did not find 'stdio.h'! Check your compiler configuration."
1047     Exit(1)
1048    
1049 johnpye 385 # Math library
1050    
1051 johnpye 673 if need_libm:
1052     if not conf.CheckMath():
1053     print 'Did not find math library, exiting!'
1054     Exit(1)
1055     #pass
1056 johnpye 427
1057 johnpye 385 # Where is 'isnan'?
1058    
1059 johnpye 740 if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1060 johnpye 385 print "Didn't find isnan"
1061 johnpye 414 # Exit(1)
1062 johnpye 385
1063 johnpye 500 # GCC visibility
1064    
1065 johnpye 502 if conf.CheckGcc():
1066     conf.env['HAVE_GCC']=True;
1067 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
1068 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
1069     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1070     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1071 johnpye 709 conf.env.Append(CCFLAGS=['-Wall'])
1072 johnpye 500
1073 johnpye 502 # YACC
1074    
1075 johnpye 506 if not conf.CheckYacc():
1076     print "YACC NOT FOUND OR NOT WORKING"
1077     else:
1078 johnpye 502 conf.env['HAVE_YACC']=True
1079    
1080     conf.env['HAVE_LEX']=True
1081    
1082 johnpye 387 # Tcl/Tk
1083 johnpye 386
1084 johnpye 586 if with_tcltk:
1085     if conf.CheckTcl():
1086     if conf.CheckTclVersion():
1087     if conf.CheckTk():
1088     if with_tcltk and conf.CheckTkVersion():
1089     if env['STATIC_TCLTK']:
1090     if conf.CheckTkTable():
1091     pass
1092     else:
1093     without_tcltk_reason = "TkTable not found"
1094     with_tcltk = False
1095     else:
1096     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1097     with_tcltk = False
1098 johnpye 521 else:
1099 johnpye 586 without_tcltk_reason = "Tk not found."
1100 johnpye 551 with_tcltk = False
1101 johnpye 428 else:
1102 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1103 johnpye 551 with_tcltk = False
1104 johnpye 586
1105 johnpye 428 else:
1106 johnpye 586 without_tcltk_reason = "Tcl not found."
1107 johnpye 551 with_tcltk = False
1108 johnpye 386
1109 johnpye 521 if env['STATIC_TCLTK']:
1110     conf.CheckX11()
1111    
1112 johnpye 395 # Python... obviously we're already running python, so we just need to
1113     # check that we can link to the python library OK:
1114    
1115 johnpye 391 if platform.system()=="Windows":
1116 johnpye 395 python_lib='python24'
1117 johnpye 391 else:
1118 johnpye 395 python_lib='python2.4'
1119 johnpye 391
1120 johnpye 395 # SWIG version
1121    
1122 johnpye 413 if not conf.CheckSwigVersion():
1123     without_python_reason = 'SWIG >= 1.3.24 is required'
1124     with_python = False
1125    
1126 johnpye 400 # CUnit
1127    
1128 johnpye 593 if with_cunit:
1129 johnpye 404 if not conf.CheckCUnit():
1130 johnpye 427 without_cunit_reason = 'CUnit not found'
1131 johnpye 665 with_cunit = False
1132 johnpye 705 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1133 johnpye 427
1134 johnpye 673 # IDA
1135    
1136     if not with_ida:
1137     without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1138     elif not conf.CheckIDA():
1139     with_ida = False
1140     without_ida_reason = "IDA not found"
1141    
1142 johnpye 797 # CONOPT
1143 johnpye 783
1144     if not with_conopt:
1145     without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1146     elif not conf.CheckCONOPT():
1147 johnpye 797 with_conopt = False
1148     without_conpt_reason = "CONOPT not found"
1149 johnpye 783
1150 johnpye 427 # BLAS
1151    
1152 johnpye 459 need_blas=False
1153 johnpye 673
1154     if with_lsode:
1155     need_fortran = True
1156 johnpye 459 need_blas=True
1157 johnpye 673
1158 johnpye 459 if need_blas:
1159     if conf.CheckLib('blas'):
1160     with_local_blas = False
1161     without_local_blas_reason = "Found BLAS installed on system"
1162     else:
1163     with_local_blas = True
1164     need_fortran = True
1165 johnpye 673 else:
1166     with_local_blas= False;
1167     without_local_blas_reason = "BLAS not required"
1168 johnpye 427
1169     # FORTRAN
1170    
1171     if need_fortran:
1172 johnpye 629 conf.env.Tool('fortran')
1173     detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1174 johnpye 427 if detect_fortran:
1175     # For some reason, g77 doesn't get detected properly on MinGW
1176 johnpye 673 if not env.has_key('F77') and not env.has_key('FORTRAN'):
1177 johnpye 427 conf.env.Replace(F77=detect_fortran)
1178     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1179     conf.env.Replace(F77FLAGS='')
1180 johnpye 428 #print "F77:",conf.env['F77']
1181     #print "F77COM:",conf.env['F77COM']
1182     #print "F77FLAGS:",conf.env['F77FLAGS']
1183 johnpye 427 fortran_builder = Builder(
1184     action='$F77COM'
1185     , suffix='.o'
1186     , src_suffix='.f'
1187     )
1188     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1189     else:
1190 johnpye 673 with_lsode=False;
1191     without_lsode_reason="FORTRAN-77 required but not found"
1192 johnpye 629
1193 johnpye 464 #else:
1194     # print "FORTRAN not required"
1195 johnpye 400
1196 johnpye 673 # F2C
1197    
1198     if need_fortran:
1199     if platform.system()=="Windows":
1200     conf.env.Append(LIBPATH='c:\mingw\lib')
1201    
1202 johnpye 816 # scrollkeeper
1203 johnpye 673
1204 johnpye 816 if with_scrollkeeper:
1205     if not conf.CheckScrollkeeperConfig():
1206     with_scrollkeeper=False
1207     without_scrollkeeper_reason="unable to detect scrollkeeper-config"
1208    
1209 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
1210    
1211     # TODO: check size of void*
1212    
1213 johnpye 393 # TODO: detect if dynamic libraries are possible or not
1214    
1215 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
1216 johnpye 740 _found_windows_h = conf.CheckHeader('Windows.h')
1217    
1218     if not _found_windows_h:
1219 johnpye 741 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1220 johnpye 740 Exit(1)
1221 johnpye 741
1222 johnpye 534 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1223 johnpye 427 with_python = 0;
1224     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
1225    
1226     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
1227    
1228 johnpye 395 conf.Finish()
1229    
1230     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
1231     env.Append(PYTHON_LIB=[python_lib])
1232     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
1233    
1234 johnpye 507 #---------------------------------------
1235     # SUBSTITUTION DICTIONARY for .in files
1236    
1237 johnpye 658 release = env.get('RELEASE')
1238     if release=="0.":
1239     release="0"
1240    
1241 johnpye 800 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1242    
1243 johnpye 507 subst_dict = {
1244     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1245     , '@GLADE_FILE@':'ascend.glade'
1246     , '@HELP_ROOT@':''
1247     , '@ICON_EXTENSION@':icon_extension
1248 johnpye 628 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1249 johnpye 507 , '@INSTALL_BIN@':env['INSTALL_BIN']
1250     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1251 johnpye 683 , '@INSTALL_LIB@':env['INSTALL_LIB']
1252 johnpye 721 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1253 johnpye 507 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1254     , '@VERSION@':version
1255 johnpye 658 , '@RELEASE@':release
1256 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1257 johnpye 507 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1258 johnpye 508 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1259     , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1260 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1261 johnpye 627 , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1262 johnpye 683 , '@PYTHON@' : python_exe
1263 johnpye 800 , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1264     , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1265     , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_LIBPATH"))
1266 johnpye 507 }
1267    
1268 johnpye 594 if env.get('WITH_LOCAL_HELP'):
1269 johnpye 507 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1270     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1271    
1272 johnpye 597 # bool options...
1273 johnpye 673 for k,v in {
1274     'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1275     ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1276     ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1277 johnpye 605 }.iteritems():
1278 johnpye 597 if env.get(k):
1279 johnpye 673 # subst_dict['@'+v+'@']='1'
1280     subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1281 johnpye 594
1282 johnpye 673 if with_ida:
1283     subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1284    
1285 johnpye 783 if with_conopt:
1286     subst_dict["/\\* #define ASC_WITH_CONOPT @ASC_WITH_CONOPT@ \\*/"]='#define ASC_WITH_CONOPT '
1287    
1288 johnpye 673 if with_lsode:
1289     subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1290    
1291 johnpye 507 if with_python:
1292     subst_dict['@ASCXX_USE_PYTHON@']="1"
1293 johnpye 673 env['WITH_PYTHON']=1;
1294 johnpye 507
1295     if env.has_key('HAVE_GCCVISIBILITY'):
1296     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
1297    
1298     env.Append(SUBST_DICT=subst_dict)
1299    
1300 johnpye 385 #------------------------------------------------------
1301 johnpye 558 # RECIPE: SWIG scanner
1302    
1303     import SCons.Script
1304    
1305     SWIGScanner = SCons.Scanner.ClassicCPP(
1306     "SWIGScan"
1307     , ".i"
1308     , "CPPPATH"
1309     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1310     )
1311    
1312     env.Append(SCANNERS=[SWIGScanner])
1313    
1314     #------------------------------------------------------
1315 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
1316    
1317     import re
1318 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
1319 johnpye 393
1320 johnpye 395 def TOOL_SUBST(env):
1321     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
1322     from the source to the target.
1323     The values of SUBST_DICT first have any construction variables expanded
1324     (its keys are not expanded).
1325     If a value of SUBST_DICT is a python callable function, it is called and
1326     the result is expanded as the value.
1327     If there's more than one source and more than one target, each target gets
1328     substituted from the corresponding source.
1329 johnpye 393 """
1330 johnpye 395 env.Append(TOOLS = 'SUBST')
1331     def do_subst_in_file(targetfile, sourcefile, dict):
1332     """Replace all instances of the keys of dict with their values.
1333     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
1334     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
1335     """
1336     try:
1337     f = open(sourcefile, 'rb')
1338     contents = f.read()
1339     f.close()
1340     except:
1341     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
1342     for (k,v) in dict.items():
1343     contents = re.sub(k, v, contents)
1344     try:
1345     f = open(targetfile, 'wb')
1346     f.write(contents)
1347     f.close()
1348     except:
1349     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
1350     return 0 # success
1351 johnpye 393
1352 johnpye 395 def subst_in_file(target, source, env):
1353     if not env.has_key('SUBST_DICT'):
1354     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
1355     d = dict(env['SUBST_DICT']) # copy it
1356     for (k,v) in d.items():
1357     if callable(v):
1358     d[k] = env.subst(v())
1359     elif SCons.Util.is_String(v):
1360     d[k]=env.subst(v)
1361     else:
1362     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
1363     for (t,s) in zip(target, source):
1364     return do_subst_in_file(str(t), str(s), d)
1365 johnpye 393
1366 johnpye 395 def subst_in_file_string(target, source, env):
1367     """This is what gets printed on the console."""
1368     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
1369     for (t,s) in zip(target, source)])
1370 johnpye 393
1371 johnpye 395 def subst_emitter(target, source, env):
1372     """Add dependency from substituted SUBST_DICT to target.
1373     Returns original target, source tuple unchanged.
1374     """
1375     d = env['SUBST_DICT'].copy() # copy it
1376     for (k,v) in d.items():
1377     if callable(v):
1378     d[k] = env.subst(v())
1379     elif SCons.Util.is_String(v):
1380     d[k]=env.subst(v)
1381     Depends(target, SCons.Node.Python.Value(d))
1382     return target, source
1383 johnpye 393
1384 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1385     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1386    
1387     TOOL_SUBST(env)
1388    
1389 johnpye 393 #------------------------------------------------------
1390 johnpye 463 # Recipe for 'CHMOD' ACTION
1391 johnpye 439
1392     import SCons
1393     from SCons.Script.SConscript import SConsEnvironment
1394     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1395     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1396    
1397     def InstallPerm(env, dest, files, perm):
1398     obj = env.Install(dest, files)
1399     for i in obj:
1400     env.AddPostAction(i, env.Chmod(str(i), perm))
1401    
1402     SConsEnvironment.InstallPerm = InstallPerm
1403    
1404     # define wrappers
1405     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1406 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1407 johnpye 629 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1408 johnpye 463
1409 johnpye 439 #------------------------------------------------------
1410 johnpye 463 # BUILD...
1411 johnpye 385
1412 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
1413 johnpye 743 env.AppendUnique(CPPPATH=['#base/generic'])
1414 johnpye 385
1415 johnpye 508 if env['DEBUG']:
1416     env.Append(CCFLAGS=['-g'])
1417    
1418 johnpye 591 if env['GCOV']:
1419     env.Append(
1420     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1421     , LIBS=['gcov']
1422     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1423     )
1424    
1425 johnpye 673 if with_ida:
1426     env.Append(WITH_IDA=1)
1427    
1428 johnpye 783 if with_conopt:
1429     env.Append(WITH_CONOPT=1)
1430    
1431 johnpye 463 #-------------
1432     # TCL/TK GUI
1433 johnpye 385
1434 johnpye 551 if with_tcltk:
1435 johnpye 569 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1436 johnpye 391 else:
1437 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1438 johnpye 386
1439 johnpye 463 #-------------
1440     # PYTHON INTERFACE
1441    
1442 johnpye 387 if with_python:
1443 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
1444 johnpye 391 else:
1445 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
1446 johnpye 400
1447 johnpye 463 #------------
1448     # BASE/GENERIC SUBDIRECTORIES
1449    
1450 johnpye 673 libascend_env = env.Copy()
1451    
1452 johnpye 463 dirs = ['general','utilities','compiler','solver','packages']
1453    
1454     srcs = []
1455     for d in dirs:
1456 johnpye 673 heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1457 johnpye 463 srcs += heresrcs
1458    
1459     #-------------
1460 johnpye 673 # IMPORTED CODE: LSODE, BLAS, etc
1461    
1462     if with_lsode:
1463     srcs += env.SConscript(['lsod/SConscript'],'env')
1464     srcs += env.SConscript(['linpack/SConscript'],'env')
1465     else:
1466     print "Skipping... LSODE won't be built:", without_lsode_reason
1467    
1468     if with_local_blas:
1469     srcs += env.SConscript(['blas/SConscript'],'env')
1470     else:
1471     print "Skipping... BLAS won't be built:", without_local_blas_reason
1472    
1473     if not with_ida:
1474     print "Skipping... IDA won't be built:", without_ida_reason
1475    
1476     #-------------
1477 johnpye 463 # LIBASCEND -- all base/generic functionality
1478    
1479 johnpye 673 libascend = libascend_env.SharedLibrary('ascend',srcs)
1480 johnpye 463
1481 johnpye 673 env.Alias('libascend',libascend)
1482    
1483 johnpye 463 #-------------
1484 johnpye 761 # UNIT TESTS (C CODE)
1485 johnpye 463
1486 johnpye 593 if with_cunit:
1487 johnpye 400 testdirs = ['general','solver','utilities']
1488 johnpye 593 testsrcs = []
1489 johnpye 400 for testdir in testdirs:
1490     path = 'base/generic/'+testdir+'/test/'
1491     env.SConscript([path+'SConscript'],'env')
1492 johnpye 593 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1493    
1494     #print "TESTSRCS =",testsrcs
1495    
1496 johnpye 400 env.SConscript(['test/SConscript'],'env')
1497     env.SConscript(['base/generic/test/SConscript'],'env')
1498 johnpye 593
1499     env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1500 johnpye 400
1501     else:
1502 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1503 johnpye 400
1504 johnpye 761 #-------------
1505     # EXTERNAL FUNCTIONS
1506    
1507 johnpye 811 env['extfns']=[]
1508     modeldirs = env.SConscript(['models/SConscript'],'env')
1509    
1510     if not with_extfns:
1511 johnpye 761 print "Skipping... External modules aren't being built:",without_extfns_reason
1512    
1513 johnpye 811 env.Alias('extfns',env['extfns'])
1514 johnpye 761
1515 johnpye 463 #------------------------------------------------------
1516 johnpye 683 # CREATE ASCEND-CONFIG scriptlet
1517    
1518     ascendconfig = env.SubstInFile('ascend-config.in')
1519    
1520     #------------------------------------------------------
1521 johnpye 463 # INSTALLATION
1522 johnpye 427
1523 johnpye 552 if env.get('CAN_INSTALL'):
1524 johnpye 427
1525 johnpye 721 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
1526 johnpye 463 install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1527 johnpye 811 install_dirs += modeldirs
1528 johnpye 449
1529 johnpye 463 # TODO: add install options
1530     env.Alias('install',install_dirs)
1531 johnpye 400
1532 johnpye 629 env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1533 johnpye 435
1534 johnpye 683 env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1535    
1536 johnpye 438 #------------------------------------------------------
1537 johnpye 631 # WINDOWS INSTALLER
1538     # For the windows installer, please see pygtk/SConscript
1539    
1540     if with_installer:
1541     pass
1542     else:
1543     print "Skipping... Windows installer isn't being built:",without_installer_reason
1544    
1545     #------------------------------------------------------
1546 johnpye 673 # PROJECT FILE for MSVC
1547    
1548     env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1549    
1550     #------------------------------------------------------
1551 johnpye 438 # CREATE the SPEC file for generation of RPM packages
1552    
1553 johnpye 463 if platform.system()=="Linux":
1554     env.SubstInFile('ascend.spec.in')
1555 johnpye 552
1556     #------------------------------------------------------
1557 johnpye 816 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
1558    
1559     if with_scrollkeeper:
1560     env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
1561     env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
1562    
1563     #------------------------------------------------------
1564 johnpye 552 # DISTRIBUTION TAR FILE
1565    
1566 johnpye 554 env['DISTTAR_FORMAT']='bz2'
1567 johnpye 556 env.Append(
1568 johnpye 566 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1569 johnpye 561 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1570 johnpye 556 )
1571 johnpye 554
1572 johnpye 563 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1573 johnpye 556 , [env.Dir('#')]
1574 johnpye 554 )
1575    
1576 johnpye 680 env.Depends(tar,'ascend.spec')
1577    
1578 johnpye 554 #------------------------------------------------------
1579 johnpye 816 # USER'S MANUAL
1580    
1581     env.SConscript('doc/SConscript',['env'])
1582    
1583     #------------------------------------------------------
1584 johnpye 766 # LIBASCEND DOXYGEN DOCUMENTATION
1585    
1586     env.SConscript('base/doc/SConscript',['env'])
1587    
1588     #------------------------------------------------------
1589 johnpye 554 # RPM BUILD
1590    
1591 johnpye 766 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
1592     # (check * for the version number used to create the tarball)
1593 johnpye 554
1594     #------------------------------------------------------
1595     # DEFAULT TARGETS
1596    
1597 johnpye 673 default_targets =['libascend']
1598 johnpye 629 if with_tcltk:
1599     default_targets.append('tcltk')
1600     if with_python:
1601     default_targets.append('pygtk')
1602 johnpye 631 if with_installer:
1603     default_targets.append('installer')
1604 johnpye 761 if with_extfns:
1605     default_targets.append('extfns')
1606 johnpye 554
1607 johnpye 629 env.Default(default_targets)
1608    
1609     print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1610    
1611 johnpye 705 # vim: set syntax=python:
1612    

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