/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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