/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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