/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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